1 // SPDX-License-Identifier: GPL-2.0-only
3 * Driver for MPC52xx processor BestComm General Buffer Descriptor
5 * Copyright (C) 2007 Sylvain Munaut <tnt@246tNt.com>
6 * Copyright (C) 2006 AppSpec Computer Technologies Corp.
7 * Jeff Gibbons <jeff.gibbons@appspec.com>
10 #include <linux/module.h>
11 #include <linux/kernel.h>
12 #include <linux/string.h>
13 #include <linux/types.h>
14 #include <asm/errno.h>
17 #include <asm/mpc52xx.h>
18 #include <asm/mpc52xx_psc.h>
20 #include <linux/fsl/bestcomm/bestcomm.h>
21 #include <linux/fsl/bestcomm/bestcomm_priv.h>
22 #include <linux/fsl/bestcomm/gen_bd.h>
25 /* ======================================================================== */
26 /* Task image/var/inc */
27 /* ======================================================================== */
29 /* gen_bd tasks images */
30 extern u32 bcom_gen_bd_rx_task
[];
31 extern u32 bcom_gen_bd_tx_task
[];
33 /* rx task vars that need to be set before enabling the task */
34 struct bcom_gen_bd_rx_var
{
35 u32 enable
; /* (u16*) address of task's control register */
36 u32 fifo
; /* (u32*) address of gen_bd's fifo */
37 u32 bd_base
; /* (struct bcom_bd*) beginning of ring buffer */
38 u32 bd_last
; /* (struct bcom_bd*) end of ring buffer */
39 u32 bd_start
; /* (struct bcom_bd*) current bd */
40 u32 buffer_size
; /* size of receive buffer */
43 /* rx task incs that need to be set before enabling the task */
44 struct bcom_gen_bd_rx_inc
{
51 /* tx task vars that need to be set before enabling the task */
52 struct bcom_gen_bd_tx_var
{
53 u32 fifo
; /* (u32*) address of gen_bd's fifo */
54 u32 enable
; /* (u16*) address of task's control register */
55 u32 bd_base
; /* (struct bcom_bd*) beginning of ring buffer */
56 u32 bd_last
; /* (struct bcom_bd*) end of ring buffer */
57 u32 bd_start
; /* (struct bcom_bd*) current bd */
58 u32 buffer_size
; /* set by uCode for each packet */
61 /* tx task incs that need to be set before enabling the task */
62 struct bcom_gen_bd_tx_inc
{
71 /* private structure */
72 struct bcom_gen_bd_priv
{
80 /* ======================================================================== */
81 /* Task support code */
82 /* ======================================================================== */
85 bcom_gen_bd_rx_init(int queue_len
, phys_addr_t fifo
,
86 int initiator
, int ipr
, int maxbufsize
)
88 struct bcom_task
*tsk
;
89 struct bcom_gen_bd_priv
*priv
;
91 tsk
= bcom_task_alloc(queue_len
, sizeof(struct bcom_gen_bd
),
92 sizeof(struct bcom_gen_bd_priv
));
96 tsk
->flags
= BCOM_FLAGS_NONE
;
100 priv
->initiator
= initiator
;
102 priv
->maxbufsize
= maxbufsize
;
104 if (bcom_gen_bd_rx_reset(tsk
)) {
111 EXPORT_SYMBOL_GPL(bcom_gen_bd_rx_init
);
114 bcom_gen_bd_rx_reset(struct bcom_task
*tsk
)
116 struct bcom_gen_bd_priv
*priv
= tsk
->priv
;
117 struct bcom_gen_bd_rx_var
*var
;
118 struct bcom_gen_bd_rx_inc
*inc
;
120 /* Shutdown the task */
121 bcom_disable_task(tsk
->tasknum
);
123 /* Reset the microcode */
124 var
= (struct bcom_gen_bd_rx_var
*) bcom_task_var(tsk
->tasknum
);
125 inc
= (struct bcom_gen_bd_rx_inc
*) bcom_task_inc(tsk
->tasknum
);
127 if (bcom_load_image(tsk
->tasknum
, bcom_gen_bd_rx_task
))
130 var
->enable
= bcom_eng
->regs_base
+
131 offsetof(struct mpc52xx_sdma
, tcr
[tsk
->tasknum
]);
132 var
->fifo
= (u32
) priv
->fifo
;
133 var
->bd_base
= tsk
->bd_pa
;
134 var
->bd_last
= tsk
->bd_pa
+ ((tsk
->num_bd
-1) * tsk
->bd_size
);
135 var
->bd_start
= tsk
->bd_pa
;
136 var
->buffer_size
= priv
->maxbufsize
;
138 inc
->incr_bytes
= -(s16
)sizeof(u32
);
139 inc
->incr_dst
= sizeof(u32
);
145 memset(tsk
->bd
, 0x00, tsk
->num_bd
* tsk
->bd_size
);
147 /* Configure some stuff */
148 bcom_set_task_pragma(tsk
->tasknum
, BCOM_GEN_RX_BD_PRAGMA
);
149 bcom_set_task_auto_start(tsk
->tasknum
, tsk
->tasknum
);
151 out_8(&bcom_eng
->regs
->ipr
[priv
->initiator
], priv
->ipr
);
152 bcom_set_initiator(tsk
->tasknum
, priv
->initiator
);
154 out_be32(&bcom_eng
->regs
->IntPend
, 1<<tsk
->tasknum
); /* Clear ints */
158 EXPORT_SYMBOL_GPL(bcom_gen_bd_rx_reset
);
161 bcom_gen_bd_rx_release(struct bcom_task
*tsk
)
163 /* Nothing special for the GenBD tasks */
166 EXPORT_SYMBOL_GPL(bcom_gen_bd_rx_release
);
169 extern struct bcom_task
*
170 bcom_gen_bd_tx_init(int queue_len
, phys_addr_t fifo
,
171 int initiator
, int ipr
)
173 struct bcom_task
*tsk
;
174 struct bcom_gen_bd_priv
*priv
;
176 tsk
= bcom_task_alloc(queue_len
, sizeof(struct bcom_gen_bd
),
177 sizeof(struct bcom_gen_bd_priv
));
181 tsk
->flags
= BCOM_FLAGS_NONE
;
185 priv
->initiator
= initiator
;
188 if (bcom_gen_bd_tx_reset(tsk
)) {
195 EXPORT_SYMBOL_GPL(bcom_gen_bd_tx_init
);
198 bcom_gen_bd_tx_reset(struct bcom_task
*tsk
)
200 struct bcom_gen_bd_priv
*priv
= tsk
->priv
;
201 struct bcom_gen_bd_tx_var
*var
;
202 struct bcom_gen_bd_tx_inc
*inc
;
204 /* Shutdown the task */
205 bcom_disable_task(tsk
->tasknum
);
207 /* Reset the microcode */
208 var
= (struct bcom_gen_bd_tx_var
*) bcom_task_var(tsk
->tasknum
);
209 inc
= (struct bcom_gen_bd_tx_inc
*) bcom_task_inc(tsk
->tasknum
);
211 if (bcom_load_image(tsk
->tasknum
, bcom_gen_bd_tx_task
))
214 var
->enable
= bcom_eng
->regs_base
+
215 offsetof(struct mpc52xx_sdma
, tcr
[tsk
->tasknum
]);
216 var
->fifo
= (u32
) priv
->fifo
;
217 var
->bd_base
= tsk
->bd_pa
;
218 var
->bd_last
= tsk
->bd_pa
+ ((tsk
->num_bd
-1) * tsk
->bd_size
);
219 var
->bd_start
= tsk
->bd_pa
;
221 inc
->incr_bytes
= -(s16
)sizeof(u32
);
222 inc
->incr_src
= sizeof(u32
);
223 inc
->incr_src_ma
= sizeof(u8
);
229 memset(tsk
->bd
, 0x00, tsk
->num_bd
* tsk
->bd_size
);
231 /* Configure some stuff */
232 bcom_set_task_pragma(tsk
->tasknum
, BCOM_GEN_TX_BD_PRAGMA
);
233 bcom_set_task_auto_start(tsk
->tasknum
, tsk
->tasknum
);
235 out_8(&bcom_eng
->regs
->ipr
[priv
->initiator
], priv
->ipr
);
236 bcom_set_initiator(tsk
->tasknum
, priv
->initiator
);
238 out_be32(&bcom_eng
->regs
->IntPend
, 1<<tsk
->tasknum
); /* Clear ints */
242 EXPORT_SYMBOL_GPL(bcom_gen_bd_tx_reset
);
245 bcom_gen_bd_tx_release(struct bcom_task
*tsk
)
247 /* Nothing special for the GenBD tasks */
250 EXPORT_SYMBOL_GPL(bcom_gen_bd_tx_release
);
252 /* ---------------------------------------------------------------------
257 * bcom_psc_parameters - Bestcomm initialization value table for PSC devices
259 * This structure is only used internally. It is a lookup table for PSC
260 * specific parameters to bestcomm tasks.
262 static struct bcom_psc_params
{
267 } bcom_psc_params
[] = {
269 .rx_initiator
= BCOM_INITIATOR_PSC1_RX
,
270 .rx_ipr
= BCOM_IPR_PSC1_RX
,
271 .tx_initiator
= BCOM_INITIATOR_PSC1_TX
,
272 .tx_ipr
= BCOM_IPR_PSC1_TX
,
275 .rx_initiator
= BCOM_INITIATOR_PSC2_RX
,
276 .rx_ipr
= BCOM_IPR_PSC2_RX
,
277 .tx_initiator
= BCOM_INITIATOR_PSC2_TX
,
278 .tx_ipr
= BCOM_IPR_PSC2_TX
,
281 .rx_initiator
= BCOM_INITIATOR_PSC3_RX
,
282 .rx_ipr
= BCOM_IPR_PSC3_RX
,
283 .tx_initiator
= BCOM_INITIATOR_PSC3_TX
,
284 .tx_ipr
= BCOM_IPR_PSC3_TX
,
287 .rx_initiator
= BCOM_INITIATOR_PSC4_RX
,
288 .rx_ipr
= BCOM_IPR_PSC4_RX
,
289 .tx_initiator
= BCOM_INITIATOR_PSC4_TX
,
290 .tx_ipr
= BCOM_IPR_PSC4_TX
,
293 .rx_initiator
= BCOM_INITIATOR_PSC5_RX
,
294 .rx_ipr
= BCOM_IPR_PSC5_RX
,
295 .tx_initiator
= BCOM_INITIATOR_PSC5_TX
,
296 .tx_ipr
= BCOM_IPR_PSC5_TX
,
299 .rx_initiator
= BCOM_INITIATOR_PSC6_RX
,
300 .rx_ipr
= BCOM_IPR_PSC6_RX
,
301 .tx_initiator
= BCOM_INITIATOR_PSC6_TX
,
302 .tx_ipr
= BCOM_IPR_PSC6_TX
,
307 * bcom_psc_gen_bd_rx_init - Allocate a receive bcom_task for a PSC port
308 * @psc_num: Number of the PSC to allocate a task for
309 * @queue_len: number of buffer descriptors to allocate for the task
310 * @fifo: physical address of FIFO register
311 * @maxbufsize: Maximum receive data size in bytes.
313 * Allocate a bestcomm task structure for receiving data from a PSC.
315 struct bcom_task
* bcom_psc_gen_bd_rx_init(unsigned psc_num
, int queue_len
,
316 phys_addr_t fifo
, int maxbufsize
)
318 if (psc_num
>= MPC52xx_PSC_MAXNUM
)
321 return bcom_gen_bd_rx_init(queue_len
, fifo
,
322 bcom_psc_params
[psc_num
].rx_initiator
,
323 bcom_psc_params
[psc_num
].rx_ipr
,
326 EXPORT_SYMBOL_GPL(bcom_psc_gen_bd_rx_init
);
329 * bcom_psc_gen_bd_tx_init - Allocate a transmit bcom_task for a PSC port
330 * @psc_num: Number of the PSC to allocate a task for
331 * @queue_len: number of buffer descriptors to allocate for the task
332 * @fifo: physical address of FIFO register
334 * Allocate a bestcomm task structure for transmitting data to a PSC.
337 bcom_psc_gen_bd_tx_init(unsigned psc_num
, int queue_len
, phys_addr_t fifo
)
340 return bcom_gen_bd_tx_init(queue_len
, fifo
,
341 bcom_psc_params
[psc_num
].tx_initiator
,
342 bcom_psc_params
[psc_num
].tx_ipr
);
344 EXPORT_SYMBOL_GPL(bcom_psc_gen_bd_tx_init
);
347 MODULE_DESCRIPTION("BestComm General Buffer Descriptor tasks driver");
348 MODULE_AUTHOR("Jeff Gibbons <jeff.gibbons@appspec.com>");
349 MODULE_LICENSE("GPL v2");