summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLiu Ying <victor.liu@nxp.com>2017-07-24 10:36:26 +0800
committerLeonard Crestez <leonard.crestez@nxp.com>2018-08-24 12:41:33 +0300
commit55704b314c4383ce8c5fea792a1d8b55e7c7b77d (patch)
tree6aa484ddf88a46208440334c031c1961c96aac60
parent17d1156e91ec9b67ee7116052effd6b00662b918 (diff)
MLK-16075-18 gpu: imx: fetchdecode: Add several YUV pixel formats support
This patch adds several YUV pixel formats support for fetchdecode. The pixel formats are YUYV, UYVY, NV12, NV21, NV16, NV61, NV24 and NV42. Signed-off-by: Liu Ying <victor.liu@nxp.com>
-rw-r--r--drivers/gpu/imx/dpu/dpu-fetchdecode.c73
1 files changed, 72 insertions, 1 deletions
diff --git a/drivers/gpu/imx/dpu/dpu-fetchdecode.c b/drivers/gpu/imx/dpu/dpu-fetchdecode.c
index 333adcfcb6cd..166fa685184c 100644
--- a/drivers/gpu/imx/dpu/dpu-fetchdecode.c
+++ b/drivers/gpu/imx/dpu/dpu-fetchdecode.c
@@ -263,14 +263,85 @@ EXPORT_SYMBOL_GPL(fetchdecode_src_buf_dimensions);
void fetchdecode_set_fmt(struct dpu_fetchdecode *fd, u32 fmt)
{
- u32 bits, shift;
+ u32 val, bits, shift;
+ bool is_planar_yuv = false, is_rastermode_yuv422 = false;
+ bool is_yuv422upsamplingmode_interpolate = false;
+ bool is_inputselect_compact = false;
+ bool need_csc = false;
int i;
+ switch (fmt) {
+ case DRM_FORMAT_YUYV:
+ case DRM_FORMAT_UYVY:
+ is_rastermode_yuv422 = true;
+ is_yuv422upsamplingmode_interpolate = true;
+ need_csc = true;
+ break;
+ case DRM_FORMAT_NV12:
+ case DRM_FORMAT_NV21:
+ case DRM_FORMAT_NV16:
+ case DRM_FORMAT_NV61:
+ is_planar_yuv = true;
+ is_rastermode_yuv422 = true;
+ is_inputselect_compact = true;
+ need_csc = true;
+ break;
+ case DRM_FORMAT_NV24:
+ case DRM_FORMAT_NV42:
+ is_planar_yuv = true;
+ is_yuv422upsamplingmode_interpolate = true;
+ is_inputselect_compact = true;
+ need_csc = true;
+ break;
+ default:
+ break;
+ }
+
+ mutex_lock(&fd->mutex);
+ val = dpu_fd_read(fd, CONTROL);
+ val &= ~YUV422UPSAMPLINGMODE_MASK;
+ val &= ~INPUTSELECT_MASK;
+ val &= ~RASTERMODE_MASK;
+ if (is_yuv422upsamplingmode_interpolate)
+ val |= YUV422UPSAMPLINGMODE(YUV422UPSAMPLINGMODE__INTERPOLATE);
+ else
+ val |= YUV422UPSAMPLINGMODE(YUV422UPSAMPLINGMODE__REPLICATE);
+ if (is_inputselect_compact)
+ val |= INPUTSELECT(INPUTSELECT__COMPPACK);
+ else
+ val |= INPUTSELECT(INPUTSELECT__INACTIVE);
+ if (is_rastermode_yuv422)
+ val |= RASTERMODE(RASTERMODE__YUV422);
+ else
+ val |= RASTERMODE(RASTERMODE__NORMAL);
+ dpu_fd_write(fd, val, CONTROL);
+
+ val = dpu_fd_read(fd, LAYERPROPERTY0);
+ val &= ~YUVCONVERSIONMODE_MASK;
+ if (need_csc)
+ /*
+ * assuming fetchdecode always ouputs RGB pixel formats
+ *
+ * FIXME:
+ * determine correct standard here - ITU601 or ITU601_FR
+ * or ITU709
+ */
+ val |= YUVCONVERSIONMODE(YUVCONVERSIONMODE__ITU601_FR);
+ else
+ val |= YUVCONVERSIONMODE(YUVCONVERSIONMODE__OFF);
+ dpu_fd_write(fd, val, LAYERPROPERTY0);
+ mutex_unlock(&fd->mutex);
+
for (i = 0; i < ARRAY_SIZE(dpu_pixel_format_matrix); i++) {
if (dpu_pixel_format_matrix[i].pixel_format == fmt) {
bits = dpu_pixel_format_matrix[i].bits;
shift = dpu_pixel_format_matrix[i].shift;
+ if (is_planar_yuv) {
+ bits &= ~(U_BITS_MASK | V_BITS_MASK);
+ shift &= ~(U_SHIFT_MASK | V_SHIFT_MASK);
+ }
+
mutex_lock(&fd->mutex);
dpu_fd_write(fd, bits, COLORCOMPONENTBITS0);
dpu_fd_write(fd, shift, COLORCOMPONENTSHIFT0);