aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSylvain Munaut <tnt@246tNt.com>2007-09-16 06:53:30 -0400
committerGrant Likely <grant.likely@secretlab.ca>2007-10-16 19:09:56 -0400
commit7acb939130ff054f195f827ed1cb389232dd8560 (patch)
tree78a30fd8b6d8f0a556370cd5b5355524d5b71fbe
parentba11c79aba8d8e9faf556a32bb8b414b4a846ac7 (diff)
[POWERPC] bestcomm: GenBD task support
This is the microcode for the GenBD task and the associated support code. This is a generic task that copy data to/from a hardware FIFO. This is currently locked to 32bits wide access but could be extended as needed. The microcode itself comes directly from the offical API (v2.2) Signed-off-by: Sylvain Munaut <tnt@246tNt.com> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
-rw-r--r--arch/powerpc/sysdev/bestcomm/Kconfig7
-rw-r--r--arch/powerpc/sysdev/bestcomm/Makefile2
-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/gen_bd.c260
-rw-r--r--arch/powerpc/sysdev/bestcomm/gen_bd.h48
6 files changed, 449 insertions, 0 deletions
diff --git a/arch/powerpc/sysdev/bestcomm/Kconfig b/arch/powerpc/sysdev/bestcomm/Kconfig
index 831763b0639e..57cc56562567 100644
--- a/arch/powerpc/sysdev/bestcomm/Kconfig
+++ b/arch/powerpc/sysdev/bestcomm/Kconfig
@@ -30,3 +30,10 @@ config PPC_BESTCOMM_FEC
30 help 30 help
31 This option enables the support for the FEC tasks. 31 This option enables the support for the FEC tasks.
32 32
33config PPC_BESTCOMM_GEN_BD
34 tristate "Bestcomm GenBD tasks support"
35 depends on PPC_BESTCOMM
36 default n
37 help
38 This option enables the support for the GenBD tasks.
39
diff --git a/arch/powerpc/sysdev/bestcomm/Makefile b/arch/powerpc/sysdev/bestcomm/Makefile
index 537d1744e6b9..aed2df2a6580 100644
--- a/arch/powerpc/sysdev/bestcomm/Makefile
+++ b/arch/powerpc/sysdev/bestcomm/Makefile
@@ -5,8 +5,10 @@
5bestcomm-core-objs := bestcomm.o sram.o 5bestcomm-core-objs := bestcomm.o sram.o
6bestcomm-ata-objs := ata.o bcom_ata_task.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 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
8 9
9obj-$(CONFIG_PPC_BESTCOMM) += bestcomm-core.o 10obj-$(CONFIG_PPC_BESTCOMM) += bestcomm-core.o
10obj-$(CONFIG_PPC_BESTCOMM_ATA) += bestcomm-ata.o 11obj-$(CONFIG_PPC_BESTCOMM_ATA) += bestcomm-ata.o
11obj-$(CONFIG_PPC_BESTCOMM_FEC) += bestcomm-fec.o 12obj-$(CONFIG_PPC_BESTCOMM_FEC) += bestcomm-fec.o
13obj-$(CONFIG_PPC_BESTCOMM_GEN_BD) += bestcomm-gen-bd.o
12 14
diff --git a/arch/powerpc/sysdev/bestcomm/bcom_gen_bd_rx_task.c b/arch/powerpc/sysdev/bestcomm/bcom_gen_bd_rx_task.c
new file mode 100644
index 000000000000..efee022b0256
--- /dev/null
+++ b/arch/powerpc/sysdev/bestcomm/bcom_gen_bd_rx_task.c
@@ -0,0 +1,63 @@
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
new file mode 100644
index 000000000000..c605aa42ecbb
--- /dev/null
+++ b/arch/powerpc/sysdev/bestcomm/bcom_gen_bd_tx_task.c
@@ -0,0 +1,69 @@
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/gen_bd.c b/arch/powerpc/sysdev/bestcomm/gen_bd.c
new file mode 100644
index 000000000000..8d33eafbb3f4
--- /dev/null
+++ b/arch/powerpc/sysdev/bestcomm/gen_bd.c
@@ -0,0 +1,260 @@
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/version.h>
15#include <linux/module.h>
16#include <linux/kernel.h>
17#include <linux/string.h>
18#include <linux/types.h>
19#include <asm/errno.h>
20#include <asm/io.h>
21
22#include <asm/mpc52xx.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
257MODULE_DESCRIPTION("BestComm General Buffer Descriptor tasks driver");
258MODULE_AUTHOR("Jeff Gibbons <jeff.gibbons@appspec.com>");
259MODULE_LICENSE("GPL v2");
260
diff --git a/arch/powerpc/sysdev/bestcomm/gen_bd.h b/arch/powerpc/sysdev/bestcomm/gen_bd.h
new file mode 100644
index 000000000000..5b6fa803c6aa
--- /dev/null
+++ b/arch/powerpc/sysdev/bestcomm/gen_bd.h
@@ -0,0 +1,48 @@
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#endif /* __BESTCOMM_GEN_BD_H__ */
48