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