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/module.h>
15 #include <linux/kernel.h>
16 #include <linux/string.h>
17 #include <linux/types.h>
18 #include <asm/errno.h>
21 #include <asm/mpc52xx.h>
22 #include <asm/mpc52xx_psc.h>
25 #include "bestcomm_priv.h"
29 /* ======================================================================== */
30 /* Task image/var/inc */
31 /* ======================================================================== */
33 /* gen_bd tasks images */
34 extern u32 bcom_gen_bd_rx_task
[];
35 extern u32 bcom_gen_bd_tx_task
[];
37 /* rx task vars that need to be set before enabling the task */
38 struct 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 */
47 /* rx task incs that need to be set before enabling the task */
48 struct bcom_gen_bd_rx_inc
{
55 /* tx task vars that need to be set before enabling the task */
56 struct 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 */
65 /* tx task incs that need to be set before enabling the task */
66 struct bcom_gen_bd_tx_inc
{
75 /* private structure */
76 struct bcom_gen_bd_priv
{
84 /* ======================================================================== */
85 /* Task support code */
86 /* ======================================================================== */
89 bcom_gen_bd_rx_init(int queue_len
, phys_addr_t fifo
,
90 int initiator
, int ipr
, int maxbufsize
)
92 struct bcom_task
*tsk
;
93 struct bcom_gen_bd_priv
*priv
;
95 tsk
= bcom_task_alloc(queue_len
, sizeof(struct bcom_gen_bd
),
96 sizeof(struct bcom_gen_bd_priv
));
100 tsk
->flags
= BCOM_FLAGS_NONE
;
104 priv
->initiator
= initiator
;
106 priv
->maxbufsize
= maxbufsize
;
108 if (bcom_gen_bd_rx_reset(tsk
)) {
115 EXPORT_SYMBOL_GPL(bcom_gen_bd_rx_init
);
118 bcom_gen_bd_rx_reset(struct bcom_task
*tsk
)
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
;
124 /* Shutdown the task */
125 bcom_disable_task(tsk
->tasknum
);
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
);
131 if (bcom_load_image(tsk
->tasknum
, bcom_gen_bd_rx_task
))
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
;
142 inc
->incr_bytes
= -(s16
)sizeof(u32
);
143 inc
->incr_dst
= sizeof(u32
);
149 memset(tsk
->bd
, 0x00, tsk
->num_bd
* tsk
->bd_size
);
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
);
155 out_8(&bcom_eng
->regs
->ipr
[priv
->initiator
], priv
->ipr
);
156 bcom_set_initiator(tsk
->tasknum
, priv
->initiator
);
158 out_be32(&bcom_eng
->regs
->IntPend
, 1<<tsk
->tasknum
); /* Clear ints */
162 EXPORT_SYMBOL_GPL(bcom_gen_bd_rx_reset
);
165 bcom_gen_bd_rx_release(struct bcom_task
*tsk
)
167 /* Nothing special for the GenBD tasks */
170 EXPORT_SYMBOL_GPL(bcom_gen_bd_rx_release
);
173 extern struct bcom_task
*
174 bcom_gen_bd_tx_init(int queue_len
, phys_addr_t fifo
,
175 int initiator
, int ipr
)
177 struct bcom_task
*tsk
;
178 struct bcom_gen_bd_priv
*priv
;
180 tsk
= bcom_task_alloc(queue_len
, sizeof(struct bcom_gen_bd
),
181 sizeof(struct bcom_gen_bd_priv
));
185 tsk
->flags
= BCOM_FLAGS_NONE
;
189 priv
->initiator
= initiator
;
192 if (bcom_gen_bd_tx_reset(tsk
)) {
199 EXPORT_SYMBOL_GPL(bcom_gen_bd_tx_init
);
202 bcom_gen_bd_tx_reset(struct bcom_task
*tsk
)
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
;
208 /* Shutdown the task */
209 bcom_disable_task(tsk
->tasknum
);
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
);
215 if (bcom_load_image(tsk
->tasknum
, bcom_gen_bd_tx_task
))
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
;
225 inc
->incr_bytes
= -(s16
)sizeof(u32
);
226 inc
->incr_src
= sizeof(u32
);
227 inc
->incr_src_ma
= sizeof(u8
);
233 memset(tsk
->bd
, 0x00, tsk
->num_bd
* tsk
->bd_size
);
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
);
239 out_8(&bcom_eng
->regs
->ipr
[priv
->initiator
], priv
->ipr
);
240 bcom_set_initiator(tsk
->tasknum
, priv
->initiator
);
242 out_be32(&bcom_eng
->regs
->IntPend
, 1<<tsk
->tasknum
); /* Clear ints */
246 EXPORT_SYMBOL_GPL(bcom_gen_bd_tx_reset
);
249 bcom_gen_bd_tx_release(struct bcom_task
*tsk
)
251 /* Nothing special for the GenBD tasks */
254 EXPORT_SYMBOL_GPL(bcom_gen_bd_tx_release
);
256 /* ---------------------------------------------------------------------
261 * bcom_psc_parameters - Bestcomm initialization value table for PSC devices
263 * This structure is only used internally. It is a lookup table for PSC
264 * specific parameters to bestcomm tasks.
266 static struct bcom_psc_params
{
271 } bcom_psc_params
[] = {
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
,
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
,
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
,
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
,
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
,
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
,
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.
317 * Allocate a bestcomm task structure for receiving data from a PSC.
319 struct bcom_task
* bcom_psc_gen_bd_rx_init(unsigned psc_num
, int queue_len
,
320 phys_addr_t fifo
, int maxbufsize
)
322 if (psc_num
>= MPC52xx_PSC_MAXNUM
)
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
,
330 EXPORT_SYMBOL_GPL(bcom_psc_gen_bd_rx_init
);
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
338 * Allocate a bestcomm task structure for transmitting data to a PSC.
341 bcom_psc_gen_bd_tx_init(unsigned psc_num
, int queue_len
, phys_addr_t fifo
)
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
);
348 EXPORT_SYMBOL_GPL(bcom_psc_gen_bd_tx_init
);
351 MODULE_DESCRIPTION("BestComm General Buffer Descriptor tasks driver");
352 MODULE_AUTHOR("Jeff Gibbons <jeff.gibbons@appspec.com>");
353 MODULE_LICENSE("GPL v2");