]> rtime.felk.cvut.cz Git - zynq/linux.git/blob - drivers/dma/xilinx/xilinx_frmbuf.c
dma: xilinx: Correct the V4L fourcc for BGRX8 in framebuffer driver
[zynq/linux.git] / drivers / dma / xilinx / xilinx_frmbuf.c
1 /*
2  * DMAEngine driver for Xilinx Framebuffer IP
3  *
4  * Copyright (C) 2016,2017 Xilinx, Inc. All rights reserved.
5  *
6  * Authors: Radhey Shyam Pandey <radheys@xilinx.com>
7  *          John Nichols <jnichol@xilinx.com>
8  *          Jeffrey Mouroux <jmouroux@xilinx.com>
9  *
10  * Based on the Freescale DMA driver.
11  *
12  * Description:
13  * The AXI Framebuffer core is a soft Xilinx IP core that
14  * provides high-bandwidth direct memory access between memory
15  * and AXI4-Stream.
16  *
17  * This program is free software: you can redistribute it and/or modify
18  * it under the terms of the GNU General Public License as published by
19  * the Free Software Foundation, either version 2 of the License, or
20  * (at your option) any later version.
21  */
22
23 #include <linux/bitops.h>
24 #include <linux/dma/xilinx_frmbuf.h>
25 #include <linux/dmapool.h>
26 #include <linux/gpio/consumer.h>
27 #include <linux/init.h>
28 #include <linux/interrupt.h>
29 #include <linux/io.h>
30 #include <linux/iopoll.h>
31 #include <linux/module.h>
32 #include <linux/of_address.h>
33 #include <linux/of_dma.h>
34 #include <linux/of_irq.h>
35 #include <linux/of_platform.h>
36 #include <linux/slab.h>
37 #include <linux/videodev2.h>
38
39 #include <drm/drm_fourcc.h>
40
41 #include "../dmaengine.h"
42
43 /* Register/Descriptor Offsets */
44 #define XILINX_FRMBUF_CTRL_OFFSET               0x00
45 #define XILINX_FRMBUF_GIE_OFFSET                0x04
46 #define XILINX_FRMBUF_IE_OFFSET                 0x08
47 #define XILINX_FRMBUF_ISR_OFFSET                0x0c
48 #define XILINX_FRMBUF_WIDTH_OFFSET              0x10
49 #define XILINX_FRMBUF_HEIGHT_OFFSET             0x18
50 #define XILINX_FRMBUF_STRIDE_OFFSET             0x20
51 #define XILINX_FRMBUF_FMT_OFFSET                0x28
52 #define XILINX_FRMBUF_ADDR_OFFSET               0x30
53 #define XILINX_FRMBUF_ADDR2_OFFSET              0x3c
54
55 /* Control Registers */
56 #define XILINX_FRMBUF_CTRL_AP_START             BIT(0)
57 #define XILINX_FRMBUF_CTRL_AP_DONE              BIT(1)
58 #define XILINX_FRMBUF_CTRL_AP_IDLE              BIT(2)
59 #define XILINX_FRMBUF_CTRL_AP_READY             BIT(3)
60 #define XILINX_FRMBUF_CTRL_AUTO_RESTART         BIT(7)
61 #define XILINX_FRMBUF_GIE_EN                    BIT(0)
62
63 /* Interrupt Status and Control */
64 #define XILINX_FRMBUF_IE_AP_DONE                BIT(0)
65 #define XILINX_FRMBUF_IE_AP_READY               BIT(1)
66
67 #define XILINX_FRMBUF_ISR_AP_DONE_IRQ           BIT(0)
68 #define XILINX_FRMBUF_ISR_AP_READY_IRQ          BIT(1)
69
70 #define XILINX_FRMBUF_ISR_ALL_IRQ_MASK  \
71                 (XILINX_FRMBUF_ISR_AP_DONE_IRQ | \
72                 XILINX_FRMBUF_ISR_AP_READY_IRQ)
73
74 /* Video Format Register Settings */
75 #define XILINX_FRMBUF_FMT_RGBX8                 10
76 #define XILINX_FRMBUF_FMT_YUVX8                 11
77 #define XILINX_FRMBUF_FMT_YUYV8                 12
78 #define XILINX_FRMBUF_FMT_RGBA8                 13
79 #define XILINX_FRMBUF_FMT_YUVA8                 14
80 #define XILINX_FRMBUF_FMT_RGBX10                15
81 #define XILINX_FRMBUF_FMT_YUVX10                16
82 #define XILINX_FRMBUF_FMT_Y_UV8                 18
83 #define XILINX_FRMBUF_FMT_Y_UV8_420             19
84 #define XILINX_FRMBUF_FMT_RGB8                  20
85 #define XILINX_FRMBUF_FMT_YUV8                  21
86 #define XILINX_FRMBUF_FMT_Y_UV10                22
87 #define XILINX_FRMBUF_FMT_Y_UV10_420            23
88 #define XILINX_FRMBUF_FMT_Y8                    24
89 #define XILINX_FRMBUF_FMT_Y10                   25
90 #define XILINX_FRMBUF_FMT_BGRA8                 26
91 #define XILINX_FRMBUF_FMT_BGRX8                 27
92 #define XILINX_FRMBUF_FMT_UYVY8                 28
93 #define XILINX_FRMBUF_FMT_BGR8                          29
94
95 /**
96  * struct xilinx_frmbuf_desc_hw - Hardware Descriptor
97  * @luma_plane_addr: Luma or packed plane buffer address
98  * @chroma_plane_addr: Chroma plane buffer address
99  * @vsize: Vertical Size
100  * @hsize: Horizontal Size
101  * @stride: Number of bytes between the first
102  *          pixels of each horizontal line
103  */
104 struct xilinx_frmbuf_desc_hw {
105         dma_addr_t luma_plane_addr;
106         dma_addr_t chroma_plane_addr;
107         u32 vsize;
108         u32 hsize;
109         u32 stride;
110 };
111
112 /**
113  * struct xilinx_frmbuf_tx_descriptor - Per Transaction structure
114  * @async_tx: Async transaction descriptor
115  * @hw: Hardware descriptor
116  * @node: Node in the channel descriptors list
117  */
118 struct xilinx_frmbuf_tx_descriptor {
119         struct dma_async_tx_descriptor async_tx;
120         struct xilinx_frmbuf_desc_hw hw;
121         struct list_head node;
122 };
123
124 /**
125  * struct xilinx_frmbuf_chan - Driver specific dma channel structure
126  * @xdev: Driver specific device structure
127  * @lock: Descriptor operation lock
128  * @chan_node: Member of a list of framebuffer channel instances
129  * @pending_list: Descriptors waiting
130  * @done_list: Complete descriptors
131  * @staged_desc: Next buffer to be programmed
132  * @active_desc: Currently active buffer being read/written to
133  * @common: DMA common channel
134  * @dev: The dma device
135  * @write_addr: callback that will write dma addresses to IP (32 or 64 bit)
136  * @irq: Channel IRQ
137  * @direction: Transfer direction
138  * @idle: Channel idle state
139  * @tasklet: Cleanup work after irq
140  * @vid_fmt: Reference to currently assigned video format description
141  */
142 struct xilinx_frmbuf_chan {
143         struct xilinx_frmbuf_device *xdev;
144         /* Descriptor operation lock */
145         spinlock_t lock;
146         struct list_head chan_node;
147         struct list_head pending_list;
148         struct list_head done_list;
149         struct xilinx_frmbuf_tx_descriptor *staged_desc;
150         struct xilinx_frmbuf_tx_descriptor *active_desc;
151         struct dma_chan common;
152         struct device *dev;
153         void (*write_addr)(struct xilinx_frmbuf_chan *chan, u32 reg,
154                            dma_addr_t value);
155         int irq;
156         enum dma_transfer_direction direction;
157         bool idle;
158         struct tasklet_struct tasklet;
159         const struct xilinx_frmbuf_format_desc *vid_fmt;
160 };
161
162 /**
163  * struct xilinx_frmbuf_format_desc - lookup table to match fourcc to format
164  * @dts_name: Device tree name for this entry.
165  * @id: Format ID
166  * @bpw: Bits of pixel data + padding in a 32-bit word (luma plane for semi-pl)
167  * @ppw: Number of pixels represented in a 32-bit word (luma plane for semi-pl)
168  * @num_planes: Expected number of plane buffers in framebuffer for this format
169  * @drm_fmt: DRM video framework equivalent fourcc code
170  * @v4l2_fmt: Video 4 Linux framework equivalent fourcc code
171  * @fmt_bitmask: Flag identifying this format in device-specific "enabled"
172  *      bitmap
173  */
174 struct xilinx_frmbuf_format_desc {
175         const char *dts_name;
176         u32 id;
177         u32 bpw;
178         u32 ppw;
179         u32 num_planes;
180         u32 drm_fmt;
181         u32 v4l2_fmt;
182         u32 fmt_bitmask;
183 };
184
185 static LIST_HEAD(frmbuf_chan_list);
186 static DEFINE_MUTEX(frmbuf_chan_list_lock);
187
188 static const struct xilinx_frmbuf_format_desc xilinx_frmbuf_formats[] = {
189         {
190                 .dts_name = "xbgr8888",
191                 .id = XILINX_FRMBUF_FMT_RGBX8,
192                 .bpw = 32,
193                 .ppw = 1,
194                 .num_planes = 1,
195                 .drm_fmt = DRM_FORMAT_XBGR8888,
196                 .v4l2_fmt = V4L2_PIX_FMT_BGRX32,
197                 .fmt_bitmask = BIT(0),
198         },
199         {
200                 .dts_name = "xbgr2101010",
201                 .id = XILINX_FRMBUF_FMT_RGBX10,
202                 .bpw = 32,
203                 .ppw = 1,
204                 .num_planes = 1,
205                 .drm_fmt = DRM_FORMAT_XBGR2101010,
206                 .v4l2_fmt = V4L2_PIX_FMT_XBGR30,
207                 .fmt_bitmask = BIT(1),
208         },
209         {
210                 .dts_name = "xrgb8888",
211                 .id = XILINX_FRMBUF_FMT_BGRX8,
212                 .bpw = 32,
213                 .ppw = 1,
214                 .num_planes = 1,
215                 .drm_fmt = DRM_FORMAT_XRGB8888,
216                 .v4l2_fmt = V4L2_PIX_FMT_XBGR32,
217                 .fmt_bitmask = BIT(2),
218         },
219         {
220                 .dts_name = "xvuy8888",
221                 .id = XILINX_FRMBUF_FMT_YUVX8,
222                 .bpw = 32,
223                 .ppw = 1,
224                 .num_planes = 1,
225                 .drm_fmt = DRM_FORMAT_XVUY8888,
226                 .v4l2_fmt = V4L2_PIX_FMT_XVUY32,
227                 .fmt_bitmask = BIT(5),
228         },
229         {
230                 .dts_name = "vuy888",
231                 .id = XILINX_FRMBUF_FMT_YUV8,
232                 .bpw = 24,
233                 .ppw = 1,
234                 .num_planes = 1,
235                 .drm_fmt = DRM_FORMAT_VUY888,
236                 .v4l2_fmt = V4L2_PIX_FMT_VUY24,
237                 .fmt_bitmask = BIT(6),
238         },
239         {
240                 .dts_name = "yuvx2101010",
241                 .id = XILINX_FRMBUF_FMT_YUVX10,
242                 .bpw = 32,
243                 .ppw = 1,
244                 .num_planes = 1,
245                 .drm_fmt = DRM_FORMAT_XVUY2101010,
246                 .v4l2_fmt = V4L2_PIX_FMT_XVUY10,
247                 .fmt_bitmask = BIT(7),
248         },
249         {
250                 .dts_name = "yuyv",
251                 .id = XILINX_FRMBUF_FMT_YUYV8,
252                 .bpw = 32,
253                 .ppw = 2,
254                 .num_planes = 1,
255                 .drm_fmt = DRM_FORMAT_YUYV,
256                 .v4l2_fmt = V4L2_PIX_FMT_YUYV,
257                 .fmt_bitmask = BIT(8),
258         },
259         {
260                 .dts_name = "uyvy",
261                 .id = XILINX_FRMBUF_FMT_UYVY8,
262                 .bpw = 32,
263                 .ppw = 2,
264                 .num_planes = 1,
265                 .drm_fmt = DRM_FORMAT_UYVY,
266                 .v4l2_fmt = V4L2_PIX_FMT_UYVY,
267                 .fmt_bitmask = BIT(9),
268         },
269         {
270                 .dts_name = "nv16",
271                 .id = XILINX_FRMBUF_FMT_Y_UV8,
272                 .bpw = 32,
273                 .ppw = 4,
274                 .num_planes = 2,
275                 .drm_fmt = DRM_FORMAT_NV16,
276                 .v4l2_fmt = V4L2_PIX_FMT_NV16M,
277                 .fmt_bitmask = BIT(11),
278         },
279         {
280                 .dts_name = "nv16",
281                 .id = XILINX_FRMBUF_FMT_Y_UV8,
282                 .bpw = 32,
283                 .ppw = 4,
284                 .num_planes = 2,
285                 .drm_fmt = 0,
286                 .v4l2_fmt = V4L2_PIX_FMT_NV16,
287                 .fmt_bitmask = BIT(11),
288         },
289         {
290                 .dts_name = "nv12",
291                 .id = XILINX_FRMBUF_FMT_Y_UV8_420,
292                 .bpw = 32,
293                 .ppw = 4,
294                 .num_planes = 2,
295                 .drm_fmt = DRM_FORMAT_NV12,
296                 .v4l2_fmt = V4L2_PIX_FMT_NV12M,
297                 .fmt_bitmask = BIT(12),
298         },
299         {
300                 .dts_name = "nv12",
301                 .id = XILINX_FRMBUF_FMT_Y_UV8_420,
302                 .bpw = 32,
303                 .ppw = 4,
304                 .num_planes = 2,
305                 .drm_fmt = 0,
306                 .v4l2_fmt = V4L2_PIX_FMT_NV12,
307                 .fmt_bitmask = BIT(12),
308         },
309         {
310                 .dts_name = "xv15",
311                 .id = XILINX_FRMBUF_FMT_Y_UV10_420,
312                 .bpw = 32,
313                 .ppw = 3,
314                 .num_planes = 2,
315                 .drm_fmt = DRM_FORMAT_XV15,
316                 .v4l2_fmt = V4L2_PIX_FMT_XV15M,
317                 .fmt_bitmask = BIT(13),
318         },
319         {
320                 .dts_name = "xv20",
321                 .id = XILINX_FRMBUF_FMT_Y_UV10,
322                 .bpw = 32,
323                 .ppw = 3,
324                 .num_planes = 2,
325                 .drm_fmt = DRM_FORMAT_XV20,
326                 .v4l2_fmt = V4L2_PIX_FMT_XV20M,
327                 .fmt_bitmask = BIT(14),
328         },
329         {
330                 .dts_name = "bgr888",
331                 .id = XILINX_FRMBUF_FMT_RGB8,
332                 .bpw = 24,
333                 .ppw = 1,
334                 .num_planes = 1,
335                 .drm_fmt = DRM_FORMAT_BGR888,
336                 .v4l2_fmt = V4L2_PIX_FMT_RGB24,
337                 .fmt_bitmask = BIT(15),
338         },
339         {
340                 .dts_name = "y8",
341                 .id = XILINX_FRMBUF_FMT_Y8,
342                 .bpw = 32,
343                 .ppw = 4,
344                 .num_planes = 1,
345                 .drm_fmt = DRM_FORMAT_Y8,
346                 .v4l2_fmt = V4L2_PIX_FMT_GREY,
347                 .fmt_bitmask = BIT(16),
348         },
349         {
350                 .dts_name = "y10",
351                 .id = XILINX_FRMBUF_FMT_Y10,
352                 .bpw = 32,
353                 .ppw = 3,
354                 .num_planes = 1,
355                 .drm_fmt = DRM_FORMAT_Y10,
356                 .v4l2_fmt = V4L2_PIX_FMT_Y10,
357                 .fmt_bitmask = BIT(17),
358         },
359         {
360                 .dts_name = "rgb888",
361                 .id = XILINX_FRMBUF_FMT_BGR8,
362                 .bpw = 24,
363                 .ppw = 1,
364                 .num_planes = 1,
365                 .drm_fmt = DRM_FORMAT_RGB888,
366                 .v4l2_fmt = V4L2_PIX_FMT_BGR24,
367                 .fmt_bitmask = BIT(18),
368         },
369 };
370
371 /**
372  * struct xilinx_frmbuf_device - dma device structure
373  * @regs: I/O mapped base address
374  * @dev: Device Structure
375  * @common: DMA device structure
376  * @chan: Driver specific dma channel
377  * @rst_gpio: GPIO reset
378  * @enabled_vid_fmts: Bitmask of video formats enabled in hardware
379  * @drm_memory_fmts: Array of supported DRM fourcc codes
380  * @drm_fmt_cnt: Count of supported DRM fourcc codes
381  * @v4l2_memory_fmts: Array of supported V4L2 fourcc codes
382  * @v4l2_fmt_cnt: Count of supported V4L2 fourcc codes
383  */
384 struct xilinx_frmbuf_device {
385         void __iomem *regs;
386         struct device *dev;
387         struct dma_device common;
388         struct xilinx_frmbuf_chan chan;
389         struct gpio_desc *rst_gpio;
390         u32 enabled_vid_fmts;
391         u32 drm_memory_fmts[ARRAY_SIZE(xilinx_frmbuf_formats)];
392         u32 drm_fmt_cnt;
393         u32 v4l2_memory_fmts[ARRAY_SIZE(xilinx_frmbuf_formats)];
394         u32 v4l2_fmt_cnt;
395 };
396
397 static const struct of_device_id xilinx_frmbuf_of_ids[] = {
398         { .compatible = "xlnx,axi-frmbuf-wr-v2",
399                 .data = (void *)DMA_DEV_TO_MEM},
400         { .compatible = "xlnx,axi-frmbuf-rd-v2",
401                 .data = (void *)DMA_MEM_TO_DEV},
402         {/* end of list */}
403 };
404
405 /******************************PROTOTYPES*************************************/
406 #define to_xilinx_chan(chan) \
407         container_of(chan, struct xilinx_frmbuf_chan, common)
408 #define to_dma_tx_descriptor(tx) \
409         container_of(tx, struct xilinx_frmbuf_tx_descriptor, async_tx)
410
411 static inline u32 frmbuf_read(struct xilinx_frmbuf_chan *chan, u32 reg)
412 {
413         return ioread32(chan->xdev->regs + reg);
414 }
415
416 static inline void frmbuf_write(struct xilinx_frmbuf_chan *chan, u32 reg,
417                                 u32 value)
418 {
419         iowrite32(value, chan->xdev->regs + reg);
420 }
421
422 static inline void frmbuf_writeq(struct xilinx_frmbuf_chan *chan, u32 reg,
423                                  u64 value)
424 {
425         iowrite32(lower_32_bits(value), chan->xdev->regs + reg);
426         iowrite32(upper_32_bits(value), chan->xdev->regs + reg + 4);
427 }
428
429 static void writeq_addr(struct xilinx_frmbuf_chan *chan, u32 reg,
430                         dma_addr_t addr)
431 {
432         frmbuf_writeq(chan, reg, (u64)addr);
433 }
434
435 static void write_addr(struct xilinx_frmbuf_chan *chan, u32 reg,
436                        dma_addr_t addr)
437 {
438         frmbuf_write(chan, reg, addr);
439 }
440
441 static inline void frmbuf_clr(struct xilinx_frmbuf_chan *chan, u32 reg,
442                               u32 clr)
443 {
444         frmbuf_write(chan, reg, frmbuf_read(chan, reg) & ~clr);
445 }
446
447 static inline void frmbuf_set(struct xilinx_frmbuf_chan *chan, u32 reg,
448                               u32 set)
449 {
450         frmbuf_write(chan, reg, frmbuf_read(chan, reg) | set);
451 }
452
453 static void frmbuf_init_format_array(struct xilinx_frmbuf_device *xdev)
454 {
455         u32 i, cnt;
456
457         for (i = 0; i < ARRAY_SIZE(xilinx_frmbuf_formats); i++) {
458                 if (!(xdev->enabled_vid_fmts &
459                       xilinx_frmbuf_formats[i].fmt_bitmask))
460                         continue;
461
462                 if (xilinx_frmbuf_formats[i].drm_fmt) {
463                         cnt = xdev->drm_fmt_cnt++;
464                         xdev->drm_memory_fmts[cnt] =
465                                 xilinx_frmbuf_formats[i].drm_fmt;
466                 }
467
468                 if (xilinx_frmbuf_formats[i].v4l2_fmt) {
469                         cnt = xdev->v4l2_fmt_cnt++;
470                         xdev->v4l2_memory_fmts[cnt] =
471                                 xilinx_frmbuf_formats[i].v4l2_fmt;
472                 }
473         }
474 }
475
476 static struct xilinx_frmbuf_device *frmbuf_find_dev(struct dma_chan *chan)
477 {
478         struct xilinx_frmbuf_chan *xchan, *temp;
479         struct xilinx_frmbuf_device *xdev;
480         bool is_frmbuf_chan = false;
481
482         list_for_each_entry_safe(xchan, temp, &frmbuf_chan_list, chan_node) {
483                 if (chan == &xchan->common)
484                         is_frmbuf_chan = true;
485         }
486
487         if (!is_frmbuf_chan)
488                 return ERR_PTR(-ENODEV);
489
490         xchan = to_xilinx_chan(chan);
491         xdev = container_of(xchan, struct xilinx_frmbuf_device, chan);
492
493         return xdev;
494 }
495
496 static int frmbuf_verify_format(struct dma_chan *chan, u32 fourcc, u32 type)
497 {
498         struct xilinx_frmbuf_chan *xil_chan = to_xilinx_chan(chan);
499         u32 i, sz = ARRAY_SIZE(xilinx_frmbuf_formats);
500
501         for (i = 0; i < sz; i++) {
502                 if ((type == XDMA_DRM &&
503                      fourcc != xilinx_frmbuf_formats[i].drm_fmt) ||
504                    (type == XDMA_V4L2 &&
505                     fourcc != xilinx_frmbuf_formats[i].v4l2_fmt))
506                         continue;
507
508                 if (!(xilinx_frmbuf_formats[i].fmt_bitmask &
509                       xil_chan->xdev->enabled_vid_fmts))
510                         return -EINVAL;
511
512                 xil_chan->vid_fmt = &xilinx_frmbuf_formats[i];
513                 return 0;
514         }
515         return -EINVAL;
516 }
517
518 static void xilinx_xdma_set_config(struct dma_chan *chan, u32 fourcc, u32 type)
519 {
520         struct xilinx_frmbuf_chan *xil_chan;
521         bool found_xchan = false;
522         int ret;
523
524         mutex_lock(&frmbuf_chan_list_lock);
525         list_for_each_entry(xil_chan, &frmbuf_chan_list, chan_node) {
526                 if (chan == &xil_chan->common) {
527                         found_xchan = true;
528                         break;
529                 }
530         }
531         mutex_unlock(&frmbuf_chan_list_lock);
532
533         if (!found_xchan) {
534                 dev_dbg(chan->device->dev,
535                         "dma chan not a Video Framebuffer channel instance\n");
536                 return;
537         }
538
539         ret = frmbuf_verify_format(chan, fourcc, type);
540         if (ret == -EINVAL) {
541                 dev_err(chan->device->dev,
542                         "Framebuffer not configured for fourcc 0x%x\n",
543                         fourcc);
544                 return;
545         }
546 }
547
548 void xilinx_xdma_drm_config(struct dma_chan *chan, u32 drm_fourcc)
549 {
550         xilinx_xdma_set_config(chan, drm_fourcc, XDMA_DRM);
551
552 } EXPORT_SYMBOL_GPL(xilinx_xdma_drm_config);
553
554 void xilinx_xdma_v4l2_config(struct dma_chan *chan, u32 v4l2_fourcc)
555 {
556         xilinx_xdma_set_config(chan, v4l2_fourcc, XDMA_V4L2);
557
558 } EXPORT_SYMBOL_GPL(xilinx_xdma_v4l2_config);
559
560 int xilinx_xdma_get_drm_vid_fmts(struct dma_chan *chan, u32 *fmt_cnt,
561                                  u32 **fmts)
562 {
563         struct xilinx_frmbuf_device *xdev;
564
565         xdev = frmbuf_find_dev(chan);
566
567         if (IS_ERR(xdev))
568                 return PTR_ERR(xdev);
569
570         *fmt_cnt = xdev->drm_fmt_cnt;
571         *fmts = xdev->drm_memory_fmts;
572
573         return 0;
574 }
575 EXPORT_SYMBOL(xilinx_xdma_get_drm_vid_fmts);
576
577 int xilinx_xdma_get_v4l2_vid_fmts(struct dma_chan *chan, u32 *fmt_cnt,
578                                   u32 **fmts)
579 {
580         struct xilinx_frmbuf_device *xdev;
581
582         xdev = frmbuf_find_dev(chan);
583
584         if (IS_ERR(xdev))
585                 return PTR_ERR(xdev);
586
587         *fmt_cnt = xdev->v4l2_fmt_cnt;
588         *fmts = xdev->v4l2_memory_fmts;
589
590         return 0;
591 }
592 EXPORT_SYMBOL(xilinx_xdma_get_v4l2_vid_fmts);
593
594 /**
595  * of_dma_xilinx_xlate - Translation function
596  * @dma_spec: Pointer to DMA specifier as found in the device tree
597  * @ofdma: Pointer to DMA controller data
598  *
599  * Return: DMA channel pointer on success or error code on error
600  */
601 static struct dma_chan *of_dma_xilinx_xlate(struct of_phandle_args *dma_spec,
602                                             struct of_dma *ofdma)
603 {
604         struct xilinx_frmbuf_device *xdev = ofdma->of_dma_data;
605
606         return dma_get_slave_channel(&xdev->chan.common);
607 }
608
609 /* -----------------------------------------------------------------------------
610  * Descriptors alloc and free
611  */
612
613 /**
614  * xilinx_frmbuf_tx_descriptor - Allocate transaction descriptor
615  * @chan: Driver specific dma channel
616  *
617  * Return: The allocated descriptor on success and NULL on failure.
618  */
619 static struct xilinx_frmbuf_tx_descriptor *
620 xilinx_frmbuf_alloc_tx_descriptor(struct xilinx_frmbuf_chan *chan)
621 {
622         struct xilinx_frmbuf_tx_descriptor *desc;
623
624         desc = kzalloc(sizeof(*desc), GFP_KERNEL);
625         if (!desc)
626                 return NULL;
627
628         return desc;
629 }
630
631 /**
632  * xilinx_frmbuf_free_desc_list - Free descriptors list
633  * @chan: Driver specific dma channel
634  * @list: List to parse and delete the descriptor
635  */
636 static void xilinx_frmbuf_free_desc_list(struct xilinx_frmbuf_chan *chan,
637                                          struct list_head *list)
638 {
639         struct xilinx_frmbuf_tx_descriptor *desc, *next;
640
641         list_for_each_entry_safe(desc, next, list, node) {
642                 list_del(&desc->node);
643                 kfree(desc);
644         }
645 }
646
647 /**
648  * xilinx_frmbuf_free_descriptors - Free channel descriptors
649  * @chan: Driver specific dma channel
650  */
651 static void xilinx_frmbuf_free_descriptors(struct xilinx_frmbuf_chan *chan)
652 {
653         unsigned long flags;
654
655         spin_lock_irqsave(&chan->lock, flags);
656
657         xilinx_frmbuf_free_desc_list(chan, &chan->pending_list);
658         xilinx_frmbuf_free_desc_list(chan, &chan->done_list);
659         kfree(chan->active_desc);
660         kfree(chan->staged_desc);
661
662         chan->staged_desc = NULL;
663         chan->active_desc = NULL;
664         INIT_LIST_HEAD(&chan->pending_list);
665         INIT_LIST_HEAD(&chan->done_list);
666
667         spin_unlock_irqrestore(&chan->lock, flags);
668 }
669
670 /**
671  * xilinx_frmbuf_free_chan_resources - Free channel resources
672  * @dchan: DMA channel
673  */
674 static void xilinx_frmbuf_free_chan_resources(struct dma_chan *dchan)
675 {
676         struct xilinx_frmbuf_chan *chan = to_xilinx_chan(dchan);
677
678         xilinx_frmbuf_free_descriptors(chan);
679 }
680
681 /**
682  * xilinx_frmbuf_chan_desc_cleanup - Clean channel descriptors
683  * @chan: Driver specific dma channel
684  */
685 static void xilinx_frmbuf_chan_desc_cleanup(struct xilinx_frmbuf_chan *chan)
686 {
687         struct xilinx_frmbuf_tx_descriptor *desc, *next;
688         unsigned long flags;
689
690         spin_lock_irqsave(&chan->lock, flags);
691
692         list_for_each_entry_safe(desc, next, &chan->done_list, node) {
693                 dma_async_tx_callback callback;
694                 void *callback_param;
695
696                 list_del(&desc->node);
697
698                 /* Run the link descriptor callback function */
699                 callback = desc->async_tx.callback;
700                 callback_param = desc->async_tx.callback_param;
701                 if (callback) {
702                         spin_unlock_irqrestore(&chan->lock, flags);
703                         callback(callback_param);
704                         spin_lock_irqsave(&chan->lock, flags);
705                 }
706
707                 /* Run any dependencies, then free the descriptor */
708                 dma_run_dependencies(&desc->async_tx);
709                 kfree(desc);
710         }
711
712         spin_unlock_irqrestore(&chan->lock, flags);
713 }
714
715 /**
716  * xilinx_frmbuf_do_tasklet - Schedule completion tasklet
717  * @data: Pointer to the Xilinx frmbuf channel structure
718  */
719 static void xilinx_frmbuf_do_tasklet(unsigned long data)
720 {
721         struct xilinx_frmbuf_chan *chan = (struct xilinx_frmbuf_chan *)data;
722
723         xilinx_frmbuf_chan_desc_cleanup(chan);
724 }
725
726 /**
727  * xilinx_frmbuf_alloc_chan_resources - Allocate channel resources
728  * @dchan: DMA channel
729  *
730  * Return: '0' on success and failure value on error
731  */
732 static int xilinx_frmbuf_alloc_chan_resources(struct dma_chan *dchan)
733 {
734         dma_cookie_init(dchan);
735
736         return 0;
737 }
738
739 /**
740  * xilinx_frmbuf_tx_status - Get frmbuf transaction status
741  * @dchan: DMA channel
742  * @cookie: Transaction identifier
743  * @txstate: Transaction state
744  *
745  * Return: fmrbuf transaction status
746  */
747 static enum dma_status xilinx_frmbuf_tx_status(struct dma_chan *dchan,
748                                                dma_cookie_t cookie,
749                                                struct dma_tx_state *txstate)
750 {
751         return dma_cookie_status(dchan, cookie, txstate);
752 }
753
754 /**
755  * xilinx_frmbuf_halt - Halt frmbuf channel
756  * @chan: Driver specific dma channel
757  */
758 static void xilinx_frmbuf_halt(struct xilinx_frmbuf_chan *chan)
759 {
760         frmbuf_clr(chan, XILINX_FRMBUF_CTRL_OFFSET,
761                    XILINX_FRMBUF_CTRL_AP_START |
762                    XILINX_FRMBUF_CTRL_AUTO_RESTART);
763         chan->idle = true;
764 }
765
766 /**
767  * xilinx_frmbuf_start - Start dma channel
768  * @chan: Driver specific dma channel
769  */
770 static void xilinx_frmbuf_start(struct xilinx_frmbuf_chan *chan)
771 {
772         frmbuf_set(chan, XILINX_FRMBUF_CTRL_OFFSET,
773                    XILINX_FRMBUF_CTRL_AP_START |
774                    XILINX_FRMBUF_CTRL_AUTO_RESTART);
775         chan->idle = false;
776 }
777
778 /**
779  * xilinx_frmbuf_complete_descriptor - Mark the active descriptor as complete
780  * This function is invoked with spinlock held
781  * @chan : xilinx frmbuf channel
782  *
783  * CONTEXT: hardirq
784  */
785 static void xilinx_frmbuf_complete_descriptor(struct xilinx_frmbuf_chan *chan)
786 {
787         struct xilinx_frmbuf_tx_descriptor *desc = chan->active_desc;
788
789         dma_cookie_complete(&desc->async_tx);
790         list_add_tail(&desc->node, &chan->done_list);
791 }
792
793 /**
794  * xilinx_frmbuf_start_transfer - Starts frmbuf transfer
795  * @chan: Driver specific channel struct pointer
796  */
797 static void xilinx_frmbuf_start_transfer(struct xilinx_frmbuf_chan *chan)
798 {
799         struct xilinx_frmbuf_tx_descriptor *desc;
800
801         if (!chan->idle)
802                 return;
803
804         if (chan->active_desc) {
805                 xilinx_frmbuf_complete_descriptor(chan);
806                 chan->active_desc = NULL;
807         }
808
809         if (chan->staged_desc) {
810                 chan->active_desc = chan->staged_desc;
811                 chan->staged_desc = NULL;
812         }
813
814         if (list_empty(&chan->pending_list))
815                 return;
816
817         desc = list_first_entry(&chan->pending_list,
818                                 struct xilinx_frmbuf_tx_descriptor,
819                                 node);
820
821         /* Start the transfer */
822         chan->write_addr(chan, XILINX_FRMBUF_ADDR_OFFSET,
823                          desc->hw.luma_plane_addr);
824         chan->write_addr(chan, XILINX_FRMBUF_ADDR2_OFFSET,
825                          desc->hw.chroma_plane_addr);
826
827         /* HW expects these parameters to be same for one transaction */
828         frmbuf_write(chan, XILINX_FRMBUF_WIDTH_OFFSET, desc->hw.hsize);
829         frmbuf_write(chan, XILINX_FRMBUF_STRIDE_OFFSET, desc->hw.stride);
830         frmbuf_write(chan, XILINX_FRMBUF_HEIGHT_OFFSET, desc->hw.vsize);
831         frmbuf_write(chan, XILINX_FRMBUF_FMT_OFFSET, chan->vid_fmt->id);
832
833         /* Start the hardware */
834         xilinx_frmbuf_start(chan);
835         list_del(&desc->node);
836         chan->staged_desc = desc;
837 }
838
839 /**
840  * xilinx_frmbuf_issue_pending - Issue pending transactions
841  * @dchan: DMA channel
842  */
843 static void xilinx_frmbuf_issue_pending(struct dma_chan *dchan)
844 {
845         struct xilinx_frmbuf_chan *chan = to_xilinx_chan(dchan);
846         unsigned long flags;
847
848         spin_lock_irqsave(&chan->lock, flags);
849         xilinx_frmbuf_start_transfer(chan);
850         spin_unlock_irqrestore(&chan->lock, flags);
851 }
852
853 /**
854  * xilinx_frmbuf_reset - Reset frmbuf channel
855  * @chan: Driver specific dma channel
856  */
857 static void xilinx_frmbuf_reset(struct xilinx_frmbuf_chan *chan)
858 {
859         /* reset ip */
860         gpiod_set_value(chan->xdev->rst_gpio, 1);
861         udelay(1);
862         gpiod_set_value(chan->xdev->rst_gpio, 0);
863 }
864
865 /**
866  * xilinx_frmbuf_chan_reset - Reset frmbuf channel and enable interrupts
867  * @chan: Driver specific frmbuf channel
868  */
869 static void xilinx_frmbuf_chan_reset(struct xilinx_frmbuf_chan *chan)
870 {
871         xilinx_frmbuf_reset(chan);
872         frmbuf_write(chan, XILINX_FRMBUF_IE_OFFSET, XILINX_FRMBUF_IE_AP_READY);
873         frmbuf_write(chan, XILINX_FRMBUF_GIE_OFFSET, XILINX_FRMBUF_GIE_EN);
874 }
875
876 /**
877  * xilinx_frmbuf_irq_handler - frmbuf Interrupt handler
878  * @irq: IRQ number
879  * @data: Pointer to the Xilinx frmbuf channel structure
880  *
881  * Return: IRQ_HANDLED/IRQ_NONE
882  */
883 static irqreturn_t xilinx_frmbuf_irq_handler(int irq, void *data)
884 {
885         struct xilinx_frmbuf_chan *chan = data;
886         u32 status;
887
888         status = frmbuf_read(chan, XILINX_FRMBUF_ISR_OFFSET);
889         if (!(status & XILINX_FRMBUF_ISR_ALL_IRQ_MASK))
890                 return IRQ_NONE;
891
892         frmbuf_write(chan, XILINX_FRMBUF_ISR_OFFSET,
893                      status & XILINX_FRMBUF_ISR_ALL_IRQ_MASK);
894
895         if (status & XILINX_FRMBUF_ISR_AP_READY_IRQ) {
896                 spin_lock(&chan->lock);
897                 chan->idle = true;
898                 xilinx_frmbuf_start_transfer(chan);
899                 spin_unlock(&chan->lock);
900         }
901
902         tasklet_schedule(&chan->tasklet);
903         return IRQ_HANDLED;
904 }
905
906 /**
907  * xilinx_frmbuf_tx_submit - Submit DMA transaction
908  * @tx: Async transaction descriptor
909  *
910  * Return: cookie value on success and failure value on error
911  */
912 static dma_cookie_t xilinx_frmbuf_tx_submit(struct dma_async_tx_descriptor *tx)
913 {
914         struct xilinx_frmbuf_tx_descriptor *desc = to_dma_tx_descriptor(tx);
915         struct xilinx_frmbuf_chan *chan = to_xilinx_chan(tx->chan);
916         dma_cookie_t cookie;
917         unsigned long flags;
918
919         spin_lock_irqsave(&chan->lock, flags);
920         cookie = dma_cookie_assign(tx);
921         list_add_tail(&desc->node, &chan->pending_list);
922         spin_unlock_irqrestore(&chan->lock, flags);
923
924         return cookie;
925 }
926
927 /**
928  * xilinx_frmbuf_dma_prep_interleaved - prepare a descriptor for a
929  *      DMA_SLAVE transaction
930  * @dchan: DMA channel
931  * @xt: Interleaved template pointer
932  * @flags: transfer ack flags
933  *
934  * Return: Async transaction descriptor on success and NULL on failure
935  */
936 static struct dma_async_tx_descriptor *
937 xilinx_frmbuf_dma_prep_interleaved(struct dma_chan *dchan,
938                                    struct dma_interleaved_template *xt,
939                                    unsigned long flags)
940 {
941         struct xilinx_frmbuf_chan *chan = to_xilinx_chan(dchan);
942         struct xilinx_frmbuf_tx_descriptor *desc;
943         struct xilinx_frmbuf_desc_hw *hw;
944
945         if (chan->direction != xt->dir || !chan->vid_fmt)
946                 goto error;
947
948         if (!xt->numf || !xt->sgl[0].size)
949                 goto error;
950
951         if (xt->frame_size != chan->vid_fmt->num_planes)
952                 goto error;
953
954         desc = xilinx_frmbuf_alloc_tx_descriptor(chan);
955         if (!desc)
956                 return NULL;
957
958         dma_async_tx_descriptor_init(&desc->async_tx, &chan->common);
959         desc->async_tx.tx_submit = xilinx_frmbuf_tx_submit;
960         async_tx_ack(&desc->async_tx);
961
962         hw = &desc->hw;
963         hw->vsize = xt->numf;
964         hw->stride = xt->sgl[0].icg + xt->sgl[0].size;
965         hw->hsize = (xt->sgl[0].size * chan->vid_fmt->ppw * 8) /
966                      chan->vid_fmt->bpw;
967
968         /* hsize calc should not have resulted in an odd number */
969         if (hw->hsize & 1)
970                 hw->hsize++;
971
972         if (chan->direction == DMA_MEM_TO_DEV) {
973                 hw->luma_plane_addr = xt->src_start;
974                 if (xt->frame_size == 2)
975                         hw->chroma_plane_addr =
976                                 xt->src_start +
977                                 xt->numf * hw->stride +
978                                 xt->sgl[0].src_icg;
979         } else {
980                 hw->luma_plane_addr = xt->dst_start;
981                 if (xt->frame_size == 2)
982                         hw->chroma_plane_addr =
983                                 xt->dst_start +
984                                 xt->numf * hw->stride +
985                                 xt->sgl[0].dst_icg;
986         }
987
988         return &desc->async_tx;
989
990 error:
991         dev_err(chan->xdev->dev,
992                 "Invalid dma template or missing dma video fmt config\n");
993         return NULL;
994 }
995
996 /**
997  * xilinx_frmbuf_terminate_all - Halt the channel and free descriptors
998  * @dchan: Driver specific dma channel pointer
999  *
1000  * Return: 0
1001  */
1002 static int xilinx_frmbuf_terminate_all(struct dma_chan *dchan)
1003 {
1004         struct xilinx_frmbuf_chan *chan = to_xilinx_chan(dchan);
1005
1006         xilinx_frmbuf_halt(chan);
1007         xilinx_frmbuf_free_descriptors(chan);
1008         /* worst case frame-to-frame boundary; ensure frame output complete */
1009         msleep(50);
1010         xilinx_frmbuf_chan_reset(chan);
1011
1012         return 0;
1013 }
1014
1015 /**
1016  * xilinx_frmbuf_synchronize - kill tasklet to stop further descr processing
1017  * @dchan: Driver specific dma channel pointer
1018  */
1019 static void xilinx_frmbuf_synchronize(struct dma_chan *dchan)
1020 {
1021         struct xilinx_frmbuf_chan *chan = to_xilinx_chan(dchan);
1022
1023         tasklet_kill(&chan->tasklet);
1024 }
1025
1026 /* -----------------------------------------------------------------------------
1027  * Probe and remove
1028  */
1029
1030 /**
1031  * xilinx_frmbuf_chan_remove - Per Channel remove function
1032  * @chan: Driver specific dma channel
1033  */
1034 static void xilinx_frmbuf_chan_remove(struct xilinx_frmbuf_chan *chan)
1035 {
1036         /* Disable all interrupts */
1037         frmbuf_clr(chan, XILINX_FRMBUF_IE_OFFSET,
1038                    XILINX_FRMBUF_ISR_ALL_IRQ_MASK);
1039
1040         tasklet_kill(&chan->tasklet);
1041         list_del(&chan->common.device_node);
1042
1043         mutex_lock(&frmbuf_chan_list_lock);
1044         list_del(&chan->chan_node);
1045         mutex_unlock(&frmbuf_chan_list_lock);
1046 }
1047
1048 /**
1049  * xilinx_frmbuf_chan_probe - Per Channel Probing
1050  * It get channel features from the device tree entry and
1051  * initialize special channel handling routines
1052  *
1053  * @xdev: Driver specific device structure
1054  * @node: Device node
1055  *
1056  * Return: '0' on success and failure value on error
1057  */
1058 static int xilinx_frmbuf_chan_probe(struct xilinx_frmbuf_device *xdev,
1059                                     struct device_node *node)
1060 {
1061         struct xilinx_frmbuf_chan *chan;
1062         int err;
1063         u32 dma_addr_size;
1064
1065         chan = &xdev->chan;
1066
1067         chan->dev = xdev->dev;
1068         chan->xdev = xdev;
1069         chan->idle = true;
1070
1071         err = of_property_read_u32(node, "xlnx,dma-addr-width",
1072                                    &dma_addr_size);
1073         if (err || (dma_addr_size != 32 && dma_addr_size != 64)) {
1074                 dev_err(xdev->dev, "missing or invalid addr width dts prop\n");
1075                 return err;
1076         }
1077
1078         if (dma_addr_size == 64 && sizeof(dma_addr_t) == sizeof(u64))
1079                 chan->write_addr = writeq_addr;
1080         else
1081                 chan->write_addr = write_addr;
1082
1083         spin_lock_init(&chan->lock);
1084         INIT_LIST_HEAD(&chan->pending_list);
1085         INIT_LIST_HEAD(&chan->done_list);
1086
1087         chan->irq = irq_of_parse_and_map(node, 0);
1088         err = devm_request_irq(xdev->dev, chan->irq, xilinx_frmbuf_irq_handler,
1089                                IRQF_SHARED, "xilinx_framebuffer", chan);
1090
1091         if (err) {
1092                 dev_err(xdev->dev, "unable to request IRQ %d\n", chan->irq);
1093                 return err;
1094         }
1095
1096         tasklet_init(&chan->tasklet, xilinx_frmbuf_do_tasklet,
1097                      (unsigned long)chan);
1098
1099         /*
1100          * Initialize the DMA channel and add it to the DMA engine channels
1101          * list.
1102          */
1103         chan->common.device = &xdev->common;
1104
1105         list_add_tail(&chan->common.device_node, &xdev->common.channels);
1106
1107         mutex_lock(&frmbuf_chan_list_lock);
1108         list_add_tail(&chan->chan_node, &frmbuf_chan_list);
1109         mutex_unlock(&frmbuf_chan_list_lock);
1110
1111         xilinx_frmbuf_chan_reset(chan);
1112
1113         return 0;
1114 }
1115
1116 /**
1117  * xilinx_frmbuf_probe - Driver probe function
1118  * @pdev: Pointer to the platform_device structure
1119  *
1120  * Return: '0' on success and failure value on error
1121  */
1122 static int xilinx_frmbuf_probe(struct platform_device *pdev)
1123 {
1124         struct device_node *node = pdev->dev.of_node;
1125         struct xilinx_frmbuf_device *xdev;
1126         struct resource *io;
1127         enum dma_transfer_direction dma_dir;
1128         const struct of_device_id *match;
1129         int err;
1130         u32 i, j;
1131         int hw_vid_fmt_cnt;
1132         const char *vid_fmts[ARRAY_SIZE(xilinx_frmbuf_formats)];
1133
1134         xdev = devm_kzalloc(&pdev->dev, sizeof(*xdev), GFP_KERNEL);
1135         if (!xdev)
1136                 return -ENOMEM;
1137
1138         xdev->dev = &pdev->dev;
1139
1140         match = of_match_node(xilinx_frmbuf_of_ids, node);
1141         if (!match)
1142                 return -ENODEV;
1143
1144         dma_dir = (enum dma_transfer_direction)match->data;
1145
1146         xdev->rst_gpio = devm_gpiod_get(&pdev->dev, "reset",
1147                                         GPIOD_OUT_HIGH);
1148         if (IS_ERR(xdev->rst_gpio)) {
1149                 err = PTR_ERR(xdev->rst_gpio);
1150                 if (err == -EPROBE_DEFER)
1151                         dev_info(&pdev->dev,
1152                                  "Probe deferred due to GPIO reset defer\n");
1153                 else
1154                         dev_err(&pdev->dev,
1155                                 "Unable to locate reset property in dt\n");
1156                 return err;
1157         }
1158
1159         gpiod_set_value_cansleep(xdev->rst_gpio, 0x0);
1160
1161         io = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1162         xdev->regs = devm_ioremap_resource(&pdev->dev, io);
1163         if (IS_ERR(xdev->regs))
1164                 return PTR_ERR(xdev->regs);
1165
1166         /* Initialize the DMA engine */
1167         /* TODO: Get DMA alignment from device tree property */
1168         xdev->common.copy_align = 4;
1169         xdev->common.dev = &pdev->dev;
1170
1171         INIT_LIST_HEAD(&xdev->common.channels);
1172         dma_cap_set(DMA_SLAVE, xdev->common.cap_mask);
1173         dma_cap_set(DMA_PRIVATE, xdev->common.cap_mask);
1174
1175         /* Initialize the channels */
1176         err = xilinx_frmbuf_chan_probe(xdev, node);
1177         if (err < 0)
1178                 return err;
1179
1180         xdev->chan.direction = dma_dir;
1181
1182         if (xdev->chan.direction == DMA_DEV_TO_MEM) {
1183                 xdev->common.directions = BIT(DMA_DEV_TO_MEM);
1184                 dev_info(&pdev->dev, "Xilinx AXI frmbuf DMA_DEV_TO_MEM\n");
1185         } else if (xdev->chan.direction == DMA_MEM_TO_DEV) {
1186                 xdev->common.directions = BIT(DMA_MEM_TO_DEV);
1187                 dev_info(&pdev->dev, "Xilinx AXI frmbuf DMA_MEM_TO_DEV\n");
1188         } else {
1189                 xilinx_frmbuf_chan_remove(&xdev->chan);
1190                 return -EINVAL;
1191         }
1192
1193         /* read supported video formats and update internal table */
1194         hw_vid_fmt_cnt = of_property_count_strings(node, "xlnx,vid-formats");
1195
1196         err = of_property_read_string_array(node, "xlnx,vid-formats",
1197                                             vid_fmts, hw_vid_fmt_cnt);
1198         if (err < 0) {
1199                 dev_err(&pdev->dev,
1200                         "Missing or invalid xlnx,vid-formats dts prop\n");
1201                 return err;
1202         }
1203
1204         for (i = 0; i < hw_vid_fmt_cnt; i++) {
1205                 const char *vid_fmt_name = vid_fmts[i];
1206
1207                 for (j = 0; j < ARRAY_SIZE(xilinx_frmbuf_formats); j++) {
1208                         const char *dts_name =
1209                                 xilinx_frmbuf_formats[j].dts_name;
1210
1211                         if (strcmp(vid_fmt_name, dts_name))
1212                                 continue;
1213
1214                         xdev->enabled_vid_fmts |=
1215                                 xilinx_frmbuf_formats[j].fmt_bitmask;
1216                 }
1217         }
1218
1219         /* Determine supported vid framework formats */
1220         frmbuf_init_format_array(xdev);
1221
1222         xdev->common.device_alloc_chan_resources =
1223                                 xilinx_frmbuf_alloc_chan_resources;
1224         xdev->common.device_free_chan_resources =
1225                                 xilinx_frmbuf_free_chan_resources;
1226         xdev->common.device_prep_interleaved_dma =
1227                                 xilinx_frmbuf_dma_prep_interleaved;
1228         xdev->common.device_terminate_all = xilinx_frmbuf_terminate_all;
1229         xdev->common.device_synchronize = xilinx_frmbuf_synchronize;
1230         xdev->common.device_tx_status = xilinx_frmbuf_tx_status;
1231         xdev->common.device_issue_pending = xilinx_frmbuf_issue_pending;
1232
1233         platform_set_drvdata(pdev, xdev);
1234
1235         /* Register the DMA engine with the core */
1236         dma_async_device_register(&xdev->common);
1237         err = of_dma_controller_register(node, of_dma_xilinx_xlate, xdev);
1238
1239         if (err < 0) {
1240                 dev_err(&pdev->dev, "Unable to register DMA to DT\n");
1241                 xilinx_frmbuf_chan_remove(&xdev->chan);
1242                 dma_async_device_unregister(&xdev->common);
1243                 return err;
1244         }
1245
1246         dev_info(&pdev->dev, "Xilinx AXI FrameBuffer Engine Driver Probed!!\n");
1247
1248         return 0;
1249 }
1250
1251 /**
1252  * xilinx_frmbuf_remove - Driver remove function
1253  * @pdev: Pointer to the platform_device structure
1254  *
1255  * Return: Always '0'
1256  */
1257 static int xilinx_frmbuf_remove(struct platform_device *pdev)
1258 {
1259         struct xilinx_frmbuf_device *xdev = platform_get_drvdata(pdev);
1260
1261         dma_async_device_unregister(&xdev->common);
1262         xilinx_frmbuf_chan_remove(&xdev->chan);
1263
1264         return 0;
1265 }
1266
1267 MODULE_DEVICE_TABLE(of, xilinx_frmbuf_of_ids);
1268
1269 static struct platform_driver xilinx_frmbuf_driver = {
1270         .driver = {
1271                 .name = "xilinx-frmbuf",
1272                 .of_match_table = xilinx_frmbuf_of_ids,
1273         },
1274         .probe = xilinx_frmbuf_probe,
1275         .remove = xilinx_frmbuf_remove,
1276 };
1277
1278 module_platform_driver(xilinx_frmbuf_driver);
1279
1280 MODULE_AUTHOR("Xilinx, Inc.");
1281 MODULE_DESCRIPTION("Xilinx Framebuffer driver");
1282 MODULE_LICENSE("GPL v2");