Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
linux-davinci
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
linux
linux-davinci
Commits
4acadb96
Commit
4acadb96
authored
Oct 17, 2007
by
Paul Mackerras
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'for-2.6.24' of
git://git.secretlab.ca/git/linux-2.6-mpc52xx
into merge
parents
5cae826e
b147d93d
Changes
27
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
27 changed files
with
2591 additions
and
7 deletions
+2591
-7
arch/powerpc/Kconfig
arch/powerpc/Kconfig
+4
-0
arch/powerpc/boot/dts/lite5200b.dts
arch/powerpc/boot/dts/lite5200b.dts
+17
-1
arch/powerpc/lib/Makefile
arch/powerpc/lib/Makefile
+1
-4
arch/powerpc/lib/rheap.c
arch/powerpc/lib/rheap.c
+15
-0
arch/powerpc/platforms/Kconfig
arch/powerpc/platforms/Kconfig
+4
-0
arch/powerpc/platforms/Kconfig.cputype
arch/powerpc/platforms/Kconfig.cputype
+1
-0
arch/powerpc/sysdev/Makefile
arch/powerpc/sysdev/Makefile
+1
-0
arch/powerpc/sysdev/bestcomm/Kconfig
arch/powerpc/sysdev/bestcomm/Kconfig
+39
-0
arch/powerpc/sysdev/bestcomm/Makefile
arch/powerpc/sysdev/bestcomm/Makefile
+14
-0
arch/powerpc/sysdev/bestcomm/ata.c
arch/powerpc/sysdev/bestcomm/ata.c
+154
-0
arch/powerpc/sysdev/bestcomm/ata.h
arch/powerpc/sysdev/bestcomm/ata.h
+37
-0
arch/powerpc/sysdev/bestcomm/bcom_ata_task.c
arch/powerpc/sysdev/bestcomm/bcom_ata_task.c
+67
-0
arch/powerpc/sysdev/bestcomm/bcom_fec_rx_task.c
arch/powerpc/sysdev/bestcomm/bcom_fec_rx_task.c
+78
-0
arch/powerpc/sysdev/bestcomm/bcom_fec_tx_task.c
arch/powerpc/sysdev/bestcomm/bcom_fec_tx_task.c
+91
-0
arch/powerpc/sysdev/bestcomm/bcom_gen_bd_rx_task.c
arch/powerpc/sysdev/bestcomm/bcom_gen_bd_rx_task.c
+63
-0
arch/powerpc/sysdev/bestcomm/bcom_gen_bd_tx_task.c
arch/powerpc/sysdev/bestcomm/bcom_gen_bd_tx_task.c
+69
-0
arch/powerpc/sysdev/bestcomm/bestcomm.c
arch/powerpc/sysdev/bestcomm/bestcomm.c
+528
-0
arch/powerpc/sysdev/bestcomm/bestcomm.h
arch/powerpc/sysdev/bestcomm/bestcomm.h
+190
-0
arch/powerpc/sysdev/bestcomm/bestcomm_priv.h
arch/powerpc/sysdev/bestcomm/bestcomm_priv.h
+334
-0
arch/powerpc/sysdev/bestcomm/fec.c
arch/powerpc/sysdev/bestcomm/fec.c
+270
-0
arch/powerpc/sysdev/bestcomm/fec.h
arch/powerpc/sysdev/bestcomm/fec.h
+61
-0
arch/powerpc/sysdev/bestcomm/gen_bd.c
arch/powerpc/sysdev/bestcomm/gen_bd.c
+260
-0
arch/powerpc/sysdev/bestcomm/gen_bd.h
arch/powerpc/sysdev/bestcomm/gen_bd.h
+48
-0
arch/powerpc/sysdev/bestcomm/sram.c
arch/powerpc/sysdev/bestcomm/sram.c
+177
-0
arch/powerpc/sysdev/bestcomm/sram.h
arch/powerpc/sysdev/bestcomm/sram.h
+54
-0
arch/ppc/Kconfig
arch/ppc/Kconfig
+6
-0
include/asm-ppc/mpc52xx_psc.h
include/asm-ppc/mpc52xx_psc.h
+8
-2
No files found.
arch/powerpc/Kconfig
View file @
4acadb96
...
...
@@ -699,3 +699,7 @@ source "crypto/Kconfig"
config PPC_CLOCK
bool
default n
config PPC_LIB_RHEAP
bool
arch/powerpc/boot/dts/lite5200b.dts
View file @
4acadb96
...
...
@@ -277,10 +277,26 @@
ethernet
@
3000
{
device_type
=
"network"
;
compatible
=
"mpc5200b-fec"
,
"mpc5200-fec"
;
reg
=
<
3000
8
00
>;
reg
=
<
3000
4
00
>;
mac
-
address
=
[
02
03
04
05
06
07
];
//
Bad
!
interrupts
=
<
2
5
0
>;
interrupt
-
parent
=
<&
mpc5200_pic
>;
phy
-
handle
=
<&
phy0
>;
};
mdio
@
3000
{
#
address
-
cells
=
<
1
>;
#
size
-
cells
=
<
0
>;
device_type
=
"mdio"
;
compatible
=
"mpc5200b-fec-phy"
;
reg
=
<
3000
400
>;
//
fec
range
,
since
we
need
to
setup
fec
interrupts
interrupts
=
<
2
5
0
>;
//
these
are
for
"mii command finished"
,
not
link
changes
&
co
.
interrupt
-
parent
=
<&
mpc5200_pic
>;
phy0
:
ethernet
-
phy
@
0
{
device_type
=
"ethernet-phy"
;
reg
=
<
0
>;
};
};
ata
@
3
a00
{
...
...
arch/powerpc/lib/Makefile
View file @
4acadb96
...
...
@@ -14,7 +14,6 @@ endif
obj-$(CONFIG_PPC64)
+=
copypage_64.o copyuser_64.o
\
memcpy_64.o usercopy_64.o mem_64.o string.o
obj-$(CONFIG_QUICC_ENGINE)
+=
rheap.o
obj-$(CONFIG_XMON)
+=
sstep.o
obj-$(CONFIG_KPROBES)
+=
sstep.o
obj-$(CONFIG_NOT_COHERENT_CACHE)
+=
dma-noncoherent.o
...
...
@@ -23,6 +22,4 @@ ifeq ($(CONFIG_PPC64),y)
obj-$(CONFIG_SMP)
+=
locks.o
endif
# Temporary hack until we have migrated to asm-powerpc
obj-$(CONFIG_8xx)
+=
rheap.o
obj-$(CONFIG_CPM2)
+=
rheap.o
obj-$(CONFIG_PPC_LIB_RHEAP)
+=
rheap.o
arch/powerpc/lib/rheap.c
View file @
4acadb96
...
...
@@ -15,6 +15,7 @@
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mm.h>
#include <linux/err.h>
#include <linux/slab.h>
...
...
@@ -275,6 +276,7 @@ rh_info_t *rh_create(unsigned int alignment)
return
info
;
}
EXPORT_SYMBOL_GPL
(
rh_create
);
/*
* Destroy a dynamically created remote heap. Deallocate only if the areas
...
...
@@ -288,6 +290,7 @@ void rh_destroy(rh_info_t * info)
if
((
info
->
flags
&
RHIF_STATIC_INFO
)
==
0
)
kfree
(
info
);
}
EXPORT_SYMBOL_GPL
(
rh_destroy
);
/*
* Initialize in place a remote heap info block. This is needed to support
...
...
@@ -320,6 +323,7 @@ void rh_init(rh_info_t * info, unsigned int alignment, int max_blocks,
for
(
i
=
0
,
blk
=
block
;
i
<
max_blocks
;
i
++
,
blk
++
)
list_add
(
&
blk
->
list
,
&
info
->
empty_list
);
}
EXPORT_SYMBOL_GPL
(
rh_init
);
/* Attach a free memory region, coalesces regions if adjuscent */
int
rh_attach_region
(
rh_info_t
*
info
,
unsigned
long
start
,
int
size
)
...
...
@@ -360,6 +364,7 @@ int rh_attach_region(rh_info_t * info, unsigned long start, int size)
return
0
;
}
EXPORT_SYMBOL_GPL
(
rh_attach_region
);
/* Detatch given address range, splits free block if needed. */
unsigned
long
rh_detach_region
(
rh_info_t
*
info
,
unsigned
long
start
,
int
size
)
...
...
@@ -428,6 +433,7 @@ unsigned long rh_detach_region(rh_info_t * info, unsigned long start, int size)
return
s
;
}
EXPORT_SYMBOL_GPL
(
rh_detach_region
);
/* Allocate a block of memory at the specified alignment. The value returned
* is an offset into the buffer initialized by rh_init(), or a negative number
...
...
@@ -502,6 +508,7 @@ unsigned long rh_alloc_align(rh_info_t * info, int size, int alignment, const ch
return
start
;
}
EXPORT_SYMBOL_GPL
(
rh_alloc_align
);
/* Allocate a block of memory at the default alignment. The value returned is
* an offset into the buffer initialized by rh_init(), or a negative number if
...
...
@@ -511,6 +518,7 @@ unsigned long rh_alloc(rh_info_t * info, int size, const char *owner)
{
return
rh_alloc_align
(
info
,
size
,
info
->
alignment
,
owner
);
}
EXPORT_SYMBOL_GPL
(
rh_alloc
);
/* Allocate a block of memory at the given offset, rounded up to the default
* alignment. The value returned is an offset into the buffer initialized by
...
...
@@ -594,6 +602,7 @@ unsigned long rh_alloc_fixed(rh_info_t * info, unsigned long start, int size, co
return
start
;
}
EXPORT_SYMBOL_GPL
(
rh_alloc_fixed
);
/* Deallocate the memory previously allocated by one of the rh_alloc functions.
* The return value is the size of the deallocated block, or a negative number
...
...
@@ -626,6 +635,7 @@ int rh_free(rh_info_t * info, unsigned long start)
return
size
;
}
EXPORT_SYMBOL_GPL
(
rh_free
);
int
rh_get_stats
(
rh_info_t
*
info
,
int
what
,
int
max_stats
,
rh_stats_t
*
stats
)
{
...
...
@@ -663,6 +673,7 @@ int rh_get_stats(rh_info_t * info, int what, int max_stats, rh_stats_t * stats)
return
nr
;
}
EXPORT_SYMBOL_GPL
(
rh_get_stats
);
int
rh_set_owner
(
rh_info_t
*
info
,
unsigned
long
start
,
const
char
*
owner
)
{
...
...
@@ -687,6 +698,7 @@ int rh_set_owner(rh_info_t * info, unsigned long start, const char *owner)
return
size
;
}
EXPORT_SYMBOL_GPL
(
rh_set_owner
);
void
rh_dump
(
rh_info_t
*
info
)
{
...
...
@@ -722,6 +734,7 @@ void rh_dump(rh_info_t * info)
st
[
i
].
size
,
st
[
i
].
owner
!=
NULL
?
st
[
i
].
owner
:
""
);
printk
(
KERN_INFO
"
\n
"
);
}
EXPORT_SYMBOL_GPL
(
rh_dump
);
void
rh_dump_blk
(
rh_info_t
*
info
,
rh_block_t
*
blk
)
{
...
...
@@ -729,3 +742,5 @@ void rh_dump_blk(rh_info_t * info, rh_block_t * blk)
"blk @0x%p: 0x%lx-0x%lx (%u)
\n
"
,
blk
,
blk
->
start
,
blk
->
start
+
blk
->
size
,
blk
->
size
);
}
EXPORT_SYMBOL_GPL
(
rh_dump_blk
);
arch/powerpc/platforms/Kconfig
View file @
4acadb96
...
...
@@ -264,6 +264,7 @@ config TAU_AVERAGE
config QUICC_ENGINE
bool
select PPC_LIB_RHEAP
help
The QUICC Engine (QE) is a new generation of communications
coprocessors on Freescale embedded CPUs (akin to CPM in older chips).
...
...
@@ -274,6 +275,7 @@ config CPM2
bool
default n
select CPM
select PPC_LIB_RHEAP
help
The CPM2 (Communications Processor Module) is a coprocessor on
embedded CPUs made by Freescale. Selecting this option means that
...
...
@@ -313,4 +315,6 @@ config FSL_ULI1575
config CPM
bool
source "arch/powerpc/sysdev/bestcomm/Kconfig"
endmenu
arch/powerpc/platforms/Kconfig.cputype
View file @
4acadb96
...
...
@@ -37,6 +37,7 @@ config PPC_8xx
select FSL_SOC
select 8xx
select WANT_DEVICE_TREE
select PPC_LIB_RHEAP
config 40x
bool "AMCC 40x"
...
...
arch/powerpc/sysdev/Makefile
View file @
4acadb96
...
...
@@ -14,6 +14,7 @@ obj-$(CONFIG_FSL_SOC) += fsl_soc.o
obj-$(CONFIG_FSL_PCI)
+=
fsl_pci.o
obj-$(CONFIG_TSI108_BRIDGE)
+=
tsi108_pci.o tsi108_dev.o
obj-$(CONFIG_QUICC_ENGINE)
+=
qe_lib/
obj-$(CONFIG_PPC_BESTCOMM)
+=
bestcomm/
mv64x60-$(CONFIG_PCI)
+=
mv64x60_pci.o
obj-$(CONFIG_MV64X60)
+=
$
(
mv64x60-y
)
mv64x60_pic.o mv64x60_dev.o
\
mv64x60_udbg.o
...
...
arch/powerpc/sysdev/bestcomm/Kconfig
0 → 100644
View file @
4acadb96
#
# Kconfig options for Bestcomm
#
config PPC_BESTCOMM
tristate "Bestcomm DMA engine support"
depends on PPC_MPC52xx
default n
select PPC_LIB_RHEAP
help
BestComm is the name of the communication coprocessor found
on the Freescale MPC5200 family of processor. It's usage is
optionnal for some drivers (like ATA), but required for
others (like FEC).
If you want to use drivers that require DMA operations,
answer Y or M. Otherwise say N.
config PPC_BESTCOMM_ATA
tristate "Bestcomm ATA task support"
depends on PPC_BESTCOMM
default n
help
This option enables the support for the ATA task.
config PPC_BESTCOMM_FEC
tristate "Bestcomm FEC tasks support"
depends on PPC_BESTCOMM
default n
help
This option enables the support for the FEC tasks.
config PPC_BESTCOMM_GEN_BD
tristate "Bestcomm GenBD tasks support"
depends on PPC_BESTCOMM
default n
help
This option enables the support for the GenBD tasks.
arch/powerpc/sysdev/bestcomm/Makefile
0 → 100644
View file @
4acadb96
#
# Makefile for BestComm & co
#
bestcomm-core-objs
:=
bestcomm.o sram.o
bestcomm-ata-objs
:=
ata.o bcom_ata_task.o
bestcomm-fec-objs
:=
fec.o bcom_fec_rx_task.o bcom_fec_tx_task.o
bestcomm-gen-bd-objs
:=
gen_bd.o bcom_gen_bd_rx_task.o bcom_gen_bd_tx_task.o
obj-$(CONFIG_PPC_BESTCOMM)
+=
bestcomm-core.o
obj-$(CONFIG_PPC_BESTCOMM_ATA)
+=
bestcomm-ata.o
obj-$(CONFIG_PPC_BESTCOMM_FEC)
+=
bestcomm-fec.o
obj-$(CONFIG_PPC_BESTCOMM_GEN_BD)
+=
bestcomm-gen-bd.o
arch/powerpc/sysdev/bestcomm/ata.c
0 → 100644
View file @
4acadb96
/*
* Bestcomm ATA task driver
*
*
* Patterned after bestcomm/fec.c by Dale Farnsworth <dfarnsworth@mvista.com>
* 2003-2004 (c) MontaVista, Software, Inc.
*
* Copyright (C) 2006-2007 Sylvain Munaut <tnt@246tNt.com>
* Copyright (C) 2006 Freescale - John Rigby
*
* This file is licensed under the terms of the GNU General Public License
* version 2. This program is licensed "as is" without any warranty of any
* kind, whether express or implied.
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/types.h>
#include <asm/io.h>
#include "bestcomm.h"
#include "bestcomm_priv.h"
#include "ata.h"
/* ======================================================================== */
/* Task image/var/inc */
/* ======================================================================== */
/* ata task image */
extern
u32
bcom_ata_task
[];
/* ata task vars that need to be set before enabling the task */
struct
bcom_ata_var
{
u32
enable
;
/* (u16*) address of task's control register */
u32
bd_base
;
/* (struct bcom_bd*) beginning of ring buffer */
u32
bd_last
;
/* (struct bcom_bd*) end of ring buffer */
u32
bd_start
;
/* (struct bcom_bd*) current bd */
u32
buffer_size
;
/* size of receive buffer */
};
/* ata task incs that need to be set before enabling the task */
struct
bcom_ata_inc
{
u16
pad0
;
s16
incr_bytes
;
u16
pad1
;
s16
incr_dst
;
u16
pad2
;
s16
incr_src
;
};
/* ======================================================================== */
/* Task support code */
/* ======================================================================== */
struct
bcom_task
*
bcom_ata_init
(
int
queue_len
,
int
maxbufsize
)
{
struct
bcom_task
*
tsk
;
struct
bcom_ata_var
*
var
;
struct
bcom_ata_inc
*
inc
;
tsk
=
bcom_task_alloc
(
queue_len
,
sizeof
(
struct
bcom_ata_bd
),
0
);
if
(
!
tsk
)
return
NULL
;
tsk
->
flags
=
BCOM_FLAGS_NONE
;
bcom_ata_reset_bd
(
tsk
);
var
=
(
struct
bcom_ata_var
*
)
bcom_task_var
(
tsk
->
tasknum
);
inc
=
(
struct
bcom_ata_inc
*
)
bcom_task_inc
(
tsk
->
tasknum
);
if
(
bcom_load_image
(
tsk
->
tasknum
,
bcom_ata_task
))
{
bcom_task_free
(
tsk
);
return
NULL
;
}
var
->
enable
=
bcom_eng
->
regs_base
+
offsetof
(
struct
mpc52xx_sdma
,
tcr
[
tsk
->
tasknum
]);
var
->
bd_base
=
tsk
->
bd_pa
;
var
->
bd_last
=
tsk
->
bd_pa
+
((
tsk
->
num_bd
-
1
)
*
tsk
->
bd_size
);
var
->
bd_start
=
tsk
->
bd_pa
;
var
->
buffer_size
=
maxbufsize
;
/* Configure some stuff */
bcom_set_task_pragma
(
tsk
->
tasknum
,
BCOM_ATA_PRAGMA
);
bcom_set_task_auto_start
(
tsk
->
tasknum
,
tsk
->
tasknum
);
out_8
(
&
bcom_eng
->
regs
->
ipr
[
BCOM_INITIATOR_ATA_RX
],
BCOM_IPR_ATA_RX
);
out_8
(
&
bcom_eng
->
regs
->
ipr
[
BCOM_INITIATOR_ATA_TX
],
BCOM_IPR_ATA_TX
);
out_be32
(
&
bcom_eng
->
regs
->
IntPend
,
1
<<
tsk
->
tasknum
);
/* Clear ints */
return
tsk
;
}
EXPORT_SYMBOL_GPL
(
bcom_ata_init
);
void
bcom_ata_rx_prepare
(
struct
bcom_task
*
tsk
)
{
struct
bcom_ata_inc
*
inc
;
inc
=
(
struct
bcom_ata_inc
*
)
bcom_task_inc
(
tsk
->
tasknum
);
inc
->
incr_bytes
=
-
(
s16
)
sizeof
(
u32
);
inc
->
incr_src
=
0
;
inc
->
incr_dst
=
sizeof
(
u32
);
bcom_set_initiator
(
tsk
->
tasknum
,
BCOM_INITIATOR_ATA_RX
);
}
EXPORT_SYMBOL_GPL
(
bcom_ata_rx_prepare
);
void
bcom_ata_tx_prepare
(
struct
bcom_task
*
tsk
)
{
struct
bcom_ata_inc
*
inc
;
inc
=
(
struct
bcom_ata_inc
*
)
bcom_task_inc
(
tsk
->
tasknum
);
inc
->
incr_bytes
=
-
(
s16
)
sizeof
(
u32
);
inc
->
incr_src
=
sizeof
(
u32
);
inc
->
incr_dst
=
0
;
bcom_set_initiator
(
tsk
->
tasknum
,
BCOM_INITIATOR_ATA_TX
);
}
EXPORT_SYMBOL_GPL
(
bcom_ata_tx_prepare
);
void
bcom_ata_reset_bd
(
struct
bcom_task
*
tsk
)
{
struct
bcom_ata_var
*
var
;
/* Reset all BD */
memset
(
tsk
->
bd
,
0x00
,
tsk
->
num_bd
*
tsk
->
bd_size
);
tsk
->
index
=
0
;
tsk
->
outdex
=
0
;
var
=
(
struct
bcom_ata_var
*
)
bcom_task_var
(
tsk
->
tasknum
);
var
->
bd_start
=
var
->
bd_base
;
}
EXPORT_SYMBOL_GPL
(
bcom_ata_reset_bd
);
void
bcom_ata_release
(
struct
bcom_task
*
tsk
)
{
/* Nothing special for the ATA tasks */
bcom_task_free
(
tsk
);
}
EXPORT_SYMBOL_GPL
(
bcom_ata_release
);
MODULE_DESCRIPTION
(
"BestComm ATA task driver"
);
MODULE_AUTHOR
(
"John Rigby"
);
MODULE_LICENSE
(
"GPL v2"
);
arch/powerpc/sysdev/bestcomm/ata.h
0 → 100644
View file @
4acadb96
/*
* Header for Bestcomm ATA task driver
*
*
* Copyright (C) 2006 Freescale - John Rigby
* Copyright (C) 2006 Sylvain Munaut <tnt@246tNt.com>
*
* This file is licensed under the terms of the GNU General Public License
* version 2. This program is licensed "as is" without any warranty of any
* kind, whether express or implied.
*/
#ifndef __BESTCOMM_ATA_H__
#define __BESTCOMM_ATA_H__
struct
bcom_ata_bd
{
u32
status
;
u32
dst_pa
;
u32
src_pa
;
};
extern
struct
bcom_task
*
bcom_ata_init
(
int
queue_len
,
int
maxbufsize
);
extern
void
bcom_ata_rx_prepare
(
struct
bcom_task
*
tsk
);
extern
void
bcom_ata_tx_prepare
(
struct
bcom_task
*
tsk
);
extern
void
bcom_ata_reset_bd
(
struct
bcom_task
*
tsk
);
#endif
/* __BESTCOMM_ATA_H__ */
arch/powerpc/sysdev/bestcomm/bcom_ata_task.c
0 → 100644
View file @
4acadb96
/*
* Bestcomm ATA task microcode
*
* Copyright (c) 2004 Freescale Semiconductor, Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*
* Created based on bestcom/code_dma/image_rtos1/dma_image.hex
*/
#include <asm/types.h>
/*
* The header consists of the following fields:
* u32 magic;
* u8 desc_size;
* u8 var_size;
* u8 inc_size;
* u8 first_var;
* u8 reserved[8];
*
* The size fields contain the number of 32-bit words.
*/
u32
bcom_ata_task
[]
=
{
/* header */
0x4243544b
,
0x0e060709
,
0x00000000
,
0x00000000
,
/* Task descriptors */
0x8198009b
,
/* LCD: idx0 = var3; idx0 <= var2; idx0 += inc3 */
0x13e00c08
,
/* DRD1A: var3 = var1; FN=0 MORE init=31 WS=0 RS=0 */
0xb8000264
,
/* LCD: idx1 = *idx0, idx2 = var0; idx1 < var9; idx1 += inc4, idx2 += inc4 */
0x10000f00
,
/* DRD1A: var3 = idx0; FN=0 MORE init=0 WS=0 RS=0 */
0x60140002
,
/* DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT init=0 WS=2 RS=2 */
0x0c8cfc8a
,
/* DRD2B1: *idx2 = EU3(); EU3(*idx2,var10) */
0xd8988240
,
/* LCDEXT: idx1 = idx1; idx1 > var9; idx1 += inc0 */
0xf845e011
,
/* LCDEXT: idx2 = *(idx0 + var00000015); ; idx2 += inc2 */
0xb845e00a
,
/* LCD: idx3 = *(idx0 + var00000019); ; idx3 += inc1 */
0x0bfecf90
,
/* DRD1A: *idx3 = *idx2; FN=0 TFD init=31 WS=3 RS=3 */
0x9898802d
,
/* LCD: idx1 = idx1; idx1 once var0; idx1 += inc5 */
0x64000005
,
/* DRD2A: EU0=0 EU1=0 EU2=0 EU3=5 INT EXT init=0 WS=0 RS=0 */
0x0c0cf849
,
/* DRD2B1: *idx0 = EU3(); EU3(idx1,var9) */
0x000001f8
,
/* NOP */
/* VAR[9]-VAR[14] */
0x40000000
,
0x7fff7fff
,
0x00000000
,
0x00000000
,
0x00000000
,
0x00000000
,
/* INC[0]-INC[6] */
0x40000000
,
0xe0000000
,
0xe0000000
,
0xa000000c
,
0x20000000
,
0x00000000
,
0x00000000
,
};
arch/powerpc/sysdev/bestcomm/bcom_fec_rx_task.c
0 → 100644
View file @
4acadb96
/*
* Bestcomm FEC RX task microcode
*
* Copyright (c) 2004 Freescale Semiconductor, Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*
* Automatically created based on BestCommAPI-2.2/code_dma/image_rtos1/dma_image.hex
* on Tue Mar 22 11:19:38 2005 GMT
*/
#include <asm/types.h>
/*
* The header consists of the following fields:
* u32 magic;
* u8 desc_size;
* u8 var_size;
* u8 inc_size;
* u8 first_var;
* u8 reserved[8];
*
* The size fields contain the number of 32-bit words.
*/
u32
bcom_fec_rx_task
[]
=
{
/* header */
0x4243544b
,
0x18060709
,
0x00000000
,
0x00000000
,
/* Task descriptors */
0x808220e3
,
/* LCD: idx0 = var1, idx1 = var4; idx1 <= var3; idx0 += inc4, idx1 += inc3 */
0x10601010
,
/* DRD1A: var4 = var2; FN=0 MORE init=3 WS=0 RS=0 */
0xb8800264
,
/* LCD: idx2 = *idx1, idx3 = var0; idx2 < var9; idx2 += inc4, idx3 += inc4 */
0x10001308
,
/* DRD1A: var4 = idx1; FN=0 MORE init=0 WS=0 RS=0 */
0x60140002
,
/* DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT init=0 WS=2 RS=2 */
0x0cccfcca
,
/* DRD2B1: *idx3 = EU3(); EU3(*idx3,var10) */
0x80004000
,
/* LCDEXT: idx2 = 0x00000000; ; */
0xb8c58029
,
/* LCD: idx3 = *(idx1 + var00000015); idx3 once var0; idx3 += inc5 */
0x60000002
,
/* DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT init=0 WS=0 RS=0 */
0x088cf8cc
,
/* DRD2B1: idx2 = EU3(); EU3(idx3,var12) */
0x991982f2
,
/* LCD: idx2 = idx2, idx3 = idx3; idx2 > var11; idx2 += inc6, idx3 += inc2 */
0x006acf80
,
/* DRD1A: *idx3 = *idx0; FN=0 init=3 WS=1 RS=1 */
0x80004000
,
/* LCDEXT: idx2 = 0x00000000; ; */
0x9999802d
,
/* LCD: idx3 = idx3; idx3 once var0; idx3 += inc5 */
0x70000002
,
/* DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT MORE init=0 WS=0 RS=0 */
0x034cfc4e
,
/* DRD2B1: var13 = EU3(); EU3(*idx1,var14) */
0x00008868
,
/* DRD1A: idx2 = var13; FN=0 init=0 WS=0 RS=0 */
0x99198341
,
/* LCD: idx2 = idx2, idx3 = idx3; idx2 > var13; idx2 += inc0, idx3 += inc1 */
0x007ecf80
,
/* DRD1A: *idx3 = *idx0; FN=0 init=3 WS=3 RS=3 */
0x99198272
,
/* LCD: idx2 = idx2, idx3 = idx3; idx2 > var9; idx2 += inc6, idx3 += inc2 */
0x046acf80
,
/* DRD1A: *idx3 = *idx0; FN=0 INT init=3 WS=1 RS=1 */
0x9819002d
,
/* LCD: idx2 = idx0; idx2 once var0; idx2 += inc5 */
0x0060c790
,
/* DRD1A: *idx1 = *idx2; FN=0 init=3 WS=0 RS=0 */
0x000001f8
,
/* NOP */
/* VAR[9]-VAR[14] */
0x40000000
,
0x7fff7fff
,
0x00000000
,
0x00000003
,
0x40000008
,
0x43ffffff
,
/* INC[0]-INC[6] */
0x40000000
,
0xe0000000
,
0xe0000000
,
0xa0000008
,
0x20000000
,
0x00000000
,
0x4000ffff
,
};
arch/powerpc/sysdev/bestcomm/bcom_fec_tx_task.c
0 → 100644
View file @
4acadb96
/*
* Bestcomm FEC TX task microcode
*
* Copyright (c) 2004 Freescale Semiconductor, Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*
* Automatically created based on BestCommAPI-2.2/code_dma/image_rtos1/dma_image.hex
* on Tue Mar 22 11:19:29 2005 GMT
*/
#include <asm/types.h>
/*
* The header consists of the following fields:
* u32 magic;
* u8 desc_size;
* u8 var_size;
* u8 inc_size;
* u8 first_var;
* u8 reserved[8];
*
* The size fields contain the number of 32-bit words.
*/
u32
bcom_fec_tx_task
[]
=
{
/* header */
0x4243544b
,
0x2407070d
,
0x00000000
,
0x00000000
,
/* Task descriptors */
0x8018001b
,
/* LCD: idx0 = var0; idx0 <= var0; idx0 += inc3 */
0x60000005
,
/* DRD2A: EU0=0 EU1=0 EU2=0 EU3=5 EXT init=0 WS=0 RS=0 */
0x01ccfc0d
,
/* DRD2B1: var7 = EU3(); EU3(*idx0,var13) */
0x8082a123
,
/* LCD: idx0 = var1, idx1 = var5; idx1 <= var4; idx0 += inc4, idx1 += inc3 */
0x10801418
,
/* DRD1A: var5 = var3; FN=0 MORE init=4 WS=0 RS=0 */
0xf88103a4
,
/* LCDEXT: idx2 = *idx1, idx3 = var2; idx2 < var14; idx2 += inc4, idx3 += inc4 */
0x801a6024
,
/* LCD: idx4 = var0; ; idx4 += inc4 */
0x10001708
,
/* DRD1A: var5 = idx1; FN=0 MORE init=0 WS=0 RS=0 */
0x60140002
,
/* DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT init=0 WS=2 RS=2 */
0x0cccfccf
,
/* DRD2B1: *idx3 = EU3(); EU3(*idx3,var15) */
0x991a002c
,
/* LCD: idx2 = idx2, idx3 = idx4; idx2 once var0; idx2 += inc5, idx3 += inc4 */
0x70000002
,
/* DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT MORE init=0 WS=0 RS=0 */
0x024cfc4d
,
/* DRD2B1: var9 = EU3(); EU3(*idx1,var13) */
0x60000003
,
/* DRD2A: EU0=0 EU1=0 EU2=0 EU3=3 EXT init=0 WS=0 RS=0 */
0x0cccf247
,
/* DRD2B1: *idx3 = EU3(); EU3(var9,var7) */
0x80004000
,
/* LCDEXT: idx2 = 0x00000000; ; */
0xb8c80029
,
/* LCD: idx3 = *(idx1 + var0000001a); idx3 once var0; idx3 += inc5 */
0x70000002
,
/* DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT MORE init=0 WS=0 RS=0 */
0x088cf8d1
,
/* DRD2B1: idx2 = EU3(); EU3(idx3,var17) */
0x00002f10
,
/* DRD1A: var11 = idx2; FN=0 init=0 WS=0 RS=0 */
0x99198432
,
/* LCD: idx2 = idx2, idx3 = idx3; idx2 > var16; idx2 += inc6, idx3 += inc2 */
0x008ac398
,
/* DRD1A: *idx0 = *idx3; FN=0 init=4 WS=1 RS=1 */
0x80004000
,
/* LCDEXT: idx2 = 0x00000000; ; */
0x9999802d
,
/* LCD: idx3 = idx3; idx3 once var0; idx3 += inc5 */
0x70000002
,
/* DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT MORE init=0 WS=0 RS=0 */
0x048cfc53
,
/* DRD2B1: var18 = EU3(); EU3(*idx1,var19) */
0x60000008
,
/* DRD2A: EU0=0 EU1=0 EU2=0 EU3=8 EXT init=0 WS=0 RS=0 */
0x088cf48b
,
/* DRD2B1: idx2 = EU3(); EU3(var18,var11) */
0x99198481
,
/* LCD: idx2 = idx2, idx3 = idx3; idx2 > var18; idx2 += inc0, idx3 += inc1 */
0x009ec398
,
/* DRD1A: *idx0 = *idx3; FN=0 init=4 WS=3 RS=3 */
0x991983b2
,
/* LCD: idx2 = idx2, idx3 = idx3; idx2 > var14; idx2 += inc6, idx3 += inc2 */
0x088ac398
,
/* DRD1A: *idx0 = *idx3; FN=0 TFD init=4 WS=1 RS=1 */
0x9919002d
,
/* LCD: idx2 = idx2; idx2 once var0; idx2 += inc5 */
0x60000005
,
/* DRD2A: EU0=0 EU1=0 EU2=0 EU3=5 EXT init=0 WS=0 RS=0 */
0x0c4cf88e
,
/* DRD2B1: *idx1 = EU3(); EU3(idx2,var14) */
0x000001f8
,
/* NOP */
/* VAR[13]-VAR[19] */
0x0c000000
,
0x40000000
,
0x7fff7fff
,
0x00000000
,
0x00000003
,
0x40000004
,
0x43ffffff
,
/* INC[0]-INC[6] */
0x40000000
,
0xe0000000
,
0xe0000000
,
0xa0000008
,
0x20000000
,
0x00000000
,
0x4000ffff
,
};
arch/powerpc/sysdev/bestcomm/bcom_gen_bd_rx_task.c
0 → 100644
View file @
4acadb96
/*
* Bestcomm GenBD RX task microcode
*
* Copyright (C) 2006 AppSpec Computer Technologies Corp.
* Jeff Gibbons <jeff.gibbons@appspec.com>
* Copyright (c) 2004 Freescale Semiconductor, Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*
* Based on BestCommAPI-2.2/code_dma/image_rtos1/dma_image.hex
* on Tue Mar 4 10:14:12 2006 GMT
*
*/
#include <asm/types.h>
/*
* The header consists of the following fields:
* u32 magic;
* u8 desc_size;
* u8 var_size;
* u8 inc_size;
* u8 first_var;
* u8 reserved[8];
*
* The size fields contain the number of 32-bit words.
*/
u32
bcom_gen_bd_rx_task
[]
=
{
/* header */
0x4243544b
,
0x0d020409
,
0x00000000
,
0x00000000
,
/* Task descriptors */
0x808220da
,
/* LCD: idx0 = var1, idx1 = var4; idx1 <= var3; idx0 += inc3, idx1 += inc2 */
0x13e01010
,
/* DRD1A: var4 = var2; FN=0 MORE init=31 WS=0 RS=0 */
0xb880025b
,
/* LCD: idx2 = *idx1, idx3 = var0; idx2 < var9; idx2 += inc3, idx3 += inc3 */
0x10001308
,
/* DRD1A: var4 = idx1; FN=0 MORE init=0 WS=0 RS=0 */
0x60140002
,
/* DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT init=0 WS=2 RS=2 */
0x0cccfcca
,
/* DRD2B1: *idx3 = EU3(); EU3(*idx3,var10) */
0xd9190240
,
/* LCDEXT: idx2 = idx2; idx2 > var9; idx2 += inc0 */
0xb8c5e009
,
/* LCD: idx3 = *(idx1 + var00000015); ; idx3 += inc1 */
0x07fecf80
,
/* DRD1A: *idx3 = *idx0; FN=0 INT init=31 WS=3 RS=3 */
0x99190024
,
/* LCD: idx2 = idx2; idx2 once var0; idx2 += inc4 */
0x60000005
,
/* DRD2A: EU0=0 EU1=0 EU2=0 EU3=5 EXT init=0 WS=0 RS=0 */
0x0c4cf889
,
/* DRD2B1: *idx1 = EU3(); EU3(idx2,var9) */
0x000001f8
,
/* NOP */
/* VAR[9]-VAR[10] */
0x40000000
,
0x7fff7fff
,
/* INC[0]-INC[3] */
0x40000000
,
0xe0000000
,
0xa0000008
,
0x20000000
,
};
arch/powerpc/sysdev/bestcomm/bcom_gen_bd_tx_task.c
0 → 100644
View file @
4acadb96
/*
* Bestcomm GenBD TX task microcode
*
* Copyright (C) 2006 AppSpec Computer Technologies Corp.
* Jeff Gibbons <jeff.gibbons@appspec.com>
* Copyright (c) 2004 Freescale Semiconductor, Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*
* Based on BestCommAPI-2.2/code_dma/image_rtos1/dma_image.hex
* on Tue Mar 4 10:14:12 2006 GMT
*
*/
#include <asm/types.h>
/*
* The header consists of the following fields:
* u32 magic;
* u8 desc_size;
* u8 var_size;
* u8 inc_size;
* u8 first_var;
* u8 reserved[8];
*
* The size fields contain the number of 32-bit words.
*/
u32
bcom_gen_bd_tx_task
[]
=
{
/* header */
0x4243544b
,
0x0f040609
,
0x00000000
,
0x00000000
,
/* Task descriptors */
0x800220e3
,
/* LCD: idx0 = var0, idx1 = var4; idx1 <= var3; idx0 += inc4, idx1 += inc3 */
0x13e01010
,
/* DRD1A: var4 = var2; FN=0 MORE init=31 WS=0 RS=0 */
0xb8808264
,
/* LCD: idx2 = *idx1, idx3 = var1; idx2 < var9; idx2 += inc4, idx3 += inc4 */
0x10001308
,
/* DRD1A: var4 = idx1; FN=0 MORE init=0 WS=0 RS=0 */
0x60140002
,
/* DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT init=0 WS=2 RS=2 */
0x0cccfcca
,
/* DRD2B1: *idx3 = EU3(); EU3(*idx3,var10) */
0xd9190300
,
/* LCDEXT: idx2 = idx2; idx2 > var12; idx2 += inc0 */
0xb8c5e009
,
/* LCD: idx3 = *(idx1 + var00000015); ; idx3 += inc1 */
0x03fec398
,
/* DRD1A: *idx0 = *idx3; FN=0 init=31 WS=3 RS=3 */
0x9919826a
,
/* LCD: idx2 = idx2, idx3 = idx3; idx2 > var9; idx2 += inc5, idx3 += inc2 */
0x0feac398
,
/* DRD1A: *idx0 = *idx3; FN=0 TFD INT init=31 WS=1 RS=1 */
0x99190036
,
/* LCD: idx2 = idx2; idx2 once var0; idx2 += inc6 */
0x60000005
,
/* DRD2A: EU0=0 EU1=0 EU2=0 EU3=5 EXT init=0 WS=0 RS=0 */
0x0c4cf889
,
/* DRD2B1: *idx1 = EU3(); EU3(idx2,var9) */
0x000001f8
,
/* NOP */
/* VAR[9]-VAR[12] */
0x40000000
,
0x7fff7fff
,
0x00000000
,
0x40000004
,
/* INC[0]-INC[5] */
0x40000000
,
0xe0000000
,
0xe0000000
,
0xa0000008
,
0x20000000
,
0x4000ffff
,
};
arch/powerpc/sysdev/bestcomm/bestcomm.c
0 → 100644
View file @
4acadb96
This diff is collapsed.
Click to expand it.
arch/powerpc/sysdev/bestcomm/bestcomm.h
0 → 100644
View file @
4acadb96
/*
* Public header for the MPC52xx processor BestComm driver
*
*
* Copyright (C) 2006 Sylvain Munaut <tnt@246tNt.com>
* Copyright (C) 2005 Varma Electronics Oy,
* ( by Andrey Volkov <avolkov@varma-el.com> )
* Copyright (C) 2003-2004 MontaVista, Software, Inc.
* ( by Dale Farnsworth <dfarnsworth@mvista.com> )
*
* This file is licensed under the terms of the GNU General Public License
* version 2. This program is licensed "as is" without any warranty of any
* kind, whether express or implied.
*/
#ifndef __BESTCOMM_H__
#define __BESTCOMM_H__
struct
bcom_bd
;
/* defined later on ... */
/* ======================================================================== */
/* Generic task managment */
/* ======================================================================== */
/**
* struct bcom_task - Structure describing a loaded BestComm task
*
* This structure is never built by the driver it self. It's built and
* filled the intermediate layer of the BestComm API, the task dependent
* support code.
*
* Most likely you don't need to poke around inside this structure. The
* fields are exposed in the header just for the sake of inline functions
*/
struct
bcom_task
{
unsigned
int
tasknum
;
unsigned
int
flags
;
int
irq
;
struct
bcom_bd
*
bd
;
phys_addr_t
bd_pa
;
void
**
cookie
;
unsigned
short
index
;
unsigned
short
outdex
;
unsigned
int
num_bd
;
unsigned
int
bd_size
;
void
*
priv
;
};
#define BCOM_FLAGS_NONE 0x00000000ul
#define BCOM_FLAGS_ENABLE_TASK (1ul << 0)
/**
* bcom_enable - Enable a BestComm task
* @tsk: The BestComm task structure
*
* This function makes sure the given task is enabled and can be run
* by the BestComm engine as needed
*/
extern
void
bcom_enable
(
struct
bcom_task
*
tsk
);
/**
* bcom_disable - Disable a BestComm task
* @tsk: The BestComm task structure
*
* This function disable a given task, making sure it's not executed
* by the BestComm engine.
*/
extern
void
bcom_disable
(
struct
bcom_task
*
tsk
);
/**
* bcom_get_task_irq - Returns the irq number of a BestComm task
* @tsk: The BestComm task structure
*/
static
inline
int
bcom_get_task_irq
(
struct
bcom_task
*
tsk
)
{
return
tsk
->
irq
;
}
/* ======================================================================== */
/* BD based tasks helpers */
/* ======================================================================== */
/**
* struct bcom_bd - Structure describing a generic BestComm buffer descriptor
* @status: The current status of this buffer. Exact meaning depends on the
* task type
* @data: An array of u32 whose meaning depends on the task type.
*/
struct
bcom_bd
{
u32
status
;
u32
data
[
1
];
/* variable, but at least 1 */
};
#define BCOM_BD_READY 0x40000000ul
/** _bcom_next_index - Get next input index.
* @tsk: pointer to task structure
*
* Support function; Device drivers should not call this
*/
static
inline
int
_bcom_next_index
(
struct
bcom_task
*
tsk
)
{
return
((
tsk
->
index
+
1
)
==
tsk
->
num_bd
)
?
0
:
tsk
->
index
+
1
;
}
/** _bcom_next_outdex - Get next output index.
* @tsk: pointer to task structure
*
* Support function; Device drivers should not call this
*/
static
inline
int
_bcom_next_outdex
(
struct
bcom_task
*
tsk
)
{
return
((
tsk
->
outdex
+
1
)
==
tsk
->
num_bd
)
?
0
:
tsk
->
outdex
+
1
;
}
/**
* bcom_queue_empty - Checks if a BestComm task BD queue is empty
* @tsk: The BestComm task structure
*/
static
inline
int
bcom_queue_empty
(
struct
bcom_task
*
tsk
)
{
return
tsk
->
index
==
tsk
->
outdex
;
}
/**
* bcom_queue_full - Checks if a BestComm task BD queue is full
* @tsk: The BestComm task structure
*/
static
inline
int
bcom_queue_full
(
struct
bcom_task
*
tsk
)
{
return
tsk
->
outdex
==
_bcom_next_index
(
tsk
);
}
/**
* bcom_buffer_done - Checks if a BestComm
* @tsk: The BestComm task structure
*/
static
inline
int
bcom_buffer_done
(
struct
bcom_task
*
tsk
)
{
if
(
bcom_queue_empty
(
tsk
))
return
0
;
return
!
(
tsk
->
bd
[
tsk
->
outdex
].
status
&
BCOM_BD_READY
);
}
/**
* bcom_prepare_next_buffer - clear status of next available buffer.
* @tsk: The BestComm task structure
*
* Returns pointer to next buffer descriptor
*/
static
inline
struct
bcom_bd
*
bcom_prepare_next_buffer
(
struct
bcom_task
*
tsk
)
{
tsk
->
bd
[
tsk
->
index
].
status
=
0
;
/* cleanup last status */
return
&
tsk
->
bd
[
tsk
->
index
];
}
static
inline
void
bcom_submit_next_buffer
(
struct
bcom_task
*
tsk
,
void
*
cookie
)
{
tsk
->
cookie
[
tsk
->
index
]
=
cookie
;
mb
();
/* ensure the bd is really up-to-date */
tsk
->
bd
[
tsk
->
index
].
status
|=
BCOM_BD_READY
;
tsk
->
index
=
_bcom_next_index
(
tsk
);
if
(
tsk
->
flags
&
BCOM_FLAGS_ENABLE_TASK
)
bcom_enable
(
tsk
);
}
static
inline
void
*
bcom_retrieve_buffer
(
struct
bcom_task
*
tsk
,
u32
*
p_status
,
struct
bcom_bd
**
p_bd
)
{
void
*
cookie
=
tsk
->
cookie
[
tsk
->
outdex
];
if
(
p_status
)
*
p_status
=
tsk
->
bd
[
tsk
->
outdex
].
status
;
if
(
p_bd
)
*
p_bd
=
&
tsk
->
bd
[
tsk
->
outdex
];
tsk
->
outdex
=
_bcom_next_outdex
(
tsk
);
return
cookie
;
}
#endif
/* __BESTCOMM_H__ */
arch/powerpc/sysdev/bestcomm/bestcomm_priv.h
0 → 100644
View file @
4acadb96
/*
* Private header for the MPC52xx processor BestComm driver
*
* By private, we mean that driver should not use it directly. It's meant
* to be used by the BestComm engine driver itself and by the intermediate
* layer between the core and the drivers.
*
* Copyright (C) 2006 Sylvain Munaut <tnt@246tNt.com>
* Copyright (C) 2005 Varma Electronics Oy,
* ( by Andrey Volkov <avolkov@varma-el.com> )
* Copyright (C) 2003-2004 MontaVista, Software, Inc.
* ( by Dale Farnsworth <dfarnsworth@mvista.com> )
*
* This file is licensed under the terms of the GNU General Public License
* version 2. This program is licensed "as is" without any warranty of any
* kind, whether express or implied.
*/
#ifndef __BESTCOMM_PRIV_H__
#define __BESTCOMM_PRIV_H__
#include <linux/spinlock.h>
#include <linux/of.h>
#include <asm/io.h>
#include <asm/mpc52xx.h>
#include "sram.h"
/* ======================================================================== */
/* Engine related stuff */
/* ======================================================================== */
/* Zones sizes and needed alignments */
#define BCOM_MAX_TASKS 16
#define BCOM_MAX_VAR 24
#define BCOM_MAX_INC 8
#define BCOM_MAX_FDT 64
#define BCOM_MAX_CTX 20
#define BCOM_CTX_SIZE (BCOM_MAX_CTX * sizeof(u32))
#define BCOM_CTX_ALIGN 0x100
#define BCOM_VAR_SIZE (BCOM_MAX_VAR * sizeof(u32))
#define BCOM_INC_SIZE (BCOM_MAX_INC * sizeof(u32))
#define BCOM_VAR_ALIGN 0x80
#define BCOM_FDT_SIZE (BCOM_MAX_FDT * sizeof(u32))
#define BCOM_FDT_ALIGN 0x100
/**
* struct bcom_tdt - Task Descriptor Table Entry
*
*/
struct
bcom_tdt
{
u32
start
;
u32
stop
;
u32
var
;
u32
fdt
;
u32
exec_status
;
/* used internally by BestComm engine */
u32
mvtp
;
/* used internally by BestComm engine */
u32
context
;
u32
litbase
;
};
/**
* struct bcom_engine
*
* This holds all info needed globaly to handle the engine
*/
struct
bcom_engine
{
struct
device_node
*
ofnode
;
struct
mpc52xx_sdma
__iomem
*
regs
;
phys_addr_t
regs_base
;
struct
bcom_tdt
*
tdt
;
u32
*
ctx
;
u32
*
var
;
u32
*
fdt
;
spinlock_t
lock
;
};
extern
struct
bcom_engine
*
bcom_eng
;
/* ======================================================================== */
/* Tasks related stuff */
/* ======================================================================== */
/* Tasks image header */
#define BCOM_TASK_MAGIC 0x4243544B
/* 'BCTK' */
struct
bcom_task_header
{
u32
magic
;
u8
desc_size
;
/* the size fields */
u8
var_size
;
/* are given in number */
u8
inc_size
;
/* of 32-bits words */
u8
first_var
;
u8
reserved
[
8
];
};
/* Descriptors stucture & co */
#define BCOM_DESC_NOP 0x000001f8
#define BCOM_LCD_MASK 0x80000000
#define BCOM_DRD_EXTENDED 0x40000000
#define BCOM_DRD_INITIATOR_SHIFT 21
/* Tasks pragma */
#define BCOM_PRAGMA_BIT_RSV 7
/* reserved pragma bit */
#define BCOM_PRAGMA_BIT_PRECISE_INC 6
/* increment 0=when possible, */
/* 1=iter end */
#define BCOM_PRAGMA_BIT_RST_ERROR_NO 5
/* don't reset errors on */
/* task enable */
#define BCOM_PRAGMA_BIT_PACK 4
/* pack data enable */
#define BCOM_PRAGMA_BIT_INTEGER 3
/* data alignment */
/* 0=frac(msb), 1=int(lsb) */
#define BCOM_PRAGMA_BIT_SPECREAD 2
/* XLB speculative read */
#define BCOM_PRAGMA_BIT_CW 1
/* write line buffer enable */
#define BCOM_PRAGMA_BIT_RL 0
/* read line buffer enable */
/* Looks like XLB speculative read generates XLB errors when a buffer
* is at the end of the physical memory. i.e. when accessing the
* lasts words, the engine tries to prefetch the next but there is no
* next ...
*/
#define BCOM_STD_PRAGMA ((0 << BCOM_PRAGMA_BIT_RSV) | \
(0 << BCOM_PRAGMA_BIT_PRECISE_INC) | \
(0 << BCOM_PRAGMA_BIT_RST_ERROR_NO) | \
(0 << BCOM_PRAGMA_BIT_PACK) | \
(0 << BCOM_PRAGMA_BIT_INTEGER) | \
(0 << BCOM_PRAGMA_BIT_SPECREAD) | \
(1 << BCOM_PRAGMA_BIT_CW) | \
(1 << BCOM_PRAGMA_BIT_RL))
#define BCOM_PCI_PRAGMA ((0 << BCOM_PRAGMA_BIT_RSV) | \
(0 << BCOM_PRAGMA_BIT_PRECISE_INC) | \
(0 << BCOM_PRAGMA_BIT_RST_ERROR_NO) | \
(0 << BCOM_PRAGMA_BIT_PACK) | \
(1 << BCOM_PRAGMA_BIT_INTEGER) | \
(0 << BCOM_PRAGMA_BIT_SPECREAD) | \
(1 << BCOM_PRAGMA_BIT_CW) | \
(1 << BCOM_PRAGMA_BIT_RL))
#define BCOM_ATA_PRAGMA BCOM_STD_PRAGMA
#define BCOM_CRC16_DP_0_PRAGMA BCOM_STD_PRAGMA
#define BCOM_CRC16_DP_1_PRAGMA BCOM_STD_PRAGMA
#define BCOM_FEC_RX_BD_PRAGMA BCOM_STD_PRAGMA
#define BCOM_FEC_TX_BD_PRAGMA BCOM_STD_PRAGMA
#define BCOM_GEN_DP_0_PRAGMA BCOM_STD_PRAGMA
#define BCOM_GEN_DP_1_PRAGMA BCOM_STD_PRAGMA
#define BCOM_GEN_DP_2_PRAGMA BCOM_STD_PRAGMA
#define BCOM_GEN_DP_3_PRAGMA BCOM_STD_PRAGMA
#define BCOM_GEN_DP_BD_0_PRAGMA BCOM_STD_PRAGMA
#define BCOM_GEN_DP_BD_1_PRAGMA BCOM_STD_PRAGMA
#define BCOM_GEN_RX_BD_PRAGMA BCOM_STD_PRAGMA
#define BCOM_GEN_TX_BD_PRAGMA BCOM_STD_PRAGMA
#define BCOM_GEN_LPC_PRAGMA BCOM_STD_PRAGMA
#define BCOM_PCI_RX_PRAGMA BCOM_PCI_PRAGMA
#define BCOM_PCI_TX_PRAGMA BCOM_PCI_PRAGMA
/* Initiators number */
#define BCOM_INITIATOR_ALWAYS 0
#define BCOM_INITIATOR_SCTMR_0 1
#define BCOM_INITIATOR_SCTMR_1 2
#define BCOM_INITIATOR_FEC_RX 3
#define BCOM_INITIATOR_FEC_TX 4
#define BCOM_INITIATOR_ATA_RX 5
#define BCOM_INITIATOR_ATA_TX 6
#define BCOM_INITIATOR_SCPCI_RX 7
#define BCOM_INITIATOR_SCPCI_TX 8
#define BCOM_INITIATOR_PSC3_RX 9
#define BCOM_INITIATOR_PSC3_TX 10
#define BCOM_INITIATOR_PSC2_RX 11
#define BCOM_INITIATOR_PSC2_TX 12
#define BCOM_INITIATOR_PSC1_RX 13
#define BCOM_INITIATOR_PSC1_TX 14
#define BCOM_INITIATOR_SCTMR_2 15
#define BCOM_INITIATOR_SCLPC 16
#define BCOM_INITIATOR_PSC5_RX 17
#define BCOM_INITIATOR_PSC5_TX 18
#define BCOM_INITIATOR_PSC4_RX 19
#define BCOM_INITIATOR_PSC4_TX 20
#define BCOM_INITIATOR_I2C2_RX 21
#define BCOM_INITIATOR_I2C2_TX 22
#define BCOM_INITIATOR_I2C1_RX 23
#define BCOM_INITIATOR_I2C1_TX 24
#define BCOM_INITIATOR_PSC6_RX 25
#define BCOM_INITIATOR_PSC6_TX 26
#define BCOM_INITIATOR_IRDA_RX 25
#define BCOM_INITIATOR_IRDA_TX 26
#define BCOM_INITIATOR_SCTMR_3 27
#define BCOM_INITIATOR_SCTMR_4 28
#define BCOM_INITIATOR_SCTMR_5 29
#define BCOM_INITIATOR_SCTMR_6 30
#define BCOM_INITIATOR_SCTMR_7 31
/* Initiators priorities */
#define BCOM_IPR_ALWAYS 7
#define BCOM_IPR_SCTMR_0 2
#define BCOM_IPR_SCTMR_1 2
#define BCOM_IPR_FEC_RX 6
#define BCOM_IPR_FEC_TX 5
#define BCOM_IPR_ATA_RX 4
#define BCOM_IPR_ATA_TX 3
#define BCOM_IPR_SCPCI_RX 2
#define BCOM_IPR_SCPCI_TX 2
#define BCOM_IPR_PSC3_RX 2
#define BCOM_IPR_PSC3_TX 2
#define BCOM_IPR_PSC2_RX 2
#define BCOM_IPR_PSC2_TX 2
#define BCOM_IPR_PSC1_RX 2
#define BCOM_IPR_PSC1_TX 2
#define BCOM_IPR_SCTMR_2 2
#define BCOM_IPR_SCLPC 2
#define BCOM_IPR_PSC5_RX 2
#define BCOM_IPR_PSC5_TX 2
#define BCOM_IPR_PSC4_RX 2
#define BCOM_IPR_PSC4_TX 2
#define BCOM_IPR_I2C2_RX 2
#define BCOM_IPR_I2C2_TX 2
#define BCOM_IPR_I2C1_RX 2
#define BCOM_IPR_I2C1_TX 2
#define BCOM_IPR_PSC6_RX 2
#define BCOM_IPR_PSC6_TX 2
#define BCOM_IPR_IRDA_RX 2
#define BCOM_IPR_IRDA_TX 2
#define BCOM_IPR_SCTMR_3 2
#define BCOM_IPR_SCTMR_4 2
#define BCOM_IPR_SCTMR_5 2
#define BCOM_IPR_SCTMR_6 2
#define BCOM_IPR_SCTMR_7 2
/* ======================================================================== */
/* API */
/* ======================================================================== */
extern
struct
bcom_task
*
bcom_task_alloc
(
int
bd_count
,
int
bd_size
,
int
priv_size
);
extern
void
bcom_task_free
(
struct
bcom_task
*
tsk
);
extern
int
bcom_load_image
(
int
task
,
u32
*
task_image
);
extern
void
bcom_set_initiator
(
int
task
,
int
initiator
);
#define TASK_ENABLE 0x8000
static
inline
void
bcom_enable_task
(
int
task
)
{
u16
reg
;
reg
=
in_be16
(
&
bcom_eng
->
regs
->
tcr
[
task
]);
out_be16
(
&
bcom_eng
->
regs
->
tcr
[
task
],
reg
|
TASK_ENABLE
);
}
static
inline
void
bcom_disable_task
(
int
task
)
{
u16
reg
=
in_be16
(
&
bcom_eng
->
regs
->
tcr
[
task
]);
out_be16
(
&
bcom_eng
->
regs
->
tcr
[
task
],
reg
&
~
TASK_ENABLE
);
}
static
inline
u32
*
bcom_task_desc
(
int
task
)
{
return
bcom_sram_pa2va
(
bcom_eng
->
tdt
[
task
].
start
);
}
static
inline
int
bcom_task_num_descs
(
int
task
)
{
return
(
bcom_eng
->
tdt
[
task
].
stop
-
bcom_eng
->
tdt
[
task
].
start
)
/
sizeof
(
u32
)
+
1
;
}
static
inline
u32
*
bcom_task_var
(
int
task
)
{
return
bcom_sram_pa2va
(
bcom_eng
->
tdt
[
task
].
var
);
}
static
inline
u32
*
bcom_task_inc
(
int
task
)
{
return
&
bcom_task_var
(
task
)[
BCOM_MAX_VAR
];
}
static
inline
int
bcom_drd_is_extended
(
u32
desc
)
{
return
(
desc
)
&
BCOM_DRD_EXTENDED
;
}
static
inline
int
bcom_desc_is_drd
(
u32
desc
)
{
return
!
(
desc
&
BCOM_LCD_MASK
)
&&
desc
!=
BCOM_DESC_NOP
;
}
static
inline
int
bcom_desc_initiator
(
u32
desc
)
{
return
(
desc
>>
BCOM_DRD_INITIATOR_SHIFT
)
&
0x1f
;
}
static
inline
void
bcom_set_desc_initiator
(
u32
*
desc
,
int
initiator
)
{
*
desc
=
(
*
desc
&
~
(
0x1f
<<
BCOM_DRD_INITIATOR_SHIFT
))
|
((
initiator
&
0x1f
)
<<
BCOM_DRD_INITIATOR_SHIFT
);
}
static
inline
void
bcom_set_task_pragma
(
int
task
,
int
pragma
)
{
u32
*
fdt
=
&
bcom_eng
->
tdt
[
task
].
fdt
;
*
fdt
=
(
*
fdt
&
~
0xff
)
|
pragma
;
}
static
inline
void
bcom_set_task_auto_start
(
int
task
,
int
next_task
)
{
u16
__iomem
*
tcr
=
&
bcom_eng
->
regs
->
tcr
[
task
];
out_be16
(
tcr
,
(
in_be16
(
tcr
)
&
~
0xff
)
|
0x00c0
|
next_task
);
}
static
inline
void
bcom_set_tcr_initiator
(
int
task
,
int
initiator
)
{
u16
__iomem
*
tcr
=
&
bcom_eng
->
regs
->
tcr
[
task
];
out_be16
(
tcr
,
(
in_be16
(
tcr
)
&
~
0x1f00
)
|
((
initiator
&
0x1f
)
<<
8
));
}
#endif
/* __BESTCOMM_PRIV_H__ */
arch/powerpc/sysdev/bestcomm/fec.c
0 → 100644
View file @
4acadb96
/*
* Bestcomm FEC tasks driver
*
*
* Copyright (C) 2006-2007 Sylvain Munaut <tnt@246tNt.com>
* Copyright (C) 2003-2004 MontaVista, Software, Inc.
* ( by Dale Farnsworth <dfarnsworth@mvista.com> )
*
* This file is licensed under the terms of the GNU General Public License
* version 2. This program is licensed "as is" without any warranty of any
* kind, whether express or implied.
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/types.h>
#include <asm/io.h>
#include "bestcomm.h"
#include "bestcomm_priv.h"
#include "fec.h"
/* ======================================================================== */
/* Task image/var/inc */
/* ======================================================================== */
/* fec tasks images */
extern
u32
bcom_fec_rx_task
[];
extern
u32
bcom_fec_tx_task
[];
/* rx task vars that need to be set before enabling the task */
struct
bcom_fec_rx_var
{
u32
enable
;
/* (u16*) address of task's control register */
u32
fifo
;
/* (u32*) address of fec's fifo */
u32
bd_base
;
/* (struct bcom_bd*) beginning of ring buffer */
u32
bd_last
;
/* (struct bcom_bd*) end of ring buffer */
u32
bd_start
;
/* (struct bcom_bd*) current bd */
u32
buffer_size
;
/* size of receive buffer */
};
/* rx task incs that need to be set before enabling the task */
struct
bcom_fec_rx_inc
{
u16
pad0
;
s16
incr_bytes
;
u16
pad1
;
s16
incr_dst
;
u16
pad2
;
s16
incr_dst_ma
;
};
/* tx task vars that need to be set before enabling the task */
struct
bcom_fec_tx_var
{
u32
DRD
;
/* (u32*) address of self-modified DRD */
u32
fifo
;
/* (u32*) address of fec's fifo */
u32
enable
;
/* (u16*) address of task's control register */
u32
bd_base
;
/* (struct bcom_bd*) beginning of ring buffer */
u32
bd_last
;
/* (struct bcom_bd*) end of ring buffer */
u32
bd_start
;
/* (struct bcom_bd*) current bd */
u32
buffer_size
;
/* set by uCode for each packet */
};
/* tx task incs that need to be set before enabling the task */
struct
bcom_fec_tx_inc
{
u16
pad0
;
s16
incr_bytes
;
u16
pad1
;
s16
incr_src
;
u16
pad2
;
s16
incr_src_ma
;
};
/* private structure in the task */
struct
bcom_fec_priv
{
phys_addr_t
fifo
;
int
maxbufsize
;
};
/* ======================================================================== */
/* Task support code */
/* ======================================================================== */
struct
bcom_task
*
bcom_fec_rx_init
(
int
queue_len
,
phys_addr_t
fifo
,
int
maxbufsize
)
{
struct
bcom_task
*
tsk
;
struct
bcom_fec_priv
*
priv
;
tsk
=
bcom_task_alloc
(
queue_len
,
sizeof
(
struct
bcom_fec_bd
),
sizeof
(
struct
bcom_fec_priv
));
if
(
!
tsk
)
return
NULL
;
tsk
->
flags
=
BCOM_FLAGS_NONE
;
priv
=
tsk
->
priv
;
priv
->
fifo
=
fifo
;
priv
->
maxbufsize
=
maxbufsize
;
if
(
bcom_fec_rx_reset
(
tsk
))
{
bcom_task_free
(
tsk
);
return
NULL
;
}
return
tsk
;
}
EXPORT_SYMBOL_GPL
(
bcom_fec_rx_init
);
int
bcom_fec_rx_reset
(
struct
bcom_task
*
tsk
)
{
struct
bcom_fec_priv
*
priv
=
tsk
->
priv
;
struct
bcom_fec_rx_var
*
var
;
struct
bcom_fec_rx_inc
*
inc
;
/* Shutdown the task */
bcom_disable_task
(
tsk
->
tasknum
);
/* Reset the microcode */
var
=
(
struct
bcom_fec_rx_var
*
)
bcom_task_var
(
tsk
->
tasknum
);
inc
=
(
struct
bcom_fec_rx_inc
*
)
bcom_task_inc
(
tsk
->
tasknum
);
if
(
bcom_load_image
(
tsk
->
tasknum
,
bcom_fec_rx_task
))
return
-
1
;
var
->
enable
=
bcom_eng
->
regs_base
+
offsetof
(
struct
mpc52xx_sdma
,
tcr
[
tsk
->
tasknum
]);
var
->
fifo
=
(
u32
)
priv
->
fifo
;
var
->
bd_base
=
tsk
->
bd_pa
;
var
->
bd_last
=
tsk
->
bd_pa
+
((
tsk
->
num_bd
-
1
)
*
tsk
->
bd_size
);
var
->
bd_start
=
tsk
->
bd_pa
;
var
->
buffer_size
=
priv
->
maxbufsize
;
inc
->
incr_bytes
=
-
(
s16
)
sizeof
(
u32
);
/* These should be in the */
inc
->
incr_dst
=
sizeof
(
u32
);
/* task image, but we stick */
inc
->
incr_dst_ma
=
sizeof
(
u8
);
/* to the official ones */
/* Reset the BDs */
tsk
->
index
=
0
;
tsk
->
outdex
=
0
;
memset
(
tsk
->
bd
,
0x00
,
tsk
->
num_bd
*
tsk
->
bd_size
);
/* Configure some stuff */
bcom_set_task_pragma
(
tsk
->
tasknum
,
BCOM_FEC_RX_BD_PRAGMA
);
bcom_set_task_auto_start
(
tsk
->
tasknum
,
tsk
->
tasknum
);
out_8
(
&
bcom_eng
->
regs
->
ipr
[
BCOM_INITIATOR_FEC_RX
],
BCOM_IPR_FEC_RX
);
out_be32
(
&
bcom_eng
->
regs
->
IntPend
,
1
<<
tsk
->
tasknum
);
/* Clear ints */
return
0
;
}
EXPORT_SYMBOL_GPL
(
bcom_fec_rx_reset
);
void
bcom_fec_rx_release
(
struct
bcom_task
*
tsk
)
{
/* Nothing special for the FEC tasks */
bcom_task_free
(
tsk
);
}
EXPORT_SYMBOL_GPL
(
bcom_fec_rx_release
);
/* Return 2nd to last DRD */
/* This is an ugly hack, but at least it's only done
once at initialization */
static
u32
*
self_modified_drd
(
int
tasknum
)
{
u32
*
desc
;
int
num_descs
;
int
drd_count
;
int
i
;
num_descs
=
bcom_task_num_descs
(
tasknum
);
desc
=
bcom_task_desc
(
tasknum
)
+
num_descs
-
1
;
drd_count
=
0
;
for
(
i
=
0
;
i
<
num_descs
;
i
++
,
desc
--
)
if
(
bcom_desc_is_drd
(
*
desc
)
&&
++
drd_count
==
3
)
break
;
return
desc
;
}
struct
bcom_task
*
bcom_fec_tx_init
(
int
queue_len
,
phys_addr_t
fifo
)
{
struct
bcom_task
*
tsk
;
struct
bcom_fec_priv
*
priv
;
tsk
=
bcom_task_alloc
(
queue_len
,
sizeof
(
struct
bcom_fec_bd
),
sizeof
(
struct
bcom_fec_priv
));
if
(
!
tsk
)
return
NULL
;
tsk
->
flags
=
BCOM_FLAGS_ENABLE_TASK
;
priv
=
tsk
->
priv
;
priv
->
fifo
=
fifo
;
if
(
bcom_fec_tx_reset
(
tsk
))
{
bcom_task_free
(
tsk
);
return
NULL
;
}
return
tsk
;
}
EXPORT_SYMBOL_GPL
(
bcom_fec_tx_init
);
int
bcom_fec_tx_reset
(
struct
bcom_task
*
tsk
)
{
struct
bcom_fec_priv
*
priv
=
tsk
->
priv
;
struct
bcom_fec_tx_var
*
var
;
struct
bcom_fec_tx_inc
*
inc
;
/* Shutdown the task */
bcom_disable_task
(
tsk
->
tasknum
);
/* Reset the microcode */
var
=
(
struct
bcom_fec_tx_var
*
)
bcom_task_var
(
tsk
->
tasknum
);
inc
=
(
struct
bcom_fec_tx_inc
*
)
bcom_task_inc
(
tsk
->
tasknum
);
if
(
bcom_load_image
(
tsk
->
tasknum
,
bcom_fec_tx_task
))
return
-
1
;
var
->
enable
=
bcom_eng
->
regs_base
+
offsetof
(
struct
mpc52xx_sdma
,
tcr
[
tsk
->
tasknum
]);
var
->
fifo
=
(
u32
)
priv
->
fifo
;
var
->
DRD
=
bcom_sram_va2pa
(
self_modified_drd
(
tsk
->
tasknum
));
var
->
bd_base
=
tsk
->
bd_pa
;
var
->
bd_last
=
tsk
->
bd_pa
+
((
tsk
->
num_bd
-
1
)
*
tsk
->
bd_size
);
var
->
bd_start
=
tsk
->
bd_pa
;
inc
->
incr_bytes
=
-
(
s16
)
sizeof
(
u32
);
/* These should be in the */
inc
->
incr_src
=
sizeof
(
u32
);
/* task image, but we stick */
inc
->
incr_src_ma
=
sizeof
(
u8
);
/* to the official ones */
/* Reset the BDs */
tsk
->
index
=
0
;
tsk
->
outdex
=
0
;
memset
(
tsk
->
bd
,
0x00
,
tsk
->
num_bd
*
tsk
->
bd_size
);
/* Configure some stuff */
bcom_set_task_pragma
(
tsk
->
tasknum
,
BCOM_FEC_TX_BD_PRAGMA
);
bcom_set_task_auto_start
(
tsk
->
tasknum
,
tsk
->
tasknum
);
out_8
(
&
bcom_eng
->
regs
->
ipr
[
BCOM_INITIATOR_FEC_TX
],
BCOM_IPR_FEC_TX
);
out_be32
(
&
bcom_eng
->
regs
->
IntPend
,
1
<<
tsk
->
tasknum
);
/* Clear ints */
return
0
;
}
EXPORT_SYMBOL_GPL
(
bcom_fec_tx_reset
);
void
bcom_fec_tx_release
(
struct
bcom_task
*
tsk
)
{
/* Nothing special for the FEC tasks */
bcom_task_free
(
tsk
);
}
EXPORT_SYMBOL_GPL
(
bcom_fec_tx_release
);
MODULE_DESCRIPTION
(
"BestComm FEC tasks driver"
);
MODULE_AUTHOR
(
"Dale Farnsworth <dfarnsworth@mvista.com>"
);
MODULE_LICENSE
(
"GPL v2"
);
arch/powerpc/sysdev/bestcomm/fec.h
0 → 100644
View file @
4acadb96
/*
* Header for Bestcomm FEC tasks driver
*
*
* Copyright (C) 2006-2007 Sylvain Munaut <tnt@246tNt.com>
* Copyright (C) 2003-2004 MontaVista, Software, Inc.
* ( by Dale Farnsworth <dfarnsworth@mvista.com> )
*
* This file is licensed under the terms of the GNU General Public License
* version 2. This program is licensed "as is" without any warranty of any
* kind, whether express or implied.
*/
#ifndef __BESTCOMM_FEC_H__
#define __BESTCOMM_FEC_H__
struct
bcom_fec_bd
{
u32
status
;
u32
skb_pa
;
};
#define BCOM_FEC_TX_BD_TFD 0x08000000ul
/* transmit frame done */
#define BCOM_FEC_TX_BD_TC 0x04000000ul
/* transmit CRC */
#define BCOM_FEC_TX_BD_ABC 0x02000000ul
/* append bad CRC */
#define BCOM_FEC_RX_BD_L 0x08000000ul
/* buffer is last in frame */
#define BCOM_FEC_RX_BD_BC 0x00800000ul
/* DA is broadcast */
#define BCOM_FEC_RX_BD_MC 0x00400000ul
/* DA is multicast and not broadcast */
#define BCOM_FEC_RX_BD_LG 0x00200000ul
/* Rx frame length violation */
#define BCOM_FEC_RX_BD_NO 0x00100000ul
/* Rx non-octet aligned frame */
#define BCOM_FEC_RX_BD_CR 0x00040000ul
/* Rx CRC error */
#define BCOM_FEC_RX_BD_OV 0x00020000ul
/* overrun */
#define BCOM_FEC_RX_BD_TR 0x00010000ul
/* Rx frame truncated */
#define BCOM_FEC_RX_BD_LEN_MASK 0x000007fful
/* mask for length of received frame */
#define BCOM_FEC_RX_BD_ERRORS (BCOM_FEC_RX_BD_LG | BCOM_FEC_RX_BD_NO | \
BCOM_FEC_RX_BD_CR | BCOM_FEC_RX_BD_OV | BCOM_FEC_RX_BD_TR)
extern
struct
bcom_task
*
bcom_fec_rx_init
(
int
queue_len
,
phys_addr_t
fifo
,
int
maxbufsize
);
extern
int
bcom_fec_rx_reset
(
struct
bcom_task
*
tsk
);
extern
void
bcom_fec_rx_release
(
struct
bcom_task
*
tsk
);
extern
struct
bcom_task
*
bcom_fec_tx_init
(
int
queue_len
,
phys_addr_t
fifo
);
extern
int
bcom_fec_tx_reset
(
struct
bcom_task
*
tsk
);
extern
void
bcom_fec_tx_release
(
struct
bcom_task
*
tsk
);
#endif
/* __BESTCOMM_FEC_H__ */
arch/powerpc/sysdev/bestcomm/gen_bd.c
0 → 100644
View file @
4acadb96
/*
* Driver for MPC52xx processor BestComm General Buffer Descriptor
*
* Copyright (C) 2007 Sylvain Munaut <tnt@246tNt.com>
* Copyright (C) 2006 AppSpec Computer Technologies Corp.
* Jeff Gibbons <jeff.gibbons@appspec.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*
*/
#include <linux/version.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/types.h>
#include <asm/errno.h>
#include <asm/io.h>
#include <asm/mpc52xx.h>
#include "bestcomm.h"
#include "bestcomm_priv.h"
#include "gen_bd.h"
/* ======================================================================== */
/* Task image/var/inc */
/* ======================================================================== */
/* gen_bd tasks images */
extern
u32
bcom_gen_bd_rx_task
[];
extern
u32
bcom_gen_bd_tx_task
[];
/* rx task vars that need to be set before enabling the task */
struct
bcom_gen_bd_rx_var
{
u32
enable
;
/* (u16*) address of task's control register */
u32
fifo
;
/* (u32*) address of gen_bd's fifo */
u32
bd_base
;
/* (struct bcom_bd*) beginning of ring buffer */
u32
bd_last
;
/* (struct bcom_bd*) end of ring buffer */
u32
bd_start
;
/* (struct bcom_bd*) current bd */
u32
buffer_size
;
/* size of receive buffer */
};
/* rx task incs that need to be set before enabling the task */
struct
bcom_gen_bd_rx_inc
{
u16
pad0
;
s16
incr_bytes
;
u16
pad1
;
s16
incr_dst
;
};
/* tx task vars that need to be set before enabling the task */
struct
bcom_gen_bd_tx_var
{
u32
fifo
;
/* (u32*) address of gen_bd's fifo */
u32
enable
;
/* (u16*) address of task's control register */
u32
bd_base
;
/* (struct bcom_bd*) beginning of ring buffer */
u32
bd_last
;
/* (struct bcom_bd*) end of ring buffer */
u32
bd_start
;
/* (struct bcom_bd*) current bd */
u32
buffer_size
;
/* set by uCode for each packet */
};
/* tx task incs that need to be set before enabling the task */
struct
bcom_gen_bd_tx_inc
{
u16
pad0
;
s16
incr_bytes
;
u16
pad1
;
s16
incr_src
;
u16
pad2
;
s16
incr_src_ma
;
};
/* private structure */
struct
bcom_gen_bd_priv
{
phys_addr_t
fifo
;
int
initiator
;
int
ipr
;
int
maxbufsize
;
};
/* ======================================================================== */
/* Task support code */
/* ======================================================================== */
struct
bcom_task
*
bcom_gen_bd_rx_init
(
int
queue_len
,
phys_addr_t
fifo
,
int
initiator
,
int
ipr
,
int
maxbufsize
)
{
struct
bcom_task
*
tsk
;
struct
bcom_gen_bd_priv
*
priv
;
tsk
=
bcom_task_alloc
(
queue_len
,
sizeof
(
struct
bcom_gen_bd
),
sizeof
(
struct
bcom_gen_bd_priv
));
if
(
!
tsk
)
return
NULL
;
tsk
->
flags
=
BCOM_FLAGS_NONE
;
priv
=
tsk
->
priv
;
priv
->
fifo
=
fifo
;
priv
->
initiator
=
initiator
;
priv
->
ipr
=
ipr
;
priv
->
maxbufsize
=
maxbufsize
;
if
(
bcom_gen_bd_rx_reset
(
tsk
))
{
bcom_task_free
(
tsk
);
return
NULL
;
}
return
tsk
;
}
EXPORT_SYMBOL_GPL
(
bcom_gen_bd_rx_init
);
int
bcom_gen_bd_rx_reset
(
struct
bcom_task
*
tsk
)
{
struct
bcom_gen_bd_priv
*
priv
=
tsk
->
priv
;
struct
bcom_gen_bd_rx_var
*
var
;
struct
bcom_gen_bd_rx_inc
*
inc
;
/* Shutdown the task */
bcom_disable_task
(
tsk
->
tasknum
);
/* Reset the microcode */
var
=
(
struct
bcom_gen_bd_rx_var
*
)
bcom_task_var
(
tsk
->
tasknum
);
inc
=
(
struct
bcom_gen_bd_rx_inc
*
)
bcom_task_inc
(
tsk
->
tasknum
);
if
(
bcom_load_image
(
tsk
->
tasknum
,
bcom_gen_bd_rx_task
))
return
-
1
;
var
->
enable
=
bcom_eng
->
regs_base
+
offsetof
(
struct
mpc52xx_sdma
,
tcr
[
tsk
->
tasknum
]);
var
->
fifo
=
(
u32
)
priv
->
fifo
;
var
->
bd_base
=
tsk
->
bd_pa
;
var
->
bd_last
=
tsk
->
bd_pa
+
((
tsk
->
num_bd
-
1
)
*
tsk
->
bd_size
);
var
->
bd_start
=
tsk
->
bd_pa
;
var
->
buffer_size
=
priv
->
maxbufsize
;
inc
->
incr_bytes
=
-
(
s16
)
sizeof
(
u32
);
inc
->
incr_dst
=
sizeof
(
u32
);
/* Reset the BDs */
tsk
->
index
=
0
;
tsk
->
outdex
=
0
;
memset
(
tsk
->
bd
,
0x00
,
tsk
->
num_bd
*
tsk
->
bd_size
);
/* Configure some stuff */
bcom_set_task_pragma
(
tsk
->
tasknum
,
BCOM_GEN_RX_BD_PRAGMA
);
bcom_set_task_auto_start
(
tsk
->
tasknum
,
tsk
->
tasknum
);
out_8
(
&
bcom_eng
->
regs
->
ipr
[
priv
->
initiator
],
priv
->
ipr
);
bcom_set_initiator
(
tsk
->
tasknum
,
priv
->
initiator
);
out_be32
(
&
bcom_eng
->
regs
->
IntPend
,
1
<<
tsk
->
tasknum
);
/* Clear ints */
return
0
;
}
EXPORT_SYMBOL_GPL
(
bcom_gen_bd_rx_reset
);
void
bcom_gen_bd_rx_release
(
struct
bcom_task
*
tsk
)
{
/* Nothing special for the GenBD tasks */
bcom_task_free
(
tsk
);
}
EXPORT_SYMBOL_GPL
(
bcom_gen_bd_rx_release
);
extern
struct
bcom_task
*
bcom_gen_bd_tx_init
(
int
queue_len
,
phys_addr_t
fifo
,
int
initiator
,
int
ipr
)
{
struct
bcom_task
*
tsk
;
struct
bcom_gen_bd_priv
*
priv
;
tsk
=
bcom_task_alloc
(
queue_len
,
sizeof
(
struct
bcom_gen_bd
),
sizeof
(
struct
bcom_gen_bd_priv
));
if
(
!
tsk
)
return
NULL
;
tsk
->
flags
=
BCOM_FLAGS_NONE
;
priv
=
tsk
->
priv
;
priv
->
fifo
=
fifo
;
priv
->
initiator
=
initiator
;
priv
->
ipr
=
ipr
;
if
(
bcom_gen_bd_tx_reset
(
tsk
))
{
bcom_task_free
(
tsk
);
return
NULL
;
}
return
tsk
;
}
EXPORT_SYMBOL_GPL
(
bcom_gen_bd_tx_init
);
int
bcom_gen_bd_tx_reset
(
struct
bcom_task
*
tsk
)
{
struct
bcom_gen_bd_priv
*
priv
=
tsk
->
priv
;
struct
bcom_gen_bd_tx_var
*
var
;
struct
bcom_gen_bd_tx_inc
*
inc
;
/* Shutdown the task */
bcom_disable_task
(
tsk
->
tasknum
);
/* Reset the microcode */
var
=
(
struct
bcom_gen_bd_tx_var
*
)
bcom_task_var
(
tsk
->
tasknum
);
inc
=
(
struct
bcom_gen_bd_tx_inc
*
)
bcom_task_inc
(
tsk
->
tasknum
);
if
(
bcom_load_image
(
tsk
->
tasknum
,
bcom_gen_bd_tx_task
))
return
-
1
;
var
->
enable
=
bcom_eng
->
regs_base
+
offsetof
(
struct
mpc52xx_sdma
,
tcr
[
tsk
->
tasknum
]);
var
->
fifo
=
(
u32
)
priv
->
fifo
;
var
->
bd_base
=
tsk
->
bd_pa
;
var
->
bd_last
=
tsk
->
bd_pa
+
((
tsk
->
num_bd
-
1
)
*
tsk
->
bd_size
);
var
->
bd_start
=
tsk
->
bd_pa
;
inc
->
incr_bytes
=
-
(
s16
)
sizeof
(
u32
);
inc
->
incr_src
=
sizeof
(
u32
);
inc
->
incr_src_ma
=
sizeof
(
u8
);
/* Reset the BDs */
tsk
->
index
=
0
;
tsk
->
outdex
=
0
;
memset
(
tsk
->
bd
,
0x00
,
tsk
->
num_bd
*
tsk
->
bd_size
);
/* Configure some stuff */
bcom_set_task_pragma
(
tsk
->
tasknum
,
BCOM_GEN_TX_BD_PRAGMA
);
bcom_set_task_auto_start
(
tsk
->
tasknum
,
tsk
->
tasknum
);
out_8
(
&
bcom_eng
->
regs
->
ipr
[
priv
->
initiator
],
priv
->
ipr
);
bcom_set_initiator
(
tsk
->
tasknum
,
priv
->
initiator
);
out_be32
(
&
bcom_eng
->
regs
->
IntPend
,
1
<<
tsk
->
tasknum
);
/* Clear ints */
return
0
;
}
EXPORT_SYMBOL_GPL
(
bcom_gen_bd_tx_reset
);
void
bcom_gen_bd_tx_release
(
struct
bcom_task
*
tsk
)
{
/* Nothing special for the GenBD tasks */
bcom_task_free
(
tsk
);
}
EXPORT_SYMBOL_GPL
(
bcom_gen_bd_tx_release
);
MODULE_DESCRIPTION
(
"BestComm General Buffer Descriptor tasks driver"
);
MODULE_AUTHOR
(
"Jeff Gibbons <jeff.gibbons@appspec.com>"
);
MODULE_LICENSE
(
"GPL v2"
);
arch/powerpc/sysdev/bestcomm/gen_bd.h
0 → 100644
View file @
4acadb96
/*
* Header for Bestcomm General Buffer Descriptor tasks driver
*
*
* Copyright (C) 2007 Sylvain Munaut <tnt@246tNt.com>
* Copyright (C) 2006 AppSpec Computer Technologies Corp.
* Jeff Gibbons <jeff.gibbons@appspec.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*
*
*/
#ifndef __BESTCOMM_GEN_BD_H__
#define __BESTCOMM_GEN_BD_H__
struct
bcom_gen_bd
{
u32
status
;
u32
buf_pa
;
};
extern
struct
bcom_task
*
bcom_gen_bd_rx_init
(
int
queue_len
,
phys_addr_t
fifo
,
int
initiator
,
int
ipr
,
int
maxbufsize
);
extern
int
bcom_gen_bd_rx_reset
(
struct
bcom_task
*
tsk
);
extern
void
bcom_gen_bd_rx_release
(
struct
bcom_task
*
tsk
);
extern
struct
bcom_task
*
bcom_gen_bd_tx_init
(
int
queue_len
,
phys_addr_t
fifo
,
int
initiator
,
int
ipr
);
extern
int
bcom_gen_bd_tx_reset
(
struct
bcom_task
*
tsk
);
extern
void
bcom_gen_bd_tx_release
(
struct
bcom_task
*
tsk
);
#endif
/* __BESTCOMM_GEN_BD_H__ */
arch/powerpc/sysdev/bestcomm/sram.c
0 → 100644
View file @
4acadb96
/*
* Simple memory allocator for on-board SRAM
*
*
* Maintainer : Sylvain Munaut <tnt@246tNt.com>
*
* Copyright (C) 2005 Sylvain Munaut <tnt@246tNt.com>
*
* This file is licensed under the terms of the GNU General Public License
* version 2. This program is licensed "as is" without any warranty of any
* kind, whether express or implied.
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/string.h>
#include <linux/ioport.h>
#include <linux/of.h>
#include <asm/io.h>
#include <asm/mmu.h>
#include "sram.h"
/* Struct keeping our 'state' */
struct
bcom_sram
*
bcom_sram
=
NULL
;
EXPORT_SYMBOL_GPL
(
bcom_sram
);
/* needed for inline functions */
/* ======================================================================== */
/* Public API */
/* ======================================================================== */
/* DO NOT USE in interrupts, if needed in irq handler, we should use the
_irqsave version of the spin_locks */
int
bcom_sram_init
(
struct
device_node
*
sram_node
,
char
*
owner
)
{
int
rv
;
const
u32
*
regaddr_p
;
u64
regaddr64
,
size64
;
unsigned
int
psize
;
/* Create our state struct */
if
(
bcom_sram
)
{
printk
(
KERN_ERR
"%s: bcom_sram_init: "
"Already initialized !
\n
"
,
owner
);
return
-
EBUSY
;
}
bcom_sram
=
kmalloc
(
sizeof
(
struct
bcom_sram
),
GFP_KERNEL
);
if
(
!
bcom_sram
)
{
printk
(
KERN_ERR
"%s: bcom_sram_init: "
"Couldn't allocate internal state !
\n
"
,
owner
);
return
-
ENOMEM
;
}
/* Get address and size of the sram */
regaddr_p
=
of_get_address
(
sram_node
,
0
,
&
size64
,
NULL
);
if
(
!
regaddr_p
)
{
printk
(
KERN_ERR
"%s: bcom_sram_init: "
"Invalid device node !
\n
"
,
owner
);
rv
=
-
EINVAL
;
goto
error_free
;
}
regaddr64
=
of_translate_address
(
sram_node
,
regaddr_p
);
bcom_sram
->
base_phys
=
(
phys_addr_t
)
regaddr64
;
bcom_sram
->
size
=
(
unsigned
int
)
size64
;
/* Request region */
if
(
!
request_mem_region
(
bcom_sram
->
base_phys
,
bcom_sram
->
size
,
owner
))
{
printk
(
KERN_ERR
"%s: bcom_sram_init: "
"Couldn't request region !
\n
"
,
owner
);
rv
=
-
EBUSY
;
goto
error_free
;
}
/* Map SRAM */
/* sram is not really __iomem */
bcom_sram
->
base_virt
=
(
void
*
)
ioremap
(
bcom_sram
->
base_phys
,
bcom_sram
->
size
);
if
(
!
bcom_sram
->
base_virt
)
{
printk
(
KERN_ERR
"%s: bcom_sram_init: "
"Map error SRAM zone 0x%08lx (0x%0x)!
\n
"
,
owner
,
bcom_sram
->
base_phys
,
bcom_sram
->
size
);
rv
=
-
ENOMEM
;
goto
error_release
;
}
/* Create an rheap (defaults to 32 bits word alignment) */
bcom_sram
->
rh
=
rh_create
(
4
);
/* Attach the free zones */
#if 0
/* Currently disabled ... for future use only */
reg_addr_p = of_get_property(sram_node, "available", &psize);
#else
regaddr_p
=
NULL
;
psize
=
0
;
#endif
if
(
!
regaddr_p
||
!
psize
)
{
/* Attach the whole zone */
rh_attach_region
(
bcom_sram
->
rh
,
0
,
bcom_sram
->
size
);
}
else
{
/* Attach each zone independently */
while
(
psize
>=
2
*
sizeof
(
u32
))
{
phys_addr_t
zbase
=
of_translate_address
(
sram_node
,
regaddr_p
);
rh_attach_region
(
bcom_sram
->
rh
,
zbase
-
bcom_sram
->
base_phys
,
regaddr_p
[
1
]);
regaddr_p
+=
2
;
psize
-=
2
*
sizeof
(
u32
);
}
}
/* Init our spinlock */
spin_lock_init
(
&
bcom_sram
->
lock
);
return
0
;
error_release:
release_mem_region
(
bcom_sram
->
base_phys
,
bcom_sram
->
size
);
error_free:
kfree
(
bcom_sram
);
bcom_sram
=
NULL
;
return
rv
;
}
EXPORT_SYMBOL_GPL
(
bcom_sram_init
);
void
bcom_sram_cleanup
(
void
)
{
/* Free resources */
if
(
bcom_sram
)
{
rh_destroy
(
bcom_sram
->
rh
);
iounmap
((
void
__iomem
*
)
bcom_sram
->
base_virt
);
release_mem_region
(
bcom_sram
->
base_phys
,
bcom_sram
->
size
);
kfree
(
bcom_sram
);
bcom_sram
=
NULL
;
}
}
EXPORT_SYMBOL_GPL
(
bcom_sram_cleanup
);
void
*
bcom_sram_alloc
(
int
size
,
int
align
,
phys_addr_t
*
phys
)
{
unsigned
long
offset
;
spin_lock
(
&
bcom_sram
->
lock
);
offset
=
rh_alloc_align
(
bcom_sram
->
rh
,
size
,
align
,
NULL
);
spin_unlock
(
&
bcom_sram
->
lock
);
if
(
IS_ERR_VALUE
(
offset
))
return
NULL
;
*
phys
=
bcom_sram
->
base_phys
+
offset
;
return
bcom_sram
->
base_virt
+
offset
;
}
EXPORT_SYMBOL_GPL
(
bcom_sram_alloc
);
void
bcom_sram_free
(
void
*
ptr
)
{
unsigned
long
offset
;
if
(
!
ptr
)
return
;
offset
=
ptr
-
bcom_sram
->
base_virt
;
spin_lock
(
&
bcom_sram
->
lock
);
rh_free
(
bcom_sram
->
rh
,
offset
);
spin_unlock
(
&
bcom_sram
->
lock
);
}
EXPORT_SYMBOL_GPL
(
bcom_sram_free
);
arch/powerpc/sysdev/bestcomm/sram.h
0 → 100644
View file @
4acadb96
/*
* Handling of a sram zone for bestcomm
*
*
* Copyright (C) 2007 Sylvain Munaut <tnt@246tNt.com>
*
* This file is licensed under the terms of the GNU General Public License
* version 2. This program is licensed "as is" without any warranty of any
* kind, whether express or implied.
*/
#ifndef __BESTCOMM_SRAM_H__
#define __BESTCOMM_SRAM_H__
#include <asm/rheap.h>
#include <asm/mmu.h>
#include <linux/spinlock.h>
/* Structure used internally */
/* The internals are here for the inline functions
* sake, certainly not for the user to mess with !
*/
struct
bcom_sram
{
phys_addr_t
base_phys
;
void
*
base_virt
;
unsigned
int
size
;
rh_info_t
*
rh
;
spinlock_t
lock
;
};
extern
struct
bcom_sram
*
bcom_sram
;
/* Public API */
extern
int
bcom_sram_init
(
struct
device_node
*
sram_node
,
char
*
owner
);
extern
void
bcom_sram_cleanup
(
void
);
extern
void
*
bcom_sram_alloc
(
int
size
,
int
align
,
phys_addr_t
*
phys
);
extern
void
bcom_sram_free
(
void
*
ptr
);
static
inline
phys_addr_t
bcom_sram_va2pa
(
void
*
va
)
{
return
bcom_sram
->
base_phys
+
(
unsigned
long
)(
va
-
bcom_sram
->
base_virt
);
}
static
inline
void
*
bcom_sram_pa2va
(
phys_addr_t
pa
)
{
return
bcom_sram
->
base_virt
+
(
unsigned
long
)(
pa
-
bcom_sram
->
base_phys
);
}
#endif
/* __BESTCOMM_SRAM_H__ */
arch/ppc/Kconfig
View file @
4acadb96
...
...
@@ -102,6 +102,7 @@ config 44x
config 8xx
bool "8xx"
select PPC_LIB_RHEAP
config E200
bool "e200"
...
...
@@ -798,6 +799,7 @@ config CPM1
config CPM2
bool
depends on 8260 || MPC8560 || MPC8555
select PPC_LIB_RHEAP
default y
help
The CPM2 (Communications Processor Module) is a coprocessor on
...
...
@@ -1277,6 +1279,10 @@ config BOOT_LOAD
config PIN_TLB
bool "Pinned Kernel TLBs (860 ONLY)"
depends on ADVANCED_OPTIONS && 8xx
config PPC_LIB_RHEAP
bool
endmenu
source "net/Kconfig"
...
...
include/asm-ppc/mpc52xx_psc.h
View file @
4acadb96
...
...
@@ -28,6 +28,10 @@
#define MPC52xx_PSC_MAXNUM 6
/* Programmable Serial Controller (PSC) status register bits */
#define MPC52xx_PSC_SR_UNEX_RX 0x0001
#define MPC52xx_PSC_SR_DATA_VAL 0x0002
#define MPC52xx_PSC_SR_DATA_OVR 0x0004
#define MPC52xx_PSC_SR_CMDSEND 0x0008
#define MPC52xx_PSC_SR_CDE 0x0080
#define MPC52xx_PSC_SR_RXRDY 0x0100
#define MPC52xx_PSC_SR_RXFULL 0x0200
...
...
@@ -132,8 +136,10 @@ struct mpc52xx_psc {
u8
reserved5
[
3
];
u8
ctlr
;
/* PSC + 0x1c */
u8
reserved6
[
3
];
u16
ccr
;
/* PSC + 0x20 */
u8
reserved7
[
14
];
u32
ccr
;
/* PSC + 0x20 */
u32
ac97_slots
;
/* PSC + 0x24 */
u32
ac97_cmd
;
/* PSC + 0x28 */
u32
ac97_data
;
/* PSC + 0x2c */
u8
ivr
;
/* PSC + 0x30 */
u8
reserved8
[
3
];
u8
ip
;
/* PSC + 0x34 */
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment