Merge tag 'drm-intel-next-2019-03-20' of git://anongit.freedesktop.org/drm/drm-intel...
[sfrench/cifs-2.6.git] / drivers / media / platform / ti-vpe / vpdma.c
1 /*
2  * VPDMA helper library
3  *
4  * Copyright (c) 2013 Texas Instruments Inc.
5  *
6  * David Griego, <dagriego@biglakesoftware.com>
7  * Dale Farnsworth, <dale@farnsworth.org>
8  * Archit Taneja, <archit@ti.com>
9  *
10  * This program is free software; you can redistribute it and/or modify it
11  * under the terms of the GNU General Public License version 2 as published by
12  * the Free Software Foundation.
13  */
14
15 #include <linux/delay.h>
16 #include <linux/dma-mapping.h>
17 #include <linux/err.h>
18 #include <linux/firmware.h>
19 #include <linux/io.h>
20 #include <linux/module.h>
21 #include <linux/platform_device.h>
22 #include <linux/sched.h>
23 #include <linux/slab.h>
24 #include <linux/videodev2.h>
25
26 #include "vpdma.h"
27 #include "vpdma_priv.h"
28
29 #define VPDMA_FIRMWARE  "vpdma-1b8.bin"
30
31 const struct vpdma_data_format vpdma_yuv_fmts[] = {
32         [VPDMA_DATA_FMT_Y444] = {
33                 .type           = VPDMA_DATA_FMT_TYPE_YUV,
34                 .data_type      = DATA_TYPE_Y444,
35                 .depth          = 8,
36         },
37         [VPDMA_DATA_FMT_Y422] = {
38                 .type           = VPDMA_DATA_FMT_TYPE_YUV,
39                 .data_type      = DATA_TYPE_Y422,
40                 .depth          = 8,
41         },
42         [VPDMA_DATA_FMT_Y420] = {
43                 .type           = VPDMA_DATA_FMT_TYPE_YUV,
44                 .data_type      = DATA_TYPE_Y420,
45                 .depth          = 8,
46         },
47         [VPDMA_DATA_FMT_C444] = {
48                 .type           = VPDMA_DATA_FMT_TYPE_YUV,
49                 .data_type      = DATA_TYPE_C444,
50                 .depth          = 8,
51         },
52         [VPDMA_DATA_FMT_C422] = {
53                 .type           = VPDMA_DATA_FMT_TYPE_YUV,
54                 .data_type      = DATA_TYPE_C422,
55                 .depth          = 8,
56         },
57         [VPDMA_DATA_FMT_C420] = {
58                 .type           = VPDMA_DATA_FMT_TYPE_YUV,
59                 .data_type      = DATA_TYPE_C420,
60                 .depth          = 4,
61         },
62         [VPDMA_DATA_FMT_YCR422] = {
63                 .type           = VPDMA_DATA_FMT_TYPE_YUV,
64                 .data_type      = DATA_TYPE_YCR422,
65                 .depth          = 16,
66         },
67         [VPDMA_DATA_FMT_YC444] = {
68                 .type           = VPDMA_DATA_FMT_TYPE_YUV,
69                 .data_type      = DATA_TYPE_YC444,
70                 .depth          = 24,
71         },
72         [VPDMA_DATA_FMT_CRY422] = {
73                 .type           = VPDMA_DATA_FMT_TYPE_YUV,
74                 .data_type      = DATA_TYPE_CRY422,
75                 .depth          = 16,
76         },
77         [VPDMA_DATA_FMT_CBY422] = {
78                 .type           = VPDMA_DATA_FMT_TYPE_YUV,
79                 .data_type      = DATA_TYPE_CBY422,
80                 .depth          = 16,
81         },
82         [VPDMA_DATA_FMT_YCB422] = {
83                 .type           = VPDMA_DATA_FMT_TYPE_YUV,
84                 .data_type      = DATA_TYPE_YCB422,
85                 .depth          = 16,
86         },
87 };
88 EXPORT_SYMBOL(vpdma_yuv_fmts);
89
90 const struct vpdma_data_format vpdma_rgb_fmts[] = {
91         [VPDMA_DATA_FMT_RGB565] = {
92                 .type           = VPDMA_DATA_FMT_TYPE_RGB,
93                 .data_type      = DATA_TYPE_RGB16_565,
94                 .depth          = 16,
95         },
96         [VPDMA_DATA_FMT_ARGB16_1555] = {
97                 .type           = VPDMA_DATA_FMT_TYPE_RGB,
98                 .data_type      = DATA_TYPE_ARGB_1555,
99                 .depth          = 16,
100         },
101         [VPDMA_DATA_FMT_ARGB16] = {
102                 .type           = VPDMA_DATA_FMT_TYPE_RGB,
103                 .data_type      = DATA_TYPE_ARGB_4444,
104                 .depth          = 16,
105         },
106         [VPDMA_DATA_FMT_RGBA16_5551] = {
107                 .type           = VPDMA_DATA_FMT_TYPE_RGB,
108                 .data_type      = DATA_TYPE_RGBA_5551,
109                 .depth          = 16,
110         },
111         [VPDMA_DATA_FMT_RGBA16] = {
112                 .type           = VPDMA_DATA_FMT_TYPE_RGB,
113                 .data_type      = DATA_TYPE_RGBA_4444,
114                 .depth          = 16,
115         },
116         [VPDMA_DATA_FMT_ARGB24] = {
117                 .type           = VPDMA_DATA_FMT_TYPE_RGB,
118                 .data_type      = DATA_TYPE_ARGB24_6666,
119                 .depth          = 24,
120         },
121         [VPDMA_DATA_FMT_RGB24] = {
122                 .type           = VPDMA_DATA_FMT_TYPE_RGB,
123                 .data_type      = DATA_TYPE_RGB24_888,
124                 .depth          = 24,
125         },
126         [VPDMA_DATA_FMT_ARGB32] = {
127                 .type           = VPDMA_DATA_FMT_TYPE_RGB,
128                 .data_type      = DATA_TYPE_ARGB32_8888,
129                 .depth          = 32,
130         },
131         [VPDMA_DATA_FMT_RGBA24] = {
132                 .type           = VPDMA_DATA_FMT_TYPE_RGB,
133                 .data_type      = DATA_TYPE_RGBA24_6666,
134                 .depth          = 24,
135         },
136         [VPDMA_DATA_FMT_RGBA32] = {
137                 .type           = VPDMA_DATA_FMT_TYPE_RGB,
138                 .data_type      = DATA_TYPE_RGBA32_8888,
139                 .depth          = 32,
140         },
141         [VPDMA_DATA_FMT_BGR565] = {
142                 .type           = VPDMA_DATA_FMT_TYPE_RGB,
143                 .data_type      = DATA_TYPE_BGR16_565,
144                 .depth          = 16,
145         },
146         [VPDMA_DATA_FMT_ABGR16_1555] = {
147                 .type           = VPDMA_DATA_FMT_TYPE_RGB,
148                 .data_type      = DATA_TYPE_ABGR_1555,
149                 .depth          = 16,
150         },
151         [VPDMA_DATA_FMT_ABGR16] = {
152                 .type           = VPDMA_DATA_FMT_TYPE_RGB,
153                 .data_type      = DATA_TYPE_ABGR_4444,
154                 .depth          = 16,
155         },
156         [VPDMA_DATA_FMT_BGRA16_5551] = {
157                 .type           = VPDMA_DATA_FMT_TYPE_RGB,
158                 .data_type      = DATA_TYPE_BGRA_5551,
159                 .depth          = 16,
160         },
161         [VPDMA_DATA_FMT_BGRA16] = {
162                 .type           = VPDMA_DATA_FMT_TYPE_RGB,
163                 .data_type      = DATA_TYPE_BGRA_4444,
164                 .depth          = 16,
165         },
166         [VPDMA_DATA_FMT_ABGR24] = {
167                 .type           = VPDMA_DATA_FMT_TYPE_RGB,
168                 .data_type      = DATA_TYPE_ABGR24_6666,
169                 .depth          = 24,
170         },
171         [VPDMA_DATA_FMT_BGR24] = {
172                 .type           = VPDMA_DATA_FMT_TYPE_RGB,
173                 .data_type      = DATA_TYPE_BGR24_888,
174                 .depth          = 24,
175         },
176         [VPDMA_DATA_FMT_ABGR32] = {
177                 .type           = VPDMA_DATA_FMT_TYPE_RGB,
178                 .data_type      = DATA_TYPE_ABGR32_8888,
179                 .depth          = 32,
180         },
181         [VPDMA_DATA_FMT_BGRA24] = {
182                 .type           = VPDMA_DATA_FMT_TYPE_RGB,
183                 .data_type      = DATA_TYPE_BGRA24_6666,
184                 .depth          = 24,
185         },
186         [VPDMA_DATA_FMT_BGRA32] = {
187                 .type           = VPDMA_DATA_FMT_TYPE_RGB,
188                 .data_type      = DATA_TYPE_BGRA32_8888,
189                 .depth          = 32,
190         },
191 };
192 EXPORT_SYMBOL(vpdma_rgb_fmts);
193
194 /*
195  * To handle RAW format we are re-using the CBY422
196  * vpdma data type so that we use the vpdma to re-order
197  * the incoming bytes, as the parser assumes that the
198  * first byte presented on the bus is the MSB of a 2
199  * bytes value.
200  * RAW8 handles from 1 to 8 bits
201  * RAW16 handles from 9 to 16 bits
202  */
203 const struct vpdma_data_format vpdma_raw_fmts[] = {
204         [VPDMA_DATA_FMT_RAW8] = {
205                 .type           = VPDMA_DATA_FMT_TYPE_YUV,
206                 .data_type      = DATA_TYPE_CBY422,
207                 .depth          = 8,
208         },
209         [VPDMA_DATA_FMT_RAW16] = {
210                 .type           = VPDMA_DATA_FMT_TYPE_YUV,
211                 .data_type      = DATA_TYPE_CBY422,
212                 .depth          = 16,
213         },
214 };
215 EXPORT_SYMBOL(vpdma_raw_fmts);
216
217 const struct vpdma_data_format vpdma_misc_fmts[] = {
218         [VPDMA_DATA_FMT_MV] = {
219                 .type           = VPDMA_DATA_FMT_TYPE_MISC,
220                 .data_type      = DATA_TYPE_MV,
221                 .depth          = 4,
222         },
223 };
224 EXPORT_SYMBOL(vpdma_misc_fmts);
225
226 struct vpdma_channel_info {
227         int num;                /* VPDMA channel number */
228         int cstat_offset;       /* client CSTAT register offset */
229 };
230
231 static const struct vpdma_channel_info chan_info[] = {
232         [VPE_CHAN_LUMA1_IN] = {
233                 .num            = VPE_CHAN_NUM_LUMA1_IN,
234                 .cstat_offset   = VPDMA_DEI_LUMA1_CSTAT,
235         },
236         [VPE_CHAN_CHROMA1_IN] = {
237                 .num            = VPE_CHAN_NUM_CHROMA1_IN,
238                 .cstat_offset   = VPDMA_DEI_CHROMA1_CSTAT,
239         },
240         [VPE_CHAN_LUMA2_IN] = {
241                 .num            = VPE_CHAN_NUM_LUMA2_IN,
242                 .cstat_offset   = VPDMA_DEI_LUMA2_CSTAT,
243         },
244         [VPE_CHAN_CHROMA2_IN] = {
245                 .num            = VPE_CHAN_NUM_CHROMA2_IN,
246                 .cstat_offset   = VPDMA_DEI_CHROMA2_CSTAT,
247         },
248         [VPE_CHAN_LUMA3_IN] = {
249                 .num            = VPE_CHAN_NUM_LUMA3_IN,
250                 .cstat_offset   = VPDMA_DEI_LUMA3_CSTAT,
251         },
252         [VPE_CHAN_CHROMA3_IN] = {
253                 .num            = VPE_CHAN_NUM_CHROMA3_IN,
254                 .cstat_offset   = VPDMA_DEI_CHROMA3_CSTAT,
255         },
256         [VPE_CHAN_MV_IN] = {
257                 .num            = VPE_CHAN_NUM_MV_IN,
258                 .cstat_offset   = VPDMA_DEI_MV_IN_CSTAT,
259         },
260         [VPE_CHAN_MV_OUT] = {
261                 .num            = VPE_CHAN_NUM_MV_OUT,
262                 .cstat_offset   = VPDMA_DEI_MV_OUT_CSTAT,
263         },
264         [VPE_CHAN_LUMA_OUT] = {
265                 .num            = VPE_CHAN_NUM_LUMA_OUT,
266                 .cstat_offset   = VPDMA_VIP_UP_Y_CSTAT,
267         },
268         [VPE_CHAN_CHROMA_OUT] = {
269                 .num            = VPE_CHAN_NUM_CHROMA_OUT,
270                 .cstat_offset   = VPDMA_VIP_UP_UV_CSTAT,
271         },
272         [VPE_CHAN_RGB_OUT] = {
273                 .num            = VPE_CHAN_NUM_RGB_OUT,
274                 .cstat_offset   = VPDMA_VIP_UP_Y_CSTAT,
275         },
276 };
277
278 static u32 read_reg(struct vpdma_data *vpdma, int offset)
279 {
280         return ioread32(vpdma->base + offset);
281 }
282
283 static void write_reg(struct vpdma_data *vpdma, int offset, u32 value)
284 {
285         iowrite32(value, vpdma->base + offset);
286 }
287
288 static int read_field_reg(struct vpdma_data *vpdma, int offset,
289                 u32 mask, int shift)
290 {
291         return (read_reg(vpdma, offset) & (mask << shift)) >> shift;
292 }
293
294 static void write_field_reg(struct vpdma_data *vpdma, int offset, u32 field,
295                 u32 mask, int shift)
296 {
297         u32 val = read_reg(vpdma, offset);
298
299         val &= ~(mask << shift);
300         val |= (field & mask) << shift;
301
302         write_reg(vpdma, offset, val);
303 }
304
305 void vpdma_dump_regs(struct vpdma_data *vpdma)
306 {
307         struct device *dev = &vpdma->pdev->dev;
308
309 #define DUMPREG(r) dev_dbg(dev, "%-35s %08x\n", #r, read_reg(vpdma, VPDMA_##r))
310
311         dev_dbg(dev, "VPDMA Registers:\n");
312
313         DUMPREG(PID);
314         DUMPREG(LIST_ADDR);
315         DUMPREG(LIST_ATTR);
316         DUMPREG(LIST_STAT_SYNC);
317         DUMPREG(BG_RGB);
318         DUMPREG(BG_YUV);
319         DUMPREG(SETUP);
320         DUMPREG(MAX_SIZE1);
321         DUMPREG(MAX_SIZE2);
322         DUMPREG(MAX_SIZE3);
323
324         /*
325          * dumping registers of only group0 and group3, because VPE channels
326          * lie within group0 and group3 registers
327          */
328         DUMPREG(INT_CHAN_STAT(0));
329         DUMPREG(INT_CHAN_MASK(0));
330         DUMPREG(INT_CHAN_STAT(3));
331         DUMPREG(INT_CHAN_MASK(3));
332         DUMPREG(INT_CLIENT0_STAT);
333         DUMPREG(INT_CLIENT0_MASK);
334         DUMPREG(INT_CLIENT1_STAT);
335         DUMPREG(INT_CLIENT1_MASK);
336         DUMPREG(INT_LIST0_STAT);
337         DUMPREG(INT_LIST0_MASK);
338
339         /*
340          * these are registers specific to VPE clients, we can make this
341          * function dump client registers specific to VPE or VIP based on
342          * who is using it
343          */
344         DUMPREG(DEI_CHROMA1_CSTAT);
345         DUMPREG(DEI_LUMA1_CSTAT);
346         DUMPREG(DEI_CHROMA2_CSTAT);
347         DUMPREG(DEI_LUMA2_CSTAT);
348         DUMPREG(DEI_CHROMA3_CSTAT);
349         DUMPREG(DEI_LUMA3_CSTAT);
350         DUMPREG(DEI_MV_IN_CSTAT);
351         DUMPREG(DEI_MV_OUT_CSTAT);
352         DUMPREG(VIP_UP_Y_CSTAT);
353         DUMPREG(VIP_UP_UV_CSTAT);
354         DUMPREG(VPI_CTL_CSTAT);
355 }
356 EXPORT_SYMBOL(vpdma_dump_regs);
357
358 /*
359  * Allocate a DMA buffer
360  */
361 int vpdma_alloc_desc_buf(struct vpdma_buf *buf, size_t size)
362 {
363         buf->size = size;
364         buf->mapped = false;
365         buf->addr = kzalloc(size, GFP_KERNEL);
366         if (!buf->addr)
367                 return -ENOMEM;
368
369         WARN_ON(((unsigned long)buf->addr & VPDMA_DESC_ALIGN) != 0);
370
371         return 0;
372 }
373 EXPORT_SYMBOL(vpdma_alloc_desc_buf);
374
375 void vpdma_free_desc_buf(struct vpdma_buf *buf)
376 {
377         WARN_ON(buf->mapped);
378         kfree(buf->addr);
379         buf->addr = NULL;
380         buf->size = 0;
381 }
382 EXPORT_SYMBOL(vpdma_free_desc_buf);
383
384 /*
385  * map descriptor/payload DMA buffer, enabling DMA access
386  */
387 int vpdma_map_desc_buf(struct vpdma_data *vpdma, struct vpdma_buf *buf)
388 {
389         struct device *dev = &vpdma->pdev->dev;
390
391         WARN_ON(buf->mapped);
392         buf->dma_addr = dma_map_single(dev, buf->addr, buf->size,
393                                 DMA_BIDIRECTIONAL);
394         if (dma_mapping_error(dev, buf->dma_addr)) {
395                 dev_err(dev, "failed to map buffer\n");
396                 return -EINVAL;
397         }
398
399         buf->mapped = true;
400
401         return 0;
402 }
403 EXPORT_SYMBOL(vpdma_map_desc_buf);
404
405 /*
406  * unmap descriptor/payload DMA buffer, disabling DMA access and
407  * allowing the main processor to access the data
408  */
409 void vpdma_unmap_desc_buf(struct vpdma_data *vpdma, struct vpdma_buf *buf)
410 {
411         struct device *dev = &vpdma->pdev->dev;
412
413         if (buf->mapped)
414                 dma_unmap_single(dev, buf->dma_addr, buf->size,
415                                 DMA_BIDIRECTIONAL);
416
417         buf->mapped = false;
418 }
419 EXPORT_SYMBOL(vpdma_unmap_desc_buf);
420
421 /*
422  * Cleanup all pending descriptors of a list
423  * First, stop the current list being processed.
424  * If the VPDMA was busy, this step makes vpdma to accept post lists.
425  * To cleanup the internal FSM, post abort list descriptor for all the
426  * channels from @channels array of size @size.
427  */
428 int vpdma_list_cleanup(struct vpdma_data *vpdma, int list_num,
429                 int *channels, int size)
430 {
431         struct vpdma_desc_list abort_list;
432         int i, ret, timeout = 500;
433
434         write_reg(vpdma, VPDMA_LIST_ATTR,
435                         (list_num << VPDMA_LIST_NUM_SHFT) |
436                         (1 << VPDMA_LIST_STOP_SHFT));
437
438         if (size <= 0 || !channels)
439                 return 0;
440
441         ret = vpdma_create_desc_list(&abort_list,
442                 size * sizeof(struct vpdma_dtd), VPDMA_LIST_TYPE_NORMAL);
443         if (ret)
444                 return ret;
445
446         for (i = 0; i < size; i++)
447                 vpdma_add_abort_channel_ctd(&abort_list, channels[i]);
448
449         ret = vpdma_map_desc_buf(vpdma, &abort_list.buf);
450         if (ret)
451                 return ret;
452         ret = vpdma_submit_descs(vpdma, &abort_list, list_num);
453         if (ret)
454                 return ret;
455
456         while (vpdma_list_busy(vpdma, list_num) && --timeout)
457                 ;
458
459         if (timeout == 0) {
460                 dev_err(&vpdma->pdev->dev, "Timed out cleaning up VPDMA list\n");
461                 return -EBUSY;
462         }
463
464         vpdma_unmap_desc_buf(vpdma, &abort_list.buf);
465         vpdma_free_desc_buf(&abort_list.buf);
466
467         return 0;
468 }
469 EXPORT_SYMBOL(vpdma_list_cleanup);
470
471 /*
472  * create a descriptor list, the user of this list will append configuration,
473  * control and data descriptors to this list, this list will be submitted to
474  * VPDMA. VPDMA's list parser will go through each descriptor and perform the
475  * required DMA operations
476  */
477 int vpdma_create_desc_list(struct vpdma_desc_list *list, size_t size, int type)
478 {
479         int r;
480
481         r = vpdma_alloc_desc_buf(&list->buf, size);
482         if (r)
483                 return r;
484
485         list->next = list->buf.addr;
486
487         list->type = type;
488
489         return 0;
490 }
491 EXPORT_SYMBOL(vpdma_create_desc_list);
492
493 /*
494  * once a descriptor list is parsed by VPDMA, we reset the list by emptying it,
495  * to allow new descriptors to be added to the list.
496  */
497 void vpdma_reset_desc_list(struct vpdma_desc_list *list)
498 {
499         list->next = list->buf.addr;
500 }
501 EXPORT_SYMBOL(vpdma_reset_desc_list);
502
503 /*
504  * free the buffer allocated for the VPDMA descriptor list, this should be
505  * called when the user doesn't want to use VPDMA any more.
506  */
507 void vpdma_free_desc_list(struct vpdma_desc_list *list)
508 {
509         vpdma_free_desc_buf(&list->buf);
510
511         list->next = NULL;
512 }
513 EXPORT_SYMBOL(vpdma_free_desc_list);
514
515 bool vpdma_list_busy(struct vpdma_data *vpdma, int list_num)
516 {
517         return read_reg(vpdma, VPDMA_LIST_STAT_SYNC) & BIT(list_num + 16);
518 }
519 EXPORT_SYMBOL(vpdma_list_busy);
520
521 /*
522  * submit a list of DMA descriptors to the VPE VPDMA, do not wait for completion
523  */
524 int vpdma_submit_descs(struct vpdma_data *vpdma,
525                         struct vpdma_desc_list *list, int list_num)
526 {
527         int list_size;
528         unsigned long flags;
529
530         if (vpdma_list_busy(vpdma, list_num))
531                 return -EBUSY;
532
533         /* 16-byte granularity */
534         list_size = (list->next - list->buf.addr) >> 4;
535
536         spin_lock_irqsave(&vpdma->lock, flags);
537         write_reg(vpdma, VPDMA_LIST_ADDR, (u32) list->buf.dma_addr);
538
539         write_reg(vpdma, VPDMA_LIST_ATTR,
540                         (list_num << VPDMA_LIST_NUM_SHFT) |
541                         (list->type << VPDMA_LIST_TYPE_SHFT) |
542                         list_size);
543         spin_unlock_irqrestore(&vpdma->lock, flags);
544
545         return 0;
546 }
547 EXPORT_SYMBOL(vpdma_submit_descs);
548
549 static void dump_dtd(struct vpdma_dtd *dtd);
550
551 void vpdma_update_dma_addr(struct vpdma_data *vpdma,
552         struct vpdma_desc_list *list, dma_addr_t dma_addr,
553         void *write_dtd, int drop, int idx)
554 {
555         struct vpdma_dtd *dtd = list->buf.addr;
556         dma_addr_t write_desc_addr;
557         int offset;
558
559         dtd += idx;
560         vpdma_unmap_desc_buf(vpdma, &list->buf);
561
562         dtd->start_addr = dma_addr;
563
564         /* Calculate write address from the offset of write_dtd from start
565          * of the list->buf
566          */
567         offset = (void *)write_dtd - list->buf.addr;
568         write_desc_addr = list->buf.dma_addr + offset;
569
570         if (drop)
571                 dtd->desc_write_addr = dtd_desc_write_addr(write_desc_addr,
572                                                            1, 1, 0);
573         else
574                 dtd->desc_write_addr = dtd_desc_write_addr(write_desc_addr,
575                                                            1, 0, 0);
576
577         vpdma_map_desc_buf(vpdma, &list->buf);
578
579         dump_dtd(dtd);
580 }
581 EXPORT_SYMBOL(vpdma_update_dma_addr);
582
583 void vpdma_set_max_size(struct vpdma_data *vpdma, int reg_addr,
584                         u32 width, u32 height)
585 {
586         if (reg_addr != VPDMA_MAX_SIZE1 && reg_addr != VPDMA_MAX_SIZE2 &&
587             reg_addr != VPDMA_MAX_SIZE3)
588                 reg_addr = VPDMA_MAX_SIZE1;
589
590         write_field_reg(vpdma, reg_addr, width - 1,
591                         VPDMA_MAX_SIZE_WIDTH_MASK, VPDMA_MAX_SIZE_WIDTH_SHFT);
592
593         write_field_reg(vpdma, reg_addr, height - 1,
594                         VPDMA_MAX_SIZE_HEIGHT_MASK, VPDMA_MAX_SIZE_HEIGHT_SHFT);
595
596 }
597 EXPORT_SYMBOL(vpdma_set_max_size);
598
599 static void dump_cfd(struct vpdma_cfd *cfd)
600 {
601         int class;
602
603         class = cfd_get_class(cfd);
604
605         pr_debug("config descriptor of payload class: %s\n",
606                 class == CFD_CLS_BLOCK ? "simple block" :
607                 "address data block");
608
609         if (class == CFD_CLS_BLOCK)
610                 pr_debug("word0: dst_addr_offset = 0x%08x\n",
611                         cfd->dest_addr_offset);
612
613         if (class == CFD_CLS_BLOCK)
614                 pr_debug("word1: num_data_wrds = %d\n", cfd->block_len);
615
616         pr_debug("word2: payload_addr = 0x%08x\n", cfd->payload_addr);
617
618         pr_debug("word3: pkt_type = %d, direct = %d, class = %d, dest = %d, payload_len = %d\n",
619                  cfd_get_pkt_type(cfd),
620                  cfd_get_direct(cfd), class, cfd_get_dest(cfd),
621                  cfd_get_payload_len(cfd));
622 }
623
624 /*
625  * append a configuration descriptor to the given descriptor list, where the
626  * payload is in the form of a simple data block specified in the descriptor
627  * header, this is used to upload scaler coefficients to the scaler module
628  */
629 void vpdma_add_cfd_block(struct vpdma_desc_list *list, int client,
630                 struct vpdma_buf *blk, u32 dest_offset)
631 {
632         struct vpdma_cfd *cfd;
633         int len = blk->size;
634
635         WARN_ON(blk->dma_addr & VPDMA_DESC_ALIGN);
636
637         cfd = list->next;
638         WARN_ON((void *)(cfd + 1) > (list->buf.addr + list->buf.size));
639
640         cfd->dest_addr_offset = dest_offset;
641         cfd->block_len = len;
642         cfd->payload_addr = (u32) blk->dma_addr;
643         cfd->ctl_payload_len = cfd_pkt_payload_len(CFD_INDIRECT, CFD_CLS_BLOCK,
644                                 client, len >> 4);
645
646         list->next = cfd + 1;
647
648         dump_cfd(cfd);
649 }
650 EXPORT_SYMBOL(vpdma_add_cfd_block);
651
652 /*
653  * append a configuration descriptor to the given descriptor list, where the
654  * payload is in the address data block format, this is used to a configure a
655  * discontiguous set of MMRs
656  */
657 void vpdma_add_cfd_adb(struct vpdma_desc_list *list, int client,
658                 struct vpdma_buf *adb)
659 {
660         struct vpdma_cfd *cfd;
661         unsigned int len = adb->size;
662
663         WARN_ON(len & VPDMA_ADB_SIZE_ALIGN);
664         WARN_ON(adb->dma_addr & VPDMA_DESC_ALIGN);
665
666         cfd = list->next;
667         BUG_ON((void *)(cfd + 1) > (list->buf.addr + list->buf.size));
668
669         cfd->w0 = 0;
670         cfd->w1 = 0;
671         cfd->payload_addr = (u32) adb->dma_addr;
672         cfd->ctl_payload_len = cfd_pkt_payload_len(CFD_INDIRECT, CFD_CLS_ADB,
673                                 client, len >> 4);
674
675         list->next = cfd + 1;
676
677         dump_cfd(cfd);
678 };
679 EXPORT_SYMBOL(vpdma_add_cfd_adb);
680
681 /*
682  * control descriptor format change based on what type of control descriptor it
683  * is, we only use 'sync on channel' control descriptors for now, so assume it's
684  * that
685  */
686 static void dump_ctd(struct vpdma_ctd *ctd)
687 {
688         pr_debug("control descriptor\n");
689
690         pr_debug("word3: pkt_type = %d, source = %d, ctl_type = %d\n",
691                 ctd_get_pkt_type(ctd), ctd_get_source(ctd), ctd_get_ctl(ctd));
692 }
693
694 /*
695  * append a 'sync on channel' type control descriptor to the given descriptor
696  * list, this descriptor stalls the VPDMA list till the time DMA is completed
697  * on the specified channel
698  */
699 void vpdma_add_sync_on_channel_ctd(struct vpdma_desc_list *list,
700                 enum vpdma_channel chan)
701 {
702         struct vpdma_ctd *ctd;
703
704         ctd = list->next;
705         WARN_ON((void *)(ctd + 1) > (list->buf.addr + list->buf.size));
706
707         ctd->w0 = 0;
708         ctd->w1 = 0;
709         ctd->w2 = 0;
710         ctd->type_source_ctl = ctd_type_source_ctl(chan_info[chan].num,
711                                 CTD_TYPE_SYNC_ON_CHANNEL);
712
713         list->next = ctd + 1;
714
715         dump_ctd(ctd);
716 }
717 EXPORT_SYMBOL(vpdma_add_sync_on_channel_ctd);
718
719 /*
720  * append an 'abort_channel' type control descriptor to the given descriptor
721  * list, this descriptor aborts any DMA transaction happening using the
722  * specified channel
723  */
724 void vpdma_add_abort_channel_ctd(struct vpdma_desc_list *list,
725                 int chan_num)
726 {
727         struct vpdma_ctd *ctd;
728
729         ctd = list->next;
730         WARN_ON((void *)(ctd + 1) > (list->buf.addr + list->buf.size));
731
732         ctd->w0 = 0;
733         ctd->w1 = 0;
734         ctd->w2 = 0;
735         ctd->type_source_ctl = ctd_type_source_ctl(chan_num,
736                                 CTD_TYPE_ABORT_CHANNEL);
737
738         list->next = ctd + 1;
739
740         dump_ctd(ctd);
741 }
742 EXPORT_SYMBOL(vpdma_add_abort_channel_ctd);
743
744 static void dump_dtd(struct vpdma_dtd *dtd)
745 {
746         int dir, chan;
747
748         dir = dtd_get_dir(dtd);
749         chan = dtd_get_chan(dtd);
750
751         pr_debug("%s data transfer descriptor for channel %d\n",
752                 dir == DTD_DIR_OUT ? "outbound" : "inbound", chan);
753
754         pr_debug("word0: data_type = %d, notify = %d, field = %d, 1D = %d, even_ln_skp = %d, odd_ln_skp = %d, line_stride = %d\n",
755                 dtd_get_data_type(dtd), dtd_get_notify(dtd), dtd_get_field(dtd),
756                 dtd_get_1d(dtd), dtd_get_even_line_skip(dtd),
757                 dtd_get_odd_line_skip(dtd), dtd_get_line_stride(dtd));
758
759         if (dir == DTD_DIR_IN)
760                 pr_debug("word1: line_length = %d, xfer_height = %d\n",
761                         dtd_get_line_length(dtd), dtd_get_xfer_height(dtd));
762
763         pr_debug("word2: start_addr = %pad\n", &dtd->start_addr);
764
765         pr_debug("word3: pkt_type = %d, mode = %d, dir = %d, chan = %d, pri = %d, next_chan = %d\n",
766                  dtd_get_pkt_type(dtd),
767                  dtd_get_mode(dtd), dir, chan, dtd_get_priority(dtd),
768                  dtd_get_next_chan(dtd));
769
770         if (dir == DTD_DIR_IN)
771                 pr_debug("word4: frame_width = %d, frame_height = %d\n",
772                         dtd_get_frame_width(dtd), dtd_get_frame_height(dtd));
773         else
774                 pr_debug("word4: desc_write_addr = 0x%08x, write_desc = %d, drp_data = %d, use_desc_reg = %d\n",
775                         dtd_get_desc_write_addr(dtd), dtd_get_write_desc(dtd),
776                         dtd_get_drop_data(dtd), dtd_get_use_desc(dtd));
777
778         if (dir == DTD_DIR_IN)
779                 pr_debug("word5: hor_start = %d, ver_start = %d\n",
780                         dtd_get_h_start(dtd), dtd_get_v_start(dtd));
781         else
782                 pr_debug("word5: max_width %d, max_height %d\n",
783                         dtd_get_max_width(dtd), dtd_get_max_height(dtd));
784
785         pr_debug("word6: client specific attr0 = 0x%08x\n", dtd->client_attr0);
786         pr_debug("word7: client specific attr1 = 0x%08x\n", dtd->client_attr1);
787 }
788
789 /*
790  * append an outbound data transfer descriptor to the given descriptor list,
791  * this sets up a 'client to memory' VPDMA transfer for the given VPDMA channel
792  *
793  * @list: vpdma desc list to which we add this descriptor
794  * @width: width of the image in pixels in memory
795  * @c_rect: compose params of output image
796  * @fmt: vpdma data format of the buffer
797  * dma_addr: dma address as seen by VPDMA
798  * max_width: enum for maximum width of data transfer
799  * max_height: enum for maximum height of data transfer
800  * chan: VPDMA channel
801  * flags: VPDMA flags to configure some descriptor fields
802  */
803 void vpdma_add_out_dtd(struct vpdma_desc_list *list, int width,
804                 int stride, const struct v4l2_rect *c_rect,
805                 const struct vpdma_data_format *fmt, dma_addr_t dma_addr,
806                 int max_w, int max_h, enum vpdma_channel chan, u32 flags)
807 {
808         vpdma_rawchan_add_out_dtd(list, width, stride, c_rect, fmt, dma_addr,
809                                   max_w, max_h, chan_info[chan].num, flags);
810 }
811 EXPORT_SYMBOL(vpdma_add_out_dtd);
812
813 void vpdma_rawchan_add_out_dtd(struct vpdma_desc_list *list, int width,
814                 int stride, const struct v4l2_rect *c_rect,
815                 const struct vpdma_data_format *fmt, dma_addr_t dma_addr,
816                 int max_w, int max_h, int raw_vpdma_chan, u32 flags)
817 {
818         int priority = 0;
819         int field = 0;
820         int notify = 1;
821         int channel, next_chan;
822         struct v4l2_rect rect = *c_rect;
823         int depth = fmt->depth;
824         struct vpdma_dtd *dtd;
825
826         channel = next_chan = raw_vpdma_chan;
827
828         if (fmt->type == VPDMA_DATA_FMT_TYPE_YUV &&
829                         fmt->data_type == DATA_TYPE_C420) {
830                 rect.height >>= 1;
831                 rect.top >>= 1;
832                 depth = 8;
833         }
834
835         dma_addr += rect.top * stride + (rect.left * depth >> 3);
836
837         dtd = list->next;
838         WARN_ON((void *)(dtd + 1) > (list->buf.addr + list->buf.size));
839
840         dtd->type_ctl_stride = dtd_type_ctl_stride(fmt->data_type,
841                                         notify,
842                                         field,
843                                         !!(flags & VPDMA_DATA_FRAME_1D),
844                                         !!(flags & VPDMA_DATA_EVEN_LINE_SKIP),
845                                         !!(flags & VPDMA_DATA_ODD_LINE_SKIP),
846                                         stride);
847         dtd->w1 = 0;
848         dtd->start_addr = (u32) dma_addr;
849         dtd->pkt_ctl = dtd_pkt_ctl(!!(flags & VPDMA_DATA_MODE_TILED),
850                                 DTD_DIR_OUT, channel, priority, next_chan);
851         dtd->desc_write_addr = dtd_desc_write_addr(0, 0, 0, 0);
852         dtd->max_width_height = dtd_max_width_height(max_w, max_h);
853         dtd->client_attr0 = 0;
854         dtd->client_attr1 = 0;
855
856         list->next = dtd + 1;
857
858         dump_dtd(dtd);
859 }
860 EXPORT_SYMBOL(vpdma_rawchan_add_out_dtd);
861
862 /*
863  * append an inbound data transfer descriptor to the given descriptor list,
864  * this sets up a 'memory to client' VPDMA transfer for the given VPDMA channel
865  *
866  * @list: vpdma desc list to which we add this descriptor
867  * @width: width of the image in pixels in memory(not the cropped width)
868  * @c_rect: crop params of input image
869  * @fmt: vpdma data format of the buffer
870  * dma_addr: dma address as seen by VPDMA
871  * chan: VPDMA channel
872  * field: top or bottom field info of the input image
873  * flags: VPDMA flags to configure some descriptor fields
874  * frame_width/height: the complete width/height of the image presented to the
875  *                      client (this makes sense when multiple channels are
876  *                      connected to the same client, forming a larger frame)
877  * start_h, start_v: position where the given channel starts providing pixel
878  *                      data to the client (makes sense when multiple channels
879  *                      contribute to the client)
880  */
881 void vpdma_add_in_dtd(struct vpdma_desc_list *list, int width,
882                 int stride, const struct v4l2_rect *c_rect,
883                 const struct vpdma_data_format *fmt, dma_addr_t dma_addr,
884                 enum vpdma_channel chan, int field, u32 flags, int frame_width,
885                 int frame_height, int start_h, int start_v)
886 {
887         int priority = 0;
888         int notify = 1;
889         int depth = fmt->depth;
890         int channel, next_chan;
891         struct v4l2_rect rect = *c_rect;
892         struct vpdma_dtd *dtd;
893
894         channel = next_chan = chan_info[chan].num;
895
896         if (fmt->type == VPDMA_DATA_FMT_TYPE_YUV &&
897                         fmt->data_type == DATA_TYPE_C420) {
898                 rect.height >>= 1;
899                 rect.top >>= 1;
900                 depth = 8;
901         }
902
903         dma_addr += rect.top * stride + (rect.left * depth >> 3);
904
905         dtd = list->next;
906         WARN_ON((void *)(dtd + 1) > (list->buf.addr + list->buf.size));
907
908         dtd->type_ctl_stride = dtd_type_ctl_stride(fmt->data_type,
909                                         notify,
910                                         field,
911                                         !!(flags & VPDMA_DATA_FRAME_1D),
912                                         !!(flags & VPDMA_DATA_EVEN_LINE_SKIP),
913                                         !!(flags & VPDMA_DATA_ODD_LINE_SKIP),
914                                         stride);
915
916         dtd->xfer_length_height = dtd_xfer_length_height(rect.width,
917                                         rect.height);
918         dtd->start_addr = (u32) dma_addr;
919         dtd->pkt_ctl = dtd_pkt_ctl(!!(flags & VPDMA_DATA_MODE_TILED),
920                                 DTD_DIR_IN, channel, priority, next_chan);
921         dtd->frame_width_height = dtd_frame_width_height(frame_width,
922                                         frame_height);
923         dtd->start_h_v = dtd_start_h_v(start_h, start_v);
924         dtd->client_attr0 = 0;
925         dtd->client_attr1 = 0;
926
927         list->next = dtd + 1;
928
929         dump_dtd(dtd);
930 }
931 EXPORT_SYMBOL(vpdma_add_in_dtd);
932
933 int vpdma_hwlist_alloc(struct vpdma_data *vpdma, void *priv)
934 {
935         int i, list_num = -1;
936         unsigned long flags;
937
938         spin_lock_irqsave(&vpdma->lock, flags);
939         for (i = 0; i < VPDMA_MAX_NUM_LIST &&
940             vpdma->hwlist_used[i] == true; i++)
941                 ;
942
943         if (i < VPDMA_MAX_NUM_LIST) {
944                 list_num = i;
945                 vpdma->hwlist_used[i] = true;
946                 vpdma->hwlist_priv[i] = priv;
947         }
948         spin_unlock_irqrestore(&vpdma->lock, flags);
949
950         return list_num;
951 }
952 EXPORT_SYMBOL(vpdma_hwlist_alloc);
953
954 void *vpdma_hwlist_get_priv(struct vpdma_data *vpdma, int list_num)
955 {
956         if (!vpdma || list_num >= VPDMA_MAX_NUM_LIST)
957                 return NULL;
958
959         return vpdma->hwlist_priv[list_num];
960 }
961 EXPORT_SYMBOL(vpdma_hwlist_get_priv);
962
963 void *vpdma_hwlist_release(struct vpdma_data *vpdma, int list_num)
964 {
965         void *priv;
966         unsigned long flags;
967
968         spin_lock_irqsave(&vpdma->lock, flags);
969         vpdma->hwlist_used[list_num] = false;
970         priv = vpdma->hwlist_priv;
971         spin_unlock_irqrestore(&vpdma->lock, flags);
972
973         return priv;
974 }
975 EXPORT_SYMBOL(vpdma_hwlist_release);
976
977 /* set or clear the mask for list complete interrupt */
978 void vpdma_enable_list_complete_irq(struct vpdma_data *vpdma, int irq_num,
979                 int list_num, bool enable)
980 {
981         u32 reg_addr = VPDMA_INT_LIST0_MASK + VPDMA_INTX_OFFSET * irq_num;
982         u32 val;
983
984         val = read_reg(vpdma, reg_addr);
985         if (enable)
986                 val |= (1 << (list_num * 2));
987         else
988                 val &= ~(1 << (list_num * 2));
989         write_reg(vpdma, reg_addr, val);
990 }
991 EXPORT_SYMBOL(vpdma_enable_list_complete_irq);
992
993 /* get the LIST_STAT register */
994 unsigned int vpdma_get_list_stat(struct vpdma_data *vpdma, int irq_num)
995 {
996         u32 reg_addr = VPDMA_INT_LIST0_STAT + VPDMA_INTX_OFFSET * irq_num;
997
998         return read_reg(vpdma, reg_addr);
999 }
1000 EXPORT_SYMBOL(vpdma_get_list_stat);
1001
1002 /* get the LIST_MASK register */
1003 unsigned int vpdma_get_list_mask(struct vpdma_data *vpdma, int irq_num)
1004 {
1005         u32 reg_addr = VPDMA_INT_LIST0_MASK + VPDMA_INTX_OFFSET * irq_num;
1006
1007         return read_reg(vpdma, reg_addr);
1008 }
1009 EXPORT_SYMBOL(vpdma_get_list_mask);
1010
1011 /* clear previously occurred list interrupts in the LIST_STAT register */
1012 void vpdma_clear_list_stat(struct vpdma_data *vpdma, int irq_num,
1013                            int list_num)
1014 {
1015         u32 reg_addr = VPDMA_INT_LIST0_STAT + VPDMA_INTX_OFFSET * irq_num;
1016
1017         write_reg(vpdma, reg_addr, 3 << (list_num * 2));
1018 }
1019 EXPORT_SYMBOL(vpdma_clear_list_stat);
1020
1021 void vpdma_set_bg_color(struct vpdma_data *vpdma,
1022                 struct vpdma_data_format *fmt, u32 color)
1023 {
1024         if (fmt->type == VPDMA_DATA_FMT_TYPE_RGB)
1025                 write_reg(vpdma, VPDMA_BG_RGB, color);
1026         else if (fmt->type == VPDMA_DATA_FMT_TYPE_YUV)
1027                 write_reg(vpdma, VPDMA_BG_YUV, color);
1028 }
1029 EXPORT_SYMBOL(vpdma_set_bg_color);
1030
1031 /*
1032  * configures the output mode of the line buffer for the given client, the
1033  * line buffer content can either be mirrored(each line repeated twice) or
1034  * passed to the client as is
1035  */
1036 void vpdma_set_line_mode(struct vpdma_data *vpdma, int line_mode,
1037                 enum vpdma_channel chan)
1038 {
1039         int client_cstat = chan_info[chan].cstat_offset;
1040
1041         write_field_reg(vpdma, client_cstat, line_mode,
1042                 VPDMA_CSTAT_LINE_MODE_MASK, VPDMA_CSTAT_LINE_MODE_SHIFT);
1043 }
1044 EXPORT_SYMBOL(vpdma_set_line_mode);
1045
1046 /*
1047  * configures the event which should trigger VPDMA transfer for the given
1048  * client
1049  */
1050 void vpdma_set_frame_start_event(struct vpdma_data *vpdma,
1051                 enum vpdma_frame_start_event fs_event,
1052                 enum vpdma_channel chan)
1053 {
1054         int client_cstat = chan_info[chan].cstat_offset;
1055
1056         write_field_reg(vpdma, client_cstat, fs_event,
1057                 VPDMA_CSTAT_FRAME_START_MASK, VPDMA_CSTAT_FRAME_START_SHIFT);
1058 }
1059 EXPORT_SYMBOL(vpdma_set_frame_start_event);
1060
1061 static void vpdma_firmware_cb(const struct firmware *f, void *context)
1062 {
1063         struct vpdma_data *vpdma = context;
1064         struct vpdma_buf fw_dma_buf;
1065         int i, r;
1066
1067         dev_dbg(&vpdma->pdev->dev, "firmware callback\n");
1068
1069         if (!f || !f->data) {
1070                 dev_err(&vpdma->pdev->dev, "couldn't get firmware\n");
1071                 return;
1072         }
1073
1074         /* already initialized */
1075         if (read_field_reg(vpdma, VPDMA_LIST_ATTR, VPDMA_LIST_RDY_MASK,
1076                         VPDMA_LIST_RDY_SHFT)) {
1077                 vpdma->cb(vpdma->pdev);
1078                 return;
1079         }
1080
1081         r = vpdma_alloc_desc_buf(&fw_dma_buf, f->size);
1082         if (r) {
1083                 dev_err(&vpdma->pdev->dev,
1084                         "failed to allocate dma buffer for firmware\n");
1085                 goto rel_fw;
1086         }
1087
1088         memcpy(fw_dma_buf.addr, f->data, f->size);
1089
1090         vpdma_map_desc_buf(vpdma, &fw_dma_buf);
1091
1092         write_reg(vpdma, VPDMA_LIST_ADDR, (u32) fw_dma_buf.dma_addr);
1093
1094         for (i = 0; i < 100; i++) {             /* max 1 second */
1095                 msleep_interruptible(10);
1096
1097                 if (read_field_reg(vpdma, VPDMA_LIST_ATTR, VPDMA_LIST_RDY_MASK,
1098                                 VPDMA_LIST_RDY_SHFT))
1099                         break;
1100         }
1101
1102         if (i == 100) {
1103                 dev_err(&vpdma->pdev->dev, "firmware upload failed\n");
1104                 goto free_buf;
1105         }
1106
1107         vpdma->cb(vpdma->pdev);
1108
1109 free_buf:
1110         vpdma_unmap_desc_buf(vpdma, &fw_dma_buf);
1111
1112         vpdma_free_desc_buf(&fw_dma_buf);
1113 rel_fw:
1114         release_firmware(f);
1115 }
1116
1117 static int vpdma_load_firmware(struct vpdma_data *vpdma)
1118 {
1119         int r;
1120         struct device *dev = &vpdma->pdev->dev;
1121
1122         r = request_firmware_nowait(THIS_MODULE, 1,
1123                 (const char *) VPDMA_FIRMWARE, dev, GFP_KERNEL, vpdma,
1124                 vpdma_firmware_cb);
1125         if (r) {
1126                 dev_err(dev, "firmware not available %s\n", VPDMA_FIRMWARE);
1127                 return r;
1128         } else {
1129                 dev_info(dev, "loading firmware %s\n", VPDMA_FIRMWARE);
1130         }
1131
1132         return 0;
1133 }
1134
1135 int vpdma_create(struct platform_device *pdev, struct vpdma_data *vpdma,
1136                 void (*cb)(struct platform_device *pdev))
1137 {
1138         struct resource *res;
1139         int r;
1140
1141         dev_dbg(&pdev->dev, "vpdma_create\n");
1142
1143         vpdma->pdev = pdev;
1144         vpdma->cb = cb;
1145         spin_lock_init(&vpdma->lock);
1146
1147         res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vpdma");
1148         if (res == NULL) {
1149                 dev_err(&pdev->dev, "missing platform resources data\n");
1150                 return -ENODEV;
1151         }
1152
1153         vpdma->base = devm_ioremap(&pdev->dev, res->start, resource_size(res));
1154         if (!vpdma->base) {
1155                 dev_err(&pdev->dev, "failed to ioremap\n");
1156                 return -ENOMEM;
1157         }
1158
1159         r = vpdma_load_firmware(vpdma);
1160         if (r) {
1161                 pr_err("failed to load firmware %s\n", VPDMA_FIRMWARE);
1162                 return r;
1163         }
1164
1165         return 0;
1166 }
1167 EXPORT_SYMBOL(vpdma_create);
1168
1169 MODULE_AUTHOR("Texas Instruments Inc.");
1170 MODULE_FIRMWARE(VPDMA_FIRMWARE);
1171 MODULE_LICENSE("GPL v2");