Skip to content

Commit 7d630c4

Browse files
kbinghammchehab
authored andcommitted
media: vsp1: Add support for extended display list headers
Extended display list headers allow pre and post command lists to be executed by the VSP pipeline. This provides the base support for features such as AUTO_FLD (for interlaced support) and AUTO_DISP (for supporting continuous camera preview pipelines. Signed-off-by: Kieran Bingham <[email protected]> Signed-off-by: Laurent Pinchart <[email protected]> Signed-off-by: Mauro Carvalho Chehab <[email protected]>
1 parent 08e41f6 commit 7d630c4

File tree

5 files changed

+133
-4
lines changed

5 files changed

+133
-4
lines changed

drivers/media/platform/vsp1/vsp1.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ struct vsp1_uif;
5353
#define VSP1_HAS_HGO (1 << 7)
5454
#define VSP1_HAS_HGT (1 << 8)
5555
#define VSP1_HAS_BRS (1 << 9)
56+
#define VSP1_HAS_EXT_DL (1 << 10)
5657

5758
struct vsp1_device_info {
5859
u32 version;

drivers/media/platform/vsp1/vsp1_dl.c

Lines changed: 104 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@
2222
#define VSP1_DLH_INT_ENABLE (1 << 1)
2323
#define VSP1_DLH_AUTO_START (1 << 0)
2424

25+
#define VSP1_DLH_EXT_PRE_CMD_EXEC (1 << 9)
26+
#define VSP1_DLH_EXT_POST_CMD_EXEC (1 << 8)
27+
2528
struct vsp1_dl_header_list {
2629
u32 num_bytes;
2730
u32 addr;
@@ -34,11 +37,58 @@ struct vsp1_dl_header {
3437
u32 flags;
3538
} __packed;
3639

40+
/**
41+
* struct vsp1_dl_ext_header - Extended display list header
42+
* @padding: padding zero bytes for alignment
43+
* @pre_ext_dl_num_cmd: number of pre-extended command bodies to parse
44+
* @flags: enables or disables execution of the pre and post command
45+
* @pre_ext_dl_plist: start address of pre-extended display list bodies
46+
* @post_ext_dl_num_cmd: number of post-extended command bodies to parse
47+
* @post_ext_dl_plist: start address of post-extended display list bodies
48+
*/
49+
struct vsp1_dl_ext_header {
50+
u32 padding;
51+
52+
/*
53+
* The datasheet represents flags as stored before pre_ext_dl_num_cmd,
54+
* expecting 32-bit accesses. The flags are appropriate to the whole
55+
* header, not just the pre_ext command, and thus warrant being
56+
* separated out. Due to byte ordering, and representing as 16 bit
57+
* values here, the flags must be positioned after the
58+
* pre_ext_dl_num_cmd.
59+
*/
60+
u16 pre_ext_dl_num_cmd;
61+
u16 flags;
62+
u32 pre_ext_dl_plist;
63+
64+
u32 post_ext_dl_num_cmd;
65+
u32 post_ext_dl_plist;
66+
} __packed;
67+
68+
struct vsp1_dl_header_extended {
69+
struct vsp1_dl_header header;
70+
struct vsp1_dl_ext_header ext;
71+
} __packed;
72+
3773
struct vsp1_dl_entry {
3874
u32 addr;
3975
u32 data;
4076
} __packed;
4177

78+
/**
79+
* struct vsp1_pre_ext_dl_body - Pre Extended Display List Body
80+
* @opcode: Extended display list command operation code
81+
* @flags: Pre-extended command flags. These are specific to each command
82+
* @address_set: Source address set pointer. Must have 16-byte alignment
83+
* @reserved: Zero bits for alignment.
84+
*/
85+
struct vsp1_pre_ext_dl_body {
86+
u32 opcode;
87+
u32 flags;
88+
u32 address_set;
89+
u32 reserved;
90+
} __packed;
91+
4292
/**
4393
* struct vsp1_dl_body - Display list body
4494
* @list: entry in the display list list of bodies
@@ -96,9 +146,12 @@ struct vsp1_dl_body_pool {
96146
* @list: entry in the display list manager lists
97147
* @dlm: the display list manager
98148
* @header: display list header
149+
* @extension: extended display list header. NULL for normal lists
99150
* @dma: DMA address for the header
100151
* @body0: first display list body
101152
* @bodies: list of extra display list bodies
153+
* @pre_cmd: pre command to be issued through extended dl header
154+
* @post_cmd: post command to be issued through extended dl header
102155
* @has_chain: if true, indicates that there's a partition chain
103156
* @chain: entry in the display list partition chain
104157
* @internal: whether the display list is used for internal purpose
@@ -108,11 +161,15 @@ struct vsp1_dl_list {
108161
struct vsp1_dl_manager *dlm;
109162

110163
struct vsp1_dl_header *header;
164+
struct vsp1_dl_ext_header *extension;
111165
dma_addr_t dma;
112166

113167
struct vsp1_dl_body *body0;
114168
struct list_head bodies;
115169

170+
struct vsp1_dl_ext_cmd *pre_cmd;
171+
struct vsp1_dl_ext_cmd *post_cmd;
172+
116173
bool has_chain;
117174
struct list_head chain;
118175

@@ -496,6 +553,14 @@ int vsp1_dl_list_add_chain(struct vsp1_dl_list *head,
496553
return 0;
497554
}
498555

556+
static void vsp1_dl_ext_cmd_fill_header(struct vsp1_dl_ext_cmd *cmd)
557+
{
558+
cmd->cmds[0].opcode = cmd->opcode;
559+
cmd->cmds[0].flags = cmd->flags;
560+
cmd->cmds[0].address_set = cmd->data_dma;
561+
cmd->cmds[0].reserved = 0;
562+
}
563+
499564
static void vsp1_dl_list_fill_header(struct vsp1_dl_list *dl, bool is_last)
500565
{
501566
struct vsp1_dl_manager *dlm = dl->dlm;
@@ -548,6 +613,27 @@ static void vsp1_dl_list_fill_header(struct vsp1_dl_list *dl, bool is_last)
548613
*/
549614
dl->header->flags = VSP1_DLH_INT_ENABLE;
550615
}
616+
617+
if (!dl->extension)
618+
return;
619+
620+
dl->extension->flags = 0;
621+
622+
if (dl->pre_cmd) {
623+
dl->extension->pre_ext_dl_plist = dl->pre_cmd->cmd_dma;
624+
dl->extension->pre_ext_dl_num_cmd = dl->pre_cmd->num_cmds;
625+
dl->extension->flags |= VSP1_DLH_EXT_PRE_CMD_EXEC;
626+
627+
vsp1_dl_ext_cmd_fill_header(dl->pre_cmd);
628+
}
629+
630+
if (dl->post_cmd) {
631+
dl->extension->post_ext_dl_plist = dl->post_cmd->cmd_dma;
632+
dl->extension->post_ext_dl_num_cmd = dl->post_cmd->num_cmds;
633+
dl->extension->flags |= VSP1_DLH_EXT_POST_CMD_EXEC;
634+
635+
vsp1_dl_ext_cmd_fill_header(dl->post_cmd);
636+
}
551637
}
552638

553639
static bool vsp1_dl_list_hw_update_pending(struct vsp1_dl_manager *dlm)
@@ -737,9 +823,17 @@ unsigned int vsp1_dlm_irq_frame_end(struct vsp1_dl_manager *dlm)
737823
/* Hardware Setup */
738824
void vsp1_dlm_setup(struct vsp1_device *vsp1)
739825
{
826+
unsigned int i;
740827
u32 ctrl = (256 << VI6_DL_CTRL_AR_WAIT_SHIFT)
741828
| VI6_DL_CTRL_DC2 | VI6_DL_CTRL_DC1 | VI6_DL_CTRL_DC0
742829
| VI6_DL_CTRL_DLE;
830+
u32 ext_dl = (0x02 << VI6_DL_EXT_CTRL_POLINT_SHIFT)
831+
| VI6_DL_EXT_CTRL_DLPRI | VI6_DL_EXT_CTRL_EXT;
832+
833+
if (vsp1_feature(vsp1, VSP1_HAS_EXT_DL)) {
834+
for (i = 0; i < vsp1->info->wpf_count; ++i)
835+
vsp1_write(vsp1, VI6_DL_EXT_CTRL(i), ext_dl);
836+
}
743837

744838
vsp1_write(vsp1, VI6_DL_CTRL, ctrl);
745839
vsp1_write(vsp1, VI6_DL_SWAP, VI6_DL_SWAP_LWS);
@@ -793,7 +887,11 @@ struct vsp1_dl_manager *vsp1_dlm_create(struct vsp1_device *vsp1,
793887
* memory. An extra body is allocated on top of the prealloc to account
794888
* for the cached body used by the vsp1_pipeline object.
795889
*/
796-
header_size = ALIGN(sizeof(struct vsp1_dl_header), 8);
890+
header_size = vsp1_feature(vsp1, VSP1_HAS_EXT_DL) ?
891+
sizeof(struct vsp1_dl_header_extended) :
892+
sizeof(struct vsp1_dl_header);
893+
894+
header_size = ALIGN(header_size, 8);
797895

798896
dlm->pool = vsp1_dl_body_pool_create(vsp1, prealloc + 1,
799897
VSP1_DL_NUM_ENTRIES, header_size);
@@ -809,6 +907,11 @@ struct vsp1_dl_manager *vsp1_dlm_create(struct vsp1_device *vsp1,
809907
return NULL;
810908
}
811909

910+
/* The extended header immediately follows the header. */
911+
if (vsp1_feature(vsp1, VSP1_HAS_EXT_DL))
912+
dl->extension = (void *)dl->header
913+
+ sizeof(*dl->header);
914+
812915
list_add_tail(&dl->list, &dlm->free);
813916
}
814917

drivers/media/platform/vsp1/vsp1_dl.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,31 @@ struct vsp1_dl_manager;
2020
#define VSP1_DL_FRAME_END_COMPLETED BIT(0)
2121
#define VSP1_DL_FRAME_END_INTERNAL BIT(1)
2222

23+
/**
24+
* struct vsp1_dl_ext_cmd - Extended Display command
25+
* @free: entry in the pool of free commands list
26+
* @opcode: command type opcode
27+
* @flags: flags used by the command
28+
* @cmds: array of command bodies for this extended cmd
29+
* @num_cmds: quantity of commands in @cmds array
30+
* @cmd_dma: DMA address of the command body
31+
* @data: memory allocation for command-specific data
32+
* @data_dma: DMA address for command-specific data
33+
*/
34+
struct vsp1_dl_ext_cmd {
35+
struct list_head free;
36+
37+
u8 opcode;
38+
u32 flags;
39+
40+
struct vsp1_pre_ext_dl_body *cmds;
41+
unsigned int num_cmds;
42+
dma_addr_t cmd_dma;
43+
44+
void *data;
45+
dma_addr_t data_dma;
46+
};
47+
2348
void vsp1_dlm_setup(struct vsp1_device *vsp1);
2449

2550
struct vsp1_dl_manager *vsp1_dlm_create(struct vsp1_device *vsp1,

drivers/media/platform/vsp1/vsp1_drv.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -754,7 +754,7 @@ static const struct vsp1_device_info vsp1_device_infos[] = {
754754
.version = VI6_IP_VERSION_MODEL_VSPD_GEN3,
755755
.model = "VSP2-D",
756756
.gen = 3,
757-
.features = VSP1_HAS_BRU | VSP1_HAS_WPF_VFLIP,
757+
.features = VSP1_HAS_BRU | VSP1_HAS_WPF_VFLIP | VSP1_HAS_EXT_DL,
758758
.lif_count = 1,
759759
.rpf_count = 5,
760760
.uif_count = 1,
@@ -774,7 +774,7 @@ static const struct vsp1_device_info vsp1_device_infos[] = {
774774
.version = VI6_IP_VERSION_MODEL_VSPDL_GEN3,
775775
.model = "VSP2-DL",
776776
.gen = 3,
777-
.features = VSP1_HAS_BRS | VSP1_HAS_BRU,
777+
.features = VSP1_HAS_BRS | VSP1_HAS_BRU | VSP1_HAS_EXT_DL,
778778
.lif_count = 2,
779779
.rpf_count = 5,
780780
.uif_count = 2,

drivers/media/platform/vsp1/vsp1_regs.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@
7272
#define VI6_DL_SWAP_WDS (1 << 1)
7373
#define VI6_DL_SWAP_BTS (1 << 0)
7474

75-
#define VI6_DL_EXT_CTRL 0x011c
75+
#define VI6_DL_EXT_CTRL(n) (0x011c + (n) * 36)
7676
#define VI6_DL_EXT_CTRL_NWE (1 << 16)
7777
#define VI6_DL_EXT_CTRL_POLINT_MASK (0x3f << 8)
7878
#define VI6_DL_EXT_CTRL_POLINT_SHIFT 8

0 commit comments

Comments
 (0)