aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/platform/ti-vpe
diff options
context:
space:
mode:
authorArchit Taneja <archit@ti.com>2013-10-16 01:36:46 -0400
committerMauro Carvalho Chehab <m.chehab@samsung.com>2013-10-28 13:10:46 -0400
commit213b8ee4001895dd60910c440f76682fb881b5cc (patch)
tree1905e8cec30a57c2a36a20babbdb8fee84ae8022 /drivers/media/platform/ti-vpe
parent9262e5a2253ad055d465fcf0905a5b5f160ce6f8 (diff)
[media] v4l: ti-vpe: Add helpers for creating VPDMA descriptors
Create functions which the VPE driver can use to create a VPDMA descriptor and add it to a VPDMA descriptor list. These functions take a pointer to an existing list, and append the configuration/data/control descriptor header to the list. In the case of configuration descriptors, the creation of a payload block may be required(the payloads can hold VPE MMR values, or scaler coefficients). The allocation of the payload buffer and it's content is left to the VPE driver. However, the VPDMA library provides helper macros to create payload in the correct format. Add debug functions to dump the descriptors in a way such that it's easy to see the values of different fields in the descriptors. 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.c268
-rw-r--r--drivers/media/platform/ti-vpe/vpdma.h48
-rw-r--r--drivers/media/platform/ti-vpe/vpdma_priv.h522
3 files changed, 838 insertions, 0 deletions
diff --git a/drivers/media/platform/ti-vpe/vpdma.c b/drivers/media/platform/ti-vpe/vpdma.c
index 42db12c373ac..af0a5ffcaa98 100644
--- a/drivers/media/platform/ti-vpe/vpdma.c
+++ b/drivers/media/platform/ti-vpe/vpdma.c
@@ -21,6 +21,7 @@
21#include <linux/platform_device.h> 21#include <linux/platform_device.h>
22#include <linux/sched.h> 22#include <linux/sched.h>
23#include <linux/slab.h> 23#include <linux/slab.h>
24#include <linux/videodev2.h>
24 25
25#include "vpdma.h" 26#include "vpdma.h"
26#include "vpdma_priv.h" 27#include "vpdma_priv.h"
@@ -416,6 +417,273 @@ int vpdma_submit_descs(struct vpdma_data *vpdma, struct vpdma_desc_list *list)
416 return 0; 417 return 0;
417} 418}
418 419
420static void dump_cfd(struct vpdma_cfd *cfd)
421{
422 int class;
423
424 class = cfd_get_class(cfd);
425
426 pr_debug("config descriptor of payload class: %s\n",
427 class == CFD_CLS_BLOCK ? "simple block" :
428 "address data block");
429
430 if (class == CFD_CLS_BLOCK)
431 pr_debug("word0: dst_addr_offset = 0x%08x\n",
432 cfd->dest_addr_offset);
433
434 if (class == CFD_CLS_BLOCK)
435 pr_debug("word1: num_data_wrds = %d\n", cfd->block_len);
436
437 pr_debug("word2: payload_addr = 0x%08x\n", cfd->payload_addr);
438
439 pr_debug("word3: pkt_type = %d, direct = %d, class = %d, dest = %d, "
440 "payload_len = %d\n", cfd_get_pkt_type(cfd),
441 cfd_get_direct(cfd), class, cfd_get_dest(cfd),
442 cfd_get_payload_len(cfd));
443}
444
445/*
446 * append a configuration descriptor to the given descriptor list, where the
447 * payload is in the form of a simple data block specified in the descriptor
448 * header, this is used to upload scaler coefficients to the scaler module
449 */
450void vpdma_add_cfd_block(struct vpdma_desc_list *list, int client,
451 struct vpdma_buf *blk, u32 dest_offset)
452{
453 struct vpdma_cfd *cfd;
454 int len = blk->size;
455
456 WARN_ON(blk->dma_addr & VPDMA_DESC_ALIGN);
457
458 cfd = list->next;
459 WARN_ON((void *)(cfd + 1) > (list->buf.addr + list->buf.size));
460
461 cfd->dest_addr_offset = dest_offset;
462 cfd->block_len = len;
463 cfd->payload_addr = (u32) blk->dma_addr;
464 cfd->ctl_payload_len = cfd_pkt_payload_len(CFD_INDIRECT, CFD_CLS_BLOCK,
465 client, len >> 4);
466
467 list->next = cfd + 1;
468
469 dump_cfd(cfd);
470}
471
472/*
473 * append a configuration descriptor to the given descriptor list, where the
474 * payload is in the address data block format, this is used to a configure a
475 * discontiguous set of MMRs
476 */
477void vpdma_add_cfd_adb(struct vpdma_desc_list *list, int client,
478 struct vpdma_buf *adb)
479{
480 struct vpdma_cfd *cfd;
481 unsigned int len = adb->size;
482
483 WARN_ON(len & VPDMA_ADB_SIZE_ALIGN);
484 WARN_ON(adb->dma_addr & VPDMA_DESC_ALIGN);
485
486 cfd = list->next;
487 BUG_ON((void *)(cfd + 1) > (list->buf.addr + list->buf.size));
488
489 cfd->w0 = 0;
490 cfd->w1 = 0;
491 cfd->payload_addr = (u32) adb->dma_addr;
492 cfd->ctl_payload_len = cfd_pkt_payload_len(CFD_INDIRECT, CFD_CLS_ADB,
493 client, len >> 4);
494
495 list->next = cfd + 1;
496
497 dump_cfd(cfd);
498};
499
500/*
501 * control descriptor format change based on what type of control descriptor it
502 * is, we only use 'sync on channel' control descriptors for now, so assume it's
503 * that
504 */
505static void dump_ctd(struct vpdma_ctd *ctd)
506{
507 pr_debug("control descriptor\n");
508
509 pr_debug("word3: pkt_type = %d, source = %d, ctl_type = %d\n",
510 ctd_get_pkt_type(ctd), ctd_get_source(ctd), ctd_get_ctl(ctd));
511}
512
513/*
514 * append a 'sync on channel' type control descriptor to the given descriptor
515 * list, this descriptor stalls the VPDMA list till the time DMA is completed
516 * on the specified channel
517 */
518void vpdma_add_sync_on_channel_ctd(struct vpdma_desc_list *list,
519 enum vpdma_channel chan)
520{
521 struct vpdma_ctd *ctd;
522
523 ctd = list->next;
524 WARN_ON((void *)(ctd + 1) > (list->buf.addr + list->buf.size));
525
526 ctd->w0 = 0;
527 ctd->w1 = 0;
528 ctd->w2 = 0;
529 ctd->type_source_ctl = ctd_type_source_ctl(chan_info[chan].num,
530 CTD_TYPE_SYNC_ON_CHANNEL);
531
532 list->next = ctd + 1;
533
534 dump_ctd(ctd);
535}
536
537static void dump_dtd(struct vpdma_dtd *dtd)
538{
539 int dir, chan;
540
541 dir = dtd_get_dir(dtd);
542 chan = dtd_get_chan(dtd);
543
544 pr_debug("%s data transfer descriptor for channel %d\n",
545 dir == DTD_DIR_OUT ? "outbound" : "inbound", chan);
546
547 pr_debug("word0: data_type = %d, notify = %d, field = %d, 1D = %d, "
548 "even_ln_skp = %d, odd_ln_skp = %d, line_stride = %d\n",
549 dtd_get_data_type(dtd), dtd_get_notify(dtd), dtd_get_field(dtd),
550 dtd_get_1d(dtd), dtd_get_even_line_skip(dtd),
551 dtd_get_odd_line_skip(dtd), dtd_get_line_stride(dtd));
552
553 if (dir == DTD_DIR_IN)
554 pr_debug("word1: line_length = %d, xfer_height = %d\n",
555 dtd_get_line_length(dtd), dtd_get_xfer_height(dtd));
556
557 pr_debug("word2: start_addr = 0x%08x\n", dtd->start_addr);
558
559 pr_debug("word3: pkt_type = %d, mode = %d, dir = %d, chan = %d, "
560 "pri = %d, next_chan = %d\n", dtd_get_pkt_type(dtd),
561 dtd_get_mode(dtd), dir, chan, dtd_get_priority(dtd),
562 dtd_get_next_chan(dtd));
563
564 if (dir == DTD_DIR_IN)
565 pr_debug("word4: frame_width = %d, frame_height = %d\n",
566 dtd_get_frame_width(dtd), dtd_get_frame_height(dtd));
567 else
568 pr_debug("word4: desc_write_addr = 0x%08x, write_desc = %d, "
569 "drp_data = %d, use_desc_reg = %d\n",
570 dtd_get_desc_write_addr(dtd), dtd_get_write_desc(dtd),
571 dtd_get_drop_data(dtd), dtd_get_use_desc(dtd));
572
573 if (dir == DTD_DIR_IN)
574 pr_debug("word5: hor_start = %d, ver_start = %d\n",
575 dtd_get_h_start(dtd), dtd_get_v_start(dtd));
576 else
577 pr_debug("word5: max_width %d, max_height %d\n",
578 dtd_get_max_width(dtd), dtd_get_max_height(dtd));
579
580 pr_debug("word6: client specfic attr0 = 0x%08x\n", dtd->client_attr0);
581 pr_debug("word7: client specfic attr1 = 0x%08x\n", dtd->client_attr1);
582}
583
584/*
585 * append an outbound data transfer descriptor to the given descriptor list,
586 * this sets up a 'client to memory' VPDMA transfer for the given VPDMA channel
587 */
588void vpdma_add_out_dtd(struct vpdma_desc_list *list, struct v4l2_rect *c_rect,
589 const struct vpdma_data_format *fmt, dma_addr_t dma_addr,
590 enum vpdma_channel chan, u32 flags)
591{
592 int priority = 0;
593 int field = 0;
594 int notify = 1;
595 int channel, next_chan;
596 int depth = fmt->depth;
597 int stride;
598 struct vpdma_dtd *dtd;
599
600 channel = next_chan = chan_info[chan].num;
601
602 if (fmt->data_type == DATA_TYPE_C420)
603 depth = 8;
604
605 stride = (depth * c_rect->width) >> 3;
606 dma_addr += (c_rect->left * depth) >> 3;
607
608 dtd = list->next;
609 WARN_ON((void *)(dtd + 1) > (list->buf.addr + list->buf.size));
610
611 dtd->type_ctl_stride = dtd_type_ctl_stride(fmt->data_type,
612 notify,
613 field,
614 !!(flags & VPDMA_DATA_FRAME_1D),
615 !!(flags & VPDMA_DATA_EVEN_LINE_SKIP),
616 !!(flags & VPDMA_DATA_ODD_LINE_SKIP),
617 stride);
618 dtd->w1 = 0;
619 dtd->start_addr = (u32) dma_addr;
620 dtd->pkt_ctl = dtd_pkt_ctl(!!(flags & VPDMA_DATA_MODE_TILED),
621 DTD_DIR_OUT, channel, priority, next_chan);
622 dtd->desc_write_addr = dtd_desc_write_addr(0, 0, 0, 0);
623 dtd->max_width_height = dtd_max_width_height(MAX_OUT_WIDTH_1920,
624 MAX_OUT_HEIGHT_1080);
625 dtd->client_attr0 = 0;
626 dtd->client_attr1 = 0;
627
628 list->next = dtd + 1;
629
630 dump_dtd(dtd);
631}
632
633/*
634 * append an inbound data transfer descriptor to the given descriptor list,
635 * this sets up a 'memory to client' VPDMA transfer for the given VPDMA channel
636 */
637void vpdma_add_in_dtd(struct vpdma_desc_list *list, int frame_width,
638 int frame_height, struct v4l2_rect *c_rect,
639 const struct vpdma_data_format *fmt, dma_addr_t dma_addr,
640 enum vpdma_channel chan, int field, u32 flags)
641{
642 int priority = 0;
643 int notify = 1;
644 int depth = fmt->depth;
645 int channel, next_chan;
646 int stride;
647 int height = c_rect->height;
648 struct vpdma_dtd *dtd;
649
650 channel = next_chan = chan_info[chan].num;
651
652 if (fmt->data_type == DATA_TYPE_C420) {
653 height >>= 1;
654 frame_height >>= 1;
655 depth = 8;
656 }
657
658 stride = (depth * c_rect->width) >> 3;
659 dma_addr += (c_rect->left * depth) >> 3;
660
661 dtd = list->next;
662 WARN_ON((void *)(dtd + 1) > (list->buf.addr + list->buf.size));
663
664 dtd->type_ctl_stride = dtd_type_ctl_stride(fmt->data_type,
665 notify,
666 field,
667 !!(flags & VPDMA_DATA_FRAME_1D),
668 !!(flags & VPDMA_DATA_EVEN_LINE_SKIP),
669 !!(flags & VPDMA_DATA_ODD_LINE_SKIP),
670 stride);
671
672 dtd->xfer_length_height = dtd_xfer_length_height(c_rect->width, height);
673 dtd->start_addr = (u32) dma_addr;
674 dtd->pkt_ctl = dtd_pkt_ctl(!!(flags & VPDMA_DATA_MODE_TILED),
675 DTD_DIR_IN, channel, priority, next_chan);
676 dtd->frame_width_height = dtd_frame_width_height(frame_width,
677 frame_height);
678 dtd->start_h_v = dtd_start_h_v(c_rect->left, c_rect->top);
679 dtd->client_attr0 = 0;
680 dtd->client_attr1 = 0;
681
682 list->next = dtd + 1;
683
684 dump_dtd(dtd);
685}
686
419/* set or clear the mask for list complete interrupt */ 687/* set or clear the mask for list complete interrupt */
420void vpdma_enable_list_complete_irq(struct vpdma_data *vpdma, int list_num, 688void vpdma_enable_list_complete_irq(struct vpdma_data *vpdma, int list_num,
421 bool enable) 689 bool enable)
diff --git a/drivers/media/platform/ti-vpe/vpdma.h b/drivers/media/platform/ti-vpe/vpdma.h
index 80566892c6cb..eaa2a71a5db9 100644
--- a/drivers/media/platform/ti-vpe/vpdma.h
+++ b/drivers/media/platform/ti-vpe/vpdma.h
@@ -124,6 +124,39 @@ enum vpdma_channel {
124 VPE_CHAN_RGB_OUT, 124 VPE_CHAN_RGB_OUT,
125}; 125};
126 126
127/* flags for VPDMA data descriptors */
128#define VPDMA_DATA_ODD_LINE_SKIP (1 << 0)
129#define VPDMA_DATA_EVEN_LINE_SKIP (1 << 1)
130#define VPDMA_DATA_FRAME_1D (1 << 2)
131#define VPDMA_DATA_MODE_TILED (1 << 3)
132
133/*
134 * client identifiers used for configuration descriptors
135 */
136#define CFD_MMR_CLIENT 0
137#define CFD_SC_CLIENT 4
138
139/* Address data block header format */
140struct vpdma_adb_hdr {
141 u32 offset;
142 u32 nwords;
143 u32 reserved0;
144 u32 reserved1;
145};
146
147/* helpers for creating ADB headers for config descriptors MMRs as client */
148#define ADB_ADDR(dma_buf, str, fld) ((dma_buf)->addr + offsetof(str, fld))
149#define MMR_ADB_ADDR(buf, str, fld) ADB_ADDR(&(buf), struct str, fld)
150
151#define VPDMA_SET_MMR_ADB_HDR(buf, str, hdr, regs, offset_a) \
152 do { \
153 struct vpdma_adb_hdr *h; \
154 struct str *adb = NULL; \
155 h = MMR_ADB_ADDR(buf, str, hdr); \
156 h->offset = (offset_a); \
157 h->nwords = sizeof(adb->regs) >> 2; \
158 } while (0)
159
127/* vpdma descriptor buffer allocation and management */ 160/* vpdma descriptor buffer allocation and management */
128int vpdma_alloc_desc_buf(struct vpdma_buf *buf, size_t size); 161int vpdma_alloc_desc_buf(struct vpdma_buf *buf, size_t size);
129void vpdma_free_desc_buf(struct vpdma_buf *buf); 162void vpdma_free_desc_buf(struct vpdma_buf *buf);
@@ -136,6 +169,21 @@ void vpdma_reset_desc_list(struct vpdma_desc_list *list);
136void vpdma_free_desc_list(struct vpdma_desc_list *list); 169void vpdma_free_desc_list(struct vpdma_desc_list *list);
137int vpdma_submit_descs(struct vpdma_data *vpdma, struct vpdma_desc_list *list); 170int vpdma_submit_descs(struct vpdma_data *vpdma, struct vpdma_desc_list *list);
138 171
172/* helpers for creating vpdma descriptors */
173void vpdma_add_cfd_block(struct vpdma_desc_list *list, int client,
174 struct vpdma_buf *blk, u32 dest_offset);
175void vpdma_add_cfd_adb(struct vpdma_desc_list *list, int client,
176 struct vpdma_buf *adb);
177void vpdma_add_sync_on_channel_ctd(struct vpdma_desc_list *list,
178 enum vpdma_channel chan);
179void vpdma_add_out_dtd(struct vpdma_desc_list *list, struct v4l2_rect *c_rect,
180 const struct vpdma_data_format *fmt, dma_addr_t dma_addr,
181 enum vpdma_channel chan, u32 flags);
182void vpdma_add_in_dtd(struct vpdma_desc_list *list, int frame_width,
183 int frame_height, struct v4l2_rect *c_rect,
184 const struct vpdma_data_format *fmt, dma_addr_t dma_addr,
185 enum vpdma_channel chan, int field, u32 flags);
186
139/* vpdma list interrupt management */ 187/* vpdma list interrupt management */
140void vpdma_enable_list_complete_irq(struct vpdma_data *vpdma, int list_num, 188void vpdma_enable_list_complete_irq(struct vpdma_data *vpdma, int list_num,
141 bool enable); 189 bool enable);
diff --git a/drivers/media/platform/ti-vpe/vpdma_priv.h b/drivers/media/platform/ti-vpe/vpdma_priv.h
index 8ff51a3cfd95..f0e9a8038c1b 100644
--- a/drivers/media/platform/ti-vpe/vpdma_priv.h
+++ b/drivers/media/platform/ti-vpe/vpdma_priv.h
@@ -116,4 +116,526 @@
116#define VPE_CHAN_NUM_CHROMA_OUT 103 116#define VPE_CHAN_NUM_CHROMA_OUT 103
117#define VPE_CHAN_NUM_RGB_OUT 106 117#define VPE_CHAN_NUM_RGB_OUT 106
118 118
119/*
120 * a VPDMA address data block payload for a configuration descriptor needs to
121 * have each sub block length as a multiple of 16 bytes. Therefore, the overall
122 * size of the payload also needs to be a multiple of 16 bytes. The sub block
123 * lengths should be ensured to be aligned by the VPDMA user.
124 */
125#define VPDMA_ADB_SIZE_ALIGN 0x0f
126
127/*
128 * data transfer descriptor
129 */
130struct vpdma_dtd {
131 u32 type_ctl_stride;
132 union {
133 u32 xfer_length_height;
134 u32 w1;
135 };
136 dma_addr_t start_addr;
137 u32 pkt_ctl;
138 union {
139 u32 frame_width_height; /* inbound */
140 dma_addr_t desc_write_addr; /* outbound */
141 };
142 union {
143 u32 start_h_v; /* inbound */
144 u32 max_width_height; /* outbound */
145 };
146 u32 client_attr0;
147 u32 client_attr1;
148};
149
150/* Data Transfer Descriptor specifics */
151#define DTD_NO_NOTIFY 0
152#define DTD_NOTIFY 1
153
154#define DTD_PKT_TYPE 0xa
155#define DTD_DIR_IN 0
156#define DTD_DIR_OUT 1
157
158/* type_ctl_stride */
159#define DTD_DATA_TYPE_MASK 0x3f
160#define DTD_DATA_TYPE_SHFT 26
161#define DTD_NOTIFY_MASK 0x01
162#define DTD_NOTIFY_SHFT 25
163#define DTD_FIELD_MASK 0x01
164#define DTD_FIELD_SHFT 24
165#define DTD_1D_MASK 0x01
166#define DTD_1D_SHFT 23
167#define DTD_EVEN_LINE_SKIP_MASK 0x01
168#define DTD_EVEN_LINE_SKIP_SHFT 20
169#define DTD_ODD_LINE_SKIP_MASK 0x01
170#define DTD_ODD_LINE_SKIP_SHFT 16
171#define DTD_LINE_STRIDE_MASK 0xffff
172#define DTD_LINE_STRIDE_SHFT 0
173
174/* xfer_length_height */
175#define DTD_LINE_LENGTH_MASK 0xffff
176#define DTD_LINE_LENGTH_SHFT 16
177#define DTD_XFER_HEIGHT_MASK 0xffff
178#define DTD_XFER_HEIGHT_SHFT 0
179
180/* pkt_ctl */
181#define DTD_PKT_TYPE_MASK 0x1f
182#define DTD_PKT_TYPE_SHFT 27
183#define DTD_MODE_MASK 0x01
184#define DTD_MODE_SHFT 26
185#define DTD_DIR_MASK 0x01
186#define DTD_DIR_SHFT 25
187#define DTD_CHAN_MASK 0x01ff
188#define DTD_CHAN_SHFT 16
189#define DTD_PRI_MASK 0x0f
190#define DTD_PRI_SHFT 9
191#define DTD_NEXT_CHAN_MASK 0x01ff
192#define DTD_NEXT_CHAN_SHFT 0
193
194/* frame_width_height */
195#define DTD_FRAME_WIDTH_MASK 0xffff
196#define DTD_FRAME_WIDTH_SHFT 16
197#define DTD_FRAME_HEIGHT_MASK 0xffff
198#define DTD_FRAME_HEIGHT_SHFT 0
199
200/* start_h_v */
201#define DTD_H_START_MASK 0xffff
202#define DTD_H_START_SHFT 16
203#define DTD_V_START_MASK 0xffff
204#define DTD_V_START_SHFT 0
205
206#define DTD_DESC_START_SHIFT 5
207#define DTD_WRITE_DESC_MASK 0x01
208#define DTD_WRITE_DESC_SHIFT 2
209#define DTD_DROP_DATA_MASK 0x01
210#define DTD_DROP_DATA_SHIFT 1
211#define DTD_USE_DESC_MASK 0x01
212#define DTD_USE_DESC_SHIFT 0
213
214/* max_width_height */
215#define DTD_MAX_WIDTH_MASK 0x07
216#define DTD_MAX_WIDTH_SHFT 4
217#define DTD_MAX_HEIGHT_MASK 0x07
218#define DTD_MAX_HEIGHT_SHFT 0
219
220/* max width configurations */
221 /* unlimited width */
222#define MAX_OUT_WIDTH_UNLIMITED 0
223/* as specified in max_size1 reg */
224#define MAX_OUT_WIDTH_REG1 1
225/* as specified in max_size2 reg */
226#define MAX_OUT_WIDTH_REG2 2
227/* as specified in max_size3 reg */
228#define MAX_OUT_WIDTH_REG3 3
229/* maximum of 352 pixels as width */
230#define MAX_OUT_WIDTH_352 4
231/* maximum of 768 pixels as width */
232#define MAX_OUT_WIDTH_768 5
233/* maximum of 1280 pixels width */
234#define MAX_OUT_WIDTH_1280 6
235/* maximum of 1920 pixels as width */
236#define MAX_OUT_WIDTH_1920 7
237
238/* max height configurations */
239 /* unlimited height */
240#define MAX_OUT_HEIGHT_UNLIMITED 0
241/* as specified in max_size1 reg */
242#define MAX_OUT_HEIGHT_REG1 1
243/* as specified in max_size2 reg */
244#define MAX_OUT_HEIGHT_REG2 2
245/* as specified in max_size3 reg */
246#define MAX_OUT_HEIGHT_REG3 3
247/* maximum of 288 lines as height */
248#define MAX_OUT_HEIGHT_288 4
249/* maximum of 576 lines as height */
250#define MAX_OUT_HEIGHT_576 5
251/* maximum of 720 lines as height */
252#define MAX_OUT_HEIGHT_720 6
253/* maximum of 1080 lines as height */
254#define MAX_OUT_HEIGHT_1080 7
255
256static inline u32 dtd_type_ctl_stride(int type, bool notify, int field,
257 bool one_d, bool even_line_skip, bool odd_line_skip,
258 int line_stride)
259{
260 return (type << DTD_DATA_TYPE_SHFT) | (notify << DTD_NOTIFY_SHFT) |
261 (field << DTD_FIELD_SHFT) | (one_d << DTD_1D_SHFT) |
262 (even_line_skip << DTD_EVEN_LINE_SKIP_SHFT) |
263 (odd_line_skip << DTD_ODD_LINE_SKIP_SHFT) |
264 line_stride;
265}
266
267static inline u32 dtd_xfer_length_height(int line_length, int xfer_height)
268{
269 return (line_length << DTD_LINE_LENGTH_SHFT) | xfer_height;
270}
271
272static inline u32 dtd_pkt_ctl(bool mode, bool dir, int chan, int pri,
273 int next_chan)
274{
275 return (DTD_PKT_TYPE << DTD_PKT_TYPE_SHFT) | (mode << DTD_MODE_SHFT) |
276 (dir << DTD_DIR_SHFT) | (chan << DTD_CHAN_SHFT) |
277 (pri << DTD_PRI_SHFT) | next_chan;
278}
279
280static inline u32 dtd_frame_width_height(int width, int height)
281{
282 return (width << DTD_FRAME_WIDTH_SHFT) | height;
283}
284
285static inline u32 dtd_desc_write_addr(unsigned int addr, bool write_desc,
286 bool drop_data, bool use_desc)
287{
288 return (addr << DTD_DESC_START_SHIFT) |
289 (write_desc << DTD_WRITE_DESC_SHIFT) |
290 (drop_data << DTD_DROP_DATA_SHIFT) |
291 use_desc;
292}
293
294static inline u32 dtd_start_h_v(int h_start, int v_start)
295{
296 return (h_start << DTD_H_START_SHFT) | v_start;
297}
298
299static inline u32 dtd_max_width_height(int max_width, int max_height)
300{
301 return (max_width << DTD_MAX_WIDTH_SHFT) | max_height;
302}
303
304static inline int dtd_get_data_type(struct vpdma_dtd *dtd)
305{
306 return dtd->type_ctl_stride >> DTD_DATA_TYPE_SHFT;
307}
308
309static inline bool dtd_get_notify(struct vpdma_dtd *dtd)
310{
311 return (dtd->type_ctl_stride >> DTD_NOTIFY_SHFT) & DTD_NOTIFY_MASK;
312}
313
314static inline int dtd_get_field(struct vpdma_dtd *dtd)
315{
316 return (dtd->type_ctl_stride >> DTD_FIELD_SHFT) & DTD_FIELD_MASK;
317}
318
319static inline bool dtd_get_1d(struct vpdma_dtd *dtd)
320{
321 return (dtd->type_ctl_stride >> DTD_1D_SHFT) & DTD_1D_MASK;
322}
323
324static inline bool dtd_get_even_line_skip(struct vpdma_dtd *dtd)
325{
326 return (dtd->type_ctl_stride >> DTD_EVEN_LINE_SKIP_SHFT)
327 & DTD_EVEN_LINE_SKIP_MASK;
328}
329
330static inline bool dtd_get_odd_line_skip(struct vpdma_dtd *dtd)
331{
332 return (dtd->type_ctl_stride >> DTD_ODD_LINE_SKIP_SHFT)
333 & DTD_ODD_LINE_SKIP_MASK;
334}
335
336static inline int dtd_get_line_stride(struct vpdma_dtd *dtd)
337{
338 return dtd->type_ctl_stride & DTD_LINE_STRIDE_MASK;
339}
340
341static inline int dtd_get_line_length(struct vpdma_dtd *dtd)
342{
343 return dtd->xfer_length_height >> DTD_LINE_LENGTH_SHFT;
344}
345
346static inline int dtd_get_xfer_height(struct vpdma_dtd *dtd)
347{
348 return dtd->xfer_length_height & DTD_XFER_HEIGHT_MASK;
349}
350
351static inline int dtd_get_pkt_type(struct vpdma_dtd *dtd)
352{
353 return dtd->pkt_ctl >> DTD_PKT_TYPE_SHFT;
354}
355
356static inline bool dtd_get_mode(struct vpdma_dtd *dtd)
357{
358 return (dtd->pkt_ctl >> DTD_MODE_SHFT) & DTD_MODE_MASK;
359}
360
361static inline bool dtd_get_dir(struct vpdma_dtd *dtd)
362{
363 return (dtd->pkt_ctl >> DTD_DIR_SHFT) & DTD_DIR_MASK;
364}
365
366static inline int dtd_get_chan(struct vpdma_dtd *dtd)
367{
368 return (dtd->pkt_ctl >> DTD_CHAN_SHFT) & DTD_CHAN_MASK;
369}
370
371static inline int dtd_get_priority(struct vpdma_dtd *dtd)
372{
373 return (dtd->pkt_ctl >> DTD_PRI_SHFT) & DTD_PRI_MASK;
374}
375
376static inline int dtd_get_next_chan(struct vpdma_dtd *dtd)
377{
378 return (dtd->pkt_ctl >> DTD_NEXT_CHAN_SHFT) & DTD_NEXT_CHAN_MASK;
379}
380
381static inline int dtd_get_frame_width(struct vpdma_dtd *dtd)
382{
383 return dtd->frame_width_height >> DTD_FRAME_WIDTH_SHFT;
384}
385
386static inline int dtd_get_frame_height(struct vpdma_dtd *dtd)
387{
388 return dtd->frame_width_height & DTD_FRAME_HEIGHT_MASK;
389}
390
391static inline int dtd_get_desc_write_addr(struct vpdma_dtd *dtd)
392{
393 return dtd->desc_write_addr >> DTD_DESC_START_SHIFT;
394}
395
396static inline bool dtd_get_write_desc(struct vpdma_dtd *dtd)
397{
398 return (dtd->desc_write_addr >> DTD_WRITE_DESC_SHIFT) &
399 DTD_WRITE_DESC_MASK;
400}
401
402static inline bool dtd_get_drop_data(struct vpdma_dtd *dtd)
403{
404 return (dtd->desc_write_addr >> DTD_DROP_DATA_SHIFT) &
405 DTD_DROP_DATA_MASK;
406}
407
408static inline bool dtd_get_use_desc(struct vpdma_dtd *dtd)
409{
410 return dtd->desc_write_addr & DTD_USE_DESC_MASK;
411}
412
413static inline int dtd_get_h_start(struct vpdma_dtd *dtd)
414{
415 return dtd->start_h_v >> DTD_H_START_SHFT;
416}
417
418static inline int dtd_get_v_start(struct vpdma_dtd *dtd)
419{
420 return dtd->start_h_v & DTD_V_START_MASK;
421}
422
423static inline int dtd_get_max_width(struct vpdma_dtd *dtd)
424{
425 return (dtd->max_width_height >> DTD_MAX_WIDTH_SHFT) &
426 DTD_MAX_WIDTH_MASK;
427}
428
429static inline int dtd_get_max_height(struct vpdma_dtd *dtd)
430{
431 return (dtd->max_width_height >> DTD_MAX_HEIGHT_SHFT) &
432 DTD_MAX_HEIGHT_MASK;
433}
434
435/*
436 * configuration descriptor
437 */
438struct vpdma_cfd {
439 union {
440 u32 dest_addr_offset;
441 u32 w0;
442 };
443 union {
444 u32 block_len; /* in words */
445 u32 w1;
446 };
447 u32 payload_addr;
448 u32 ctl_payload_len; /* in words */
449};
450
451/* Configuration descriptor specifics */
452
453#define CFD_PKT_TYPE 0xb
454
455#define CFD_DIRECT 1
456#define CFD_INDIRECT 0
457#define CFD_CLS_ADB 0
458#define CFD_CLS_BLOCK 1
459
460/* block_len */
461#define CFD__BLOCK_LEN_MASK 0xffff
462#define CFD__BLOCK_LEN_SHFT 0
463
464/* ctl_payload_len */
465#define CFD_PKT_TYPE_MASK 0x1f
466#define CFD_PKT_TYPE_SHFT 27
467#define CFD_DIRECT_MASK 0x01
468#define CFD_DIRECT_SHFT 26
469#define CFD_CLASS_MASK 0x03
470#define CFD_CLASS_SHFT 24
471#define CFD_DEST_MASK 0xff
472#define CFD_DEST_SHFT 16
473#define CFD_PAYLOAD_LEN_MASK 0xffff
474#define CFD_PAYLOAD_LEN_SHFT 0
475
476static inline u32 cfd_pkt_payload_len(bool direct, int cls, int dest,
477 int payload_len)
478{
479 return (CFD_PKT_TYPE << CFD_PKT_TYPE_SHFT) |
480 (direct << CFD_DIRECT_SHFT) |
481 (cls << CFD_CLASS_SHFT) |
482 (dest << CFD_DEST_SHFT) |
483 payload_len;
484}
485
486static inline int cfd_get_pkt_type(struct vpdma_cfd *cfd)
487{
488 return cfd->ctl_payload_len >> CFD_PKT_TYPE_SHFT;
489}
490
491static inline bool cfd_get_direct(struct vpdma_cfd *cfd)
492{
493 return (cfd->ctl_payload_len >> CFD_DIRECT_SHFT) & CFD_DIRECT_MASK;
494}
495
496static inline bool cfd_get_class(struct vpdma_cfd *cfd)
497{
498 return (cfd->ctl_payload_len >> CFD_CLASS_SHFT) & CFD_CLASS_MASK;
499}
500
501static inline int cfd_get_dest(struct vpdma_cfd *cfd)
502{
503 return (cfd->ctl_payload_len >> CFD_DEST_SHFT) & CFD_DEST_MASK;
504}
505
506static inline int cfd_get_payload_len(struct vpdma_cfd *cfd)
507{
508 return cfd->ctl_payload_len & CFD_PAYLOAD_LEN_MASK;
509}
510
511/*
512 * control descriptor
513 */
514struct vpdma_ctd {
515 union {
516 u32 timer_value;
517 u32 list_addr;
518 u32 w0;
519 };
520 union {
521 u32 pixel_line_count;
522 u32 list_size;
523 u32 w1;
524 };
525 union {
526 u32 event;
527 u32 fid_ctl;
528 u32 w2;
529 };
530 u32 type_source_ctl;
531};
532
533/* control descriptor types */
534#define CTD_TYPE_SYNC_ON_CLIENT 0
535#define CTD_TYPE_SYNC_ON_LIST 1
536#define CTD_TYPE_SYNC_ON_EXT 2
537#define CTD_TYPE_SYNC_ON_LM_TIMER 3
538#define CTD_TYPE_SYNC_ON_CHANNEL 4
539#define CTD_TYPE_CHNG_CLIENT_IRQ 5
540#define CTD_TYPE_SEND_IRQ 6
541#define CTD_TYPE_RELOAD_LIST 7
542#define CTD_TYPE_ABORT_CHANNEL 8
543
544#define CTD_PKT_TYPE 0xc
545
546/* timer_value */
547#define CTD_TIMER_VALUE_MASK 0xffff
548#define CTD_TIMER_VALUE_SHFT 0
549
550/* pixel_line_count */
551#define CTD_PIXEL_COUNT_MASK 0xffff
552#define CTD_PIXEL_COUNT_SHFT 16
553#define CTD_LINE_COUNT_MASK 0xffff
554#define CTD_LINE_COUNT_SHFT 0
555
556/* list_size */
557#define CTD_LIST_SIZE_MASK 0xffff
558#define CTD_LIST_SIZE_SHFT 0
559
560/* event */
561#define CTD_EVENT_MASK 0x0f
562#define CTD_EVENT_SHFT 0
563
564/* fid_ctl */
565#define CTD_FID2_MASK 0x03
566#define CTD_FID2_SHFT 4
567#define CTD_FID1_MASK 0x03
568#define CTD_FID1_SHFT 2
569#define CTD_FID0_MASK 0x03
570#define CTD_FID0_SHFT 0
571
572/* type_source_ctl */
573#define CTD_PKT_TYPE_MASK 0x1f
574#define CTD_PKT_TYPE_SHFT 27
575#define CTD_SOURCE_MASK 0xff
576#define CTD_SOURCE_SHFT 16
577#define CTD_CONTROL_MASK 0x0f
578#define CTD_CONTROL_SHFT 0
579
580static inline u32 ctd_pixel_line_count(int pixel_count, int line_count)
581{
582 return (pixel_count << CTD_PIXEL_COUNT_SHFT) | line_count;
583}
584
585static inline u32 ctd_set_fid_ctl(int fid0, int fid1, int fid2)
586{
587 return (fid2 << CTD_FID2_SHFT) | (fid1 << CTD_FID1_SHFT) | fid0;
588}
589
590static inline u32 ctd_type_source_ctl(int source, int control)
591{
592 return (CTD_PKT_TYPE << CTD_PKT_TYPE_SHFT) |
593 (source << CTD_SOURCE_SHFT) | control;
594}
595
596static inline u32 ctd_get_pixel_count(struct vpdma_ctd *ctd)
597{
598 return ctd->pixel_line_count >> CTD_PIXEL_COUNT_SHFT;
599}
600
601static inline int ctd_get_line_count(struct vpdma_ctd *ctd)
602{
603 return ctd->pixel_line_count & CTD_LINE_COUNT_MASK;
604}
605
606static inline int ctd_get_event(struct vpdma_ctd *ctd)
607{
608 return ctd->event & CTD_EVENT_MASK;
609}
610
611static inline int ctd_get_fid2_ctl(struct vpdma_ctd *ctd)
612{
613 return (ctd->fid_ctl >> CTD_FID2_SHFT) & CTD_FID2_MASK;
614}
615
616static inline int ctd_get_fid1_ctl(struct vpdma_ctd *ctd)
617{
618 return (ctd->fid_ctl >> CTD_FID1_SHFT) & CTD_FID1_MASK;
619}
620
621static inline int ctd_get_fid0_ctl(struct vpdma_ctd *ctd)
622{
623 return ctd->fid_ctl & CTD_FID2_MASK;
624}
625
626static inline int ctd_get_pkt_type(struct vpdma_ctd *ctd)
627{
628 return ctd->type_source_ctl >> CTD_PKT_TYPE_SHFT;
629}
630
631static inline int ctd_get_source(struct vpdma_ctd *ctd)
632{
633 return (ctd->type_source_ctl >> CTD_SOURCE_SHFT) & CTD_SOURCE_MASK;
634}
635
636static inline int ctd_get_ctl(struct vpdma_ctd *ctd)
637{
638 return ctd->type_source_ctl & CTD_CONTROL_MASK;
639}
640
119#endif 641#endif