From e8de6183649b3d5bece4ff28517ee5bd207c7d37 Mon Sep 17 00:00:00 2001 From: Ao Xu Date: Fri, 6 Jan 2023 17:02:22 +0800 Subject: [PATCH] drm: add rgba1010102 formats support [1/1] PD#SWPL-106925 Problem: no rgba1010102 formats support Solution: add rgba1010102 formats support Verify: ay301 Test: DRM-OSD-44 Change-Id: Ie8132c653eff65a45b5e34b4fe43ab2dd90c0550 Signed-off-by: Ao Xu --- arch/arm64/boot/dts/amlogic/mesont5m_drm.dtsi | 8 +- drivers/drm/Makefile | 2 +- drivers/drm/meson_cvbs.c | 2 +- drivers/drm/meson_drv.c | 26 +--- drivers/drm/meson_drv.h | 23 ++- drivers/drm/meson_hdmi.c | 2 +- drivers/drm/meson_lcd.c | 2 +- drivers/drm/meson_of_parser.c | 135 ++++++++++++++++++ drivers/drm/meson_plane.c | 92 ++++++------ drivers/drm/meson_vpu.c | 34 +---- drivers/drm/vpu-hw/meson_vpu_osd_mif.c | 29 +++- drivers/drm/vpu-hw/meson_vpu_osd_mif.h | 4 + 12 files changed, 241 insertions(+), 118 deletions(-) create mode 100644 drivers/drm/meson_of_parser.c diff --git a/arch/arm64/boot/dts/amlogic/mesont5m_drm.dtsi b/arch/arm64/boot/dts/amlogic/mesont5m_drm.dtsi index 72ddc9326..97a05ede8 100644 --- a/arch/arm64/boot/dts/amlogic/mesont5m_drm.dtsi +++ b/arch/arm64/boot/dts/amlogic/mesont5m_drm.dtsi @@ -57,11 +57,13 @@ ports = <&connectors_dev>; fbdev_sizes = <1920 1080 1920 2160 32>; osd_ver = /bits/ 8 ; - osd_afbc_mask = <4>; + /* 0:def group 1:def group + 1010102 formats */ + osd_formats_group = <1>; + /* OSD1&OSD2 with afbc, OSD3 has no afbc */ + osd_afbc_mask = <3>; vfm_mode = <1>; /** 0:drm mode 1:composer mode */ memory-region = <&logo_reserved>; - primary_plane_index = <0>; /* primary plane index for crtcs */ - crtc_masks = <1 1 1>; /*for encoder: 0:hdmi 1:lcd 2:cvbs*/ + crtc_masks = <0 1 1>; /*for encoder: 0:hdmi 1:lcd 2:cvbs*/ vpu_topology: vpu_topology { vpu_blocks { diff --git a/drivers/drm/Makefile b/drivers/drm/Makefile index 7e9b9d3e7..10d1605e9 100644 --- a/drivers/drm/Makefile +++ b/drivers/drm/Makefile @@ -24,7 +24,7 @@ endif $(MESON_DRM_MODULE_NAME)-y += meson_drv.o meson_plane.o \ meson_atomic.o meson_sysfs.o\ meson_writeback.o meson_logo.o\ - meson_async_atomic.o \ + meson_async_atomic.o meson_of_parser.o \ meson_vpu_pipeline_traverse.o \ meson_crtc.o meson_vpu_pipeline.o \ meson_vpu_pipeline_private.o \ diff --git a/drivers/drm/meson_cvbs.c b/drivers/drm/meson_cvbs.c index b5caaac2f..dd5b941af 100644 --- a/drivers/drm/meson_cvbs.c +++ b/drivers/drm/meson_cvbs.c @@ -209,7 +209,7 @@ int meson_cvbs_dev_bind(struct drm_device *drm, connector = &am_drm_cvbs->base.connector; /* Encoder */ - encoder->possible_crtcs = priv->crtc_masks[ENCODER_CVBS]; + encoder->possible_crtcs = priv->of_conf.crtc_masks[ENCODER_CVBS]; drm_encoder_helper_add(encoder, &am_cvbs_encoder_helper_funcs); ret = drm_encoder_init(drm, encoder, &am_cvbs_encoder_funcs, diff --git a/drivers/drm/meson_drv.c b/drivers/drm/meson_drv.c index fe00a6038..eb6cdb947 100644 --- a/drivers/drm/meson_drv.c +++ b/drivers/drm/meson_drv.c @@ -184,8 +184,7 @@ static int am_meson_drm_bind(struct device *dev) struct meson_drm *priv; struct drm_device *drm; struct platform_device *pdev = to_platform_device(dev); - u32 crtc_masks[ENCODER_MAX]; - int i, vpu_dma_mask, ret = 0; + int ret = 0; meson_driver.driver_features = DRIVER_HAVE_IRQ | DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC | DRIVER_RENDER; @@ -207,29 +206,6 @@ static int am_meson_drm_bind(struct device *dev) priv->bound_data.connector_component_bind = meson_connector_dev_bind; priv->bound_data.connector_component_unbind = meson_connector_dev_unbind; priv->osd_occupied_index = -1; - /*initialize encoders crtc_masks, it will replaced by dts*/ - for (i = 0; i < ENCODER_MAX; i++) - priv->crtc_masks[i] = 1; - - ret = of_property_read_u32_array(dev->of_node, "crtc_masks", - crtc_masks, ENCODER_MAX); - if (ret) { - DRM_ERROR("crtc_masks get fail!\n"); - } else { - for (i = 0; i < ENCODER_MAX; i++) - priv->crtc_masks[i] = crtc_masks[i]; - } - - vpu_dma_mask = 0; - ret = of_property_read_u32(dev->of_node, "vpu_dma_mask", &vpu_dma_mask); - if (!ret && vpu_dma_mask == 1) { - ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)); - if (ret) - ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); - - if (ret) - DRM_ERROR("drm set dma mask fail\n"); - } dev_set_drvdata(dev, priv); diff --git a/drivers/drm/meson_drv.h b/drivers/drm/meson_drv.h index 702698b94..a7de4bc03 100644 --- a/drivers/drm/meson_drv.h +++ b/drivers/drm/meson_drv.h @@ -51,6 +51,20 @@ enum vpu_enc_type { ENCODER_MAX }; +struct meson_of_conf { + /*for encoder: 0:hdmi 1:lcd 2:cvbs*/ + u32 crtc_masks[ENCODER_MAX]; + + u32 vfm_mode; + + u32 osd_afbc_mask; + + u32 crtcmask_osd[MESON_MAX_OSD]; + u32 crtcmask_video[MESON_MAX_VIDEO]; + + u32 osd_formats_group; +}; + struct meson_drm { struct device *dev; @@ -79,12 +93,8 @@ struct meson_drm { u32 num_planes; struct am_osd_plane *osd_planes[MESON_MAX_OSD]; struct am_video_plane *video_planes[MESON_MAX_VIDEO]; - u32 crtcmask_osd[MESON_MAX_OSD]; - u32 crtcmask_video[MESON_MAX_VIDEO]; - u32 osd_afbc_mask; - /*for encoder: 0:hdmi 1:lcd 2:cvbs*/ - u32 crtc_masks[ENCODER_MAX]; + struct meson_of_conf of_conf; /*CONFIG_AMLOGIC_DRM_EMULATE_FBDEV*/ struct meson_drm_fbdev_config ui_config; @@ -109,6 +119,9 @@ int meson_atomic_commit(struct drm_device *dev, struct drm_atomic_state *state, bool nonblock); void meson_atomic_helper_commit_tail(struct drm_atomic_state *old_state); + +/*meson of parse*/ +void meson_of_init(struct drm_device *dev, struct meson_drm *priv); /*******************************/ #ifdef CONFIG_DEBUG_FS diff --git a/drivers/drm/meson_hdmi.c b/drivers/drm/meson_hdmi.c index c733ef4c9..4b65d5a50 100644 --- a/drivers/drm/meson_hdmi.c +++ b/drivers/drm/meson_hdmi.c @@ -1870,7 +1870,7 @@ int meson_hdmitx_dev_bind(struct drm_device *drm, connector->interlace_allowed = 1; /* Encoder */ - encoder->possible_crtcs = priv->crtc_masks[ENCODER_HDMI]; + encoder->possible_crtcs = priv->of_conf.crtc_masks[ENCODER_HDMI]; drm_encoder_helper_add(encoder, &meson_hdmitx_encoder_helper_funcs); ret = drm_encoder_init(drm, encoder, &meson_hdmitx_encoder_funcs, DRM_MODE_ENCODER_TMDS, "am_hdmi_encoder"); diff --git a/drivers/drm/meson_lcd.c b/drivers/drm/meson_lcd.c index 2d6383256..188babca2 100644 --- a/drivers/drm/meson_lcd.c +++ b/drivers/drm/meson_lcd.c @@ -329,7 +329,7 @@ int meson_panel_dev_bind(struct drm_device *drm, } /* Encoder */ - encoder->possible_crtcs = priv->crtc_masks[ENCODER_LCD]; + encoder->possible_crtcs = priv->of_conf.crtc_masks[ENCODER_LCD]; drm_encoder_helper_add(encoder, &meson_panel_encoder_helper_funcs); ret = drm_encoder_init(drm, encoder, &meson_panel_encoder_funcs, encoder_type, "am_lcd_encoder"); diff --git a/drivers/drm/meson_of_parser.c b/drivers/drm/meson_of_parser.c new file mode 100644 index 000000000..7b3960d3c --- /dev/null +++ b/drivers/drm/meson_of_parser.c @@ -0,0 +1,135 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2019 Amlogic, Inc. All rights reserved. + */ + +#include +#include +#include +#include + +#include "meson_drv.h" +#include "meson_vpu_pipeline.h" + +static void meson_parse_crtc_masks(struct device_node *node, struct meson_of_conf *conf) +{ + int i, ret; + u32 crtc_masks[ENCODER_MAX]; + + ret = 0; + /*initialize encoders crtc_masks, it will replaced by dts*/ + for (i = 0; i < ENCODER_MAX; i++) + conf->crtc_masks[i] = 1; + + ret = of_property_read_u32_array(node, "crtc_masks", + crtc_masks, ENCODER_MAX); + if (ret) { + DRM_DEBUG("crtc_masks get fail!\n"); + } else { + for (i = 0; i < ENCODER_MAX; i++) + conf->crtc_masks[i] = crtc_masks[i]; + } +} + +static void meson_parse_dma_mask(struct device *dev) +{ + int ret, vpu_dma_mask; + + ret = 0; + vpu_dma_mask = 0; + + ret = of_property_read_u32(dev->of_node, "vpu_dma_mask", &vpu_dma_mask); + if (!ret && vpu_dma_mask == 1) { + ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64)); + if (ret) + ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32)); + + if (ret) + DRM_ERROR("drm set dma mask fail\n"); + } +} + +static void meson_video_parse_config(struct drm_device *dev, struct meson_of_conf *conf) +{ + u32 mode_flag = 0; + int ret; + + ret = of_property_read_u32(dev->dev->of_node, + "vfm_mode", &mode_flag); + if (ret) + DRM_DEBUG("%s parse vfm mode fail!\n", __func__); + + conf->vfm_mode = mode_flag; +} + +static void meson_osd_parse_config(struct drm_device *dev, struct meson_of_conf *conf) +{ + u32 osd_afbc_mask = 0xff; + u32 osd_formats_group = 0; + int ret; + + ret = of_property_read_u32(dev->dev->of_node, + "osd_afbc_mask", &osd_afbc_mask); + if (ret) + DRM_DEBUG("%s parse osd afbc mask fail!\n", __func__); + + conf->osd_afbc_mask = osd_afbc_mask; + + ret = of_property_read_u32(dev->dev->of_node, + "osd_formats_group", &osd_formats_group); + if (ret) + DRM_DEBUG("%s parse osd formats group fail!\n", __func__); + + conf->osd_formats_group = osd_formats_group; +} + +static void am_meson_vpu_get_plane_crtc_mask(struct meson_drm *priv, + char *name, u32 num, u32 *crtc_mask) +{ + struct device_node *np = priv->dev->of_node; + int ret; + + ret = of_property_read_u32_array(np, name, + crtc_mask, num); + if (ret) { + DRM_DEBUG("undefined %s!\n", name); + return; + } +} + +void meson_of_init(struct drm_device *dev, struct meson_drm *priv) +{ + int ret; + u32 osd_occupied_index; + struct meson_of_conf *conf = &priv->of_conf; + struct meson_vpu_pipeline *pipeline = priv->pipeline; + + meson_parse_crtc_masks(dev->dev->of_node, conf); + + meson_parse_dma_mask(dev->dev); + + ret = of_property_read_u8(dev->dev->of_node, + "osd_ver", &pipeline->osd_version); + + ret = of_property_read_u32(dev->dev->of_node, + "osd_occupied_index", &osd_occupied_index); + if (!ret) + priv->osd_occupied_index = osd_occupied_index; + + am_meson_vpu_get_plane_crtc_mask(priv, "crtcmask_of_osd", + pipeline->num_osds, conf->crtcmask_osd); + am_meson_vpu_get_plane_crtc_mask(priv, "crtcmask_of_video", + pipeline->num_video, conf->crtcmask_video); + /* overwrite ctrc mask of video&osd, these should be defined in xxx.dts, + * it is mainly suitable to the board with different configurations for + * the same chip. + */ + am_meson_vpu_get_plane_crtc_mask(priv, "overwrite_crtcmask_of_osd", + pipeline->num_osds, conf->crtcmask_osd); + am_meson_vpu_get_plane_crtc_mask(priv, "overwrite_crtcmask_of_video", + pipeline->num_video, conf->crtcmask_video); + + meson_osd_parse_config(dev, conf); + meson_video_parse_config(dev, conf); +} + diff --git a/drivers/drm/meson_plane.c b/drivers/drm/meson_plane.c index 4f6446ed7..5a33fdabc 100644 --- a/drivers/drm/meson_plane.c +++ b/drivers/drm/meson_plane.c @@ -57,6 +57,23 @@ static const u32 supported_drm_formats[] = { DRM_FORMAT_RGB565, }; +static const u32 supported_drm_formats_v2[] = { + DRM_FORMAT_RGBA1010102, + DRM_FORMAT_ARGB2101010, + DRM_FORMAT_ABGR2101010, + DRM_FORMAT_BGRA1010102, + DRM_FORMAT_XRGB8888, + DRM_FORMAT_XBGR8888, + DRM_FORMAT_RGBX8888, + DRM_FORMAT_BGRX8888, + DRM_FORMAT_ARGB8888, + DRM_FORMAT_ABGR8888, + DRM_FORMAT_RGBA8888, + DRM_FORMAT_BGRA8888, + DRM_FORMAT_RGB888, + DRM_FORMAT_RGB565, +}; + static u64 video_fbc_modifier[] = { DRM_FORMAT_MOD_AMLOGIC_FBC(AMLOGIC_FBC_LAYOUT_BASIC, 0), DRM_FORMAT_MOD_AMLOGIC_FBC(AMLOGIC_FBC_LAYOUT_BASIC, @@ -514,32 +531,6 @@ static int meson_video_plane_get_fb_info(struct drm_plane *plane, return 0; } -static u32 meson_video_parse_config(struct drm_device *dev) -{ - u32 mode_flag = 0; - int ret; - - ret = of_property_read_u32(dev->dev->of_node, - "vfm_mode", &mode_flag); - if (ret) - DRM_INFO("%s parse vfm mode fail!\n", __func__); - - return mode_flag; -} - -static u32 meson_osd_parse_config(struct drm_device *dev) -{ - u32 osd_afbc_mask = 0; - int ret; - - ret = of_property_read_u32(dev->dev->of_node, - "osd_afbc_mask", &osd_afbc_mask); - if (ret) - DRM_INFO("%s parse osd afbc mask fail!\n", __func__); - - return osd_afbc_mask; -} - static const char *am_meson_video_fence_get_driver_name(struct dma_fence *fence) { return "meson"; @@ -1411,7 +1402,7 @@ static void meson_plane_get_primary_plane(struct meson_drm *priv, for (i = 0; i < MESON_MAX_CRTC; i++) { for (j = 0; j < MESON_MAX_OSDS; j++) { - if (i == priv->crtcmask_osd[j] && + if (i == priv->of_conf.crtcmask_osd[j] && priv->osd_occupied_index != j) { first_plane = (first_plane != -1) ? first_plane : j; @@ -1430,9 +1421,12 @@ static struct am_osd_plane *am_osd_plane_create(struct meson_drm *priv, int i, u32 crtc_mask, enum drm_plane_type type) { struct am_osd_plane *osd_plane; + struct meson_of_conf *conf; struct drm_plane *plane; u32 zpos, min_zpos, max_zpos, osd_index; char plane_name[8]; + const u32 *formats_group; + int num_formats; const char *const_plane_name; osd_plane = devm_kzalloc(priv->drm->dev, sizeof(*osd_plane), @@ -1446,6 +1440,7 @@ static struct am_osd_plane *am_osd_plane_create(struct meson_drm *priv, osd_plane->drv = priv; osd_plane->plane_index = i; osd_plane->plane_type = OSD_PLANE; + conf = &priv->of_conf; #ifdef CONFIG_AMLOGIC_MEDIA_FB get_logo_osd_reverse(&osd_index, &logo.osd_reverse); @@ -1478,22 +1473,30 @@ static struct am_osd_plane *am_osd_plane_create(struct meson_drm *priv, else osd_plane->osd_occupied = false; - if (priv->osd_afbc_mask) { + if (conf->osd_formats_group) { + formats_group = supported_drm_formats_v2; + num_formats = ARRAY_SIZE(supported_drm_formats_v2); + } else { + formats_group = supported_drm_formats; + num_formats = ARRAY_SIZE(supported_drm_formats); + } + + if (conf->osd_afbc_mask & BIT(i)) { + drm_universal_plane_init(priv->drm, plane, 1 << crtc_mask, + &am_osd_plane_funs, + formats_group, + num_formats, + afbc_modifier, + type, const_plane_name); + } else { priv->drm->mode_config.allow_fb_modifiers = false; drm_universal_plane_init(priv->drm, plane, 1 << crtc_mask, &am_osd_plane_funs, - supported_drm_formats, - ARRAY_SIZE(supported_drm_formats), + formats_group, + num_formats, NULL, type, const_plane_name); priv->drm->mode_config.allow_fb_modifiers = true; - } else { - drm_universal_plane_init(priv->drm, plane, 1 << crtc_mask, - &am_osd_plane_funs, - supported_drm_formats, - ARRAY_SIZE(supported_drm_formats), - afbc_modifier, - type, const_plane_name); } drm_plane_create_blend_mode_property(plane, BIT(DRM_MODE_BLEND_PIXEL_NONE) | @@ -1575,17 +1578,15 @@ int am_meson_plane_create(struct meson_drm *priv) struct am_osd_plane *plane; struct am_video_plane *video_plane; struct meson_vpu_pipeline *pipeline = priv->pipeline; + struct meson_of_conf *conf = &priv->of_conf; enum drm_plane_type type[MESON_MAX_OSD]; int i, osd_index, video_index; - u32 vfm_mode; - u32 osd_afbc_mask; memset(priv->osd_planes, 0, sizeof(struct am_osd_plane *) * MESON_MAX_OSD); memset(priv->video_planes, 0, sizeof(struct am_video_plane *) * MESON_MAX_VIDEO); /*calculate primary plane*/ meson_plane_get_primary_plane(priv, type); - osd_afbc_mask = meson_osd_parse_config(priv->drm); /*osd plane*/ for (i = 0; i < MESON_MAX_OSD; i++) { @@ -1593,8 +1594,9 @@ int am_meson_plane_create(struct meson_drm *priv) continue; osd_index = pipeline->osds[i]->base.index; - priv->osd_afbc_mask = osd_afbc_mask >> i & 1; - plane = am_osd_plane_create(priv, osd_index, priv->crtcmask_osd[i], type[i]); + plane = am_osd_plane_create(priv, osd_index, + conf->crtcmask_osd[i], + type[i]); if (!plane) return -ENOMEM; @@ -1605,16 +1607,16 @@ int am_meson_plane_create(struct meson_drm *priv) priv->osd_planes[i] = plane; priv->num_planes++; } - vfm_mode = meson_video_parse_config(priv->drm); /*video plane: init after osd to provide osd id at first.*/ for (i = 0; i < pipeline->num_video; i++) { video_index = pipeline->video[i]->base.index; - video_plane = am_video_plane_create(priv, video_index, priv->crtcmask_video[i]); + video_plane = am_video_plane_create(priv, video_index, + conf->crtcmask_video[i]); if (!video_plane) return -ENOMEM; - video_plane->vfm_mode = vfm_mode; + video_plane->vfm_mode = conf->vfm_mode; priv->video_planes[i] = video_plane; priv->num_planes++; } diff --git a/drivers/drm/meson_vpu.c b/drivers/drm/meson_vpu.c index 534c79c92..a82cf79fe 100644 --- a/drivers/drm/meson_vpu.c +++ b/drivers/drm/meson_vpu.c @@ -154,19 +154,7 @@ static void am_meson_vpu_power_config(bool en) meson_vpu_power_config(VPU_VIU2_OSD_ROT, en); } -static void am_meson_vpu_get_plane_crtc_mask(struct meson_drm *priv, - char *name, u32 num, u32 *crtc_mask) -{ - struct device_node *np = priv->dev->of_node; - int ret; - ret = of_property_read_u32_array(np, name, - crtc_mask, num); - if (ret) { - DRM_DEBUG("undefined %s!\n", name); - return; - } -} static int am_meson_vpu_bind(struct device *dev, struct device *master, void *data) @@ -178,7 +166,6 @@ static int am_meson_vpu_bind(struct device *dev, struct meson_vpu_pipeline *pipeline = private->pipeline; struct am_meson_crtc *amcrtc; struct meson_vpu_data *vpu_data; - u32 osd_occupied_index; int i, ret, irq; DRM_DEBUG("%s in[%d]\n", __func__, __LINE__); @@ -189,26 +176,7 @@ static int am_meson_vpu_bind(struct device *dev, vpu_topology_populate(pipeline); meson_vpu_block_state_init(private, private->pipeline); - ret = of_property_read_u8(dev->of_node, - "osd_ver", &pipeline->osd_version); - - ret = of_property_read_u32(dev->of_node, - "osd_occupied_index", &osd_occupied_index); - if (!ret) - private->osd_occupied_index = osd_occupied_index; - - am_meson_vpu_get_plane_crtc_mask(private, "crtcmask_of_osd", - pipeline->num_osds, private->crtcmask_osd); - am_meson_vpu_get_plane_crtc_mask(private, "crtcmask_of_video", - pipeline->num_video, private->crtcmask_video); - /* overwrite ctrc mask of video&osd, these should be defined in xxx.dts, - * it is mainly suitable to the board with different configurations for - * the same chip. - */ - am_meson_vpu_get_plane_crtc_mask(private, "overwrite_crtcmask_of_osd", - pipeline->num_osds, private->crtcmask_osd); - am_meson_vpu_get_plane_crtc_mask(private, "overwrite_crtcmask_of_video", - pipeline->num_video, private->crtcmask_video); + meson_of_init(drm_dev, private); ret = am_meson_plane_create(private); if (ret) { diff --git a/drivers/drm/vpu-hw/meson_vpu_osd_mif.c b/drivers/drm/vpu-hw/meson_vpu_osd_mif.c index c4d0d95e3..948583a06 100644 --- a/drivers/drm/vpu-hw/meson_vpu_osd_mif.c +++ b/drivers/drm/vpu-hw/meson_vpu_osd_mif.c @@ -163,6 +163,22 @@ const struct meson_drm_format_info *__meson_drm_format_info(u32 format) .hw_blkmode = BLOCK_MODE_32BIT, .hw_colormat = COLOR_MATRIX_BGRA8888, .alpha_replace = 0 }, + { .format = DRM_FORMAT_RGBA1010102, + .hw_blkmode = BLOCK_MODE_32BIT, + .hw_colormat = COLOR_MATRIX_RGBA1010102, + .alpha_replace = 0 }, + { .format = DRM_FORMAT_ARGB2101010, + .hw_blkmode = BLOCK_MODE_32BIT, + .hw_colormat = COLOR_MATRIX_ARGB2101010, + .alpha_replace = 0 }, + { .format = DRM_FORMAT_ABGR2101010, + .hw_blkmode = BLOCK_MODE_32BIT, + .hw_colormat = COLOR_MATRIX_ABGR2101010, + .alpha_replace = 0 }, + { .format = DRM_FORMAT_BGRA1010102, + .hw_blkmode = BLOCK_MODE_32BIT, + .hw_colormat = COLOR_MATRIX_BGRA1010102, + .alpha_replace = 0 }, { .format = DRM_FORMAT_RGB888, .hw_blkmode = BLOCK_MODE_24BIT, .hw_colormat = COLOR_MATRIX_RGB888, @@ -509,7 +525,7 @@ static void osd_afbc_config(struct meson_vpu_block *vblk, static void osd_afbc_config_v7(struct meson_vpu_block *vblk, struct rdma_reg_ops *reg_ops, struct osd_mif_reg_s *reg, - u8 osd_index, bool afbc_en) + u8 osd_index, u32 pixel_format, bool afbc_en) { if (!afbc_en) reg_ops->rdma_write_reg_bits(reg->viu_osd_ctrl_stat2, 0, 1, 1); @@ -517,7 +533,14 @@ static void osd_afbc_config_v7(struct meson_vpu_block *vblk, reg_ops->rdma_write_reg_bits(reg->viu_osd_ctrl_stat2, 1, 1, 1); osd_mali_unpack_enable(vblk, reg_ops, reg, afbc_en); - osd_endian_mode(vblk, reg_ops, reg, !afbc_en); + if (pixel_format == DRM_FORMAT_RGBA1010102 || + pixel_format == DRM_FORMAT_ARGB2101010 || + pixel_format == DRM_FORMAT_ABGR2101010 || + pixel_format == DRM_FORMAT_BGRA1010102) + osd_endian_mode(vblk, reg_ops, reg, afbc_en); + else + osd_endian_mode(vblk, reg_ops, reg, !afbc_en); + osd_mem_mode(vblk, reg_ops, reg, 1); osd_mali_src_en_v7(vblk, reg_ops, reg, osd_index, afbc_en); } @@ -835,7 +858,7 @@ static void osd_set_state(struct meson_vpu_block *vblk, osd_color_config(vblk, reg_ops, reg, pixel_format, mvos->pixel_blend, afbc_en); if (pipeline->osd_version == OSD_V7) - osd_afbc_config_v7(vblk, reg_ops, reg, vblk->index, afbc_en); + osd_afbc_config_v7(vblk, reg_ops, reg, vblk->index, pixel_format, afbc_en); else osd_afbc_config(vblk, reg_ops, reg, vblk->index, afbc_en); diff --git a/drivers/drm/vpu-hw/meson_vpu_osd_mif.h b/drivers/drm/vpu-hw/meson_vpu_osd_mif.h index c5dc4cd88..dd5235d04 100644 --- a/drivers/drm/vpu-hw/meson_vpu_osd_mif.h +++ b/drivers/drm/vpu-hw/meson_vpu_osd_mif.h @@ -224,6 +224,10 @@ enum osd_color_matrix_e { COLOR_MATRIX_ARGB8888, COLOR_MATRIX_ABGR8888, COLOR_MATRIX_BGRA8888, + COLOR_MATRIX_RGBA1010102 = 12, + COLOR_MATRIX_ARGB2101010, + COLOR_MATRIX_ABGR2101010, + COLOR_MATRIX_BGRA1010102, /*for 24bit:blk-mode=BLOCK_MODE_24BIT*/ COLOR_MATRIX_RGB888 = 0, COLOR_MATRIX_BGR888 = 5,