aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/platform/ti-vpe
diff options
context:
space:
mode:
authorArchit Taneja <archit@ti.com>2013-10-16 01:36:45 -0400
committerMauro Carvalho Chehab <m.chehab@samsung.com>2013-10-28 13:08:44 -0400
commit9262e5a2253ad055d465fcf0905a5b5f160ce6f8 (patch)
tree49c4505b7da57dd5c21112aead2d7282d67899dc /drivers/media/platform/ti-vpe
parent23c4919c6fd15e76fe245ad0158f8739a3fa0747 (diff)
[media] v4l: ti-vpe: Create a vpdma helper library
The primary function of VPDMA is to move data between external memory and internal processing modules(in our case, VPE) that source or sink data. VPDMA is capable of buffering this data and then delivering the data as demanded to the modules as programmed. The modules that source or sink data are referred to as clients or ports. A channel is setup inside the VPDMA to connect a specific memory buffer to a specific client. The VPDMA centralizes the DMA control functions and buffering required to allow all the clients to minimize the effect of long latency times. Add the following to the VPDMA helper: - A data struct which describe VPDMA channels. For now, these channels are the ones used only by VPE, the list of channels will increase when VIP(Video Input Port) also uses the VPDMA library. This channel information will be used to populate fields required by data descriptors. - Data structs which describe the different data types supported by VPDMA. This data type information will be used to populate fields required by data descriptors and used by the VPE driver to map a V4L2 format to the corresponding VPDMA data type. - Provide VPDMA register offset definitions, functions to read, write and modify VPDMA registers. - Functions to create and submit a VPDMA list. A list is a group of descriptors that makes up a set of DMA transfers that need to be completed. Each descriptor will either perform a DMA transaction to fetch input buffers and write to output buffers(data descriptors), or configure the MMRs of sub blocks of VPE(configuration descriptors), or provide control information to VPDMA (control descriptors). - Functions to allocate, map and unmap buffers needed for the descriptor list, payloads containing MMR values and scaler coefficients. These use the DMA mapping APIs to ensure exclusive access to VPDMA. - Functions to enable VPDMA interrupts. VPDMA can trigger an interrupt on the VPE interrupt line when a descriptor list is parsed completely and the DMA transactions are completed. This requires masking the events in VPDMA registers and configuring some top level VPE interrupt registers. - Enable some VPDMA specific parameters: frame start event(when to start DMA for a client) and line mode(whether each line fetched should be mirrored or not). - Function to load firmware required by VPDMA. VPDMA requires a firmware for it's internal list manager. We add the required request_firmware apis to fetch this firmware from user space. - Function to dump VPDMA registers. - A function to initialize and create a VPDMA instance, this will be called by the VPE driver with it's platform device pointer, this function will take care of loading VPDMA firmware and returning a vpdma_data instance back to the VPE driver. The VIP driver will also call the same init function to initialize it's own VPDMA instance. Signed-off-by: Archit Taneja <archit@ti.com> Acked-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Kamil Debski <k.debski@samsung.com> Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
Diffstat (limited to 'drivers/media/platform/ti-vpe')
-rw-r--r--drivers/media/platform/ti-vpe/vpdma.c578
-rw-r--r--drivers/media/platform/ti-vpe/vpdma.h155
-rw-r--r--drivers/media/platform/ti-vpe/vpdma_priv.h119
3 files changed, 852 insertions, 0 deletions
diff --git a/drivers/media/platform/ti-vpe/vpdma.c b/drivers/media/platform/ti-vpe/vpdma.c
new file mode 100644
index 000000000000..42db12c373ac
--- /dev/null
+++ b/drivers/media/platform/ti-vpe/vpdma.c
@@ -0,0 +1,578 @@
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
25#include "vpdma.h"
26#include "vpdma_priv.h"
27
28#define VPDMA_FIRMWARE "vpdma-1b8.bin"
29
30const struct vpdma_data_format vpdma_yuv_fmts[] = {
31 [VPDMA_DATA_FMT_Y444] = {
32 .data_type = DATA_TYPE_Y444,
33 .depth = 8,
34 },
35 [VPDMA_DATA_FMT_Y422] = {
36 .data_type = DATA_TYPE_Y422,
37 .depth = 8,
38 },
39 [VPDMA_DATA_FMT_Y420] = {
40 .data_type = DATA_TYPE_Y420,
41 .depth = 8,
42 },
43 [VPDMA_DATA_FMT_C444] = {
44 .data_type = DATA_TYPE_C444,
45 .depth = 8,
46 },
47 [VPDMA_DATA_FMT_C422] = {
48 .data_type = DATA_TYPE_C422,
49 .depth = 8,
50 },
51 [VPDMA_DATA_FMT_C420] = {
52 .data_type = DATA_TYPE_C420,
53 .depth = 4,
54 },
55 [VPDMA_DATA_FMT_YC422] = {
56 .data_type = DATA_TYPE_YC422,
57 .depth = 16,
58 },
59 [VPDMA_DATA_FMT_YC444] = {
60 .data_type = DATA_TYPE_YC444,
61 .depth = 24,
62 },
63 [VPDMA_DATA_FMT_CY422] = {
64 .data_type = DATA_TYPE_CY422,
65 .depth = 16,
66 },
67};
68
69const struct vpdma_data_format vpdma_rgb_fmts[] = {
70 [VPDMA_DATA_FMT_RGB565] = {
71 .data_type = DATA_TYPE_RGB16_565,
72 .depth = 16,
73 },
74 [VPDMA_DATA_FMT_ARGB16_1555] = {
75 .data_type = DATA_TYPE_ARGB_1555,
76 .depth = 16,
77 },
78 [VPDMA_DATA_FMT_ARGB16] = {
79 .data_type = DATA_TYPE_ARGB_4444,
80 .depth = 16,
81 },
82 [VPDMA_DATA_FMT_RGBA16_5551] = {
83 .data_type = DATA_TYPE_RGBA_5551,
84 .depth = 16,
85 },
86 [VPDMA_DATA_FMT_RGBA16] = {
87 .data_type = DATA_TYPE_RGBA_4444,
88 .depth = 16,
89 },
90 [VPDMA_DATA_FMT_ARGB24] = {
91 .data_type = DATA_TYPE_ARGB24_6666,
92 .depth = 24,
93 },
94 [VPDMA_DATA_FMT_RGB24] = {
95 .data_type = DATA_TYPE_RGB24_888,
96 .depth = 24,
97 },
98 [VPDMA_DATA_FMT_ARGB32] = {
99 .data_type = DATA_TYPE_ARGB32_8888,
100 .depth = 32,
101 },
102 [VPDMA_DATA_FMT_RGBA24] = {
103 .data_type = DATA_TYPE_RGBA24_6666,
104 .depth = 24,
105 },
106 [VPDMA_DATA_FMT_RGBA32] = {
107 .data_type = DATA_TYPE_RGBA32_8888,
108 .depth = 32,
109 },
110 [VPDMA_DATA_FMT_BGR565] = {
111 .data_type = DATA_TYPE_BGR16_565,
112 .depth = 16,
113 },
114 [VPDMA_DATA_FMT_ABGR16_1555] = {
115 .data_type = DATA_TYPE_ABGR_1555,
116 .depth = 16,
117 },
118 [VPDMA_DATA_FMT_ABGR16] = {
119 .data_type = DATA_TYPE_ABGR_4444,
120 .depth = 16,
121 },
122 [VPDMA_DATA_FMT_BGRA16_5551] = {
123 .data_type = DATA_TYPE_BGRA_5551,
124 .depth = 16,
125 },
126 [VPDMA_DATA_FMT_BGRA16] = {
127 .data_type = DATA_TYPE_BGRA_4444,
128 .depth = 16,
129 },
130 [VPDMA_DATA_FMT_ABGR24] = {
131 .data_type = DATA_TYPE_ABGR24_6666,
132 .depth = 24,
133 },
134 [VPDMA_DATA_FMT_BGR24] = {
135 .data_type = DATA_TYPE_BGR24_888,
136 .depth = 24,
137 },
138 [VPDMA_DATA_FMT_ABGR32] = {
139 .data_type = DATA_TYPE_ABGR32_8888,
140 .depth = 32,
141 },
142 [VPDMA_DATA_FMT_BGRA24] = {
143 .data_type = DATA_TYPE_BGRA24_6666,
144 .depth = 24,
145 },
146 [VPDMA_DATA_FMT_BGRA32] = {
147 .data_type = DATA_TYPE_BGRA32_8888,
148 .depth = 32,
149 },
150};
151
152const struct vpdma_data_format vpdma_misc_fmts[] = {
153 [VPDMA_DATA_FMT_MV] = {
154 .data_type = DATA_TYPE_MV,
155 .depth = 4,
156 },
157};
158
159struct vpdma_channel_info {
160 int num; /* VPDMA channel number */
161 int cstat_offset; /* client CSTAT register offset */
162};
163
164static const struct vpdma_channel_info chan_info[] = {
165 [VPE_CHAN_LUMA1_IN] = {
166 .num = VPE_CHAN_NUM_LUMA1_IN,
167 .cstat_offset = VPDMA_DEI_LUMA1_CSTAT,
168 },
169 [VPE_CHAN_CHROMA1_IN] = {
170 .num = VPE_CHAN_NUM_CHROMA1_IN,
171 .cstat_offset = VPDMA_DEI_CHROMA1_CSTAT,
172 },
173 [VPE_CHAN_LUMA2_IN] = {
174 .num = VPE_CHAN_NUM_LUMA2_IN,
175 .cstat_offset = VPDMA_DEI_LUMA2_CSTAT,
176 },
177 [VPE_CHAN_CHROMA2_IN] = {
178 .num = VPE_CHAN_NUM_CHROMA2_IN,
179 .cstat_offset = VPDMA_DEI_CHROMA2_CSTAT,
180 },
181 [VPE_CHAN_LUMA3_IN] = {
182 .num = VPE_CHAN_NUM_LUMA3_IN,
183 .cstat_offset = VPDMA_DEI_LUMA3_CSTAT,
184 },
185 [VPE_CHAN_CHROMA3_IN] = {
186 .num = VPE_CHAN_NUM_CHROMA3_IN,
187 .cstat_offset = VPDMA_DEI_CHROMA3_CSTAT,
188 },
189 [VPE_CHAN_MV_IN] = {
190 .num = VPE_CHAN_NUM_MV_IN,
191 .cstat_offset = VPDMA_DEI_MV_IN_CSTAT,
192 },
193 [VPE_CHAN_MV_OUT] = {
194 .num = VPE_CHAN_NUM_MV_OUT,
195 .cstat_offset = VPDMA_DEI_MV_OUT_CSTAT,
196 },
197 [VPE_CHAN_LUMA_OUT] = {
198 .num = VPE_CHAN_NUM_LUMA_OUT,
199 .cstat_offset = VPDMA_VIP_UP_Y_CSTAT,
200 },
201 [VPE_CHAN_CHROMA_OUT] = {
202 .num = VPE_CHAN_NUM_CHROMA_OUT,
203 .cstat_offset = VPDMA_VIP_UP_UV_CSTAT,
204 },
205 [VPE_CHAN_RGB_OUT] = {
206 .num = VPE_CHAN_NUM_RGB_OUT,
207 .cstat_offset = VPDMA_VIP_UP_Y_CSTAT,
208 },
209};
210
211static u32 read_reg(struct vpdma_data *vpdma, int offset)
212{
213 return ioread32(vpdma->base + offset);
214}
215
216static void write_reg(struct vpdma_data *vpdma, int offset, u32 value)
217{
218 iowrite32(value, vpdma->base + offset);
219}
220
221static int read_field_reg(struct vpdma_data *vpdma, int offset,
222 u32 mask, int shift)
223{
224 return (read_reg(vpdma, offset) & (mask << shift)) >> shift;
225}
226
227static void write_field_reg(struct vpdma_data *vpdma, int offset, u32 field,
228 u32 mask, int shift)
229{
230 u32 val = read_reg(vpdma, offset);
231
232 val &= ~(mask << shift);
233 val |= (field & mask) << shift;
234
235 write_reg(vpdma, offset, val);
236}
237
238void vpdma_dump_regs(struct vpdma_data *vpdma)
239{
240 struct device *dev = &vpdma->pdev->dev;
241
242#define DUMPREG(r) dev_dbg(dev, "%-35s %08x\n", #r, read_reg(vpdma, VPDMA_##r))
243
244 dev_dbg(dev, "VPDMA Registers:\n");
245
246 DUMPREG(PID);
247 DUMPREG(LIST_ADDR);
248 DUMPREG(LIST_ATTR);
249 DUMPREG(LIST_STAT_SYNC);
250 DUMPREG(BG_RGB);
251 DUMPREG(BG_YUV);
252 DUMPREG(SETUP);
253 DUMPREG(MAX_SIZE1);
254 DUMPREG(MAX_SIZE2);
255 DUMPREG(MAX_SIZE3);
256
257 /*
258 * dumping registers of only group0 and group3, because VPE channels
259 * lie within group0 and group3 registers
260 */
261 DUMPREG(INT_CHAN_STAT(0));
262 DUMPREG(INT_CHAN_MASK(0));
263 DUMPREG(INT_CHAN_STAT(3));
264 DUMPREG(INT_CHAN_MASK(3));
265 DUMPREG(INT_CLIENT0_STAT);
266 DUMPREG(INT_CLIENT0_MASK);
267 DUMPREG(INT_CLIENT1_STAT);
268 DUMPREG(INT_CLIENT1_MASK);
269 DUMPREG(INT_LIST0_STAT);
270 DUMPREG(INT_LIST0_MASK);
271
272 /*
273 * these are registers specific to VPE clients, we can make this
274 * function dump client registers specific to VPE or VIP based on
275 * who is using it
276 */
277 DUMPREG(DEI_CHROMA1_CSTAT);
278 DUMPREG(DEI_LUMA1_CSTAT);
279 DUMPREG(DEI_CHROMA2_CSTAT);
280 DUMPREG(DEI_LUMA2_CSTAT);
281 DUMPREG(DEI_CHROMA3_CSTAT);
282 DUMPREG(DEI_LUMA3_CSTAT);
283 DUMPREG(DEI_MV_IN_CSTAT);
284 DUMPREG(DEI_MV_OUT_CSTAT);
285 DUMPREG(VIP_UP_Y_CSTAT);
286 DUMPREG(VIP_UP_UV_CSTAT);
287 DUMPREG(VPI_CTL_CSTAT);
288}
289
290/*
291 * Allocate a DMA buffer
292 */
293int vpdma_alloc_desc_buf(struct vpdma_buf *buf, size_t size)
294{
295 buf->size = size;
296 buf->mapped = false;
297 buf->addr = kzalloc(size, GFP_KERNEL);
298 if (!buf->addr)
299 return -ENOMEM;
300
301 WARN_ON((u32) buf->addr & VPDMA_DESC_ALIGN);
302
303 return 0;
304}
305
306void vpdma_free_desc_buf(struct vpdma_buf *buf)
307{
308 WARN_ON(buf->mapped);
309 kfree(buf->addr);
310 buf->addr = NULL;
311 buf->size = 0;
312}
313
314/*
315 * map descriptor/payload DMA buffer, enabling DMA access
316 */
317int vpdma_map_desc_buf(struct vpdma_data *vpdma, struct vpdma_buf *buf)
318{
319 struct device *dev = &vpdma->pdev->dev;
320
321 WARN_ON(buf->mapped);
322 buf->dma_addr = dma_map_single(dev, buf->addr, buf->size,
323 DMA_TO_DEVICE);
324 if (dma_mapping_error(dev, buf->dma_addr)) {
325 dev_err(dev, "failed to map buffer\n");
326 return -EINVAL;
327 }
328
329 buf->mapped = true;
330
331 return 0;
332}
333
334/*
335 * unmap descriptor/payload DMA buffer, disabling DMA access and
336 * allowing the main processor to acces the data
337 */
338void vpdma_unmap_desc_buf(struct vpdma_data *vpdma, struct vpdma_buf *buf)
339{
340 struct device *dev = &vpdma->pdev->dev;
341
342 if (buf->mapped)
343 dma_unmap_single(dev, buf->dma_addr, buf->size, DMA_TO_DEVICE);
344
345 buf->mapped = false;
346}
347
348/*
349 * create a descriptor list, the user of this list will append configuration,
350 * control and data descriptors to this list, this list will be submitted to
351 * VPDMA. VPDMA's list parser will go through each descriptor and perform the
352 * required DMA operations
353 */
354int vpdma_create_desc_list(struct vpdma_desc_list *list, size_t size, int type)
355{
356 int r;
357
358 r = vpdma_alloc_desc_buf(&list->buf, size);
359 if (r)
360 return r;
361
362 list->next = list->buf.addr;
363
364 list->type = type;
365
366 return 0;
367}
368
369/*
370 * once a descriptor list is parsed by VPDMA, we reset the list by emptying it,
371 * to allow new descriptors to be added to the list.
372 */
373void vpdma_reset_desc_list(struct vpdma_desc_list *list)
374{
375 list->next = list->buf.addr;
376}
377
378/*
379 * free the buffer allocated fot the VPDMA descriptor list, this should be
380 * called when the user doesn't want to use VPDMA any more.
381 */
382void vpdma_free_desc_list(struct vpdma_desc_list *list)
383{
384 vpdma_free_desc_buf(&list->buf);
385
386 list->next = NULL;
387}
388
389static bool vpdma_list_busy(struct vpdma_data *vpdma, int list_num)
390{
391 return read_reg(vpdma, VPDMA_LIST_STAT_SYNC) & BIT(list_num + 16);
392}
393
394/*
395 * submit a list of DMA descriptors to the VPE VPDMA, do not wait for completion
396 */
397int vpdma_submit_descs(struct vpdma_data *vpdma, struct vpdma_desc_list *list)
398{
399 /* we always use the first list */
400 int list_num = 0;
401 int list_size;
402
403 if (vpdma_list_busy(vpdma, list_num))
404 return -EBUSY;
405
406 /* 16-byte granularity */
407 list_size = (list->next - list->buf.addr) >> 4;
408
409 write_reg(vpdma, VPDMA_LIST_ADDR, (u32) list->buf.dma_addr);
410
411 write_reg(vpdma, VPDMA_LIST_ATTR,
412 (list_num << VPDMA_LIST_NUM_SHFT) |
413 (list->type << VPDMA_LIST_TYPE_SHFT) |
414 list_size);
415
416 return 0;
417}
418
419/* set or clear the mask for list complete interrupt */
420void vpdma_enable_list_complete_irq(struct vpdma_data *vpdma, int list_num,
421 bool enable)
422{
423 u32 val;
424
425 val = read_reg(vpdma, VPDMA_INT_LIST0_MASK);
426 if (enable)
427 val |= (1 << (list_num * 2));
428 else
429 val &= ~(1 << (list_num * 2));
430 write_reg(vpdma, VPDMA_INT_LIST0_MASK, val);
431}
432
433/* clear previosuly occured list intterupts in the LIST_STAT register */
434void vpdma_clear_list_stat(struct vpdma_data *vpdma)
435{
436 write_reg(vpdma, VPDMA_INT_LIST0_STAT,
437 read_reg(vpdma, VPDMA_INT_LIST0_STAT));
438}
439
440/*
441 * configures the output mode of the line buffer for the given client, the
442 * line buffer content can either be mirrored(each line repeated twice) or
443 * passed to the client as is
444 */
445void vpdma_set_line_mode(struct vpdma_data *vpdma, int line_mode,
446 enum vpdma_channel chan)
447{
448 int client_cstat = chan_info[chan].cstat_offset;
449
450 write_field_reg(vpdma, client_cstat, line_mode,
451 VPDMA_CSTAT_LINE_MODE_MASK, VPDMA_CSTAT_LINE_MODE_SHIFT);
452}
453
454/*
455 * configures the event which should trigger VPDMA transfer for the given
456 * client
457 */
458void vpdma_set_frame_start_event(struct vpdma_data *vpdma,
459 enum vpdma_frame_start_event fs_event,
460 enum vpdma_channel chan)
461{
462 int client_cstat = chan_info[chan].cstat_offset;
463
464 write_field_reg(vpdma, client_cstat, fs_event,
465 VPDMA_CSTAT_FRAME_START_MASK, VPDMA_CSTAT_FRAME_START_SHIFT);
466}
467
468static void vpdma_firmware_cb(const struct firmware *f, void *context)
469{
470 struct vpdma_data *vpdma = context;
471 struct vpdma_buf fw_dma_buf;
472 int i, r;
473
474 dev_dbg(&vpdma->pdev->dev, "firmware callback\n");
475
476 if (!f || !f->data) {
477 dev_err(&vpdma->pdev->dev, "couldn't get firmware\n");
478 return;
479 }
480
481 /* already initialized */
482 if (read_field_reg(vpdma, VPDMA_LIST_ATTR, VPDMA_LIST_RDY_MASK,
483 VPDMA_LIST_RDY_SHFT)) {
484 vpdma->ready = true;
485 return;
486 }
487
488 r = vpdma_alloc_desc_buf(&fw_dma_buf, f->size);
489 if (r) {
490 dev_err(&vpdma->pdev->dev,
491 "failed to allocate dma buffer for firmware\n");
492 goto rel_fw;
493 }
494
495 memcpy(fw_dma_buf.addr, f->data, f->size);
496
497 vpdma_map_desc_buf(vpdma, &fw_dma_buf);
498
499 write_reg(vpdma, VPDMA_LIST_ADDR, (u32) fw_dma_buf.dma_addr);
500
501 for (i = 0; i < 100; i++) { /* max 1 second */
502 msleep_interruptible(10);
503
504 if (read_field_reg(vpdma, VPDMA_LIST_ATTR, VPDMA_LIST_RDY_MASK,
505 VPDMA_LIST_RDY_SHFT))
506 break;
507 }
508
509 if (i == 100) {
510 dev_err(&vpdma->pdev->dev, "firmware upload failed\n");
511 goto free_buf;
512 }
513
514 vpdma->ready = true;
515
516free_buf:
517 vpdma_unmap_desc_buf(vpdma, &fw_dma_buf);
518
519 vpdma_free_desc_buf(&fw_dma_buf);
520rel_fw:
521 release_firmware(f);
522}
523
524static int vpdma_load_firmware(struct vpdma_data *vpdma)
525{
526 int r;
527 struct device *dev = &vpdma->pdev->dev;
528
529 r = request_firmware_nowait(THIS_MODULE, 1,
530 (const char *) VPDMA_FIRMWARE, dev, GFP_KERNEL, vpdma,
531 vpdma_firmware_cb);
532 if (r) {
533 dev_err(dev, "firmware not available %s\n", VPDMA_FIRMWARE);
534 return r;
535 } else {
536 dev_info(dev, "loading firmware %s\n", VPDMA_FIRMWARE);
537 }
538
539 return 0;
540}
541
542struct vpdma_data *vpdma_create(struct platform_device *pdev)
543{
544 struct resource *res;
545 struct vpdma_data *vpdma;
546 int r;
547
548 dev_dbg(&pdev->dev, "vpdma_create\n");
549
550 vpdma = devm_kzalloc(&pdev->dev, sizeof(*vpdma), GFP_KERNEL);
551 if (!vpdma) {
552 dev_err(&pdev->dev, "couldn't alloc vpdma_dev\n");
553 return ERR_PTR(-ENOMEM);
554 }
555
556 vpdma->pdev = pdev;
557
558 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vpdma");
559 if (res == NULL) {
560 dev_err(&pdev->dev, "missing platform resources data\n");
561 return ERR_PTR(-ENODEV);
562 }
563
564 vpdma->base = devm_ioremap(&pdev->dev, res->start, resource_size(res));
565 if (!vpdma->base) {
566 dev_err(&pdev->dev, "failed to ioremap\n");
567 return ERR_PTR(-ENOMEM);
568 }
569
570 r = vpdma_load_firmware(vpdma);
571 if (r) {
572 pr_err("failed to load firmware %s\n", VPDMA_FIRMWARE);
573 return ERR_PTR(r);
574 }
575
576 return vpdma;
577}
578MODULE_FIRMWARE(VPDMA_FIRMWARE);
diff --git a/drivers/media/platform/ti-vpe/vpdma.h b/drivers/media/platform/ti-vpe/vpdma.h
new file mode 100644
index 000000000000..80566892c6cb
--- /dev/null
+++ b/drivers/media/platform/ti-vpe/vpdma.h
@@ -0,0 +1,155 @@
1/*
2 * Copyright (c) 2013 Texas Instruments Inc.
3 *
4 * David Griego, <dagriego@biglakesoftware.com>
5 * Dale Farnsworth, <dale@farnsworth.org>
6 * Archit Taneja, <archit@ti.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 2 as published by
10 * the Free Software Foundation.
11 */
12
13#ifndef __TI_VPDMA_H_
14#define __TI_VPDMA_H_
15
16/*
17 * A vpdma_buf tracks the size, DMA address and mapping status of each
18 * driver DMA area.
19 */
20struct vpdma_buf {
21 void *addr;
22 dma_addr_t dma_addr;
23 size_t size;
24 bool mapped;
25};
26
27struct vpdma_desc_list {
28 struct vpdma_buf buf;
29 void *next;
30 int type;
31};
32
33struct vpdma_data {
34 void __iomem *base;
35
36 struct platform_device *pdev;
37
38 /* tells whether vpdma firmware is loaded or not */
39 bool ready;
40};
41
42struct vpdma_data_format {
43 int data_type;
44 u8 depth;
45};
46
47#define VPDMA_DESC_ALIGN 16 /* 16-byte descriptor alignment */
48
49#define VPDMA_DTD_DESC_SIZE 32 /* 8 words */
50#define VPDMA_CFD_CTD_DESC_SIZE 16 /* 4 words */
51
52#define VPDMA_LIST_TYPE_NORMAL 0
53#define VPDMA_LIST_TYPE_SELF_MODIFYING 1
54#define VPDMA_LIST_TYPE_DOORBELL 2
55
56enum vpdma_yuv_formats {
57 VPDMA_DATA_FMT_Y444 = 0,
58 VPDMA_DATA_FMT_Y422,
59 VPDMA_DATA_FMT_Y420,
60 VPDMA_DATA_FMT_C444,
61 VPDMA_DATA_FMT_C422,
62 VPDMA_DATA_FMT_C420,
63 VPDMA_DATA_FMT_YC422,
64 VPDMA_DATA_FMT_YC444,
65 VPDMA_DATA_FMT_CY422,
66};
67
68enum vpdma_rgb_formats {
69 VPDMA_DATA_FMT_RGB565 = 0,
70 VPDMA_DATA_FMT_ARGB16_1555,
71 VPDMA_DATA_FMT_ARGB16,
72 VPDMA_DATA_FMT_RGBA16_5551,
73 VPDMA_DATA_FMT_RGBA16,
74 VPDMA_DATA_FMT_ARGB24,
75 VPDMA_DATA_FMT_RGB24,
76 VPDMA_DATA_FMT_ARGB32,
77 VPDMA_DATA_FMT_RGBA24,
78 VPDMA_DATA_FMT_RGBA32,
79 VPDMA_DATA_FMT_BGR565,
80 VPDMA_DATA_FMT_ABGR16_1555,
81 VPDMA_DATA_FMT_ABGR16,
82 VPDMA_DATA_FMT_BGRA16_5551,
83 VPDMA_DATA_FMT_BGRA16,
84 VPDMA_DATA_FMT_ABGR24,
85 VPDMA_DATA_FMT_BGR24,
86 VPDMA_DATA_FMT_ABGR32,
87 VPDMA_DATA_FMT_BGRA24,
88 VPDMA_DATA_FMT_BGRA32,
89};
90
91enum vpdma_misc_formats {
92 VPDMA_DATA_FMT_MV = 0,
93};
94
95extern const struct vpdma_data_format vpdma_yuv_fmts[];
96extern const struct vpdma_data_format vpdma_rgb_fmts[];
97extern const struct vpdma_data_format vpdma_misc_fmts[];
98
99enum vpdma_frame_start_event {
100 VPDMA_FSEVENT_HDMI_FID = 0,
101 VPDMA_FSEVENT_DVO2_FID,
102 VPDMA_FSEVENT_HDCOMP_FID,
103 VPDMA_FSEVENT_SD_FID,
104 VPDMA_FSEVENT_LM_FID0,
105 VPDMA_FSEVENT_LM_FID1,
106 VPDMA_FSEVENT_LM_FID2,
107 VPDMA_FSEVENT_CHANNEL_ACTIVE,
108};
109
110/*
111 * VPDMA channel numbers
112 */
113enum vpdma_channel {
114 VPE_CHAN_LUMA1_IN,
115 VPE_CHAN_CHROMA1_IN,
116 VPE_CHAN_LUMA2_IN,
117 VPE_CHAN_CHROMA2_IN,
118 VPE_CHAN_LUMA3_IN,
119 VPE_CHAN_CHROMA3_IN,
120 VPE_CHAN_MV_IN,
121 VPE_CHAN_MV_OUT,
122 VPE_CHAN_LUMA_OUT,
123 VPE_CHAN_CHROMA_OUT,
124 VPE_CHAN_RGB_OUT,
125};
126
127/* vpdma descriptor buffer allocation and management */
128int vpdma_alloc_desc_buf(struct vpdma_buf *buf, size_t size);
129void vpdma_free_desc_buf(struct vpdma_buf *buf);
130int vpdma_map_desc_buf(struct vpdma_data *vpdma, struct vpdma_buf *buf);
131void vpdma_unmap_desc_buf(struct vpdma_data *vpdma, struct vpdma_buf *buf);
132
133/* vpdma descriptor list funcs */
134int vpdma_create_desc_list(struct vpdma_desc_list *list, size_t size, int type);
135void vpdma_reset_desc_list(struct vpdma_desc_list *list);
136void vpdma_free_desc_list(struct vpdma_desc_list *list);
137int vpdma_submit_descs(struct vpdma_data *vpdma, struct vpdma_desc_list *list);
138
139/* vpdma list interrupt management */
140void vpdma_enable_list_complete_irq(struct vpdma_data *vpdma, int list_num,
141 bool enable);
142void vpdma_clear_list_stat(struct vpdma_data *vpdma);
143
144/* vpdma client configuration */
145void vpdma_set_line_mode(struct vpdma_data *vpdma, int line_mode,
146 enum vpdma_channel chan);
147void vpdma_set_frame_start_event(struct vpdma_data *vpdma,
148 enum vpdma_frame_start_event fs_event, enum vpdma_channel chan);
149
150void vpdma_dump_regs(struct vpdma_data *vpdma);
151
152/* initialize vpdma, passed with VPE's platform device pointer */
153struct vpdma_data *vpdma_create(struct platform_device *pdev);
154
155#endif
diff --git a/drivers/media/platform/ti-vpe/vpdma_priv.h b/drivers/media/platform/ti-vpe/vpdma_priv.h
new file mode 100644
index 000000000000..8ff51a3cfd95
--- /dev/null
+++ b/drivers/media/platform/ti-vpe/vpdma_priv.h
@@ -0,0 +1,119 @@
1/*
2 * Copyright (c) 2013 Texas Instruments Inc.
3 *
4 * David Griego, <dagriego@biglakesoftware.com>
5 * Dale Farnsworth, <dale@farnsworth.org>
6 * Archit Taneja, <archit@ti.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 2 as published by
10 * the Free Software Foundation.
11 */
12
13#ifndef _TI_VPDMA_PRIV_H_
14#define _TI_VPDMA_PRIV_H_
15
16/*
17 * VPDMA Register offsets
18 */
19
20/* Top level */
21#define VPDMA_PID 0x00
22#define VPDMA_LIST_ADDR 0x04
23#define VPDMA_LIST_ATTR 0x08
24#define VPDMA_LIST_STAT_SYNC 0x0c
25#define VPDMA_BG_RGB 0x18
26#define VPDMA_BG_YUV 0x1c
27#define VPDMA_SETUP 0x30
28#define VPDMA_MAX_SIZE1 0x34
29#define VPDMA_MAX_SIZE2 0x38
30#define VPDMA_MAX_SIZE3 0x3c
31
32/* Interrupts */
33#define VPDMA_INT_CHAN_STAT(grp) (0x40 + grp * 8)
34#define VPDMA_INT_CHAN_MASK(grp) (VPDMA_INT_CHAN_STAT(grp) + 4)
35#define VPDMA_INT_CLIENT0_STAT 0x78
36#define VPDMA_INT_CLIENT0_MASK 0x7c
37#define VPDMA_INT_CLIENT1_STAT 0x80
38#define VPDMA_INT_CLIENT1_MASK 0x84
39#define VPDMA_INT_LIST0_STAT 0x88
40#define VPDMA_INT_LIST0_MASK 0x8c
41
42#define VPDMA_PERFMON(i) (0x200 + i * 4)
43
44/* VPE specific client registers */
45#define VPDMA_DEI_CHROMA1_CSTAT 0x0300
46#define VPDMA_DEI_LUMA1_CSTAT 0x0304
47#define VPDMA_DEI_LUMA2_CSTAT 0x0308
48#define VPDMA_DEI_CHROMA2_CSTAT 0x030c
49#define VPDMA_DEI_LUMA3_CSTAT 0x0310
50#define VPDMA_DEI_CHROMA3_CSTAT 0x0314
51#define VPDMA_DEI_MV_IN_CSTAT 0x0330
52#define VPDMA_DEI_MV_OUT_CSTAT 0x033c
53#define VPDMA_VIP_UP_Y_CSTAT 0x0390
54#define VPDMA_VIP_UP_UV_CSTAT 0x0394
55#define VPDMA_VPI_CTL_CSTAT 0x03d0
56
57/* Reg field info for VPDMA_CLIENT_CSTAT registers */
58#define VPDMA_CSTAT_LINE_MODE_MASK 0x03
59#define VPDMA_CSTAT_LINE_MODE_SHIFT 8
60#define VPDMA_CSTAT_FRAME_START_MASK 0xf
61#define VPDMA_CSTAT_FRAME_START_SHIFT 10
62
63#define VPDMA_LIST_NUM_MASK 0x07
64#define VPDMA_LIST_NUM_SHFT 24
65#define VPDMA_LIST_STOP_SHFT 20
66#define VPDMA_LIST_RDY_MASK 0x01
67#define VPDMA_LIST_RDY_SHFT 19
68#define VPDMA_LIST_TYPE_MASK 0x03
69#define VPDMA_LIST_TYPE_SHFT 16
70#define VPDMA_LIST_SIZE_MASK 0xffff
71
72/* VPDMA data type values for data formats */
73#define DATA_TYPE_Y444 0x0
74#define DATA_TYPE_Y422 0x1
75#define DATA_TYPE_Y420 0x2
76#define DATA_TYPE_C444 0x4
77#define DATA_TYPE_C422 0x5
78#define DATA_TYPE_C420 0x6
79#define DATA_TYPE_YC422 0x7
80#define DATA_TYPE_YC444 0x8
81#define DATA_TYPE_CY422 0x23
82
83#define DATA_TYPE_RGB16_565 0x0
84#define DATA_TYPE_ARGB_1555 0x1
85#define DATA_TYPE_ARGB_4444 0x2
86#define DATA_TYPE_RGBA_5551 0x3
87#define DATA_TYPE_RGBA_4444 0x4
88#define DATA_TYPE_ARGB24_6666 0x5
89#define DATA_TYPE_RGB24_888 0x6
90#define DATA_TYPE_ARGB32_8888 0x7
91#define DATA_TYPE_RGBA24_6666 0x8
92#define DATA_TYPE_RGBA32_8888 0x9
93#define DATA_TYPE_BGR16_565 0x10
94#define DATA_TYPE_ABGR_1555 0x11
95#define DATA_TYPE_ABGR_4444 0x12
96#define DATA_TYPE_BGRA_5551 0x13
97#define DATA_TYPE_BGRA_4444 0x14
98#define DATA_TYPE_ABGR24_6666 0x15
99#define DATA_TYPE_BGR24_888 0x16
100#define DATA_TYPE_ABGR32_8888 0x17
101#define DATA_TYPE_BGRA24_6666 0x18
102#define DATA_TYPE_BGRA32_8888 0x19
103
104#define DATA_TYPE_MV 0x3
105
106/* VPDMA channel numbers(only VPE channels for now) */
107#define VPE_CHAN_NUM_LUMA1_IN 0
108#define VPE_CHAN_NUM_CHROMA1_IN 1
109#define VPE_CHAN_NUM_LUMA2_IN 2
110#define VPE_CHAN_NUM_CHROMA2_IN 3
111#define VPE_CHAN_NUM_LUMA3_IN 4
112#define VPE_CHAN_NUM_CHROMA3_IN 5
113#define VPE_CHAN_NUM_MV_IN 12
114#define VPE_CHAN_NUM_MV_OUT 15
115#define VPE_CHAN_NUM_LUMA_OUT 102
116#define VPE_CHAN_NUM_CHROMA_OUT 103
117#define VPE_CHAN_NUM_RGB_OUT 106
118
119#endif