1 // SPDX-License-Identifier: GPL-2.0-only
3 * The driver for Freescale MPC512x LocalPlus Bus FIFO
4 * (called SCLPC in the Reference Manual).
6 * Copyright (C) 2013-2015 Alexander Popov <alex.popov@linux.com>.
9 #include <linux/interrupt.h>
10 #include <linux/kernel.h>
11 #include <linux/module.h>
13 #include <linux/of_platform.h>
14 #include <linux/of_address.h>
15 #include <linux/of_irq.h>
16 #include <asm/mpc5121.h>
18 #include <linux/spinlock.h>
19 #include <linux/slab.h>
20 #include <linux/dmaengine.h>
21 #include <linux/dma-direction.h>
22 #include <linux/dma-mapping.h>
24 #define DRV_NAME "mpc512x_lpbfifo"
28 u32 base
; /* must be zero */
33 static struct lpbfifo_data
{
34 spinlock_t lock
; /* for protecting lpbfifo_data */
35 phys_addr_t regs_phys
;
36 resource_size_t regs_size
;
37 struct mpc512x_lpbfifo __iomem
*regs
;
39 struct cs_range
*cs_ranges
;
41 struct dma_chan
*chan
;
42 struct mpc512x_lpbfifo_request
*req
;
43 dma_addr_t ram_bus_addr
;
44 bool wait_lpbfifo_irq
;
45 bool wait_lpbfifo_callback
;
49 * A data transfer from RAM to some device on LPB is finished
50 * when both mpc512x_lpbfifo_irq() and mpc512x_lpbfifo_callback()
51 * have been called. We execute the callback registered in
52 * mpc512x_lpbfifo_request just after that.
53 * But for a data transfer from some device on LPB to RAM we don't enable
54 * LPBFIFO interrupt because clearing MPC512X_SCLPC_SUCCESS interrupt flag
55 * automatically disables LPBFIFO reading request to the DMA controller
56 * and the data transfer hangs. So the callback registered in
57 * mpc512x_lpbfifo_request is executed at the end of mpc512x_lpbfifo_callback().
61 * mpc512x_lpbfifo_irq - IRQ handler for LPB FIFO
63 static irqreturn_t
mpc512x_lpbfifo_irq(int irq
, void *param
)
65 struct device
*dev
= (struct device
*)param
;
66 struct mpc512x_lpbfifo_request
*req
= NULL
;
70 spin_lock_irqsave(&lpbfifo
.lock
, flags
);
76 if (!req
|| req
->dir
== MPC512X_LPBFIFO_REQ_DIR_READ
) {
77 dev_err(dev
, "bogus LPBFIFO IRQ\n");
81 status
= in_be32(&lpbfifo
.regs
->status
);
82 if (status
!= MPC512X_SCLPC_SUCCESS
) {
83 dev_err(dev
, "DMA transfer from RAM to peripheral failed\n");
84 out_be32(&lpbfifo
.regs
->enable
,
85 MPC512X_SCLPC_RESET
| MPC512X_SCLPC_FIFO_RESET
);
88 /* Clear the interrupt flag */
89 out_be32(&lpbfifo
.regs
->status
, MPC512X_SCLPC_SUCCESS
);
91 lpbfifo
.wait_lpbfifo_irq
= false;
93 if (lpbfifo
.wait_lpbfifo_callback
)
96 /* Transfer is finished, set the FIFO as idle */
99 spin_unlock_irqrestore(&lpbfifo
.lock
, flags
);
107 spin_unlock_irqrestore(&lpbfifo
.lock
, flags
);
112 * mpc512x_lpbfifo_callback is called by DMA driver when
113 * DMA transaction is finished.
115 static void mpc512x_lpbfifo_callback(void *param
)
118 struct mpc512x_lpbfifo_request
*req
= NULL
;
119 enum dma_data_direction dir
;
121 spin_lock_irqsave(&lpbfifo
.lock
, flags
);
124 spin_unlock_irqrestore(&lpbfifo
.lock
, flags
);
130 pr_err("bogus LPBFIFO callback\n");
131 spin_unlock_irqrestore(&lpbfifo
.lock
, flags
);
135 /* Release the mapping */
136 if (req
->dir
== MPC512X_LPBFIFO_REQ_DIR_WRITE
)
139 dir
= DMA_FROM_DEVICE
;
140 dma_unmap_single(lpbfifo
.chan
->device
->dev
,
141 lpbfifo
.ram_bus_addr
, req
->size
, dir
);
143 lpbfifo
.wait_lpbfifo_callback
= false;
145 if (!lpbfifo
.wait_lpbfifo_irq
) {
146 /* Transfer is finished, set the FIFO as idle */
149 spin_unlock_irqrestore(&lpbfifo
.lock
, flags
);
154 spin_unlock_irqrestore(&lpbfifo
.lock
, flags
);
158 static int mpc512x_lpbfifo_kick(void)
161 bool no_incr
= false;
162 u32 bpt
= 32; /* max bytes per LPBFIFO transaction involving DMA */
165 struct dma_device
*dma_dev
= NULL
;
166 struct scatterlist sg
;
167 enum dma_data_direction dir
;
168 struct dma_slave_config dma_conf
= {};
169 struct dma_async_tx_descriptor
*dma_tx
= NULL
;
174 * 1. Fit the requirements:
175 * - the packet size must be a multiple of 4 since FIFO Data Word
176 * Register allows only full-word access according the Reference
178 * - the physical address of the device on LPB and the packet size
179 * must be aligned on BPT (bytes per transaction) or 8-bytes
180 * boundary according the Reference Manual;
181 * - but we choose DMA maxburst equal (or very close to) BPT to prevent
182 * DMA controller from overtaking FIFO and causing FIFO underflow
183 * error. So we force the packet size to be aligned on BPT boundary
184 * not to confuse DMA driver which requires the packet size to be
185 * aligned on maxburst boundary;
186 * - BPT should be set to the LPB device port size for operation with
187 * disabled auto-incrementing according Reference Manual.
189 if (lpbfifo
.req
->size
== 0 || !IS_ALIGNED(lpbfifo
.req
->size
, 4))
192 if (lpbfifo
.req
->portsize
!= LPB_DEV_PORTSIZE_UNDEFINED
) {
193 bpt
= lpbfifo
.req
->portsize
;
198 if (IS_ALIGNED(lpbfifo
.req
->dev_phys_addr
, min(bpt
, 0x8u
)) &&
199 IS_ALIGNED(lpbfifo
.req
->size
, bpt
)) {
208 dma_conf
.dst_maxburst
= max(bpt
, 0x4u
) / 4;
209 dma_conf
.src_maxburst
= max(bpt
, 0x4u
) / 4;
211 for (i
= 0; i
< lpbfifo
.cs_n
; i
++) {
212 phys_addr_t cs_start
= lpbfifo
.cs_ranges
[i
].addr
;
213 phys_addr_t cs_end
= cs_start
+ lpbfifo
.cs_ranges
[i
].size
;
214 phys_addr_t access_start
= lpbfifo
.req
->dev_phys_addr
;
215 phys_addr_t access_end
= access_start
+ lpbfifo
.req
->size
;
217 if (access_start
>= cs_start
&& access_end
<= cs_end
) {
218 cs
= lpbfifo
.cs_ranges
[i
].csnum
;
222 if (i
== lpbfifo
.cs_n
)
226 dma_dev
= lpbfifo
.chan
->device
;
228 if (lpbfifo
.req
->dir
== MPC512X_LPBFIFO_REQ_DIR_WRITE
) {
230 dma_conf
.direction
= DMA_MEM_TO_DEV
;
231 dma_conf
.dst_addr
= lpbfifo
.regs_phys
+
232 offsetof(struct mpc512x_lpbfifo
, data_word
);
234 dir
= DMA_FROM_DEVICE
;
235 dma_conf
.direction
= DMA_DEV_TO_MEM
;
236 dma_conf
.src_addr
= lpbfifo
.regs_phys
+
237 offsetof(struct mpc512x_lpbfifo
, data_word
);
239 dma_conf
.dst_addr_width
= DMA_SLAVE_BUSWIDTH_4_BYTES
;
240 dma_conf
.src_addr_width
= DMA_SLAVE_BUSWIDTH_4_BYTES
;
242 /* Make DMA channel work with LPB FIFO data register */
243 if (dma_dev
->device_config(lpbfifo
.chan
, &dma_conf
)) {
248 sg_init_table(&sg
, 1);
250 sg_dma_address(&sg
) = dma_map_single(dma_dev
->dev
,
251 lpbfifo
.req
->ram_virt_addr
, lpbfifo
.req
->size
, dir
);
252 if (dma_mapping_error(dma_dev
->dev
, sg_dma_address(&sg
)))
255 lpbfifo
.ram_bus_addr
= sg_dma_address(&sg
); /* For freeing later */
257 sg_dma_len(&sg
) = lpbfifo
.req
->size
;
259 dma_tx
= dmaengine_prep_slave_sg(lpbfifo
.chan
, &sg
,
260 1, dma_conf
.direction
, 0);
265 dma_tx
->callback
= mpc512x_lpbfifo_callback
;
266 dma_tx
->callback_param
= NULL
;
268 /* 3. Prepare FIFO */
269 out_be32(&lpbfifo
.regs
->enable
,
270 MPC512X_SCLPC_RESET
| MPC512X_SCLPC_FIFO_RESET
);
271 out_be32(&lpbfifo
.regs
->enable
, 0x0);
274 * Configure the watermarks for write operation (RAM->DMA->FIFO->dev):
275 * - high watermark 7 words according the Reference Manual,
276 * - low watermark 512 bytes (half of the FIFO).
277 * These watermarks don't work for read operation since the
278 * MPC512X_SCLPC_FLUSH bit is set (according the Reference Manual).
280 out_be32(&lpbfifo
.regs
->fifo_ctrl
, MPC512X_SCLPC_FIFO_CTRL(0x7));
281 out_be32(&lpbfifo
.regs
->fifo_alarm
, MPC512X_SCLPC_FIFO_ALARM(0x200));
284 * Start address is a physical address of the region which belongs
285 * to the device on the LocalPlus Bus
287 out_be32(&lpbfifo
.regs
->start_addr
, lpbfifo
.req
->dev_phys_addr
);
290 * Configure chip select, transfer direction, address increment option
291 * and bytes per transaction option
293 bits
= MPC512X_SCLPC_CS(cs
);
294 if (lpbfifo
.req
->dir
== MPC512X_LPBFIFO_REQ_DIR_READ
)
295 bits
|= MPC512X_SCLPC_READ
| MPC512X_SCLPC_FLUSH
;
297 bits
|= MPC512X_SCLPC_DAI
;
298 bits
|= MPC512X_SCLPC_BPT(bpt
);
299 out_be32(&lpbfifo
.regs
->ctrl
, bits
);
302 bits
= MPC512X_SCLPC_ENABLE
| MPC512X_SCLPC_ABORT_INT_ENABLE
;
303 if (lpbfifo
.req
->dir
== MPC512X_LPBFIFO_REQ_DIR_WRITE
)
304 bits
|= MPC512X_SCLPC_NORM_INT_ENABLE
;
306 lpbfifo
.wait_lpbfifo_irq
= false;
308 out_be32(&lpbfifo
.regs
->enable
, bits
);
310 /* 4. Set packet size and kick FIFO off */
311 bits
= lpbfifo
.req
->size
| MPC512X_SCLPC_START
;
312 out_be32(&lpbfifo
.regs
->pkt_size
, bits
);
314 /* 5. Finally kick DMA off */
315 cookie
= dma_tx
->tx_submit(dma_tx
);
316 if (dma_submit_error(cookie
)) {
324 out_be32(&lpbfifo
.regs
->enable
,
325 MPC512X_SCLPC_RESET
| MPC512X_SCLPC_FIFO_RESET
);
327 dma_unmap_single(dma_dev
->dev
, sg_dma_address(&sg
),
328 lpbfifo
.req
->size
, dir
);
332 static int mpc512x_lpbfifo_submit_locked(struct mpc512x_lpbfifo_request
*req
)
339 /* Check whether a transfer is in progress */
343 lpbfifo
.wait_lpbfifo_irq
= true;
344 lpbfifo
.wait_lpbfifo_callback
= true;
347 ret
= mpc512x_lpbfifo_kick();
349 lpbfifo
.req
= NULL
; /* Set the FIFO as idle */
354 int mpc512x_lpbfifo_submit(struct mpc512x_lpbfifo_request
*req
)
359 spin_lock_irqsave(&lpbfifo
.lock
, flags
);
360 ret
= mpc512x_lpbfifo_submit_locked(req
);
361 spin_unlock_irqrestore(&lpbfifo
.lock
, flags
);
365 EXPORT_SYMBOL(mpc512x_lpbfifo_submit
);
368 * LPBFIFO driver uses "ranges" property of "localbus" device tree node
369 * for being able to determine the chip select number of a client device
370 * ordering a DMA transfer.
372 static int get_cs_ranges(struct device
*dev
)
375 struct device_node
*lb_node
;
376 const u32
*addr_cells_p
;
377 const u32
*size_cells_p
;
381 lb_node
= of_find_compatible_node(NULL
, NULL
, "fsl,mpc5121-localbus");
386 * The node defined as compatible with 'fsl,mpc5121-localbus'
387 * should have two address cells and one size cell.
388 * Every item of its ranges property should consist of:
389 * - the first address cell which is the chipselect number;
390 * - the second address cell which is the offset in the chipselect,
392 * - CPU address of the beginning of an access window;
393 * - the only size cell which is the size of an access window.
395 addr_cells_p
= of_get_property(lb_node
, "#address-cells", NULL
);
396 size_cells_p
= of_get_property(lb_node
, "#size-cells", NULL
);
397 if (addr_cells_p
== NULL
|| *addr_cells_p
!= 2 ||
398 size_cells_p
== NULL
|| *size_cells_p
!= 1) {
402 proplen
= of_property_count_u32_elems(lb_node
, "ranges");
403 if (proplen
<= 0 || proplen
% 4 != 0)
406 lpbfifo
.cs_n
= proplen
/ 4;
407 lpbfifo
.cs_ranges
= devm_kcalloc(dev
, lpbfifo
.cs_n
,
408 sizeof(struct cs_range
), GFP_KERNEL
);
409 if (!lpbfifo
.cs_ranges
)
412 if (of_property_read_u32_array(lb_node
, "ranges",
413 (u32
*)lpbfifo
.cs_ranges
, proplen
) != 0) {
417 for (i
= 0; i
< lpbfifo
.cs_n
; i
++) {
418 if (lpbfifo
.cs_ranges
[i
].base
!= 0)
425 of_node_put(lb_node
);
429 static int mpc512x_lpbfifo_probe(struct platform_device
*pdev
)
434 memset(&lpbfifo
, 0, sizeof(struct lpbfifo_data
));
435 spin_lock_init(&lpbfifo
.lock
);
437 lpbfifo
.chan
= dma_request_chan(&pdev
->dev
, "rx-tx");
438 if (IS_ERR(lpbfifo
.chan
))
439 return PTR_ERR(lpbfifo
.chan
);
441 if (of_address_to_resource(pdev
->dev
.of_node
, 0, &r
) != 0) {
442 dev_err(&pdev
->dev
, "bad 'reg' in 'sclpc' device tree node\n");
447 lpbfifo
.regs_phys
= r
.start
;
448 lpbfifo
.regs_size
= resource_size(&r
);
450 if (!devm_request_mem_region(&pdev
->dev
, lpbfifo
.regs_phys
,
451 lpbfifo
.regs_size
, DRV_NAME
)) {
452 dev_err(&pdev
->dev
, "unable to request region\n");
457 lpbfifo
.regs
= devm_ioremap(&pdev
->dev
,
458 lpbfifo
.regs_phys
, lpbfifo
.regs_size
);
460 dev_err(&pdev
->dev
, "mapping registers failed\n");
465 out_be32(&lpbfifo
.regs
->enable
,
466 MPC512X_SCLPC_RESET
| MPC512X_SCLPC_FIFO_RESET
);
468 if (get_cs_ranges(&pdev
->dev
) != 0) {
469 dev_err(&pdev
->dev
, "bad '/localbus' device tree node\n");
474 lpbfifo
.irq
= irq_of_parse_and_map(pdev
->dev
.of_node
, 0);
476 dev_err(&pdev
->dev
, "mapping irq failed\n");
481 if (request_irq(lpbfifo
.irq
, mpc512x_lpbfifo_irq
, 0,
482 DRV_NAME
, &pdev
->dev
) != 0) {
483 dev_err(&pdev
->dev
, "requesting irq failed\n");
488 dev_info(&pdev
->dev
, "probe succeeded\n");
492 irq_dispose_mapping(lpbfifo
.irq
);
494 dma_release_channel(lpbfifo
.chan
);
498 static int mpc512x_lpbfifo_remove(struct platform_device
*pdev
)
501 struct dma_device
*dma_dev
= lpbfifo
.chan
->device
;
502 struct mpc512x_lpbfifo __iomem
*regs
= NULL
;
504 spin_lock_irqsave(&lpbfifo
.lock
, flags
);
507 spin_unlock_irqrestore(&lpbfifo
.lock
, flags
);
509 dma_dev
->device_terminate_all(lpbfifo
.chan
);
510 out_be32(®s
->enable
, MPC512X_SCLPC_RESET
| MPC512X_SCLPC_FIFO_RESET
);
512 free_irq(lpbfifo
.irq
, &pdev
->dev
);
513 irq_dispose_mapping(lpbfifo
.irq
);
514 dma_release_channel(lpbfifo
.chan
);
519 static const struct of_device_id mpc512x_lpbfifo_match
[] = {
520 { .compatible
= "fsl,mpc512x-lpbfifo", },
523 MODULE_DEVICE_TABLE(of
, mpc512x_lpbfifo_match
);
525 static struct platform_driver mpc512x_lpbfifo_driver
= {
526 .probe
= mpc512x_lpbfifo_probe
,
527 .remove
= mpc512x_lpbfifo_remove
,
530 .of_match_table
= mpc512x_lpbfifo_match
,
534 module_platform_driver(mpc512x_lpbfifo_driver
);
536 MODULE_AUTHOR("Alexander Popov <alex.popov@linux.com>");
537 MODULE_DESCRIPTION("MPC512x LocalPlus Bus FIFO device driver");
538 MODULE_LICENSE("GPL v2");