2 * Driver for MPC52xx processor BestComm General Buffer Descriptor
4 * Copyright (C) 2007 Sylvain Munaut <tnt@246tNt.com>
5 * Copyright (C) 2006 AppSpec Computer Technologies Corp.
6 * Jeff Gibbons <jeff.gibbons@appspec.com>
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.
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>
22 #include <asm/mpc52xx.h>
23 #include <asm/mpc52xx_psc.h>
26 #include "bestcomm_priv.h"
30 /* ======================================================================== */
31 /* Task image/var/inc */
32 /* ======================================================================== */
34 /* gen_bd tasks images */
35 extern u32 bcom_gen_bd_rx_task
[];
36 extern u32 bcom_gen_bd_tx_task
[];
38 /* rx task vars that need to be set before enabling the task */
39 struct bcom_gen_bd_rx_var
{
40 u32 enable
; /* (u16*) address of task's control register */
41 u32 fifo
; /* (u32*) address of gen_bd's fifo */
42 u32 bd_base
; /* (struct bcom_bd*) beginning of ring buffer */
43 u32 bd_last
; /* (struct bcom_bd*) end of ring buffer */
44 u32 bd_start
; /* (struct bcom_bd*) current bd */
45 u32 buffer_size
; /* size of receive buffer */
48 /* rx task incs that need to be set before enabling the task */
49 struct bcom_gen_bd_rx_inc
{
56 /* tx task vars that need to be set before enabling the task */
57 struct bcom_gen_bd_tx_var
{
58 u32 fifo
; /* (u32*) address of gen_bd's fifo */
59 u32 enable
; /* (u16*) address of task's control register */
60 u32 bd_base
; /* (struct bcom_bd*) beginning of ring buffer */
61 u32 bd_last
; /* (struct bcom_bd*) end of ring buffer */
62 u32 bd_start
; /* (struct bcom_bd*) current bd */
63 u32 buffer_size
; /* set by uCode for each packet */
66 /* tx task incs that need to be set before enabling the task */
67 struct bcom_gen_bd_tx_inc
{
76 /* private structure */
77 struct bcom_gen_bd_priv
{
85 /* ======================================================================== */
86 /* Task support code */
87 /* ======================================================================== */
90 bcom_gen_bd_rx_init(int queue_len
, phys_addr_t fifo
,
91 int initiator
, int ipr
, int maxbufsize
)
93 struct bcom_task
*tsk
;
94 struct bcom_gen_bd_priv
*priv
;
96 tsk
= bcom_task_alloc(queue_len
, sizeof(struct bcom_gen_bd
),
97 sizeof(struct bcom_gen_bd_priv
));
101 tsk
->flags
= BCOM_FLAGS_NONE
;
105 priv
->initiator
= initiator
;
107 priv
->maxbufsize
= maxbufsize
;
109 if (bcom_gen_bd_rx_reset(tsk
)) {
116 EXPORT_SYMBOL_GPL(bcom_gen_bd_rx_init
);
119 bcom_gen_bd_rx_reset(struct bcom_task
*tsk
)
121 struct bcom_gen_bd_priv
*priv
= tsk
->priv
;
122 struct bcom_gen_bd_rx_var
*var
;
123 struct bcom_gen_bd_rx_inc
*inc
;
125 /* Shutdown the task */
126 bcom_disable_task(tsk
->tasknum
);
128 /* Reset the microcode */
129 var
= (struct bcom_gen_bd_rx_var
*) bcom_task_var(tsk
->tasknum
);
130 inc
= (struct bcom_gen_bd_rx_inc
*) bcom_task_inc(tsk
->tasknum
);
132 if (bcom_load_image(tsk
->tasknum
, bcom_gen_bd_rx_task
))
135 var
->enable
= bcom_eng
->regs_base
+
136 offsetof(struct mpc52xx_sdma
, tcr
[tsk
->tasknum
]);
137 var
->fifo
= (u32
) priv
->fifo
;
138 var
->bd_base
= tsk
->bd_pa
;
139 var
->bd_last
= tsk
->bd_pa
+ ((tsk
->num_bd
-1) * tsk
->bd_size
);
140 var
->bd_start
= tsk
->bd_pa
;
141 var
->buffer_size
= priv
->maxbufsize
;
143 inc
->incr_bytes
= -(s16
)sizeof(u32
);
144 inc
->incr_dst
= sizeof(u32
);
150 memset(tsk
->bd
, 0x00, tsk
->num_bd
* tsk
->bd_size
);
152 /* Configure some stuff */
153 bcom_set_task_pragma(tsk
->tasknum
, BCOM_GEN_RX_BD_PRAGMA
);
154 bcom_set_task_auto_start(tsk
->tasknum
, tsk
->tasknum
);
156 out_8(&bcom_eng
->regs
->ipr
[priv
->initiator
], priv
->ipr
);
157 bcom_set_initiator(tsk
->tasknum
, priv
->initiator
);
159 out_be32(&bcom_eng
->regs
->IntPend
, 1<<tsk
->tasknum
); /* Clear ints */
163 EXPORT_SYMBOL_GPL(bcom_gen_bd_rx_reset
);
166 bcom_gen_bd_rx_release(struct bcom_task
*tsk
)
168 /* Nothing special for the GenBD tasks */
171 EXPORT_SYMBOL_GPL(bcom_gen_bd_rx_release
);
174 extern struct bcom_task
*
175 bcom_gen_bd_tx_init(int queue_len
, phys_addr_t fifo
,
176 int initiator
, int ipr
)
178 struct bcom_task
*tsk
;
179 struct bcom_gen_bd_priv
*priv
;
181 tsk
= bcom_task_alloc(queue_len
, sizeof(struct bcom_gen_bd
),
182 sizeof(struct bcom_gen_bd_priv
));
186 tsk
->flags
= BCOM_FLAGS_NONE
;
190 priv
->initiator
= initiator
;
193 if (bcom_gen_bd_tx_reset(tsk
)) {
200 EXPORT_SYMBOL_GPL(bcom_gen_bd_tx_init
);
203 bcom_gen_bd_tx_reset(struct bcom_task
*tsk
)
205 struct bcom_gen_bd_priv
*priv
= tsk
->priv
;
206 struct bcom_gen_bd_tx_var
*var
;
207 struct bcom_gen_bd_tx_inc
*inc
;
209 /* Shutdown the task */
210 bcom_disable_task(tsk
->tasknum
);
212 /* Reset the microcode */
213 var
= (struct bcom_gen_bd_tx_var
*) bcom_task_var(tsk
->tasknum
);
214 inc
= (struct bcom_gen_bd_tx_inc
*) bcom_task_inc(tsk
->tasknum
);
216 if (bcom_load_image(tsk
->tasknum
, bcom_gen_bd_tx_task
))
219 var
->enable
= bcom_eng
->regs_base
+
220 offsetof(struct mpc52xx_sdma
, tcr
[tsk
->tasknum
]);
221 var
->fifo
= (u32
) priv
->fifo
;
222 var
->bd_base
= tsk
->bd_pa
;
223 var
->bd_last
= tsk
->bd_pa
+ ((tsk
->num_bd
-1) * tsk
->bd_size
);
224 var
->bd_start
= tsk
->bd_pa
;
226 inc
->incr_bytes
= -(s16
)sizeof(u32
);
227 inc
->incr_src
= sizeof(u32
);
228 inc
->incr_src_ma
= sizeof(u8
);
234 memset(tsk
->bd
, 0x00, tsk
->num_bd
* tsk
->bd_size
);
236 /* Configure some stuff */
237 bcom_set_task_pragma(tsk
->tasknum
, BCOM_GEN_TX_BD_PRAGMA
);
238 bcom_set_task_auto_start(tsk
->tasknum
, tsk
->tasknum
);
240 out_8(&bcom_eng
->regs
->ipr
[priv
->initiator
], priv
->ipr
);
241 bcom_set_initiator(tsk
->tasknum
, priv
->initiator
);
243 out_be32(&bcom_eng
->regs
->IntPend
, 1<<tsk
->tasknum
); /* Clear ints */
247 EXPORT_SYMBOL_GPL(bcom_gen_bd_tx_reset
);
250 bcom_gen_bd_tx_release(struct bcom_task
*tsk
)
252 /* Nothing special for the GenBD tasks */
255 EXPORT_SYMBOL_GPL(bcom_gen_bd_tx_release
);
257 /* ---------------------------------------------------------------------
262 * bcom_psc_parameters - Bestcomm initialization value table for PSC devices
264 * This structure is only used internally. It is a lookup table for PSC
265 * specific parameters to bestcomm tasks.
267 static struct bcom_psc_params
{
272 } bcom_psc_params
[] = {
274 .rx_initiator
= BCOM_INITIATOR_PSC1_RX
,
275 .rx_ipr
= BCOM_IPR_PSC1_RX
,
276 .tx_initiator
= BCOM_INITIATOR_PSC1_TX
,
277 .tx_ipr
= BCOM_IPR_PSC1_TX
,
280 .rx_initiator
= BCOM_INITIATOR_PSC2_RX
,
281 .rx_ipr
= BCOM_IPR_PSC2_RX
,
282 .tx_initiator
= BCOM_INITIATOR_PSC2_TX
,
283 .tx_ipr
= BCOM_IPR_PSC2_TX
,
286 .rx_initiator
= BCOM_INITIATOR_PSC3_RX
,
287 .rx_ipr
= BCOM_IPR_PSC3_RX
,
288 .tx_initiator
= BCOM_INITIATOR_PSC3_TX
,
289 .tx_ipr
= BCOM_IPR_PSC3_TX
,
292 .rx_initiator
= BCOM_INITIATOR_PSC4_RX
,
293 .rx_ipr
= BCOM_IPR_PSC4_RX
,
294 .tx_initiator
= BCOM_INITIATOR_PSC4_TX
,
295 .tx_ipr
= BCOM_IPR_PSC4_TX
,
298 .rx_initiator
= BCOM_INITIATOR_PSC5_RX
,
299 .rx_ipr
= BCOM_IPR_PSC5_RX
,
300 .tx_initiator
= BCOM_INITIATOR_PSC5_TX
,
301 .tx_ipr
= BCOM_IPR_PSC5_TX
,
304 .rx_initiator
= BCOM_INITIATOR_PSC6_RX
,
305 .rx_ipr
= BCOM_IPR_PSC6_RX
,
306 .tx_initiator
= BCOM_INITIATOR_PSC6_TX
,
307 .tx_ipr
= BCOM_IPR_PSC6_TX
,
312 * bcom_psc_gen_bd_rx_init - Allocate a receive bcom_task for a PSC port
313 * @psc_num: Number of the PSC to allocate a task for
314 * @queue_len: number of buffer descriptors to allocate for the task
315 * @fifo: physical address of FIFO register
316 * @maxbufsize: Maximum receive data size in bytes.
318 * Allocate a bestcomm task structure for receiving data from a PSC.
320 struct bcom_task
* bcom_psc_gen_bd_rx_init(unsigned psc_num
, int queue_len
,
321 phys_addr_t fifo
, int maxbufsize
)
323 if (psc_num
>= MPC52xx_PSC_MAXNUM
)
326 return bcom_gen_bd_rx_init(queue_len
, fifo
,
327 bcom_psc_params
[psc_num
].rx_initiator
,
328 bcom_psc_params
[psc_num
].rx_ipr
,
331 EXPORT_SYMBOL_GPL(bcom_psc_gen_bd_rx_init
);
334 * bcom_psc_gen_bd_tx_init - Allocate a transmit bcom_task for a PSC port
335 * @psc_num: Number of the PSC to allocate a task for
336 * @queue_len: number of buffer descriptors to allocate for the task
337 * @fifo: physical address of FIFO register
339 * Allocate a bestcomm task structure for transmitting data to a PSC.
342 bcom_psc_gen_bd_tx_init(unsigned psc_num
, int queue_len
, phys_addr_t fifo
)
345 return bcom_gen_bd_tx_init(queue_len
, fifo
,
346 bcom_psc_params
[psc_num
].tx_initiator
,
347 bcom_psc_params
[psc_num
].tx_ipr
);
349 EXPORT_SYMBOL_GPL(bcom_psc_gen_bd_tx_init
);
352 MODULE_DESCRIPTION("BestComm General Buffer Descriptor tasks driver");
353 MODULE_AUTHOR("Jeff Gibbons <jeff.gibbons@appspec.com>");
354 MODULE_LICENSE("GPL v2");