From 5af868ab366794c70c60be395c6d0a16831d2689 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joonas=20Kylm=C3=A4l=C3=A4?= Date: Fri, 24 Jul 2020 11:21:19 -0400 Subject: drm: exynos: add bgr pixel format support to fimd MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Joonas Kylmälä --- drivers/gpu/drm/exynos/exynos_drm_fimd.c | 37 ++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index cd1d565a98dd..461e95840b1a 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c @@ -37,6 +37,16 @@ * CPU Interface. */ +enum { + FIMD_OUTPUT_RGB, + FIMD_OUTPUT_BGR, +}; + +static int pixel_order = FIMD_OUTPUT_RGB; +module_param(pixel_order, int, 0); +MODULE_PARM_DESC(pixel_order, "RGB interface pixel order (rgb = 0 (default), " + "bgr = 1)"); + #define MIN_FB_WIDTH_FOR_16WORD_BURST 128 /* position control register for hardware window 0, 2 ~ 4.*/ @@ -218,15 +228,22 @@ static const enum drm_plane_type fimd_win_types[WINDOWS_NR] = { DRM_PLANE_TYPE_CURSOR, }; -static const uint32_t fimd_formats[] = { +static const uint32_t fimd_rgb_formats[] = { DRM_FORMAT_C8, DRM_FORMAT_XRGB1555, DRM_FORMAT_RGB565, DRM_FORMAT_XRGB8888, DRM_FORMAT_ARGB8888, - DRM_FORMAT_ABGR8888, +}; + +static const uint32_t fimd_bgr_formats[] = { + // TODO: remove this, needed for Linux logo to show up DRM_FORMAT_XRGB8888, + + DRM_FORMAT_XBGR1555, + DRM_FORMAT_BGR565, DRM_FORMAT_XBGR8888, + DRM_FORMAT_ABGR8888, }; static const unsigned int capabilities[WINDOWS_NR] = { @@ -669,21 +686,25 @@ static void fimd_win_set_pixfmt(struct fimd_context *ctx, unsigned int win, val |= WINCONx_BYTSWP; break; case DRM_FORMAT_XRGB1555: + case DRM_FORMAT_XBGR1555: val |= WINCON0_BPPMODE_16BPP_1555; val |= WINCONx_HAWSWP; val |= WINCONx_BURSTLEN_16WORD; break; case DRM_FORMAT_RGB565: + case DRM_FORMAT_BGR565: val |= WINCON0_BPPMODE_16BPP_565; val |= WINCONx_HAWSWP; val |= WINCONx_BURSTLEN_16WORD; break; case DRM_FORMAT_XRGB8888: + case DRM_FORMAT_XBGR8888: val |= WINCON0_BPPMODE_24BPP_888; val |= WINCONx_WSWP; val |= WINCONx_BURSTLEN_16WORD; break; case DRM_FORMAT_ARGB8888: + case DRM_FORMAT_ABGR8888: default: val |= WINCON1_BPPMODE_25BPP_A1888; val |= WINCONx_WSWP; @@ -1066,8 +1087,13 @@ static int fimd_bind(struct device *dev, struct device *master, void *data) ctx->drm_dev = drm_dev; for (i = 0; i < WINDOWS_NR; i++) { - ctx->configs[i].pixel_formats = fimd_formats; - ctx->configs[i].num_pixel_formats = ARRAY_SIZE(fimd_formats); + if (pixel_order == FIMD_OUTPUT_BGR && !ctx->i80_if) { + ctx->configs[i].pixel_formats = fimd_bgr_formats; + ctx->configs[i].num_pixel_formats = ARRAY_SIZE(fimd_bgr_formats); + } else { + ctx->configs[i].pixel_formats = fimd_rgb_formats; + ctx->configs[i].num_pixel_formats = ARRAY_SIZE(fimd_rgb_formats); + } ctx->configs[i].zpos = i; ctx->configs[i].type = fimd_win_types[i]; ctx->configs[i].capabilities = capabilities[i]; @@ -1170,6 +1196,9 @@ static int fimd_probe(struct platform_device *pdev) } of_node_put(i80_if_timings); + if (pixel_order == FIMD_OUTPUT_BGR && !ctx->i80_if) + ctx->vidcon0 |= VIDCON0_PNRMODE_BGR; + ctx->sysreg = syscon_regmap_lookup_by_phandle(dev->of_node, "samsung,sysreg"); if (IS_ERR(ctx->sysreg)) { -- cgit v1.2.3