@@ -59,6 +59,20 @@ static struct s5p_mfc_fmt formats[] = {
5959 .num_planes = 2 ,
6060 .versions = MFC_V6PLUS_BITS ,
6161 },
62+ {
63+ .fourcc = V4L2_PIX_FMT_YUV420M ,
64+ .codec_mode = S5P_MFC_CODEC_NONE ,
65+ .type = MFC_FMT_RAW ,
66+ .num_planes = 3 ,
67+ .versions = MFC_V12_BIT ,
68+ },
69+ {
70+ .fourcc = V4L2_PIX_FMT_YVU420M ,
71+ .codec_mode = S5P_MFC_CODEC_NONE ,
72+ .type = MFC_FMT_RAW ,
73+ .num_planes = 3 ,
74+ .versions = MFC_V12_BIT ,
75+ },
6276 {
6377 .fourcc = V4L2_PIX_FMT_H264 ,
6478 .codec_mode = S5P_MFC_CODEC_H264_ENC ,
@@ -1193,14 +1207,20 @@ static int enc_pre_frame_start(struct s5p_mfc_ctx *ctx)
11931207 struct s5p_mfc_dev * dev = ctx -> dev ;
11941208 struct s5p_mfc_buf * dst_mb ;
11951209 struct s5p_mfc_buf * src_mb ;
1196- unsigned long src_y_addr , src_c_addr , dst_addr ;
1210+ unsigned long src_y_addr , src_c_addr , src_c_1_addr , dst_addr ;
11971211 unsigned int dst_size ;
11981212
11991213 src_mb = list_entry (ctx -> src_queue .next , struct s5p_mfc_buf , list );
12001214 src_y_addr = vb2_dma_contig_plane_dma_addr (& src_mb -> b -> vb2_buf , 0 );
12011215 src_c_addr = vb2_dma_contig_plane_dma_addr (& src_mb -> b -> vb2_buf , 1 );
1216+ if (ctx -> src_fmt -> fourcc == V4L2_PIX_FMT_YUV420M || ctx -> src_fmt -> fourcc ==
1217+ V4L2_PIX_FMT_YVU420M )
1218+ src_c_1_addr =
1219+ vb2_dma_contig_plane_dma_addr (& src_mb -> b -> vb2_buf , 2 );
1220+ else
1221+ src_c_1_addr = 0 ;
12021222 s5p_mfc_hw_call (dev -> mfc_ops , set_enc_frame_buffer , ctx ,
1203- src_y_addr , src_c_addr );
1223+ src_y_addr , src_c_addr , src_c_1_addr );
12041224
12051225 dst_mb = list_entry (ctx -> dst_queue .next , struct s5p_mfc_buf , list );
12061226 dst_addr = vb2_dma_contig_plane_dma_addr (& dst_mb -> b -> vb2_buf , 0 );
@@ -1215,8 +1235,8 @@ static int enc_post_frame_start(struct s5p_mfc_ctx *ctx)
12151235{
12161236 struct s5p_mfc_dev * dev = ctx -> dev ;
12171237 struct s5p_mfc_buf * mb_entry ;
1218- unsigned long enc_y_addr = 0 , enc_c_addr = 0 ;
1219- unsigned long mb_y_addr , mb_c_addr ;
1238+ unsigned long enc_y_addr = 0 , enc_c_addr = 0 , enc_c_1_addr = 0 ;
1239+ unsigned long mb_y_addr , mb_c_addr , mb_c_1_addr ;
12201240 int slice_type ;
12211241 unsigned int strm_size ;
12221242 bool src_ready ;
@@ -1229,18 +1249,26 @@ static int enc_post_frame_start(struct s5p_mfc_ctx *ctx)
12291249 mfc_read (dev , S5P_FIMV_ENC_SI_PIC_CNT ));
12301250 if (slice_type >= 0 ) {
12311251 s5p_mfc_hw_call (dev -> mfc_ops , get_enc_frame_buffer , ctx ,
1232- & enc_y_addr , & enc_c_addr );
1252+ & enc_y_addr , & enc_c_addr , & enc_c_1_addr );
12331253 list_for_each_entry (mb_entry , & ctx -> src_queue , list ) {
12341254 mb_y_addr = vb2_dma_contig_plane_dma_addr (
12351255 & mb_entry -> b -> vb2_buf , 0 );
12361256 mb_c_addr = vb2_dma_contig_plane_dma_addr (
12371257 & mb_entry -> b -> vb2_buf , 1 );
1238- if ((enc_y_addr == mb_y_addr ) &&
1239- (enc_c_addr == mb_c_addr )) {
1258+ if (ctx -> src_fmt -> fourcc ==
1259+ V4L2_PIX_FMT_YUV420M ||
1260+ ctx -> src_fmt -> fourcc ==
1261+ V4L2_PIX_FMT_YVU420M )
1262+ mb_c_1_addr = vb2_dma_contig_plane_dma_addr
1263+ (& mb_entry -> b -> vb2_buf , 2 );
1264+ else
1265+ mb_c_1_addr = 0 ;
1266+ if (enc_y_addr == mb_y_addr && enc_c_addr == mb_c_addr && enc_c_1_addr
1267+ == mb_c_1_addr ) {
12401268 list_del (& mb_entry -> list );
12411269 ctx -> src_queue_cnt -- ;
12421270 vb2_buffer_done (& mb_entry -> b -> vb2_buf ,
1243- VB2_BUF_STATE_DONE );
1271+ VB2_BUF_STATE_DONE );
12441272 break ;
12451273 }
12461274 }
@@ -1249,20 +1277,27 @@ static int enc_post_frame_start(struct s5p_mfc_ctx *ctx)
12491277 & mb_entry -> b -> vb2_buf , 0 );
12501278 mb_c_addr = vb2_dma_contig_plane_dma_addr (
12511279 & mb_entry -> b -> vb2_buf , 1 );
1252- if ((enc_y_addr == mb_y_addr ) &&
1253- (enc_c_addr == mb_c_addr )) {
1280+ if (ctx -> src_fmt -> fourcc ==
1281+ V4L2_PIX_FMT_YUV420M ||
1282+ ctx -> src_fmt -> fourcc == V4L2_PIX_FMT_YVU420M )
1283+ mb_c_1_addr = vb2_dma_contig_plane_dma_addr (&
1284+ mb_entry -> b -> vb2_buf , 2 );
1285+ else
1286+ mb_c_1_addr = 0 ;
1287+ if (enc_y_addr == mb_y_addr && enc_c_addr == mb_c_addr && enc_c_1_addr
1288+ == mb_c_1_addr ) {
12541289 list_del (& mb_entry -> list );
12551290 ctx -> ref_queue_cnt -- ;
12561291 vb2_buffer_done (& mb_entry -> b -> vb2_buf ,
1257- VB2_BUF_STATE_DONE );
1292+ VB2_BUF_STATE_DONE );
12581293 break ;
12591294 }
12601295 }
12611296 }
12621297 if (ctx -> src_queue_cnt > 0 && (ctx -> state == MFCINST_RUNNING ||
1263- ctx -> state == MFCINST_FINISHING )) {
1298+ ctx -> state == MFCINST_FINISHING )) {
12641299 mb_entry = list_entry (ctx -> src_queue .next , struct s5p_mfc_buf ,
1265- list );
1300+ list );
12661301 if (mb_entry -> flags & MFC_BUF_FLAG_USED ) {
12671302 list_del (& mb_entry -> list );
12681303 ctx -> src_queue_cnt -- ;
@@ -1381,10 +1416,15 @@ static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
13811416 pix_fmt_mp -> pixelformat = ctx -> src_fmt -> fourcc ;
13821417 pix_fmt_mp -> num_planes = ctx -> src_fmt -> num_planes ;
13831418
1384- pix_fmt_mp -> plane_fmt [0 ].bytesperline = ctx -> buf_width ;
1419+ pix_fmt_mp -> plane_fmt [0 ].bytesperline = ctx -> stride [ 0 ] ;
13851420 pix_fmt_mp -> plane_fmt [0 ].sizeimage = ctx -> luma_size ;
1386- pix_fmt_mp -> plane_fmt [1 ].bytesperline = ctx -> buf_width ;
1421+ pix_fmt_mp -> plane_fmt [1 ].bytesperline = ctx -> stride [ 1 ] ;
13871422 pix_fmt_mp -> plane_fmt [1 ].sizeimage = ctx -> chroma_size ;
1423+ if (ctx -> src_fmt -> fourcc == V4L2_PIX_FMT_YUV420M || ctx -> src_fmt -> fourcc ==
1424+ V4L2_PIX_FMT_YVU420M ) {
1425+ pix_fmt_mp -> plane_fmt [2 ].bytesperline = ctx -> stride [2 ];
1426+ pix_fmt_mp -> plane_fmt [2 ].sizeimage = ctx -> chroma_size_1 ;
1427+ }
13881428 } else {
13891429 mfc_err ("invalid buf type\n" );
13901430 return - EINVAL ;
@@ -1468,9 +1508,14 @@ static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
14681508
14691509 s5p_mfc_hw_call (dev -> mfc_ops , enc_calc_src_size , ctx );
14701510 pix_fmt_mp -> plane_fmt [0 ].sizeimage = ctx -> luma_size ;
1471- pix_fmt_mp -> plane_fmt [0 ].bytesperline = ctx -> buf_width ;
1511+ pix_fmt_mp -> plane_fmt [0 ].bytesperline = ctx -> stride [ 0 ] ;
14721512 pix_fmt_mp -> plane_fmt [1 ].sizeimage = ctx -> chroma_size ;
1473- pix_fmt_mp -> plane_fmt [1 ].bytesperline = ctx -> buf_width ;
1513+ pix_fmt_mp -> plane_fmt [1 ].bytesperline = ctx -> stride [1 ];
1514+ if (ctx -> src_fmt -> fourcc == V4L2_PIX_FMT_YUV420M || ctx -> src_fmt -> fourcc ==
1515+ V4L2_PIX_FMT_YVU420M ) {
1516+ pix_fmt_mp -> plane_fmt [2 ].bytesperline = ctx -> stride [2 ];
1517+ pix_fmt_mp -> plane_fmt [2 ].sizeimage = ctx -> chroma_size_1 ;
1518+ }
14741519
14751520 ctx -> src_bufs_cnt = 0 ;
14761521 ctx -> output_state = QUEUE_FREE ;
@@ -2414,10 +2459,18 @@ static int s5p_mfc_queue_setup(struct vb2_queue *vq,
24142459
24152460 psize [0 ] = ctx -> luma_size ;
24162461 psize [1 ] = ctx -> chroma_size ;
2462+ if (ctx -> src_fmt && (ctx -> src_fmt -> fourcc ==
2463+ V4L2_PIX_FMT_YUV420M || ctx -> src_fmt -> fourcc ==
2464+ V4L2_PIX_FMT_YVU420M ))
2465+ psize [2 ] = ctx -> chroma_size_1 ;
24172466
24182467 if (IS_MFCV6_PLUS (dev )) {
24192468 alloc_devs [0 ] = ctx -> dev -> mem_dev [BANK_L_CTX ];
24202469 alloc_devs [1 ] = ctx -> dev -> mem_dev [BANK_L_CTX ];
2470+ if (ctx -> src_fmt && (ctx -> src_fmt -> fourcc ==
2471+ V4L2_PIX_FMT_YUV420M || ctx -> src_fmt -> fourcc ==
2472+ V4L2_PIX_FMT_YVU420M ))
2473+ alloc_devs [2 ] = ctx -> dev -> mem_dev [BANK_L_CTX ];
24212474 } else {
24222475 alloc_devs [0 ] = ctx -> dev -> mem_dev [BANK_R_CTX ];
24232476 alloc_devs [1 ] = ctx -> dev -> mem_dev [BANK_R_CTX ];
@@ -2456,6 +2509,11 @@ static int s5p_mfc_buf_init(struct vb2_buffer *vb)
24562509 vb2_dma_contig_plane_dma_addr (vb , 0 );
24572510 ctx -> src_bufs [i ].cookie .raw .chroma =
24582511 vb2_dma_contig_plane_dma_addr (vb , 1 );
2512+ if (ctx -> src_fmt -> fourcc ==
2513+ V4L2_PIX_FMT_YUV420M || ctx -> src_fmt -> fourcc ==
2514+ V4L2_PIX_FMT_YVU420M )
2515+ ctx -> src_bufs [i ].cookie .raw .chroma_1 =
2516+ vb2_dma_contig_plane_dma_addr (vb , 2 );
24592517 ctx -> src_bufs_cnt ++ ;
24602518 } else {
24612519 mfc_err ("invalid queue type: %d\n" , vq -> type );
@@ -2493,6 +2551,12 @@ static int s5p_mfc_buf_prepare(struct vb2_buffer *vb)
24932551 mfc_err ("plane size is too small for output\n" );
24942552 return - EINVAL ;
24952553 }
2554+ if ((ctx -> src_fmt -> fourcc == V4L2_PIX_FMT_YUV420M ||
2555+ ctx -> src_fmt -> fourcc == V4L2_PIX_FMT_YVU420M ) &&
2556+ (vb2_plane_size (vb , 2 ) < ctx -> chroma_size_1 )) {
2557+ mfc_err ("plane size is too small for output\n" );
2558+ return - EINVAL ;
2559+ }
24962560 } else {
24972561 mfc_err ("invalid queue type: %d\n" , vq -> type );
24982562 return - EINVAL ;
0 commit comments