[PATCH RESEND] drm/mediatek: Add 0 size check to mtk_drm_gem_obj
Add a check to mtk_drm_gem_init if we attempt to allocate a GEM object of 0 bytes. Currently, no such check exists and the kernel will panic if a userspace application attempts to allocate a 0x0 GBM buffer. Tested by attempting to allocate a 0x0 GBM buffer on an MT8188 and verifying that we now return EINVAL. Fixes: 119f5173628a ("drm/mediatek: Add DRM Driver for Mediatek SoC MT8173.") Signed-off-by: Justin green Reviewed-by: AngeloGioacchino Del Regno --- drivers/gpu/drm/mediatek/mtk_drm_gem.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/mediatek/mtk_drm_gem.c b/drivers/gpu/drm/mediatek/mtk_drm_gem.c index 4f2e3feabc0f..ee49367b6138 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_gem.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_gem.c @@ -38,6 +38,9 @@ static struct mtk_drm_gem_obj *mtk_drm_gem_init(struct drm_device *dev, size = round_up(size, PAGE_SIZE); +if (size == 0) + return ERR_PTR(-EINVAL); + mtk_gem_obj = kzalloc(sizeof(*mtk_gem_obj), GFP_KERNEL); if (!mtk_gem_obj) return ERR_PTR(-ENOMEM); -- 2.44.0.278.ge034bb2e1d-goog
[PATCH] drm/mediatek: Add 0 size check to mtk_drm_gem_obj
Add a check to mtk_drm_gem_init if we attempt to allocate a GEM object of 0 bytes. Currently, no such check exists and the kernel will panic if a userspace application attempts to allocate a 0x0 GBM buffer. Tested by attempting to allocate a 0x0 GBM buffer on an MT8188 and verifying that we now return EINVAL. Signed-off-by: Justin green --- drivers/gpu/drm/mediatek/mtk_drm_gem.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/mediatek/mtk_drm_gem.c b/drivers/gpu/drm/mediatek/mtk_drm_gem.c index 4f2e3feabc0f..ee49367b6138 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_gem.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_gem.c @@ -38,6 +38,9 @@ static struct mtk_drm_gem_obj *mtk_drm_gem_init(struct drm_device *dev, size = round_up(size, PAGE_SIZE); +if (size == 0) + return ERR_PTR(-EINVAL); + mtk_gem_obj = kzalloc(sizeof(*mtk_gem_obj), GFP_KERNEL); if (!mtk_gem_obj) return ERR_PTR(-ENOMEM); -- 2.44.0.278.ge034bb2e1d-goog
[PATCH] drm/mediatek: Add MT8188 Overlay Driver Data
Add MT8188 overlay driver configuration data. This change consequently enables 10-bit overlay support on MT8188 devices. Tested by running ChromeOS UI on MT8188 and using modetest -P. AR30 and BA30 overlays are confirmed to work from modetest. Signed-off-by: Justin Green Tested-by: Justin Green --- drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 13 + 1 file changed, 13 insertions(+) diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c index 2bffe4245466..696aabe124c2 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c @@ -635,6 +635,17 @@ static const struct mtk_disp_ovl_data mt8195_ovl_driver_data = { .supports_clrfmt_ext = true, }; +static const struct mtk_disp_ovl_data mt8188_ovl_driver_data = { + .addr = DISP_REG_OVL_ADDR_MT8173, + .gmc_bits = 10, + .layer_nr = 4, + .fmt_rgb565_is_0 = true, + .smi_id_en = true, + .formats = mt8195_formats, + .num_formats = ARRAY_SIZE(mt8195_formats), + .supports_clrfmt_ext = true, +}; + static const struct of_device_id mtk_disp_ovl_driver_dt_match[] = { { .compatible = "mediatek,mt2701-disp-ovl", .data = &mt2701_ovl_driver_data}, @@ -650,6 +661,8 @@ static const struct of_device_id mtk_disp_ovl_driver_dt_match[] = { .data = &mt8192_ovl_2l_driver_data}, { .compatible = "mediatek,mt8195-disp-ovl", .data = &mt8195_ovl_driver_data}, + { .compatible = "mediatek,mt8188-disp-ovl", + .data = &mt8188_ovl_driver_data}, {}, }; MODULE_DEVICE_TABLE(of, mtk_disp_ovl_driver_dt_match); -- 2.44.0.rc0.258.g7320e95886-goog
Re: [PATCH RESEND] drm/mediatek: Add valid modifier check
> See c91acda3a380 ("drm/gem: Check for valid formats") and the related gem fb helper functions to see how this is supposed to be done. Oh that's interesting, so does this imply that the infrastructure automatically calls format_mod_supported() during framebuffer creation? In that case, this entire patch might be unnecessary in the tip of tree kernel. On Thu, Aug 3, 2023 at 4:24 AM Daniel Vetter wrote: > > On Mon, Jul 24, 2023 at 01:58:39PM -0400, Justin Green wrote: > > Add a check to mtk_drm_mode_fb_create() that rejects any modifier that > > is not the AFBC mode supported by MT8195's display overlays. > > > > Tested by booting ChromeOS and verifying the UI works, and by running > > the ChromeOS kms_addfb_basic binary, which has a test called > > "addfb25-bad-modifier" that attempts to create a framebuffer with the > > modifier DRM_FORMAT_MOD_INVALID and verifies the ADDFB2 ioctl returns > > EINVAL. > > > > Signed-off-by: Justin Green > > --- > > drivers/gpu/drm/mediatek/mtk_drm_drv.c | 7 +++ > > 1 file changed, 7 insertions(+) > > > > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c > > b/drivers/gpu/drm/mediatek/mtk_drm_drv.c > > index cd5b18ef7951..2096e8a794ad 100644 > > --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c > > +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c > > @@ -51,6 +51,13 @@ mtk_drm_mode_fb_create(struct drm_device *dev, > > if (info->num_planes != 1) > > return ERR_PTR(-EINVAL); > > > > + if (cmd->modifier[0] && > > + cmd->modifier[0] != DRM_FORMAT_MOD_ARM_AFBC( > > + AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 | > > + AFBC_FORMAT_MOD_SPLIT | > > + AFBC_FORMAT_MOD_SPARSE)) > > + return ERR_PTR(-EINVAL); > > If you set the modifiers/format properties correctly and use all the > helpers then the drm core should already validate that only formats you > can use are allowed. > > See c91acda3a380 ("drm/gem: Check for valid formats") and the related gem > fb helper functions to see how this is supposed to be done. These kind of > checks in driver code for gem drivers (which really is everyone at this > point) should not be needed at all. > > Cheers, Sima > > > + > > return drm_gem_fb_create(dev, file, cmd); > > } > > > > -- > > 2.41.0.162.gfafddb0af9-goog > > > > -- > Daniel Vetter > Software Engineer, Intel Corporation > http://blog.ffwll.ch
Re: [PATCH RESEND] drm/mediatek: Add valid modifier check
> ...so that a per-plane logic in mtk_drm_plane can be easily added, because... I think my concern is more that if we need to validate the format and the modifier differently because of the plane data, then this method would provide limited value. For example, on my MT8195, plane ID 38 supports AR30 and BA30, but plane ID 50 does not support any 10-bit pixel formats. On Thu, Jul 27, 2023 at 5:37 AM AngeloGioacchino Del Regno wrote: > > Il 26/07/23 21:44, Justin Green ha scritto: > >> Would it make more sense to commmonize function > >> mtk_plane_format_mod_supported() > >> and call that one here instead? > > I had considered that, but mtk_plane_format_mod_supported() is > > required to take a drm_plane as a parameter in order to conform to the > > type signature defined in drm_plane_funcs, but > > mtk_drm_mode_fb_create() does not have a drm_plane to provide, since > > the framebuffer is created later in the function. Technically we don't > > actually use the drm_plane in the implementation of > > mtk_plane_format_mod_supported() today, so we could just use a null > > pointer, but I figured we may one day need to add per-plane logic. > > > > My suggestion was not to use that function as-is, but rather to add a helper > like > > bool mtk_format_modifier_supported(u32 format, u32 modifier) { ... } > > ...so that a per-plane logic in mtk_drm_plane can be easily added, because... > > static bool mtk_plane_format_mod_supported(struct drm_plane *plane, >u32 format, u32 modifier) > { > return mtk_format_modifier_supported(format, modifier); > } > > so apart from that, is there any other reason to not do that? :-) > > Regards, > Angelo > > >> This is not DRM_FORMAT_MOD_INVALID. Please either explicitly compare > >> against INVALID if that's what you meant, or against LINEAR if that's what > >> you meant, or both. > > Ack, I meant to use LINEAR. Will update for the next version of the patch. > >
[PATCH v2] drm/mediatek: Add valid modifier check
Add a check to mtk_drm_mode_fb_create() that rejects any modifier that is not the AFBC mode supported by MT8195's display overlays. Tested by booting ChromeOS and verifying the UI works, and by running the ChromeOS kms_addfb_basic binary, which has a test called "addfb25-bad-modifier" that attempts to create a framebuffer with the modifier DRM_FORMAT_MOD_INVALID and verifies the ADDFB2 ioctl returns EINVAL. Signed-off-by: Justin Green Tested-by: Fei Shao --- v2: * Replace zero check with comparison to DRM_FORMAT_MOD_LINEAR. drivers/gpu/drm/mediatek/mtk_drm_drv.c | 7 +++ 1 file changed, 7 insertions(+) diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c index cd5b18ef7951..2719a1e3163a 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c @@ -51,6 +51,13 @@ mtk_drm_mode_fb_create(struct drm_device *dev, if (info->num_planes != 1) return ERR_PTR(-EINVAL); + if (cmd->modifier[0] != DRM_FORMAT_MOD_LINEAR && + cmd->modifier[0] != DRM_FORMAT_MOD_ARM_AFBC( + AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 | + AFBC_FORMAT_MOD_SPLIT | + AFBC_FORMAT_MOD_SPARSE)) + return ERR_PTR(-EINVAL); + return drm_gem_fb_create(dev, file, cmd); } -- 2.41.0.487.g6d72f3e995-goog
Re: [PATCH RESEND] drm/mediatek: Add valid modifier check
> Would it make more sense to commmonize function > mtk_plane_format_mod_supported() > and call that one here instead? I had considered that, but mtk_plane_format_mod_supported() is required to take a drm_plane as a parameter in order to conform to the type signature defined in drm_plane_funcs, but mtk_drm_mode_fb_create() does not have a drm_plane to provide, since the framebuffer is created later in the function. Technically we don't actually use the drm_plane in the implementation of mtk_plane_format_mod_supported() today, so we could just use a null pointer, but I figured we may one day need to add per-plane logic. > This is not DRM_FORMAT_MOD_INVALID. Please either explicitly compare against > INVALID if that's what you meant, or against LINEAR if that's what you meant, > or both. Ack, I meant to use LINEAR. Will update for the next version of the patch.
[PATCH RESEND] drm/mediatek: Add valid modifier check
Add a check to mtk_drm_mode_fb_create() that rejects any modifier that is not the AFBC mode supported by MT8195's display overlays. Tested by booting ChromeOS and verifying the UI works, and by running the ChromeOS kms_addfb_basic binary, which has a test called "addfb25-bad-modifier" that attempts to create a framebuffer with the modifier DRM_FORMAT_MOD_INVALID and verifies the ADDFB2 ioctl returns EINVAL. Signed-off-by: Justin Green --- drivers/gpu/drm/mediatek/mtk_drm_drv.c | 7 +++ 1 file changed, 7 insertions(+) diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c index cd5b18ef7951..2096e8a794ad 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c @@ -51,6 +51,13 @@ mtk_drm_mode_fb_create(struct drm_device *dev, if (info->num_planes != 1) return ERR_PTR(-EINVAL); + if (cmd->modifier[0] && + cmd->modifier[0] != DRM_FORMAT_MOD_ARM_AFBC( + AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 | + AFBC_FORMAT_MOD_SPLIT | + AFBC_FORMAT_MOD_SPARSE)) + return ERR_PTR(-EINVAL); + return drm_gem_fb_create(dev, file, cmd); } -- 2.41.0.162.gfafddb0af9-goog
[PATCH] drm/mediatek: Add valid modifier check
Add a check to mtk_drm_mode_fb_create() that rejects any modifier that is not the AFBC mode supported by MT8195's display overlays. Tested by booting ChromeOS and verifying the UI works, and by running the ChromeOS kms_addfb_basic binary, which has a test called "addfb25-bad-modifier" that attempts to create a framebuffer with the modifier DRM_FORMAT_MOD_INVALID and verifies the ADDFB2 ioctl returns EINVAL. Signed-off-by: Justin Green --- drivers/gpu/drm/mediatek/mtk_drm_drv.c | 7 +++ 1 file changed, 7 insertions(+) diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c index cd5b18ef7951..2096e8a794ad 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c @@ -51,6 +51,13 @@ mtk_drm_mode_fb_create(struct drm_device *dev, if (info->num_planes != 1) return ERR_PTR(-EINVAL); + if (cmd->modifier[0] && + cmd->modifier[0] != DRM_FORMAT_MOD_ARM_AFBC( + AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 | + AFBC_FORMAT_MOD_SPLIT | + AFBC_FORMAT_MOD_SPARSE)) + return ERR_PTR(-EINVAL); + return drm_gem_fb_create(dev, file, cmd); } -- 2.41.0.162.gfafddb0af9-goog
[PATCH v8 2/3] drm/mediatek: Add support for AR30 and BA30 overlays
Add the ability for the Mediatek DRM driver to control the bit depth register. If the DTS indicates the device supports 10-bit overlays and the current format has a fourcc of AR30, BA30, or RA30, we set the bit depth register to 10 bit. The next patch in the series actually enables 10-bit overlays for MT8195 devices, but this current patch should be a no-op. This patch was tested by simply running Chrome on an MT8195 and looking for regressions. Signed-off-by: Justin Green --- drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 33 + 1 file changed, 33 insertions(+) diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c index 8743c8047dc9..a6255e847104 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c @@ -41,6 +41,7 @@ #define DISP_REG_OVL_RDMA_CTRL(n) (0x00c0 + 0x20 * (n)) #define DISP_REG_OVL_RDMA_GMC(n) (0x00c8 + 0x20 * (n)) #define DISP_REG_OVL_ADDR_MT2701 0x0040 +#define DISP_REG_OVL_CLRFMT_EXT0x02D0 #define DISP_REG_OVL_ADDR_MT8173 0x0f40 #define DISP_REG_OVL_ADDR(ovl, n) ((ovl)->data->addr + 0x20 * (n)) #define DISP_REG_OVL_HDR_ADDR(ovl, n) ((ovl)->data->addr + 0x20 * (n) + 0x04) @@ -61,6 +62,10 @@ 0 : OVL_CON_CLRFMT_RGB) #define OVL_CON_CLRFMT_RGB888(ovl) ((ovl)->data->fmt_rgb565_is_0 ? \ OVL_CON_CLRFMT_RGB : 0) +#define OVL_CON_CLRFMT_BIT_DEPTH_MASK(ovl) (0xFF << 4 * (ovl)) +#define OVL_CON_CLRFMT_BIT_DEPTH(depth, ovl) (depth << 4 * (ovl)) +#define OVL_CON_CLRFMT_8_BIT 0x00 +#define OVL_CON_CLRFMT_10_BIT 0x01 #defineOVL_CON_AEN BIT(8) #defineOVL_CON_ALPHA 0xff #defineOVL_CON_VIRT_FLIP BIT(9) @@ -89,6 +94,7 @@ struct mtk_disp_ovl_data { bool supports_afbc; const u32 *formats; size_t num_formats; + bool supports_clrfmt_ext; }; /* @@ -218,6 +224,30 @@ static void mtk_ovl_set_afbc(struct mtk_disp_ovl *ovl, struct cmdq_pkt *cmdq_pkt DISP_REG_OVL_DATAPATH_CON, OVL_LAYER_AFBC_EN(idx)); } +static void mtk_ovl_set_bit_depth(struct device *dev, int idx, u32 format, + struct cmdq_pkt *cmdq_pkt) +{ + struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); + unsigned int reg; + unsigned int bit_depth = OVL_CON_CLRFMT_8_BIT; + + if (!ovl->data->supports_clrfmt_ext) + return; + + reg = readl(ovl->regs + DISP_REG_OVL_CLRFMT_EXT); + reg &= ~OVL_CON_CLRFMT_BIT_DEPTH_MASK(idx); + + if (format == DRM_FORMAT_RGBA1010102 || + format == DRM_FORMAT_BGRA1010102 || + format == DRM_FORMAT_ARGB2101010) + bit_depth = OVL_CON_CLRFMT_10_BIT; + + reg |= OVL_CON_CLRFMT_BIT_DEPTH(bit_depth, idx); + + mtk_ddp_write(cmdq_pkt, reg, &ovl->cmdq_reg, + ovl->regs, DISP_REG_OVL_CLRFMT_EXT); +} + void mtk_ovl_config(struct device *dev, unsigned int w, unsigned int h, unsigned int vrefresh, unsigned int bpc, struct cmdq_pkt *cmdq_pkt) @@ -332,9 +362,11 @@ static unsigned int ovl_fmt_convert(struct mtk_disp_ovl *ovl, unsigned int fmt) return OVL_CON_CLRFMT_ARGB; case DRM_FORMAT_BGRX: case DRM_FORMAT_BGRA: + case DRM_FORMAT_BGRA1010102: return OVL_CON_CLRFMT_ARGB | OVL_CON_BYTE_SWAP; case DRM_FORMAT_XRGB: case DRM_FORMAT_ARGB: + case DRM_FORMAT_ARGB2101010: return OVL_CON_CLRFMT_RGBA; case DRM_FORMAT_XBGR: case DRM_FORMAT_ABGR: @@ -418,6 +450,7 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int idx, &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_PITCH_MSB(idx)); } + mtk_ovl_set_bit_depth(dev, idx, fmt, cmdq_pkt); mtk_ovl_layer_on(dev, idx, cmdq_pkt); } -- 2.39.1.456.gfc5497dd1b-goog
[PATCH v8 1/3] drm/mediatek: Refactor pixel format logic
Add an DDP component interface for querying pixel format support and move list of supported pixel formats into DDP components instead of mtk_drm_plane.c Tested by running Chrome on an MT8195. Signed-off-by: Justin Green --- drivers/gpu/drm/mediatek/mtk_disp_drv.h | 4 ++ drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 44 + drivers/gpu/drm/mediatek/mtk_disp_rdma.c| 38 ++ drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 4 +- drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 4 ++ drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 20 ++ drivers/gpu/drm/mediatek/mtk_drm_plane.c| 24 --- drivers/gpu/drm/mediatek/mtk_drm_plane.h| 3 +- 8 files changed, 123 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h b/drivers/gpu/drm/mediatek/mtk_disp_drv.h index 33e61a136bbc..0df6a06defb8 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h +++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h @@ -96,6 +96,8 @@ void mtk_ovl_register_vblank_cb(struct device *dev, void mtk_ovl_unregister_vblank_cb(struct device *dev); void mtk_ovl_enable_vblank(struct device *dev); void mtk_ovl_disable_vblank(struct device *dev); +const u32 *mtk_ovl_get_formats(struct device *dev); +size_t mtk_ovl_get_num_formats(struct device *dev); void mtk_rdma_bypass_shadow(struct device *dev); int mtk_rdma_clk_enable(struct device *dev); @@ -115,6 +117,8 @@ void mtk_rdma_register_vblank_cb(struct device *dev, void mtk_rdma_unregister_vblank_cb(struct device *dev); void mtk_rdma_enable_vblank(struct device *dev); void mtk_rdma_disable_vblank(struct device *dev); +const u32 *mtk_rdma_get_formats(struct device *dev); +size_t mtk_rdma_get_num_formats(struct device *dev); int mtk_mdp_rdma_clk_enable(struct device *dev); void mtk_mdp_rdma_clk_disable(struct device *dev); diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c index 84daeaffab6a..8743c8047dc9 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c @@ -66,6 +66,20 @@ #defineOVL_CON_VIRT_FLIP BIT(9) #defineOVL_CON_HORZ_FLIP BIT(10) +static const u32 mt8173_formats[] = { + DRM_FORMAT_XRGB, + DRM_FORMAT_ARGB, + DRM_FORMAT_BGRX, + DRM_FORMAT_BGRA, + DRM_FORMAT_ABGR, + DRM_FORMAT_XBGR, + DRM_FORMAT_RGB888, + DRM_FORMAT_BGR888, + DRM_FORMAT_RGB565, + DRM_FORMAT_UYVY, + DRM_FORMAT_YUYV, +}; + struct mtk_disp_ovl_data { unsigned int addr; unsigned int gmc_bits; @@ -73,6 +87,8 @@ struct mtk_disp_ovl_data { bool fmt_rgb565_is_0; bool smi_id_en; bool supports_afbc; + const u32 *formats; + size_t num_formats; }; /* @@ -138,6 +154,20 @@ void mtk_ovl_disable_vblank(struct device *dev) writel_relaxed(0x0, ovl->regs + DISP_REG_OVL_INTEN); } +const u32 *mtk_ovl_get_formats(struct device *dev) +{ + struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); + + return ovl->data->formats; +} + +size_t mtk_ovl_get_num_formats(struct device *dev) +{ + struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); + + return ovl->data->num_formats; +} + int mtk_ovl_clk_enable(struct device *dev) { struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); @@ -495,6 +525,8 @@ static const struct mtk_disp_ovl_data mt2701_ovl_driver_data = { .gmc_bits = 8, .layer_nr = 4, .fmt_rgb565_is_0 = false, + .formats = mt8173_formats, + .num_formats = ARRAY_SIZE(mt8173_formats), }; static const struct mtk_disp_ovl_data mt8173_ovl_driver_data = { @@ -502,6 +534,8 @@ static const struct mtk_disp_ovl_data mt8173_ovl_driver_data = { .gmc_bits = 8, .layer_nr = 4, .fmt_rgb565_is_0 = true, + .formats = mt8173_formats, + .num_formats = ARRAY_SIZE(mt8173_formats), }; static const struct mtk_disp_ovl_data mt8183_ovl_driver_data = { @@ -509,6 +543,8 @@ static const struct mtk_disp_ovl_data mt8183_ovl_driver_data = { .gmc_bits = 10, .layer_nr = 4, .fmt_rgb565_is_0 = true, + .formats = mt8173_formats, + .num_formats = ARRAY_SIZE(mt8173_formats), }; static const struct mtk_disp_ovl_data mt8183_ovl_2l_driver_data = { @@ -516,6 +552,8 @@ static const struct mtk_disp_ovl_data mt8183_ovl_2l_driver_data = { .gmc_bits = 10, .layer_nr = 2, .fmt_rgb565_is_0 = true, + .formats = mt8173_formats, + .num_formats = ARRAY_SIZE(mt8173_formats), }; static const struct mtk_disp_ovl_data mt8192_ovl_driver_data = { @@ -524,6 +562,8 @@ static const struct mtk_disp_ovl_data mt8192_ovl_driver_data = { .layer_nr = 4, .fmt_rgb565_is_0 = true, .smi_id_en = true, + .formats = mt8173_formats, + .num_formats = ARRAY_SIZE(mt8173_formats), }; static const struct mt
[PATCH v7 RESEND 2/3] drm/mediatek: Add support for AR30 and BA30 overlays
Add the ability for the Mediatek DRM driver to control the bit depth register. If the DTS indicates the device supports 10-bit overlays and the current format has a fourcc of AR30, BA30, or RA30, we set the bit depth register to 10 bit. The next patch in the series actually enables 10-bit overlays for MT8195 devices, but this current patch should be a no-op. This patch was tested by simply running Chrome on an MT8195 and looking for regressions. Signed-off-by: Justin Green --- drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 33 + 1 file changed, 33 insertions(+) diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c index 8743c8047dc9..a6255e847104 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c @@ -41,6 +41,7 @@ #define DISP_REG_OVL_RDMA_CTRL(n) (0x00c0 + 0x20 * (n)) #define DISP_REG_OVL_RDMA_GMC(n) (0x00c8 + 0x20 * (n)) #define DISP_REG_OVL_ADDR_MT2701 0x0040 +#define DISP_REG_OVL_CLRFMT_EXT0x02D0 #define DISP_REG_OVL_ADDR_MT8173 0x0f40 #define DISP_REG_OVL_ADDR(ovl, n) ((ovl)->data->addr + 0x20 * (n)) #define DISP_REG_OVL_HDR_ADDR(ovl, n) ((ovl)->data->addr + 0x20 * (n) + 0x04) @@ -61,6 +62,10 @@ 0 : OVL_CON_CLRFMT_RGB) #define OVL_CON_CLRFMT_RGB888(ovl) ((ovl)->data->fmt_rgb565_is_0 ? \ OVL_CON_CLRFMT_RGB : 0) +#define OVL_CON_CLRFMT_BIT_DEPTH_MASK(ovl) (0xFF << 4 * (ovl)) +#define OVL_CON_CLRFMT_BIT_DEPTH(depth, ovl) (depth << 4 * (ovl)) +#define OVL_CON_CLRFMT_8_BIT 0x00 +#define OVL_CON_CLRFMT_10_BIT 0x01 #defineOVL_CON_AEN BIT(8) #defineOVL_CON_ALPHA 0xff #defineOVL_CON_VIRT_FLIP BIT(9) @@ -89,6 +94,7 @@ struct mtk_disp_ovl_data { bool supports_afbc; const u32 *formats; size_t num_formats; + bool supports_clrfmt_ext; }; /* @@ -218,6 +224,30 @@ static void mtk_ovl_set_afbc(struct mtk_disp_ovl *ovl, struct cmdq_pkt *cmdq_pkt DISP_REG_OVL_DATAPATH_CON, OVL_LAYER_AFBC_EN(idx)); } +static void mtk_ovl_set_bit_depth(struct device *dev, int idx, u32 format, + struct cmdq_pkt *cmdq_pkt) +{ + struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); + unsigned int reg; + unsigned int bit_depth = OVL_CON_CLRFMT_8_BIT; + + if (!ovl->data->supports_clrfmt_ext) + return; + + reg = readl(ovl->regs + DISP_REG_OVL_CLRFMT_EXT); + reg &= ~OVL_CON_CLRFMT_BIT_DEPTH_MASK(idx); + + if (format == DRM_FORMAT_RGBA1010102 || + format == DRM_FORMAT_BGRA1010102 || + format == DRM_FORMAT_ARGB2101010) + bit_depth = OVL_CON_CLRFMT_10_BIT; + + reg |= OVL_CON_CLRFMT_BIT_DEPTH(bit_depth, idx); + + mtk_ddp_write(cmdq_pkt, reg, &ovl->cmdq_reg, + ovl->regs, DISP_REG_OVL_CLRFMT_EXT); +} + void mtk_ovl_config(struct device *dev, unsigned int w, unsigned int h, unsigned int vrefresh, unsigned int bpc, struct cmdq_pkt *cmdq_pkt) @@ -332,9 +362,11 @@ static unsigned int ovl_fmt_convert(struct mtk_disp_ovl *ovl, unsigned int fmt) return OVL_CON_CLRFMT_ARGB; case DRM_FORMAT_BGRX: case DRM_FORMAT_BGRA: + case DRM_FORMAT_BGRA1010102: return OVL_CON_CLRFMT_ARGB | OVL_CON_BYTE_SWAP; case DRM_FORMAT_XRGB: case DRM_FORMAT_ARGB: + case DRM_FORMAT_ARGB2101010: return OVL_CON_CLRFMT_RGBA; case DRM_FORMAT_XBGR: case DRM_FORMAT_ABGR: @@ -418,6 +450,7 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int idx, &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_PITCH_MSB(idx)); } + mtk_ovl_set_bit_depth(dev, idx, fmt, cmdq_pkt); mtk_ovl_layer_on(dev, idx, cmdq_pkt); } -- 2.39.1.456.gfc5497dd1b-goog
Re: [PATCH v7 RESEND 2/3] drm/mediatek: Add support for AR30 and BA30 overlays
Hi Chun-Kuang, Thanks for the review! This patch was tested like the previous one, by running Chrome on an MT8195 and looking for regressions. I'll post a new series with the updated patch descriptions. Regards, Justin On Wed, Mar 8, 2023 at 6:34 PM Chun-Kuang Hu wrote: > > Hi, Justin: > > Justin Green 於 2023年3月8日 週三 下午11:34寫道: > > > > Tested using "modetest -P" on an MT8195 device. > > I think you could not test this when only apply the first two patches > of this series, so move the test information to the third patch. In > this patch, you could describe more about what and why this patch > does. The other modification looks good to me. > > Regards, > Chun-Kuang. > > > > > Signed-off-by: Justin Green > > --- > > drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 33 + > > 1 file changed, 33 insertions(+) > > > > diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c > > b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c > > index 8743c8047dc9..a6255e847104 100644 > > --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c > > +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c > > @@ -41,6 +41,7 @@ > > #define DISP_REG_OVL_RDMA_CTRL(n) (0x00c0 + 0x20 * (n)) > > #define DISP_REG_OVL_RDMA_GMC(n) (0x00c8 + 0x20 * (n)) > > #define DISP_REG_OVL_ADDR_MT2701 0x0040 > > +#define DISP_REG_OVL_CLRFMT_EXT0x02D0 > > #define DISP_REG_OVL_ADDR_MT8173 0x0f40 > > #define DISP_REG_OVL_ADDR(ovl, n) ((ovl)->data->addr + 0x20 * > > (n)) > > #define DISP_REG_OVL_HDR_ADDR(ovl, n) ((ovl)->data->addr + 0x20 * > > (n) + 0x04) > > @@ -61,6 +62,10 @@ > > 0 : OVL_CON_CLRFMT_RGB) > > #define OVL_CON_CLRFMT_RGB888(ovl) ((ovl)->data->fmt_rgb565_is_0 ? \ > > OVL_CON_CLRFMT_RGB : 0) > > +#define OVL_CON_CLRFMT_BIT_DEPTH_MASK(ovl) (0xFF << 4 * (ovl)) > > +#define OVL_CON_CLRFMT_BIT_DEPTH(depth, ovl) (depth << 4 * (ovl)) > > +#define OVL_CON_CLRFMT_8_BIT 0x00 > > +#define OVL_CON_CLRFMT_10_BIT 0x01 > > #defineOVL_CON_AEN BIT(8) > > #defineOVL_CON_ALPHA 0xff > > #defineOVL_CON_VIRT_FLIP BIT(9) > > @@ -89,6 +94,7 @@ struct mtk_disp_ovl_data { > > bool supports_afbc; > > const u32 *formats; > > size_t num_formats; > > + bool supports_clrfmt_ext; > > }; > > > > /* > > @@ -218,6 +224,30 @@ static void mtk_ovl_set_afbc(struct mtk_disp_ovl *ovl, > > struct cmdq_pkt *cmdq_pkt > >DISP_REG_OVL_DATAPATH_CON, > > OVL_LAYER_AFBC_EN(idx)); > > } > > > > +static void mtk_ovl_set_bit_depth(struct device *dev, int idx, u32 format, > > + struct cmdq_pkt *cmdq_pkt) > > +{ > > + struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); > > + unsigned int reg; > > + unsigned int bit_depth = OVL_CON_CLRFMT_8_BIT; > > + > > + if (!ovl->data->supports_clrfmt_ext) > > + return; > > + > > + reg = readl(ovl->regs + DISP_REG_OVL_CLRFMT_EXT); > > + reg &= ~OVL_CON_CLRFMT_BIT_DEPTH_MASK(idx); > > + > > + if (format == DRM_FORMAT_RGBA1010102 || > > + format == DRM_FORMAT_BGRA1010102 || > > + format == DRM_FORMAT_ARGB2101010) > > + bit_depth = OVL_CON_CLRFMT_10_BIT; > > + > > + reg |= OVL_CON_CLRFMT_BIT_DEPTH(bit_depth, idx); > > + > > + mtk_ddp_write(cmdq_pkt, reg, &ovl->cmdq_reg, > > + ovl->regs, DISP_REG_OVL_CLRFMT_EXT); > > +} > > + > > void mtk_ovl_config(struct device *dev, unsigned int w, > > unsigned int h, unsigned int vrefresh, > > unsigned int bpc, struct cmdq_pkt *cmdq_pkt) > > @@ -332,9 +362,11 @@ static unsigned int ovl_fmt_convert(struct > > mtk_disp_ovl *ovl, unsigned int fmt) > > return OVL_CON_CLRFMT_ARGB; > > case DRM_FORMAT_BGRX: > > case DRM_FORMAT_BGRA: > > + case DRM_FORMAT_BGRA1010102: > > return OVL_CON_CLRFMT_ARGB | OVL_CON_BYTE_SWAP; > > case DRM_FORMAT_XRGB: > > case DRM_FORMAT_ARGB: > > + case DRM_FORMAT_ARGB2101010: > > return OVL_CON_CLRFMT_RGBA; > > case DRM_FORMAT_XBGR: > > case DRM_FORMAT_ABGR: > > @@ -418,6 +450,7 @@ void mtk_ovl_layer_config(struct device *dev, unsigned > > int idx, > > &ovl->cmdq_reg, ovl->regs, > > DISP_REG_OVL_PITCH_MSB(idx)); > > } > > > > + mtk_ovl_set_bit_depth(dev, idx, fmt, cmdq_pkt); > > mtk_ovl_layer_on(dev, idx, cmdq_pkt); > > } > > > > -- > > 2.39.1.456.gfc5497dd1b-goog > >
[PATCH v8 3/3] drm/mediatek: Enable AR30 and BA30 overlays on MT8195
Modify the overlay driver data for MT8195 to enable bit depth control and enable support for AR30 and BA30 framebuffer formats. This patch in combination with the previous two patches in the series will allow MT8195 devices to scanout AR30 and BA30 framebuffers. Tested using "modetest -P" on an MT8195 device. The test pattern displays correctly for both AR30 and BA30 formats. Signed-off-by: Justin Green --- drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 21 +++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c index a6255e847104..7d26f7055751 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c @@ -85,6 +85,22 @@ static const u32 mt8173_formats[] = { DRM_FORMAT_YUYV, }; +static const u32 mt8195_formats[] = { + DRM_FORMAT_XRGB, + DRM_FORMAT_ARGB, + DRM_FORMAT_ARGB2101010, + DRM_FORMAT_BGRX, + DRM_FORMAT_BGRA, + DRM_FORMAT_BGRA1010102, + DRM_FORMAT_ABGR, + DRM_FORMAT_XBGR, + DRM_FORMAT_RGB888, + DRM_FORMAT_BGR888, + DRM_FORMAT_RGB565, + DRM_FORMAT_UYVY, + DRM_FORMAT_YUYV, +}; + struct mtk_disp_ovl_data { unsigned int addr; unsigned int gmc_bits; @@ -616,8 +632,9 @@ static const struct mtk_disp_ovl_data mt8195_ovl_driver_data = { .fmt_rgb565_is_0 = true, .smi_id_en = true, .supports_afbc = true, - .formats = mt8173_formats, - .num_formats = ARRAY_SIZE(mt8173_formats), + .formats = mt8195_formats, + .num_formats = ARRAY_SIZE(mt8195_formats), + .supports_clrfmt_ext = true, }; static const struct of_device_id mtk_disp_ovl_driver_dt_match[] = { -- 2.39.1.456.gfc5497dd1b-goog
[PATCH v8 0/3] drm/mediatek: Add support for 10-bit overlays
This patch series adds support for 10-bit overlays to the Mediatek DRM driver. Specifically, we add support for AR30 and BA30 overlays on MT8195 devices and lay the groundwork for supporting more 10-bit formats on more devices. 1. Refactor plane initialization logic to allow individual DDP components to provide their supported pixel formats. 2. Add AR30 and BA30 support to overlay driver. 3. Enable AR30 and BA30 overlays on MT8195. Version history: v2: * Rebase and resolve merge conflicts with the AFBC patch. v3: * Moved 10-bit support detection to mtk_disk_ovl.c v4: * Moved formats to mtk_disp_ovl.c and mtk_disp_rdma.c v5: * Minor style adjustments per checkpatch.pl v6: * Refactor patch into patch series. * Add formats directly to private data. v7: * Gate setting OVL_CLRFMT_EXT register on compatibility. * Split patches for adding 10-bit support and enabling 10-bit support on MT8195. v8: * Updated descriptions for patches 2 and 3 in the series. Justin Green (3): drm/mediatek: Refactor pixel format logic drm/mediatek: Add support for AR30 and BA30 overlays drm/mediatek: Enable AR30 and BA30 overlays on MT8195 drivers/gpu/drm/mediatek/mtk_disp_drv.h | 4 + drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 94 + drivers/gpu/drm/mediatek/mtk_disp_rdma.c| 38 + drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 4 +- drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 4 + drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 20 + drivers/gpu/drm/mediatek/mtk_drm_plane.c| 24 ++ drivers/gpu/drm/mediatek/mtk_drm_plane.h| 3 +- 8 files changed, 173 insertions(+), 18 deletions(-) -- 2.39.1.456.gfc5497dd1b-goog
[PATCH v7 RESEND 3/3] drm/mediatek: Enable AR30 and BA30 overlays on MT8195
Tested using "modetest -P" on an MT8195 device. Signed-off-by: Justin Green --- drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 21 +++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c index a6255e847104..7d26f7055751 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c @@ -85,6 +85,22 @@ static const u32 mt8173_formats[] = { DRM_FORMAT_YUYV, }; +static const u32 mt8195_formats[] = { + DRM_FORMAT_XRGB, + DRM_FORMAT_ARGB, + DRM_FORMAT_ARGB2101010, + DRM_FORMAT_BGRX, + DRM_FORMAT_BGRA, + DRM_FORMAT_BGRA1010102, + DRM_FORMAT_ABGR, + DRM_FORMAT_XBGR, + DRM_FORMAT_RGB888, + DRM_FORMAT_BGR888, + DRM_FORMAT_RGB565, + DRM_FORMAT_UYVY, + DRM_FORMAT_YUYV, +}; + struct mtk_disp_ovl_data { unsigned int addr; unsigned int gmc_bits; @@ -616,8 +632,9 @@ static const struct mtk_disp_ovl_data mt8195_ovl_driver_data = { .fmt_rgb565_is_0 = true, .smi_id_en = true, .supports_afbc = true, - .formats = mt8173_formats, - .num_formats = ARRAY_SIZE(mt8173_formats), + .formats = mt8195_formats, + .num_formats = ARRAY_SIZE(mt8195_formats), + .supports_clrfmt_ext = true, }; static const struct of_device_id mtk_disp_ovl_driver_dt_match[] = { -- 2.39.1.456.gfc5497dd1b-goog
[PATCH v7 RESEND 2/3] drm/mediatek: Add support for AR30 and BA30 overlays
Tested using "modetest -P" on an MT8195 device. Signed-off-by: Justin Green --- drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 33 + 1 file changed, 33 insertions(+) diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c index 8743c8047dc9..a6255e847104 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c @@ -41,6 +41,7 @@ #define DISP_REG_OVL_RDMA_CTRL(n) (0x00c0 + 0x20 * (n)) #define DISP_REG_OVL_RDMA_GMC(n) (0x00c8 + 0x20 * (n)) #define DISP_REG_OVL_ADDR_MT2701 0x0040 +#define DISP_REG_OVL_CLRFMT_EXT0x02D0 #define DISP_REG_OVL_ADDR_MT8173 0x0f40 #define DISP_REG_OVL_ADDR(ovl, n) ((ovl)->data->addr + 0x20 * (n)) #define DISP_REG_OVL_HDR_ADDR(ovl, n) ((ovl)->data->addr + 0x20 * (n) + 0x04) @@ -61,6 +62,10 @@ 0 : OVL_CON_CLRFMT_RGB) #define OVL_CON_CLRFMT_RGB888(ovl) ((ovl)->data->fmt_rgb565_is_0 ? \ OVL_CON_CLRFMT_RGB : 0) +#define OVL_CON_CLRFMT_BIT_DEPTH_MASK(ovl) (0xFF << 4 * (ovl)) +#define OVL_CON_CLRFMT_BIT_DEPTH(depth, ovl) (depth << 4 * (ovl)) +#define OVL_CON_CLRFMT_8_BIT 0x00 +#define OVL_CON_CLRFMT_10_BIT 0x01 #defineOVL_CON_AEN BIT(8) #defineOVL_CON_ALPHA 0xff #defineOVL_CON_VIRT_FLIP BIT(9) @@ -89,6 +94,7 @@ struct mtk_disp_ovl_data { bool supports_afbc; const u32 *formats; size_t num_formats; + bool supports_clrfmt_ext; }; /* @@ -218,6 +224,30 @@ static void mtk_ovl_set_afbc(struct mtk_disp_ovl *ovl, struct cmdq_pkt *cmdq_pkt DISP_REG_OVL_DATAPATH_CON, OVL_LAYER_AFBC_EN(idx)); } +static void mtk_ovl_set_bit_depth(struct device *dev, int idx, u32 format, + struct cmdq_pkt *cmdq_pkt) +{ + struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); + unsigned int reg; + unsigned int bit_depth = OVL_CON_CLRFMT_8_BIT; + + if (!ovl->data->supports_clrfmt_ext) + return; + + reg = readl(ovl->regs + DISP_REG_OVL_CLRFMT_EXT); + reg &= ~OVL_CON_CLRFMT_BIT_DEPTH_MASK(idx); + + if (format == DRM_FORMAT_RGBA1010102 || + format == DRM_FORMAT_BGRA1010102 || + format == DRM_FORMAT_ARGB2101010) + bit_depth = OVL_CON_CLRFMT_10_BIT; + + reg |= OVL_CON_CLRFMT_BIT_DEPTH(bit_depth, idx); + + mtk_ddp_write(cmdq_pkt, reg, &ovl->cmdq_reg, + ovl->regs, DISP_REG_OVL_CLRFMT_EXT); +} + void mtk_ovl_config(struct device *dev, unsigned int w, unsigned int h, unsigned int vrefresh, unsigned int bpc, struct cmdq_pkt *cmdq_pkt) @@ -332,9 +362,11 @@ static unsigned int ovl_fmt_convert(struct mtk_disp_ovl *ovl, unsigned int fmt) return OVL_CON_CLRFMT_ARGB; case DRM_FORMAT_BGRX: case DRM_FORMAT_BGRA: + case DRM_FORMAT_BGRA1010102: return OVL_CON_CLRFMT_ARGB | OVL_CON_BYTE_SWAP; case DRM_FORMAT_XRGB: case DRM_FORMAT_ARGB: + case DRM_FORMAT_ARGB2101010: return OVL_CON_CLRFMT_RGBA; case DRM_FORMAT_XBGR: case DRM_FORMAT_ABGR: @@ -418,6 +450,7 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int idx, &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_PITCH_MSB(idx)); } + mtk_ovl_set_bit_depth(dev, idx, fmt, cmdq_pkt); mtk_ovl_layer_on(dev, idx, cmdq_pkt); } -- 2.39.1.456.gfc5497dd1b-goog
[PATCH v7 RESEND 1/3] drm/mediatek: Refactor pixel format logic
Add an DDP component interface for querying pixel format support and move list of supported pixel formats into DDP components instead of mtk_drm_plane.c Tested by running Chrome on an MT8195. Signed-off-by: Justin Green --- drivers/gpu/drm/mediatek/mtk_disp_drv.h | 4 ++ drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 44 + drivers/gpu/drm/mediatek/mtk_disp_rdma.c| 38 ++ drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 4 +- drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 4 ++ drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 20 ++ drivers/gpu/drm/mediatek/mtk_drm_plane.c| 24 --- drivers/gpu/drm/mediatek/mtk_drm_plane.h| 3 +- 8 files changed, 123 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h b/drivers/gpu/drm/mediatek/mtk_disp_drv.h index 33e61a136bbc..0df6a06defb8 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h +++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h @@ -96,6 +96,8 @@ void mtk_ovl_register_vblank_cb(struct device *dev, void mtk_ovl_unregister_vblank_cb(struct device *dev); void mtk_ovl_enable_vblank(struct device *dev); void mtk_ovl_disable_vblank(struct device *dev); +const u32 *mtk_ovl_get_formats(struct device *dev); +size_t mtk_ovl_get_num_formats(struct device *dev); void mtk_rdma_bypass_shadow(struct device *dev); int mtk_rdma_clk_enable(struct device *dev); @@ -115,6 +117,8 @@ void mtk_rdma_register_vblank_cb(struct device *dev, void mtk_rdma_unregister_vblank_cb(struct device *dev); void mtk_rdma_enable_vblank(struct device *dev); void mtk_rdma_disable_vblank(struct device *dev); +const u32 *mtk_rdma_get_formats(struct device *dev); +size_t mtk_rdma_get_num_formats(struct device *dev); int mtk_mdp_rdma_clk_enable(struct device *dev); void mtk_mdp_rdma_clk_disable(struct device *dev); diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c index 84daeaffab6a..8743c8047dc9 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c @@ -66,6 +66,20 @@ #defineOVL_CON_VIRT_FLIP BIT(9) #defineOVL_CON_HORZ_FLIP BIT(10) +static const u32 mt8173_formats[] = { + DRM_FORMAT_XRGB, + DRM_FORMAT_ARGB, + DRM_FORMAT_BGRX, + DRM_FORMAT_BGRA, + DRM_FORMAT_ABGR, + DRM_FORMAT_XBGR, + DRM_FORMAT_RGB888, + DRM_FORMAT_BGR888, + DRM_FORMAT_RGB565, + DRM_FORMAT_UYVY, + DRM_FORMAT_YUYV, +}; + struct mtk_disp_ovl_data { unsigned int addr; unsigned int gmc_bits; @@ -73,6 +87,8 @@ struct mtk_disp_ovl_data { bool fmt_rgb565_is_0; bool smi_id_en; bool supports_afbc; + const u32 *formats; + size_t num_formats; }; /* @@ -138,6 +154,20 @@ void mtk_ovl_disable_vblank(struct device *dev) writel_relaxed(0x0, ovl->regs + DISP_REG_OVL_INTEN); } +const u32 *mtk_ovl_get_formats(struct device *dev) +{ + struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); + + return ovl->data->formats; +} + +size_t mtk_ovl_get_num_formats(struct device *dev) +{ + struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); + + return ovl->data->num_formats; +} + int mtk_ovl_clk_enable(struct device *dev) { struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); @@ -495,6 +525,8 @@ static const struct mtk_disp_ovl_data mt2701_ovl_driver_data = { .gmc_bits = 8, .layer_nr = 4, .fmt_rgb565_is_0 = false, + .formats = mt8173_formats, + .num_formats = ARRAY_SIZE(mt8173_formats), }; static const struct mtk_disp_ovl_data mt8173_ovl_driver_data = { @@ -502,6 +534,8 @@ static const struct mtk_disp_ovl_data mt8173_ovl_driver_data = { .gmc_bits = 8, .layer_nr = 4, .fmt_rgb565_is_0 = true, + .formats = mt8173_formats, + .num_formats = ARRAY_SIZE(mt8173_formats), }; static const struct mtk_disp_ovl_data mt8183_ovl_driver_data = { @@ -509,6 +543,8 @@ static const struct mtk_disp_ovl_data mt8183_ovl_driver_data = { .gmc_bits = 10, .layer_nr = 4, .fmt_rgb565_is_0 = true, + .formats = mt8173_formats, + .num_formats = ARRAY_SIZE(mt8173_formats), }; static const struct mtk_disp_ovl_data mt8183_ovl_2l_driver_data = { @@ -516,6 +552,8 @@ static const struct mtk_disp_ovl_data mt8183_ovl_2l_driver_data = { .gmc_bits = 10, .layer_nr = 2, .fmt_rgb565_is_0 = true, + .formats = mt8173_formats, + .num_formats = ARRAY_SIZE(mt8173_formats), }; static const struct mtk_disp_ovl_data mt8192_ovl_driver_data = { @@ -524,6 +562,8 @@ static const struct mtk_disp_ovl_data mt8192_ovl_driver_data = { .layer_nr = 4, .fmt_rgb565_is_0 = true, .smi_id_en = true, + .formats = mt8173_formats, + .num_formats = ARRAY_SIZE(mt8173_formats), }; static const struct mt
[PATCH v7 RESEND 0/3] drm/mediatek: Add support for 10-bit overlays
This patch series adds support for 10-bit overlays to the Mediatek DRM driver. Specifically, we add support for AR30 and BA30 overlays on MT8195 devices and lay the groundwork for supporting more 10-bit formats on more devices. 1. Refactor plane initialization logic to allow individual DDP components to provide their supported pixel formats. 2. Add AR30 and BA30 support to overlay driver. 3. Enable AR30 and BA30 overlays on MT8195. Version history: v2: * Rebase and resolve merge conflicts with the AFBC patch. v3: * Moved 10-bit support detection to mtk_disk_ovl.c v4: * Moved formats to mtk_disp_ovl.c and mtk_disp_rdma.c v5: * Minor style adjustments per checkpatch.pl v6: * Refactor patch into patch series. * Add formats directly to private data. v7: * Gate setting OVL_CLRFMT_EXT register on compatibility. * Split patches for adding 10-bit support and enabling 10-bit support on MT8195. Justin Green (3): drm/mediatek: Refactor pixel format logic drm/mediatek: Add support for AR30 and BA30 overlays drm/mediatek: Enable AR30 and BA30 overlays on MT8195 drivers/gpu/drm/mediatek/mtk_disp_drv.h | 4 + drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 94 + drivers/gpu/drm/mediatek/mtk_disp_rdma.c| 38 + drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 4 +- drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 4 + drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 20 + drivers/gpu/drm/mediatek/mtk_drm_plane.c| 24 ++ drivers/gpu/drm/mediatek/mtk_drm_plane.h| 3 +- 8 files changed, 173 insertions(+), 18 deletions(-) -- 2.39.1.456.gfc5497dd1b-goog
Re: [PATCH 1/3] drm/mediatek: Refactor pixel format logic
> Yes, I had a comment on the naming in that patch. Never the less, I think if > we > don't need to "overwrite" the value, we should use just one struct for the > values instead of copying them to the different .c files and give them SoC > specific names. I don't have a very strong opinion about this, and in fact that is how v1 of the patch worked, but Chun-Kuang specifically suggested moving that struct into the .c files a few versions back. I think it makes sense if we expect additional skew between the different components and what pixel formats they support.
Re: [PATCH 1/3] drm/mediatek: Refactor pixel format logic
Hi Matthias, > mt8173_formats are the same as the old struct formats. Maybe we should use > that > and only overwrite where we actually use a different array. I think this was sort of how the original patch worked, but we wanted to add some flexibility to allow different components to support different formats. In patch 3 of the series, we actually overwrite this field with mt8195_formats. > Why can't we use ARRAY_SIZE(formats) here like we did before? I think ARRAY_SIZE is just a macro for getting the length of statically allocated arrays. Because we won't know until runtime which list of pixel formats we will be using, I'm not sure we can use that in this circumstance? Regards, Justin
[PATCH 3/3] drm/mediatek: Enable AR30 and BA30 overlays on MT8195
Tested using "modetest -P" on an MT8195 device. Signed-off-by: Justin Green --- drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 21 +++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c index a6255e847104..7d26f7055751 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c @@ -85,6 +85,22 @@ static const u32 mt8173_formats[] = { DRM_FORMAT_YUYV, }; +static const u32 mt8195_formats[] = { + DRM_FORMAT_XRGB, + DRM_FORMAT_ARGB, + DRM_FORMAT_ARGB2101010, + DRM_FORMAT_BGRX, + DRM_FORMAT_BGRA, + DRM_FORMAT_BGRA1010102, + DRM_FORMAT_ABGR, + DRM_FORMAT_XBGR, + DRM_FORMAT_RGB888, + DRM_FORMAT_BGR888, + DRM_FORMAT_RGB565, + DRM_FORMAT_UYVY, + DRM_FORMAT_YUYV, +}; + struct mtk_disp_ovl_data { unsigned int addr; unsigned int gmc_bits; @@ -616,8 +632,9 @@ static const struct mtk_disp_ovl_data mt8195_ovl_driver_data = { .fmt_rgb565_is_0 = true, .smi_id_en = true, .supports_afbc = true, - .formats = mt8173_formats, - .num_formats = ARRAY_SIZE(mt8173_formats), + .formats = mt8195_formats, + .num_formats = ARRAY_SIZE(mt8195_formats), + .supports_clrfmt_ext = true, }; static const struct of_device_id mtk_disp_ovl_driver_dt_match[] = { -- 2.39.1.456.gfc5497dd1b-goog
[PATCH 2/3] drm/mediatek: Add support for AR30 and BA30 overlays
Tested using "modetest -P" on an MT8195 device. Signed-off-by: Justin Green --- drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 33 + 1 file changed, 33 insertions(+) diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c index 8743c8047dc9..a6255e847104 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c @@ -41,6 +41,7 @@ #define DISP_REG_OVL_RDMA_CTRL(n) (0x00c0 + 0x20 * (n)) #define DISP_REG_OVL_RDMA_GMC(n) (0x00c8 + 0x20 * (n)) #define DISP_REG_OVL_ADDR_MT2701 0x0040 +#define DISP_REG_OVL_CLRFMT_EXT0x02D0 #define DISP_REG_OVL_ADDR_MT8173 0x0f40 #define DISP_REG_OVL_ADDR(ovl, n) ((ovl)->data->addr + 0x20 * (n)) #define DISP_REG_OVL_HDR_ADDR(ovl, n) ((ovl)->data->addr + 0x20 * (n) + 0x04) @@ -61,6 +62,10 @@ 0 : OVL_CON_CLRFMT_RGB) #define OVL_CON_CLRFMT_RGB888(ovl) ((ovl)->data->fmt_rgb565_is_0 ? \ OVL_CON_CLRFMT_RGB : 0) +#define OVL_CON_CLRFMT_BIT_DEPTH_MASK(ovl) (0xFF << 4 * (ovl)) +#define OVL_CON_CLRFMT_BIT_DEPTH(depth, ovl) (depth << 4 * (ovl)) +#define OVL_CON_CLRFMT_8_BIT 0x00 +#define OVL_CON_CLRFMT_10_BIT 0x01 #defineOVL_CON_AEN BIT(8) #defineOVL_CON_ALPHA 0xff #defineOVL_CON_VIRT_FLIP BIT(9) @@ -89,6 +94,7 @@ struct mtk_disp_ovl_data { bool supports_afbc; const u32 *formats; size_t num_formats; + bool supports_clrfmt_ext; }; /* @@ -218,6 +224,30 @@ static void mtk_ovl_set_afbc(struct mtk_disp_ovl *ovl, struct cmdq_pkt *cmdq_pkt DISP_REG_OVL_DATAPATH_CON, OVL_LAYER_AFBC_EN(idx)); } +static void mtk_ovl_set_bit_depth(struct device *dev, int idx, u32 format, + struct cmdq_pkt *cmdq_pkt) +{ + struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); + unsigned int reg; + unsigned int bit_depth = OVL_CON_CLRFMT_8_BIT; + + if (!ovl->data->supports_clrfmt_ext) + return; + + reg = readl(ovl->regs + DISP_REG_OVL_CLRFMT_EXT); + reg &= ~OVL_CON_CLRFMT_BIT_DEPTH_MASK(idx); + + if (format == DRM_FORMAT_RGBA1010102 || + format == DRM_FORMAT_BGRA1010102 || + format == DRM_FORMAT_ARGB2101010) + bit_depth = OVL_CON_CLRFMT_10_BIT; + + reg |= OVL_CON_CLRFMT_BIT_DEPTH(bit_depth, idx); + + mtk_ddp_write(cmdq_pkt, reg, &ovl->cmdq_reg, + ovl->regs, DISP_REG_OVL_CLRFMT_EXT); +} + void mtk_ovl_config(struct device *dev, unsigned int w, unsigned int h, unsigned int vrefresh, unsigned int bpc, struct cmdq_pkt *cmdq_pkt) @@ -332,9 +362,11 @@ static unsigned int ovl_fmt_convert(struct mtk_disp_ovl *ovl, unsigned int fmt) return OVL_CON_CLRFMT_ARGB; case DRM_FORMAT_BGRX: case DRM_FORMAT_BGRA: + case DRM_FORMAT_BGRA1010102: return OVL_CON_CLRFMT_ARGB | OVL_CON_BYTE_SWAP; case DRM_FORMAT_XRGB: case DRM_FORMAT_ARGB: + case DRM_FORMAT_ARGB2101010: return OVL_CON_CLRFMT_RGBA; case DRM_FORMAT_XBGR: case DRM_FORMAT_ABGR: @@ -418,6 +450,7 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int idx, &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_PITCH_MSB(idx)); } + mtk_ovl_set_bit_depth(dev, idx, fmt, cmdq_pkt); mtk_ovl_layer_on(dev, idx, cmdq_pkt); } -- 2.39.1.456.gfc5497dd1b-goog
[PATCH 1/3] drm/mediatek: Refactor pixel format logic
Add an DDP component interface for querying pixel format support and move list of supported pixel formats into DDP components instead of mtk_drm_plane.c Tested by running Chrome on an MT8195. Signed-off-by: Justin Green --- drivers/gpu/drm/mediatek/mtk_disp_drv.h | 4 ++ drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 44 + drivers/gpu/drm/mediatek/mtk_disp_rdma.c| 38 ++ drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 4 +- drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 4 ++ drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 20 ++ drivers/gpu/drm/mediatek/mtk_drm_plane.c| 24 --- drivers/gpu/drm/mediatek/mtk_drm_plane.h| 3 +- 8 files changed, 123 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h b/drivers/gpu/drm/mediatek/mtk_disp_drv.h index 33e61a136bbc..0df6a06defb8 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h +++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h @@ -96,6 +96,8 @@ void mtk_ovl_register_vblank_cb(struct device *dev, void mtk_ovl_unregister_vblank_cb(struct device *dev); void mtk_ovl_enable_vblank(struct device *dev); void mtk_ovl_disable_vblank(struct device *dev); +const u32 *mtk_ovl_get_formats(struct device *dev); +size_t mtk_ovl_get_num_formats(struct device *dev); void mtk_rdma_bypass_shadow(struct device *dev); int mtk_rdma_clk_enable(struct device *dev); @@ -115,6 +117,8 @@ void mtk_rdma_register_vblank_cb(struct device *dev, void mtk_rdma_unregister_vblank_cb(struct device *dev); void mtk_rdma_enable_vblank(struct device *dev); void mtk_rdma_disable_vblank(struct device *dev); +const u32 *mtk_rdma_get_formats(struct device *dev); +size_t mtk_rdma_get_num_formats(struct device *dev); int mtk_mdp_rdma_clk_enable(struct device *dev); void mtk_mdp_rdma_clk_disable(struct device *dev); diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c index 84daeaffab6a..8743c8047dc9 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c @@ -66,6 +66,20 @@ #defineOVL_CON_VIRT_FLIP BIT(9) #defineOVL_CON_HORZ_FLIP BIT(10) +static const u32 mt8173_formats[] = { + DRM_FORMAT_XRGB, + DRM_FORMAT_ARGB, + DRM_FORMAT_BGRX, + DRM_FORMAT_BGRA, + DRM_FORMAT_ABGR, + DRM_FORMAT_XBGR, + DRM_FORMAT_RGB888, + DRM_FORMAT_BGR888, + DRM_FORMAT_RGB565, + DRM_FORMAT_UYVY, + DRM_FORMAT_YUYV, +}; + struct mtk_disp_ovl_data { unsigned int addr; unsigned int gmc_bits; @@ -73,6 +87,8 @@ struct mtk_disp_ovl_data { bool fmt_rgb565_is_0; bool smi_id_en; bool supports_afbc; + const u32 *formats; + size_t num_formats; }; /* @@ -138,6 +154,20 @@ void mtk_ovl_disable_vblank(struct device *dev) writel_relaxed(0x0, ovl->regs + DISP_REG_OVL_INTEN); } +const u32 *mtk_ovl_get_formats(struct device *dev) +{ + struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); + + return ovl->data->formats; +} + +size_t mtk_ovl_get_num_formats(struct device *dev) +{ + struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); + + return ovl->data->num_formats; +} + int mtk_ovl_clk_enable(struct device *dev) { struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); @@ -495,6 +525,8 @@ static const struct mtk_disp_ovl_data mt2701_ovl_driver_data = { .gmc_bits = 8, .layer_nr = 4, .fmt_rgb565_is_0 = false, + .formats = mt8173_formats, + .num_formats = ARRAY_SIZE(mt8173_formats), }; static const struct mtk_disp_ovl_data mt8173_ovl_driver_data = { @@ -502,6 +534,8 @@ static const struct mtk_disp_ovl_data mt8173_ovl_driver_data = { .gmc_bits = 8, .layer_nr = 4, .fmt_rgb565_is_0 = true, + .formats = mt8173_formats, + .num_formats = ARRAY_SIZE(mt8173_formats), }; static const struct mtk_disp_ovl_data mt8183_ovl_driver_data = { @@ -509,6 +543,8 @@ static const struct mtk_disp_ovl_data mt8183_ovl_driver_data = { .gmc_bits = 10, .layer_nr = 4, .fmt_rgb565_is_0 = true, + .formats = mt8173_formats, + .num_formats = ARRAY_SIZE(mt8173_formats), }; static const struct mtk_disp_ovl_data mt8183_ovl_2l_driver_data = { @@ -516,6 +552,8 @@ static const struct mtk_disp_ovl_data mt8183_ovl_2l_driver_data = { .gmc_bits = 10, .layer_nr = 2, .fmt_rgb565_is_0 = true, + .formats = mt8173_formats, + .num_formats = ARRAY_SIZE(mt8173_formats), }; static const struct mtk_disp_ovl_data mt8192_ovl_driver_data = { @@ -524,6 +562,8 @@ static const struct mtk_disp_ovl_data mt8192_ovl_driver_data = { .layer_nr = 4, .fmt_rgb565_is_0 = true, .smi_id_en = true, + .formats = mt8173_formats, + .num_formats = ARRAY_SIZE(mt8173_formats), }; static const struct mt
[PATCH 0/3 v7] drm/mediatek: Add support for 10-bit overlays
This patch series adds support for 10-bit overlays to the Mediatek DRM driver. Specifically, we add support for AR30 and BA30 overlays on MT8195 devices and lay the groundwork for supporting more 10-bit formats on more devices. 1. Refactor plane initialization logic to allow individual DDP components to provide their supported pixel formats. 2. Add AR30 and BA30 support to overlay driver. 3. Enable AR30 and BA30 overlays on MT8195. Version history: v2: * Rebase and resolve merge conflicts with the AFBC patch. v3: * Moved 10-bit support detection to mtk_disk_ovl.c v4: * Moved formats to mtk_disp_ovl.c and mtk_disp_rdma.c v5: * Minor style adjustments per checkpatch.pl v6: * Refactor patch into patch series. * Add formats directly to private data. v7: * Gate setting OVL_CLRFMT_EXT register on compatibility. * Split patches for adding 10-bit support and enabling 10-bit support on MT8195. Justin Green (3): drm/mediatek: Refactor pixel format logic drm/mediatek: Add support for AR30 and BA30 overlays drm/mediatek: Enable AR30 and BA30 overlays on MT8195 drivers/gpu/drm/mediatek/mtk_disp_drv.h | 4 + drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 94 + drivers/gpu/drm/mediatek/mtk_disp_rdma.c| 38 + drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 4 +- drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 4 + drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 20 + drivers/gpu/drm/mediatek/mtk_drm_plane.c| 24 ++ drivers/gpu/drm/mediatek/mtk_drm_plane.h| 3 +- 8 files changed, 173 insertions(+), 18 deletions(-) -- 2.39.1.456.gfc5497dd1b-goog
Re: [PATCH 2/2] drm/mediatek: Add support for AR30 and BA30 overlays
Hi Chun-Kuang, > Does all SoC have this register? If no, you should write this register > for the SoC have this register. I can't confirm this from the documentation that I have, I can only confirm this register exists on MT8195 and MT8186. I will send out another patch. Thanks, Justin
Re: [PATCH v5] drm/mediatek: Add support for AR30 and BA30
Hi Chun-Kuang, These two series are independent, so my preference would be to apply whichever series becomes ready first. There won't technically be a merge conflict, but I think the ovl-adaptor component will fail to initialize correctly once the first patch of this series lands, because the ovl-adaptor patch series does not yet implement the get_formats() interface. I can send a follow-up patch after the ovl-adaptor series lands, or let Nancy know about the potential runtime issue. Regards, Justin On Wed, Feb 1, 2023 at 10:30 AM Chun-Kuang Hu wrote: > > Hi, Justin: > > Justin Green 於 2023年1月31日 週二 下午11:04寫道: > > > > Hi Chun-Kuang, > > Thanks for the review! Will try to have a new patch out later today. > > > > Re MT8195 RDMA: Yes, the MT8195 RDMA has a 10 bit mode, but I left > > this unimplemented because I have no means of testing it > > unfortunately; ChromeOS does not use this hardware. > > > > I also wanted to mention, I think this patch might conflict with the > > in-flight ovl-adaptor patch. Is there a protocol for a situation like > > this? > > If I prefer the order of the two series, I would told you. But I have > no preference of these two series, so you may decide these two serious > are independent or dependent. If independent, I would apply the one > which is ready first, so the other one should rebase. If dependent, > you should discuss with Nancy the order of these two serious, the > second series should rebase on first series. > > Regards, > Chun-Kuang. > > > > > Regards, > > Justin > > > > On Mon, Jan 30, 2023 at 7:28 PM Chun-Kuang Hu > > wrote: > > > > > > Hi, Justin: > > > > > > Justin Green 於 2023年1月31日 週二 上午4:36寫道: > > > > > > > > Add support for AR30 and BA30 pixel formats to the Mediatek DRM driver. > > > > > > > > Tested using "modetest -P" on an MT8195. > > > > > > > > Signed-off-by: Justin Green > > > > --- > > > > v2: > > > > * Rebase and resolve merge conflicts with the AFBC patch. > > > > v3: > > > > * Moved 10-bit support detection to mtk_disk_ovl.c > > > > v4: > > > > * Moved formats to mtk_disp_ovl.c and mtk_disp_rdma.c > > > > v5: > > > > * Minor style adjustments per checkpatch.pl > > > > > > > > drivers/gpu/drm/mediatek/mtk_disp_drv.h | 4 ++ > > > > drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 75 + > > > > drivers/gpu/drm/mediatek/mtk_disp_rdma.c| 27 > > > > drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 4 +- > > > > drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 4 ++ > > > > drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 20 ++ > > > > drivers/gpu/drm/mediatek/mtk_drm_plane.c| 28 +++- > > > > drivers/gpu/drm/mediatek/mtk_drm_plane.h| 3 +- > > > > 8 files changed, 146 insertions(+), 19 deletions(-) > > > > > > > > diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h > > > > b/drivers/gpu/drm/mediatek/mtk_disp_drv.h > > > > index 33e61a136bbc..6ad22ce75b81 100644 > > > > --- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h > > > > +++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h > > > > @@ -96,6 +96,8 @@ void mtk_ovl_register_vblank_cb(struct device *dev, > > > > void mtk_ovl_unregister_vblank_cb(struct device *dev); > > > > void mtk_ovl_enable_vblank(struct device *dev); > > > > void mtk_ovl_disable_vblank(struct device *dev); > > > > +const u32 *mtk_ovl_get_formats(struct device *dev); > > > > +size_t mtk_ovl_get_num_formats(struct device *dev); > > > > > > > > void mtk_rdma_bypass_shadow(struct device *dev); > > > > int mtk_rdma_clk_enable(struct device *dev); > > > > @@ -122,4 +124,6 @@ void mtk_mdp_rdma_start(struct device *dev, struct > > > > cmdq_pkt *cmdq_pkt); > > > > void mtk_mdp_rdma_stop(struct device *dev, struct cmdq_pkt *cmdq_pkt); > > > > void mtk_mdp_rdma_config(struct device *dev, struct mtk_mdp_rdma_cfg > > > > *cfg, > > > > struct cmdq_pkt *cmdq_pkt); > > > > +const u32 *mtk_rdma_get_formats(struct device *dev); > > > > +size_t mtk_rdma_get_num_formats(struct device *dev); > > > > #endif > > > > diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c > > > > b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c > > > > index 84daeaffab6a..1db7
Re: [PATCH 0/2 v6] drm/mediatek: Add support for 10-bit overlays
My apologies, I accidentally mangled the version history. It should actually read: v2: * Rebase and resolve merge conflicts with the AFBC patch. v3: * Moved 10-bit support detection to mtk_disk_ovl.c v4: * Moved formats to mtk_disp_ovl.c and mtk_disp_rdma.c v5: * Minor style adjustments per checkpatch.pl v6: * Refactor patch into patch series. * Add formats directly to private data. On Tue, Jan 31, 2023 at 3:08 PM Justin Green wrote: > > This patch series adds support for 10-bit overlays to the Mediatek DRM driver. > Specifically, we add support for AR30 and BA30 overlays on MT8195 devices and > lay the groundwork for supporting more 10-bit formats on more devices. > > 1. Refactor plane initialization logic to allow individual DDP components to > provide their supported pixel formats. > > 2. Add AR30 and BA30 support to the MT8195 overlay driver. > > > Version history: > v6: > * Refactor patch into patch series. > * Add formats directly to private data. > > v5: > * Removed some dead defines. > * Refactored mtk_ovl_set_afbc(). > > v4: > * Move modifier validation to format_mod_supported function. > * Add modifiers to drm_universal_plane_init() call. > * Make comparisons to DRM_FORMAT_MOD_LINEAR explicit rather than relying on > DRM_FORMAT_LINEAR being equal to 0. > * Gate AFBC control bit writes on device compatibility. > > v3: > * Replaced pitch bitshift math with union based approach. > * Refactored overlay register writes to shared code between non-AFBC and > AFBC. > * Minor code cleanups. > > v2: > * Marked mtk_ovl_set_afbc as static. > * Reflowed some lines to fit column limit. > > > Justin Green (2): > drm/mediatek: Refactor pixel format logic > drm/mediatek: Add support for AR30 and BA30 overlays > > drivers/gpu/drm/mediatek/mtk_disp_drv.h | 4 + > drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 89 + > drivers/gpu/drm/mediatek/mtk_disp_rdma.c| 38 + > drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 4 +- > drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 4 + > drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 20 + > drivers/gpu/drm/mediatek/mtk_drm_plane.c| 24 ++ > drivers/gpu/drm/mediatek/mtk_drm_plane.h| 3 +- > 8 files changed, 168 insertions(+), 18 deletions(-) > > -- > 2.39.1.456.gfc5497dd1b-goog >
[PATCH 1/2] drm/mediatek: Refactor pixel format logic
Add an DDP component interface for querying pixel format support and move list of supported pixel formats into DDP components instead of mtk_drm_plane.c Tested by running Chrome on an MT8195. Signed-off-by: Justin Green edit1 --- drivers/gpu/drm/mediatek/mtk_disp_drv.h | 4 ++ drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 44 + drivers/gpu/drm/mediatek/mtk_disp_rdma.c| 38 ++ drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 4 +- drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 4 ++ drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 20 ++ drivers/gpu/drm/mediatek/mtk_drm_plane.c| 24 --- drivers/gpu/drm/mediatek/mtk_drm_plane.h| 3 +- 8 files changed, 123 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h b/drivers/gpu/drm/mediatek/mtk_disp_drv.h index 33e61a136bbc..0df6a06defb8 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h +++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h @@ -96,6 +96,8 @@ void mtk_ovl_register_vblank_cb(struct device *dev, void mtk_ovl_unregister_vblank_cb(struct device *dev); void mtk_ovl_enable_vblank(struct device *dev); void mtk_ovl_disable_vblank(struct device *dev); +const u32 *mtk_ovl_get_formats(struct device *dev); +size_t mtk_ovl_get_num_formats(struct device *dev); void mtk_rdma_bypass_shadow(struct device *dev); int mtk_rdma_clk_enable(struct device *dev); @@ -115,6 +117,8 @@ void mtk_rdma_register_vblank_cb(struct device *dev, void mtk_rdma_unregister_vblank_cb(struct device *dev); void mtk_rdma_enable_vblank(struct device *dev); void mtk_rdma_disable_vblank(struct device *dev); +const u32 *mtk_rdma_get_formats(struct device *dev); +size_t mtk_rdma_get_num_formats(struct device *dev); int mtk_mdp_rdma_clk_enable(struct device *dev); void mtk_mdp_rdma_clk_disable(struct device *dev); diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c index 84daeaffab6a..8743c8047dc9 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c @@ -66,6 +66,20 @@ #defineOVL_CON_VIRT_FLIP BIT(9) #defineOVL_CON_HORZ_FLIP BIT(10) +static const u32 mt8173_formats[] = { + DRM_FORMAT_XRGB, + DRM_FORMAT_ARGB, + DRM_FORMAT_BGRX, + DRM_FORMAT_BGRA, + DRM_FORMAT_ABGR, + DRM_FORMAT_XBGR, + DRM_FORMAT_RGB888, + DRM_FORMAT_BGR888, + DRM_FORMAT_RGB565, + DRM_FORMAT_UYVY, + DRM_FORMAT_YUYV, +}; + struct mtk_disp_ovl_data { unsigned int addr; unsigned int gmc_bits; @@ -73,6 +87,8 @@ struct mtk_disp_ovl_data { bool fmt_rgb565_is_0; bool smi_id_en; bool supports_afbc; + const u32 *formats; + size_t num_formats; }; /* @@ -138,6 +154,20 @@ void mtk_ovl_disable_vblank(struct device *dev) writel_relaxed(0x0, ovl->regs + DISP_REG_OVL_INTEN); } +const u32 *mtk_ovl_get_formats(struct device *dev) +{ + struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); + + return ovl->data->formats; +} + +size_t mtk_ovl_get_num_formats(struct device *dev) +{ + struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); + + return ovl->data->num_formats; +} + int mtk_ovl_clk_enable(struct device *dev) { struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); @@ -495,6 +525,8 @@ static const struct mtk_disp_ovl_data mt2701_ovl_driver_data = { .gmc_bits = 8, .layer_nr = 4, .fmt_rgb565_is_0 = false, + .formats = mt8173_formats, + .num_formats = ARRAY_SIZE(mt8173_formats), }; static const struct mtk_disp_ovl_data mt8173_ovl_driver_data = { @@ -502,6 +534,8 @@ static const struct mtk_disp_ovl_data mt8173_ovl_driver_data = { .gmc_bits = 8, .layer_nr = 4, .fmt_rgb565_is_0 = true, + .formats = mt8173_formats, + .num_formats = ARRAY_SIZE(mt8173_formats), }; static const struct mtk_disp_ovl_data mt8183_ovl_driver_data = { @@ -509,6 +543,8 @@ static const struct mtk_disp_ovl_data mt8183_ovl_driver_data = { .gmc_bits = 10, .layer_nr = 4, .fmt_rgb565_is_0 = true, + .formats = mt8173_formats, + .num_formats = ARRAY_SIZE(mt8173_formats), }; static const struct mtk_disp_ovl_data mt8183_ovl_2l_driver_data = { @@ -516,6 +552,8 @@ static const struct mtk_disp_ovl_data mt8183_ovl_2l_driver_data = { .gmc_bits = 10, .layer_nr = 2, .fmt_rgb565_is_0 = true, + .formats = mt8173_formats, + .num_formats = ARRAY_SIZE(mt8173_formats), }; static const struct mtk_disp_ovl_data mt8192_ovl_driver_data = { @@ -524,6 +562,8 @@ static const struct mtk_disp_ovl_data mt8192_ovl_driver_data = { .layer_nr = 4, .fmt_rgb565_is_0 = true, .smi_id_en = true, + .formats = mt8173_formats, + .num_formats = ARRAY_SIZE(mt8173_formats), }; static const struct mt
[PATCH 2/2] drm/mediatek: Add support for AR30 and BA30 overlays
Add support for overlays with pixel formats AR30 and BA30 on MT8195. Tested using "modetest -P" on an MT8195 device. Signed-off-by: Justin Green --- drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 49 - 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c index 8743c8047dc9..cd2f9a156456 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c @@ -41,6 +41,7 @@ #define DISP_REG_OVL_RDMA_CTRL(n) (0x00c0 + 0x20 * (n)) #define DISP_REG_OVL_RDMA_GMC(n) (0x00c8 + 0x20 * (n)) #define DISP_REG_OVL_ADDR_MT2701 0x0040 +#define DISP_REG_OVL_CLRFMT_EXT0x02D0 #define DISP_REG_OVL_ADDR_MT8173 0x0f40 #define DISP_REG_OVL_ADDR(ovl, n) ((ovl)->data->addr + 0x20 * (n)) #define DISP_REG_OVL_HDR_ADDR(ovl, n) ((ovl)->data->addr + 0x20 * (n) + 0x04) @@ -61,6 +62,10 @@ 0 : OVL_CON_CLRFMT_RGB) #define OVL_CON_CLRFMT_RGB888(ovl) ((ovl)->data->fmt_rgb565_is_0 ? \ OVL_CON_CLRFMT_RGB : 0) +#define OVL_CON_CLRFMT_BIT_DEPTH_MASK(ovl) (0xFF << 4 * (ovl)) +#define OVL_CON_CLRFMT_BIT_DEPTH(depth, ovl) (depth << 4 * (ovl)) +#define OVL_CON_CLRFMT_8_BIT 0x00 +#define OVL_CON_CLRFMT_10_BIT 0x01 #defineOVL_CON_AEN BIT(8) #defineOVL_CON_ALPHA 0xff #defineOVL_CON_VIRT_FLIP BIT(9) @@ -80,6 +85,22 @@ static const u32 mt8173_formats[] = { DRM_FORMAT_YUYV, }; +static const u32 mt8195_formats[] = { + DRM_FORMAT_XRGB, + DRM_FORMAT_ARGB, + DRM_FORMAT_ARGB2101010, + DRM_FORMAT_BGRX, + DRM_FORMAT_BGRA, + DRM_FORMAT_BGRA1010102, + DRM_FORMAT_ABGR, + DRM_FORMAT_XBGR, + DRM_FORMAT_RGB888, + DRM_FORMAT_BGR888, + DRM_FORMAT_RGB565, + DRM_FORMAT_UYVY, + DRM_FORMAT_YUYV, +}; + struct mtk_disp_ovl_data { unsigned int addr; unsigned int gmc_bits; @@ -218,6 +239,27 @@ static void mtk_ovl_set_afbc(struct mtk_disp_ovl *ovl, struct cmdq_pkt *cmdq_pkt DISP_REG_OVL_DATAPATH_CON, OVL_LAYER_AFBC_EN(idx)); } +static void mtk_ovl_set_bit_depth(struct device *dev, int idx, u32 format, + struct cmdq_pkt *cmdq_pkt) +{ + struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); + unsigned int reg; + unsigned int bit_depth = OVL_CON_CLRFMT_8_BIT; + + reg = readl(ovl->regs + DISP_REG_OVL_CLRFMT_EXT); + reg &= ~OVL_CON_CLRFMT_BIT_DEPTH_MASK(idx); + + if (format == DRM_FORMAT_RGBA1010102 || + format == DRM_FORMAT_BGRA1010102 || + format == DRM_FORMAT_ARGB2101010) + bit_depth = OVL_CON_CLRFMT_10_BIT; + + reg |= OVL_CON_CLRFMT_BIT_DEPTH(bit_depth, idx); + + mtk_ddp_write(cmdq_pkt, reg, &ovl->cmdq_reg, + ovl->regs, DISP_REG_OVL_CLRFMT_EXT); +} + void mtk_ovl_config(struct device *dev, unsigned int w, unsigned int h, unsigned int vrefresh, unsigned int bpc, struct cmdq_pkt *cmdq_pkt) @@ -332,9 +374,11 @@ static unsigned int ovl_fmt_convert(struct mtk_disp_ovl *ovl, unsigned int fmt) return OVL_CON_CLRFMT_ARGB; case DRM_FORMAT_BGRX: case DRM_FORMAT_BGRA: + case DRM_FORMAT_BGRA1010102: return OVL_CON_CLRFMT_ARGB | OVL_CON_BYTE_SWAP; case DRM_FORMAT_XRGB: case DRM_FORMAT_ARGB: + case DRM_FORMAT_ARGB2101010: return OVL_CON_CLRFMT_RGBA; case DRM_FORMAT_XBGR: case DRM_FORMAT_ABGR: @@ -418,6 +462,7 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int idx, &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_PITCH_MSB(idx)); } + mtk_ovl_set_bit_depth(dev, idx, fmt, cmdq_pkt); mtk_ovl_layer_on(dev, idx, cmdq_pkt); } @@ -583,8 +628,8 @@ static const struct mtk_disp_ovl_data mt8195_ovl_driver_data = { .fmt_rgb565_is_0 = true, .smi_id_en = true, .supports_afbc = true, - .formats = mt8173_formats, - .num_formats = ARRAY_SIZE(mt8173_formats), + .formats = mt8195_formats, + .num_formats = ARRAY_SIZE(mt8195_formats), }; static const struct of_device_id mtk_disp_ovl_driver_dt_match[] = { -- 2.39.1.456.gfc5497dd1b-goog
[PATCH 0/2 v6] drm/mediatek: Add support for 10-bit overlays
This patch series adds support for 10-bit overlays to the Mediatek DRM driver. Specifically, we add support for AR30 and BA30 overlays on MT8195 devices and lay the groundwork for supporting more 10-bit formats on more devices. 1. Refactor plane initialization logic to allow individual DDP components to provide their supported pixel formats. 2. Add AR30 and BA30 support to the MT8195 overlay driver. Version history: v6: * Refactor patch into patch series. * Add formats directly to private data. v5: * Removed some dead defines. * Refactored mtk_ovl_set_afbc(). v4: * Move modifier validation to format_mod_supported function. * Add modifiers to drm_universal_plane_init() call. * Make comparisons to DRM_FORMAT_MOD_LINEAR explicit rather than relying on DRM_FORMAT_LINEAR being equal to 0. * Gate AFBC control bit writes on device compatibility. v3: * Replaced pitch bitshift math with union based approach. * Refactored overlay register writes to shared code between non-AFBC and AFBC. * Minor code cleanups. v2: * Marked mtk_ovl_set_afbc as static. * Reflowed some lines to fit column limit. Justin Green (2): drm/mediatek: Refactor pixel format logic drm/mediatek: Add support for AR30 and BA30 overlays drivers/gpu/drm/mediatek/mtk_disp_drv.h | 4 + drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 89 + drivers/gpu/drm/mediatek/mtk_disp_rdma.c| 38 + drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 4 +- drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 4 + drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 20 + drivers/gpu/drm/mediatek/mtk_drm_plane.c| 24 ++ drivers/gpu/drm/mediatek/mtk_drm_plane.h| 3 +- 8 files changed, 168 insertions(+), 18 deletions(-) -- 2.39.1.456.gfc5497dd1b-goog
Re: [PATCH v5] drm/mediatek: Add support for AR30 and BA30
Hi Chun-Kuang, Thanks for the review! Will try to have a new patch out later today. Re MT8195 RDMA: Yes, the MT8195 RDMA has a 10 bit mode, but I left this unimplemented because I have no means of testing it unfortunately; ChromeOS does not use this hardware. I also wanted to mention, I think this patch might conflict with the in-flight ovl-adaptor patch. Is there a protocol for a situation like this? Regards, Justin On Mon, Jan 30, 2023 at 7:28 PM Chun-Kuang Hu wrote: > > Hi, Justin: > > Justin Green 於 2023年1月31日 週二 上午4:36寫道: > > > > Add support for AR30 and BA30 pixel formats to the Mediatek DRM driver. > > > > Tested using "modetest -P" on an MT8195. > > > > Signed-off-by: Justin Green > > --- > > v2: > > * Rebase and resolve merge conflicts with the AFBC patch. > > v3: > > * Moved 10-bit support detection to mtk_disk_ovl.c > > v4: > > * Moved formats to mtk_disp_ovl.c and mtk_disp_rdma.c > > v5: > > * Minor style adjustments per checkpatch.pl > > > > drivers/gpu/drm/mediatek/mtk_disp_drv.h | 4 ++ > > drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 75 + > > drivers/gpu/drm/mediatek/mtk_disp_rdma.c| 27 > > drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 4 +- > > drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 4 ++ > > drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 20 ++ > > drivers/gpu/drm/mediatek/mtk_drm_plane.c| 28 +++- > > drivers/gpu/drm/mediatek/mtk_drm_plane.h| 3 +- > > 8 files changed, 146 insertions(+), 19 deletions(-) > > > > diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h > > b/drivers/gpu/drm/mediatek/mtk_disp_drv.h > > index 33e61a136bbc..6ad22ce75b81 100644 > > --- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h > > +++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h > > @@ -96,6 +96,8 @@ void mtk_ovl_register_vblank_cb(struct device *dev, > > void mtk_ovl_unregister_vblank_cb(struct device *dev); > > void mtk_ovl_enable_vblank(struct device *dev); > > void mtk_ovl_disable_vblank(struct device *dev); > > +const u32 *mtk_ovl_get_formats(struct device *dev); > > +size_t mtk_ovl_get_num_formats(struct device *dev); > > > > void mtk_rdma_bypass_shadow(struct device *dev); > > int mtk_rdma_clk_enable(struct device *dev); > > @@ -122,4 +124,6 @@ void mtk_mdp_rdma_start(struct device *dev, struct > > cmdq_pkt *cmdq_pkt); > > void mtk_mdp_rdma_stop(struct device *dev, struct cmdq_pkt *cmdq_pkt); > > void mtk_mdp_rdma_config(struct device *dev, struct mtk_mdp_rdma_cfg *cfg, > > struct cmdq_pkt *cmdq_pkt); > > +const u32 *mtk_rdma_get_formats(struct device *dev); > > +size_t mtk_rdma_get_num_formats(struct device *dev); > > #endif > > diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c > > b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c > > index 84daeaffab6a..1db70a77560f 100644 > > --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c > > +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c > > @@ -41,6 +41,7 @@ > > #define DISP_REG_OVL_RDMA_CTRL(n) (0x00c0 + 0x20 * (n)) > > #define DISP_REG_OVL_RDMA_GMC(n) (0x00c8 + 0x20 * (n)) > > #define DISP_REG_OVL_ADDR_MT2701 0x0040 > > +#define DISP_REG_OVL_CLRFMT_EXT0x02D0 > > #define DISP_REG_OVL_ADDR_MT8173 0x0f40 > > #define DISP_REG_OVL_ADDR(ovl, n) ((ovl)->data->addr + 0x20 * > > (n)) > > #define DISP_REG_OVL_HDR_ADDR(ovl, n) ((ovl)->data->addr + 0x20 * > > (n) + 0x04) > > @@ -61,11 +62,45 @@ > > 0 : OVL_CON_CLRFMT_RGB) > > #define OVL_CON_CLRFMT_RGB888(ovl) ((ovl)->data->fmt_rgb565_is_0 ? \ > > OVL_CON_CLRFMT_RGB : 0) > > +#define OVL_CON_CLRFMT_BIT_DEPTH_MASK(ovl) (0xFF << 4 * (ovl)) > > +#define OVL_CON_CLRFMT_BIT_DEPTH(depth, ovl) (depth << 4 * (ovl)) > > +#define OVL_CON_CLRFMT_8_BIT 0x00 > > +#define OVL_CON_CLRFMT_10_BIT 0x01 > > #defineOVL_CON_AEN BIT(8) > > #defineOVL_CON_ALPHA 0xff > > #defineOVL_CON_VIRT_FLIP BIT(9) > > #defineOVL_CON_HORZ_FLIP BIT(10) > > > > +static const u32 formats_mt8173[] = { > > + DRM_FORMAT_XRGB, > > + DRM_FORMAT_ARGB, > > + DRM_FORMAT_BGRX, > > + DRM_FORMAT_BGRA, > > + DRM_FORMAT_ABGR, > > + DRM_FORMAT_XBGR, > > + D
[PATCH v5] drm/mediatek: Add support for AR30 and BA30
Add support for AR30 and BA30 pixel formats to the Mediatek DRM driver. Tested using "modetest -P" on an MT8195. Signed-off-by: Justin Green --- v2: * Rebase and resolve merge conflicts with the AFBC patch. v3: * Moved 10-bit support detection to mtk_disk_ovl.c v4: * Moved formats to mtk_disp_ovl.c and mtk_disp_rdma.c v5: * Minor style adjustments per checkpatch.pl drivers/gpu/drm/mediatek/mtk_disp_drv.h | 4 ++ drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 75 + drivers/gpu/drm/mediatek/mtk_disp_rdma.c| 27 drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 4 +- drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 4 ++ drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 20 ++ drivers/gpu/drm/mediatek/mtk_drm_plane.c| 28 +++- drivers/gpu/drm/mediatek/mtk_drm_plane.h| 3 +- 8 files changed, 146 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h b/drivers/gpu/drm/mediatek/mtk_disp_drv.h index 33e61a136bbc..6ad22ce75b81 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h +++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h @@ -96,6 +96,8 @@ void mtk_ovl_register_vblank_cb(struct device *dev, void mtk_ovl_unregister_vblank_cb(struct device *dev); void mtk_ovl_enable_vblank(struct device *dev); void mtk_ovl_disable_vblank(struct device *dev); +const u32 *mtk_ovl_get_formats(struct device *dev); +size_t mtk_ovl_get_num_formats(struct device *dev); void mtk_rdma_bypass_shadow(struct device *dev); int mtk_rdma_clk_enable(struct device *dev); @@ -122,4 +124,6 @@ void mtk_mdp_rdma_start(struct device *dev, struct cmdq_pkt *cmdq_pkt); void mtk_mdp_rdma_stop(struct device *dev, struct cmdq_pkt *cmdq_pkt); void mtk_mdp_rdma_config(struct device *dev, struct mtk_mdp_rdma_cfg *cfg, struct cmdq_pkt *cmdq_pkt); +const u32 *mtk_rdma_get_formats(struct device *dev); +size_t mtk_rdma_get_num_formats(struct device *dev); #endif diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c index 84daeaffab6a..1db70a77560f 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c @@ -41,6 +41,7 @@ #define DISP_REG_OVL_RDMA_CTRL(n) (0x00c0 + 0x20 * (n)) #define DISP_REG_OVL_RDMA_GMC(n) (0x00c8 + 0x20 * (n)) #define DISP_REG_OVL_ADDR_MT2701 0x0040 +#define DISP_REG_OVL_CLRFMT_EXT0x02D0 #define DISP_REG_OVL_ADDR_MT8173 0x0f40 #define DISP_REG_OVL_ADDR(ovl, n) ((ovl)->data->addr + 0x20 * (n)) #define DISP_REG_OVL_HDR_ADDR(ovl, n) ((ovl)->data->addr + 0x20 * (n) + 0x04) @@ -61,11 +62,45 @@ 0 : OVL_CON_CLRFMT_RGB) #define OVL_CON_CLRFMT_RGB888(ovl) ((ovl)->data->fmt_rgb565_is_0 ? \ OVL_CON_CLRFMT_RGB : 0) +#define OVL_CON_CLRFMT_BIT_DEPTH_MASK(ovl) (0xFF << 4 * (ovl)) +#define OVL_CON_CLRFMT_BIT_DEPTH(depth, ovl) (depth << 4 * (ovl)) +#define OVL_CON_CLRFMT_8_BIT 0x00 +#define OVL_CON_CLRFMT_10_BIT 0x01 #defineOVL_CON_AEN BIT(8) #defineOVL_CON_ALPHA 0xff #defineOVL_CON_VIRT_FLIP BIT(9) #defineOVL_CON_HORZ_FLIP BIT(10) +static const u32 formats_mt8173[] = { + DRM_FORMAT_XRGB, + DRM_FORMAT_ARGB, + DRM_FORMAT_BGRX, + DRM_FORMAT_BGRA, + DRM_FORMAT_ABGR, + DRM_FORMAT_XBGR, + DRM_FORMAT_RGB888, + DRM_FORMAT_BGR888, + DRM_FORMAT_RGB565, + DRM_FORMAT_UYVY, + DRM_FORMAT_YUYV, +}; + +static const u32 formats_mt8195[] = { + DRM_FORMAT_XRGB, + DRM_FORMAT_ARGB, + DRM_FORMAT_ARGB2101010, + DRM_FORMAT_BGRX, + DRM_FORMAT_BGRA, + DRM_FORMAT_BGRA1010102, + DRM_FORMAT_ABGR, + DRM_FORMAT_XBGR, + DRM_FORMAT_RGB888, + DRM_FORMAT_BGR888, + DRM_FORMAT_RGB565, + DRM_FORMAT_UYVY, + DRM_FORMAT_YUYV, +}; + struct mtk_disp_ovl_data { unsigned int addr; unsigned int gmc_bits; @@ -73,6 +108,7 @@ struct mtk_disp_ovl_data { bool fmt_rgb565_is_0; bool smi_id_en; bool supports_afbc; + bool supports_10bit; }; /* @@ -188,6 +224,26 @@ static void mtk_ovl_set_afbc(struct mtk_disp_ovl *ovl, struct cmdq_pkt *cmdq_pkt DISP_REG_OVL_DATAPATH_CON, OVL_LAYER_AFBC_EN(idx)); } +static void mtk_ovl_set_bit_depth(struct device *dev, int idx, u32 format, + struct cmdq_pkt *cmdq_pkt) +{ + struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); + unsigned int reg; + unsigned int bit_depth = OVL_CON_CLRFMT_8_BIT; + + reg = readl(ovl->regs + DISP_REG_OVL_CLRFMT_EXT); + reg &= ~OVL_CON_CLRFMT_BIT_DEPTH_MASK(idx);
[PATCH v4] drm/mediatek: Add support for AR30 and BA30
Add support for AR30 and BA30 pixel formats to the Mediatek DRM driver. Tested using "modetest -P" on an MT8195. Signed-off-by: Justin Green --- v2: * Rebase and resolve merge conflicts with the AFBC patch. v3: * Moved 10-bit support detection to mtk_disk_ovl.c v4: * Moved formats to mtk_disp_ovl.c and mtk_disp_rdma.c drivers/gpu/drm/mediatek/mtk_disp_drv.h | 4 ++ drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 75 + drivers/gpu/drm/mediatek/mtk_disp_rdma.c| 27 drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 4 +- drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 4 ++ drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 20 ++ drivers/gpu/drm/mediatek/mtk_drm_plane.c| 28 +++- drivers/gpu/drm/mediatek/mtk_drm_plane.h| 3 +- 8 files changed, 146 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h b/drivers/gpu/drm/mediatek/mtk_disp_drv.h index 33e61a136bbc..c292022b8270 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h +++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h @@ -96,6 +96,8 @@ void mtk_ovl_register_vblank_cb(struct device *dev, void mtk_ovl_unregister_vblank_cb(struct device *dev); void mtk_ovl_enable_vblank(struct device *dev); void mtk_ovl_disable_vblank(struct device *dev); +const u32* mtk_ovl_get_formats(struct device *dev); +size_t mtk_ovl_get_num_formats(struct device *dev); void mtk_rdma_bypass_shadow(struct device *dev); int mtk_rdma_clk_enable(struct device *dev); @@ -122,4 +124,6 @@ void mtk_mdp_rdma_start(struct device *dev, struct cmdq_pkt *cmdq_pkt); void mtk_mdp_rdma_stop(struct device *dev, struct cmdq_pkt *cmdq_pkt); void mtk_mdp_rdma_config(struct device *dev, struct mtk_mdp_rdma_cfg *cfg, struct cmdq_pkt *cmdq_pkt); +const u32* mtk_rdma_get_formats(struct device *dev); +size_t mtk_rdma_get_num_formats(struct device *dev); #endif diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c index 84daeaffab6a..781cd18f94ba 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c @@ -41,6 +41,7 @@ #define DISP_REG_OVL_RDMA_CTRL(n) (0x00c0 + 0x20 * (n)) #define DISP_REG_OVL_RDMA_GMC(n) (0x00c8 + 0x20 * (n)) #define DISP_REG_OVL_ADDR_MT2701 0x0040 +#define DISP_REG_OVL_CLRFMT_EXT0x02D0 #define DISP_REG_OVL_ADDR_MT8173 0x0f40 #define DISP_REG_OVL_ADDR(ovl, n) ((ovl)->data->addr + 0x20 * (n)) #define DISP_REG_OVL_HDR_ADDR(ovl, n) ((ovl)->data->addr + 0x20 * (n) + 0x04) @@ -61,11 +62,45 @@ 0 : OVL_CON_CLRFMT_RGB) #define OVL_CON_CLRFMT_RGB888(ovl) ((ovl)->data->fmt_rgb565_is_0 ? \ OVL_CON_CLRFMT_RGB : 0) +#define OVL_CON_CLRFMT_BIT_DEPTH_MASK(ovl) (0xFF << 4 * (ovl)) +#define OVL_CON_CLRFMT_BIT_DEPTH(depth, ovl) (depth << 4 * (ovl)) +#define OVL_CON_CLRFMT_8_BIT 0x00 +#define OVL_CON_CLRFMT_10_BIT 0x01 #defineOVL_CON_AEN BIT(8) #defineOVL_CON_ALPHA 0xff #defineOVL_CON_VIRT_FLIP BIT(9) #defineOVL_CON_HORZ_FLIP BIT(10) +static const u32 formats_mt8173[] = { + DRM_FORMAT_XRGB, + DRM_FORMAT_ARGB, + DRM_FORMAT_BGRX, + DRM_FORMAT_BGRA, + DRM_FORMAT_ABGR, + DRM_FORMAT_XBGR, + DRM_FORMAT_RGB888, + DRM_FORMAT_BGR888, + DRM_FORMAT_RGB565, + DRM_FORMAT_UYVY, + DRM_FORMAT_YUYV, +}; + +static const u32 formats_mt8195[] = { + DRM_FORMAT_XRGB, + DRM_FORMAT_ARGB, + DRM_FORMAT_ARGB2101010, + DRM_FORMAT_BGRX, + DRM_FORMAT_BGRA, + DRM_FORMAT_BGRA1010102, + DRM_FORMAT_ABGR, + DRM_FORMAT_XBGR, + DRM_FORMAT_RGB888, + DRM_FORMAT_BGR888, + DRM_FORMAT_RGB565, + DRM_FORMAT_UYVY, + DRM_FORMAT_YUYV, +}; + struct mtk_disp_ovl_data { unsigned int addr; unsigned int gmc_bits; @@ -73,6 +108,7 @@ struct mtk_disp_ovl_data { bool fmt_rgb565_is_0; bool smi_id_en; bool supports_afbc; + bool supports_10bit; }; /* @@ -188,6 +224,26 @@ static void mtk_ovl_set_afbc(struct mtk_disp_ovl *ovl, struct cmdq_pkt *cmdq_pkt DISP_REG_OVL_DATAPATH_CON, OVL_LAYER_AFBC_EN(idx)); } +static void mtk_ovl_set_bit_depth(struct device *dev, int idx, u32 format, + struct cmdq_pkt *cmdq_pkt) +{ + struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); + unsigned int reg; + unsigned int bit_depth = OVL_CON_CLRFMT_8_BIT; + + reg = readl(ovl->regs + DISP_REG_OVL_CLRFMT_EXT); + reg &= ~OVL_CON_CLRFMT_BIT_DEPTH_MASK(idx); + + if (format == DRM_FORMAT_RGBA1010102
[PATCH v3] drm/mediatek: Add support for AR30 and BA30
Add support for AR30 and BA30 pixel formats to the Mediatek DRM driver. Tested using "modetest -P" on an MT8195. Signed-off-by: Justin Green --- v2: * Rebase and resolve merge conflicts with the AFBC patch. v3: * Moved 10-bit support detection to mtk_disk_ovl.c drivers/gpu/drm/mediatek/mtk_disp_drv.h | 1 + drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 37 + drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 3 +- drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 1 + drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 10 ++ drivers/gpu/drm/mediatek/mtk_drm_plane.c| 37 ++--- drivers/gpu/drm/mediatek/mtk_drm_plane.h| 2 +- 7 files changed, 84 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h b/drivers/gpu/drm/mediatek/mtk_disp_drv.h index 33e61a136bbc..b75139da3032 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h +++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h @@ -96,6 +96,7 @@ void mtk_ovl_register_vblank_cb(struct device *dev, void mtk_ovl_unregister_vblank_cb(struct device *dev); void mtk_ovl_enable_vblank(struct device *dev); void mtk_ovl_disable_vblank(struct device *dev); +int mtk_ovl_supports_10bit(struct device *dev); void mtk_rdma_bypass_shadow(struct device *dev); int mtk_rdma_clk_enable(struct device *dev); diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c index 84daeaffab6a..412a749a509e 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c @@ -41,6 +41,7 @@ #define DISP_REG_OVL_RDMA_CTRL(n) (0x00c0 + 0x20 * (n)) #define DISP_REG_OVL_RDMA_GMC(n) (0x00c8 + 0x20 * (n)) #define DISP_REG_OVL_ADDR_MT2701 0x0040 +#define DISP_REG_OVL_CLRFMT_EXT0x02D0 #define DISP_REG_OVL_ADDR_MT8173 0x0f40 #define DISP_REG_OVL_ADDR(ovl, n) ((ovl)->data->addr + 0x20 * (n)) #define DISP_REG_OVL_HDR_ADDR(ovl, n) ((ovl)->data->addr + 0x20 * (n) + 0x04) @@ -61,6 +62,10 @@ 0 : OVL_CON_CLRFMT_RGB) #define OVL_CON_CLRFMT_RGB888(ovl) ((ovl)->data->fmt_rgb565_is_0 ? \ OVL_CON_CLRFMT_RGB : 0) +#define OVL_CON_CLRFMT_BIT_DEPTH_MASK(ovl) (0xFF << 4 * (ovl)) +#define OVL_CON_CLRFMT_BIT_DEPTH(depth, ovl) (depth << 4 * (ovl)) +#define OVL_CON_CLRFMT_8_BIT 0x00 +#define OVL_CON_CLRFMT_10_BIT 0x01 #defineOVL_CON_AEN BIT(8) #defineOVL_CON_ALPHA 0xff #defineOVL_CON_VIRT_FLIP BIT(9) @@ -73,6 +78,7 @@ struct mtk_disp_ovl_data { bool fmt_rgb565_is_0; bool smi_id_en; bool supports_afbc; + bool supports_10bit; }; /* @@ -188,6 +194,26 @@ static void mtk_ovl_set_afbc(struct mtk_disp_ovl *ovl, struct cmdq_pkt *cmdq_pkt DISP_REG_OVL_DATAPATH_CON, OVL_LAYER_AFBC_EN(idx)); } +static void mtk_ovl_set_bit_depth(struct device *dev, int idx, u32 format, + struct cmdq_pkt *cmdq_pkt) +{ + struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); + unsigned int reg; + unsigned int bit_depth = OVL_CON_CLRFMT_8_BIT; + + reg = readl(ovl->regs + DISP_REG_OVL_CLRFMT_EXT); + reg &= ~OVL_CON_CLRFMT_BIT_DEPTH_MASK(idx); + + if (format == DRM_FORMAT_RGBA1010102 || + format == DRM_FORMAT_BGRA1010102 || + format == DRM_FORMAT_ARGB2101010) + bit_depth = OVL_CON_CLRFMT_10_BIT; + + reg |= OVL_CON_CLRFMT_BIT_DEPTH(bit_depth, idx); + + mtk_ddp_write(cmdq_pkt, reg, &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_CLRFMT_EXT); +} + void mtk_ovl_config(struct device *dev, unsigned int w, unsigned int h, unsigned int vrefresh, unsigned int bpc, struct cmdq_pkt *cmdq_pkt) @@ -216,6 +242,13 @@ unsigned int mtk_ovl_supported_rotations(struct device *dev) DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y; } +int mtk_ovl_supports_10bit(struct device *dev) +{ + struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); + + return ovl->data->supports_10bit; +} + int mtk_ovl_layer_check(struct device *dev, unsigned int idx, struct mtk_plane_state *mtk_state) { @@ -302,9 +335,11 @@ static unsigned int ovl_fmt_convert(struct mtk_disp_ovl *ovl, unsigned int fmt) return OVL_CON_CLRFMT_ARGB; case DRM_FORMAT_BGRX: case DRM_FORMAT_BGRA: + case DRM_FORMAT_BGRA1010102: return OVL_CON_CLRFMT_ARGB | OVL_CON_BYTE_SWAP; case DRM_FORMAT_XRGB: case DRM_FORMAT_ARGB: + case DRM_FORMAT_ARGB2101010: return OVL_CON_CLRFMT_RGBA; case DRM_FORMAT_XBGR: case DRM_FORMAT_ABGR: @@ -388,6 +423,7 @@
Re: [PATCH v2] drm/mediatek: Add support for AR30 and BA30
Thanks for the suggestion! That's a lot cleaner than manually traversing the device tree. Will send out another patch. On Thu, Jan 26, 2023 at 7:36 PM Chun-Kuang Hu wrote: > > Hi, Justin: > > Justin Green 於 2023年1月11日 週三 上午4:47寫道: > > > > Add support for AR30 and BA30 pixel formats to the Mediatek DRM driver. > > > > Tested using "modetest -P" on an MT8195. > > > > Signed-off-by: Justin Green > > --- > > v2: > > * Rebase and resolve merge conflicts with the AFBC patch. > > > > drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 28 + > > drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 19 +++- > > drivers/gpu/drm/mediatek/mtk_drm_plane.c | 39 +--- > > drivers/gpu/drm/mediatek/mtk_drm_plane.h | 2 +- > > 4 files changed, 81 insertions(+), 7 deletions(-) > > > > diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c > > b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c > > index 84daeaffab6a..667ae57c8754 100644 > > --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c > > +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c > > @@ -41,6 +41,7 @@ > > #define DISP_REG_OVL_RDMA_CTRL(n) (0x00c0 + 0x20 * (n)) > > #define DISP_REG_OVL_RDMA_GMC(n) (0x00c8 + 0x20 * (n)) > > #define DISP_REG_OVL_ADDR_MT2701 0x0040 > > +#define DISP_REG_OVL_CLRFMT_EXT0x02D0 > > #define DISP_REG_OVL_ADDR_MT8173 0x0f40 > > #define DISP_REG_OVL_ADDR(ovl, n) ((ovl)->data->addr + 0x20 * > > (n)) > > #define DISP_REG_OVL_HDR_ADDR(ovl, n) ((ovl)->data->addr + 0x20 * > > (n) + 0x04) > > @@ -61,6 +62,10 @@ > > 0 : OVL_CON_CLRFMT_RGB) > > #define OVL_CON_CLRFMT_RGB888(ovl) ((ovl)->data->fmt_rgb565_is_0 ? \ > > OVL_CON_CLRFMT_RGB : 0) > > +#define OVL_CON_CLRFMT_BIT_DEPTH_MASK(ovl) (0xFF << 4 * (ovl)) > > +#define OVL_CON_CLRFMT_BIT_DEPTH(depth, ovl) (depth << 4 * (ovl)) > > +#define OVL_CON_CLRFMT_8_BIT 0x00 > > +#define OVL_CON_CLRFMT_10_BIT 0x01 > > #defineOVL_CON_AEN BIT(8) > > #defineOVL_CON_ALPHA 0xff > > #defineOVL_CON_VIRT_FLIP BIT(9) > > @@ -188,6 +193,26 @@ static void mtk_ovl_set_afbc(struct mtk_disp_ovl *ovl, > > struct cmdq_pkt *cmdq_pkt > >DISP_REG_OVL_DATAPATH_CON, > > OVL_LAYER_AFBC_EN(idx)); > > } > > > > +static void mtk_ovl_set_bit_depth(struct device *dev, int idx, u32 format, > > + struct cmdq_pkt *cmdq_pkt) > > +{ > > + struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); > > + unsigned int reg; > > + unsigned int bit_depth = OVL_CON_CLRFMT_8_BIT; > > + > > + reg = readl(ovl->regs + DISP_REG_OVL_CLRFMT_EXT); > > + reg &= ~OVL_CON_CLRFMT_BIT_DEPTH_MASK(idx); > > + > > + if (format == DRM_FORMAT_RGBA1010102 || > > + format == DRM_FORMAT_BGRA1010102 || > > + format == DRM_FORMAT_ARGB2101010) > > + bit_depth = OVL_CON_CLRFMT_10_BIT; > > + > > + reg |= OVL_CON_CLRFMT_BIT_DEPTH(bit_depth, idx); > > + > > + mtk_ddp_write(cmdq_pkt, reg, &ovl->cmdq_reg, ovl->regs, > > DISP_REG_OVL_CLRFMT_EXT); > > +} > > + > > void mtk_ovl_config(struct device *dev, unsigned int w, > > unsigned int h, unsigned int vrefresh, > > unsigned int bpc, struct cmdq_pkt *cmdq_pkt) > > @@ -302,9 +327,11 @@ static unsigned int ovl_fmt_convert(struct > > mtk_disp_ovl *ovl, unsigned int fmt) > > return OVL_CON_CLRFMT_ARGB; > > case DRM_FORMAT_BGRX: > > case DRM_FORMAT_BGRA: > > + case DRM_FORMAT_BGRA1010102: > > return OVL_CON_CLRFMT_ARGB | OVL_CON_BYTE_SWAP; > > case DRM_FORMAT_XRGB: > > case DRM_FORMAT_ARGB: > > + case DRM_FORMAT_ARGB2101010: > > return OVL_CON_CLRFMT_RGBA; > > case DRM_FORMAT_XBGR: > > case DRM_FORMAT_ABGR: > > @@ -388,6 +415,7 @@ void mtk_ovl_layer_config(struct device *dev, unsigned > > int idx, > > &ovl->cmdq_reg, ovl->regs, > > DISP_REG_OVL_PITCH_MSB(idx)); > > } > > > > + mtk_ovl_set_bit_depth(dev, idx, fmt, cmdq_pkt); > &
[PATCH v2] drm/mediatek: Add support for AR30 and BA30
Add support for AR30 and BA30 pixel formats to the Mediatek DRM driver. Tested using "modetest -P" on an MT8195. Signed-off-by: Justin Green --- v2: * Rebase and resolve merge conflicts with the AFBC patch. drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 28 + drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 19 +++- drivers/gpu/drm/mediatek/mtk_drm_plane.c | 39 +--- drivers/gpu/drm/mediatek/mtk_drm_plane.h | 2 +- 4 files changed, 81 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c index 84daeaffab6a..667ae57c8754 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c @@ -41,6 +41,7 @@ #define DISP_REG_OVL_RDMA_CTRL(n) (0x00c0 + 0x20 * (n)) #define DISP_REG_OVL_RDMA_GMC(n) (0x00c8 + 0x20 * (n)) #define DISP_REG_OVL_ADDR_MT2701 0x0040 +#define DISP_REG_OVL_CLRFMT_EXT0x02D0 #define DISP_REG_OVL_ADDR_MT8173 0x0f40 #define DISP_REG_OVL_ADDR(ovl, n) ((ovl)->data->addr + 0x20 * (n)) #define DISP_REG_OVL_HDR_ADDR(ovl, n) ((ovl)->data->addr + 0x20 * (n) + 0x04) @@ -61,6 +62,10 @@ 0 : OVL_CON_CLRFMT_RGB) #define OVL_CON_CLRFMT_RGB888(ovl) ((ovl)->data->fmt_rgb565_is_0 ? \ OVL_CON_CLRFMT_RGB : 0) +#define OVL_CON_CLRFMT_BIT_DEPTH_MASK(ovl) (0xFF << 4 * (ovl)) +#define OVL_CON_CLRFMT_BIT_DEPTH(depth, ovl) (depth << 4 * (ovl)) +#define OVL_CON_CLRFMT_8_BIT 0x00 +#define OVL_CON_CLRFMT_10_BIT 0x01 #defineOVL_CON_AEN BIT(8) #defineOVL_CON_ALPHA 0xff #defineOVL_CON_VIRT_FLIP BIT(9) @@ -188,6 +193,26 @@ static void mtk_ovl_set_afbc(struct mtk_disp_ovl *ovl, struct cmdq_pkt *cmdq_pkt DISP_REG_OVL_DATAPATH_CON, OVL_LAYER_AFBC_EN(idx)); } +static void mtk_ovl_set_bit_depth(struct device *dev, int idx, u32 format, + struct cmdq_pkt *cmdq_pkt) +{ + struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); + unsigned int reg; + unsigned int bit_depth = OVL_CON_CLRFMT_8_BIT; + + reg = readl(ovl->regs + DISP_REG_OVL_CLRFMT_EXT); + reg &= ~OVL_CON_CLRFMT_BIT_DEPTH_MASK(idx); + + if (format == DRM_FORMAT_RGBA1010102 || + format == DRM_FORMAT_BGRA1010102 || + format == DRM_FORMAT_ARGB2101010) + bit_depth = OVL_CON_CLRFMT_10_BIT; + + reg |= OVL_CON_CLRFMT_BIT_DEPTH(bit_depth, idx); + + mtk_ddp_write(cmdq_pkt, reg, &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_CLRFMT_EXT); +} + void mtk_ovl_config(struct device *dev, unsigned int w, unsigned int h, unsigned int vrefresh, unsigned int bpc, struct cmdq_pkt *cmdq_pkt) @@ -302,9 +327,11 @@ static unsigned int ovl_fmt_convert(struct mtk_disp_ovl *ovl, unsigned int fmt) return OVL_CON_CLRFMT_ARGB; case DRM_FORMAT_BGRX: case DRM_FORMAT_BGRA: + case DRM_FORMAT_BGRA1010102: return OVL_CON_CLRFMT_ARGB | OVL_CON_BYTE_SWAP; case DRM_FORMAT_XRGB: case DRM_FORMAT_ARGB: + case DRM_FORMAT_ARGB2101010: return OVL_CON_CLRFMT_RGBA; case DRM_FORMAT_XBGR: case DRM_FORMAT_ABGR: @@ -388,6 +415,7 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int idx, &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_PITCH_MSB(idx)); } + mtk_ovl_set_bit_depth(dev, idx, fmt, cmdq_pkt); mtk_ovl_layer_on(dev, idx, cmdq_pkt); } diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c index 112615817dcb..d50379c97c4b 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c @@ -842,6 +842,21 @@ enum drm_plane_type mtk_drm_crtc_plane_type(unsigned int plane_idx, } +static const char *ovls_with_10bit_cap[] = { + "mediatek,mt8195-disp-ovl", +}; + +static bool is_10bit_cap_device(void) +{ + for (int i = 0; i < ARRAY_SIZE(ovls_with_10bit_cap); i++) { + if (of_find_compatible_node(NULL, NULL, + ovls_with_10bit_cap[i])) + return true; + } + + return false; +} + static int mtk_drm_crtc_init_comp_planes(struct drm_device *drm_dev, struct mtk_drm_crtc *mtk_crtc, int comp_idx, int pipe) @@ -849,6 +864,7 @@ static int mtk_drm_crtc_init_comp_planes(struct drm_device *drm_dev, int num_planes = mtk_drm_crtc_num_comp_planes(mtk_crtc, comp_idx); struct mtk
[RESEND PATCH] drm/mediatek: Add support for AR30 and BA30
Add support for AR30 and BA30 pixel formats to the Mediatek DRM driver. Tested using "modetest -P" on an MT8195. Signed-off-by: Justin Green --- drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 29 ++ drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 19 +++- drivers/gpu/drm/mediatek/mtk_drm_plane.c | 38 drivers/gpu/drm/mediatek/mtk_drm_plane.h | 2 +- 4 files changed, 81 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c index 002b0f6cae1a..be1dfc82aab2 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c @@ -38,6 +38,7 @@ #define DISP_REG_OVL_RDMA_CTRL(n) (0x00c0 + 0x20 * (n)) #define DISP_REG_OVL_RDMA_GMC(n) (0x00c8 + 0x20 * (n)) #define DISP_REG_OVL_ADDR_MT2701 0x0040 +#define DISP_REG_OVL_CLRFMT_EXT0x02D0 #define DISP_REG_OVL_ADDR_MT8173 0x0f40 #define DISP_REG_OVL_ADDR(ovl, n) ((ovl)->data->addr + 0x20 * (n)) @@ -56,6 +57,10 @@ 0 : OVL_CON_CLRFMT_RGB) #define OVL_CON_CLRFMT_RGB888(ovl) ((ovl)->data->fmt_rgb565_is_0 ? \ OVL_CON_CLRFMT_RGB : 0) +#define OVL_CON_CLRFMT_BIT_DEPTH_MASK(ovl) (0xFF << 4 * (ovl)) +#define OVL_CON_CLRFMT_BIT_DEPTH(depth, ovl) (depth << 4 * (ovl)) +#define OVL_CON_CLRFMT_8_BIT 0x00 +#define OVL_CON_CLRFMT_10_BIT 0x01 #defineOVL_CON_AEN BIT(8) #defineOVL_CON_ALPHA 0xff #defineOVL_CON_VIRT_FLIP BIT(9) @@ -175,6 +180,26 @@ void mtk_ovl_stop(struct device *dev) } +static void mtk_ovl_set_bit_depth(struct device *dev, int idx, u32 format, + struct cmdq_pkt *cmdq_pkt) +{ + struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); + unsigned int reg; + unsigned int bit_depth = OVL_CON_CLRFMT_8_BIT; + + reg = readl(ovl->regs + DISP_REG_OVL_CLRFMT_EXT); + reg &= ~OVL_CON_CLRFMT_BIT_DEPTH_MASK(idx); + + if (format == DRM_FORMAT_RGBA1010102 || + format == DRM_FORMAT_BGRA1010102 || + format == DRM_FORMAT_ARGB2101010) + bit_depth = OVL_CON_CLRFMT_10_BIT; + + reg |= OVL_CON_CLRFMT_BIT_DEPTH(bit_depth, idx); + + mtk_ddp_write(cmdq_pkt, reg, &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_CLRFMT_EXT); +} + void mtk_ovl_config(struct device *dev, unsigned int w, unsigned int h, unsigned int vrefresh, unsigned int bpc, struct cmdq_pkt *cmdq_pkt) @@ -289,9 +314,11 @@ static unsigned int ovl_fmt_convert(struct mtk_disp_ovl *ovl, unsigned int fmt) return OVL_CON_CLRFMT_ARGB; case DRM_FORMAT_BGRX: case DRM_FORMAT_BGRA: + case DRM_FORMAT_BGRA1010102: return OVL_CON_CLRFMT_ARGB | OVL_CON_BYTE_SWAP; case DRM_FORMAT_XRGB: case DRM_FORMAT_ARGB: + case DRM_FORMAT_ARGB2101010: return OVL_CON_CLRFMT_RGBA; case DRM_FORMAT_XBGR: case DRM_FORMAT_ABGR: @@ -346,6 +373,8 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int idx, mtk_ddp_write_relaxed(cmdq_pkt, addr, &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_ADDR(ovl, idx)); + mtk_ovl_set_bit_depth(dev, idx, fmt, cmdq_pkt); + mtk_ovl_layer_on(dev, idx, cmdq_pkt); } diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c index 42cc7052b050..b2b944344c7a 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c @@ -843,6 +843,21 @@ enum drm_plane_type mtk_drm_crtc_plane_type(unsigned int plane_idx, } +static const char *ovls_with_10bit_cap[] = { + "mediatek,mt8195-disp-ovl", +}; + +static bool is_10bit_cap_device(void) +{ + for (int i = 0; i < ARRAY_SIZE(ovls_with_10bit_cap); i++) { + if (of_find_compatible_node(NULL, NULL, + ovls_with_10bit_cap[i])) + return true; + } + + return false; +} + static int mtk_drm_crtc_init_comp_planes(struct drm_device *drm_dev, struct mtk_drm_crtc *mtk_crtc, int comp_idx, int pipe) @@ -850,6 +865,7 @@ static int mtk_drm_crtc_init_comp_planes(struct drm_device *drm_dev, int num_planes = mtk_drm_crtc_num_comp_planes(mtk_crtc, comp_idx); struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[comp_idx]; int i, ret; + bool supports_10bit = is_10bit_cap_device(); for (i = 0; i < num_planes; i++) { ret = mtk_plane_init(drm_dev, @@ -857,7 +873,8 @@ static int mtk_drm_crtc_init_
[PATCH v5] drm/mediatek: Add AFBC support to Mediatek DRM driver
From: Justin Green Tested on MT8195 and confirmed both correct video output and improved DRAM bandwidth performance. v5: * Removed some dead defines. * Refactored mtk_ovl_set_afbc(). v4: * Move modifier validation to format_mod_supported function. * Add modifiers to drm_universal_plane_init() call. * Make comparisons to DRM_FORMAT_MOD_LINEAR explicit rather than relying on DRM_FORMAT_LINEAR being equal to 0. * Gate AFBC control bit writes on device compatibility. v3: * Replaced pitch bitshift math with union based approach. * Refactored overlay register writes to shared code between non-AFBC and AFBC. * Minor code cleanups. v2: * Marked mtk_ovl_set_afbc as static. * Reflowed some lines to fit column limit. Signed-off-by: Justin Green --- drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 57 +- drivers/gpu/drm/mediatek/mtk_drm_plane.c | 74 +++- drivers/gpu/drm/mediatek/mtk_drm_plane.h | 8 +++ 3 files changed, 134 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c index 002b0f6cae1a..5a59e7b99c5d 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c @@ -29,17 +29,22 @@ #define DISP_REG_OVL_DATAPATH_CON 0x0024 #define OVL_LAYER_SMI_ID_ENBIT(0) #define OVL_BGCLR_SEL_IN BIT(2) +#define OVL_LAYER_AFBC_EN(n) BIT(4+n) #define DISP_REG_OVL_ROI_BGCLR 0x0028 #define DISP_REG_OVL_SRC_CON 0x002c #define DISP_REG_OVL_CON(n)(0x0030 + 0x20 * (n)) #define DISP_REG_OVL_SRC_SIZE(n) (0x0038 + 0x20 * (n)) #define DISP_REG_OVL_OFFSET(n) (0x003c + 0x20 * (n)) +#define DISP_REG_OVL_PITCH_MSB(n) (0x0040 + 0x20 * (n)) +#define OVL_PITCH_MSB_2ND_SUBBUF BIT(16) #define DISP_REG_OVL_PITCH(n) (0x0044 + 0x20 * (n)) #define DISP_REG_OVL_RDMA_CTRL(n) (0x00c0 + 0x20 * (n)) #define DISP_REG_OVL_RDMA_GMC(n) (0x00c8 + 0x20 * (n)) #define DISP_REG_OVL_ADDR_MT2701 0x0040 #define DISP_REG_OVL_ADDR_MT8173 0x0f40 #define DISP_REG_OVL_ADDR(ovl, n) ((ovl)->data->addr + 0x20 * (n)) +#define DISP_REG_OVL_HDR_ADDR(ovl, n) ((ovl)->data->addr + 0x20 * (n) + 0x04) +#define DISP_REG_OVL_HDR_PITCH(ovl, n) ((ovl)->data->addr + 0x20 * (n) + 0x08) #define GMC_THRESHOLD_BITS 16 #define GMC_THRESHOLD_HIGH ((1 << GMC_THRESHOLD_BITS) / 4) @@ -67,6 +72,7 @@ struct mtk_disp_ovl_data { unsigned int layer_nr; bool fmt_rgb565_is_0; bool smi_id_en; + bool supports_afbc; }; /* @@ -172,7 +178,14 @@ void mtk_ovl_stop(struct device *dev) reg = reg & ~OVL_LAYER_SMI_ID_EN; writel_relaxed(reg, ovl->regs + DISP_REG_OVL_DATAPATH_CON); } +} +static void mtk_ovl_set_afbc(struct mtk_disp_ovl *ovl, struct cmdq_pkt *cmdq_pkt, +int idx, bool enabled) +{ + mtk_ddp_write_mask(cmdq_pkt, enabled ? OVL_LAYER_AFBC_EN(idx) : 0, + &ovl->cmdq_reg, ovl->regs, + DISP_REG_OVL_DATAPATH_CON, OVL_LAYER_AFBC_EN(idx)); } void mtk_ovl_config(struct device *dev, unsigned int w, @@ -310,11 +323,23 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int idx, struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); struct mtk_plane_pending_state *pending = &state->pending; unsigned int addr = pending->addr; - unsigned int pitch = pending->pitch & 0x; + unsigned int hdr_addr = pending->hdr_addr; + unsigned int pitch = pending->pitch; + unsigned int hdr_pitch = pending->hdr_pitch; unsigned int fmt = pending->format; unsigned int offset = (pending->y << 16) | pending->x; unsigned int src_size = (pending->height << 16) | pending->width; unsigned int con; + bool is_afbc = pending->modifier != DRM_FORMAT_MOD_LINEAR; + union overlay_pitch { + struct split_pitch { + u16 lsb; + u16 msb; + } split_pitch; + u32 pitch; + } overlay_pitch; + + overlay_pitch.pitch = pitch; if (!pending->enable) { mtk_ovl_layer_off(dev, idx, cmdq_pkt); @@ -335,9 +360,12 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int idx, addr += pending->pitch - 1; } + if (ovl->data->supports_afbc) + mtk_ovl_set_afbc(ovl, cmdq_pkt, idx, is_afbc); + mtk_ddp_write_relaxed(cmdq_pkt, con, &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_CON(idx)); - mtk_ddp_write_re
Re: [PATCH v3] drm/mediatek: Add AFBC support to Mediatek DRM driver
Hi Chun-Kuang, > > + mtk_ovl_set_afbc(dev, cmdq_pkt, idx, is_afbc); > > mtk_ddp_write_relaxed(cmdq_pkt, con, &ovl->cmdq_reg, ovl->regs, > > DISP_REG_OVL_CON(idx)); > > - mtk_ddp_write_relaxed(cmdq_pkt, pitch, &ovl->cmdq_reg, ovl->regs, > > + mtk_ddp_write_relaxed(cmdq_pkt, overlay_pitch.split_pitch.lsb, > > &ovl->cmdq_reg, ovl->regs, > > DISP_REG_OVL_PITCH(idx)); > > Is this general for all MediaTek SoC? If so, separate this to an > independent patch. Otherwise, use a device variable to separate this > setting. Yes and no. Technically all MediaTek SoCs have two separate registers for the pitch, each are 16 bits, so this code is technically always needed. However, because the lsb register is 16 bit, this issue has never come up, because nobody has tried to display a plane that was 16384 ARGB pixels across. In fact, I think most MediaTek SoCs have a resolution limit of 4K. The reason this issue comes up now is because "pitch" is calculated differently for AFBC frames, and actually refers to the size in bytes of one row of AFBC blocks. Should I still separate this into an independent patch? > > } > > @@ -492,6 +567,15 @@ static const struct mtk_disp_ovl_data > > mt8192_ovl_2l_driver_data = { > > .smi_id_en = true, > > }; > > > > +static const struct mtk_disp_ovl_data mt8195_ovl_driver_data = { > > In this binding document, mt8195 ovl is compatible to mt8133 ovl. > Please confirm that mt8195 is not identical with mt8133. Do you mean MT8183? If so, we do not have any documentation indicating that the MT8183 supports AFBC. Do you have some reason to believe otherwise? > Usually the pitch needs alignment. So I guess the formula is > > hdr_pitch = ALIGN(width_in_blocks * AFBC_HEADER_BLOCK_SIZE, > AFBC_HEADER_ALIGNMENT); > hdr_size = hdr_pitch * height_in_blocks; The documentation does not indicate that the pitch needs alignment beyond the AFBC header block size. > Could you explain the meaning of hdr_pitch? hdr_pitch refers to the size in bytes of one row of AFBC header blocks. AFBC is a proprietary compressed frame buffer format, but from what public information we have, it appears to be block compressed data stored in 2 contiguous planes. The first is called the "header" plane, and the second is called the "body" plane. The header plane contains metadata for each block of pixel data, and the body plane contains sparse compressed block data. I'll send another patch with the other changes you mentioned. Thanks! Justin
[PATCH] drm/mediatek: Add support for AR30 and BA30
Add support for AR30 and BA30 pixel formats to the Mediatek DRM driver. Tested using "modetest -P" on an MT8195. Signed-off-by: Justin Green --- drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 29 ++ drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 19 +++- drivers/gpu/drm/mediatek/mtk_drm_plane.c | 38 drivers/gpu/drm/mediatek/mtk_drm_plane.h | 2 +- 4 files changed, 81 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c index 002b0f6cae1a..be1dfc82aab2 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c @@ -38,6 +38,7 @@ #define DISP_REG_OVL_RDMA_CTRL(n) (0x00c0 + 0x20 * (n)) #define DISP_REG_OVL_RDMA_GMC(n) (0x00c8 + 0x20 * (n)) #define DISP_REG_OVL_ADDR_MT2701 0x0040 +#define DISP_REG_OVL_CLRFMT_EXT0x02D0 #define DISP_REG_OVL_ADDR_MT8173 0x0f40 #define DISP_REG_OVL_ADDR(ovl, n) ((ovl)->data->addr + 0x20 * (n)) @@ -56,6 +57,10 @@ 0 : OVL_CON_CLRFMT_RGB) #define OVL_CON_CLRFMT_RGB888(ovl) ((ovl)->data->fmt_rgb565_is_0 ? \ OVL_CON_CLRFMT_RGB : 0) +#define OVL_CON_CLRFMT_BIT_DEPTH_MASK(ovl) (0xFF << 4 * (ovl)) +#define OVL_CON_CLRFMT_BIT_DEPTH(depth, ovl) (depth << 4 * (ovl)) +#define OVL_CON_CLRFMT_8_BIT 0x00 +#define OVL_CON_CLRFMT_10_BIT 0x01 #defineOVL_CON_AEN BIT(8) #defineOVL_CON_ALPHA 0xff #defineOVL_CON_VIRT_FLIP BIT(9) @@ -175,6 +180,26 @@ void mtk_ovl_stop(struct device *dev) } +static void mtk_ovl_set_bit_depth(struct device *dev, int idx, u32 format, + struct cmdq_pkt *cmdq_pkt) +{ + struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); + unsigned int reg; + unsigned int bit_depth = OVL_CON_CLRFMT_8_BIT; + + reg = readl(ovl->regs + DISP_REG_OVL_CLRFMT_EXT); + reg &= ~OVL_CON_CLRFMT_BIT_DEPTH_MASK(idx); + + if (format == DRM_FORMAT_RGBA1010102 || + format == DRM_FORMAT_BGRA1010102 || + format == DRM_FORMAT_ARGB2101010) + bit_depth = OVL_CON_CLRFMT_10_BIT; + + reg |= OVL_CON_CLRFMT_BIT_DEPTH(bit_depth, idx); + + mtk_ddp_write(cmdq_pkt, reg, &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_CLRFMT_EXT); +} + void mtk_ovl_config(struct device *dev, unsigned int w, unsigned int h, unsigned int vrefresh, unsigned int bpc, struct cmdq_pkt *cmdq_pkt) @@ -289,9 +314,11 @@ static unsigned int ovl_fmt_convert(struct mtk_disp_ovl *ovl, unsigned int fmt) return OVL_CON_CLRFMT_ARGB; case DRM_FORMAT_BGRX: case DRM_FORMAT_BGRA: + case DRM_FORMAT_BGRA1010102: return OVL_CON_CLRFMT_ARGB | OVL_CON_BYTE_SWAP; case DRM_FORMAT_XRGB: case DRM_FORMAT_ARGB: + case DRM_FORMAT_ARGB2101010: return OVL_CON_CLRFMT_RGBA; case DRM_FORMAT_XBGR: case DRM_FORMAT_ABGR: @@ -346,6 +373,8 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int idx, mtk_ddp_write_relaxed(cmdq_pkt, addr, &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_ADDR(ovl, idx)); + mtk_ovl_set_bit_depth(dev, idx, fmt, cmdq_pkt); + mtk_ovl_layer_on(dev, idx, cmdq_pkt); } diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c index 42cc7052b050..b2b944344c7a 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c @@ -843,6 +843,21 @@ enum drm_plane_type mtk_drm_crtc_plane_type(unsigned int plane_idx, } +static const char *ovls_with_10bit_cap[] = { + "mediatek,mt8195-disp-ovl", +}; + +static bool is_10bit_cap_device(void) +{ + for (int i = 0; i < ARRAY_SIZE(ovls_with_10bit_cap); i++) { + if (of_find_compatible_node(NULL, NULL, + ovls_with_10bit_cap[i])) + return true; + } + + return false; +} + static int mtk_drm_crtc_init_comp_planes(struct drm_device *drm_dev, struct mtk_drm_crtc *mtk_crtc, int comp_idx, int pipe) @@ -850,6 +865,7 @@ static int mtk_drm_crtc_init_comp_planes(struct drm_device *drm_dev, int num_planes = mtk_drm_crtc_num_comp_planes(mtk_crtc, comp_idx); struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[comp_idx]; int i, ret; + bool supports_10bit = is_10bit_cap_device(); for (i = 0; i < num_planes; i++) { ret = mtk_plane_init(drm_dev, @@ -857,
[PATCH v4] drm/mediatek: Add AFBC support to Mediatek DRM driver
Tested on MT8195 and confirmed both correct video output and improved DRAM bandwidth performance. v4: * Move modifier validation to format_mod_supported function. * Add modifiers to drm_universal_plane_init() call. * Make comparisons to DRM_FORMAT_MOD_LINEAR explicit rather than relying on DRM_FORMAT_LINEAR being equal to 0. * Gate AFBC control bit writes on device compatibility. v3: * Replaced pitch bitshift math with union based approach. * Refactored overlay register writes to shared code between non-AFBC and AFBC. * Minor code cleanups. v2: * Marked mtk_ovl_set_afbc as static. * Reflowed some lines to fit column limit. Signed-off-by: Justin Green --- drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 67 - drivers/gpu/drm/mediatek/mtk_drm_plane.c | 74 +++- drivers/gpu/drm/mediatek/mtk_drm_plane.h | 8 +++ 3 files changed, 144 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c index 002b0f6cae1a..6d4c0e44a2f1 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c @@ -29,17 +29,24 @@ #define DISP_REG_OVL_DATAPATH_CON 0x0024 #define OVL_LAYER_SMI_ID_ENBIT(0) #define OVL_BGCLR_SEL_IN BIT(2) +#define OVL_LAYER_AFBC_EN(n) BIT(4+n) #define DISP_REG_OVL_ROI_BGCLR 0x0028 #define DISP_REG_OVL_SRC_CON 0x002c #define DISP_REG_OVL_CON(n)(0x0030 + 0x20 * (n)) #define DISP_REG_OVL_SRC_SIZE(n) (0x0038 + 0x20 * (n)) #define DISP_REG_OVL_OFFSET(n) (0x003c + 0x20 * (n)) +#define DISP_REG_OVL_PITCH_MSB(n) (0x0040 + 0x20 * (n)) +#define OVL_PITCH_MSB_2ND_SUBBUF BIT(16) +#define OVL_PITCH_MSB_YUV_TRANSBIT(20) #define DISP_REG_OVL_PITCH(n) (0x0044 + 0x20 * (n)) +#define DISP_REG_OVL_CLIP(n) (0x004c + 0x20 * (n)) #define DISP_REG_OVL_RDMA_CTRL(n) (0x00c0 + 0x20 * (n)) #define DISP_REG_OVL_RDMA_GMC(n) (0x00c8 + 0x20 * (n)) #define DISP_REG_OVL_ADDR_MT2701 0x0040 #define DISP_REG_OVL_ADDR_MT8173 0x0f40 #define DISP_REG_OVL_ADDR(ovl, n) ((ovl)->data->addr + 0x20 * (n)) +#define DISP_REG_OVL_HDR_ADDR(ovl, n) ((ovl)->data->addr + 0x20 * (n) + 0x04) +#define DISP_REG_OVL_HDR_PITCH(ovl, n) ((ovl)->data->addr + 0x20 * (n) + 0x08) #define GMC_THRESHOLD_BITS 16 #define GMC_THRESHOLD_HIGH ((1 << GMC_THRESHOLD_BITS) / 4) @@ -67,6 +74,7 @@ struct mtk_disp_ovl_data { unsigned int layer_nr; bool fmt_rgb565_is_0; bool smi_id_en; + bool supports_afbc; }; /* @@ -172,7 +180,22 @@ void mtk_ovl_stop(struct device *dev) reg = reg & ~OVL_LAYER_SMI_ID_EN; writel_relaxed(reg, ovl->regs + DISP_REG_OVL_DATAPATH_CON); } +} + +static void mtk_ovl_set_afbc(struct device *dev, struct cmdq_pkt *cmdq_pkt, +int idx, bool enabled) +{ + struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); + unsigned int reg; + reg = readl(ovl->regs + DISP_REG_OVL_DATAPATH_CON); + if (enabled) + reg = reg | OVL_LAYER_AFBC_EN(idx); + else + reg = reg & ~OVL_LAYER_AFBC_EN(idx); + + mtk_ddp_write_relaxed(cmdq_pkt, reg, &ovl->cmdq_reg, + ovl->regs, DISP_REG_OVL_DATAPATH_CON); } void mtk_ovl_config(struct device *dev, unsigned int w, @@ -310,11 +333,23 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int idx, struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); struct mtk_plane_pending_state *pending = &state->pending; unsigned int addr = pending->addr; - unsigned int pitch = pending->pitch & 0x; + unsigned int hdr_addr = pending->hdr_addr; + unsigned int pitch = pending->pitch; + unsigned int hdr_pitch = pending->hdr_pitch; unsigned int fmt = pending->format; unsigned int offset = (pending->y << 16) | pending->x; unsigned int src_size = (pending->height << 16) | pending->width; unsigned int con; + bool is_afbc = pending->modifier != DRM_FORMAT_MOD_LINEAR; + union overlay_pitch { + struct split_pitch { + u16 lsb; + u16 msb; + } split_pitch; + u32 pitch; + } overlay_pitch; + + overlay_pitch.pitch = pitch; if (!pending->enable) { mtk_ovl_layer_off(dev, idx, cmdq_pkt); @@ -335,9 +370,12 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int idx, addr += pending->pitch - 1;
Re: [PATCH v3] drm/mediatek: Add AFBC support to Mediatek DRM driver
Thanks for the comments everyone! I'll upload a new CL sometime today. I did want to ask though, I realize I should be using u32/u64 for kernel code in general, but the rest of this file seems to be written using unsigned int/unsigned long long. In this circumstance, does keeping with the style of the original source take precedence over general style guidelines, or vice versa?
[PATCH v3] drm/mediatek: Add AFBC support to Mediatek DRM driver
Tested on MT8195 and confirmed both correct video output and improved DRAM bandwidth performance. v3: * Replaced pitch bitshift math with union based approach. * Refactored overlay register writes to shared code between non-AFBC and AFBC. * Minor code cleanups. v2: * Marked mtk_ovl_set_afbc as static. * Reflowed some lines to fit column limit. Signed-off-by: Justin Green --- drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 90 +++- drivers/gpu/drm/mediatek/mtk_drm_plane.c | 37 +- drivers/gpu/drm/mediatek/mtk_drm_plane.h | 8 +++ 3 files changed, 131 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c index 002b0f6cae1a..3f89b5f5064f 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c @@ -29,17 +29,24 @@ #define DISP_REG_OVL_DATAPATH_CON 0x0024 #define OVL_LAYER_SMI_ID_ENBIT(0) #define OVL_BGCLR_SEL_IN BIT(2) +#define OVL_LAYER_AFBC_EN(n) BIT(4+n) #define DISP_REG_OVL_ROI_BGCLR 0x0028 #define DISP_REG_OVL_SRC_CON 0x002c #define DISP_REG_OVL_CON(n)(0x0030 + 0x20 * (n)) #define DISP_REG_OVL_SRC_SIZE(n) (0x0038 + 0x20 * (n)) #define DISP_REG_OVL_OFFSET(n) (0x003c + 0x20 * (n)) +#define DISP_REG_OVL_PITCH_MSB(n) (0x0040 + 0x20 * (n)) +#define OVL_PITCH_MSB_2ND_SUBBUF BIT(16) +#define OVL_PITCH_MSB_YUV_TRANSBIT(20) #define DISP_REG_OVL_PITCH(n) (0x0044 + 0x20 * (n)) +#define DISP_REG_OVL_CLIP(n) (0x004c + 0x20 * (n)) #define DISP_REG_OVL_RDMA_CTRL(n) (0x00c0 + 0x20 * (n)) #define DISP_REG_OVL_RDMA_GMC(n) (0x00c8 + 0x20 * (n)) #define DISP_REG_OVL_ADDR_MT2701 0x0040 #define DISP_REG_OVL_ADDR_MT8173 0x0f40 #define DISP_REG_OVL_ADDR(ovl, n) ((ovl)->data->addr + 0x20 * (n)) +#define DISP_REG_OVL_HDR_ADDR(ovl, n) ((ovl)->data->addr + 0x20 * (n) + 0x04) +#define DISP_REG_OVL_HDR_PITCH(ovl, n) ((ovl)->data->addr + 0x20 * (n) + 0x08) #define GMC_THRESHOLD_BITS 16 #define GMC_THRESHOLD_HIGH ((1 << GMC_THRESHOLD_BITS) / 4) @@ -67,6 +74,7 @@ struct mtk_disp_ovl_data { unsigned int layer_nr; bool fmt_rgb565_is_0; bool smi_id_en; + bool supports_afbc; }; /* @@ -172,7 +180,22 @@ void mtk_ovl_stop(struct device *dev) reg = reg & ~OVL_LAYER_SMI_ID_EN; writel_relaxed(reg, ovl->regs + DISP_REG_OVL_DATAPATH_CON); } +} + +static void mtk_ovl_set_afbc(struct device *dev, struct cmdq_pkt *cmdq_pkt, +int idx, bool enabled) +{ + struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); + unsigned int reg; + reg = readl(ovl->regs + DISP_REG_OVL_DATAPATH_CON); + if (enabled) + reg = reg | OVL_LAYER_AFBC_EN(idx); + else + reg = reg & ~OVL_LAYER_AFBC_EN(idx); + + mtk_ddp_write_relaxed(cmdq_pkt, reg, &ovl->cmdq_reg, + ovl->regs, DISP_REG_OVL_DATAPATH_CON); } void mtk_ovl_config(struct device *dev, unsigned int w, @@ -226,6 +249,32 @@ int mtk_ovl_layer_check(struct device *dev, unsigned int idx, if (state->fb->format->is_yuv && rotation != 0) return -EINVAL; + if (state->fb->modifier) { + unsigned long long modifier; + unsigned int fourcc; + struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); + + if (!ovl->data->supports_afbc) + return -EINVAL; + + modifier = state->fb->modifier; + + if (modifier != DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 | + AFBC_FORMAT_MOD_SPLIT | + AFBC_FORMAT_MOD_SPARSE)) + return -EINVAL; + + fourcc = state->fb->format->format; + if (fourcc != DRM_FORMAT_BGRA && + fourcc != DRM_FORMAT_ABGR && + fourcc != DRM_FORMAT_ARGB && + fourcc != DRM_FORMAT_XRGB && + fourcc != DRM_FORMAT_XBGR && + fourcc != DRM_FORMAT_RGB888 && + fourcc != DRM_FORMAT_BGR888) + return -EINVAL; + } + state->rotation = rotation; return 0; @@ -310,11 +359,23 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int idx, struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); struct mtk_plane_pending_stat
Re: [RESEND PATCH v2] drm/mediatek: Add AFBC support to Mediatek DRM driver
> These would be different from the macros that are available in bitfield.h, but > not *fundamentally* different, so these would look a little redundant... > > I think that you refer to that `pitch` variable that's coming from the > DRM(/fb) > API... and bitfield macros are for register access... so I guess that one > clean > way of avoiding the magic shifting (that is purely used to split the 32-bits > number in two 16-bits 'chunks') would be to perhaps use a union, so that you > will have something like u.pitch_lsb, u.pitch_msb (with lsb/msb being two > u16). Do you mean something like this? union pitch_val { struct split_pitch_val { uint16_t lsb; uint16_t msb; } split; uint32_t val; }; I think my concern with that approach would be it assumes the compiler packs structs tightly and it also assumes the endianness of the machine, whereas a bitshift is maybe more portable. Is this an issue worth considering since we know this driver will only run on specific MTK SoCs?
Re: [RESEND PATCH v2] drm/mediatek: Add AFBC support to Mediatek DRM driver
Hi Angelo, Thanks for the suggestions! I'll upload another patch with those changes. Re the pitch register math, would it be acceptable to define separate macros for the LSB and MSB to abstract away the magic numbers? For example: #define OVL_PITCH_MSB(n)((n >> 16) & GENMASK(15, 0)) #define OVL_PITCH_LSB(n)(n & GENMASK(15, 0)) Regards, Justin On Tue, Oct 11, 2022 at 5:09 AM AngeloGioacchino Del Regno wrote: > > Il 10/10/22 17:01, Justin Green ha scritto: > > From: Justin Green > > > > Add AFBC support to Mediatek DRM driver and enable on MT8195. > > > > Tested on MT8195 and confirmed both correct video output and improved DRAM > > bandwidth performance. > > > > v2: > > Marked mtk_ovl_set_afbc as static, reflowed some lines to fit column > > limit. > > > > Signed-off-by: Justin Green > > Hello Justin, > thanks for the patch! > > However, there's something to improve... > > > --- > > drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 108 --- > > drivers/gpu/drm/mediatek/mtk_drm_plane.c | 37 +++- > > drivers/gpu/drm/mediatek/mtk_drm_plane.h | 8 ++ > > 3 files changed, 140 insertions(+), 13 deletions(-) > > > > diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c > > b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c > > index 002b0f6cae1a..1724ea85a840 100644 > > --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c > > +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c > > ..snip.. > > > @@ -208,6 +231,8 @@ int mtk_ovl_layer_check(struct device *dev, unsigned > > int idx, > > { > > struct drm_plane_state *state = &mtk_state->base; > > unsigned int rotation = 0; > > + unsigned long long modifier; > > + unsigned int fourcc; > > > > rotation = drm_rotation_simplify(state->rotation, > >DRM_MODE_ROTATE_0 | > > @@ -226,6 +251,30 @@ int mtk_ovl_layer_check(struct device *dev, unsigned > > int idx, > > if (state->fb->format->is_yuv && rotation != 0) > > return -EINVAL; > > > > + if (state->fb->modifier) { > > + struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); > > Since you're introducing modifier and fourcc for this branch only, you > may as well just declare them here instead, but either way is fine. > > > + > > + if (!ovl->data->supports_afbc) > > + return -EINVAL; > > + > > + modifier = state->fb->modifier; > > + > > + if (modifier != > > DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 | > > + AFBC_FORMAT_MOD_SPLIT > > | > > + > > AFBC_FORMAT_MOD_SPARSE)) > > + return -EINVAL; > > + > > + fourcc = state->fb->format->format; > > + if (fourcc != DRM_FORMAT_BGRA && > > + fourcc != DRM_FORMAT_ABGR && > > + fourcc != DRM_FORMAT_ARGB && > > + fourcc != DRM_FORMAT_XRGB && > > + fourcc != DRM_FORMAT_XBGR && > > + fourcc != DRM_FORMAT_RGB888 && > > + fourcc != DRM_FORMAT_BGR888) > > + return -EINVAL; > > + } > > + > > state->rotation = rotation; > > > > return 0; > > @@ -310,11 +359,14 @@ void mtk_ovl_layer_config(struct device *dev, > > unsigned int idx, > > struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); > > struct mtk_plane_pending_state *pending = &state->pending; > > unsigned int addr = pending->addr; > > - unsigned int pitch = pending->pitch & 0x; > > + unsigned int hdr_addr = pending->hdr_addr; > > + unsigned int pitch = pending->pitch; > > + unsigned int hdr_pitch = pending->hdr_pitch; > > unsigned int fmt = pending->format; > > unsigned int offset = (pending->y << 16) | pending->x; > > unsigned int src_size = (pending->height << 16) | pending->width; > > unsigned int con; > > + bool is_afbc = pending->modifier; > > > > if (!pending->enable) { > > mtk_ovl_layer_off(dev, idx, cmdq_pkt); > > @@ -335,16 +387,39 @@ void mtk_ovl_layer_config(struct device *dev, >
[RESEND PATCH v2] drm/mediatek: Add AFBC support to Mediatek DRM driver
From: Justin Green Add AFBC support to Mediatek DRM driver and enable on MT8195. Tested on MT8195 and confirmed both correct video output and improved DRAM bandwidth performance. v2: Marked mtk_ovl_set_afbc as static, reflowed some lines to fit column limit. Signed-off-by: Justin Green --- drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 108 --- drivers/gpu/drm/mediatek/mtk_drm_plane.c | 37 +++- drivers/gpu/drm/mediatek/mtk_drm_plane.h | 8 ++ 3 files changed, 140 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c index 002b0f6cae1a..1724ea85a840 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c @@ -29,17 +29,24 @@ #define DISP_REG_OVL_DATAPATH_CON 0x0024 #define OVL_LAYER_SMI_ID_ENBIT(0) #define OVL_BGCLR_SEL_IN BIT(2) +#define OVL_LAYER_AFBC_EN(n) BIT(4+n) #define DISP_REG_OVL_ROI_BGCLR 0x0028 #define DISP_REG_OVL_SRC_CON 0x002c #define DISP_REG_OVL_CON(n)(0x0030 + 0x20 * (n)) #define DISP_REG_OVL_SRC_SIZE(n) (0x0038 + 0x20 * (n)) #define DISP_REG_OVL_OFFSET(n) (0x003c + 0x20 * (n)) +#define DISP_REG_OVL_PITCH_MSB(n) (0x0040 + 0x20 * (n)) +#define OVL_PITCH_MSB_2ND_SUBBUF BIT(16) +#define OVL_PITCH_MSB_YUV_TRANSBIT(20) #define DISP_REG_OVL_PITCH(n) (0x0044 + 0x20 * (n)) +#define DISP_REG_OVL_CLIP(n) (0x004c + 0x20 * (n)) #define DISP_REG_OVL_RDMA_CTRL(n) (0x00c0 + 0x20 * (n)) #define DISP_REG_OVL_RDMA_GMC(n) (0x00c8 + 0x20 * (n)) #define DISP_REG_OVL_ADDR_MT2701 0x0040 #define DISP_REG_OVL_ADDR_MT8173 0x0f40 #define DISP_REG_OVL_ADDR(ovl, n) ((ovl)->data->addr + 0x20 * (n)) +#define DISP_REG_OVL_HDR_ADDR(ovl, n) ((ovl)->data->addr + 0x20 * (n) + 0x04) +#define DISP_REG_OVL_HDR_PITCH(ovl, n) ((ovl)->data->addr + 0x20 * (n) + 0x08) #define GMC_THRESHOLD_BITS 16 #define GMC_THRESHOLD_HIGH ((1 << GMC_THRESHOLD_BITS) / 4) @@ -67,6 +74,7 @@ struct mtk_disp_ovl_data { unsigned int layer_nr; bool fmt_rgb565_is_0; bool smi_id_en; + bool supports_afbc; }; /* @@ -172,7 +180,22 @@ void mtk_ovl_stop(struct device *dev) reg = reg & ~OVL_LAYER_SMI_ID_EN; writel_relaxed(reg, ovl->regs + DISP_REG_OVL_DATAPATH_CON); } +} + +static void mtk_ovl_set_afbc(struct device *dev, struct cmdq_pkt *cmdq_pkt, +int idx, bool enabled) +{ + struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); + unsigned int reg; + reg = readl(ovl->regs + DISP_REG_OVL_DATAPATH_CON); + if (enabled) + reg = reg | OVL_LAYER_AFBC_EN(idx); + else + reg = reg & ~OVL_LAYER_AFBC_EN(idx); + + mtk_ddp_write_relaxed(cmdq_pkt, reg, &ovl->cmdq_reg, + ovl->regs, DISP_REG_OVL_DATAPATH_CON); } void mtk_ovl_config(struct device *dev, unsigned int w, @@ -208,6 +231,8 @@ int mtk_ovl_layer_check(struct device *dev, unsigned int idx, { struct drm_plane_state *state = &mtk_state->base; unsigned int rotation = 0; + unsigned long long modifier; + unsigned int fourcc; rotation = drm_rotation_simplify(state->rotation, DRM_MODE_ROTATE_0 | @@ -226,6 +251,30 @@ int mtk_ovl_layer_check(struct device *dev, unsigned int idx, if (state->fb->format->is_yuv && rotation != 0) return -EINVAL; + if (state->fb->modifier) { + struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); + + if (!ovl->data->supports_afbc) + return -EINVAL; + + modifier = state->fb->modifier; + + if (modifier != DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 | + AFBC_FORMAT_MOD_SPLIT | + AFBC_FORMAT_MOD_SPARSE)) + return -EINVAL; + + fourcc = state->fb->format->format; + if (fourcc != DRM_FORMAT_BGRA && + fourcc != DRM_FORMAT_ABGR && + fourcc != DRM_FORMAT_ARGB && + fourcc != DRM_FORMAT_XRGB && + fourcc != DRM_FORMAT_XBGR && + fourcc != DRM_FORMAT_RGB888 && + fourcc != DRM_FORMAT_BGR888) + return -EINVAL; + } + state->rotatio
[PATCH v2] drm/mediatek: Add AFBC support to Mediatek DRM driver
Add AFBC support to Mediatek DRM driver and enable on MT8195. Tested on MT8195 and confirmed both correct video output and improved DRAM bandwidth performance. v2: Marked mtk_ovl_set_afbc as static, reflowed some lines to fit column limit. Signed-off-by: Justin Green --- drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 108 --- drivers/gpu/drm/mediatek/mtk_drm_plane.c | 37 +++- drivers/gpu/drm/mediatek/mtk_drm_plane.h | 8 ++ 3 files changed, 140 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c index 002b0f6cae1a..1724ea85a840 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c @@ -29,17 +29,24 @@ #define DISP_REG_OVL_DATAPATH_CON 0x0024 #define OVL_LAYER_SMI_ID_ENBIT(0) #define OVL_BGCLR_SEL_IN BIT(2) +#define OVL_LAYER_AFBC_EN(n) BIT(4+n) #define DISP_REG_OVL_ROI_BGCLR 0x0028 #define DISP_REG_OVL_SRC_CON 0x002c #define DISP_REG_OVL_CON(n)(0x0030 + 0x20 * (n)) #define DISP_REG_OVL_SRC_SIZE(n) (0x0038 + 0x20 * (n)) #define DISP_REG_OVL_OFFSET(n) (0x003c + 0x20 * (n)) +#define DISP_REG_OVL_PITCH_MSB(n) (0x0040 + 0x20 * (n)) +#define OVL_PITCH_MSB_2ND_SUBBUF BIT(16) +#define OVL_PITCH_MSB_YUV_TRANSBIT(20) #define DISP_REG_OVL_PITCH(n) (0x0044 + 0x20 * (n)) +#define DISP_REG_OVL_CLIP(n) (0x004c + 0x20 * (n)) #define DISP_REG_OVL_RDMA_CTRL(n) (0x00c0 + 0x20 * (n)) #define DISP_REG_OVL_RDMA_GMC(n) (0x00c8 + 0x20 * (n)) #define DISP_REG_OVL_ADDR_MT2701 0x0040 #define DISP_REG_OVL_ADDR_MT8173 0x0f40 #define DISP_REG_OVL_ADDR(ovl, n) ((ovl)->data->addr + 0x20 * (n)) +#define DISP_REG_OVL_HDR_ADDR(ovl, n) ((ovl)->data->addr + 0x20 * (n) + 0x04) +#define DISP_REG_OVL_HDR_PITCH(ovl, n) ((ovl)->data->addr + 0x20 * (n) + 0x08) #define GMC_THRESHOLD_BITS 16 #define GMC_THRESHOLD_HIGH ((1 << GMC_THRESHOLD_BITS) / 4) @@ -67,6 +74,7 @@ struct mtk_disp_ovl_data { unsigned int layer_nr; bool fmt_rgb565_is_0; bool smi_id_en; + bool supports_afbc; }; /* @@ -172,7 +180,22 @@ void mtk_ovl_stop(struct device *dev) reg = reg & ~OVL_LAYER_SMI_ID_EN; writel_relaxed(reg, ovl->regs + DISP_REG_OVL_DATAPATH_CON); } +} + +static void mtk_ovl_set_afbc(struct device *dev, struct cmdq_pkt *cmdq_pkt, +int idx, bool enabled) +{ + struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); + unsigned int reg; + reg = readl(ovl->regs + DISP_REG_OVL_DATAPATH_CON); + if (enabled) + reg = reg | OVL_LAYER_AFBC_EN(idx); + else + reg = reg & ~OVL_LAYER_AFBC_EN(idx); + + mtk_ddp_write_relaxed(cmdq_pkt, reg, &ovl->cmdq_reg, + ovl->regs, DISP_REG_OVL_DATAPATH_CON); } void mtk_ovl_config(struct device *dev, unsigned int w, @@ -208,6 +231,8 @@ int mtk_ovl_layer_check(struct device *dev, unsigned int idx, { struct drm_plane_state *state = &mtk_state->base; unsigned int rotation = 0; + unsigned long long modifier; + unsigned int fourcc; rotation = drm_rotation_simplify(state->rotation, DRM_MODE_ROTATE_0 | @@ -226,6 +251,30 @@ int mtk_ovl_layer_check(struct device *dev, unsigned int idx, if (state->fb->format->is_yuv && rotation != 0) return -EINVAL; + if (state->fb->modifier) { + struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); + + if (!ovl->data->supports_afbc) + return -EINVAL; + + modifier = state->fb->modifier; + + if (modifier != DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 | + AFBC_FORMAT_MOD_SPLIT | + AFBC_FORMAT_MOD_SPARSE)) + return -EINVAL; + + fourcc = state->fb->format->format; + if (fourcc != DRM_FORMAT_BGRA && + fourcc != DRM_FORMAT_ABGR && + fourcc != DRM_FORMAT_ARGB && + fourcc != DRM_FORMAT_XRGB && + fourcc != DRM_FORMAT_XBGR && + fourcc != DRM_FORMAT_RGB888 && + fourcc != DRM_FORMAT_BGR888) + return -EINVAL; + } + state->rotation = rotation;
[PATCH] drm/mediatek: Add AFBC support to Mediatek DRM driver
Add AFBC support to Mediatek DRM driver and enable on MT8195. Tested on MT8195 and confirmed both correct video output and improved DRAM bandwidth performance. Signed-off-by: Justin Green --- drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 106 --- drivers/gpu/drm/mediatek/mtk_drm_plane.c | 37 +++- drivers/gpu/drm/mediatek/mtk_drm_plane.h | 8 ++ 3 files changed, 138 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c index 002b0f6cae1a..7425c88964d0 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c @@ -29,17 +29,24 @@ #define DISP_REG_OVL_DATAPATH_CON 0x0024 #define OVL_LAYER_SMI_ID_ENBIT(0) #define OVL_BGCLR_SEL_IN BIT(2) +#define OVL_LAYER_AFBC_EN(n) BIT(4+n) #define DISP_REG_OVL_ROI_BGCLR 0x0028 #define DISP_REG_OVL_SRC_CON 0x002c #define DISP_REG_OVL_CON(n)(0x0030 + 0x20 * (n)) #define DISP_REG_OVL_SRC_SIZE(n) (0x0038 + 0x20 * (n)) #define DISP_REG_OVL_OFFSET(n) (0x003c + 0x20 * (n)) +#define DISP_REG_OVL_PITCH_MSB(n) (0x0040 + 0x20 * (n)) +#define OVL_PITCH_MSB_2ND_SUBBUF BIT(16) +#define OVL_PITCH_MSB_YUV_TRANSBIT(20) #define DISP_REG_OVL_PITCH(n) (0x0044 + 0x20 * (n)) +#define DISP_REG_OVL_CLIP(n) (0x004c + 0x20 * (n)) #define DISP_REG_OVL_RDMA_CTRL(n) (0x00c0 + 0x20 * (n)) #define DISP_REG_OVL_RDMA_GMC(n) (0x00c8 + 0x20 * (n)) #define DISP_REG_OVL_ADDR_MT2701 0x0040 #define DISP_REG_OVL_ADDR_MT8173 0x0f40 #define DISP_REG_OVL_ADDR(ovl, n) ((ovl)->data->addr + 0x20 * (n)) +#define DISP_REG_OVL_HDR_ADDR(ovl, n) ((ovl)->data->addr + 0x20 * (n) + 0x04) +#define DISP_REG_OVL_HDR_PITCH(ovl, n) ((ovl)->data->addr + 0x20 * (n) + 0x08) #define GMC_THRESHOLD_BITS 16 #define GMC_THRESHOLD_HIGH ((1 << GMC_THRESHOLD_BITS) / 4) @@ -67,6 +74,7 @@ struct mtk_disp_ovl_data { unsigned int layer_nr; bool fmt_rgb565_is_0; bool smi_id_en; + bool supports_afbc; }; /* @@ -172,7 +180,20 @@ void mtk_ovl_stop(struct device *dev) reg = reg & ~OVL_LAYER_SMI_ID_EN; writel_relaxed(reg, ovl->regs + DISP_REG_OVL_DATAPATH_CON); } +} + +void mtk_ovl_set_afbc(struct device *dev, struct cmdq_pkt *cmdq_pkt, int idx, bool enabled) +{ + struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); + unsigned int reg; + reg = readl(ovl->regs + DISP_REG_OVL_DATAPATH_CON); + if (enabled) + reg = reg | OVL_LAYER_AFBC_EN(idx); + else + reg = reg & ~OVL_LAYER_AFBC_EN(idx); + + mtk_ddp_write_relaxed(cmdq_pkt, reg, &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_DATAPATH_CON); } void mtk_ovl_config(struct device *dev, unsigned int w, @@ -208,6 +229,8 @@ int mtk_ovl_layer_check(struct device *dev, unsigned int idx, { struct drm_plane_state *state = &mtk_state->base; unsigned int rotation = 0; + unsigned long long modifier; + unsigned int fourcc; rotation = drm_rotation_simplify(state->rotation, DRM_MODE_ROTATE_0 | @@ -226,6 +249,30 @@ int mtk_ovl_layer_check(struct device *dev, unsigned int idx, if (state->fb->format->is_yuv && rotation != 0) return -EINVAL; + if (state->fb->modifier) { + struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); + + if (!ovl->data->supports_afbc) + return -EINVAL; + + modifier = state->fb->modifier; + + if (modifier != DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 | + AFBC_FORMAT_MOD_SPLIT | + AFBC_FORMAT_MOD_SPARSE)) + return -EINVAL; + + fourcc = state->fb->format->format; + if (fourcc != DRM_FORMAT_BGRA && + fourcc != DRM_FORMAT_ABGR && + fourcc != DRM_FORMAT_ARGB && + fourcc != DRM_FORMAT_XRGB && + fourcc != DRM_FORMAT_XBGR && + fourcc != DRM_FORMAT_RGB888 && + fourcc != DRM_FORMAT_BGR888) + return -EINVAL; + } + state->rotation = rotation; return 0; @@ -310,11 +357,14 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int idx, struct mtk_disp_ovl *ovl = dev_get_drvdata