aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/sysdev
diff options
context:
space:
mode:
authorPhilippe De Muyter <phdm@macqel.be>2012-10-12 11:52:45 -0400
committerAnatolij Gustschin <agust@denx.de>2013-01-03 09:41:20 -0500
commit9a32299394d8cce79ca7d0098dc32c4f14032dcd (patch)
tree24334ecc985c2234d1a988d6c85e8557f35ba21d /arch/powerpc/sysdev
parentd1c3ed669a2d452cacfb48c2d171a1f364dae2ed (diff)
powerpc, dma: move bestcomm driver from arch/powerpc/sysdev to drivers/dma
The bestcomm dma hardware, and some of its users like the FEC ethernet component, is used in different FreeScale parts, including non-powerpc parts like the ColdFire MCF547x & MCF548x families. Don't keep the driver hidden in arch/powerpc where it is inaccessible for other arches. .c files are moved to drivers/dma/bestcomm, while .h files are moved to include/linux/fsl/bestcomm. Makefiles, Kconfigs and #include directives are updated for the new file locations. Tested by recompiling for MPC5200 with all bestcomm users enabled. Signed-off-by: Philippe De Muyter <phdm@macqel.be> Signed-off-by: Anatolij Gustschin <agust@denx.de>
Diffstat (limited to 'arch/powerpc/sysdev')
-rw-r--r--arch/powerpc/sysdev/Makefile1
-rw-r--r--arch/powerpc/sysdev/bestcomm/Kconfig36
-rw-r--r--arch/powerpc/sysdev/bestcomm/Makefile14
-rw-r--r--arch/powerpc/sysdev/bestcomm/ata.c157
-rw-r--r--arch/powerpc/sysdev/bestcomm/ata.h30
-rw-r--r--arch/powerpc/sysdev/bestcomm/bcom_ata_task.c67
-rw-r--r--arch/powerpc/sysdev/bestcomm/bcom_fec_rx_task.c78
-rw-r--r--arch/powerpc/sysdev/bestcomm/bcom_fec_tx_task.c91
-rw-r--r--arch/powerpc/sysdev/bestcomm/bcom_gen_bd_rx_task.c63
-rw-r--r--arch/powerpc/sysdev/bestcomm/bcom_gen_bd_tx_task.c69
-rw-r--r--arch/powerpc/sysdev/bestcomm/bestcomm.c532
-rw-r--r--arch/powerpc/sysdev/bestcomm/bestcomm.h213
-rw-r--r--arch/powerpc/sysdev/bestcomm/bestcomm_priv.h350
-rw-r--r--arch/powerpc/sysdev/bestcomm/fec.c270
-rw-r--r--arch/powerpc/sysdev/bestcomm/fec.h61
-rw-r--r--arch/powerpc/sysdev/bestcomm/gen_bd.c354
-rw-r--r--arch/powerpc/sysdev/bestcomm/gen_bd.h53
-rw-r--r--arch/powerpc/sysdev/bestcomm/sram.c178
-rw-r--r--arch/powerpc/sysdev/bestcomm/sram.h54
19 files changed, 0 insertions, 2671 deletions
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile
index a57600b3a4e3..3884776600fd 100644
--- a/arch/powerpc/sysdev/Makefile
+++ b/arch/powerpc/sysdev/Makefile
@@ -26,7 +26,6 @@ obj-$(CONFIG_SIMPLE_GPIO) += simple_gpio.o
26obj-$(CONFIG_FSL_RIO) += fsl_rio.o fsl_rmu.o 26obj-$(CONFIG_FSL_RIO) += fsl_rio.o fsl_rmu.o
27obj-$(CONFIG_TSI108_BRIDGE) += tsi108_pci.o tsi108_dev.o 27obj-$(CONFIG_TSI108_BRIDGE) += tsi108_pci.o tsi108_dev.o
28obj-$(CONFIG_QUICC_ENGINE) += qe_lib/ 28obj-$(CONFIG_QUICC_ENGINE) += qe_lib/
29obj-$(CONFIG_PPC_BESTCOMM) += bestcomm/
30mv64x60-$(CONFIG_PCI) += mv64x60_pci.o 29mv64x60-$(CONFIG_PCI) += mv64x60_pci.o
31obj-$(CONFIG_MV64X60) += $(mv64x60-y) mv64x60_pic.o mv64x60_dev.o \ 30obj-$(CONFIG_MV64X60) += $(mv64x60-y) mv64x60_pic.o mv64x60_dev.o \
32 mv64x60_udbg.o 31 mv64x60_udbg.o
diff --git a/arch/powerpc/sysdev/bestcomm/Kconfig b/arch/powerpc/sysdev/bestcomm/Kconfig
deleted file mode 100644
index 29e427085efb..000000000000
--- a/arch/powerpc/sysdev/bestcomm/Kconfig
+++ /dev/null
@@ -1,36 +0,0 @@
1#
2# Kconfig options for Bestcomm
3#
4
5config PPC_BESTCOMM
6 tristate "Bestcomm DMA engine support"
7 depends on PPC_MPC52xx
8 default n
9 select PPC_LIB_RHEAP
10 help
11 BestComm is the name of the communication coprocessor found
12 on the Freescale MPC5200 family of processor. Its usage is
13 optional for some drivers (like ATA), but required for
14 others (like FEC).
15
16 If you want to use drivers that require DMA operations,
17 answer Y or M. Otherwise say N.
18
19config PPC_BESTCOMM_ATA
20 tristate
21 depends on PPC_BESTCOMM
22 help
23 This option enables the support for the ATA task.
24
25config PPC_BESTCOMM_FEC
26 tristate
27 depends on PPC_BESTCOMM
28 help
29 This option enables the support for the FEC tasks.
30
31config PPC_BESTCOMM_GEN_BD
32 tristate
33 depends on PPC_BESTCOMM
34 help
35 This option enables the support for the GenBD tasks.
36
diff --git a/arch/powerpc/sysdev/bestcomm/Makefile b/arch/powerpc/sysdev/bestcomm/Makefile
deleted file mode 100644
index aed2df2a6580..000000000000
--- a/arch/powerpc/sysdev/bestcomm/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
1#
2# Makefile for BestComm & co
3#
4
5bestcomm-core-objs := bestcomm.o sram.o
6bestcomm-ata-objs := ata.o bcom_ata_task.o
7bestcomm-fec-objs := fec.o bcom_fec_rx_task.o bcom_fec_tx_task.o
8bestcomm-gen-bd-objs := gen_bd.o bcom_gen_bd_rx_task.o bcom_gen_bd_tx_task.o
9
10obj-$(CONFIG_PPC_BESTCOMM) += bestcomm-core.o
11obj-$(CONFIG_PPC_BESTCOMM_ATA) += bestcomm-ata.o
12obj-$(CONFIG_PPC_BESTCOMM_FEC) += bestcomm-fec.o
13obj-$(CONFIG_PPC_BESTCOMM_GEN_BD) += bestcomm-gen-bd.o
14
diff --git a/arch/powerpc/sysdev/bestcomm/ata.c b/arch/powerpc/sysdev/bestcomm/ata.c
deleted file mode 100644
index 901c9f91e5dd..000000000000
--- a/arch/powerpc/sysdev/bestcomm/ata.c
+++ /dev/null
@@ -1,157 +0,0 @@
1/*
2 * Bestcomm ATA task driver
3 *
4 *
5 * Patterned after bestcomm/fec.c by Dale Farnsworth <dfarnsworth@mvista.com>
6 * 2003-2004 (c) MontaVista, Software, Inc.
7 *
8 * Copyright (C) 2006-2007 Sylvain Munaut <tnt@246tNt.com>
9 * Copyright (C) 2006 Freescale - John Rigby
10 *
11 * This file is licensed under the terms of the GNU General Public License
12 * version 2. This program is licensed "as is" without any warranty of any
13 * kind, whether express or implied.
14 */
15
16#include <linux/kernel.h>
17#include <linux/module.h>
18#include <linux/types.h>
19#include <asm/io.h>
20
21#include "bestcomm.h"
22#include "bestcomm_priv.h"
23#include "ata.h"
24
25
26/* ======================================================================== */
27/* Task image/var/inc */
28/* ======================================================================== */
29
30/* ata task image */
31extern u32 bcom_ata_task[];
32
33/* ata task vars that need to be set before enabling the task */
34struct bcom_ata_var {
35 u32 enable; /* (u16*) address of task's control register */
36 u32 bd_base; /* (struct bcom_bd*) beginning of ring buffer */
37 u32 bd_last; /* (struct bcom_bd*) end of ring buffer */
38 u32 bd_start; /* (struct bcom_bd*) current bd */
39 u32 buffer_size; /* size of receive buffer */
40};
41
42/* ata task incs that need to be set before enabling the task */
43struct bcom_ata_inc {
44 u16 pad0;
45 s16 incr_bytes;
46 u16 pad1;
47 s16 incr_dst;
48 u16 pad2;
49 s16 incr_src;
50};
51
52
53/* ======================================================================== */
54/* Task support code */
55/* ======================================================================== */
56
57struct bcom_task *
58bcom_ata_init(int queue_len, int maxbufsize)
59{
60 struct bcom_task *tsk;
61 struct bcom_ata_var *var;
62 struct bcom_ata_inc *inc;
63
64 /* Prefetch breaks ATA DMA. Turn it off for ATA DMA */
65 bcom_disable_prefetch();
66
67 tsk = bcom_task_alloc(queue_len, sizeof(struct bcom_ata_bd), 0);
68 if (!tsk)
69 return NULL;
70
71 tsk->flags = BCOM_FLAGS_NONE;
72
73 bcom_ata_reset_bd(tsk);
74
75 var = (struct bcom_ata_var *) bcom_task_var(tsk->tasknum);
76 inc = (struct bcom_ata_inc *) bcom_task_inc(tsk->tasknum);
77
78 if (bcom_load_image(tsk->tasknum, bcom_ata_task)) {
79 bcom_task_free(tsk);
80 return NULL;
81 }
82
83 var->enable = bcom_eng->regs_base +
84 offsetof(struct mpc52xx_sdma, tcr[tsk->tasknum]);
85 var->bd_base = tsk->bd_pa;
86 var->bd_last = tsk->bd_pa + ((tsk->num_bd-1) * tsk->bd_size);
87 var->bd_start = tsk->bd_pa;
88 var->buffer_size = maxbufsize;
89
90 /* Configure some stuff */
91 bcom_set_task_pragma(tsk->tasknum, BCOM_ATA_PRAGMA);
92 bcom_set_task_auto_start(tsk->tasknum, tsk->tasknum);
93
94 out_8(&bcom_eng->regs->ipr[BCOM_INITIATOR_ATA_RX], BCOM_IPR_ATA_RX);
95 out_8(&bcom_eng->regs->ipr[BCOM_INITIATOR_ATA_TX], BCOM_IPR_ATA_TX);
96
97 out_be32(&bcom_eng->regs->IntPend, 1<<tsk->tasknum); /* Clear ints */
98
99 return tsk;
100}
101EXPORT_SYMBOL_GPL(bcom_ata_init);
102
103void bcom_ata_rx_prepare(struct bcom_task *tsk)
104{
105 struct bcom_ata_inc *inc;
106
107 inc = (struct bcom_ata_inc *) bcom_task_inc(tsk->tasknum);
108
109 inc->incr_bytes = -(s16)sizeof(u32);
110 inc->incr_src = 0;
111 inc->incr_dst = sizeof(u32);
112
113 bcom_set_initiator(tsk->tasknum, BCOM_INITIATOR_ATA_RX);
114}
115EXPORT_SYMBOL_GPL(bcom_ata_rx_prepare);
116
117void bcom_ata_tx_prepare(struct bcom_task *tsk)
118{
119 struct bcom_ata_inc *inc;
120
121 inc = (struct bcom_ata_inc *) bcom_task_inc(tsk->tasknum);
122
123 inc->incr_bytes = -(s16)sizeof(u32);
124 inc->incr_src = sizeof(u32);
125 inc->incr_dst = 0;
126
127 bcom_set_initiator(tsk->tasknum, BCOM_INITIATOR_ATA_TX);
128}
129EXPORT_SYMBOL_GPL(bcom_ata_tx_prepare);
130
131void bcom_ata_reset_bd(struct bcom_task *tsk)
132{
133 struct bcom_ata_var *var;
134
135 /* Reset all BD */
136 memset(tsk->bd, 0x00, tsk->num_bd * tsk->bd_size);
137
138 tsk->index = 0;
139 tsk->outdex = 0;
140
141 var = (struct bcom_ata_var *) bcom_task_var(tsk->tasknum);
142 var->bd_start = var->bd_base;
143}
144EXPORT_SYMBOL_GPL(bcom_ata_reset_bd);
145
146void bcom_ata_release(struct bcom_task *tsk)
147{
148 /* Nothing special for the ATA tasks */
149 bcom_task_free(tsk);
150}
151EXPORT_SYMBOL_GPL(bcom_ata_release);
152
153
154MODULE_DESCRIPTION("BestComm ATA task driver");
155MODULE_AUTHOR("John Rigby");
156MODULE_LICENSE("GPL v2");
157
diff --git a/arch/powerpc/sysdev/bestcomm/ata.h b/arch/powerpc/sysdev/bestcomm/ata.h
deleted file mode 100644
index 0b2371811334..000000000000
--- a/arch/powerpc/sysdev/bestcomm/ata.h
+++ /dev/null
@@ -1,30 +0,0 @@
1/*
2 * Header for Bestcomm ATA task driver
3 *
4 *
5 * Copyright (C) 2006 Freescale - John Rigby
6 * Copyright (C) 2006 Sylvain Munaut <tnt@246tNt.com>
7 *
8 * This file is licensed under the terms of the GNU General Public License
9 * version 2. This program is licensed "as is" without any warranty of any
10 * kind, whether express or implied.
11 */
12
13#ifndef __BESTCOMM_ATA_H__
14#define __BESTCOMM_ATA_H__
15
16
17struct bcom_ata_bd {
18 u32 status;
19 u32 src_pa;
20 u32 dst_pa;
21};
22
23extern struct bcom_task * bcom_ata_init(int queue_len, int maxbufsize);
24extern void bcom_ata_rx_prepare(struct bcom_task *tsk);
25extern void bcom_ata_tx_prepare(struct bcom_task *tsk);
26extern void bcom_ata_reset_bd(struct bcom_task *tsk);
27extern void bcom_ata_release(struct bcom_task *tsk);
28
29#endif /* __BESTCOMM_ATA_H__ */
30
diff --git a/arch/powerpc/sysdev/bestcomm/bcom_ata_task.c b/arch/powerpc/sysdev/bestcomm/bcom_ata_task.c
deleted file mode 100644
index cc6049a4e469..000000000000
--- a/arch/powerpc/sysdev/bestcomm/bcom_ata_task.c
+++ /dev/null
@@ -1,67 +0,0 @@
1/*
2 * Bestcomm ATA task microcode
3 *
4 * Copyright (c) 2004 Freescale Semiconductor, Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 as published
8 * by the Free Software Foundation.
9 *
10 * Created based on bestcom/code_dma/image_rtos1/dma_image.hex
11 */
12
13#include <asm/types.h>
14
15/*
16 * The header consists of the following fields:
17 * u32 magic;
18 * u8 desc_size;
19 * u8 var_size;
20 * u8 inc_size;
21 * u8 first_var;
22 * u8 reserved[8];
23 *
24 * The size fields contain the number of 32-bit words.
25 */
26
27u32 bcom_ata_task[] = {
28 /* header */
29 0x4243544b,
30 0x0e060709,
31 0x00000000,
32 0x00000000,
33
34 /* Task descriptors */
35 0x8198009b, /* LCD: idx0 = var3; idx0 <= var2; idx0 += inc3 */
36 0x13e00c08, /* DRD1A: var3 = var1; FN=0 MORE init=31 WS=0 RS=0 */
37 0xb8000264, /* LCD: idx1 = *idx0, idx2 = var0; idx1 < var9; idx1 += inc4, idx2 += inc4 */
38 0x10000f00, /* DRD1A: var3 = idx0; FN=0 MORE init=0 WS=0 RS=0 */
39 0x60140002, /* DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT init=0 WS=2 RS=2 */
40 0x0c8cfc8a, /* DRD2B1: *idx2 = EU3(); EU3(*idx2,var10) */
41 0xd8988240, /* LCDEXT: idx1 = idx1; idx1 > var9; idx1 += inc0 */
42 0xf845e011, /* LCDEXT: idx2 = *(idx0 + var00000015); ; idx2 += inc2 */
43 0xb845e00a, /* LCD: idx3 = *(idx0 + var00000019); ; idx3 += inc1 */
44 0x0bfecf90, /* DRD1A: *idx3 = *idx2; FN=0 TFD init=31 WS=3 RS=3 */
45 0x9898802d, /* LCD: idx1 = idx1; idx1 once var0; idx1 += inc5 */
46 0x64000005, /* DRD2A: EU0=0 EU1=0 EU2=0 EU3=5 INT EXT init=0 WS=0 RS=0 */
47 0x0c0cf849, /* DRD2B1: *idx0 = EU3(); EU3(idx1,var9) */
48 0x000001f8, /* NOP */
49
50 /* VAR[9]-VAR[14] */
51 0x40000000,
52 0x7fff7fff,
53 0x00000000,
54 0x00000000,
55 0x00000000,
56 0x00000000,
57
58 /* INC[0]-INC[6] */
59 0x40000000,
60 0xe0000000,
61 0xe0000000,
62 0xa000000c,
63 0x20000000,
64 0x00000000,
65 0x00000000,
66};
67
diff --git a/arch/powerpc/sysdev/bestcomm/bcom_fec_rx_task.c b/arch/powerpc/sysdev/bestcomm/bcom_fec_rx_task.c
deleted file mode 100644
index a1ad6a02fcef..000000000000
--- a/arch/powerpc/sysdev/bestcomm/bcom_fec_rx_task.c
+++ /dev/null
@@ -1,78 +0,0 @@
1/*
2 * Bestcomm FEC RX task microcode
3 *
4 * Copyright (c) 2004 Freescale Semiconductor, Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 as published
8 * by the Free Software Foundation.
9 *
10 * Automatically created based on BestCommAPI-2.2/code_dma/image_rtos1/dma_image.hex
11 * on Tue Mar 22 11:19:38 2005 GMT
12 */
13
14#include <asm/types.h>
15
16/*
17 * The header consists of the following fields:
18 * u32 magic;
19 * u8 desc_size;
20 * u8 var_size;
21 * u8 inc_size;
22 * u8 first_var;
23 * u8 reserved[8];
24 *
25 * The size fields contain the number of 32-bit words.
26 */
27
28u32 bcom_fec_rx_task[] = {
29 /* header */
30 0x4243544b,
31 0x18060709,
32 0x00000000,
33 0x00000000,
34
35 /* Task descriptors */
36 0x808220e3, /* LCD: idx0 = var1, idx1 = var4; idx1 <= var3; idx0 += inc4, idx1 += inc3 */
37 0x10601010, /* DRD1A: var4 = var2; FN=0 MORE init=3 WS=0 RS=0 */
38 0xb8800264, /* LCD: idx2 = *idx1, idx3 = var0; idx2 < var9; idx2 += inc4, idx3 += inc4 */
39 0x10001308, /* DRD1A: var4 = idx1; FN=0 MORE init=0 WS=0 RS=0 */
40 0x60140002, /* DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT init=0 WS=2 RS=2 */
41 0x0cccfcca, /* DRD2B1: *idx3 = EU3(); EU3(*idx3,var10) */
42 0x80004000, /* LCDEXT: idx2 = 0x00000000; ; */
43 0xb8c58029, /* LCD: idx3 = *(idx1 + var00000015); idx3 once var0; idx3 += inc5 */
44 0x60000002, /* DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT init=0 WS=0 RS=0 */
45 0x088cf8cc, /* DRD2B1: idx2 = EU3(); EU3(idx3,var12) */
46 0x991982f2, /* LCD: idx2 = idx2, idx3 = idx3; idx2 > var11; idx2 += inc6, idx3 += inc2 */
47 0x006acf80, /* DRD1A: *idx3 = *idx0; FN=0 init=3 WS=1 RS=1 */
48 0x80004000, /* LCDEXT: idx2 = 0x00000000; ; */
49 0x9999802d, /* LCD: idx3 = idx3; idx3 once var0; idx3 += inc5 */
50 0x70000002, /* DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT MORE init=0 WS=0 RS=0 */
51 0x034cfc4e, /* DRD2B1: var13 = EU3(); EU3(*idx1,var14) */
52 0x00008868, /* DRD1A: idx2 = var13; FN=0 init=0 WS=0 RS=0 */
53 0x99198341, /* LCD: idx2 = idx2, idx3 = idx3; idx2 > var13; idx2 += inc0, idx3 += inc1 */
54 0x007ecf80, /* DRD1A: *idx3 = *idx0; FN=0 init=3 WS=3 RS=3 */
55 0x99198272, /* LCD: idx2 = idx2, idx3 = idx3; idx2 > var9; idx2 += inc6, idx3 += inc2 */
56 0x046acf80, /* DRD1A: *idx3 = *idx0; FN=0 INT init=3 WS=1 RS=1 */
57 0x9819002d, /* LCD: idx2 = idx0; idx2 once var0; idx2 += inc5 */
58 0x0060c790, /* DRD1A: *idx1 = *idx2; FN=0 init=3 WS=0 RS=0 */
59 0x000001f8, /* NOP */
60
61 /* VAR[9]-VAR[14] */
62 0x40000000,
63 0x7fff7fff,
64 0x00000000,
65 0x00000003,
66 0x40000008,
67 0x43ffffff,
68
69 /* INC[0]-INC[6] */
70 0x40000000,
71 0xe0000000,
72 0xe0000000,
73 0xa0000008,
74 0x20000000,
75 0x00000000,
76 0x4000ffff,
77};
78
diff --git a/arch/powerpc/sysdev/bestcomm/bcom_fec_tx_task.c b/arch/powerpc/sysdev/bestcomm/bcom_fec_tx_task.c
deleted file mode 100644
index b1c495c3a65a..000000000000
--- a/arch/powerpc/sysdev/bestcomm/bcom_fec_tx_task.c
+++ /dev/null
@@ -1,91 +0,0 @@
1/*
2 * Bestcomm FEC TX task microcode
3 *
4 * Copyright (c) 2004 Freescale Semiconductor, Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 as published
8 * by the Free Software Foundation.
9 *
10 * Automatically created based on BestCommAPI-2.2/code_dma/image_rtos1/dma_image.hex
11 * on Tue Mar 22 11:19:29 2005 GMT
12 */
13
14#include <asm/types.h>
15
16/*
17 * The header consists of the following fields:
18 * u32 magic;
19 * u8 desc_size;
20 * u8 var_size;
21 * u8 inc_size;
22 * u8 first_var;
23 * u8 reserved[8];
24 *
25 * The size fields contain the number of 32-bit words.
26 */
27
28u32 bcom_fec_tx_task[] = {
29 /* header */
30 0x4243544b,
31 0x2407070d,
32 0x00000000,
33 0x00000000,
34
35 /* Task descriptors */
36 0x8018001b, /* LCD: idx0 = var0; idx0 <= var0; idx0 += inc3 */
37 0x60000005, /* DRD2A: EU0=0 EU1=0 EU2=0 EU3=5 EXT init=0 WS=0 RS=0 */
38 0x01ccfc0d, /* DRD2B1: var7 = EU3(); EU3(*idx0,var13) */
39 0x8082a123, /* LCD: idx0 = var1, idx1 = var5; idx1 <= var4; idx0 += inc4, idx1 += inc3 */
40 0x10801418, /* DRD1A: var5 = var3; FN=0 MORE init=4 WS=0 RS=0 */
41 0xf88103a4, /* LCDEXT: idx2 = *idx1, idx3 = var2; idx2 < var14; idx2 += inc4, idx3 += inc4 */
42 0x801a6024, /* LCD: idx4 = var0; ; idx4 += inc4 */
43 0x10001708, /* DRD1A: var5 = idx1; FN=0 MORE init=0 WS=0 RS=0 */
44 0x60140002, /* DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT init=0 WS=2 RS=2 */
45 0x0cccfccf, /* DRD2B1: *idx3 = EU3(); EU3(*idx3,var15) */
46 0x991a002c, /* LCD: idx2 = idx2, idx3 = idx4; idx2 once var0; idx2 += inc5, idx3 += inc4 */
47 0x70000002, /* DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT MORE init=0 WS=0 RS=0 */
48 0x024cfc4d, /* DRD2B1: var9 = EU3(); EU3(*idx1,var13) */
49 0x60000003, /* DRD2A: EU0=0 EU1=0 EU2=0 EU3=3 EXT init=0 WS=0 RS=0 */
50 0x0cccf247, /* DRD2B1: *idx3 = EU3(); EU3(var9,var7) */
51 0x80004000, /* LCDEXT: idx2 = 0x00000000; ; */
52 0xb8c80029, /* LCD: idx3 = *(idx1 + var0000001a); idx3 once var0; idx3 += inc5 */
53 0x70000002, /* DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT MORE init=0 WS=0 RS=0 */
54 0x088cf8d1, /* DRD2B1: idx2 = EU3(); EU3(idx3,var17) */
55 0x00002f10, /* DRD1A: var11 = idx2; FN=0 init=0 WS=0 RS=0 */
56 0x99198432, /* LCD: idx2 = idx2, idx3 = idx3; idx2 > var16; idx2 += inc6, idx3 += inc2 */
57 0x008ac398, /* DRD1A: *idx0 = *idx3; FN=0 init=4 WS=1 RS=1 */
58 0x80004000, /* LCDEXT: idx2 = 0x00000000; ; */
59 0x9999802d, /* LCD: idx3 = idx3; idx3 once var0; idx3 += inc5 */
60 0x70000002, /* DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT MORE init=0 WS=0 RS=0 */
61 0x048cfc53, /* DRD2B1: var18 = EU3(); EU3(*idx1,var19) */
62 0x60000008, /* DRD2A: EU0=0 EU1=0 EU2=0 EU3=8 EXT init=0 WS=0 RS=0 */
63 0x088cf48b, /* DRD2B1: idx2 = EU3(); EU3(var18,var11) */
64 0x99198481, /* LCD: idx2 = idx2, idx3 = idx3; idx2 > var18; idx2 += inc0, idx3 += inc1 */
65 0x009ec398, /* DRD1A: *idx0 = *idx3; FN=0 init=4 WS=3 RS=3 */
66 0x991983b2, /* LCD: idx2 = idx2, idx3 = idx3; idx2 > var14; idx2 += inc6, idx3 += inc2 */
67 0x088ac398, /* DRD1A: *idx0 = *idx3; FN=0 TFD init=4 WS=1 RS=1 */
68 0x9919002d, /* LCD: idx2 = idx2; idx2 once var0; idx2 += inc5 */
69 0x60000005, /* DRD2A: EU0=0 EU1=0 EU2=0 EU3=5 EXT init=0 WS=0 RS=0 */
70 0x0c4cf88e, /* DRD2B1: *idx1 = EU3(); EU3(idx2,var14) */
71 0x000001f8, /* NOP */
72
73 /* VAR[13]-VAR[19] */
74 0x0c000000,
75 0x40000000,
76 0x7fff7fff,
77 0x00000000,
78 0x00000003,
79 0x40000004,
80 0x43ffffff,
81
82 /* INC[0]-INC[6] */
83 0x40000000,
84 0xe0000000,
85 0xe0000000,
86 0xa0000008,
87 0x20000000,
88 0x00000000,
89 0x4000ffff,
90};
91
diff --git a/arch/powerpc/sysdev/bestcomm/bcom_gen_bd_rx_task.c b/arch/powerpc/sysdev/bestcomm/bcom_gen_bd_rx_task.c
deleted file mode 100644
index efee022b0256..000000000000
--- a/arch/powerpc/sysdev/bestcomm/bcom_gen_bd_rx_task.c
+++ /dev/null
@@ -1,63 +0,0 @@
1/*
2 * Bestcomm GenBD RX task microcode
3 *
4 * Copyright (C) 2006 AppSpec Computer Technologies Corp.
5 * Jeff Gibbons <jeff.gibbons@appspec.com>
6 * Copyright (c) 2004 Freescale Semiconductor, Inc.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 2 as published
10 * by the Free Software Foundation.
11 *
12 * Based on BestCommAPI-2.2/code_dma/image_rtos1/dma_image.hex
13 * on Tue Mar 4 10:14:12 2006 GMT
14 *
15 */
16
17#include <asm/types.h>
18
19/*
20 * The header consists of the following fields:
21 * u32 magic;
22 * u8 desc_size;
23 * u8 var_size;
24 * u8 inc_size;
25 * u8 first_var;
26 * u8 reserved[8];
27 *
28 * The size fields contain the number of 32-bit words.
29 */
30
31u32 bcom_gen_bd_rx_task[] = {
32 /* header */
33 0x4243544b,
34 0x0d020409,
35 0x00000000,
36 0x00000000,
37
38 /* Task descriptors */
39 0x808220da, /* LCD: idx0 = var1, idx1 = var4; idx1 <= var3; idx0 += inc3, idx1 += inc2 */
40 0x13e01010, /* DRD1A: var4 = var2; FN=0 MORE init=31 WS=0 RS=0 */
41 0xb880025b, /* LCD: idx2 = *idx1, idx3 = var0; idx2 < var9; idx2 += inc3, idx3 += inc3 */
42 0x10001308, /* DRD1A: var4 = idx1; FN=0 MORE init=0 WS=0 RS=0 */
43 0x60140002, /* DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT init=0 WS=2 RS=2 */
44 0x0cccfcca, /* DRD2B1: *idx3 = EU3(); EU3(*idx3,var10) */
45 0xd9190240, /* LCDEXT: idx2 = idx2; idx2 > var9; idx2 += inc0 */
46 0xb8c5e009, /* LCD: idx3 = *(idx1 + var00000015); ; idx3 += inc1 */
47 0x07fecf80, /* DRD1A: *idx3 = *idx0; FN=0 INT init=31 WS=3 RS=3 */
48 0x99190024, /* LCD: idx2 = idx2; idx2 once var0; idx2 += inc4 */
49 0x60000005, /* DRD2A: EU0=0 EU1=0 EU2=0 EU3=5 EXT init=0 WS=0 RS=0 */
50 0x0c4cf889, /* DRD2B1: *idx1 = EU3(); EU3(idx2,var9) */
51 0x000001f8, /* NOP */
52
53 /* VAR[9]-VAR[10] */
54 0x40000000,
55 0x7fff7fff,
56
57 /* INC[0]-INC[3] */
58 0x40000000,
59 0xe0000000,
60 0xa0000008,
61 0x20000000,
62};
63
diff --git a/arch/powerpc/sysdev/bestcomm/bcom_gen_bd_tx_task.c b/arch/powerpc/sysdev/bestcomm/bcom_gen_bd_tx_task.c
deleted file mode 100644
index c605aa42ecbb..000000000000
--- a/arch/powerpc/sysdev/bestcomm/bcom_gen_bd_tx_task.c
+++ /dev/null
@@ -1,69 +0,0 @@
1/*
2 * Bestcomm GenBD TX task microcode
3 *
4 * Copyright (C) 2006 AppSpec Computer Technologies Corp.
5 * Jeff Gibbons <jeff.gibbons@appspec.com>
6 * Copyright (c) 2004 Freescale Semiconductor, Inc.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 2 as published
10 * by the Free Software Foundation.
11 *
12 * Based on BestCommAPI-2.2/code_dma/image_rtos1/dma_image.hex
13 * on Tue Mar 4 10:14:12 2006 GMT
14 *
15 */
16
17#include <asm/types.h>
18
19/*
20 * The header consists of the following fields:
21 * u32 magic;
22 * u8 desc_size;
23 * u8 var_size;
24 * u8 inc_size;
25 * u8 first_var;
26 * u8 reserved[8];
27 *
28 * The size fields contain the number of 32-bit words.
29 */
30
31u32 bcom_gen_bd_tx_task[] = {
32 /* header */
33 0x4243544b,
34 0x0f040609,
35 0x00000000,
36 0x00000000,
37
38 /* Task descriptors */
39 0x800220e3, /* LCD: idx0 = var0, idx1 = var4; idx1 <= var3; idx0 += inc4, idx1 += inc3 */
40 0x13e01010, /* DRD1A: var4 = var2; FN=0 MORE init=31 WS=0 RS=0 */
41 0xb8808264, /* LCD: idx2 = *idx1, idx3 = var1; idx2 < var9; idx2 += inc4, idx3 += inc4 */
42 0x10001308, /* DRD1A: var4 = idx1; FN=0 MORE init=0 WS=0 RS=0 */
43 0x60140002, /* DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT init=0 WS=2 RS=2 */
44 0x0cccfcca, /* DRD2B1: *idx3 = EU3(); EU3(*idx3,var10) */
45 0xd9190300, /* LCDEXT: idx2 = idx2; idx2 > var12; idx2 += inc0 */
46 0xb8c5e009, /* LCD: idx3 = *(idx1 + var00000015); ; idx3 += inc1 */
47 0x03fec398, /* DRD1A: *idx0 = *idx3; FN=0 init=31 WS=3 RS=3 */
48 0x9919826a, /* LCD: idx2 = idx2, idx3 = idx3; idx2 > var9; idx2 += inc5, idx3 += inc2 */
49 0x0feac398, /* DRD1A: *idx0 = *idx3; FN=0 TFD INT init=31 WS=1 RS=1 */
50 0x99190036, /* LCD: idx2 = idx2; idx2 once var0; idx2 += inc6 */
51 0x60000005, /* DRD2A: EU0=0 EU1=0 EU2=0 EU3=5 EXT init=0 WS=0 RS=0 */
52 0x0c4cf889, /* DRD2B1: *idx1 = EU3(); EU3(idx2,var9) */
53 0x000001f8, /* NOP */
54
55 /* VAR[9]-VAR[12] */
56 0x40000000,
57 0x7fff7fff,
58 0x00000000,
59 0x40000004,
60
61 /* INC[0]-INC[5] */
62 0x40000000,
63 0xe0000000,
64 0xe0000000,
65 0xa0000008,
66 0x20000000,
67 0x4000ffff,
68};
69
diff --git a/arch/powerpc/sysdev/bestcomm/bestcomm.c b/arch/powerpc/sysdev/bestcomm/bestcomm.c
deleted file mode 100644
index b3fbb271be87..000000000000
--- a/arch/powerpc/sysdev/bestcomm/bestcomm.c
+++ /dev/null
@@ -1,532 +0,0 @@
1/*
2 * Driver for MPC52xx processor BestComm peripheral controller
3 *
4 *
5 * Copyright (C) 2006-2007 Sylvain Munaut <tnt@246tNt.com>
6 * Copyright (C) 2005 Varma Electronics Oy,
7 * ( by Andrey Volkov <avolkov@varma-el.com> )
8 * Copyright (C) 2003-2004 MontaVista, Software, Inc.
9 * ( by Dale Farnsworth <dfarnsworth@mvista.com> )
10 *
11 * This file is licensed under the terms of the GNU General Public License
12 * version 2. This program is licensed "as is" without any warranty of any
13 * kind, whether express or implied.
14 */
15
16#include <linux/module.h>
17#include <linux/kernel.h>
18#include <linux/slab.h>
19#include <linux/of.h>
20#include <linux/of_device.h>
21#include <linux/of_platform.h>
22#include <asm/io.h>
23#include <asm/irq.h>
24#include <asm/mpc52xx.h>
25
26#include "sram.h"
27#include "bestcomm_priv.h"
28#include "bestcomm.h"
29
30#define DRIVER_NAME "bestcomm-core"
31
32/* MPC5200 device tree match tables */
33static struct of_device_id mpc52xx_sram_ids[] __devinitdata = {
34 { .compatible = "fsl,mpc5200-sram", },
35 { .compatible = "mpc5200-sram", },
36 {}
37};
38
39
40struct bcom_engine *bcom_eng = NULL;
41EXPORT_SYMBOL_GPL(bcom_eng); /* needed for inline functions */
42
43/* ======================================================================== */
44/* Public and private API */
45/* ======================================================================== */
46
47/* Private API */
48
49struct bcom_task *
50bcom_task_alloc(int bd_count, int bd_size, int priv_size)
51{
52 int i, tasknum = -1;
53 struct bcom_task *tsk;
54
55 /* Don't try to do anything if bestcomm init failed */
56 if (!bcom_eng)
57 return NULL;
58
59 /* Get and reserve a task num */
60 spin_lock(&bcom_eng->lock);
61
62 for (i=0; i<BCOM_MAX_TASKS; i++)
63 if (!bcom_eng->tdt[i].stop) { /* we use stop as a marker */
64 bcom_eng->tdt[i].stop = 0xfffffffful; /* dummy addr */
65 tasknum = i;
66 break;
67 }
68
69 spin_unlock(&bcom_eng->lock);
70
71 if (tasknum < 0)
72 return NULL;
73
74 /* Allocate our structure */
75 tsk = kzalloc(sizeof(struct bcom_task) + priv_size, GFP_KERNEL);
76 if (!tsk)
77 goto error;
78
79 tsk->tasknum = tasknum;
80 if (priv_size)
81 tsk->priv = (void*)tsk + sizeof(struct bcom_task);
82
83 /* Get IRQ of that task */
84 tsk->irq = irq_of_parse_and_map(bcom_eng->ofnode, tsk->tasknum);
85 if (tsk->irq == NO_IRQ)
86 goto error;
87
88 /* Init the BDs, if needed */
89 if (bd_count) {
90 tsk->cookie = kmalloc(sizeof(void*) * bd_count, GFP_KERNEL);
91 if (!tsk->cookie)
92 goto error;
93
94 tsk->bd = bcom_sram_alloc(bd_count * bd_size, 4, &tsk->bd_pa);
95 if (!tsk->bd)
96 goto error;
97 memset(tsk->bd, 0x00, bd_count * bd_size);
98
99 tsk->num_bd = bd_count;
100 tsk->bd_size = bd_size;
101 }
102
103 return tsk;
104
105error:
106 if (tsk) {
107 if (tsk->irq != NO_IRQ)
108 irq_dispose_mapping(tsk->irq);
109 bcom_sram_free(tsk->bd);
110 kfree(tsk->cookie);
111 kfree(tsk);
112 }
113
114 bcom_eng->tdt[tasknum].stop = 0;
115
116 return NULL;
117}
118EXPORT_SYMBOL_GPL(bcom_task_alloc);
119
120void
121bcom_task_free(struct bcom_task *tsk)
122{
123 /* Stop the task */
124 bcom_disable_task(tsk->tasknum);
125
126 /* Clear TDT */
127 bcom_eng->tdt[tsk->tasknum].start = 0;
128 bcom_eng->tdt[tsk->tasknum].stop = 0;
129
130 /* Free everything */
131 irq_dispose_mapping(tsk->irq);
132 bcom_sram_free(tsk->bd);
133 kfree(tsk->cookie);
134 kfree(tsk);
135}
136EXPORT_SYMBOL_GPL(bcom_task_free);
137
138int
139bcom_load_image(int task, u32 *task_image)
140{
141 struct bcom_task_header *hdr = (struct bcom_task_header *)task_image;
142 struct bcom_tdt *tdt;
143 u32 *desc, *var, *inc;
144 u32 *desc_src, *var_src, *inc_src;
145
146 /* Safety checks */
147 if (hdr->magic != BCOM_TASK_MAGIC) {
148 printk(KERN_ERR DRIVER_NAME
149 ": Trying to load invalid microcode\n");
150 return -EINVAL;
151 }
152
153 if ((task < 0) || (task >= BCOM_MAX_TASKS)) {
154 printk(KERN_ERR DRIVER_NAME
155 ": Trying to load invalid task %d\n", task);
156 return -EINVAL;
157 }
158
159 /* Initial load or reload */
160 tdt = &bcom_eng->tdt[task];
161
162 if (tdt->start) {
163 desc = bcom_task_desc(task);
164 if (hdr->desc_size != bcom_task_num_descs(task)) {
165 printk(KERN_ERR DRIVER_NAME
166 ": Trying to reload wrong task image "
167 "(%d size %d/%d)!\n",
168 task,
169 hdr->desc_size,
170 bcom_task_num_descs(task));
171 return -EINVAL;
172 }
173 } else {
174 phys_addr_t start_pa;
175
176 desc = bcom_sram_alloc(hdr->desc_size * sizeof(u32), 4, &start_pa);
177 if (!desc)
178 return -ENOMEM;
179
180 tdt->start = start_pa;
181 tdt->stop = start_pa + ((hdr->desc_size-1) * sizeof(u32));
182 }
183
184 var = bcom_task_var(task);
185 inc = bcom_task_inc(task);
186
187 /* Clear & copy */
188 memset(var, 0x00, BCOM_VAR_SIZE);
189 memset(inc, 0x00, BCOM_INC_SIZE);
190
191 desc_src = (u32 *)(hdr + 1);
192 var_src = desc_src + hdr->desc_size;
193 inc_src = var_src + hdr->var_size;
194
195 memcpy(desc, desc_src, hdr->desc_size * sizeof(u32));
196 memcpy(var + hdr->first_var, var_src, hdr->var_size * sizeof(u32));
197 memcpy(inc, inc_src, hdr->inc_size * sizeof(u32));
198
199 return 0;
200}
201EXPORT_SYMBOL_GPL(bcom_load_image);
202
203void
204bcom_set_initiator(int task, int initiator)
205{
206 int i;
207 int num_descs;
208 u32 *desc;
209 int next_drd_has_initiator;
210
211 bcom_set_tcr_initiator(task, initiator);
212
213 /* Just setting tcr is apparently not enough due to some problem */
214 /* with it. So we just go thru all the microcode and replace in */
215 /* the DRD directly */
216
217 desc = bcom_task_desc(task);
218 next_drd_has_initiator = 1;
219 num_descs = bcom_task_num_descs(task);
220
221 for (i=0; i<num_descs; i++, desc++) {
222 if (!bcom_desc_is_drd(*desc))
223 continue;
224 if (next_drd_has_initiator)
225 if (bcom_desc_initiator(*desc) != BCOM_INITIATOR_ALWAYS)
226 bcom_set_desc_initiator(desc, initiator);
227 next_drd_has_initiator = !bcom_drd_is_extended(*desc);
228 }
229}
230EXPORT_SYMBOL_GPL(bcom_set_initiator);
231
232
233/* Public API */
234
235void
236bcom_enable(struct bcom_task *tsk)
237{
238 bcom_enable_task(tsk->tasknum);
239}
240EXPORT_SYMBOL_GPL(bcom_enable);
241
242void
243bcom_disable(struct bcom_task *tsk)
244{
245 bcom_disable_task(tsk->tasknum);
246}
247EXPORT_SYMBOL_GPL(bcom_disable);
248
249
250/* ======================================================================== */
251/* Engine init/cleanup */
252/* ======================================================================== */
253
254/* Function Descriptor table */
255/* this will need to be updated if Freescale changes their task code FDT */
256static u32 fdt_ops[] = {
257 0xa0045670, /* FDT[48] - load_acc() */
258 0x80045670, /* FDT[49] - unload_acc() */
259 0x21800000, /* FDT[50] - and() */
260 0x21e00000, /* FDT[51] - or() */
261 0x21500000, /* FDT[52] - xor() */
262 0x21400000, /* FDT[53] - andn() */
263 0x21500000, /* FDT[54] - not() */
264 0x20400000, /* FDT[55] - add() */
265 0x20500000, /* FDT[56] - sub() */
266 0x20800000, /* FDT[57] - lsh() */
267 0x20a00000, /* FDT[58] - rsh() */
268 0xc0170000, /* FDT[59] - crc8() */
269 0xc0145670, /* FDT[60] - crc16() */
270 0xc0345670, /* FDT[61] - crc32() */
271 0xa0076540, /* FDT[62] - endian32() */
272 0xa0000760, /* FDT[63] - endian16() */
273};
274
275
276static int __devinit
277bcom_engine_init(void)
278{
279 int task;
280 phys_addr_t tdt_pa, ctx_pa, var_pa, fdt_pa;
281 unsigned int tdt_size, ctx_size, var_size, fdt_size;
282
283 /* Allocate & clear SRAM zones for FDT, TDTs, contexts and vars/incs */
284 tdt_size = BCOM_MAX_TASKS * sizeof(struct bcom_tdt);
285 ctx_size = BCOM_MAX_TASKS * BCOM_CTX_SIZE;
286 var_size = BCOM_MAX_TASKS * (BCOM_VAR_SIZE + BCOM_INC_SIZE);
287 fdt_size = BCOM_FDT_SIZE;
288
289 bcom_eng->tdt = bcom_sram_alloc(tdt_size, sizeof(u32), &tdt_pa);
290 bcom_eng->ctx = bcom_sram_alloc(ctx_size, BCOM_CTX_ALIGN, &ctx_pa);
291 bcom_eng->var = bcom_sram_alloc(var_size, BCOM_VAR_ALIGN, &var_pa);
292 bcom_eng->fdt = bcom_sram_alloc(fdt_size, BCOM_FDT_ALIGN, &fdt_pa);
293
294 if (!bcom_eng->tdt || !bcom_eng->ctx || !bcom_eng->var || !bcom_eng->fdt) {
295 printk(KERN_ERR "DMA: SRAM alloc failed in engine init !\n");
296
297 bcom_sram_free(bcom_eng->tdt);
298 bcom_sram_free(bcom_eng->ctx);
299 bcom_sram_free(bcom_eng->var);
300 bcom_sram_free(bcom_eng->fdt);
301
302 return -ENOMEM;
303 }
304
305 memset(bcom_eng->tdt, 0x00, tdt_size);
306 memset(bcom_eng->ctx, 0x00, ctx_size);
307 memset(bcom_eng->var, 0x00, var_size);
308 memset(bcom_eng->fdt, 0x00, fdt_size);
309
310 /* Copy the FDT for the EU#3 */
311 memcpy(&bcom_eng->fdt[48], fdt_ops, sizeof(fdt_ops));
312
313 /* Initialize Task base structure */
314 for (task=0; task<BCOM_MAX_TASKS; task++)
315 {
316 out_be16(&bcom_eng->regs->tcr[task], 0);
317 out_8(&bcom_eng->regs->ipr[task], 0);
318
319 bcom_eng->tdt[task].context = ctx_pa;
320 bcom_eng->tdt[task].var = var_pa;
321 bcom_eng->tdt[task].fdt = fdt_pa;
322
323 var_pa += BCOM_VAR_SIZE + BCOM_INC_SIZE;
324 ctx_pa += BCOM_CTX_SIZE;
325 }
326
327 out_be32(&bcom_eng->regs->taskBar, tdt_pa);
328
329 /* Init 'always' initiator */
330 out_8(&bcom_eng->regs->ipr[BCOM_INITIATOR_ALWAYS], BCOM_IPR_ALWAYS);
331
332 /* Disable COMM Bus Prefetch on the original 5200; it's broken */
333 if ((mfspr(SPRN_SVR) & MPC5200_SVR_MASK) == MPC5200_SVR)
334 bcom_disable_prefetch();
335
336 /* Init lock */
337 spin_lock_init(&bcom_eng->lock);
338
339 return 0;
340}
341
342static void
343bcom_engine_cleanup(void)
344{
345 int task;
346
347 /* Stop all tasks */
348 for (task=0; task<BCOM_MAX_TASKS; task++)
349 {
350 out_be16(&bcom_eng->regs->tcr[task], 0);
351 out_8(&bcom_eng->regs->ipr[task], 0);
352 }
353
354 out_be32(&bcom_eng->regs->taskBar, 0ul);
355
356 /* Release the SRAM zones */
357 bcom_sram_free(bcom_eng->tdt);
358 bcom_sram_free(bcom_eng->ctx);
359 bcom_sram_free(bcom_eng->var);
360 bcom_sram_free(bcom_eng->fdt);
361}
362
363
364/* ======================================================================== */
365/* OF platform driver */
366/* ======================================================================== */
367
368static int __devinit mpc52xx_bcom_probe(struct platform_device *op)
369{
370 struct device_node *ofn_sram;
371 struct resource res_bcom;
372
373 int rv;
374
375 /* Inform user we're ok so far */
376 printk(KERN_INFO "DMA: MPC52xx BestComm driver\n");
377
378 /* Get the bestcomm node */
379 of_node_get(op->dev.of_node);
380
381 /* Prepare SRAM */
382 ofn_sram = of_find_matching_node(NULL, mpc52xx_sram_ids);
383 if (!ofn_sram) {
384 printk(KERN_ERR DRIVER_NAME ": "
385 "No SRAM found in device tree\n");
386 rv = -ENODEV;
387 goto error_ofput;
388 }
389 rv = bcom_sram_init(ofn_sram, DRIVER_NAME);
390 of_node_put(ofn_sram);
391
392 if (rv) {
393 printk(KERN_ERR DRIVER_NAME ": "
394 "Error in SRAM init\n");
395 goto error_ofput;
396 }
397
398 /* Get a clean struct */
399 bcom_eng = kzalloc(sizeof(struct bcom_engine), GFP_KERNEL);
400 if (!bcom_eng) {
401 printk(KERN_ERR DRIVER_NAME ": "
402 "Can't allocate state structure\n");
403 rv = -ENOMEM;
404 goto error_sramclean;
405 }
406
407 /* Save the node */
408 bcom_eng->ofnode = op->dev.of_node;
409
410 /* Get, reserve & map io */
411 if (of_address_to_resource(op->dev.of_node, 0, &res_bcom)) {
412 printk(KERN_ERR DRIVER_NAME ": "
413 "Can't get resource\n");
414 rv = -EINVAL;
415 goto error_sramclean;
416 }
417
418 if (!request_mem_region(res_bcom.start, sizeof(struct mpc52xx_sdma),
419 DRIVER_NAME)) {
420 printk(KERN_ERR DRIVER_NAME ": "
421 "Can't request registers region\n");
422 rv = -EBUSY;
423 goto error_sramclean;
424 }
425
426 bcom_eng->regs_base = res_bcom.start;
427 bcom_eng->regs = ioremap(res_bcom.start, sizeof(struct mpc52xx_sdma));
428 if (!bcom_eng->regs) {
429 printk(KERN_ERR DRIVER_NAME ": "
430 "Can't map registers\n");
431 rv = -ENOMEM;
432 goto error_release;
433 }
434
435 /* Now, do the real init */
436 rv = bcom_engine_init();
437 if (rv)
438 goto error_unmap;
439
440 /* Done ! */
441 printk(KERN_INFO "DMA: MPC52xx BestComm engine @%08lx ok !\n",
442 (long)bcom_eng->regs_base);
443
444 return 0;
445
446 /* Error path */
447error_unmap:
448 iounmap(bcom_eng->regs);
449error_release:
450 release_mem_region(res_bcom.start, sizeof(struct mpc52xx_sdma));
451error_sramclean:
452 kfree(bcom_eng);
453 bcom_sram_cleanup();
454error_ofput:
455 of_node_put(op->dev.of_node);
456
457 printk(KERN_ERR "DMA: MPC52xx BestComm init failed !\n");
458
459 return rv;
460}
461
462
463static int mpc52xx_bcom_remove(struct platform_device *op)
464{
465 /* Clean up the engine */
466 bcom_engine_cleanup();
467
468 /* Cleanup SRAM */
469 bcom_sram_cleanup();
470
471 /* Release regs */
472 iounmap(bcom_eng->regs);
473 release_mem_region(bcom_eng->regs_base, sizeof(struct mpc52xx_sdma));
474
475 /* Release the node */
476 of_node_put(bcom_eng->ofnode);
477
478 /* Release memory */
479 kfree(bcom_eng);
480 bcom_eng = NULL;
481
482 return 0;
483}
484
485static struct of_device_id mpc52xx_bcom_of_match[] = {
486 { .compatible = "fsl,mpc5200-bestcomm", },
487 { .compatible = "mpc5200-bestcomm", },
488 {},
489};
490
491MODULE_DEVICE_TABLE(of, mpc52xx_bcom_of_match);
492
493
494static struct platform_driver mpc52xx_bcom_of_platform_driver = {
495 .probe = mpc52xx_bcom_probe,
496 .remove = mpc52xx_bcom_remove,
497 .driver = {
498 .name = DRIVER_NAME,
499 .owner = THIS_MODULE,
500 .of_match_table = mpc52xx_bcom_of_match,
501 },
502};
503
504
505/* ======================================================================== */
506/* Module */
507/* ======================================================================== */
508
509static int __init
510mpc52xx_bcom_init(void)
511{
512 return platform_driver_register(&mpc52xx_bcom_of_platform_driver);
513}
514
515static void __exit
516mpc52xx_bcom_exit(void)
517{
518 platform_driver_unregister(&mpc52xx_bcom_of_platform_driver);
519}
520
521/* If we're not a module, we must make sure everything is setup before */
522/* anyone tries to use us ... that's why we use subsys_initcall instead */
523/* of module_init. */
524subsys_initcall(mpc52xx_bcom_init);
525module_exit(mpc52xx_bcom_exit);
526
527MODULE_DESCRIPTION("Freescale MPC52xx BestComm DMA");
528MODULE_AUTHOR("Sylvain Munaut <tnt@246tNt.com>");
529MODULE_AUTHOR("Andrey Volkov <avolkov@varma-el.com>");
530MODULE_AUTHOR("Dale Farnsworth <dfarnsworth@mvista.com>");
531MODULE_LICENSE("GPL v2");
532
diff --git a/arch/powerpc/sysdev/bestcomm/bestcomm.h b/arch/powerpc/sysdev/bestcomm/bestcomm.h
deleted file mode 100644
index a0e2e6b19b57..000000000000
--- a/arch/powerpc/sysdev/bestcomm/bestcomm.h
+++ /dev/null
@@ -1,213 +0,0 @@
1/*
2 * Public header for the MPC52xx processor BestComm driver
3 *
4 *
5 * Copyright (C) 2006 Sylvain Munaut <tnt@246tNt.com>
6 * Copyright (C) 2005 Varma Electronics Oy,
7 * ( by Andrey Volkov <avolkov@varma-el.com> )
8 * Copyright (C) 2003-2004 MontaVista, Software, Inc.
9 * ( by Dale Farnsworth <dfarnsworth@mvista.com> )
10 *
11 * This file is licensed under the terms of the GNU General Public License
12 * version 2. This program is licensed "as is" without any warranty of any
13 * kind, whether express or implied.
14 */
15
16#ifndef __BESTCOMM_H__
17#define __BESTCOMM_H__
18
19/**
20 * struct bcom_bd - Structure describing a generic BestComm buffer descriptor
21 * @status: The current status of this buffer. Exact meaning depends on the
22 * task type
23 * @data: An array of u32 extra data. Size of array is task dependent.
24 *
25 * Note: Don't dereference a bcom_bd pointer as an array. The size of the
26 * bcom_bd is variable. Use bcom_get_bd() instead.
27 */
28struct bcom_bd {
29 u32 status;
30 u32 data[0]; /* variable payload size */
31};
32
33/* ======================================================================== */
34/* Generic task management */
35/* ======================================================================== */
36
37/**
38 * struct bcom_task - Structure describing a loaded BestComm task
39 *
40 * This structure is never built by the driver it self. It's built and
41 * filled the intermediate layer of the BestComm API, the task dependent
42 * support code.
43 *
44 * Most likely you don't need to poke around inside this structure. The
45 * fields are exposed in the header just for the sake of inline functions
46 */
47struct bcom_task {
48 unsigned int tasknum;
49 unsigned int flags;
50 int irq;
51
52 struct bcom_bd *bd;
53 phys_addr_t bd_pa;
54 void **cookie;
55 unsigned short index;
56 unsigned short outdex;
57 unsigned int num_bd;
58 unsigned int bd_size;
59
60 void* priv;
61};
62
63#define BCOM_FLAGS_NONE 0x00000000ul
64#define BCOM_FLAGS_ENABLE_TASK (1ul << 0)
65
66/**
67 * bcom_enable - Enable a BestComm task
68 * @tsk: The BestComm task structure
69 *
70 * This function makes sure the given task is enabled and can be run
71 * by the BestComm engine as needed
72 */
73extern void bcom_enable(struct bcom_task *tsk);
74
75/**
76 * bcom_disable - Disable a BestComm task
77 * @tsk: The BestComm task structure
78 *
79 * This function disable a given task, making sure it's not executed
80 * by the BestComm engine.
81 */
82extern void bcom_disable(struct bcom_task *tsk);
83
84
85/**
86 * bcom_get_task_irq - Returns the irq number of a BestComm task
87 * @tsk: The BestComm task structure
88 */
89static inline int
90bcom_get_task_irq(struct bcom_task *tsk) {
91 return tsk->irq;
92}
93
94/* ======================================================================== */
95/* BD based tasks helpers */
96/* ======================================================================== */
97
98#define BCOM_BD_READY 0x40000000ul
99
100/** _bcom_next_index - Get next input index.
101 * @tsk: pointer to task structure
102 *
103 * Support function; Device drivers should not call this
104 */
105static inline int
106_bcom_next_index(struct bcom_task *tsk)
107{
108 return ((tsk->index + 1) == tsk->num_bd) ? 0 : tsk->index + 1;
109}
110
111/** _bcom_next_outdex - Get next output index.
112 * @tsk: pointer to task structure
113 *
114 * Support function; Device drivers should not call this
115 */
116static inline int
117_bcom_next_outdex(struct bcom_task *tsk)
118{
119 return ((tsk->outdex + 1) == tsk->num_bd) ? 0 : tsk->outdex + 1;
120}
121
122/**
123 * bcom_queue_empty - Checks if a BestComm task BD queue is empty
124 * @tsk: The BestComm task structure
125 */
126static inline int
127bcom_queue_empty(struct bcom_task *tsk)
128{
129 return tsk->index == tsk->outdex;
130}
131
132/**
133 * bcom_queue_full - Checks if a BestComm task BD queue is full
134 * @tsk: The BestComm task structure
135 */
136static inline int
137bcom_queue_full(struct bcom_task *tsk)
138{
139 return tsk->outdex == _bcom_next_index(tsk);
140}
141
142/**
143 * bcom_get_bd - Get a BD from the queue
144 * @tsk: The BestComm task structure
145 * index: Index of the BD to fetch
146 */
147static inline struct bcom_bd
148*bcom_get_bd(struct bcom_task *tsk, unsigned int index)
149{
150 /* A cast to (void*) so the address can be incremented by the
151 * real size instead of by sizeof(struct bcom_bd) */
152 return ((void *)tsk->bd) + (index * tsk->bd_size);
153}
154
155/**
156 * bcom_buffer_done - Checks if a BestComm
157 * @tsk: The BestComm task structure
158 */
159static inline int
160bcom_buffer_done(struct bcom_task *tsk)
161{
162 struct bcom_bd *bd;
163 if (bcom_queue_empty(tsk))
164 return 0;
165
166 bd = bcom_get_bd(tsk, tsk->outdex);
167 return !(bd->status & BCOM_BD_READY);
168}
169
170/**
171 * bcom_prepare_next_buffer - clear status of next available buffer.
172 * @tsk: The BestComm task structure
173 *
174 * Returns pointer to next buffer descriptor
175 */
176static inline struct bcom_bd *
177bcom_prepare_next_buffer(struct bcom_task *tsk)
178{
179 struct bcom_bd *bd;
180
181 bd = bcom_get_bd(tsk, tsk->index);
182 bd->status = 0; /* cleanup last status */
183 return bd;
184}
185
186static inline void
187bcom_submit_next_buffer(struct bcom_task *tsk, void *cookie)
188{
189 struct bcom_bd *bd = bcom_get_bd(tsk, tsk->index);
190
191 tsk->cookie[tsk->index] = cookie;
192 mb(); /* ensure the bd is really up-to-date */
193 bd->status |= BCOM_BD_READY;
194 tsk->index = _bcom_next_index(tsk);
195 if (tsk->flags & BCOM_FLAGS_ENABLE_TASK)
196 bcom_enable(tsk);
197}
198
199static inline void *
200bcom_retrieve_buffer(struct bcom_task *tsk, u32 *p_status, struct bcom_bd **p_bd)
201{
202 void *cookie = tsk->cookie[tsk->outdex];
203 struct bcom_bd *bd = bcom_get_bd(tsk, tsk->outdex);
204
205 if (p_status)
206 *p_status = bd->status;
207 if (p_bd)
208 *p_bd = bd;
209 tsk->outdex = _bcom_next_outdex(tsk);
210 return cookie;
211}
212
213#endif /* __BESTCOMM_H__ */
diff --git a/arch/powerpc/sysdev/bestcomm/bestcomm_priv.h b/arch/powerpc/sysdev/bestcomm/bestcomm_priv.h
deleted file mode 100644
index 3b52f3ffbdf8..000000000000
--- a/arch/powerpc/sysdev/bestcomm/bestcomm_priv.h
+++ /dev/null
@@ -1,350 +0,0 @@
1/*
2 * Private header for the MPC52xx processor BestComm driver
3 *
4 * By private, we mean that driver should not use it directly. It's meant
5 * to be used by the BestComm engine driver itself and by the intermediate
6 * layer between the core and the drivers.
7 *
8 * Copyright (C) 2006 Sylvain Munaut <tnt@246tNt.com>
9 * Copyright (C) 2005 Varma Electronics Oy,
10 * ( by Andrey Volkov <avolkov@varma-el.com> )
11 * Copyright (C) 2003-2004 MontaVista, Software, Inc.
12 * ( by Dale Farnsworth <dfarnsworth@mvista.com> )
13 *
14 * This file is licensed under the terms of the GNU General Public License
15 * version 2. This program is licensed "as is" without any warranty of any
16 * kind, whether express or implied.
17 */
18
19#ifndef __BESTCOMM_PRIV_H__
20#define __BESTCOMM_PRIV_H__
21
22#include <linux/spinlock.h>
23#include <linux/of.h>
24#include <asm/io.h>
25#include <asm/mpc52xx.h>
26
27#include "sram.h"
28
29
30/* ======================================================================== */
31/* Engine related stuff */
32/* ======================================================================== */
33
34/* Zones sizes and needed alignments */
35#define BCOM_MAX_TASKS 16
36#define BCOM_MAX_VAR 24
37#define BCOM_MAX_INC 8
38#define BCOM_MAX_FDT 64
39#define BCOM_MAX_CTX 20
40#define BCOM_CTX_SIZE (BCOM_MAX_CTX * sizeof(u32))
41#define BCOM_CTX_ALIGN 0x100
42#define BCOM_VAR_SIZE (BCOM_MAX_VAR * sizeof(u32))
43#define BCOM_INC_SIZE (BCOM_MAX_INC * sizeof(u32))
44#define BCOM_VAR_ALIGN 0x80
45#define BCOM_FDT_SIZE (BCOM_MAX_FDT * sizeof(u32))
46#define BCOM_FDT_ALIGN 0x100
47
48/**
49 * struct bcom_tdt - Task Descriptor Table Entry
50 *
51 */
52struct bcom_tdt {
53 u32 start;
54 u32 stop;
55 u32 var;
56 u32 fdt;
57 u32 exec_status; /* used internally by BestComm engine */
58 u32 mvtp; /* used internally by BestComm engine */
59 u32 context;
60 u32 litbase;
61};
62
63/**
64 * struct bcom_engine
65 *
66 * This holds all info needed globaly to handle the engine
67 */
68struct bcom_engine {
69 struct device_node *ofnode;
70 struct mpc52xx_sdma __iomem *regs;
71 phys_addr_t regs_base;
72
73 struct bcom_tdt *tdt;
74 u32 *ctx;
75 u32 *var;
76 u32 *fdt;
77
78 spinlock_t lock;
79};
80
81extern struct bcom_engine *bcom_eng;
82
83
84/* ======================================================================== */
85/* Tasks related stuff */
86/* ======================================================================== */
87
88/* Tasks image header */
89#define BCOM_TASK_MAGIC 0x4243544B /* 'BCTK' */
90
91struct bcom_task_header {
92 u32 magic;
93 u8 desc_size; /* the size fields */
94 u8 var_size; /* are given in number */
95 u8 inc_size; /* of 32-bits words */
96 u8 first_var;
97 u8 reserved[8];
98};
99
100/* Descriptors structure & co */
101#define BCOM_DESC_NOP 0x000001f8
102#define BCOM_LCD_MASK 0x80000000
103#define BCOM_DRD_EXTENDED 0x40000000
104#define BCOM_DRD_INITIATOR_SHIFT 21
105
106/* Tasks pragma */
107#define BCOM_PRAGMA_BIT_RSV 7 /* reserved pragma bit */
108#define BCOM_PRAGMA_BIT_PRECISE_INC 6 /* increment 0=when possible, */
109 /* 1=iter end */
110#define BCOM_PRAGMA_BIT_RST_ERROR_NO 5 /* don't reset errors on */
111 /* task enable */
112#define BCOM_PRAGMA_BIT_PACK 4 /* pack data enable */
113#define BCOM_PRAGMA_BIT_INTEGER 3 /* data alignment */
114 /* 0=frac(msb), 1=int(lsb) */
115#define BCOM_PRAGMA_BIT_SPECREAD 2 /* XLB speculative read */
116#define BCOM_PRAGMA_BIT_CW 1 /* write line buffer enable */
117#define BCOM_PRAGMA_BIT_RL 0 /* read line buffer enable */
118
119 /* Looks like XLB speculative read generates XLB errors when a buffer
120 * is at the end of the physical memory. i.e. when accessing the
121 * lasts words, the engine tries to prefetch the next but there is no
122 * next ...
123 */
124#define BCOM_STD_PRAGMA ((0 << BCOM_PRAGMA_BIT_RSV) | \
125 (0 << BCOM_PRAGMA_BIT_PRECISE_INC) | \
126 (0 << BCOM_PRAGMA_BIT_RST_ERROR_NO) | \
127 (0 << BCOM_PRAGMA_BIT_PACK) | \
128 (0 << BCOM_PRAGMA_BIT_INTEGER) | \
129 (0 << BCOM_PRAGMA_BIT_SPECREAD) | \
130 (1 << BCOM_PRAGMA_BIT_CW) | \
131 (1 << BCOM_PRAGMA_BIT_RL))
132
133#define BCOM_PCI_PRAGMA ((0 << BCOM_PRAGMA_BIT_RSV) | \
134 (0 << BCOM_PRAGMA_BIT_PRECISE_INC) | \
135 (0 << BCOM_PRAGMA_BIT_RST_ERROR_NO) | \
136 (0 << BCOM_PRAGMA_BIT_PACK) | \
137 (1 << BCOM_PRAGMA_BIT_INTEGER) | \
138 (0 << BCOM_PRAGMA_BIT_SPECREAD) | \
139 (1 << BCOM_PRAGMA_BIT_CW) | \
140 (1 << BCOM_PRAGMA_BIT_RL))
141
142#define BCOM_ATA_PRAGMA BCOM_STD_PRAGMA
143#define BCOM_CRC16_DP_0_PRAGMA BCOM_STD_PRAGMA
144#define BCOM_CRC16_DP_1_PRAGMA BCOM_STD_PRAGMA
145#define BCOM_FEC_RX_BD_PRAGMA BCOM_STD_PRAGMA
146#define BCOM_FEC_TX_BD_PRAGMA BCOM_STD_PRAGMA
147#define BCOM_GEN_DP_0_PRAGMA BCOM_STD_PRAGMA
148#define BCOM_GEN_DP_1_PRAGMA BCOM_STD_PRAGMA
149#define BCOM_GEN_DP_2_PRAGMA BCOM_STD_PRAGMA
150#define BCOM_GEN_DP_3_PRAGMA BCOM_STD_PRAGMA
151#define BCOM_GEN_DP_BD_0_PRAGMA BCOM_STD_PRAGMA
152#define BCOM_GEN_DP_BD_1_PRAGMA BCOM_STD_PRAGMA
153#define BCOM_GEN_RX_BD_PRAGMA BCOM_STD_PRAGMA
154#define BCOM_GEN_TX_BD_PRAGMA BCOM_STD_PRAGMA
155#define BCOM_GEN_LPC_PRAGMA BCOM_STD_PRAGMA
156#define BCOM_PCI_RX_PRAGMA BCOM_PCI_PRAGMA
157#define BCOM_PCI_TX_PRAGMA BCOM_PCI_PRAGMA
158
159/* Initiators number */
160#define BCOM_INITIATOR_ALWAYS 0
161#define BCOM_INITIATOR_SCTMR_0 1
162#define BCOM_INITIATOR_SCTMR_1 2
163#define BCOM_INITIATOR_FEC_RX 3
164#define BCOM_INITIATOR_FEC_TX 4
165#define BCOM_INITIATOR_ATA_RX 5
166#define BCOM_INITIATOR_ATA_TX 6
167#define BCOM_INITIATOR_SCPCI_RX 7
168#define BCOM_INITIATOR_SCPCI_TX 8
169#define BCOM_INITIATOR_PSC3_RX 9
170#define BCOM_INITIATOR_PSC3_TX 10
171#define BCOM_INITIATOR_PSC2_RX 11
172#define BCOM_INITIATOR_PSC2_TX 12
173#define BCOM_INITIATOR_PSC1_RX 13
174#define BCOM_INITIATOR_PSC1_TX 14
175#define BCOM_INITIATOR_SCTMR_2 15
176#define BCOM_INITIATOR_SCLPC 16
177#define BCOM_INITIATOR_PSC5_RX 17
178#define BCOM_INITIATOR_PSC5_TX 18
179#define BCOM_INITIATOR_PSC4_RX 19
180#define BCOM_INITIATOR_PSC4_TX 20
181#define BCOM_INITIATOR_I2C2_RX 21
182#define BCOM_INITIATOR_I2C2_TX 22
183#define BCOM_INITIATOR_I2C1_RX 23
184#define BCOM_INITIATOR_I2C1_TX 24
185#define BCOM_INITIATOR_PSC6_RX 25
186#define BCOM_INITIATOR_PSC6_TX 26
187#define BCOM_INITIATOR_IRDA_RX 25
188#define BCOM_INITIATOR_IRDA_TX 26
189#define BCOM_INITIATOR_SCTMR_3 27
190#define BCOM_INITIATOR_SCTMR_4 28
191#define BCOM_INITIATOR_SCTMR_5 29
192#define BCOM_INITIATOR_SCTMR_6 30
193#define BCOM_INITIATOR_SCTMR_7 31
194
195/* Initiators priorities */
196#define BCOM_IPR_ALWAYS 7
197#define BCOM_IPR_SCTMR_0 2
198#define BCOM_IPR_SCTMR_1 2
199#define BCOM_IPR_FEC_RX 6
200#define BCOM_IPR_FEC_TX 5
201#define BCOM_IPR_ATA_RX 7
202#define BCOM_IPR_ATA_TX 7
203#define BCOM_IPR_SCPCI_RX 2
204#define BCOM_IPR_SCPCI_TX 2
205#define BCOM_IPR_PSC3_RX 2
206#define BCOM_IPR_PSC3_TX 2
207#define BCOM_IPR_PSC2_RX 2
208#define BCOM_IPR_PSC2_TX 2
209#define BCOM_IPR_PSC1_RX 2
210#define BCOM_IPR_PSC1_TX 2
211#define BCOM_IPR_SCTMR_2 2
212#define BCOM_IPR_SCLPC 2
213#define BCOM_IPR_PSC5_RX 2
214#define BCOM_IPR_PSC5_TX 2
215#define BCOM_IPR_PSC4_RX 2
216#define BCOM_IPR_PSC4_TX 2
217#define BCOM_IPR_I2C2_RX 2
218#define BCOM_IPR_I2C2_TX 2
219#define BCOM_IPR_I2C1_RX 2
220#define BCOM_IPR_I2C1_TX 2
221#define BCOM_IPR_PSC6_RX 2
222#define BCOM_IPR_PSC6_TX 2
223#define BCOM_IPR_IRDA_RX 2
224#define BCOM_IPR_IRDA_TX 2
225#define BCOM_IPR_SCTMR_3 2
226#define BCOM_IPR_SCTMR_4 2
227#define BCOM_IPR_SCTMR_5 2
228#define BCOM_IPR_SCTMR_6 2
229#define BCOM_IPR_SCTMR_7 2
230
231
232/* ======================================================================== */
233/* API */
234/* ======================================================================== */
235
236extern struct bcom_task *bcom_task_alloc(int bd_count, int bd_size, int priv_size);
237extern void bcom_task_free(struct bcom_task *tsk);
238extern int bcom_load_image(int task, u32 *task_image);
239extern void bcom_set_initiator(int task, int initiator);
240
241
242#define TASK_ENABLE 0x8000
243
244/**
245 * bcom_disable_prefetch - Hook to disable bus prefetching
246 *
247 * ATA DMA and the original MPC5200 need this due to silicon bugs. At the
248 * moment disabling prefetch is a one-way street. There is no mechanism
249 * in place to turn prefetch back on after it has been disabled. There is
250 * no reason it couldn't be done, it would just be more complex to implement.
251 */
252static inline void bcom_disable_prefetch(void)
253{
254 u16 regval;
255
256 regval = in_be16(&bcom_eng->regs->PtdCntrl);
257 out_be16(&bcom_eng->regs->PtdCntrl, regval | 1);
258};
259
260static inline void
261bcom_enable_task(int task)
262{
263 u16 reg;
264 reg = in_be16(&bcom_eng->regs->tcr[task]);
265 out_be16(&bcom_eng->regs->tcr[task], reg | TASK_ENABLE);
266}
267
268static inline void
269bcom_disable_task(int task)
270{
271 u16 reg = in_be16(&bcom_eng->regs->tcr[task]);
272 out_be16(&bcom_eng->regs->tcr[task], reg & ~TASK_ENABLE);
273}
274
275
276static inline u32 *
277bcom_task_desc(int task)
278{
279 return bcom_sram_pa2va(bcom_eng->tdt[task].start);
280}
281
282static inline int
283bcom_task_num_descs(int task)
284{
285 return (bcom_eng->tdt[task].stop - bcom_eng->tdt[task].start)/sizeof(u32) + 1;
286}
287
288static inline u32 *
289bcom_task_var(int task)
290{
291 return bcom_sram_pa2va(bcom_eng->tdt[task].var);
292}
293
294static inline u32 *
295bcom_task_inc(int task)
296{
297 return &bcom_task_var(task)[BCOM_MAX_VAR];
298}
299
300
301static inline int
302bcom_drd_is_extended(u32 desc)
303{
304 return (desc) & BCOM_DRD_EXTENDED;
305}
306
307static inline int
308bcom_desc_is_drd(u32 desc)
309{
310 return !(desc & BCOM_LCD_MASK) && desc != BCOM_DESC_NOP;
311}
312
313static inline int
314bcom_desc_initiator(u32 desc)
315{
316 return (desc >> BCOM_DRD_INITIATOR_SHIFT) & 0x1f;
317}
318
319static inline void
320bcom_set_desc_initiator(u32 *desc, int initiator)
321{
322 *desc = (*desc & ~(0x1f << BCOM_DRD_INITIATOR_SHIFT)) |
323 ((initiator & 0x1f) << BCOM_DRD_INITIATOR_SHIFT);
324}
325
326
327static inline void
328bcom_set_task_pragma(int task, int pragma)
329{
330 u32 *fdt = &bcom_eng->tdt[task].fdt;
331 *fdt = (*fdt & ~0xff) | pragma;
332}
333
334static inline void
335bcom_set_task_auto_start(int task, int next_task)
336{
337 u16 __iomem *tcr = &bcom_eng->regs->tcr[task];
338 out_be16(tcr, (in_be16(tcr) & ~0xff) | 0x00c0 | next_task);
339}
340
341static inline void
342bcom_set_tcr_initiator(int task, int initiator)
343{
344 u16 __iomem *tcr = &bcom_eng->regs->tcr[task];
345 out_be16(tcr, (in_be16(tcr) & ~0x1f00) | ((initiator & 0x1f) << 8));
346}
347
348
349#endif /* __BESTCOMM_PRIV_H__ */
350
diff --git a/arch/powerpc/sysdev/bestcomm/fec.c b/arch/powerpc/sysdev/bestcomm/fec.c
deleted file mode 100644
index 957a988d23ea..000000000000
--- a/arch/powerpc/sysdev/bestcomm/fec.c
+++ /dev/null
@@ -1,270 +0,0 @@
1/*
2 * Bestcomm FEC tasks driver
3 *
4 *
5 * Copyright (C) 2006-2007 Sylvain Munaut <tnt@246tNt.com>
6 * Copyright (C) 2003-2004 MontaVista, Software, Inc.
7 * ( by Dale Farnsworth <dfarnsworth@mvista.com> )
8 *
9 * This file is licensed under the terms of the GNU General Public License
10 * version 2. This program is licensed "as is" without any warranty of any
11 * kind, whether express or implied.
12 */
13
14#include <linux/kernel.h>
15#include <linux/module.h>
16#include <linux/types.h>
17#include <asm/io.h>
18
19#include "bestcomm.h"
20#include "bestcomm_priv.h"
21#include "fec.h"
22
23
24/* ======================================================================== */
25/* Task image/var/inc */
26/* ======================================================================== */
27
28/* fec tasks images */
29extern u32 bcom_fec_rx_task[];
30extern u32 bcom_fec_tx_task[];
31
32/* rx task vars that need to be set before enabling the task */
33struct bcom_fec_rx_var {
34 u32 enable; /* (u16*) address of task's control register */
35 u32 fifo; /* (u32*) address of fec's fifo */
36 u32 bd_base; /* (struct bcom_bd*) beginning of ring buffer */
37 u32 bd_last; /* (struct bcom_bd*) end of ring buffer */
38 u32 bd_start; /* (struct bcom_bd*) current bd */
39 u32 buffer_size; /* size of receive buffer */
40};
41
42/* rx task incs that need to be set before enabling the task */
43struct bcom_fec_rx_inc {
44 u16 pad0;
45 s16 incr_bytes;
46 u16 pad1;
47 s16 incr_dst;
48 u16 pad2;
49 s16 incr_dst_ma;
50};
51
52/* tx task vars that need to be set before enabling the task */
53struct bcom_fec_tx_var {
54 u32 DRD; /* (u32*) address of self-modified DRD */
55 u32 fifo; /* (u32*) address of fec's fifo */
56 u32 enable; /* (u16*) address of task's control register */
57 u32 bd_base; /* (struct bcom_bd*) beginning of ring buffer */
58 u32 bd_last; /* (struct bcom_bd*) end of ring buffer */
59 u32 bd_start; /* (struct bcom_bd*) current bd */
60 u32 buffer_size; /* set by uCode for each packet */
61};
62
63/* tx task incs that need to be set before enabling the task */
64struct bcom_fec_tx_inc {
65 u16 pad0;
66 s16 incr_bytes;
67 u16 pad1;
68 s16 incr_src;
69 u16 pad2;
70 s16 incr_src_ma;
71};
72
73/* private structure in the task */
74struct bcom_fec_priv {
75 phys_addr_t fifo;
76 int maxbufsize;
77};
78
79
80/* ======================================================================== */
81/* Task support code */
82/* ======================================================================== */
83
84struct bcom_task *
85bcom_fec_rx_init(int queue_len, phys_addr_t fifo, int maxbufsize)
86{
87 struct bcom_task *tsk;
88 struct bcom_fec_priv *priv;
89
90 tsk = bcom_task_alloc(queue_len, sizeof(struct bcom_fec_bd),
91 sizeof(struct bcom_fec_priv));
92 if (!tsk)
93 return NULL;
94
95 tsk->flags = BCOM_FLAGS_NONE;
96
97 priv = tsk->priv;
98 priv->fifo = fifo;
99 priv->maxbufsize = maxbufsize;
100
101 if (bcom_fec_rx_reset(tsk)) {
102 bcom_task_free(tsk);
103 return NULL;
104 }
105
106 return tsk;
107}
108EXPORT_SYMBOL_GPL(bcom_fec_rx_init);
109
110int
111bcom_fec_rx_reset(struct bcom_task *tsk)
112{
113 struct bcom_fec_priv *priv = tsk->priv;
114 struct bcom_fec_rx_var *var;
115 struct bcom_fec_rx_inc *inc;
116
117 /* Shutdown the task */
118 bcom_disable_task(tsk->tasknum);
119
120 /* Reset the microcode */
121 var = (struct bcom_fec_rx_var *) bcom_task_var(tsk->tasknum);
122 inc = (struct bcom_fec_rx_inc *) bcom_task_inc(tsk->tasknum);
123
124 if (bcom_load_image(tsk->tasknum, bcom_fec_rx_task))
125 return -1;
126
127 var->enable = bcom_eng->regs_base +
128 offsetof(struct mpc52xx_sdma, tcr[tsk->tasknum]);
129 var->fifo = (u32) priv->fifo;
130 var->bd_base = tsk->bd_pa;
131 var->bd_last = tsk->bd_pa + ((tsk->num_bd-1) * tsk->bd_size);
132 var->bd_start = tsk->bd_pa;
133 var->buffer_size = priv->maxbufsize;
134
135 inc->incr_bytes = -(s16)sizeof(u32); /* These should be in the */
136 inc->incr_dst = sizeof(u32); /* task image, but we stick */
137 inc->incr_dst_ma= sizeof(u8); /* to the official ones */
138
139 /* Reset the BDs */
140 tsk->index = 0;
141 tsk->outdex = 0;
142
143 memset(tsk->bd, 0x00, tsk->num_bd * tsk->bd_size);
144
145 /* Configure some stuff */
146 bcom_set_task_pragma(tsk->tasknum, BCOM_FEC_RX_BD_PRAGMA);
147 bcom_set_task_auto_start(tsk->tasknum, tsk->tasknum);
148
149 out_8(&bcom_eng->regs->ipr[BCOM_INITIATOR_FEC_RX], BCOM_IPR_FEC_RX);
150
151 out_be32(&bcom_eng->regs->IntPend, 1<<tsk->tasknum); /* Clear ints */
152
153 return 0;
154}
155EXPORT_SYMBOL_GPL(bcom_fec_rx_reset);
156
157void
158bcom_fec_rx_release(struct bcom_task *tsk)
159{
160 /* Nothing special for the FEC tasks */
161 bcom_task_free(tsk);
162}
163EXPORT_SYMBOL_GPL(bcom_fec_rx_release);
164
165
166
167 /* Return 2nd to last DRD */
168 /* This is an ugly hack, but at least it's only done
169 once at initialization */
170static u32 *self_modified_drd(int tasknum)
171{
172 u32 *desc;
173 int num_descs;
174 int drd_count;
175 int i;
176
177 num_descs = bcom_task_num_descs(tasknum);
178 desc = bcom_task_desc(tasknum) + num_descs - 1;
179 drd_count = 0;
180 for (i=0; i<num_descs; i++, desc--)
181 if (bcom_desc_is_drd(*desc) && ++drd_count == 3)
182 break;
183 return desc;
184}
185
186struct bcom_task *
187bcom_fec_tx_init(int queue_len, phys_addr_t fifo)
188{
189 struct bcom_task *tsk;
190 struct bcom_fec_priv *priv;
191
192 tsk = bcom_task_alloc(queue_len, sizeof(struct bcom_fec_bd),
193 sizeof(struct bcom_fec_priv));
194 if (!tsk)
195 return NULL;
196
197 tsk->flags = BCOM_FLAGS_ENABLE_TASK;
198
199 priv = tsk->priv;
200 priv->fifo = fifo;
201
202 if (bcom_fec_tx_reset(tsk)) {
203 bcom_task_free(tsk);
204 return NULL;
205 }
206
207 return tsk;
208}
209EXPORT_SYMBOL_GPL(bcom_fec_tx_init);
210
211int
212bcom_fec_tx_reset(struct bcom_task *tsk)
213{
214 struct bcom_fec_priv *priv = tsk->priv;
215 struct bcom_fec_tx_var *var;
216 struct bcom_fec_tx_inc *inc;
217
218 /* Shutdown the task */
219 bcom_disable_task(tsk->tasknum);
220
221 /* Reset the microcode */
222 var = (struct bcom_fec_tx_var *) bcom_task_var(tsk->tasknum);
223 inc = (struct bcom_fec_tx_inc *) bcom_task_inc(tsk->tasknum);
224
225 if (bcom_load_image(tsk->tasknum, bcom_fec_tx_task))
226 return -1;
227
228 var->enable = bcom_eng->regs_base +
229 offsetof(struct mpc52xx_sdma, tcr[tsk->tasknum]);
230 var->fifo = (u32) priv->fifo;
231 var->DRD = bcom_sram_va2pa(self_modified_drd(tsk->tasknum));
232 var->bd_base = tsk->bd_pa;
233 var->bd_last = tsk->bd_pa + ((tsk->num_bd-1) * tsk->bd_size);
234 var->bd_start = tsk->bd_pa;
235
236 inc->incr_bytes = -(s16)sizeof(u32); /* These should be in the */
237 inc->incr_src = sizeof(u32); /* task image, but we stick */
238 inc->incr_src_ma= sizeof(u8); /* to the official ones */
239
240 /* Reset the BDs */
241 tsk->index = 0;
242 tsk->outdex = 0;
243
244 memset(tsk->bd, 0x00, tsk->num_bd * tsk->bd_size);
245
246 /* Configure some stuff */
247 bcom_set_task_pragma(tsk->tasknum, BCOM_FEC_TX_BD_PRAGMA);
248 bcom_set_task_auto_start(tsk->tasknum, tsk->tasknum);
249
250 out_8(&bcom_eng->regs->ipr[BCOM_INITIATOR_FEC_TX], BCOM_IPR_FEC_TX);
251
252 out_be32(&bcom_eng->regs->IntPend, 1<<tsk->tasknum); /* Clear ints */
253
254 return 0;
255}
256EXPORT_SYMBOL_GPL(bcom_fec_tx_reset);
257
258void
259bcom_fec_tx_release(struct bcom_task *tsk)
260{
261 /* Nothing special for the FEC tasks */
262 bcom_task_free(tsk);
263}
264EXPORT_SYMBOL_GPL(bcom_fec_tx_release);
265
266
267MODULE_DESCRIPTION("BestComm FEC tasks driver");
268MODULE_AUTHOR("Dale Farnsworth <dfarnsworth@mvista.com>");
269MODULE_LICENSE("GPL v2");
270
diff --git a/arch/powerpc/sysdev/bestcomm/fec.h b/arch/powerpc/sysdev/bestcomm/fec.h
deleted file mode 100644
index ee565d94d503..000000000000
--- a/arch/powerpc/sysdev/bestcomm/fec.h
+++ /dev/null
@@ -1,61 +0,0 @@
1/*
2 * Header for Bestcomm FEC tasks driver
3 *
4 *
5 * Copyright (C) 2006-2007 Sylvain Munaut <tnt@246tNt.com>
6 * Copyright (C) 2003-2004 MontaVista, Software, Inc.
7 * ( by Dale Farnsworth <dfarnsworth@mvista.com> )
8 *
9 * This file is licensed under the terms of the GNU General Public License
10 * version 2. This program is licensed "as is" without any warranty of any
11 * kind, whether express or implied.
12 */
13
14#ifndef __BESTCOMM_FEC_H__
15#define __BESTCOMM_FEC_H__
16
17
18struct bcom_fec_bd {
19 u32 status;
20 u32 skb_pa;
21};
22
23#define BCOM_FEC_TX_BD_TFD 0x08000000ul /* transmit frame done */
24#define BCOM_FEC_TX_BD_TC 0x04000000ul /* transmit CRC */
25#define BCOM_FEC_TX_BD_ABC 0x02000000ul /* append bad CRC */
26
27#define BCOM_FEC_RX_BD_L 0x08000000ul /* buffer is last in frame */
28#define BCOM_FEC_RX_BD_BC 0x00800000ul /* DA is broadcast */
29#define BCOM_FEC_RX_BD_MC 0x00400000ul /* DA is multicast and not broadcast */
30#define BCOM_FEC_RX_BD_LG 0x00200000ul /* Rx frame length violation */
31#define BCOM_FEC_RX_BD_NO 0x00100000ul /* Rx non-octet aligned frame */
32#define BCOM_FEC_RX_BD_CR 0x00040000ul /* Rx CRC error */
33#define BCOM_FEC_RX_BD_OV 0x00020000ul /* overrun */
34#define BCOM_FEC_RX_BD_TR 0x00010000ul /* Rx frame truncated */
35#define BCOM_FEC_RX_BD_LEN_MASK 0x000007fful /* mask for length of received frame */
36#define BCOM_FEC_RX_BD_ERRORS (BCOM_FEC_RX_BD_LG | BCOM_FEC_RX_BD_NO | \
37 BCOM_FEC_RX_BD_CR | BCOM_FEC_RX_BD_OV | BCOM_FEC_RX_BD_TR)
38
39
40extern struct bcom_task *
41bcom_fec_rx_init(int queue_len, phys_addr_t fifo, int maxbufsize);
42
43extern int
44bcom_fec_rx_reset(struct bcom_task *tsk);
45
46extern void
47bcom_fec_rx_release(struct bcom_task *tsk);
48
49
50extern struct bcom_task *
51bcom_fec_tx_init(int queue_len, phys_addr_t fifo);
52
53extern int
54bcom_fec_tx_reset(struct bcom_task *tsk);
55
56extern void
57bcom_fec_tx_release(struct bcom_task *tsk);
58
59
60#endif /* __BESTCOMM_FEC_H__ */
61
diff --git a/arch/powerpc/sysdev/bestcomm/gen_bd.c b/arch/powerpc/sysdev/bestcomm/gen_bd.c
deleted file mode 100644
index e0a53e3147b2..000000000000
--- a/arch/powerpc/sysdev/bestcomm/gen_bd.c
+++ /dev/null
@@ -1,354 +0,0 @@
1/*
2 * Driver for MPC52xx processor BestComm General Buffer Descriptor
3 *
4 * Copyright (C) 2007 Sylvain Munaut <tnt@246tNt.com>
5 * Copyright (C) 2006 AppSpec Computer Technologies Corp.
6 * Jeff Gibbons <jeff.gibbons@appspec.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 2 as published
10 * by the Free Software Foundation.
11 *
12 */
13
14#include <linux/module.h>
15#include <linux/kernel.h>
16#include <linux/string.h>
17#include <linux/types.h>
18#include <asm/errno.h>
19#include <asm/io.h>
20
21#include <asm/mpc52xx.h>
22#include <asm/mpc52xx_psc.h>
23
24#include "bestcomm.h"
25#include "bestcomm_priv.h"
26#include "gen_bd.h"
27
28
29/* ======================================================================== */
30/* Task image/var/inc */
31/* ======================================================================== */
32
33/* gen_bd tasks images */
34extern u32 bcom_gen_bd_rx_task[];
35extern u32 bcom_gen_bd_tx_task[];
36
37/* rx task vars that need to be set before enabling the task */
38struct bcom_gen_bd_rx_var {
39 u32 enable; /* (u16*) address of task's control register */
40 u32 fifo; /* (u32*) address of gen_bd's fifo */
41 u32 bd_base; /* (struct bcom_bd*) beginning of ring buffer */
42 u32 bd_last; /* (struct bcom_bd*) end of ring buffer */
43 u32 bd_start; /* (struct bcom_bd*) current bd */
44 u32 buffer_size; /* size of receive buffer */
45};
46
47/* rx task incs that need to be set before enabling the task */
48struct bcom_gen_bd_rx_inc {
49 u16 pad0;
50 s16 incr_bytes;
51 u16 pad1;
52 s16 incr_dst;
53};
54
55/* tx task vars that need to be set before enabling the task */
56struct bcom_gen_bd_tx_var {
57 u32 fifo; /* (u32*) address of gen_bd's fifo */
58 u32 enable; /* (u16*) address of task's control register */
59 u32 bd_base; /* (struct bcom_bd*) beginning of ring buffer */
60 u32 bd_last; /* (struct bcom_bd*) end of ring buffer */
61 u32 bd_start; /* (struct bcom_bd*) current bd */
62 u32 buffer_size; /* set by uCode for each packet */
63};
64
65/* tx task incs that need to be set before enabling the task */
66struct bcom_gen_bd_tx_inc {
67 u16 pad0;
68 s16 incr_bytes;
69 u16 pad1;
70 s16 incr_src;
71 u16 pad2;
72 s16 incr_src_ma;
73};
74
75/* private structure */
76struct bcom_gen_bd_priv {
77 phys_addr_t fifo;
78 int initiator;
79 int ipr;
80 int maxbufsize;
81};
82
83
84/* ======================================================================== */
85/* Task support code */
86/* ======================================================================== */
87
88struct bcom_task *
89bcom_gen_bd_rx_init(int queue_len, phys_addr_t fifo,
90 int initiator, int ipr, int maxbufsize)
91{
92 struct bcom_task *tsk;
93 struct bcom_gen_bd_priv *priv;
94
95 tsk = bcom_task_alloc(queue_len, sizeof(struct bcom_gen_bd),
96 sizeof(struct bcom_gen_bd_priv));
97 if (!tsk)
98 return NULL;
99
100 tsk->flags = BCOM_FLAGS_NONE;
101
102 priv = tsk->priv;
103 priv->fifo = fifo;
104 priv->initiator = initiator;
105 priv->ipr = ipr;
106 priv->maxbufsize = maxbufsize;
107
108 if (bcom_gen_bd_rx_reset(tsk)) {
109 bcom_task_free(tsk);
110 return NULL;
111 }
112
113 return tsk;
114}
115EXPORT_SYMBOL_GPL(bcom_gen_bd_rx_init);
116
117int
118bcom_gen_bd_rx_reset(struct bcom_task *tsk)
119{
120 struct bcom_gen_bd_priv *priv = tsk->priv;
121 struct bcom_gen_bd_rx_var *var;
122 struct bcom_gen_bd_rx_inc *inc;
123
124 /* Shutdown the task */
125 bcom_disable_task(tsk->tasknum);
126
127 /* Reset the microcode */
128 var = (struct bcom_gen_bd_rx_var *) bcom_task_var(tsk->tasknum);
129 inc = (struct bcom_gen_bd_rx_inc *) bcom_task_inc(tsk->tasknum);
130
131 if (bcom_load_image(tsk->tasknum, bcom_gen_bd_rx_task))
132 return -1;
133
134 var->enable = bcom_eng->regs_base +
135 offsetof(struct mpc52xx_sdma, tcr[tsk->tasknum]);
136 var->fifo = (u32) priv->fifo;
137 var->bd_base = tsk->bd_pa;
138 var->bd_last = tsk->bd_pa + ((tsk->num_bd-1) * tsk->bd_size);
139 var->bd_start = tsk->bd_pa;
140 var->buffer_size = priv->maxbufsize;
141
142 inc->incr_bytes = -(s16)sizeof(u32);
143 inc->incr_dst = sizeof(u32);
144
145 /* Reset the BDs */
146 tsk->index = 0;
147 tsk->outdex = 0;
148
149 memset(tsk->bd, 0x00, tsk->num_bd * tsk->bd_size);
150
151 /* Configure some stuff */
152 bcom_set_task_pragma(tsk->tasknum, BCOM_GEN_RX_BD_PRAGMA);
153 bcom_set_task_auto_start(tsk->tasknum, tsk->tasknum);
154
155 out_8(&bcom_eng->regs->ipr[priv->initiator], priv->ipr);
156 bcom_set_initiator(tsk->tasknum, priv->initiator);
157
158 out_be32(&bcom_eng->regs->IntPend, 1<<tsk->tasknum); /* Clear ints */
159
160 return 0;
161}
162EXPORT_SYMBOL_GPL(bcom_gen_bd_rx_reset);
163
164void
165bcom_gen_bd_rx_release(struct bcom_task *tsk)
166{
167 /* Nothing special for the GenBD tasks */
168 bcom_task_free(tsk);
169}
170EXPORT_SYMBOL_GPL(bcom_gen_bd_rx_release);
171
172
173extern struct bcom_task *
174bcom_gen_bd_tx_init(int queue_len, phys_addr_t fifo,
175 int initiator, int ipr)
176{
177 struct bcom_task *tsk;
178 struct bcom_gen_bd_priv *priv;
179
180 tsk = bcom_task_alloc(queue_len, sizeof(struct bcom_gen_bd),
181 sizeof(struct bcom_gen_bd_priv));
182 if (!tsk)
183 return NULL;
184
185 tsk->flags = BCOM_FLAGS_NONE;
186
187 priv = tsk->priv;
188 priv->fifo = fifo;
189 priv->initiator = initiator;
190 priv->ipr = ipr;
191
192 if (bcom_gen_bd_tx_reset(tsk)) {
193 bcom_task_free(tsk);
194 return NULL;
195 }
196
197 return tsk;
198}
199EXPORT_SYMBOL_GPL(bcom_gen_bd_tx_init);
200
201int
202bcom_gen_bd_tx_reset(struct bcom_task *tsk)
203{
204 struct bcom_gen_bd_priv *priv = tsk->priv;
205 struct bcom_gen_bd_tx_var *var;
206 struct bcom_gen_bd_tx_inc *inc;
207
208 /* Shutdown the task */
209 bcom_disable_task(tsk->tasknum);
210
211 /* Reset the microcode */
212 var = (struct bcom_gen_bd_tx_var *) bcom_task_var(tsk->tasknum);
213 inc = (struct bcom_gen_bd_tx_inc *) bcom_task_inc(tsk->tasknum);
214
215 if (bcom_load_image(tsk->tasknum, bcom_gen_bd_tx_task))
216 return -1;
217
218 var->enable = bcom_eng->regs_base +
219 offsetof(struct mpc52xx_sdma, tcr[tsk->tasknum]);
220 var->fifo = (u32) priv->fifo;
221 var->bd_base = tsk->bd_pa;
222 var->bd_last = tsk->bd_pa + ((tsk->num_bd-1) * tsk->bd_size);
223 var->bd_start = tsk->bd_pa;
224
225 inc->incr_bytes = -(s16)sizeof(u32);
226 inc->incr_src = sizeof(u32);
227 inc->incr_src_ma = sizeof(u8);
228
229 /* Reset the BDs */
230 tsk->index = 0;
231 tsk->outdex = 0;
232
233 memset(tsk->bd, 0x00, tsk->num_bd * tsk->bd_size);
234
235 /* Configure some stuff */
236 bcom_set_task_pragma(tsk->tasknum, BCOM_GEN_TX_BD_PRAGMA);
237 bcom_set_task_auto_start(tsk->tasknum, tsk->tasknum);
238
239 out_8(&bcom_eng->regs->ipr[priv->initiator], priv->ipr);
240 bcom_set_initiator(tsk->tasknum, priv->initiator);
241
242 out_be32(&bcom_eng->regs->IntPend, 1<<tsk->tasknum); /* Clear ints */
243
244 return 0;
245}
246EXPORT_SYMBOL_GPL(bcom_gen_bd_tx_reset);
247
248void
249bcom_gen_bd_tx_release(struct bcom_task *tsk)
250{
251 /* Nothing special for the GenBD tasks */
252 bcom_task_free(tsk);
253}
254EXPORT_SYMBOL_GPL(bcom_gen_bd_tx_release);
255
256/* ---------------------------------------------------------------------
257 * PSC support code
258 */
259
260/**
261 * bcom_psc_parameters - Bestcomm initialization value table for PSC devices
262 *
263 * This structure is only used internally. It is a lookup table for PSC
264 * specific parameters to bestcomm tasks.
265 */
266static struct bcom_psc_params {
267 int rx_initiator;
268 int rx_ipr;
269 int tx_initiator;
270 int tx_ipr;
271} bcom_psc_params[] = {
272 [0] = {
273 .rx_initiator = BCOM_INITIATOR_PSC1_RX,
274 .rx_ipr = BCOM_IPR_PSC1_RX,
275 .tx_initiator = BCOM_INITIATOR_PSC1_TX,
276 .tx_ipr = BCOM_IPR_PSC1_TX,
277 },
278 [1] = {
279 .rx_initiator = BCOM_INITIATOR_PSC2_RX,
280 .rx_ipr = BCOM_IPR_PSC2_RX,
281 .tx_initiator = BCOM_INITIATOR_PSC2_TX,
282 .tx_ipr = BCOM_IPR_PSC2_TX,
283 },
284 [2] = {
285 .rx_initiator = BCOM_INITIATOR_PSC3_RX,
286 .rx_ipr = BCOM_IPR_PSC3_RX,
287 .tx_initiator = BCOM_INITIATOR_PSC3_TX,
288 .tx_ipr = BCOM_IPR_PSC3_TX,
289 },
290 [3] = {
291 .rx_initiator = BCOM_INITIATOR_PSC4_RX,
292 .rx_ipr = BCOM_IPR_PSC4_RX,
293 .tx_initiator = BCOM_INITIATOR_PSC4_TX,
294 .tx_ipr = BCOM_IPR_PSC4_TX,
295 },
296 [4] = {
297 .rx_initiator = BCOM_INITIATOR_PSC5_RX,
298 .rx_ipr = BCOM_IPR_PSC5_RX,
299 .tx_initiator = BCOM_INITIATOR_PSC5_TX,
300 .tx_ipr = BCOM_IPR_PSC5_TX,
301 },
302 [5] = {
303 .rx_initiator = BCOM_INITIATOR_PSC6_RX,
304 .rx_ipr = BCOM_IPR_PSC6_RX,
305 .tx_initiator = BCOM_INITIATOR_PSC6_TX,
306 .tx_ipr = BCOM_IPR_PSC6_TX,
307 },
308};
309
310/**
311 * bcom_psc_gen_bd_rx_init - Allocate a receive bcom_task for a PSC port
312 * @psc_num: Number of the PSC to allocate a task for
313 * @queue_len: number of buffer descriptors to allocate for the task
314 * @fifo: physical address of FIFO register
315 * @maxbufsize: Maximum receive data size in bytes.
316 *
317 * Allocate a bestcomm task structure for receiving data from a PSC.
318 */
319struct bcom_task * bcom_psc_gen_bd_rx_init(unsigned psc_num, int queue_len,
320 phys_addr_t fifo, int maxbufsize)
321{
322 if (psc_num >= MPC52xx_PSC_MAXNUM)
323 return NULL;
324
325 return bcom_gen_bd_rx_init(queue_len, fifo,
326 bcom_psc_params[psc_num].rx_initiator,
327 bcom_psc_params[psc_num].rx_ipr,
328 maxbufsize);
329}
330EXPORT_SYMBOL_GPL(bcom_psc_gen_bd_rx_init);
331
332/**
333 * bcom_psc_gen_bd_tx_init - Allocate a transmit bcom_task for a PSC port
334 * @psc_num: Number of the PSC to allocate a task for
335 * @queue_len: number of buffer descriptors to allocate for the task
336 * @fifo: physical address of FIFO register
337 *
338 * Allocate a bestcomm task structure for transmitting data to a PSC.
339 */
340struct bcom_task *
341bcom_psc_gen_bd_tx_init(unsigned psc_num, int queue_len, phys_addr_t fifo)
342{
343 struct psc;
344 return bcom_gen_bd_tx_init(queue_len, fifo,
345 bcom_psc_params[psc_num].tx_initiator,
346 bcom_psc_params[psc_num].tx_ipr);
347}
348EXPORT_SYMBOL_GPL(bcom_psc_gen_bd_tx_init);
349
350
351MODULE_DESCRIPTION("BestComm General Buffer Descriptor tasks driver");
352MODULE_AUTHOR("Jeff Gibbons <jeff.gibbons@appspec.com>");
353MODULE_LICENSE("GPL v2");
354
diff --git a/arch/powerpc/sysdev/bestcomm/gen_bd.h b/arch/powerpc/sysdev/bestcomm/gen_bd.h
deleted file mode 100644
index de47260e69da..000000000000
--- a/arch/powerpc/sysdev/bestcomm/gen_bd.h
+++ /dev/null
@@ -1,53 +0,0 @@
1/*
2 * Header for Bestcomm General Buffer Descriptor tasks driver
3 *
4 *
5 * Copyright (C) 2007 Sylvain Munaut <tnt@246tNt.com>
6 * Copyright (C) 2006 AppSpec Computer Technologies Corp.
7 * Jeff Gibbons <jeff.gibbons@appspec.com>
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License version 2 as published
11 * by the Free Software Foundation.
12 *
13 *
14 */
15
16#ifndef __BESTCOMM_GEN_BD_H__
17#define __BESTCOMM_GEN_BD_H__
18
19struct bcom_gen_bd {
20 u32 status;
21 u32 buf_pa;
22};
23
24
25extern struct bcom_task *
26bcom_gen_bd_rx_init(int queue_len, phys_addr_t fifo,
27 int initiator, int ipr, int maxbufsize);
28
29extern int
30bcom_gen_bd_rx_reset(struct bcom_task *tsk);
31
32extern void
33bcom_gen_bd_rx_release(struct bcom_task *tsk);
34
35
36extern struct bcom_task *
37bcom_gen_bd_tx_init(int queue_len, phys_addr_t fifo,
38 int initiator, int ipr);
39
40extern int
41bcom_gen_bd_tx_reset(struct bcom_task *tsk);
42
43extern void
44bcom_gen_bd_tx_release(struct bcom_task *tsk);
45
46
47/* PSC support utility wrappers */
48struct bcom_task * bcom_psc_gen_bd_rx_init(unsigned psc_num, int queue_len,
49 phys_addr_t fifo, int maxbufsize);
50struct bcom_task * bcom_psc_gen_bd_tx_init(unsigned psc_num, int queue_len,
51 phys_addr_t fifo);
52#endif /* __BESTCOMM_GEN_BD_H__ */
53
diff --git a/arch/powerpc/sysdev/bestcomm/sram.c b/arch/powerpc/sysdev/bestcomm/sram.c
deleted file mode 100644
index b6db23e085fb..000000000000
--- a/arch/powerpc/sysdev/bestcomm/sram.c
+++ /dev/null
@@ -1,178 +0,0 @@
1/*
2 * Simple memory allocator for on-board SRAM
3 *
4 *
5 * Maintainer : Sylvain Munaut <tnt@246tNt.com>
6 *
7 * Copyright (C) 2005 Sylvain Munaut <tnt@246tNt.com>
8 *
9 * This file is licensed under the terms of the GNU General Public License
10 * version 2. This program is licensed "as is" without any warranty of any
11 * kind, whether express or implied.
12 */
13
14#include <linux/err.h>
15#include <linux/kernel.h>
16#include <linux/export.h>
17#include <linux/slab.h>
18#include <linux/spinlock.h>
19#include <linux/string.h>
20#include <linux/ioport.h>
21#include <linux/of.h>
22
23#include <asm/io.h>
24#include <asm/mmu.h>
25
26#include "sram.h"
27
28
29/* Struct keeping our 'state' */
30struct bcom_sram *bcom_sram = NULL;
31EXPORT_SYMBOL_GPL(bcom_sram); /* needed for inline functions */
32
33
34/* ======================================================================== */
35/* Public API */
36/* ======================================================================== */
37/* DO NOT USE in interrupts, if needed in irq handler, we should use the
38 _irqsave version of the spin_locks */
39
40int bcom_sram_init(struct device_node *sram_node, char *owner)
41{
42 int rv;
43 const u32 *regaddr_p;
44 u64 regaddr64, size64;
45 unsigned int psize;
46
47 /* Create our state struct */
48 if (bcom_sram) {
49 printk(KERN_ERR "%s: bcom_sram_init: "
50 "Already initialized !\n", owner);
51 return -EBUSY;
52 }
53
54 bcom_sram = kmalloc(sizeof(struct bcom_sram), GFP_KERNEL);
55 if (!bcom_sram) {
56 printk(KERN_ERR "%s: bcom_sram_init: "
57 "Couldn't allocate internal state !\n", owner);
58 return -ENOMEM;
59 }
60
61 /* Get address and size of the sram */
62 regaddr_p = of_get_address(sram_node, 0, &size64, NULL);
63 if (!regaddr_p) {
64 printk(KERN_ERR "%s: bcom_sram_init: "
65 "Invalid device node !\n", owner);
66 rv = -EINVAL;
67 goto error_free;
68 }
69
70 regaddr64 = of_translate_address(sram_node, regaddr_p);
71
72 bcom_sram->base_phys = (phys_addr_t) regaddr64;
73 bcom_sram->size = (unsigned int) size64;
74
75 /* Request region */
76 if (!request_mem_region(bcom_sram->base_phys, bcom_sram->size, owner)) {
77 printk(KERN_ERR "%s: bcom_sram_init: "
78 "Couldn't request region !\n", owner);
79 rv = -EBUSY;
80 goto error_free;
81 }
82
83 /* Map SRAM */
84 /* sram is not really __iomem */
85 bcom_sram->base_virt = (void*) ioremap(bcom_sram->base_phys, bcom_sram->size);
86
87 if (!bcom_sram->base_virt) {
88 printk(KERN_ERR "%s: bcom_sram_init: "
89 "Map error SRAM zone 0x%08lx (0x%0x)!\n",
90 owner, (long)bcom_sram->base_phys, bcom_sram->size );
91 rv = -ENOMEM;
92 goto error_release;
93 }
94
95 /* Create an rheap (defaults to 32 bits word alignment) */
96 bcom_sram->rh = rh_create(4);
97
98 /* Attach the free zones */
99#if 0
100 /* Currently disabled ... for future use only */
101 reg_addr_p = of_get_property(sram_node, "available", &psize);
102#else
103 regaddr_p = NULL;
104 psize = 0;
105#endif
106
107 if (!regaddr_p || !psize) {
108 /* Attach the whole zone */
109 rh_attach_region(bcom_sram->rh, 0, bcom_sram->size);
110 } else {
111 /* Attach each zone independently */
112 while (psize >= 2 * sizeof(u32)) {
113 phys_addr_t zbase = of_translate_address(sram_node, regaddr_p);
114 rh_attach_region(bcom_sram->rh, zbase - bcom_sram->base_phys, regaddr_p[1]);
115 regaddr_p += 2;
116 psize -= 2 * sizeof(u32);
117 }
118 }
119
120 /* Init our spinlock */
121 spin_lock_init(&bcom_sram->lock);
122
123 return 0;
124
125error_release:
126 release_mem_region(bcom_sram->base_phys, bcom_sram->size);
127error_free:
128 kfree(bcom_sram);
129 bcom_sram = NULL;
130
131 return rv;
132}
133EXPORT_SYMBOL_GPL(bcom_sram_init);
134
135void bcom_sram_cleanup(void)
136{
137 /* Free resources */
138 if (bcom_sram) {
139 rh_destroy(bcom_sram->rh);
140 iounmap((void __iomem *)bcom_sram->base_virt);
141 release_mem_region(bcom_sram->base_phys, bcom_sram->size);
142 kfree(bcom_sram);
143 bcom_sram = NULL;
144 }
145}
146EXPORT_SYMBOL_GPL(bcom_sram_cleanup);
147
148void* bcom_sram_alloc(int size, int align, phys_addr_t *phys)
149{
150 unsigned long offset;
151
152 spin_lock(&bcom_sram->lock);
153 offset = rh_alloc_align(bcom_sram->rh, size, align, NULL);
154 spin_unlock(&bcom_sram->lock);
155
156 if (IS_ERR_VALUE(offset))
157 return NULL;
158
159 *phys = bcom_sram->base_phys + offset;
160 return bcom_sram->base_virt + offset;
161}
162EXPORT_SYMBOL_GPL(bcom_sram_alloc);
163
164void bcom_sram_free(void *ptr)
165{
166 unsigned long offset;
167
168 if (!ptr)
169 return;
170
171 offset = ptr - bcom_sram->base_virt;
172
173 spin_lock(&bcom_sram->lock);
174 rh_free(bcom_sram->rh, offset);
175 spin_unlock(&bcom_sram->lock);
176}
177EXPORT_SYMBOL_GPL(bcom_sram_free);
178
diff --git a/arch/powerpc/sysdev/bestcomm/sram.h b/arch/powerpc/sysdev/bestcomm/sram.h
deleted file mode 100644
index b6d668963cce..000000000000
--- a/arch/powerpc/sysdev/bestcomm/sram.h
+++ /dev/null
@@ -1,54 +0,0 @@
1/*
2 * Handling of a sram zone for bestcomm
3 *
4 *
5 * Copyright (C) 2007 Sylvain Munaut <tnt@246tNt.com>
6 *
7 * This file is licensed under the terms of the GNU General Public License
8 * version 2. This program is licensed "as is" without any warranty of any
9 * kind, whether express or implied.
10 */
11
12#ifndef __BESTCOMM_SRAM_H__
13#define __BESTCOMM_SRAM_H__
14
15#include <asm/rheap.h>
16#include <asm/mmu.h>
17#include <linux/spinlock.h>
18
19
20/* Structure used internally */
21 /* The internals are here for the inline functions
22 * sake, certainly not for the user to mess with !
23 */
24struct bcom_sram {
25 phys_addr_t base_phys;
26 void *base_virt;
27 unsigned int size;
28 rh_info_t *rh;
29 spinlock_t lock;
30};
31
32extern struct bcom_sram *bcom_sram;
33
34
35/* Public API */
36extern int bcom_sram_init(struct device_node *sram_node, char *owner);
37extern void bcom_sram_cleanup(void);
38
39extern void* bcom_sram_alloc(int size, int align, phys_addr_t *phys);
40extern void bcom_sram_free(void *ptr);
41
42static inline phys_addr_t bcom_sram_va2pa(void *va) {
43 return bcom_sram->base_phys +
44 (unsigned long)(va - bcom_sram->base_virt);
45}
46
47static inline void *bcom_sram_pa2va(phys_addr_t pa) {
48 return bcom_sram->base_virt +
49 (unsigned long)(pa - bcom_sram->base_phys);
50}
51
52
53#endif /* __BESTCOMM_SRAM_H__ */
54