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