Skip to content

Commit 4a1cde0

Browse files
committed
drivers: video: dcmipp: add nv12 pixel format support
Add YUV420 semi-planar pixel format (NV12). Signed-off-by: Hugues Fruchet <[email protected]>
1 parent 4cea4fa commit 4a1cde0

File tree

1 file changed

+47
-9
lines changed

1 file changed

+47
-9
lines changed

drivers/video/video_stm32_dcmipp.c

Lines changed: 47 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -205,17 +205,25 @@ void HAL_DCMIPP_PIPE_VsyncEventCallback(DCMIPP_HandleTypeDef *hdcmipp, uint32_t
205205
return;
206206
}
207207

208-
/*
209-
* TODO - we only support 1 buffer formats for the time being, setting of
210-
* MEMORY_ADDRESS_1 and MEMORY_ADDRESS_2 required depending on the pixelformat
211-
* for Pipe1
212-
*/
213208
ret = HAL_DCMIPP_PIPE_SetMemoryAddress(&dcmipp->hdcmipp, Pipe, DCMIPP_MEMORY_ADDRESS_0,
214209
(uint32_t)pipe->next->buffer);
215210
if (ret != HAL_OK) {
216211
LOG_ERR("Failed to update memory address");
217212
return;
218213
}
214+
215+
if (pipe->fmt.pixelformat == VIDEO_PIX_FMT_NV12) {
216+
uint32_t addr = (uint32_t)pipe->next->buffer +
217+
pipe->fmt.width * pipe->fmt.height;
218+
219+
ret = HAL_DCMIPP_PIPE_SetMemoryAddress(&dcmipp->hdcmipp, Pipe,
220+
DCMIPP_MEMORY_ADDRESS_1,
221+
addr);
222+
if (ret != HAL_OK) {
223+
LOG_ERR("Failed to update second memory address");
224+
return;
225+
}
226+
}
219227
}
220228

221229
#if defined(STM32_DCMIPP_HAS_CSI)
@@ -432,6 +440,7 @@ static const struct stm32_dcmipp_mapping {
432440
PIXEL_PIPE_FMT(RGB565, RGB565_1, 0, (BIT(1) | BIT(2))),
433441
PIXEL_PIPE_FMT(YUYV, YUV422_1, 0, (BIT(1) | BIT(2))),
434442
PIXEL_PIPE_FMT(YVYU, YUV422_1, 1, (BIT(1) | BIT(2))),
443+
PIXEL_PIPE_FMT(NV12, YUV420_2, 0, (BIT(1) | BIT(2))),
435444
PIXEL_PIPE_FMT(GREY, MONO_Y8_G8_1, 0, (BIT(1) | BIT(2))),
436445
PIXEL_PIPE_FMT(RGB24, RGB888_YUV444_1, 1, (BIT(1) | BIT(2))),
437446
PIXEL_PIPE_FMT(BGR24, RGB888_YUV444_1, 0, (BIT(1) | BIT(2))),
@@ -460,7 +469,7 @@ static const struct stm32_dcmipp_mapping {
460469
((fmt) == VIDEO_PIX_FMT_GREY || \
461470
(fmt) == VIDEO_PIX_FMT_YUYV || (fmt) == VIDEO_PIX_FMT_YVYU || \
462471
(fmt) == VIDEO_PIX_FMT_VYUY || (fmt) == VIDEO_PIX_FMT_UYVY || \
463-
(fmt) == VIDEO_PIX_FMT_XYUV32) ? VIDEO_COLORSPACE_YUV : \
472+
(fmt) == VIDEO_PIX_FMT_XYUV32 || (fmt) == VIDEO_PIX_FMT_NV12) ? VIDEO_COLORSPACE_YUV : \
464473
\
465474
VIDEO_COLORSPACE_RAW)
466475

@@ -481,6 +490,9 @@ static inline void stm32_dcmipp_compute_fmt_pitch(uint32_t pipe_id, struct video
481490
{
482491
fmt->pitch = fmt->width * video_bits_per_pixel(fmt->pixelformat) / BITS_PER_BYTE;
483492
#if defined(STM32_DCMIPP_HAS_PIXEL_PIPES)
493+
if (fmt->pixelformat == VIDEO_PIX_FMT_NV12)
494+
fmt->pitch = fmt->width;
495+
484496
if (pipe_id == DCMIPP_PIPE1 || pipe_id == DCMIPP_PIPE2) {
485497
/* On Pipe1 and Pipe2, the pitch must be multiple of 16 bytes */
486498
fmt->pitch = ROUND_UP(fmt->pitch, 16);
@@ -1044,9 +1056,21 @@ static int stm32_dcmipp_stream_enable(const struct device *dev)
10441056
}
10451057
#if defined(STM32_DCMIPP_HAS_CSI)
10461058
else if (config->bus_type == VIDEO_BUS_TYPE_CSI2_DPHY) {
1047-
ret = HAL_DCMIPP_CSI_PIPE_Start(&dcmipp->hdcmipp, pipe->id, DCMIPP_VIRTUAL_CHANNEL0,
1048-
(uint32_t)pipe->next->buffer,
1049-
DCMIPP_MODE_CONTINUOUS);
1059+
uint32_t addr = (uint32_t)pipe->next->buffer;
1060+
1061+
if (pipe->fmt.pixelformat == VIDEO_PIX_FMT_NV12) {
1062+
DCMIPP_SemiPlanarDstAddressTypeDef spaddr;
1063+
1064+
spaddr.YAddress = addr;
1065+
spaddr.UVAddress = addr + pipe->fmt.width * pipe->fmt.height;
1066+
ret = HAL_DCMIPP_CSI_PIPE_SemiPlanarStart(&dcmipp->hdcmipp,
1067+
pipe->id, DCMIPP_VIRTUAL_CHANNEL0,
1068+
&spaddr, DCMIPP_MODE_CONTINUOUS);
1069+
} else {
1070+
ret = HAL_DCMIPP_CSI_PIPE_Start(&dcmipp->hdcmipp, pipe->id,
1071+
DCMIPP_VIRTUAL_CHANNEL0,
1072+
addr, DCMIPP_MODE_CONTINUOUS);
1073+
}
10501074
}
10511075
#endif
10521076
else {
@@ -1193,6 +1217,20 @@ static int stm32_dcmipp_enqueue(const struct device *dev, struct video_buffer *v
11931217
LOG_ERR("Failed to update memory address");
11941218
return -EIO;
11951219
}
1220+
1221+
if (pipe->fmt.pixelformat == VIDEO_PIX_FMT_NV12) {
1222+
uint32_t addr = (uint32_t)pipe->next->buffer +
1223+
pipe->fmt.width * pipe->fmt.height;
1224+
1225+
ret = HAL_DCMIPP_PIPE_SetMemoryAddress(&dcmipp->hdcmipp, pipe->id,
1226+
DCMIPP_MEMORY_ADDRESS_1,
1227+
addr);
1228+
if (ret != HAL_OK) {
1229+
LOG_ERR("Failed to update second memory address");
1230+
return -EIO;
1231+
}
1232+
}
1233+
11961234
if (pipe->id == DCMIPP_PIPE0) {
11971235
SET_BIT(dcmipp->hdcmipp.Instance->P0FCTCR, DCMIPP_P0FCTCR_CPTREQ);
11981236
}

0 commit comments

Comments
 (0)