diff --git a/target/linux/rockchip/patches-6.6/033-01-v6.7-drm-rockchip-vop-Add-rv1126-vop_lite-support.patch b/target/linux/rockchip/patches-6.6/033-01-v6.7-drm-rockchip-vop-Add-rv1126-vop_lite-support.patch new file mode 100644 index 0000000000..b2ce0c3123 --- /dev/null +++ b/target/linux/rockchip/patches-6.6/033-01-v6.7-drm-rockchip-vop-Add-rv1126-vop_lite-support.patch @@ -0,0 +1,88 @@ +From 3c3cfcb93f6e6e1cede0cdfe3ec24f16ee108929 Mon Sep 17 00:00:00 2001 +From: Jagan Teki +Date: Mon, 31 Jul 2023 16:30:04 +0530 +Subject: [PATCH] drm/rockchip: vop: Add rv1126 vop_lite support + +RV1126 VOP_LITE supports the video output processing ofMIPI DSI, +RGB display interfaces with max output resolution of 1920x1080. + +Add support for rv1126 vop. + +Signed-off-by: Jagan Teki +Signed-off-by: Heiko Stuebner +Link: https://patchwork.freedesktop.org/patch/msgid/20230731110012.2913742-7-jagan@edgeble.ai +--- + drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 55 +++++++++++++++++++++ + 1 file changed, 55 insertions(+) + +--- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c ++++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c +@@ -1120,6 +1120,59 @@ static const struct vop_data rk3328_vop + .max_output = { 4096, 2160 }, + }; + ++static const struct vop_common rv1126_common = { ++ .standby = VOP_REG_SYNC(PX30_SYS_CTRL2, 0x1, 1), ++ .out_mode = VOP_REG(PX30_DSP_CTRL2, 0xf, 16), ++ .dsp_blank = VOP_REG(PX30_DSP_CTRL2, 0x1, 14), ++ .dither_down_en = VOP_REG(PX30_DSP_CTRL2, 0x1, 8), ++ .dither_down_sel = VOP_REG(PX30_DSP_CTRL2, 0x1, 7), ++ .dither_down_mode = VOP_REG(PX30_DSP_CTRL2, 0x1, 6), ++ .cfg_done = VOP_REG_SYNC(PX30_REG_CFG_DONE, 0x1, 0), ++ .dither_up = VOP_REG(PX30_DSP_CTRL2, 0x1, 2), ++ .dsp_lut_en = VOP_REG(PX30_DSP_CTRL2, 0x1, 5), ++ .gate_en = VOP_REG(PX30_DSP_CTRL2, 0x1, 0), ++}; ++ ++static const struct vop_modeset rv1126_modeset = { ++ .htotal_pw = VOP_REG(PX30_DSP_HTOTAL_HS_END, 0x0fff0fff, 0), ++ .hact_st_end = VOP_REG(PX30_DSP_HACT_ST_END, 0x0fff0fff, 0), ++ .vtotal_pw = VOP_REG(PX30_DSP_VTOTAL_VS_END, 0x0fff0fff, 0), ++ .vact_st_end = VOP_REG(PX30_DSP_VACT_ST_END, 0x0fff0fff, 0), ++}; ++ ++static const struct vop_output rv1126_output = { ++ .rgb_dclk_pol = VOP_REG(PX30_DSP_CTRL0, 0x1, 1), ++ .rgb_pin_pol = VOP_REG(PX30_DSP_CTRL0, 0x7, 2), ++ .rgb_en = VOP_REG(PX30_DSP_CTRL0, 0x1, 0), ++ .mipi_dclk_pol = VOP_REG(PX30_DSP_CTRL0, 0x1, 25), ++ .mipi_pin_pol = VOP_REG(PX30_DSP_CTRL0, 0x7, 26), ++ .mipi_en = VOP_REG(PX30_DSP_CTRL0, 0x1, 24), ++}; ++ ++static const struct vop_misc rv1126_misc = { ++ .global_regdone_en = VOP_REG(PX30_SYS_CTRL2, 0x1, 13), ++}; ++ ++static const struct vop_win_data rv1126_vop_win_data[] = { ++ { .base = 0x00, .phy = &px30_win0_data, ++ .type = DRM_PLANE_TYPE_OVERLAY }, ++ { .base = 0x00, .phy = &px30_win2_data, ++ .type = DRM_PLANE_TYPE_PRIMARY }, ++}; ++ ++static const struct vop_data rv1126_vop = { ++ .version = VOP_VERSION(2, 0xb), ++ .intr = &px30_intr, ++ .common = &rv1126_common, ++ .modeset = &rv1126_modeset, ++ .output = &rv1126_output, ++ .misc = &rv1126_misc, ++ .win = rv1126_vop_win_data, ++ .win_size = ARRAY_SIZE(rv1126_vop_win_data), ++ .max_output = { 1920, 1080 }, ++ .lut_size = 1024, ++}; ++ + static const struct of_device_id vop_driver_dt_match[] = { + { .compatible = "rockchip,rk3036-vop", + .data = &rk3036_vop }, +@@ -1147,6 +1200,8 @@ static const struct of_device_id vop_dri + .data = &rk3228_vop }, + { .compatible = "rockchip,rk3328-vop", + .data = &rk3328_vop }, ++ { .compatible = "rockchip,rv1126-vop", ++ .data = &rv1126_vop }, + {}, + }; + MODULE_DEVICE_TABLE(of, vop_driver_dt_match); diff --git a/target/linux/rockchip/patches-6.6/033-02-v6.7-drm-rockchip-dsi-Add-rv1126-MIPI-DSI-support.patch b/target/linux/rockchip/patches-6.6/033-02-v6.7-drm-rockchip-dsi-Add-rv1126-MIPI-DSI-support.patch new file mode 100644 index 0000000000..83571e238d --- /dev/null +++ b/target/linux/rockchip/patches-6.6/033-02-v6.7-drm-rockchip-dsi-Add-rv1126-MIPI-DSI-support.patch @@ -0,0 +1,60 @@ +From 11fdb231f4127bf60839a63a8c7ed640ebe4751a Mon Sep 17 00:00:00 2001 +From: Jagan Teki +Date: Mon, 31 Jul 2023 16:30:06 +0530 +Subject: [PATCH] drm/rockchip: dsi: Add rv1126 MIPI DSI support + +RV1126 MIPI DSI supports V1.2 DPHY with 4 lanes and 1Gbps transfer +rate for lane. + +Add support for it. + +Signed-off-by: Jagan Teki +Signed-off-by: Heiko Stuebner +Link: https://patchwork.freedesktop.org/patch/msgid/20230731110012.2913742-9-jagan@edgeble.ai +--- + .../gpu/drm/rockchip/dw-mipi-dsi-rockchip.c | 20 +++++++++++++++++++ + 1 file changed, 20 insertions(+) + +--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c ++++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c +@@ -198,6 +198,11 @@ + #define RK3568_DSI1_TURNDISABLE BIT(2) + #define RK3568_DSI1_FORCERXMODE BIT(0) + ++#define RV1126_GRF_DSIPHY_CON 0x10220 ++#define RV1126_DSI_FORCETXSTOPMODE (0xf << 4) ++#define RV1126_DSI_TURNDISABLE BIT(2) ++#define RV1126_DSI_FORCERXMODE BIT(0) ++ + #define HIWORD_UPDATE(val, mask) (val | (mask) << 16) + + enum { +@@ -1651,6 +1656,18 @@ static const struct rockchip_dw_dsi_chip + { /* sentinel */ } + }; + ++static const struct rockchip_dw_dsi_chip_data rv1126_chip_data[] = { ++ { ++ .reg = 0xffb30000, ++ .lanecfg1_grf_reg = RV1126_GRF_DSIPHY_CON, ++ .lanecfg1 = HIWORD_UPDATE(0, RV1126_DSI_TURNDISABLE | ++ RV1126_DSI_FORCERXMODE | ++ RV1126_DSI_FORCETXSTOPMODE), ++ .max_data_lanes = 4, ++ }, ++ { /* sentinel */ } ++}; ++ + static const struct of_device_id dw_mipi_dsi_rockchip_dt_ids[] = { + { + .compatible = "rockchip,px30-mipi-dsi", +@@ -1664,6 +1681,9 @@ static const struct of_device_id dw_mipi + }, { + .compatible = "rockchip,rk3568-mipi-dsi", + .data = &rk3568_chip_data, ++ }, { ++ .compatible = "rockchip,rv1126-mipi-dsi", ++ .data = &rv1126_chip_data, + }, + { /* sentinel */ } + }; diff --git a/target/linux/rockchip/patches-6.6/033-03-v6.7-drm-rockchip-vop-Use-cleanup-helper-directly-as-destroy.patch b/target/linux/rockchip/patches-6.6/033-03-v6.7-drm-rockchip-vop-Use-cleanup-helper-directly-as-destroy.patch new file mode 100644 index 0000000000..96cca08194 --- /dev/null +++ b/target/linux/rockchip/patches-6.6/033-03-v6.7-drm-rockchip-vop-Use-cleanup-helper-directly-as-destroy.patch @@ -0,0 +1,71 @@ +From 800f7c332df7cd9614c416fd005a6bb53f96f13c Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Wed, 21 Jun 2023 22:33:18 +0000 +Subject: [PATCH] drm/rockchip: vop: Use cleanup helper directly as destroy + funcs + +vop_plane_destroy and vop_crtc_destroy are plain wrappers around +drm_plane_cleanup and drm_crtc_cleanup. Use them directly as plane and +crtc funcs to closer match VOP2 driver. + +Signed-off-by: Jonas Karlman +Reviewed-by: Sascha Hauer +Signed-off-by: Heiko Stuebner +Link: https://patchwork.freedesktop.org/patch/msgid/20230621223311.2239547-3-jonas@kwiboo.se +--- + drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 16 +++------------- + 1 file changed, 3 insertions(+), 13 deletions(-) + +--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +@@ -773,11 +773,6 @@ out: + } + } + +-static void vop_plane_destroy(struct drm_plane *plane) +-{ +- drm_plane_cleanup(plane); +-} +- + static inline bool rockchip_afbc(u64 modifier) + { + return modifier == ROCKCHIP_AFBC_MOD; +@@ -1139,7 +1134,7 @@ static const struct drm_plane_helper_fun + static const struct drm_plane_funcs vop_plane_funcs = { + .update_plane = drm_atomic_helper_update_plane, + .disable_plane = drm_atomic_helper_disable_plane, +- .destroy = vop_plane_destroy, ++ .destroy = drm_plane_cleanup, + .reset = drm_atomic_helper_plane_reset, + .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, +@@ -1610,11 +1605,6 @@ static const struct drm_crtc_helper_func + .atomic_disable = vop_crtc_atomic_disable, + }; + +-static void vop_crtc_destroy(struct drm_crtc *crtc) +-{ +- drm_crtc_cleanup(crtc); +-} +- + static struct drm_crtc_state *vop_crtc_duplicate_state(struct drm_crtc *crtc) + { + struct rockchip_crtc_state *rockchip_state; +@@ -1722,7 +1712,7 @@ vop_crtc_verify_crc_source(struct drm_cr + static const struct drm_crtc_funcs vop_crtc_funcs = { + .set_config = drm_atomic_helper_set_config, + .page_flip = drm_atomic_helper_page_flip, +- .destroy = vop_crtc_destroy, ++ .destroy = drm_crtc_cleanup, + .reset = vop_crtc_reset, + .atomic_duplicate_state = vop_crtc_duplicate_state, + .atomic_destroy_state = vop_crtc_destroy_state, +@@ -1973,7 +1963,7 @@ static void vop_destroy_crtc(struct vop + */ + list_for_each_entry_safe(plane, tmp, &drm_dev->mode_config.plane_list, + head) +- vop_plane_destroy(plane); ++ drm_plane_cleanup(plane); + + /* + * Destroy CRTC after vop_plane_destroy() since vop_disable_plane() diff --git a/target/linux/rockchip/patches-6.6/033-04-v6.7-drm-rockchip-vop2-Demote-message-in-mod_supported-to.patch b/target/linux/rockchip/patches-6.6/033-04-v6.7-drm-rockchip-vop2-Demote-message-in-mod_supported-to.patch new file mode 100644 index 0000000000..f0811b3881 --- /dev/null +++ b/target/linux/rockchip/patches-6.6/033-04-v6.7-drm-rockchip-vop2-Demote-message-in-mod_supported-to.patch @@ -0,0 +1,35 @@ +From eb23cffdd7f085149799e5eda12a9aff792cc34d Mon Sep 17 00:00:00 2001 +From: Michael Tretter +Date: Mon, 9 Oct 2023 12:37:53 +0200 +Subject: [PATCH] drm/rockchip: vop2: Demote message in mod_supported to + drm_dbg_kms + +Checking if a modifier is supported by a plane is normal behavior. It is +normal that a plane may not support certain modifiers. Failing the check +doesn't justify an error message in the kernel log and may mislead +users. + +Demote the error message to drm_dbg_kms to only print the message if the +respective debug messages are enabled. This is similar to the behavior +in rockchip_drm_vop.c. + +Signed-off-by: Michael Tretter +Signed-off-by: Heiko Stuebner +Link: https://patchwork.freedesktop.org/patch/msgid/20231009103753.830458-1-m.tretter@pengutronix.de +--- + drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +@@ -469,8 +469,8 @@ static bool rockchip_vop2_mod_supported( + return true; + + if (!rockchip_afbc(plane, modifier)) { +- drm_err(vop2->drm, "Unsupported format modifier 0x%llx\n", +- modifier); ++ drm_dbg_kms(vop2->drm, "Unsupported format modifier 0x%llx\n", ++ modifier); + + return false; + } diff --git a/target/linux/rockchip/patches-6.6/033-05-v6.7-drm-rockchip-remove-redundant-of_match_ptr.patch b/target/linux/rockchip/patches-6.6/033-05-v6.7-drm-rockchip-remove-redundant-of_match_ptr.patch new file mode 100644 index 0000000000..41d6e9d4b6 --- /dev/null +++ b/target/linux/rockchip/patches-6.6/033-05-v6.7-drm-rockchip-remove-redundant-of_match_ptr.patch @@ -0,0 +1,53 @@ +From 63a06c9fe30bf84d1ab6f07d0e408bd1d4ccaf85 Mon Sep 17 00:00:00 2001 +From: Zhu Wang +Date: Mon, 31 Jul 2023 20:53:04 +0800 +Subject: [PATCH] drm/rockchip: remove redundant of_match_ptr + +The driver depends on CONFIG_OF, so it is not necessary to use +of_match_ptr here. + +Even for drivers that do not depend on CONFIG_OF, it's almost always +better to leave out the of_match_ptr(), since the only thing it can +possibly do is to save a few bytes of .text if a driver can be used both +with and without it. Hence we remove of_match_ptr. + +Signed-off-by: Zhu Wang +Signed-off-by: Heiko Stuebner +Link: https://patchwork.freedesktop.org/patch/msgid/20230731125304.87059-1-wangzhu9@huawei.com +--- + drivers/gpu/drm/rockchip/cdn-dp-core.c | 2 +- + drivers/gpu/drm/rockchip/rockchip_lvds.c | 2 +- + drivers/gpu/drm/rockchip/rockchip_vop2_reg.c | 2 +- + 3 files changed, 3 insertions(+), 3 deletions(-) + +--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c ++++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c +@@ -1261,7 +1261,7 @@ struct platform_driver cdn_dp_driver = { + .driver = { + .name = "cdn-dp", + .owner = THIS_MODULE, +- .of_match_table = of_match_ptr(cdn_dp_dt_ids), ++ .of_match_table = cdn_dp_dt_ids, + .pm = &cdn_dp_pm_ops, + }, + }; +--- a/drivers/gpu/drm/rockchip/rockchip_lvds.c ++++ b/drivers/gpu/drm/rockchip/rockchip_lvds.c +@@ -751,6 +751,6 @@ struct platform_driver rockchip_lvds_dri + .remove_new = rockchip_lvds_remove, + .driver = { + .name = "rockchip-lvds", +- .of_match_table = of_match_ptr(rockchip_lvds_dt_ids), ++ .of_match_table = rockchip_lvds_dt_ids, + }, + }; +--- a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c ++++ b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c +@@ -274,6 +274,6 @@ struct platform_driver vop2_platform_dri + .remove_new = vop2_remove, + .driver = { + .name = "rockchip-vop2", +- .of_match_table = of_match_ptr(vop2_dt_match), ++ .of_match_table = vop2_dt_match, + }, + }; diff --git a/target/linux/rockchip/patches-6.6/033-06-v6.7-drm-rockchip-dsi-Use-devm_platform_get_and_ioremap_reso.patch b/target/linux/rockchip/patches-6.6/033-06-v6.7-drm-rockchip-dsi-Use-devm_platform_get_and_ioremap_reso.patch new file mode 100644 index 0000000000..b7c34d9ab1 --- /dev/null +++ b/target/linux/rockchip/patches-6.6/033-06-v6.7-drm-rockchip-dsi-Use-devm_platform_get_and_ioremap_reso.patch @@ -0,0 +1,29 @@ +From 253a1d33e5cfdf62525f5d6ed2bf03acbadd1582 Mon Sep 17 00:00:00 2001 +From: Yang Li +Date: Fri, 21 Apr 2023 16:13:03 +0800 +Subject: [PATCH] drm/rockchip: dsi: Use + devm_platform_get_and_ioremap_resource() + +Convert platform_get_resource(), devm_ioremap_resource() to a single +call to devm_platform_get_and_ioremap_resource(), as this is exactly +what this function does. + +Signed-off-by: Yang Li +Signed-off-by: Heiko Stuebner +Link: https://patchwork.freedesktop.org/patch/msgid/20230421081303.122452-1-yang.lee@linux.alibaba.com +--- + drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c ++++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c +@@ -1358,8 +1358,7 @@ static int dw_mipi_dsi_rockchip_probe(st + if (!dsi) + return -ENOMEM; + +- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +- dsi->base = devm_ioremap_resource(dev, res); ++ dsi->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); + if (IS_ERR(dsi->base)) { + DRM_DEV_ERROR(dev, "Unable to get dsi registers\n"); + return PTR_ERR(dsi->base); diff --git a/target/linux/rockchip/patches-6.6/033-07-v6.7-drm-rockchip-remove-unused-struct-in-vop2.patch b/target/linux/rockchip/patches-6.6/033-07-v6.7-drm-rockchip-remove-unused-struct-in-vop2.patch new file mode 100644 index 0000000000..b272363a4d --- /dev/null +++ b/target/linux/rockchip/patches-6.6/033-07-v6.7-drm-rockchip-remove-unused-struct-in-vop2.patch @@ -0,0 +1,54 @@ +From ac1c11c23fc51c1ba51a3ed586df40ffe6b1de35 Mon Sep 17 00:00:00 2001 +From: Andy Yan +Date: Fri, 13 Oct 2023 20:20:36 +0800 +Subject: [PATCH] drm/rockchip: remove unused struct in vop2 + +These structs are undefined and un used. + +Fixes: 604be85547ce ("drm/rockchip: Add VOP2 driver") +Signed-off-by: Andy Yan +Reviewed-by: Sascha Hauer +Signed-off-by: Heiko Stuebner +Link: https://patchwork.freedesktop.org/patch/msgid/20231013122036.1594090-1-andyshrk@163.com +--- + drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 2 -- + drivers/gpu/drm/rockchip/rockchip_drm_vop2.h | 3 --- + 2 files changed, 5 deletions(-) + +--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +@@ -160,7 +160,6 @@ struct vop2_video_port { + struct vop2 *vop2; + struct clk *dclk; + unsigned int id; +- const struct vop2_video_port_regs *regs; + const struct vop2_video_port_data *data; + + struct completion dsp_hold_completion; +@@ -2273,7 +2272,6 @@ static int vop2_create_crtcs(struct vop2 + vp = &vop2->vps[i]; + vp->vop2 = vop2; + vp->id = vp_data->id; +- vp->regs = vp_data->regs; + vp->data = vp_data; + + snprintf(dclk_name, sizeof(dclk_name), "dclk_vp%d", vp->id); +--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h +@@ -134,16 +134,13 @@ struct vop2_video_port_data { + u16 cubic_lut_len; + struct vop_rect max_output; + const u8 pre_scan_max_dly[4]; +- const struct vop2_video_port_regs *regs; + unsigned int offset; + }; + + struct vop2_data { + u8 nr_vps; +- const struct vop2_ctrl *ctrl; + const struct vop2_win_data *win; + const struct vop2_video_port_data *vp; +- const struct vop_csc_table *csc_table; + struct vop_rect max_input; + struct vop_rect max_output; + diff --git a/target/linux/rockchip/patches-6.6/033-08-v6.7-drm-rockchip-remove-NR_LAYERS-macro-on-vop2.patch b/target/linux/rockchip/patches-6.6/033-08-v6.7-drm-rockchip-remove-NR_LAYERS-macro-on-vop2.patch new file mode 100644 index 0000000000..bb57001cec --- /dev/null +++ b/target/linux/rockchip/patches-6.6/033-08-v6.7-drm-rockchip-remove-NR_LAYERS-macro-on-vop2.patch @@ -0,0 +1,36 @@ +From dc00748adcf03d754bf43035c668bc5b20fb6597 Mon Sep 17 00:00:00 2001 +From: Andy Yan +Date: Fri, 13 Oct 2023 20:20:51 +0800 +Subject: [PATCH] drm/rockchip: remove NR_LAYERS macro on vop2 + +There are 8 layers on rk3588, so a fix defined macro is +not appropriate. + +Signed-off-by: Andy Yan +Reviewed-by: Sascha Hauer +Signed-off-by: Heiko Stuebner +Link: https://patchwork.freedesktop.org/patch/msgid/20231013122051.1594164-1-andyshrk@163.com +--- + drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +@@ -2250,8 +2250,6 @@ static struct vop2_video_port *find_vp_w + return NULL; + } + +-#define NR_LAYERS 6 +- + static int vop2_create_crtcs(struct vop2 *vop2) + { + const struct vop2_data *vop2_data = vop2->data; +@@ -2370,7 +2368,7 @@ static int vop2_create_crtcs(struct vop2 + struct vop2_video_port *vp = &vop2->vps[i]; + + if (vp->crtc.port) +- vp->nlayers = NR_LAYERS / nvps; ++ vp->nlayers = vop2_data->win_size / nvps; + } + + return 0; diff --git a/target/linux/rockchip/patches-6.6/033-09-v6.7-drm-rockchip-vop-fix-format-bpp-calculation.patch b/target/linux/rockchip/patches-6.6/033-09-v6.7-drm-rockchip-vop-fix-format-bpp-calculation.patch new file mode 100644 index 0000000000..653f420814 --- /dev/null +++ b/target/linux/rockchip/patches-6.6/033-09-v6.7-drm-rockchip-vop-fix-format-bpp-calculation.patch @@ -0,0 +1,57 @@ +From 45ad07c7053df0b67e13d8deb574920d11651fb2 Mon Sep 17 00:00:00 2001 +From: Andy Yan +Date: Wed, 18 Oct 2023 17:42:10 +0800 +Subject: [PATCH] drm/rockchip: vop: fix format bpp calculation + +We can't rely on cpp for bpp calculation as the cpp of +some formats(DRM_FORMAT_YUV420_8BIT/10BIT, etc) is zero. + +Signed-off-by: Andy Yan +Acked-by: Sascha Hauer +Signed-off-by: Heiko Stuebner +Link: https://patchwork.freedesktop.org/patch/msgid/20231018094210.2475771-1-andyshrk@163.com +--- + drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 18 ++++++++++++++++-- + 1 file changed, 16 insertions(+), 2 deletions(-) + +--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +@@ -282,6 +282,20 @@ static void vop2_win_disable(struct vop2 + vop2_win_write(win, VOP2_WIN_CLUSTER_ENABLE, 0); + } + ++static u32 vop2_get_bpp(const struct drm_format_info *format) ++{ ++ switch (format->format) { ++ case DRM_FORMAT_YUV420_8BIT: ++ return 12; ++ case DRM_FORMAT_YUV420_10BIT: ++ return 15; ++ case DRM_FORMAT_VUY101010: ++ return 30; ++ default: ++ return drm_format_info_bpp(format, 0); ++ } ++} ++ + static enum vop2_data_format vop2_convert_format(u32 format) + { + switch (format) { +@@ -482,7 +496,7 @@ static u32 vop2_afbc_transform_offset(st + { + struct drm_rect *src = &pstate->src; + struct drm_framebuffer *fb = pstate->fb; +- u32 bpp = fb->format->cpp[0] * 8; ++ u32 bpp = vop2_get_bpp(fb->format); + u32 vir_width = (fb->pitches[0] << 3) / bpp; + u32 width = drm_rect_width(src) >> 16; + u32 height = drm_rect_height(src) >> 16; +@@ -1080,7 +1094,7 @@ static void vop2_plane_atomic_update(str + struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode; + struct vop2 *vop2 = win->vop2; + struct drm_framebuffer *fb = pstate->fb; +- u32 bpp = fb->format->cpp[0] * 8; ++ u32 bpp = vop2_get_bpp(fb->format); + u32 actual_w, actual_h, dsp_w, dsp_h; + u32 act_info, dsp_info; + u32 format; diff --git a/target/linux/rockchip/patches-6.6/033-10-v6.7-drm-rockchip-vop2-remove-the-unsupported-format-of-cluste.patch b/target/linux/rockchip/patches-6.6/033-10-v6.7-drm-rockchip-vop2-remove-the-unsupported-format-of-cluste.patch new file mode 100644 index 0000000000..05bf2146dd --- /dev/null +++ b/target/linux/rockchip/patches-6.6/033-10-v6.7-drm-rockchip-vop2-remove-the-unsupported-format-of-cluste.patch @@ -0,0 +1,89 @@ +From 01d5a75370a60c3a8d691347ae6ebb2a9f8dc44a Mon Sep 17 00:00:00 2001 +From: Andy Yan +Date: Wed, 18 Oct 2023 17:42:39 +0800 +Subject: [PATCH] drm/rockchip: vop2: remove the unsupported format of cluster + window + +The cluster window on vop2 doesn't support linear yuv +format(NV12/16/24), it only support afbc based yuv +format(DRM_FORMAT_YUV420_8BIT/10BIT), which will be +added in next patch. + +Fixes: 604be85547ce ("drm/rockchip: Add VOP2 driver") +Signed-off-by: Andy Yan +Acked-by: Sascha Hauer +Signed-off-by: Heiko Stuebner +Link: https://patchwork.freedesktop.org/patch/msgid/20231018094239.2475851-1-andyshrk@163.com +--- + drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 24 +------------------- + drivers/gpu/drm/rockchip/rockchip_vop2_reg.c | 3 --- + 2 files changed, 1 insertion(+), 26 deletions(-) + +--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +@@ -342,10 +342,6 @@ static enum vop2_afbc_format vop2_conver + case DRM_FORMAT_RGB565: + case DRM_FORMAT_BGR565: + return VOP2_AFBC_FMT_RGB565; +- case DRM_FORMAT_NV12: +- return VOP2_AFBC_FMT_YUV420; +- case DRM_FORMAT_NV16: +- return VOP2_AFBC_FMT_YUV422; + default: + return VOP2_AFBC_FMT_INVALID; + } +@@ -366,25 +362,9 @@ static bool vop2_win_rb_swap(u32 format) + } + } + +-static bool vop2_afbc_rb_swap(u32 format) +-{ +- switch (format) { +- case DRM_FORMAT_NV24: +- return true; +- default: +- return false; +- } +-} +- + static bool vop2_afbc_uv_swap(u32 format) + { +- switch (format) { +- case DRM_FORMAT_NV12: +- case DRM_FORMAT_NV16: +- return true; +- default: +- return false; +- } ++ return false; + } + + static bool vop2_win_uv_swap(u32 format) +@@ -1232,7 +1212,6 @@ static void vop2_plane_atomic_update(str + drm_err(vop2->drm, "vp%d %s stride[%d] not 64 pixel aligned\n", + vp->id, win->data->name, stride); + +- rb_swap = vop2_afbc_rb_swap(fb->format->format); + uv_swap = vop2_afbc_uv_swap(fb->format->format); + /* + * This is a workaround for crazy IC design, Cluster +@@ -1249,7 +1228,6 @@ static void vop2_plane_atomic_update(str + if (vop2_cluster_window(win)) + vop2_win_write(win, VOP2_WIN_AFBC_ENABLE, 1); + vop2_win_write(win, VOP2_WIN_AFBC_FORMAT, afbc_format); +- vop2_win_write(win, VOP2_WIN_AFBC_RB_SWAP, rb_swap); + vop2_win_write(win, VOP2_WIN_AFBC_UV_SWAP, uv_swap); + vop2_win_write(win, VOP2_WIN_AFBC_AUTO_GATING_EN, 0); + vop2_win_write(win, VOP2_WIN_AFBC_BLOCK_SPLIT_EN, 0); +--- a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c ++++ b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c +@@ -24,9 +24,6 @@ static const uint32_t formats_win_full_1 + DRM_FORMAT_BGR888, + DRM_FORMAT_RGB565, + DRM_FORMAT_BGR565, +- DRM_FORMAT_NV12, +- DRM_FORMAT_NV16, +- DRM_FORMAT_NV24, + }; + + static const uint32_t formats_win_full_10bit_yuyv[] = { diff --git a/target/linux/rockchip/patches-6.6/033-11-v6.7-drm-rockchip-vop2-Add-more-supported-10bit-formats.patch b/target/linux/rockchip/patches-6.6/033-11-v6.7-drm-rockchip-vop2-Add-more-supported-10bit-formats.patch new file mode 100644 index 0000000000..660845ec0d --- /dev/null +++ b/target/linux/rockchip/patches-6.6/033-11-v6.7-drm-rockchip-vop2-Add-more-supported-10bit-formats.patch @@ -0,0 +1,162 @@ +From bfd8a5c228fa3bb97884f77529c09e8745da08b9 Mon Sep 17 00:00:00 2001 +From: Andy Yan +Date: Wed, 18 Oct 2023 17:43:18 +0800 +Subject: [PATCH] drm/rockchip: vop2: Add more supported 10bit formats + +Add 10 bit RGB and AFBC based YUV format supported +by vop2. + +Signed-off-by: Andy Yan +Acked-by: Sascha Hauer +Signed-off-by: Heiko Stuebner +Link: https://patchwork.freedesktop.org/patch/msgid/20231018094318.2476081-1-andyshrk@163.com +--- + drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 45 +++++++++++++++++++- + drivers/gpu/drm/rockchip/rockchip_vop2_reg.c | 22 +++++++--- + 2 files changed, 61 insertions(+), 6 deletions(-) + +--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +@@ -299,6 +299,11 @@ static u32 vop2_get_bpp(const struct drm + static enum vop2_data_format vop2_convert_format(u32 format) + { + switch (format) { ++ case DRM_FORMAT_XRGB2101010: ++ case DRM_FORMAT_ARGB2101010: ++ case DRM_FORMAT_XBGR2101010: ++ case DRM_FORMAT_ABGR2101010: ++ return VOP2_FMT_XRGB101010; + case DRM_FORMAT_XRGB8888: + case DRM_FORMAT_ARGB8888: + case DRM_FORMAT_XBGR8888: +@@ -311,10 +316,19 @@ static enum vop2_data_format vop2_conver + case DRM_FORMAT_BGR565: + return VOP2_FMT_RGB565; + case DRM_FORMAT_NV12: ++ case DRM_FORMAT_NV21: ++ case DRM_FORMAT_YUV420_8BIT: + return VOP2_FMT_YUV420SP; ++ case DRM_FORMAT_NV15: ++ case DRM_FORMAT_YUV420_10BIT: ++ return VOP2_FMT_YUV420SP_10; + case DRM_FORMAT_NV16: ++ case DRM_FORMAT_NV61: + return VOP2_FMT_YUV422SP; ++ case DRM_FORMAT_Y210: ++ return VOP2_FMT_YUV422SP_10; + case DRM_FORMAT_NV24: ++ case DRM_FORMAT_NV42: + return VOP2_FMT_YUV444SP; + case DRM_FORMAT_YUYV: + case DRM_FORMAT_YVYU: +@@ -331,6 +345,11 @@ static enum vop2_data_format vop2_conver + static enum vop2_afbc_format vop2_convert_afbc_format(u32 format) + { + switch (format) { ++ case DRM_FORMAT_XRGB2101010: ++ case DRM_FORMAT_ARGB2101010: ++ case DRM_FORMAT_XBGR2101010: ++ case DRM_FORMAT_ABGR2101010: ++ return VOP2_AFBC_FMT_ARGB2101010; + case DRM_FORMAT_XRGB8888: + case DRM_FORMAT_ARGB8888: + case DRM_FORMAT_XBGR8888: +@@ -342,6 +361,17 @@ static enum vop2_afbc_format vop2_conver + case DRM_FORMAT_RGB565: + case DRM_FORMAT_BGR565: + return VOP2_AFBC_FMT_RGB565; ++ case DRM_FORMAT_YUV420_8BIT: ++ return VOP2_AFBC_FMT_YUV420; ++ case DRM_FORMAT_YUV420_10BIT: ++ return VOP2_AFBC_FMT_YUV420_10BIT; ++ case DRM_FORMAT_YVYU: ++ case DRM_FORMAT_YUYV: ++ case DRM_FORMAT_VYUY: ++ case DRM_FORMAT_UYVY: ++ return VOP2_AFBC_FMT_YUV422; ++ case DRM_FORMAT_Y210: ++ return VOP2_AFBC_FMT_YUV422_10BIT; + default: + return VOP2_AFBC_FMT_INVALID; + } +@@ -352,6 +382,8 @@ static enum vop2_afbc_format vop2_conver + static bool vop2_win_rb_swap(u32 format) + { + switch (format) { ++ case DRM_FORMAT_XBGR2101010: ++ case DRM_FORMAT_ABGR2101010: + case DRM_FORMAT_XBGR8888: + case DRM_FORMAT_ABGR8888: + case DRM_FORMAT_BGR888: +@@ -364,7 +396,15 @@ static bool vop2_win_rb_swap(u32 format) + + static bool vop2_afbc_uv_swap(u32 format) + { +- return false; ++ switch (format) { ++ case DRM_FORMAT_YUYV: ++ case DRM_FORMAT_Y210: ++ case DRM_FORMAT_YUV420_8BIT: ++ case DRM_FORMAT_YUV420_10BIT: ++ return true; ++ default: ++ return false; ++ } + } + + static bool vop2_win_uv_swap(u32 format) +@@ -373,6 +413,9 @@ static bool vop2_win_uv_swap(u32 format) + case DRM_FORMAT_NV12: + case DRM_FORMAT_NV16: + case DRM_FORMAT_NV24: ++ case DRM_FORMAT_NV15: ++ case DRM_FORMAT_YUYV: ++ case DRM_FORMAT_UYVY: + return true; + default: + return false; +--- a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c ++++ b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c +@@ -16,6 +16,10 @@ + #include "rockchip_drm_vop2.h" + + static const uint32_t formats_win_full_10bit[] = { ++ DRM_FORMAT_XRGB2101010, ++ DRM_FORMAT_ARGB2101010, ++ DRM_FORMAT_XBGR2101010, ++ DRM_FORMAT_ABGR2101010, + DRM_FORMAT_XRGB8888, + DRM_FORMAT_ARGB8888, + DRM_FORMAT_XBGR8888, +@@ -24,6 +28,10 @@ static const uint32_t formats_win_full_1 + DRM_FORMAT_BGR888, + DRM_FORMAT_RGB565, + DRM_FORMAT_BGR565, ++ DRM_FORMAT_YUV420_8BIT, /* yuv420_8bit non-Linear mode only */ ++ DRM_FORMAT_YUV420_10BIT, /* yuv420_10bit non-Linear mode only */ ++ DRM_FORMAT_YUYV, /* yuv422_8bit non-Linear mode only*/ ++ DRM_FORMAT_Y210, /* yuv422_10bit non-Linear mode only */ + }; + + static const uint32_t formats_win_full_10bit_yuyv[] = { +@@ -35,11 +43,15 @@ static const uint32_t formats_win_full_1 + DRM_FORMAT_BGR888, + DRM_FORMAT_RGB565, + DRM_FORMAT_BGR565, +- DRM_FORMAT_NV12, +- DRM_FORMAT_NV16, +- DRM_FORMAT_NV24, +- DRM_FORMAT_YVYU, +- DRM_FORMAT_VYUY, ++ DRM_FORMAT_NV12, /* yuv420_8bit linear mode, 2 plane */ ++ DRM_FORMAT_NV21, /* yuv420_8bit linear mode, 2 plane */ ++ DRM_FORMAT_NV15, /* yuv420_10bit linear mode, 2 plane, no padding */ ++ DRM_FORMAT_NV16, /* yuv422_8bit linear mode, 2 plane */ ++ DRM_FORMAT_NV61, /* yuv422_8bit linear mode, 2 plane */ ++ DRM_FORMAT_NV24, /* yuv444_8bit linear mode, 2 plane */ ++ DRM_FORMAT_NV42, /* yuv444_8bit linear mode, 2 plane */ ++ DRM_FORMAT_YVYU, /* yuv422_8bit[YVYU] linear mode */ ++ DRM_FORMAT_VYUY, /* yuv422_8bit[VYUY] linear mode */ + }; + + static const uint32_t formats_win_lite[] = { diff --git a/target/linux/rockchip/patches-6.6/033-12-v6.7-drm-rockchip-vop2-rename-window-formats-to-show-window-ty.patch b/target/linux/rockchip/patches-6.6/033-12-v6.7-drm-rockchip-vop2-rename-window-formats-to-show-window-ty.patch new file mode 100644 index 0000000000..8d735684d2 --- /dev/null +++ b/target/linux/rockchip/patches-6.6/033-12-v6.7-drm-rockchip-vop2-rename-window-formats-to-show-window-ty.patch @@ -0,0 +1,116 @@ +From 215737e37d07ade8952048339e37aec6c6f82223 Mon Sep 17 00:00:00 2001 +From: Andy Yan +Date: Wed, 18 Oct 2023 17:43:39 +0800 +Subject: [PATCH] drm/rockchip: vop2: rename window formats to show window type + using them + +formats_win_full_10bit is for cluster window, +formats_win_full_10bit_yuyv is for rk356x esmart, rk3588 esmart window +will support more format. +formats_win_lite is for smart window. + +Rename it based the windows type may let meaning is clearer + +Signed-off-by: Andy Yan +Acked-by: Sascha Hauer +Signed-off-by: Heiko Stuebner +Link: https://patchwork.freedesktop.org/patch/msgid/20231018094339.2476142-1-andyshrk@163.com +--- + drivers/gpu/drm/rockchip/rockchip_vop2_reg.c | 30 ++++++++++---------- + 1 file changed, 15 insertions(+), 15 deletions(-) + +--- a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c ++++ b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c +@@ -15,7 +15,7 @@ + + #include "rockchip_drm_vop2.h" + +-static const uint32_t formats_win_full_10bit[] = { ++static const uint32_t formats_cluster[] = { + DRM_FORMAT_XRGB2101010, + DRM_FORMAT_ARGB2101010, + DRM_FORMAT_XBGR2101010, +@@ -34,7 +34,7 @@ static const uint32_t formats_win_full_1 + DRM_FORMAT_Y210, /* yuv422_10bit non-Linear mode only */ + }; + +-static const uint32_t formats_win_full_10bit_yuyv[] = { ++static const uint32_t formats_rk356x_esmart[] = { + DRM_FORMAT_XRGB8888, + DRM_FORMAT_ARGB8888, + DRM_FORMAT_XBGR8888, +@@ -54,7 +54,7 @@ static const uint32_t formats_win_full_1 + DRM_FORMAT_VYUY, /* yuv422_8bit[VYUY] linear mode */ + }; + +-static const uint32_t formats_win_lite[] = { ++static const uint32_t formats_smart[] = { + DRM_FORMAT_XRGB8888, + DRM_FORMAT_ARGB8888, + DRM_FORMAT_XBGR8888, +@@ -153,8 +153,8 @@ static const struct vop2_win_data rk3568 + .name = "Smart0-win0", + .phys_id = ROCKCHIP_VOP2_SMART0, + .base = 0x1c00, +- .formats = formats_win_lite, +- .nformats = ARRAY_SIZE(formats_win_lite), ++ .formats = formats_smart, ++ .nformats = ARRAY_SIZE(formats_smart), + .format_modifiers = format_modifiers, + .layer_sel_id = 3, + .supported_rotations = DRM_MODE_REFLECT_Y, +@@ -165,8 +165,8 @@ static const struct vop2_win_data rk3568 + }, { + .name = "Smart1-win0", + .phys_id = ROCKCHIP_VOP2_SMART1, +- .formats = formats_win_lite, +- .nformats = ARRAY_SIZE(formats_win_lite), ++ .formats = formats_smart, ++ .nformats = ARRAY_SIZE(formats_smart), + .format_modifiers = format_modifiers, + .base = 0x1e00, + .layer_sel_id = 7, +@@ -178,8 +178,8 @@ static const struct vop2_win_data rk3568 + }, { + .name = "Esmart1-win0", + .phys_id = ROCKCHIP_VOP2_ESMART1, +- .formats = formats_win_full_10bit_yuyv, +- .nformats = ARRAY_SIZE(formats_win_full_10bit_yuyv), ++ .formats = formats_rk356x_esmart, ++ .nformats = ARRAY_SIZE(formats_rk356x_esmart), + .format_modifiers = format_modifiers, + .base = 0x1a00, + .layer_sel_id = 6, +@@ -191,8 +191,8 @@ static const struct vop2_win_data rk3568 + }, { + .name = "Esmart0-win0", + .phys_id = ROCKCHIP_VOP2_ESMART0, +- .formats = formats_win_full_10bit_yuyv, +- .nformats = ARRAY_SIZE(formats_win_full_10bit_yuyv), ++ .formats = formats_rk356x_esmart, ++ .nformats = ARRAY_SIZE(formats_rk356x_esmart), + .format_modifiers = format_modifiers, + .base = 0x1800, + .layer_sel_id = 2, +@@ -205,8 +205,8 @@ static const struct vop2_win_data rk3568 + .name = "Cluster0-win0", + .phys_id = ROCKCHIP_VOP2_CLUSTER0, + .base = 0x1000, +- .formats = formats_win_full_10bit, +- .nformats = ARRAY_SIZE(formats_win_full_10bit), ++ .formats = formats_cluster, ++ .nformats = ARRAY_SIZE(formats_cluster), + .format_modifiers = format_modifiers_afbc, + .layer_sel_id = 0, + .supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 | +@@ -220,8 +220,8 @@ static const struct vop2_win_data rk3568 + .name = "Cluster1-win0", + .phys_id = ROCKCHIP_VOP2_CLUSTER1, + .base = 0x1200, +- .formats = formats_win_full_10bit, +- .nformats = ARRAY_SIZE(formats_win_full_10bit), ++ .formats = formats_cluster, ++ .nformats = ARRAY_SIZE(formats_cluster), + .format_modifiers = format_modifiers_afbc, + .layer_sel_id = 1, + .supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 | diff --git a/target/linux/rockchip/patches-6.6/033-13-v6.7-drm-fourcc-Add-NV20-and-NV30-YUV-formats.patch b/target/linux/rockchip/patches-6.6/033-13-v6.7-drm-fourcc-Add-NV20-and-NV30-YUV-formats.patch new file mode 100644 index 0000000000..43b0d5a545 --- /dev/null +++ b/target/linux/rockchip/patches-6.6/033-13-v6.7-drm-fourcc-Add-NV20-and-NV30-YUV-formats.patch @@ -0,0 +1,57 @@ +From 728c15b4b5f3369cbde73d5e0f14701ab370f985 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Mon, 23 Oct 2023 17:37:14 +0000 +Subject: [PATCH] drm/fourcc: Add NV20 and NV30 YUV formats + +DRM_FORMAT_NV20 and DRM_FORMAT_NV30 formats is the 2x1 and non-subsampled +variant of NV15, a 10-bit 2-plane YUV format that has no padding between +components. Instead, luminance and chrominance samples are grouped into 4s +so that each group is packed into an integer number of bytes: + +YYYY = UVUV = 4 * 10 bits = 40 bits = 5 bytes + +The '20' and '30' suffix refers to the optimum effective bits per pixel +which is achieved when the total number of luminance samples is a multiple +of 4. + +V2: Added NV30 format + +Signed-off-by: Jonas Karlman +Reviewed-by: Sandy Huang +Reviewed-by: Christopher Obbard +Tested-by: Christopher Obbard +Signed-off-by: Heiko Stuebner +Link: https://patchwork.freedesktop.org/patch/msgid/20231023173718.188102-2-jonas@kwiboo.se +--- + drivers/gpu/drm/drm_fourcc.c | 8 ++++++++ + include/uapi/drm/drm_fourcc.h | 2 ++ + 2 files changed, 10 insertions(+) + +--- a/drivers/gpu/drm/drm_fourcc.c ++++ b/drivers/gpu/drm/drm_fourcc.c +@@ -299,6 +299,14 @@ const struct drm_format_info *__drm_form + .num_planes = 2, .char_per_block = { 5, 5, 0 }, + .block_w = { 4, 2, 0 }, .block_h = { 1, 1, 0 }, .hsub = 2, + .vsub = 2, .is_yuv = true }, ++ { .format = DRM_FORMAT_NV20, .depth = 0, ++ .num_planes = 2, .char_per_block = { 5, 5, 0 }, ++ .block_w = { 4, 2, 0 }, .block_h = { 1, 1, 0 }, .hsub = 2, ++ .vsub = 1, .is_yuv = true }, ++ { .format = DRM_FORMAT_NV30, .depth = 0, ++ .num_planes = 2, .char_per_block = { 5, 5, 0 }, ++ .block_w = { 4, 2, 0 }, .block_h = { 1, 1, 0 }, .hsub = 1, ++ .vsub = 1, .is_yuv = true }, + { .format = DRM_FORMAT_Q410, .depth = 0, + .num_planes = 3, .char_per_block = { 2, 2, 2 }, + .block_w = { 1, 1, 1 }, .block_h = { 1, 1, 1 }, .hsub = 1, +--- a/include/uapi/drm/drm_fourcc.h ++++ b/include/uapi/drm/drm_fourcc.h +@@ -323,6 +323,8 @@ extern "C" { + * index 1 = Cr:Cb plane, [39:0] Cr1:Cb1:Cr0:Cb0 little endian + */ + #define DRM_FORMAT_NV15 fourcc_code('N', 'V', '1', '5') /* 2x2 subsampled Cr:Cb plane */ ++#define DRM_FORMAT_NV20 fourcc_code('N', 'V', '2', '0') /* 2x1 subsampled Cr:Cb plane */ ++#define DRM_FORMAT_NV30 fourcc_code('N', 'V', '3', '0') /* non-subsampled Cr:Cb plane */ + + /* + * 2 plane YCbCr MSB aligned diff --git a/target/linux/rockchip/patches-6.6/033-14-v6.7-drm-rockchip-vop-Add-NV15-NV20-and-NV30-support.patch b/target/linux/rockchip/patches-6.6/033-14-v6.7-drm-rockchip-vop-Add-NV15-NV20-and-NV30-support.patch new file mode 100644 index 0000000000..38c9d2b37c --- /dev/null +++ b/target/linux/rockchip/patches-6.6/033-14-v6.7-drm-rockchip-vop-Add-NV15-NV20-and-NV30-support.patch @@ -0,0 +1,231 @@ +From d4b384228562848e4b76b608a5876c92160e993c Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Mon, 23 Oct 2023 17:37:15 +0000 +Subject: [PATCH] drm/rockchip: vop: Add NV15, NV20 and NV30 support + +Add support for displaying 10-bit 4:2:0 and 4:2:2 formats produced by +the Rockchip Video Decoder on RK322X, RK3288, RK3328 and RK3399. +Also add support for 10-bit 4:4:4 format while at it. + +V5: Use drm_format_info_min_pitch() for correct bpp + Add missing NV21, NV61 and NV42 formats +V4: Rework RK3328/RK3399 win0/1 data to not affect RK3368 +V2: Added NV30 support + +Signed-off-by: Jonas Karlman +Reviewed-by: Sandy Huang +Reviewed-by: Christopher Obbard +Tested-by: Christopher Obbard +Signed-off-by: Heiko Stuebner +Link: https://patchwork.freedesktop.org/patch/msgid/20231023173718.188102-3-jonas@kwiboo.se +--- + drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 36 ++++++++--- + drivers/gpu/drm/rockchip/rockchip_drm_vop.h | 1 + + drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 66 +++++++++++++++++---- + 3 files changed, 86 insertions(+), 17 deletions(-) + +--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +@@ -280,6 +280,18 @@ static bool has_uv_swapped(uint32_t form + } + } + ++static bool is_fmt_10(uint32_t format) ++{ ++ switch (format) { ++ case DRM_FORMAT_NV15: ++ case DRM_FORMAT_NV20: ++ case DRM_FORMAT_NV30: ++ return true; ++ default: ++ return false; ++ } ++} ++ + static enum vop_data_format vop_convert_format(uint32_t format) + { + switch (format) { +@@ -295,12 +307,15 @@ static enum vop_data_format vop_convert_ + case DRM_FORMAT_BGR565: + return VOP_FMT_RGB565; + case DRM_FORMAT_NV12: ++ case DRM_FORMAT_NV15: + case DRM_FORMAT_NV21: + return VOP_FMT_YUV420SP; + case DRM_FORMAT_NV16: ++ case DRM_FORMAT_NV20: + case DRM_FORMAT_NV61: + return VOP_FMT_YUV422SP; + case DRM_FORMAT_NV24: ++ case DRM_FORMAT_NV30: + case DRM_FORMAT_NV42: + return VOP_FMT_YUV444SP; + default: +@@ -947,7 +962,12 @@ static void vop_plane_atomic_update(stru + dsp_sty = dest->y1 + crtc->mode.vtotal - crtc->mode.vsync_start; + dsp_st = dsp_sty << 16 | (dsp_stx & 0xffff); + +- offset = (src->x1 >> 16) * fb->format->cpp[0]; ++ if (fb->format->char_per_block[0]) ++ offset = drm_format_info_min_pitch(fb->format, 0, ++ src->x1 >> 16); ++ else ++ offset = (src->x1 >> 16) * fb->format->cpp[0]; ++ + offset += (src->y1 >> 16) * fb->pitches[0]; + dma_addr = rk_obj->dma_addr + offset + fb->offsets[0]; + +@@ -973,6 +993,7 @@ static void vop_plane_atomic_update(stru + } + + VOP_WIN_SET(vop, win, format, format); ++ VOP_WIN_SET(vop, win, fmt_10, is_fmt_10(fb->format->format)); + VOP_WIN_SET(vop, win, yrgb_vir, DIV_ROUND_UP(fb->pitches[0], 4)); + VOP_WIN_SET(vop, win, yrgb_mst, dma_addr); + VOP_WIN_YUV2YUV_SET(vop, win_yuv2yuv, y2r_en, is_yuv); +@@ -982,15 +1003,16 @@ static void vop_plane_atomic_update(stru + (new_state->rotation & DRM_MODE_REFLECT_X) ? 1 : 0); + + if (is_yuv) { +- int hsub = fb->format->hsub; +- int vsub = fb->format->vsub; +- int bpp = fb->format->cpp[1]; +- + uv_obj = fb->obj[1]; + rk_uv_obj = to_rockchip_obj(uv_obj); + +- offset = (src->x1 >> 16) * bpp / hsub; +- offset += (src->y1 >> 16) * fb->pitches[1] / vsub; ++ if (fb->format->char_per_block[1]) ++ offset = drm_format_info_min_pitch(fb->format, 1, ++ src->x1 >> 16); ++ else ++ offset = (src->x1 >> 16) * fb->format->cpp[1]; ++ offset /= fb->format->hsub; ++ offset += (src->y1 >> 16) * fb->pitches[1] / fb->format->vsub; + + dma_addr = rk_uv_obj->dma_addr + offset + fb->offsets[1]; + VOP_WIN_SET(vop, win, uv_vir, DIV_ROUND_UP(fb->pitches[1], 4)); +--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h +@@ -186,6 +186,7 @@ struct vop_win_phy { + struct vop_reg enable; + struct vop_reg gate; + struct vop_reg format; ++ struct vop_reg fmt_10; + struct vop_reg rb_swap; + struct vop_reg uv_swap; + struct vop_reg act_info; +--- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c ++++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c +@@ -53,6 +53,26 @@ static const uint32_t formats_win_full[] + DRM_FORMAT_NV42, + }; + ++static const uint32_t formats_win_full_10[] = { ++ DRM_FORMAT_XRGB8888, ++ DRM_FORMAT_ARGB8888, ++ DRM_FORMAT_XBGR8888, ++ DRM_FORMAT_ABGR8888, ++ DRM_FORMAT_RGB888, ++ DRM_FORMAT_BGR888, ++ DRM_FORMAT_RGB565, ++ DRM_FORMAT_BGR565, ++ DRM_FORMAT_NV12, ++ DRM_FORMAT_NV21, ++ DRM_FORMAT_NV16, ++ DRM_FORMAT_NV61, ++ DRM_FORMAT_NV24, ++ DRM_FORMAT_NV42, ++ DRM_FORMAT_NV15, ++ DRM_FORMAT_NV20, ++ DRM_FORMAT_NV30, ++}; ++ + static const uint64_t format_modifiers_win_full[] = { + DRM_FORMAT_MOD_LINEAR, + DRM_FORMAT_MOD_INVALID, +@@ -627,11 +647,12 @@ static const struct vop_scl_regs rk3288_ + + static const struct vop_win_phy rk3288_win01_data = { + .scl = &rk3288_win_full_scl, +- .data_formats = formats_win_full, +- .nformats = ARRAY_SIZE(formats_win_full), ++ .data_formats = formats_win_full_10, ++ .nformats = ARRAY_SIZE(formats_win_full_10), + .format_modifiers = format_modifiers_win_full, + .enable = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 0), + .format = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 1), ++ .fmt_10 = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 4), + .rb_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 12), + .uv_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 15), + .act_info = VOP_REG(RK3288_WIN0_ACT_INFO, 0x1fff1fff, 0), +@@ -936,13 +957,38 @@ static const struct vop_win_yuv2yuv_data + + }; + +-static const struct vop_win_phy rk3399_win01_data = { ++static const struct vop_win_phy rk3399_win0_data = { + .scl = &rk3288_win_full_scl, +- .data_formats = formats_win_full, +- .nformats = ARRAY_SIZE(formats_win_full), ++ .data_formats = formats_win_full_10, ++ .nformats = ARRAY_SIZE(formats_win_full_10), + .format_modifiers = format_modifiers_win_full_afbc, + .enable = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 0), + .format = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 1), ++ .fmt_10 = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 4), ++ .rb_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 12), ++ .uv_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 15), ++ .x_mir_en = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 21), ++ .y_mir_en = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 22), ++ .act_info = VOP_REG(RK3288_WIN0_ACT_INFO, 0x1fff1fff, 0), ++ .dsp_info = VOP_REG(RK3288_WIN0_DSP_INFO, 0x0fff0fff, 0), ++ .dsp_st = VOP_REG(RK3288_WIN0_DSP_ST, 0x1fff1fff, 0), ++ .yrgb_mst = VOP_REG(RK3288_WIN0_YRGB_MST, 0xffffffff, 0), ++ .uv_mst = VOP_REG(RK3288_WIN0_CBR_MST, 0xffffffff, 0), ++ .yrgb_vir = VOP_REG(RK3288_WIN0_VIR, 0x3fff, 0), ++ .uv_vir = VOP_REG(RK3288_WIN0_VIR, 0x3fff, 16), ++ .src_alpha_ctl = VOP_REG(RK3288_WIN0_SRC_ALPHA_CTRL, 0xff, 0), ++ .dst_alpha_ctl = VOP_REG(RK3288_WIN0_DST_ALPHA_CTRL, 0xff, 0), ++ .channel = VOP_REG(RK3288_WIN0_CTRL2, 0xff, 0), ++}; ++ ++static const struct vop_win_phy rk3399_win1_data = { ++ .scl = &rk3288_win_full_scl, ++ .data_formats = formats_win_full_10, ++ .nformats = ARRAY_SIZE(formats_win_full_10), ++ .format_modifiers = format_modifiers_win_full, ++ .enable = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 0), ++ .format = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 1), ++ .fmt_10 = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 4), + .rb_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 12), + .uv_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 15), + .x_mir_en = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 21), +@@ -965,9 +1011,9 @@ static const struct vop_win_phy rk3399_w + * AFBC on the primary plane. + */ + static const struct vop_win_data rk3399_vop_win_data[] = { +- { .base = 0x00, .phy = &rk3399_win01_data, ++ { .base = 0x00, .phy = &rk3399_win0_data, + .type = DRM_PLANE_TYPE_PRIMARY }, +- { .base = 0x40, .phy = &rk3368_win01_data, ++ { .base = 0x40, .phy = &rk3399_win1_data, + .type = DRM_PLANE_TYPE_OVERLAY }, + { .base = 0x00, .phy = &rk3368_win23_data, + .type = DRM_PLANE_TYPE_OVERLAY }, +@@ -1099,11 +1145,11 @@ static const struct vop_intr rk3328_vop_ + }; + + static const struct vop_win_data rk3328_vop_win_data[] = { +- { .base = 0xd0, .phy = &rk3368_win01_data, ++ { .base = 0xd0, .phy = &rk3399_win1_data, + .type = DRM_PLANE_TYPE_PRIMARY }, +- { .base = 0x1d0, .phy = &rk3368_win01_data, ++ { .base = 0x1d0, .phy = &rk3399_win1_data, + .type = DRM_PLANE_TYPE_OVERLAY }, +- { .base = 0x2d0, .phy = &rk3368_win01_data, ++ { .base = 0x2d0, .phy = &rk3399_win1_data, + .type = DRM_PLANE_TYPE_CURSOR }, + }; + diff --git a/target/linux/rockchip/patches-6.6/033-15-v6.8-drm-rockchip-vop2-Add-NV20-and-NV30-support.patch b/target/linux/rockchip/patches-6.6/033-15-v6.8-drm-rockchip-vop2-Add-NV20-and-NV30-support.patch new file mode 100644 index 0000000000..ead6b64a9f --- /dev/null +++ b/target/linux/rockchip/patches-6.6/033-15-v6.8-drm-rockchip-vop2-Add-NV20-and-NV30-support.patch @@ -0,0 +1,67 @@ +From 5fc6aa7db080fd90ef00846aac04e8a211088132 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Wed, 25 Oct 2023 21:32:46 +0000 +Subject: [PATCH] drm/rockchip: vop2: Add NV20 and NV30 support + +Add support for the 10-bit 4:2:2 and 4:4:4 formats NV20 and NV30. + +These formats can be tested using modetest [1]: + + modetest -P @:1920x1080@ + +e.g. on a ROCK 3 Model A (rk3568): + + modetest -P 43@67:1920x1080@NV20 -F tiles,tiles + modetest -P 43@67:1920x1080@NV30 -F smpte,smpte + +[1] https://gitlab.freedesktop.org/mesa/drm/-/merge_requests/329 + +Signed-off-by: Jonas Karlman +Reviewed-by: Christopher Obbard +Tested-by: Christopher Obbard +Signed-off-by: Heiko Stuebner +Link: https://patchwork.freedesktop.org/patch/msgid/20231025213248.2641962-1-jonas@kwiboo.se +--- + drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 5 +++++ + drivers/gpu/drm/rockchip/rockchip_vop2_reg.c | 2 ++ + 2 files changed, 7 insertions(+) + +--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +@@ -325,11 +325,14 @@ static enum vop2_data_format vop2_conver + case DRM_FORMAT_NV16: + case DRM_FORMAT_NV61: + return VOP2_FMT_YUV422SP; ++ case DRM_FORMAT_NV20: + case DRM_FORMAT_Y210: + return VOP2_FMT_YUV422SP_10; + case DRM_FORMAT_NV24: + case DRM_FORMAT_NV42: + return VOP2_FMT_YUV444SP; ++ case DRM_FORMAT_NV30: ++ return VOP2_FMT_YUV444SP_10; + case DRM_FORMAT_YUYV: + case DRM_FORMAT_YVYU: + return VOP2_FMT_VYUY422; +@@ -414,6 +417,8 @@ static bool vop2_win_uv_swap(u32 format) + case DRM_FORMAT_NV16: + case DRM_FORMAT_NV24: + case DRM_FORMAT_NV15: ++ case DRM_FORMAT_NV20: ++ case DRM_FORMAT_NV30: + case DRM_FORMAT_YUYV: + case DRM_FORMAT_UYVY: + return true; +--- a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c ++++ b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c +@@ -48,8 +48,10 @@ static const uint32_t formats_rk356x_esm + DRM_FORMAT_NV15, /* yuv420_10bit linear mode, 2 plane, no padding */ + DRM_FORMAT_NV16, /* yuv422_8bit linear mode, 2 plane */ + DRM_FORMAT_NV61, /* yuv422_8bit linear mode, 2 plane */ ++ DRM_FORMAT_NV20, /* yuv422_10bit linear mode, 2 plane, no padding */ + DRM_FORMAT_NV24, /* yuv444_8bit linear mode, 2 plane */ + DRM_FORMAT_NV42, /* yuv444_8bit linear mode, 2 plane */ ++ DRM_FORMAT_NV30, /* yuv444_10bit linear mode, 2 plane, no padding */ + DRM_FORMAT_YVYU, /* yuv422_8bit[YVYU] linear mode */ + DRM_FORMAT_VYUY, /* yuv422_8bit[VYUY] linear mode */ + }; diff --git a/target/linux/rockchip/patches-6.6/033-16-v6.8-drm-rockchip-rk3066_hdmi-Remove-useless-mode_fixup.patch b/target/linux/rockchip/patches-6.6/033-16-v6.8-drm-rockchip-rk3066_hdmi-Remove-useless-mode_fixup.patch new file mode 100644 index 0000000000..861e58df1c --- /dev/null +++ b/target/linux/rockchip/patches-6.6/033-16-v6.8-drm-rockchip-rk3066_hdmi-Remove-useless-mode_fixup.patch @@ -0,0 +1,40 @@ +From 1044f4a31734eef000f42cdaaf35bb2f76286be5 Mon Sep 17 00:00:00 2001 +From: Johan Jonker +Date: Thu, 2 Nov 2023 14:41:48 +0100 +Subject: [PATCH] drm/rockchip: rk3066_hdmi: Remove useless mode_fixup + +The mode_fixup implementation doesn't do anything, so we can simply +remove it. + +Signed-off-by: Johan Jonker +Signed-off-by: Heiko Stuebner +Link: https://patchwork.freedesktop.org/patch/msgid/5649ac03-db92-42a9-d86a-76dfa1af7c64@gmail.com +--- + drivers/gpu/drm/rockchip/rk3066_hdmi.c | 9 --------- + 1 file changed, 9 deletions(-) + +--- a/drivers/gpu/drm/rockchip/rk3066_hdmi.c ++++ b/drivers/gpu/drm/rockchip/rk3066_hdmi.c +@@ -434,14 +434,6 @@ static void rk3066_hdmi_encoder_disable( + rk3066_hdmi_set_power_mode(hdmi, HDMI_SYS_POWER_MODE_A); + } + +-static bool +-rk3066_hdmi_encoder_mode_fixup(struct drm_encoder *encoder, +- const struct drm_display_mode *mode, +- struct drm_display_mode *adj_mode) +-{ +- return true; +-} +- + static int + rk3066_hdmi_encoder_atomic_check(struct drm_encoder *encoder, + struct drm_crtc_state *crtc_state, +@@ -459,7 +451,6 @@ static const + struct drm_encoder_helper_funcs rk3066_hdmi_encoder_helper_funcs = { + .enable = rk3066_hdmi_encoder_enable, + .disable = rk3066_hdmi_encoder_disable, +- .mode_fixup = rk3066_hdmi_encoder_mode_fixup, + .mode_set = rk3066_hdmi_encoder_mode_set, + .atomic_check = rk3066_hdmi_encoder_atomic_check, + }; diff --git a/target/linux/rockchip/patches-6.6/033-17-v6.8-drm-rockchip-rk3066_hdmi-Switch-encoder-hooks-to-atomic.patch b/target/linux/rockchip/patches-6.6/033-17-v6.8-drm-rockchip-rk3066_hdmi-Switch-encoder-hooks-to-atomic.patch new file mode 100644 index 0000000000..11679324e8 --- /dev/null +++ b/target/linux/rockchip/patches-6.6/033-17-v6.8-drm-rockchip-rk3066_hdmi-Switch-encoder-hooks-to-atomic.patch @@ -0,0 +1,88 @@ +From ae3436a5e7c2ef4f92938133bd99f92fc47ea34e Mon Sep 17 00:00:00 2001 +From: Johan Jonker +Date: Thu, 2 Nov 2023 14:42:04 +0100 +Subject: [PATCH] drm/rockchip: rk3066_hdmi: Switch encoder hooks to atomic + +The rk3066_hdmi encoder still uses the non atomic variants +of enable and disable. Convert to their atomic equivalents. +In atomic mode there is no need to save the adjusted mode, +so remove the mode_set function. + +Signed-off-by: Johan Jonker +Signed-off-by: Heiko Stuebner +Link: https://patchwork.freedesktop.org/patch/msgid/034c3446-d619-f4c3-3aaa-ab51dc19d07f@gmail.com +--- + drivers/gpu/drm/rockchip/rk3066_hdmi.c | 35 +++++++++++++------------- + 1 file changed, 17 insertions(+), 18 deletions(-) + +--- a/drivers/gpu/drm/rockchip/rk3066_hdmi.c ++++ b/drivers/gpu/drm/rockchip/rk3066_hdmi.c +@@ -55,7 +55,6 @@ struct rk3066_hdmi { + unsigned int tmdsclk; + + struct hdmi_data_info hdmi_data; +- struct drm_display_mode previous_mode; + }; + + static struct rk3066_hdmi *encoder_to_rk3066_hdmi(struct drm_encoder *encoder) +@@ -387,21 +386,21 @@ static int rk3066_hdmi_setup(struct rk30 + return 0; + } + +-static void +-rk3066_hdmi_encoder_mode_set(struct drm_encoder *encoder, +- struct drm_display_mode *mode, +- struct drm_display_mode *adj_mode) ++static void rk3066_hdmi_encoder_enable(struct drm_encoder *encoder, ++ struct drm_atomic_state *state) + { + struct rk3066_hdmi *hdmi = encoder_to_rk3066_hdmi(encoder); ++ struct drm_connector_state *conn_state; ++ struct drm_crtc_state *crtc_state; ++ int mux, val; + +- /* Store the display mode for plugin/DPMS poweron events. */ +- drm_mode_copy(&hdmi->previous_mode, adj_mode); +-} ++ conn_state = drm_atomic_get_new_connector_state(state, &hdmi->connector); ++ if (WARN_ON(!conn_state)) ++ return; + +-static void rk3066_hdmi_encoder_enable(struct drm_encoder *encoder) +-{ +- struct rk3066_hdmi *hdmi = encoder_to_rk3066_hdmi(encoder); +- int mux, val; ++ crtc_state = drm_atomic_get_new_crtc_state(state, conn_state->crtc); ++ if (WARN_ON(!crtc_state)) ++ return; + + mux = drm_of_encoder_active_endpoint_id(hdmi->dev->of_node, encoder); + if (mux) +@@ -414,10 +413,11 @@ static void rk3066_hdmi_encoder_enable(s + DRM_DEV_DEBUG(hdmi->dev, "hdmi encoder enable select: vop%s\n", + (mux) ? "1" : "0"); + +- rk3066_hdmi_setup(hdmi, &hdmi->previous_mode); ++ rk3066_hdmi_setup(hdmi, &crtc_state->adjusted_mode); + } + +-static void rk3066_hdmi_encoder_disable(struct drm_encoder *encoder) ++static void rk3066_hdmi_encoder_disable(struct drm_encoder *encoder, ++ struct drm_atomic_state *state) + { + struct rk3066_hdmi *hdmi = encoder_to_rk3066_hdmi(encoder); + +@@ -449,10 +449,9 @@ rk3066_hdmi_encoder_atomic_check(struct + + static const + struct drm_encoder_helper_funcs rk3066_hdmi_encoder_helper_funcs = { +- .enable = rk3066_hdmi_encoder_enable, +- .disable = rk3066_hdmi_encoder_disable, +- .mode_set = rk3066_hdmi_encoder_mode_set, +- .atomic_check = rk3066_hdmi_encoder_atomic_check, ++ .atomic_check = rk3066_hdmi_encoder_atomic_check, ++ .atomic_enable = rk3066_hdmi_encoder_enable, ++ .atomic_disable = rk3066_hdmi_encoder_disable, + }; + + static enum drm_connector_status diff --git a/target/linux/rockchip/patches-6.6/033-18-v6.8-drm-rockchip-rk3066_hdmi-include-drm-drm_atomic.h.patch b/target/linux/rockchip/patches-6.6/033-18-v6.8-drm-rockchip-rk3066_hdmi-include-drm-drm_atomic.h.patch new file mode 100644 index 0000000000..99acce8617 --- /dev/null +++ b/target/linux/rockchip/patches-6.6/033-18-v6.8-drm-rockchip-rk3066_hdmi-include-drm-drm_atomic.h.patch @@ -0,0 +1,43 @@ +From f4814c20d14ca168382e8887c768f290e4a2a861 Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +Date: Wed, 22 Nov 2023 23:18:29 +0100 +Subject: [PATCH] drm/rockchip: rk3066_hdmi: include drm/drm_atomic.h + +Without this header, the newly added code fails to build: + +drivers/gpu/drm/rockchip/rk3066_hdmi.c: In function 'rk3066_hdmi_encoder_enable': +drivers/gpu/drm/rockchip/rk3066_hdmi.c:397:22: error: implicit declaration of function 'drm_atomic_get_new_connector_state'; did you mean 'drm_atomic_helper_connector_reset'? [-Werror=implicit-function-declaration] + 397 | conn_state = drm_atomic_get_new_connector_state(state, &hdmi->connector); + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + | drm_atomic_helper_connector_reset +drivers/gpu/drm/rockchip/rk3066_hdmi.c:397:20: error: assignment to 'struct drm_connector_state *' from 'int' makes pointer from integer without a cast [-Werror=int-conversion] + 397 | conn_state = drm_atomic_get_new_connector_state(state, &hdmi->connector); + | ^ +drivers/gpu/drm/rockchip/rk3066_hdmi.c:401:22: error: implicit declaration of function 'drm_atomic_get_new_crtc_state'; did you mean 'drm_atomic_helper_swap_state'? [-Werror=implicit-function-declaration] + 401 | crtc_state = drm_atomic_get_new_crtc_state(state, conn_state->crtc); + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + | drm_atomic_helper_swap_state +drivers/gpu/drm/rockchip/rk3066_hdmi.c:401:20: error: assignment to 'struct drm_crtc_state *' from 'int' makes pointer from integer without a cast [-Werror=int-conversion] + 401 | crtc_state = drm_atomic_get_new_crtc_state(state, conn_state->crtc); + | ^ + +Fixes: ae3436a5e7c2 ("drm/rockchip: rk3066_hdmi: Switch encoder hooks to atomic") +Signed-off-by: Arnd Bergmann +Acked-by: Randy Dunlap +Tested-by: Randy Dunlap # build-tested +Signed-off-by: Heiko Stuebner +Link: https://patchwork.freedesktop.org/patch/msgid/20231122221838.3164349-1-arnd@kernel.org +--- + drivers/gpu/drm/rockchip/rk3066_hdmi.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/gpu/drm/rockchip/rk3066_hdmi.c ++++ b/drivers/gpu/drm/rockchip/rk3066_hdmi.c +@@ -4,6 +4,7 @@ + * Zheng Yang + */ + ++#include + #include + #include + #include diff --git a/target/linux/rockchip/patches-6.6/033-19-v6.8-drm-rockchip-move-output-interface-related-definition-to.patch b/target/linux/rockchip/patches-6.6/033-19-v6.8-drm-rockchip-move-output-interface-related-definition-to.patch new file mode 100644 index 0000000000..86942283ae --- /dev/null +++ b/target/linux/rockchip/patches-6.6/033-19-v6.8-drm-rockchip-move-output-interface-related-definition-to.patch @@ -0,0 +1,189 @@ +From 8c8546546f256f834e9c7cab48e5946df340d1a8 Mon Sep 17 00:00:00 2001 +From: Andy Yan +Date: Mon, 11 Dec 2023 19:56:27 +0800 +Subject: [PATCH] drm/rockchip: move output interface related definition to + rockchip_drm_drv.h + +The output interface related definition can shared between +vop and vop2, move them to rockchip_drm_drv.h can avoid duplicated +definition. + +Signed-off-by: Andy Yan +Reviewed-by: Sascha Hauer +Signed-off-by: Heiko Stuebner +Link: https://patchwork.freedesktop.org/patch/msgid/20231211115627.1784735-1-andyshrk@163.com +--- + drivers/gpu/drm/rockchip/analogix_dp-rockchip.c | 1 - + drivers/gpu/drm/rockchip/cdn-dp-core.c | 1 - + drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c | 1 - + drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 1 - + drivers/gpu/drm/rockchip/inno_hdmi.c | 1 - + drivers/gpu/drm/rockchip/rk3066_hdmi.c | 1 - + drivers/gpu/drm/rockchip/rockchip_drm_drv.h | 17 +++++++++++++++++ + drivers/gpu/drm/rockchip/rockchip_drm_vop.h | 12 ------------ + drivers/gpu/drm/rockchip/rockchip_drm_vop2.h | 16 +--------------- + drivers/gpu/drm/rockchip/rockchip_lvds.c | 1 - + drivers/gpu/drm/rockchip/rockchip_rgb.c | 1 - + 11 files changed, 18 insertions(+), 35 deletions(-) + +--- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c ++++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c +@@ -30,7 +30,6 @@ + #include + + #include "rockchip_drm_drv.h" +-#include "rockchip_drm_vop.h" + + #define RK3288_GRF_SOC_CON6 0x25c + #define RK3288_EDP_LCDC_SEL BIT(5) +--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c ++++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c +@@ -24,7 +24,6 @@ + + #include "cdn-dp-core.h" + #include "cdn-dp-reg.h" +-#include "rockchip_drm_vop.h" + + static inline struct cdn_dp_device *connector_to_dp(struct drm_connector *connector) + { +--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c ++++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c +@@ -26,7 +26,6 @@ + #include + + #include "rockchip_drm_drv.h" +-#include "rockchip_drm_vop.h" + + #define DSI_PHY_RSTZ 0xa0 + #define PHY_DISFORCEPLL 0 +--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c ++++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +@@ -18,7 +18,6 @@ + #include + + #include "rockchip_drm_drv.h" +-#include "rockchip_drm_vop.h" + + #define RK3228_GRF_SOC_CON2 0x0408 + #define RK3228_HDMI_SDAIN_MSK BIT(14) +--- a/drivers/gpu/drm/rockchip/inno_hdmi.c ++++ b/drivers/gpu/drm/rockchip/inno_hdmi.c +@@ -23,7 +23,6 @@ + #include + + #include "rockchip_drm_drv.h" +-#include "rockchip_drm_vop.h" + + #include "inno_hdmi.h" + +--- a/drivers/gpu/drm/rockchip/rk3066_hdmi.c ++++ b/drivers/gpu/drm/rockchip/rk3066_hdmi.c +@@ -18,7 +18,6 @@ + #include "rk3066_hdmi.h" + + #include "rockchip_drm_drv.h" +-#include "rockchip_drm_vop.h" + + #define DEFAULT_PLLA_RATE 30000000 + +--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h +@@ -20,6 +20,23 @@ + #define ROCKCHIP_MAX_CONNECTOR 2 + #define ROCKCHIP_MAX_CRTC 4 + ++/* ++ * display output interface supported by rockchip lcdc ++ */ ++#define ROCKCHIP_OUT_MODE_P888 0 ++#define ROCKCHIP_OUT_MODE_BT1120 0 ++#define ROCKCHIP_OUT_MODE_P666 1 ++#define ROCKCHIP_OUT_MODE_P565 2 ++#define ROCKCHIP_OUT_MODE_BT656 5 ++#define ROCKCHIP_OUT_MODE_S888 8 ++#define ROCKCHIP_OUT_MODE_S888_DUMMY 12 ++#define ROCKCHIP_OUT_MODE_YUV420 14 ++/* for use special outface */ ++#define ROCKCHIP_OUT_MODE_AAAA 15 ++ ++/* output flags */ ++#define ROCKCHIP_OUTPUT_DSI_DUAL BIT(0) ++ + struct drm_device; + struct drm_connector; + struct iommu_domain; +--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h +@@ -277,18 +277,6 @@ struct vop_data { + /* dst alpha ctrl define */ + #define DST_FACTOR_M0(x) (((x) & 0x7) << 6) + +-/* +- * display output interface supported by rockchip lcdc +- */ +-#define ROCKCHIP_OUT_MODE_P888 0 +-#define ROCKCHIP_OUT_MODE_P666 1 +-#define ROCKCHIP_OUT_MODE_P565 2 +-/* for use special outface */ +-#define ROCKCHIP_OUT_MODE_AAAA 15 +- +-/* output flags */ +-#define ROCKCHIP_OUTPUT_DSI_DUAL BIT(0) +- + enum alpha_mode { + ALPHA_STRAIGHT, + ALPHA_INVERSE, +--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h +@@ -7,10 +7,9 @@ + #ifndef _ROCKCHIP_DRM_VOP2_H + #define _ROCKCHIP_DRM_VOP2_H + +-#include "rockchip_drm_vop.h" +- + #include + #include ++#include "rockchip_drm_vop.h" + + #define VOP_FEATURE_OUTPUT_10BIT BIT(0) + +@@ -166,19 +165,6 @@ struct vop2_data { + #define WB_YRGB_FIFO_FULL_INTR BIT(18) + #define WB_COMPLETE_INTR BIT(19) + +-/* +- * display output interface supported by rockchip lcdc +- */ +-#define ROCKCHIP_OUT_MODE_P888 0 +-#define ROCKCHIP_OUT_MODE_BT1120 0 +-#define ROCKCHIP_OUT_MODE_P666 1 +-#define ROCKCHIP_OUT_MODE_P565 2 +-#define ROCKCHIP_OUT_MODE_BT656 5 +-#define ROCKCHIP_OUT_MODE_S888 8 +-#define ROCKCHIP_OUT_MODE_S888_DUMMY 12 +-#define ROCKCHIP_OUT_MODE_YUV420 14 +-/* for use special outface */ +-#define ROCKCHIP_OUT_MODE_AAAA 15 + + enum vop_csc_format { + CSC_BT601L, +--- a/drivers/gpu/drm/rockchip/rockchip_lvds.c ++++ b/drivers/gpu/drm/rockchip/rockchip_lvds.c +@@ -27,7 +27,6 @@ + #include + + #include "rockchip_drm_drv.h" +-#include "rockchip_drm_vop.h" + #include "rockchip_lvds.h" + + #define DISPLAY_OUTPUT_RGB 0 +--- a/drivers/gpu/drm/rockchip/rockchip_rgb.c ++++ b/drivers/gpu/drm/rockchip/rockchip_rgb.c +@@ -19,7 +19,6 @@ + #include + + #include "rockchip_drm_drv.h" +-#include "rockchip_drm_vop.h" + #include "rockchip_rgb.h" + + struct rockchip_rgb { diff --git a/target/linux/rockchip/patches-6.6/033-20-v6.8-Revert-drm-rockchip-vop2-Use-regcache_sync-to-fix.patch b/target/linux/rockchip/patches-6.6/033-20-v6.8-Revert-drm-rockchip-vop2-Use-regcache_sync-to-fix.patch new file mode 100644 index 0000000000..68eccf9496 --- /dev/null +++ b/target/linux/rockchip/patches-6.6/033-20-v6.8-Revert-drm-rockchip-vop2-Use-regcache_sync-to-fix.patch @@ -0,0 +1,60 @@ +From 81a06f1d02e588cfa14c5e5953d9dc50b1d404be Mon Sep 17 00:00:00 2001 +From: Andy Yan +Date: Mon, 11 Dec 2023 19:57:19 +0800 +Subject: [PATCH] Revert "drm/rockchip: vop2: Use regcache_sync() to fix + suspend/resume" + +This reverts commit b63a553e8f5aa6574eeb535a551817a93c426d8c. + +regcache_sync will try to reload the configuration in regcache to +hardware, but the registers of 4 Cluster windows and Esmart1/2/3 on +the upcoming rk3588 can not be set successfully before internal PD +power on. + +Also it's better to keep the hardware register as it is before we really +enable it. + +So let's revert this version, and keep the first version: +commit afa965a45e01 ("drm/rockchip: vop2: fix suspend/resume") + +Signed-off-by: Andy Yan +Reviewed-by: Sascha Hauer +Signed-off-by: Heiko Stuebner +Link: https://patchwork.freedesktop.org/patch/msgid/20231211115719.1784834-1-andyshrk@163.com +--- + drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +@@ -217,6 +217,8 @@ struct vop2 { + struct vop2_win win[]; + }; + ++static const struct regmap_config vop2_regmap_config; ++ + static struct vop2_video_port *to_vop2_video_port(struct drm_crtc *crtc) + { + return container_of(crtc, struct vop2_video_port, crtc); +@@ -883,7 +885,11 @@ static void vop2_enable(struct vop2 *vop + return; + } + +- regcache_sync(vop2->map); ++ ret = regmap_reinit_cache(vop2->map, &vop2_regmap_config); ++ if (ret) { ++ drm_err(vop2->drm, "failed to reinit cache: %d\n", ret); ++ return; ++ } + + if (vop2->data->soc_id == 3566) + vop2_writel(vop2, RK3568_OTP_WIN_EN, 1); +@@ -913,8 +919,6 @@ static void vop2_disable(struct vop2 *vo + + pm_runtime_put_sync(vop2->dev); + +- regcache_mark_dirty(vop2->map); +- + clk_disable_unprepare(vop2->aclk); + clk_disable_unprepare(vop2->hclk); + } diff --git a/target/linux/rockchip/patches-6.6/033-21-v6.8-drm-rockchip-vop2-set-half_block_en-bit-in-all-mode.patch b/target/linux/rockchip/patches-6.6/033-21-v6.8-drm-rockchip-vop2-set-half_block_en-bit-in-all-mode.patch new file mode 100644 index 0000000000..dbc2e25a6e --- /dev/null +++ b/target/linux/rockchip/patches-6.6/033-21-v6.8-drm-rockchip-vop2-set-half_block_en-bit-in-all-mode.patch @@ -0,0 +1,83 @@ +From bebad6bd4fbdc448ad3b337ad281b813e68f6f53 Mon Sep 17 00:00:00 2001 +From: Andy Yan +Date: Mon, 11 Dec 2023 19:57:30 +0800 +Subject: [PATCH] drm/rockchip: vop2: set half_block_en bit in all mode + +At first we thought the half_block_en bit in AFBCD_CTRL register +only work in afbc mode. But the fact is that it control the line +buffer in all mode(afbc/tile/linear), so we need configure it in +all case. + +As the cluster windows of rk3568 only supports afbc format +so is therefore not affected. + +Signed-off-by: Andy Yan +Reviewed-by: Sascha Hauer +Signed-off-by: Heiko Stuebner +Link: https://patchwork.freedesktop.org/patch/msgid/20231211115730.1784893-1-andyshrk@163.com +--- + drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 25 ++++++++++++++------ + 1 file changed, 18 insertions(+), 7 deletions(-) + +--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +@@ -521,6 +521,18 @@ static bool rockchip_vop2_mod_supported( + return vop2_convert_afbc_format(format) >= 0; + } + ++/* ++ * 0: Full mode, 16 lines for one tail ++ * 1: half block mode, 8 lines one tail ++ */ ++static bool vop2_half_block_enable(struct drm_plane_state *pstate) ++{ ++ if (pstate->rotation & (DRM_MODE_ROTATE_270 | DRM_MODE_ROTATE_90)) ++ return false; ++ else ++ return true; ++} ++ + static u32 vop2_afbc_transform_offset(struct drm_plane_state *pstate, + bool afbc_half_block_en) + { +@@ -1144,6 +1156,7 @@ static void vop2_plane_atomic_update(str + bool rotate_90 = pstate->rotation & DRM_MODE_ROTATE_90; + struct rockchip_gem_object *rk_obj; + unsigned long offset; ++ bool half_block_en; + bool afbc_en; + dma_addr_t yrgb_mst; + dma_addr_t uv_mst; +@@ -1236,6 +1249,7 @@ static void vop2_plane_atomic_update(str + dsp_info = (dsp_h - 1) << 16 | ((dsp_w - 1) & 0xffff); + + format = vop2_convert_format(fb->format->format); ++ half_block_en = vop2_half_block_enable(pstate); + + drm_dbg(vop2->drm, "vp%d update %s[%dx%d->%dx%d@%dx%d] fmt[%p4cc_%s] addr[%pad]\n", + vp->id, win->data->name, actual_w, actual_h, dsp_w, dsp_h, +@@ -1243,6 +1257,9 @@ static void vop2_plane_atomic_update(str + &fb->format->format, + afbc_en ? "AFBC" : "", &yrgb_mst); + ++ if (vop2_cluster_window(win)) ++ vop2_win_write(win, VOP2_WIN_AFBC_HALF_BLOCK_EN, half_block_en); ++ + if (afbc_en) { + u32 stride; + +@@ -1283,13 +1300,7 @@ static void vop2_plane_atomic_update(str + vop2_win_write(win, VOP2_WIN_AFBC_UV_SWAP, uv_swap); + vop2_win_write(win, VOP2_WIN_AFBC_AUTO_GATING_EN, 0); + vop2_win_write(win, VOP2_WIN_AFBC_BLOCK_SPLIT_EN, 0); +- if (pstate->rotation & (DRM_MODE_ROTATE_270 | DRM_MODE_ROTATE_90)) { +- vop2_win_write(win, VOP2_WIN_AFBC_HALF_BLOCK_EN, 0); +- transform_offset = vop2_afbc_transform_offset(pstate, false); +- } else { +- vop2_win_write(win, VOP2_WIN_AFBC_HALF_BLOCK_EN, 1); +- transform_offset = vop2_afbc_transform_offset(pstate, true); +- } ++ transform_offset = vop2_afbc_transform_offset(pstate, half_block_en); + vop2_win_write(win, VOP2_WIN_AFBC_HDR_PTR, yrgb_mst); + vop2_win_write(win, VOP2_WIN_AFBC_PIC_SIZE, act_info); + vop2_win_write(win, VOP2_WIN_AFBC_TRANSFORM_OFFSET, transform_offset); diff --git a/target/linux/rockchip/patches-6.6/033-22-v6.8-drm-rockchip-vop2-clear-afbc-en-and-transform-bit-for.patch b/target/linux/rockchip/patches-6.6/033-22-v6.8-drm-rockchip-vop2-clear-afbc-en-and-transform-bit-for.patch new file mode 100644 index 0000000000..0708a0c77c --- /dev/null +++ b/target/linux/rockchip/patches-6.6/033-22-v6.8-drm-rockchip-vop2-clear-afbc-en-and-transform-bit-for.patch @@ -0,0 +1,36 @@ +From 20529a68307feed00dd3d431d3fff0572616b0f2 Mon Sep 17 00:00:00 2001 +From: Andy Yan +Date: Mon, 11 Dec 2023 19:57:41 +0800 +Subject: [PATCH] drm/rockchip: vop2: clear afbc en and transform bit for + cluster window at linear mode + +The enable bit and transform offset of cluster windows should be +cleared when it work at linear mode, or we may have a iommu fault +issue on rk3588 which cluster windows switch between afbc and linear +mode. + +As the cluster windows of rk3568 only supports afbc format +so is therefore not affected. + +Signed-off-by: Andy Yan +Reviewed-by: Sascha Hauer +Signed-off-by: Heiko Stuebner +Link: https://patchwork.freedesktop.org/patch/msgid/20231211115741.1784954-1-andyshrk@163.com +--- + drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +@@ -1312,6 +1312,11 @@ static void vop2_plane_atomic_update(str + vop2_win_write(win, VOP2_WIN_AFBC_ROTATE_270, rotate_270); + vop2_win_write(win, VOP2_WIN_AFBC_ROTATE_90, rotate_90); + } else { ++ if (vop2_cluster_window(win)) { ++ vop2_win_write(win, VOP2_WIN_AFBC_ENABLE, 0); ++ vop2_win_write(win, VOP2_WIN_AFBC_TRANSFORM_OFFSET, 0); ++ } ++ + vop2_win_write(win, VOP2_WIN_YRGB_VIR, DIV_ROUND_UP(fb->pitches[0], 4)); + } + diff --git a/target/linux/rockchip/patches-6.6/033-23-v6.8-drm-rockchip-vop2-Add-write-mask-for-VP-config-done.patch b/target/linux/rockchip/patches-6.6/033-23-v6.8-drm-rockchip-vop2-Add-write-mask-for-VP-config-done.patch new file mode 100644 index 0000000000..33ca068702 --- /dev/null +++ b/target/linux/rockchip/patches-6.6/033-23-v6.8-drm-rockchip-vop2-Add-write-mask-for-VP-config-done.patch @@ -0,0 +1,50 @@ +From d1f8face0fc1298c88ef4a0479c3027b46ca2c77 Mon Sep 17 00:00:00 2001 +From: Andy Yan +Date: Mon, 11 Dec 2023 19:57:52 +0800 +Subject: [PATCH] drm/rockchip: vop2: Add write mask for VP config done + +The write mask bit is used to make sure when writing +config done bit for one VP will not overwrite the other. + +Unfortunately, the write mask bit is missing on +rk3566/8, that means when we write to these bits, +it will not take any effect. + +We need this to make the vop work properly after +rk3566/8 variants. + +Signed-off-by: Andy Yan +Signed-off-by: Heiko Stuebner +Link: https://patchwork.freedesktop.org/patch/msgid/20231211115752.1785013-1-andyshrk@163.com +--- + drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 15 +++++++++++++-- + 1 file changed, 13 insertions(+), 2 deletions(-) + +--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +@@ -268,12 +268,23 @@ static bool vop2_cluster_window(const st + return win->data->feature & WIN_FEATURE_CLUSTER; + } + ++/* ++ * Note: ++ * The write mask function is documented but missing on rk3566/8, writes ++ * to these bits have no effect. For newer soc(rk3588 and following) the ++ * write mask is needed for register writes. ++ * ++ * GLB_CFG_DONE_EN has no write mask bit. ++ * ++ */ + static void vop2_cfg_done(struct vop2_video_port *vp) + { + struct vop2 *vop2 = vp->vop2; ++ u32 val = RK3568_REG_CFG_DONE__GLB_CFG_DONE_EN; + +- regmap_set_bits(vop2->map, RK3568_REG_CFG_DONE, +- BIT(vp->id) | RK3568_REG_CFG_DONE__GLB_CFG_DONE_EN); ++ val |= BIT(vp->id) | (BIT(vp->id) << 16); ++ ++ regmap_set_bits(vop2->map, RK3568_REG_CFG_DONE, val); + } + + static void vop2_win_disable(struct vop2_win *win) diff --git a/target/linux/rockchip/patches-6.6/033-24-v6.8-drm-rockchip-vop2-Set-YUV-RGB-overlay-mode.patch b/target/linux/rockchip/patches-6.6/033-24-v6.8-drm-rockchip-vop2-Set-YUV-RGB-overlay-mode.patch new file mode 100644 index 0000000000..5799323680 --- /dev/null +++ b/target/linux/rockchip/patches-6.6/033-24-v6.8-drm-rockchip-vop2-Set-YUV-RGB-overlay-mode.patch @@ -0,0 +1,95 @@ +From dd49ee4614cfb0b1f627c4353b60cecfe998a374 Mon Sep 17 00:00:00 2001 +From: Andy Yan +Date: Mon, 11 Dec 2023 19:58:05 +0800 +Subject: [PATCH] drm/rockchip: vop2: Set YUV/RGB overlay mode + +Set overlay mode register according to the +output mode is yuv or rgb. + +Signed-off-by: Andy Yan +Signed-off-by: Heiko Stuebner +Link: https://patchwork.freedesktop.org/patch/msgid/20231211115805.1785073-1-andyshrk@163.com +--- + drivers/gpu/drm/rockchip/rockchip_drm_drv.h | 1 + + drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 17 ++++++++++++++--- + drivers/gpu/drm/rockchip/rockchip_drm_vop2.h | 1 + + 3 files changed, 16 insertions(+), 3 deletions(-) + +--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h +@@ -48,6 +48,7 @@ struct rockchip_crtc_state { + int output_bpc; + int output_flags; + bool enable_afbc; ++ bool yuv_overlay; + u32 bus_format; + u32 bus_flags; + int color_space; +--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +@@ -1623,6 +1623,8 @@ static void vop2_crtc_atomic_enable(stru + + vop2->enable_count++; + ++ vcstate->yuv_overlay = is_yuv_output(vcstate->bus_format); ++ + vop2_crtc_enable_irq(vp, VP_INT_POST_BUF_EMPTY); + + polflags = 0; +@@ -1650,7 +1652,7 @@ static void vop2_crtc_atomic_enable(stru + if (vop2_output_uv_swap(vcstate->bus_format, vcstate->output_mode)) + dsp_ctrl |= RK3568_VP_DSP_CTRL__DSP_RB_SWAP; + +- if (is_yuv_output(vcstate->bus_format)) ++ if (vcstate->yuv_overlay) + dsp_ctrl |= RK3568_VP_DSP_CTRL__POST_DSP_OUT_R2Y; + + vop2_dither_setup(crtc, &dsp_ctrl); +@@ -1959,10 +1961,12 @@ static void vop2_setup_layer_mixer(struc + u16 hdisplay; + u32 bg_dly; + u32 pre_scan_dly; ++ u32 ovl_ctrl; + int i; + struct vop2_video_port *vp0 = &vop2->vps[0]; + struct vop2_video_port *vp1 = &vop2->vps[1]; + struct vop2_video_port *vp2 = &vop2->vps[2]; ++ struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(vp->crtc.state); + + adjusted_mode = &vp->crtc.state->adjusted_mode; + hsync_len = adjusted_mode->crtc_hsync_end - adjusted_mode->crtc_hsync_start; +@@ -1975,7 +1979,15 @@ static void vop2_setup_layer_mixer(struc + pre_scan_dly = ((bg_dly + (hdisplay >> 1) - 1) << 16) | hsync_len; + vop2_vp_write(vp, RK3568_VP_PRE_SCAN_HTIMING, pre_scan_dly); + +- vop2_writel(vop2, RK3568_OVL_CTRL, 0); ++ ovl_ctrl = vop2_readl(vop2, RK3568_OVL_CTRL); ++ ovl_ctrl |= RK3568_OVL_CTRL__LAYERSEL_REGDONE_IMD; ++ if (vcstate->yuv_overlay) ++ ovl_ctrl |= RK3568_OVL_CTRL__YUV_MODE(vp->id); ++ else ++ ovl_ctrl &= ~RK3568_OVL_CTRL__YUV_MODE(vp->id); ++ ++ vop2_writel(vop2, RK3568_OVL_CTRL, ovl_ctrl); ++ + port_sel = vop2_readl(vop2, RK3568_OVL_PORT_SEL); + port_sel &= RK3568_OVL_PORT_SEL__SEL_PORT; + +@@ -2049,7 +2061,6 @@ static void vop2_setup_layer_mixer(struc + + vop2_writel(vop2, RK3568_OVL_LAYER_SEL, layer_sel); + vop2_writel(vop2, RK3568_OVL_PORT_SEL, port_sel); +- vop2_writel(vop2, RK3568_OVL_CTRL, RK3568_OVL_CTRL__LAYERSEL_REGDONE_IMD); + } + + static void vop2_setup_dly_for_windows(struct vop2 *vop2) +--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h +@@ -401,6 +401,7 @@ enum dst_factor_mode { + #define VOP2_COLOR_KEY_MASK BIT(31) + + #define RK3568_OVL_CTRL__LAYERSEL_REGDONE_IMD BIT(28) ++#define RK3568_OVL_CTRL__YUV_MODE(vp) BIT(vp) + + #define RK3568_VP_BG_MIX_CTRL__BG_DLY GENMASK(31, 24) + diff --git a/target/linux/rockchip/patches-6.6/033-25-v6.8-drm-rockchip-vop2-set-bg-dly-and-prescan-dly-at.patch b/target/linux/rockchip/patches-6.6/033-25-v6.8-drm-rockchip-vop2-set-bg-dly-and-prescan-dly-at.patch new file mode 100644 index 0000000000..c42069fcea --- /dev/null +++ b/target/linux/rockchip/patches-6.6/033-25-v6.8-drm-rockchip-vop2-set-bg-dly-and-prescan-dly-at.patch @@ -0,0 +1,70 @@ +From 075a5b3969becb1ebc2f1d4fa1a1fe9163679273 Mon Sep 17 00:00:00 2001 +From: Andy Yan +Date: Mon, 11 Dec 2023 19:58:15 +0800 +Subject: [PATCH] drm/rockchip: vop2: set bg dly and prescan dly at + vop2_post_config + +We need to setup background delay cycle and prescan +delay cycle when a mode is enable to avoid trigger +POST_BUF_EMPTY irq on rk3588. + +Note: RK356x has no such requirement. + +Signed-off-by: Andy Yan +Signed-off-by: Heiko Stuebner +Link: https://patchwork.freedesktop.org/patch/msgid/20231211115815.1785131-1-andyshrk@163.com +--- + drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 26 ++++++++------------ + 1 file changed, 10 insertions(+), 16 deletions(-) + +--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +@@ -1460,8 +1460,18 @@ static void vop2_post_config(struct drm_ + u32 top_margin = 100, bottom_margin = 100; + u16 hsize = hdisplay * (left_margin + right_margin) / 200; + u16 vsize = vdisplay * (top_margin + bottom_margin) / 200; ++ u16 hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start; + u16 hact_end, vact_end; + u32 val; ++ u32 bg_dly; ++ u32 pre_scan_dly; ++ ++ bg_dly = vp->data->pre_scan_max_dly[3]; ++ vop2_writel(vp->vop2, RK3568_VP_BG_MIX_CTRL(vp->id), ++ FIELD_PREP(RK3568_VP_BG_MIX_CTRL__BG_DLY, bg_dly)); ++ ++ pre_scan_dly = ((bg_dly + (hdisplay >> 1) - 1) << 16) | hsync_len; ++ vop2_vp_write(vp, RK3568_VP_PRE_SCAN_HTIMING, pre_scan_dly); + + vsize = rounddown(vsize, 2); + hsize = rounddown(hsize, 2); +@@ -1956,11 +1966,6 @@ static void vop2_setup_layer_mixer(struc + u32 layer_sel = 0; + u32 port_sel; + unsigned int nlayer, ofs; +- struct drm_display_mode *adjusted_mode; +- u16 hsync_len; +- u16 hdisplay; +- u32 bg_dly; +- u32 pre_scan_dly; + u32 ovl_ctrl; + int i; + struct vop2_video_port *vp0 = &vop2->vps[0]; +@@ -1968,17 +1973,6 @@ static void vop2_setup_layer_mixer(struc + struct vop2_video_port *vp2 = &vop2->vps[2]; + struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(vp->crtc.state); + +- adjusted_mode = &vp->crtc.state->adjusted_mode; +- hsync_len = adjusted_mode->crtc_hsync_end - adjusted_mode->crtc_hsync_start; +- hdisplay = adjusted_mode->crtc_hdisplay; +- +- bg_dly = vp->data->pre_scan_max_dly[3]; +- vop2_writel(vop2, RK3568_VP_BG_MIX_CTRL(vp->id), +- FIELD_PREP(RK3568_VP_BG_MIX_CTRL__BG_DLY, bg_dly)); +- +- pre_scan_dly = ((bg_dly + (hdisplay >> 1) - 1) << 16) | hsync_len; +- vop2_vp_write(vp, RK3568_VP_PRE_SCAN_HTIMING, pre_scan_dly); +- + ovl_ctrl = vop2_readl(vop2, RK3568_OVL_CTRL); + ovl_ctrl |= RK3568_OVL_CTRL__LAYERSEL_REGDONE_IMD; + if (vcstate->yuv_overlay) diff --git a/target/linux/rockchip/patches-6.6/033-26-v6.8-drm-rockchip-vop2-rename-grf-to-sys_grf.patch b/target/linux/rockchip/patches-6.6/033-26-v6.8-drm-rockchip-vop2-rename-grf-to-sys_grf.patch new file mode 100644 index 0000000000..ede24cafe9 --- /dev/null +++ b/target/linux/rockchip/patches-6.6/033-26-v6.8-drm-rockchip-vop2-rename-grf-to-sys_grf.patch @@ -0,0 +1,50 @@ +From c408af1afc4b74ea6df69e0313be97f1f83e981a Mon Sep 17 00:00:00 2001 +From: Andy Yan +Date: Mon, 11 Dec 2023 19:58:26 +0800 +Subject: [PATCH] drm/rockchip: vop2: rename grf to sys_grf + +The vop2 need to reference more grf(system grf, vop grf, vo0/1 grf,etc) +in the upcoming rk3588. + +So we rename the current system grf to sys_grf. + +Signed-off-by: Andy Yan +Reviewed-by: Sascha Hauer +Signed-off-by: Heiko Stuebner +Link: https://patchwork.freedesktop.org/patch/msgid/20231211115826.1785190-1-andyshrk@163.com +--- + drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +@@ -190,7 +190,7 @@ struct vop2 { + void __iomem *regs; + struct regmap *map; + +- struct regmap *grf; ++ struct regmap *sys_grf; + + /* physical map length of vop2 register */ + u32 len; +@@ -1524,9 +1524,9 @@ static void rk3568_set_intf_mux(struct v + dip &= ~RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL; + dip |= FIELD_PREP(RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL, polflags); + if (polflags & POLFLAG_DCLK_INV) +- regmap_write(vop2->grf, RK3568_GRF_VO_CON1, BIT(3 + 16) | BIT(3)); ++ regmap_write(vop2->sys_grf, RK3568_GRF_VO_CON1, BIT(3 + 16) | BIT(3)); + else +- regmap_write(vop2->grf, RK3568_GRF_VO_CON1, BIT(3 + 16)); ++ regmap_write(vop2->sys_grf, RK3568_GRF_VO_CON1, BIT(3 + 16)); + break; + case ROCKCHIP_VOP2_EP_HDMI0: + die &= ~RK3568_SYS_DSP_INFACE_EN_HDMI_MUX; +@@ -2767,7 +2767,7 @@ static int vop2_bind(struct device *dev, + return PTR_ERR(vop2->lut_regs); + } + +- vop2->grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,grf"); ++ vop2->sys_grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,grf"); + + vop2->hclk = devm_clk_get(vop2->dev, "hclk"); + if (IS_ERR(vop2->hclk)) { diff --git a/target/linux/rockchip/patches-6.6/033-27-v6.8-dt-bindings-rockchip-vop2-Add-more-endpoint-definition.patch b/target/linux/rockchip/patches-6.6/033-27-v6.8-dt-bindings-rockchip-vop2-Add-more-endpoint-definition.patch new file mode 100644 index 0000000000..9e92daf374 --- /dev/null +++ b/target/linux/rockchip/patches-6.6/033-27-v6.8-dt-bindings-rockchip-vop2-Add-more-endpoint-definition.patch @@ -0,0 +1,28 @@ +From dc7226acacc6502291446f9e33cf96246ec49a30 Mon Sep 17 00:00:00 2001 +From: Andy Yan +Date: Mon, 11 Dec 2023 19:59:07 +0800 +Subject: [PATCH] dt-bindings: rockchip,vop2: Add more endpoint definition + +There are 2 HDMI, 2 DP, 2 eDP on rk3588, so add +corresponding endpoint definition for it. + +Signed-off-by: Andy Yan +Acked-by: Krzysztof Kozlowski +Signed-off-by: Heiko Stuebner +Link: https://patchwork.freedesktop.org/patch/msgid/20231211115907.1785377-1-andyshrk@163.com +--- + include/dt-bindings/soc/rockchip,vop2.h | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/include/dt-bindings/soc/rockchip,vop2.h ++++ b/include/dt-bindings/soc/rockchip,vop2.h +@@ -10,5 +10,9 @@ + #define ROCKCHIP_VOP2_EP_LVDS0 5 + #define ROCKCHIP_VOP2_EP_MIPI1 6 + #define ROCKCHIP_VOP2_EP_LVDS1 7 ++#define ROCKCHIP_VOP2_EP_HDMI1 8 ++#define ROCKCHIP_VOP2_EP_EDP1 9 ++#define ROCKCHIP_VOP2_EP_DP0 10 ++#define ROCKCHIP_VOP2_EP_DP1 11 + + #endif /* __DT_BINDINGS_ROCKCHIP_VOP2_H */ diff --git a/target/linux/rockchip/patches-6.6/033-28-v6.8-drm-rockchip-vop2-Add-support-for-rk3588.patch b/target/linux/rockchip/patches-6.6/033-28-v6.8-drm-rockchip-vop2-Add-support-for-rk3588.patch new file mode 100644 index 0000000000..244d8174a6 --- /dev/null +++ b/target/linux/rockchip/patches-6.6/033-28-v6.8-drm-rockchip-vop2-Add-support-for-rk3588.patch @@ -0,0 +1,997 @@ +From 5a028e8f062fc862f051f8e62a0d5a1abac91955 Mon Sep 17 00:00:00 2001 +From: Andy Yan +Date: Mon, 11 Dec 2023 19:59:19 +0800 +Subject: [PATCH] drm/rockchip: vop2: Add support for rk3588 + +VOP2 on rk3588: + +Four video ports: +VP0 Max 4096x2160 +VP1 Max 4096x2160 +VP2 Max 4096x2160 +VP3 Max 2048x1080 + +4 4K Cluster windows with AFBC/line RGB and AFBC-only YUV support +4 4K Esmart windows with line RGB/YUV support + +Signed-off-by: Andy Yan +Reviewed-by: Sascha Hauer +Signed-off-by: Heiko Stuebner +Link: https://patchwork.freedesktop.org/patch/msgid/20231211115919.1785435-1-andyshrk@163.com +--- + drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 400 ++++++++++++++++++- + drivers/gpu/drm/rockchip/rockchip_drm_vop2.h | 81 ++++ + drivers/gpu/drm/rockchip/rockchip_vop2_reg.c | 221 ++++++++++ + 3 files changed, 696 insertions(+), 6 deletions(-) + +--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +@@ -191,6 +191,9 @@ struct vop2 { + struct regmap *map; + + struct regmap *sys_grf; ++ struct regmap *vop_grf; ++ struct regmap *vo1_grf; ++ struct regmap *sys_pmu; + + /* physical map length of vop2 register */ + u32 len; +@@ -209,6 +212,7 @@ struct vop2 { + unsigned int enable_count; + struct clk *hclk; + struct clk *aclk; ++ struct clk *pclk; + + /* optional internal rgb encoder */ + struct rockchip_rgb *rgb; +@@ -217,6 +221,23 @@ struct vop2 { + struct vop2_win win[]; + }; + ++#define vop2_output_if_is_hdmi(x) ((x) == ROCKCHIP_VOP2_EP_HDMI0 || \ ++ (x) == ROCKCHIP_VOP2_EP_HDMI1) ++ ++#define vop2_output_if_is_dp(x) ((x) == ROCKCHIP_VOP2_EP_DP0 || \ ++ (x) == ROCKCHIP_VOP2_EP_DP1) ++ ++#define vop2_output_if_is_edp(x) ((x) == ROCKCHIP_VOP2_EP_EDP0 || \ ++ (x) == ROCKCHIP_VOP2_EP_EDP1) ++ ++#define vop2_output_if_is_mipi(x) ((x) == ROCKCHIP_VOP2_EP_MIPI0 || \ ++ (x) == ROCKCHIP_VOP2_EP_MIPI1) ++ ++#define vop2_output_if_is_lvds(x) ((x) == ROCKCHIP_VOP2_EP_LVDS0 || \ ++ (x) == ROCKCHIP_VOP2_EP_LVDS1) ++ ++#define vop2_output_if_is_dpi(x) ((x) == ROCKCHIP_VOP2_EP_RGB0) ++ + static const struct regmap_config vop2_regmap_config; + + static struct vop2_video_port *to_vop2_video_port(struct drm_crtc *crtc) +@@ -475,6 +496,17 @@ static bool vop2_output_uv_swap(u32 bus_ + return false; + } + ++static bool vop2_output_rg_swap(struct vop2 *vop2, u32 bus_format) ++{ ++ if (vop2->data->soc_id == 3588) { ++ if (bus_format == MEDIA_BUS_FMT_YUV8_1X24 || ++ bus_format == MEDIA_BUS_FMT_YUV10_1X30) ++ return true; ++ } ++ ++ return false; ++} ++ + static bool is_yuv_output(u32 bus_format) + { + switch (bus_format) { +@@ -879,13 +911,32 @@ static int vop2_core_clks_prepare_enable + goto err; + } + ++ ret = clk_prepare_enable(vop2->pclk); ++ if (ret < 0) { ++ drm_err(vop2->drm, "failed to enable pclk - %d\n", ret); ++ goto err1; ++ } ++ + return 0; ++err1: ++ clk_disable_unprepare(vop2->aclk); + err: + clk_disable_unprepare(vop2->hclk); + + return ret; + } + ++static void rk3588_vop2_power_domain_enable_all(struct vop2 *vop2) ++{ ++ u32 pd; ++ ++ pd = vop2_readl(vop2, RK3588_SYS_PD_CTRL); ++ pd &= ~(VOP2_PD_CLUSTER0 | VOP2_PD_CLUSTER1 | VOP2_PD_CLUSTER2 | ++ VOP2_PD_CLUSTER3 | VOP2_PD_ESMART); ++ ++ vop2_writel(vop2, RK3588_SYS_PD_CTRL, pd); ++} ++ + static void vop2_enable(struct vop2 *vop2) + { + int ret; +@@ -917,6 +968,9 @@ static void vop2_enable(struct vop2 *vop + if (vop2->data->soc_id == 3566) + vop2_writel(vop2, RK3568_OTP_WIN_EN, 1); + ++ if (vop2->data->soc_id == 3588) ++ rk3588_vop2_power_domain_enable_all(vop2); ++ + vop2_writel(vop2, RK3568_REG_CFG_DONE, RK3568_REG_CFG_DONE__GLB_CFG_DONE_EN); + + /* +@@ -942,6 +996,7 @@ static void vop2_disable(struct vop2 *vo + + pm_runtime_put_sync(vop2->dev); + ++ clk_disable_unprepare(vop2->pclk); + clk_disable_unprepare(vop2->aclk); + clk_disable_unprepare(vop2->hclk); + } +@@ -1309,7 +1364,19 @@ static void vop2_plane_atomic_update(str + vop2_win_write(win, VOP2_WIN_AFBC_ENABLE, 1); + vop2_win_write(win, VOP2_WIN_AFBC_FORMAT, afbc_format); + vop2_win_write(win, VOP2_WIN_AFBC_UV_SWAP, uv_swap); +- vop2_win_write(win, VOP2_WIN_AFBC_AUTO_GATING_EN, 0); ++ /* ++ * On rk3566/8, this bit is auto gating enable, ++ * but this function is not work well so we need ++ * to disable it for these two platform. ++ * On rk3588, and the following new soc(rk3528/rk3576), ++ * this bit is gating disable, we should write 1 to ++ * disable gating when enable afbc. ++ */ ++ if (vop2->data->soc_id == 3566 || vop2->data->soc_id == 3568) ++ vop2_win_write(win, VOP2_WIN_AFBC_AUTO_GATING_EN, 0); ++ else ++ vop2_win_write(win, VOP2_WIN_AFBC_AUTO_GATING_EN, 1); ++ + vop2_win_write(win, VOP2_WIN_AFBC_BLOCK_SPLIT_EN, 0); + transform_offset = vop2_afbc_transform_offset(pstate, half_block_en); + vop2_win_write(win, VOP2_WIN_AFBC_HDR_PTR, yrgb_mst); +@@ -1507,10 +1574,10 @@ static void vop2_post_config(struct drm_ + vop2_vp_write(vp, RK3568_VP_DSP_BG, 0); + } + +-static void rk3568_set_intf_mux(struct vop2_video_port *vp, int id, +- u32 polflags) ++static unsigned long rk3568_set_intf_mux(struct vop2_video_port *vp, int id, u32 polflags) + { + struct vop2 *vop2 = vp->vop2; ++ struct drm_crtc *crtc = &vp->crtc; + u32 die, dip; + + die = vop2_readl(vop2, RK3568_DSP_IF_EN); +@@ -1572,13 +1639,281 @@ static void rk3568_set_intf_mux(struct v + break; + default: + drm_err(vop2->drm, "Invalid interface id %d on vp%d\n", id, vp->id); +- return; ++ return 0; ++ } ++ ++ dip |= RK3568_DSP_IF_POL__CFG_DONE_IMD; ++ ++ vop2_writel(vop2, RK3568_DSP_IF_EN, die); ++ vop2_writel(vop2, RK3568_DSP_IF_POL, dip); ++ ++ return crtc->state->adjusted_mode.crtc_clock * 1000LL; ++} ++ ++/* ++ * calc the dclk on rk3588 ++ * the available div of dclk is 1, 2, 4 ++ */ ++static unsigned long rk3588_calc_dclk(unsigned long child_clk, unsigned long max_dclk) ++{ ++ if (child_clk * 4 <= max_dclk) ++ return child_clk * 4; ++ else if (child_clk * 2 <= max_dclk) ++ return child_clk * 2; ++ else if (child_clk <= max_dclk) ++ return child_clk; ++ else ++ return 0; ++} ++ ++/* ++ * 4 pixclk/cycle on rk3588 ++ * RGB/eDP/HDMI: if_pixclk >= dclk_core ++ * DP: dp_pixclk = dclk_out <= dclk_core ++ * DSI: mipi_pixclk <= dclk_out <= dclk_core ++ */ ++static unsigned long rk3588_calc_cru_cfg(struct vop2_video_port *vp, int id, ++ int *dclk_core_div, int *dclk_out_div, ++ int *if_pixclk_div, int *if_dclk_div) ++{ ++ struct vop2 *vop2 = vp->vop2; ++ struct drm_crtc *crtc = &vp->crtc; ++ struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode; ++ struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state); ++ int output_mode = vcstate->output_mode; ++ unsigned long v_pixclk = adjusted_mode->crtc_clock * 1000LL; /* video timing pixclk */ ++ unsigned long dclk_core_rate = v_pixclk >> 2; ++ unsigned long dclk_rate = v_pixclk; ++ unsigned long dclk_out_rate; ++ unsigned long if_dclk_rate; ++ unsigned long if_pixclk_rate; ++ int K = 1; ++ ++ if (vop2_output_if_is_hdmi(id)) { ++ /* ++ * K = 2: dclk_core = if_pixclk_rate > if_dclk_rate ++ * K = 1: dclk_core = hdmie_edp_dclk > if_pixclk_rate ++ */ ++ if (output_mode == ROCKCHIP_OUT_MODE_YUV420) { ++ dclk_rate = dclk_rate >> 1; ++ K = 2; ++ } ++ ++ if_pixclk_rate = (dclk_core_rate << 1) / K; ++ if_dclk_rate = dclk_core_rate / K; ++ /* ++ * *if_pixclk_div = dclk_rate / if_pixclk_rate; ++ * *if_dclk_div = dclk_rate / if_dclk_rate; ++ */ ++ *if_pixclk_div = 2; ++ *if_dclk_div = 4; ++ } else if (vop2_output_if_is_edp(id)) { ++ /* ++ * edp_pixclk = edp_dclk > dclk_core ++ */ ++ if_pixclk_rate = v_pixclk / K; ++ dclk_rate = if_pixclk_rate * K; ++ /* ++ * *if_pixclk_div = dclk_rate / if_pixclk_rate; ++ * *if_dclk_div = *if_pixclk_div; ++ */ ++ *if_pixclk_div = K; ++ *if_dclk_div = K; ++ } else if (vop2_output_if_is_dp(id)) { ++ if (output_mode == ROCKCHIP_OUT_MODE_YUV420) ++ dclk_out_rate = v_pixclk >> 3; ++ else ++ dclk_out_rate = v_pixclk >> 2; ++ ++ dclk_rate = rk3588_calc_dclk(dclk_out_rate, 600000); ++ if (!dclk_rate) { ++ drm_err(vop2->drm, "DP dclk_out_rate out of range, dclk_out_rate: %ld KHZ\n", ++ dclk_out_rate); ++ return 0; ++ } ++ *dclk_out_div = dclk_rate / dclk_out_rate; ++ } else if (vop2_output_if_is_mipi(id)) { ++ if_pixclk_rate = dclk_core_rate / K; ++ /* ++ * dclk_core = dclk_out * K = if_pixclk * K = v_pixclk / 4 ++ */ ++ dclk_out_rate = if_pixclk_rate; ++ /* ++ * dclk_rate = N * dclk_core_rate N = (1,2,4 ), ++ * we get a little factor here ++ */ ++ dclk_rate = rk3588_calc_dclk(dclk_out_rate, 600000); ++ if (!dclk_rate) { ++ drm_err(vop2->drm, "MIPI dclk out of range, dclk_out_rate: %ld KHZ\n", ++ dclk_out_rate); ++ return 0; ++ } ++ *dclk_out_div = dclk_rate / dclk_out_rate; ++ /* ++ * mipi pixclk == dclk_out ++ */ ++ *if_pixclk_div = 1; ++ } else if (vop2_output_if_is_dpi(id)) { ++ dclk_rate = v_pixclk; ++ } ++ ++ *dclk_core_div = dclk_rate / dclk_core_rate; ++ *if_pixclk_div = ilog2(*if_pixclk_div); ++ *if_dclk_div = ilog2(*if_dclk_div); ++ *dclk_core_div = ilog2(*dclk_core_div); ++ *dclk_out_div = ilog2(*dclk_out_div); ++ ++ drm_dbg(vop2->drm, "dclk: %ld, pixclk_div: %d, dclk_div: %d\n", ++ dclk_rate, *if_pixclk_div, *if_dclk_div); ++ ++ return dclk_rate; ++} ++ ++/* ++ * MIPI port mux on rk3588: ++ * 0: Video Port2 ++ * 1: Video Port3 ++ * 3: Video Port 1(MIPI1 only) ++ */ ++static u32 rk3588_get_mipi_port_mux(int vp_id) ++{ ++ if (vp_id == 1) ++ return 3; ++ else if (vp_id == 3) ++ return 1; ++ else ++ return 0; ++} ++ ++static u32 rk3588_get_hdmi_pol(u32 flags) ++{ ++ u32 val; ++ ++ val = (flags & DRM_MODE_FLAG_NHSYNC) ? BIT(HSYNC_POSITIVE) : 0; ++ val |= (flags & DRM_MODE_FLAG_NVSYNC) ? BIT(VSYNC_POSITIVE) : 0; ++ ++ return val; ++} ++ ++static unsigned long rk3588_set_intf_mux(struct vop2_video_port *vp, int id, u32 polflags) ++{ ++ struct vop2 *vop2 = vp->vop2; ++ int dclk_core_div, dclk_out_div, if_pixclk_div, if_dclk_div; ++ unsigned long clock; ++ u32 die, dip, div, vp_clk_div, val; ++ ++ clock = rk3588_calc_cru_cfg(vp, id, &dclk_core_div, &dclk_out_div, ++ &if_pixclk_div, &if_dclk_div); ++ if (!clock) ++ return 0; ++ ++ vp_clk_div = FIELD_PREP(RK3588_VP_CLK_CTRL__DCLK_CORE_DIV, dclk_core_div); ++ vp_clk_div |= FIELD_PREP(RK3588_VP_CLK_CTRL__DCLK_OUT_DIV, dclk_out_div); ++ ++ die = vop2_readl(vop2, RK3568_DSP_IF_EN); ++ dip = vop2_readl(vop2, RK3568_DSP_IF_POL); ++ div = vop2_readl(vop2, RK3568_DSP_IF_CTRL); ++ ++ switch (id) { ++ case ROCKCHIP_VOP2_EP_HDMI0: ++ div &= ~RK3588_DSP_IF_EDP_HDMI0_DCLK_DIV; ++ div &= ~RK3588_DSP_IF_EDP_HDMI0_PCLK_DIV; ++ div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_DCLK_DIV, if_dclk_div); ++ div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_PCLK_DIV, if_pixclk_div); ++ die &= ~RK3588_SYS_DSP_INFACE_EN_EDP_HDMI0_MUX; ++ die |= RK3588_SYS_DSP_INFACE_EN_HDMI0 | ++ FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_EDP_HDMI0_MUX, vp->id); ++ val = rk3588_get_hdmi_pol(polflags); ++ regmap_write(vop2->vop_grf, RK3588_GRF_VOP_CON2, HIWORD_UPDATE(1, 1, 1)); ++ regmap_write(vop2->vo1_grf, RK3588_GRF_VO1_CON0, HIWORD_UPDATE(val, 6, 5)); ++ break; ++ case ROCKCHIP_VOP2_EP_HDMI1: ++ div &= ~RK3588_DSP_IF_EDP_HDMI1_DCLK_DIV; ++ div &= ~RK3588_DSP_IF_EDP_HDMI1_PCLK_DIV; ++ div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI1_DCLK_DIV, if_dclk_div); ++ div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI1_PCLK_DIV, if_pixclk_div); ++ die &= ~RK3588_SYS_DSP_INFACE_EN_EDP_HDMI1_MUX; ++ die |= RK3588_SYS_DSP_INFACE_EN_HDMI1 | ++ FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_EDP_HDMI1_MUX, vp->id); ++ val = rk3588_get_hdmi_pol(polflags); ++ regmap_write(vop2->vop_grf, RK3588_GRF_VOP_CON2, HIWORD_UPDATE(1, 4, 4)); ++ regmap_write(vop2->vo1_grf, RK3588_GRF_VO1_CON0, HIWORD_UPDATE(val, 8, 7)); ++ break; ++ case ROCKCHIP_VOP2_EP_EDP0: ++ div &= ~RK3588_DSP_IF_EDP_HDMI0_DCLK_DIV; ++ div &= ~RK3588_DSP_IF_EDP_HDMI0_PCLK_DIV; ++ div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_DCLK_DIV, if_dclk_div); ++ div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_PCLK_DIV, if_pixclk_div); ++ die &= ~RK3588_SYS_DSP_INFACE_EN_EDP_HDMI0_MUX; ++ die |= RK3588_SYS_DSP_INFACE_EN_EDP0 | ++ FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_EDP_HDMI0_MUX, vp->id); ++ regmap_write(vop2->vop_grf, RK3588_GRF_VOP_CON2, HIWORD_UPDATE(1, 0, 0)); ++ break; ++ case ROCKCHIP_VOP2_EP_EDP1: ++ div &= ~RK3588_DSP_IF_EDP_HDMI1_DCLK_DIV; ++ div &= ~RK3588_DSP_IF_EDP_HDMI1_PCLK_DIV; ++ div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_DCLK_DIV, if_dclk_div); ++ div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_PCLK_DIV, if_pixclk_div); ++ die &= ~RK3588_SYS_DSP_INFACE_EN_EDP_HDMI1_MUX; ++ die |= RK3588_SYS_DSP_INFACE_EN_EDP1 | ++ FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_EDP_HDMI1_MUX, vp->id); ++ regmap_write(vop2->vop_grf, RK3588_GRF_VOP_CON2, HIWORD_UPDATE(1, 3, 3)); ++ break; ++ case ROCKCHIP_VOP2_EP_MIPI0: ++ div &= ~RK3588_DSP_IF_MIPI0_PCLK_DIV; ++ div |= FIELD_PREP(RK3588_DSP_IF_MIPI0_PCLK_DIV, if_pixclk_div); ++ die &= ~RK3588_SYS_DSP_INFACE_EN_MIPI0_MUX; ++ val = rk3588_get_mipi_port_mux(vp->id); ++ die |= RK3588_SYS_DSP_INFACE_EN_MIPI0 | ++ FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_MIPI0_MUX, !!val); ++ break; ++ case ROCKCHIP_VOP2_EP_MIPI1: ++ div &= ~RK3588_DSP_IF_MIPI1_PCLK_DIV; ++ div |= FIELD_PREP(RK3588_DSP_IF_MIPI1_PCLK_DIV, if_pixclk_div); ++ die &= ~RK3588_SYS_DSP_INFACE_EN_MIPI1_MUX; ++ val = rk3588_get_mipi_port_mux(vp->id); ++ die |= RK3588_SYS_DSP_INFACE_EN_MIPI1 | ++ FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_MIPI1_MUX, val); ++ break; ++ case ROCKCHIP_VOP2_EP_DP0: ++ die &= ~RK3588_SYS_DSP_INFACE_EN_DP0_MUX; ++ die |= RK3588_SYS_DSP_INFACE_EN_DP0 | ++ FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_DP0_MUX, vp->id); ++ dip &= ~RK3588_DSP_IF_POL__DP0_PIN_POL; ++ dip |= FIELD_PREP(RK3588_DSP_IF_POL__DP0_PIN_POL, polflags); ++ break; ++ case ROCKCHIP_VOP2_EP_DP1: ++ die &= ~RK3588_SYS_DSP_INFACE_EN_MIPI1_MUX; ++ die |= RK3588_SYS_DSP_INFACE_EN_MIPI1 | ++ FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_MIPI1_MUX, vp->id); ++ dip &= ~RK3588_DSP_IF_POL__DP1_PIN_POL; ++ dip |= FIELD_PREP(RK3588_DSP_IF_POL__DP1_PIN_POL, polflags); ++ break; ++ default: ++ drm_err(vop2->drm, "Invalid interface id %d on vp%d\n", id, vp->id); ++ return 0; + } + + dip |= RK3568_DSP_IF_POL__CFG_DONE_IMD; + ++ vop2_vp_write(vp, RK3588_VP_CLK_CTRL, vp_clk_div); + vop2_writel(vop2, RK3568_DSP_IF_EN, die); ++ vop2_writel(vop2, RK3568_DSP_IF_CTRL, div); + vop2_writel(vop2, RK3568_DSP_IF_POL, dip); ++ ++ return clock; ++} ++ ++static unsigned long vop2_set_intf_mux(struct vop2_video_port *vp, int ep_id, u32 polflags) ++{ ++ struct vop2 *vop2 = vp->vop2; ++ ++ if (vop2->data->soc_id == 3566 || vop2->data->soc_id == 3568) ++ return rk3568_set_intf_mux(vp, ep_id, polflags); ++ else if (vop2->data->soc_id == 3588) ++ return rk3588_set_intf_mux(vp, ep_id, polflags); ++ else ++ return 0; + } + + static int us_to_vertical_line(struct drm_display_mode *mode, int us) +@@ -1648,9 +1983,17 @@ static void vop2_crtc_atomic_enable(stru + drm_for_each_encoder_mask(encoder, crtc->dev, crtc_state->encoder_mask) { + struct rockchip_encoder *rkencoder = to_rockchip_encoder(encoder); + +- rk3568_set_intf_mux(vp, rkencoder->crtc_endpoint_id, polflags); ++ /* ++ * for drive a high resolution(4KP120, 8K), vop on rk3588/rk3576 need ++ * process multi(1/2/4/8) pixels per cycle, so the dclk feed by the ++ * system cru may be the 1/2 or 1/4 of mode->clock. ++ */ ++ clock = vop2_set_intf_mux(vp, rkencoder->crtc_endpoint_id, polflags); + } + ++ if (!clock) ++ return; ++ + if (vcstate->output_mode == ROCKCHIP_OUT_MODE_AAAA && + !(vp_data->feature & VOP_FEATURE_OUTPUT_10BIT)) + out_mode = ROCKCHIP_OUT_MODE_P888; +@@ -1661,6 +2004,8 @@ static void vop2_crtc_atomic_enable(stru + + if (vop2_output_uv_swap(vcstate->bus_format, vcstate->output_mode)) + dsp_ctrl |= RK3568_VP_DSP_CTRL__DSP_RB_SWAP; ++ if (vop2_output_rg_swap(vop2, vcstate->bus_format)) ++ dsp_ctrl |= RK3568_VP_DSP_CTRL__DSP_RG_SWAP; + + if (vcstate->yuv_overlay) + dsp_ctrl |= RK3568_VP_DSP_CTRL__POST_DSP_OUT_R2Y; +@@ -2022,6 +2367,14 @@ static void vop2_setup_layer_mixer(struc + port_sel &= ~RK3568_OVL_PORT_SEL__CLUSTER1; + port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__CLUSTER1, vp->id); + break; ++ case ROCKCHIP_VOP2_CLUSTER2: ++ port_sel &= ~RK3588_OVL_PORT_SEL__CLUSTER2; ++ port_sel |= FIELD_PREP(RK3588_OVL_PORT_SEL__CLUSTER2, vp->id); ++ break; ++ case ROCKCHIP_VOP2_CLUSTER3: ++ port_sel &= ~RK3588_OVL_PORT_SEL__CLUSTER3; ++ port_sel |= FIELD_PREP(RK3588_OVL_PORT_SEL__CLUSTER3, vp->id); ++ break; + case ROCKCHIP_VOP2_ESMART0: + port_sel &= ~RK3568_OVL_PORT_SEL__ESMART0; + port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__ESMART0, vp->id); +@@ -2030,6 +2383,14 @@ static void vop2_setup_layer_mixer(struc + port_sel &= ~RK3568_OVL_PORT_SEL__ESMART1; + port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__ESMART1, vp->id); + break; ++ case ROCKCHIP_VOP2_ESMART2: ++ port_sel &= ~RK3588_OVL_PORT_SEL__ESMART2; ++ port_sel |= FIELD_PREP(RK3588_OVL_PORT_SEL__ESMART2, vp->id); ++ break; ++ case ROCKCHIP_VOP2_ESMART3: ++ port_sel &= ~RK3588_OVL_PORT_SEL__ESMART3; ++ port_sel |= FIELD_PREP(RK3588_OVL_PORT_SEL__ESMART3, vp->id); ++ break; + case ROCKCHIP_VOP2_SMART0: + port_sel &= ~RK3568_OVL_PORT_SEL__SMART0; + port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__SMART0, vp->id); +@@ -2766,8 +3127,29 @@ static int vop2_bind(struct device *dev, + if (IS_ERR(vop2->lut_regs)) + return PTR_ERR(vop2->lut_regs); + } ++ if (vop2_data->feature & VOP2_FEATURE_HAS_SYS_GRF) { ++ vop2->sys_grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,grf"); ++ if (IS_ERR(vop2->sys_grf)) ++ return dev_err_probe(dev, PTR_ERR(vop2->sys_grf), "cannot get sys_grf"); ++ } ++ ++ if (vop2_data->feature & VOP2_FEATURE_HAS_VOP_GRF) { ++ vop2->vop_grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,vop-grf"); ++ if (IS_ERR(vop2->vop_grf)) ++ return dev_err_probe(dev, PTR_ERR(vop2->vop_grf), "cannot get vop_grf"); ++ } ++ ++ if (vop2_data->feature & VOP2_FEATURE_HAS_VO1_GRF) { ++ vop2->vo1_grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,vo1-grf"); ++ if (IS_ERR(vop2->vo1_grf)) ++ return dev_err_probe(dev, PTR_ERR(vop2->vo1_grf), "cannot get vo1_grf"); ++ } + +- vop2->sys_grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,grf"); ++ if (vop2_data->feature & VOP2_FEATURE_HAS_SYS_PMU) { ++ vop2->sys_pmu = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,pmu"); ++ if (IS_ERR(vop2->sys_pmu)) ++ return dev_err_probe(dev, PTR_ERR(vop2->sys_pmu), "cannot get sys_pmu"); ++ } + + vop2->hclk = devm_clk_get(vop2->dev, "hclk"); + if (IS_ERR(vop2->hclk)) { +@@ -2781,6 +3163,12 @@ static int vop2_bind(struct device *dev, + return PTR_ERR(vop2->aclk); + } + ++ vop2->pclk = devm_clk_get_optional(vop2->dev, "pclk_vop"); ++ if (IS_ERR(vop2->pclk)) { ++ drm_err(vop2->drm, "failed to get pclk source\n"); ++ return PTR_ERR(vop2->pclk); ++ } ++ + vop2->irq = platform_get_irq(pdev, 0); + if (vop2->irq < 0) { + drm_err(vop2->drm, "cannot find irq for vop2\n"); +--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h +@@ -13,9 +13,16 @@ + + #define VOP_FEATURE_OUTPUT_10BIT BIT(0) + ++#define VOP2_FEATURE_HAS_SYS_GRF BIT(0) ++#define VOP2_FEATURE_HAS_VO0_GRF BIT(1) ++#define VOP2_FEATURE_HAS_VO1_GRF BIT(2) ++#define VOP2_FEATURE_HAS_VOP_GRF BIT(3) ++#define VOP2_FEATURE_HAS_SYS_PMU BIT(4) ++ + #define WIN_FEATURE_AFBDC BIT(0) + #define WIN_FEATURE_CLUSTER BIT(1) + ++#define HIWORD_UPDATE(v, h, l) ((GENMASK(h, l) << 16) | ((v) << (l))) + /* + * the delay number of a window in different mode. + */ +@@ -38,6 +45,18 @@ enum vop2_scale_down_mode { + VOP2_SCALE_DOWN_AVG, + }; + ++/* ++ * vop2 internal power domain id, ++ * should be all none zero, 0 will be treat as invalid; ++ */ ++#define VOP2_PD_CLUSTER0 BIT(0) ++#define VOP2_PD_CLUSTER1 BIT(1) ++#define VOP2_PD_CLUSTER2 BIT(2) ++#define VOP2_PD_CLUSTER3 BIT(3) ++#define VOP2_PD_DSC_8K BIT(5) ++#define VOP2_PD_DSC_4K BIT(6) ++#define VOP2_PD_ESMART BIT(7) ++ + enum vop2_win_regs { + VOP2_WIN_ENABLE, + VOP2_WIN_FORMAT, +@@ -138,6 +157,7 @@ struct vop2_video_port_data { + + struct vop2_data { + u8 nr_vps; ++ u64 feature; + const struct vop2_win_data *win; + const struct vop2_video_port_data *vp; + struct vop_rect max_input; +@@ -192,6 +212,11 @@ enum dst_factor_mode { + }; + + #define RK3568_GRF_VO_CON1 0x0364 ++ ++#define RK3588_GRF_SOC_CON1 0x0304 ++#define RK3588_GRF_VOP_CON2 0x08 ++#define RK3588_GRF_VO1_CON0 0x00 ++ + /* System registers definition */ + #define RK3568_REG_CFG_DONE 0x000 + #define RK3568_VERSION_INFO 0x004 +@@ -200,6 +225,7 @@ enum dst_factor_mode { + #define RK3568_DSP_IF_EN 0x028 + #define RK3568_DSP_IF_CTRL 0x02c + #define RK3568_DSP_IF_POL 0x030 ++#define RK3588_SYS_PD_CTRL 0x034 + #define RK3568_WB_CTRL 0x40 + #define RK3568_WB_XSCAL_FACTOR 0x44 + #define RK3568_WB_YRGB_MST 0x48 +@@ -220,9 +246,14 @@ enum dst_factor_mode { + #define RK3568_VP_INT_RAW_STATUS(vp) (0xAC + (vp) * 0x10) + + /* Video Port registers definition */ ++#define RK3568_VP0_CTRL_BASE 0x0C00 ++#define RK3568_VP1_CTRL_BASE 0x0D00 ++#define RK3568_VP2_CTRL_BASE 0x0E00 ++#define RK3588_VP3_CTRL_BASE 0x0F00 + #define RK3568_VP_DSP_CTRL 0x00 + #define RK3568_VP_MIPI_CTRL 0x04 + #define RK3568_VP_COLOR_BAR_CTRL 0x08 ++#define RK3588_VP_CLK_CTRL 0x0C + #define RK3568_VP_3D_LUT_CTRL 0x10 + #define RK3568_VP_3D_LUT_MST 0x20 + #define RK3568_VP_DSP_BG 0x2C +@@ -264,6 +295,17 @@ enum dst_factor_mode { + #define RK3568_SMART_DLY_NUM 0x6F8 + + /* Cluster register definition, offset relative to window base */ ++#define RK3568_CLUSTER0_CTRL_BASE 0x1000 ++#define RK3568_CLUSTER1_CTRL_BASE 0x1200 ++#define RK3588_CLUSTER2_CTRL_BASE 0x1400 ++#define RK3588_CLUSTER3_CTRL_BASE 0x1600 ++#define RK3568_ESMART0_CTRL_BASE 0x1800 ++#define RK3568_ESMART1_CTRL_BASE 0x1A00 ++#define RK3568_SMART0_CTRL_BASE 0x1C00 ++#define RK3568_SMART1_CTRL_BASE 0x1E00 ++#define RK3588_ESMART2_CTRL_BASE 0x1C00 ++#define RK3588_ESMART3_CTRL_BASE 0x1E00 ++ + #define RK3568_CLUSTER_WIN_CTRL0 0x00 + #define RK3568_CLUSTER_WIN_CTRL1 0x04 + #define RK3568_CLUSTER_WIN_YRGB_MST 0x10 +@@ -357,13 +399,18 @@ enum dst_factor_mode { + #define RK3568_VP_DSP_CTRL__DITHER_DOWN_EN BIT(17) + #define RK3568_VP_DSP_CTRL__PRE_DITHER_DOWN_EN BIT(16) + #define RK3568_VP_DSP_CTRL__POST_DSP_OUT_R2Y BIT(15) ++#define RK3568_VP_DSP_CTRL__DSP_RG_SWAP BIT(10) + #define RK3568_VP_DSP_CTRL__DSP_RB_SWAP BIT(9) ++#define RK3568_VP_DSP_CTRL__DSP_BG_SWAP BIT(8) + #define RK3568_VP_DSP_CTRL__DSP_INTERLACE BIT(7) + #define RK3568_VP_DSP_CTRL__DSP_FILED_POL BIT(6) + #define RK3568_VP_DSP_CTRL__P2I_EN BIT(5) + #define RK3568_VP_DSP_CTRL__CORE_DCLK_DIV BIT(4) + #define RK3568_VP_DSP_CTRL__OUT_MODE GENMASK(3, 0) + ++#define RK3588_VP_CLK_CTRL__DCLK_OUT_DIV GENMASK(3, 2) ++#define RK3588_VP_CLK_CTRL__DCLK_CORE_DIV GENMASK(1, 0) ++ + #define RK3568_VP_POST_SCL_CTRL__VSCALEDOWN BIT(1) + #define RK3568_VP_POST_SCL_CTRL__HSCALEDOWN BIT(0) + +@@ -382,11 +429,37 @@ enum dst_factor_mode { + #define RK3568_SYS_DSP_INFACE_EN_HDMI BIT(1) + #define RK3568_SYS_DSP_INFACE_EN_RGB BIT(0) + ++#define RK3588_SYS_DSP_INFACE_EN_MIPI1_MUX GENMASK(22, 21) ++#define RK3588_SYS_DSP_INFACE_EN_MIPI0_MUX GENMASK(20, 20) ++#define RK3588_SYS_DSP_INFACE_EN_EDP_HDMI1_MUX GENMASK(19, 18) ++#define RK3588_SYS_DSP_INFACE_EN_EDP_HDMI0_MUX GENMASK(17, 16) ++#define RK3588_SYS_DSP_INFACE_EN_DP1_MUX GENMASK(15, 14) ++#define RK3588_SYS_DSP_INFACE_EN_DP0_MUX GENMASK(13, 12) ++#define RK3588_SYS_DSP_INFACE_EN_DPI GENMASK(9, 8) ++#define RK3588_SYS_DSP_INFACE_EN_MIPI1 BIT(7) ++#define RK3588_SYS_DSP_INFACE_EN_MIPI0 BIT(6) ++#define RK3588_SYS_DSP_INFACE_EN_HDMI1 BIT(5) ++#define RK3588_SYS_DSP_INFACE_EN_EDP1 BIT(4) ++#define RK3588_SYS_DSP_INFACE_EN_HDMI0 BIT(3) ++#define RK3588_SYS_DSP_INFACE_EN_EDP0 BIT(2) ++#define RK3588_SYS_DSP_INFACE_EN_DP1 BIT(1) ++#define RK3588_SYS_DSP_INFACE_EN_DP0 BIT(0) ++ ++#define RK3588_DSP_IF_MIPI1_PCLK_DIV GENMASK(27, 26) ++#define RK3588_DSP_IF_MIPI0_PCLK_DIV GENMASK(25, 24) ++#define RK3588_DSP_IF_EDP_HDMI1_PCLK_DIV GENMASK(22, 22) ++#define RK3588_DSP_IF_EDP_HDMI1_DCLK_DIV GENMASK(21, 20) ++#define RK3588_DSP_IF_EDP_HDMI0_PCLK_DIV GENMASK(18, 18) ++#define RK3588_DSP_IF_EDP_HDMI0_DCLK_DIV GENMASK(17, 16) ++ + #define RK3568_DSP_IF_POL__MIPI_PIN_POL GENMASK(19, 16) + #define RK3568_DSP_IF_POL__EDP_PIN_POL GENMASK(15, 12) + #define RK3568_DSP_IF_POL__HDMI_PIN_POL GENMASK(7, 4) + #define RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL GENMASK(3, 0) + ++#define RK3588_DSP_IF_POL__DP1_PIN_POL GENMASK(14, 12) ++#define RK3588_DSP_IF_POL__DP0_PIN_POL GENMASK(10, 8) ++ + #define RK3568_VP0_MIPI_CTRL__DCLK_DIV2_PHASE_LOCK BIT(5) + #define RK3568_VP0_MIPI_CTRL__DCLK_DIV2 BIT(4) + +@@ -408,8 +481,12 @@ enum dst_factor_mode { + #define RK3568_OVL_PORT_SEL__SEL_PORT GENMASK(31, 16) + #define RK3568_OVL_PORT_SEL__SMART1 GENMASK(31, 30) + #define RK3568_OVL_PORT_SEL__SMART0 GENMASK(29, 28) ++#define RK3588_OVL_PORT_SEL__ESMART3 GENMASK(31, 30) ++#define RK3588_OVL_PORT_SEL__ESMART2 GENMASK(29, 28) + #define RK3568_OVL_PORT_SEL__ESMART1 GENMASK(27, 26) + #define RK3568_OVL_PORT_SEL__ESMART0 GENMASK(25, 24) ++#define RK3588_OVL_PORT_SEL__CLUSTER3 GENMASK(23, 22) ++#define RK3588_OVL_PORT_SEL__CLUSTER2 GENMASK(21, 20) + #define RK3568_OVL_PORT_SEL__CLUSTER1 GENMASK(19, 18) + #define RK3568_OVL_PORT_SEL__CLUSTER0 GENMASK(17, 16) + #define RK3568_OVL_PORT_SET__PORT2_MUX GENMASK(11, 8) +@@ -422,6 +499,10 @@ enum dst_factor_mode { + #define RK3568_CLUSTER_DLY_NUM__CLUSTER0_1 GENMASK(15, 8) + #define RK3568_CLUSTER_DLY_NUM__CLUSTER0_0 GENMASK(7, 0) + ++#define RK3568_CLUSTER_WIN_CTRL0__WIN0_EN BIT(0) ++ ++#define RK3568_SMART_REGION0_CTRL__WIN0_EN BIT(0) ++ + #define RK3568_SMART_DLY_NUM__SMART1 GENMASK(31, 24) + #define RK3568_SMART_DLY_NUM__SMART0 GENMASK(23, 16) + #define RK3568_SMART_DLY_NUM__ESMART1 GENMASK(15, 8) +--- a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c ++++ b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c +@@ -34,6 +34,30 @@ static const uint32_t formats_cluster[] + DRM_FORMAT_Y210, /* yuv422_10bit non-Linear mode only */ + }; + ++static const uint32_t formats_esmart[] = { ++ DRM_FORMAT_XRGB8888, ++ DRM_FORMAT_ARGB8888, ++ DRM_FORMAT_XBGR8888, ++ DRM_FORMAT_ABGR8888, ++ DRM_FORMAT_RGB888, ++ DRM_FORMAT_BGR888, ++ DRM_FORMAT_RGB565, ++ DRM_FORMAT_BGR565, ++ DRM_FORMAT_NV12, /* yuv420_8bit linear mode, 2 plane */ ++ DRM_FORMAT_NV21, /* yvu420_8bit linear mode, 2 plane */ ++ DRM_FORMAT_NV16, /* yuv422_8bit linear mode, 2 plane */ ++ DRM_FORMAT_NV61, /* yvu422_8bit linear mode, 2 plane */ ++ DRM_FORMAT_NV20, /* yuv422_10bit linear mode, 2 plane, no padding */ ++ DRM_FORMAT_NV24, /* yuv444_8bit linear mode, 2 plane */ ++ DRM_FORMAT_NV42, /* yvu444_8bit linear mode, 2 plane */ ++ DRM_FORMAT_NV30, /* yuv444_10bit linear mode, 2 plane, no padding */ ++ DRM_FORMAT_NV15, /* yuv420_10bit linear mode, 2 plane, no padding */ ++ DRM_FORMAT_YVYU, /* yuv422_8bit[YVYU] linear mode */ ++ DRM_FORMAT_VYUY, /* yuv422_8bit[VYUY] linear mode */ ++ DRM_FORMAT_YUYV, /* yuv422_8bit[YUYV] linear mode */ ++ DRM_FORMAT_UYVY, /* yuv422_8bit[UYVY] linear mode */ ++}; ++ + static const uint32_t formats_rk356x_esmart[] = { + DRM_FORMAT_XRGB8888, + DRM_FORMAT_ARGB8888, +@@ -236,7 +260,188 @@ static const struct vop2_win_data rk3568 + }, + }; + ++static const struct vop2_video_port_data rk3588_vop_video_ports[] = { ++ { ++ .id = 0, ++ .feature = VOP_FEATURE_OUTPUT_10BIT, ++ .gamma_lut_len = 1024, ++ .cubic_lut_len = 9 * 9 * 9, /* 9x9x9 */ ++ .max_output = { 4096, 2304 }, ++ /* hdr2sdr sdr2hdr hdr2hdr sdr2sdr */ ++ .pre_scan_max_dly = { 76, 65, 65, 54 }, ++ .offset = 0xc00, ++ }, { ++ .id = 1, ++ .feature = VOP_FEATURE_OUTPUT_10BIT, ++ .gamma_lut_len = 1024, ++ .cubic_lut_len = 729, /* 9x9x9 */ ++ .max_output = { 4096, 2304 }, ++ .pre_scan_max_dly = { 76, 65, 65, 54 }, ++ .offset = 0xd00, ++ }, { ++ .id = 2, ++ .feature = VOP_FEATURE_OUTPUT_10BIT, ++ .gamma_lut_len = 1024, ++ .cubic_lut_len = 17 * 17 * 17, /* 17x17x17 */ ++ .max_output = { 4096, 2304 }, ++ .pre_scan_max_dly = { 52, 52, 52, 52 }, ++ .offset = 0xe00, ++ }, { ++ .id = 3, ++ .gamma_lut_len = 1024, ++ .max_output = { 2048, 1536 }, ++ .pre_scan_max_dly = { 52, 52, 52, 52 }, ++ .offset = 0xf00, ++ }, ++}; ++ ++/* ++ * rk3588 vop with 4 cluster, 4 esmart win. ++ * Every cluster can work as 4K win or split into two win. ++ * All win in cluster support AFBCD. ++ * ++ * Every esmart win and smart win support 4 Multi-region. ++ * ++ * Scale filter mode: ++ * ++ * * Cluster: bicubic for horizontal scale up, others use bilinear ++ * * ESmart: ++ * * nearest-neighbor/bilinear/bicubic for scale up ++ * * nearest-neighbor/bilinear/average for scale down ++ * ++ * AXI Read ID assignment: ++ * Two AXI bus: ++ * AXI0 is a read/write bus with a higher performance. ++ * AXI1 is a read only bus. ++ * ++ * Every window on a AXI bus must assigned two unique ++ * read id(yrgb_id/uv_id, valid id are 0x1~0xe). ++ * ++ * AXI0: ++ * Cluster0/1, Esmart0/1, WriteBack ++ * ++ * AXI 1: ++ * Cluster2/3, Esmart2/3 ++ * ++ */ ++static const struct vop2_win_data rk3588_vop_win_data[] = { ++ { ++ .name = "Cluster0-win0", ++ .phys_id = ROCKCHIP_VOP2_CLUSTER0, ++ .base = 0x1000, ++ .formats = formats_cluster, ++ .nformats = ARRAY_SIZE(formats_cluster), ++ .format_modifiers = format_modifiers_afbc, ++ .layer_sel_id = 0, ++ .supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 | ++ DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y, ++ .max_upscale_factor = 4, ++ .max_downscale_factor = 4, ++ .dly = { 4, 26, 29 }, ++ .type = DRM_PLANE_TYPE_PRIMARY, ++ .feature = WIN_FEATURE_AFBDC | WIN_FEATURE_CLUSTER, ++ }, { ++ .name = "Cluster1-win0", ++ .phys_id = ROCKCHIP_VOP2_CLUSTER1, ++ .base = 0x1200, ++ .formats = formats_cluster, ++ .nformats = ARRAY_SIZE(formats_cluster), ++ .format_modifiers = format_modifiers_afbc, ++ .layer_sel_id = 1, ++ .supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 | ++ DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y, ++ .type = DRM_PLANE_TYPE_PRIMARY, ++ .max_upscale_factor = 4, ++ .max_downscale_factor = 4, ++ .dly = { 4, 26, 29 }, ++ .feature = WIN_FEATURE_AFBDC | WIN_FEATURE_CLUSTER, ++ }, { ++ .name = "Cluster2-win0", ++ .phys_id = ROCKCHIP_VOP2_CLUSTER2, ++ .base = 0x1400, ++ .formats = formats_cluster, ++ .nformats = ARRAY_SIZE(formats_cluster), ++ .format_modifiers = format_modifiers_afbc, ++ .layer_sel_id = 4, ++ .supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 | ++ DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y, ++ .type = DRM_PLANE_TYPE_PRIMARY, ++ .max_upscale_factor = 4, ++ .max_downscale_factor = 4, ++ .dly = { 4, 26, 29 }, ++ .feature = WIN_FEATURE_AFBDC | WIN_FEATURE_CLUSTER, ++ }, { ++ .name = "Cluster3-win0", ++ .phys_id = ROCKCHIP_VOP2_CLUSTER3, ++ .base = 0x1600, ++ .formats = formats_cluster, ++ .nformats = ARRAY_SIZE(formats_cluster), ++ .format_modifiers = format_modifiers_afbc, ++ .layer_sel_id = 5, ++ .supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 | ++ DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y, ++ .type = DRM_PLANE_TYPE_PRIMARY, ++ .max_upscale_factor = 4, ++ .max_downscale_factor = 4, ++ .dly = { 4, 26, 29 }, ++ .feature = WIN_FEATURE_AFBDC | WIN_FEATURE_CLUSTER, ++ }, { ++ .name = "Esmart0-win0", ++ .phys_id = ROCKCHIP_VOP2_ESMART0, ++ .formats = formats_esmart, ++ .nformats = ARRAY_SIZE(formats_esmart), ++ .format_modifiers = format_modifiers, ++ .base = 0x1800, ++ .layer_sel_id = 2, ++ .supported_rotations = DRM_MODE_REFLECT_Y, ++ .type = DRM_PLANE_TYPE_OVERLAY, ++ .max_upscale_factor = 8, ++ .max_downscale_factor = 8, ++ .dly = { 23, 45, 48 }, ++ }, { ++ .name = "Esmart1-win0", ++ .phys_id = ROCKCHIP_VOP2_ESMART1, ++ .formats = formats_esmart, ++ .nformats = ARRAY_SIZE(formats_esmart), ++ .format_modifiers = format_modifiers, ++ .base = 0x1a00, ++ .layer_sel_id = 3, ++ .supported_rotations = DRM_MODE_REFLECT_Y, ++ .type = DRM_PLANE_TYPE_OVERLAY, ++ .max_upscale_factor = 8, ++ .max_downscale_factor = 8, ++ .dly = { 23, 45, 48 }, ++ }, { ++ .name = "Esmart2-win0", ++ .phys_id = ROCKCHIP_VOP2_ESMART2, ++ .base = 0x1c00, ++ .formats = formats_esmart, ++ .nformats = ARRAY_SIZE(formats_esmart), ++ .format_modifiers = format_modifiers, ++ .layer_sel_id = 6, ++ .supported_rotations = DRM_MODE_REFLECT_Y, ++ .type = DRM_PLANE_TYPE_OVERLAY, ++ .max_upscale_factor = 8, ++ .max_downscale_factor = 8, ++ .dly = { 23, 45, 48 }, ++ }, { ++ .name = "Esmart3-win0", ++ .phys_id = ROCKCHIP_VOP2_ESMART3, ++ .formats = formats_esmart, ++ .nformats = ARRAY_SIZE(formats_esmart), ++ .format_modifiers = format_modifiers, ++ .base = 0x1e00, ++ .layer_sel_id = 7, ++ .supported_rotations = DRM_MODE_REFLECT_Y, ++ .type = DRM_PLANE_TYPE_OVERLAY, ++ .max_upscale_factor = 8, ++ .max_downscale_factor = 8, ++ .dly = { 23, 45, 48 }, ++ }, ++}; ++ + static const struct vop2_data rk3566_vop = { ++ .feature = VOP2_FEATURE_HAS_SYS_GRF, + .nr_vps = 3, + .max_input = { 4096, 2304 }, + .max_output = { 4096, 2304 }, +@@ -247,6 +452,7 @@ static const struct vop2_data rk3566_vop + }; + + static const struct vop2_data rk3568_vop = { ++ .feature = VOP2_FEATURE_HAS_SYS_GRF, + .nr_vps = 3, + .max_input = { 4096, 2304 }, + .max_output = { 4096, 2304 }, +@@ -256,6 +462,18 @@ static const struct vop2_data rk3568_vop + .soc_id = 3568, + }; + ++static const struct vop2_data rk3588_vop = { ++ .feature = VOP2_FEATURE_HAS_SYS_GRF | VOP2_FEATURE_HAS_VO1_GRF | ++ VOP2_FEATURE_HAS_VOP_GRF | VOP2_FEATURE_HAS_SYS_PMU, ++ .nr_vps = 4, ++ .max_input = { 4096, 4320 }, ++ .max_output = { 4096, 4320 }, ++ .vp = rk3588_vop_video_ports, ++ .win = rk3588_vop_win_data, ++ .win_size = ARRAY_SIZE(rk3588_vop_win_data), ++ .soc_id = 3588, ++}; ++ + static const struct of_device_id vop2_dt_match[] = { + { + .compatible = "rockchip,rk3566-vop", +@@ -264,6 +482,9 @@ static const struct of_device_id vop2_dt + .compatible = "rockchip,rk3568-vop", + .data = &rk3568_vop, + }, { ++ .compatible = "rockchip,rk3588-vop", ++ .data = &rk3588_vop ++ }, { + }, + }; + MODULE_DEVICE_TABLE(of, vop2_dt_match); diff --git a/target/linux/rockchip/patches-6.6/033-29-v6.8-drm-rockchip-vop2-rename-VOP_FEATURE_OUTPUT_10BIT-to.patch b/target/linux/rockchip/patches-6.6/033-29-v6.8-drm-rockchip-vop2-rename-VOP_FEATURE_OUTPUT_10BIT-to.patch new file mode 100644 index 0000000000..e38fd49d51 --- /dev/null +++ b/target/linux/rockchip/patches-6.6/033-29-v6.8-drm-rockchip-vop2-rename-VOP_FEATURE_OUTPUT_10BIT-to.patch @@ -0,0 +1,80 @@ +From 9d7fe7704d534c2d043aff2987f10671a8b4373d Mon Sep 17 00:00:00 2001 +From: Andy Yan +Date: Mon, 11 Dec 2023 19:59:31 +0800 +Subject: [PATCH] drm/rockchip: vop2: rename VOP_FEATURE_OUTPUT_10BIT to + VOP2_VP_FEATURE_OUTPUT_10BIT + +VOP2 has multiple independent video ports with different +feature, so rename VOP_FEATURE_OUTPUT_10BIT to +VOP2_VP_FEATURE_OUTPUT_10BIT for more clearly meaning. + +Signed-off-by: Andy Yan +Reviewed-by: Sascha Hauer +Signed-off-by: Heiko Stuebner +Link: https://patchwork.freedesktop.org/patch/msgid/20231211115931.1785495-1-andyshrk@163.com +--- + drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 2 +- + drivers/gpu/drm/rockchip/rockchip_drm_vop2.h | 2 +- + drivers/gpu/drm/rockchip/rockchip_vop2_reg.c | 8 ++++---- + 3 files changed, 6 insertions(+), 6 deletions(-) + +--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +@@ -1995,7 +1995,7 @@ static void vop2_crtc_atomic_enable(stru + return; + + if (vcstate->output_mode == ROCKCHIP_OUT_MODE_AAAA && +- !(vp_data->feature & VOP_FEATURE_OUTPUT_10BIT)) ++ !(vp_data->feature & VOP2_VP_FEATURE_OUTPUT_10BIT)) + out_mode = ROCKCHIP_OUT_MODE_P888; + else + out_mode = vcstate->output_mode; +--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h +@@ -11,7 +11,7 @@ + #include + #include "rockchip_drm_vop.h" + +-#define VOP_FEATURE_OUTPUT_10BIT BIT(0) ++#define VOP2_VP_FEATURE_OUTPUT_10BIT BIT(0) + + #define VOP2_FEATURE_HAS_SYS_GRF BIT(0) + #define VOP2_FEATURE_HAS_VO0_GRF BIT(1) +--- a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c ++++ b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c +@@ -136,7 +136,7 @@ static const uint64_t format_modifiers_a + static const struct vop2_video_port_data rk3568_vop_video_ports[] = { + { + .id = 0, +- .feature = VOP_FEATURE_OUTPUT_10BIT, ++ .feature = VOP2_VP_FEATURE_OUTPUT_10BIT, + .gamma_lut_len = 1024, + .cubic_lut_len = 9 * 9 * 9, + .max_output = { 4096, 2304 }, +@@ -263,7 +263,7 @@ static const struct vop2_win_data rk3568 + static const struct vop2_video_port_data rk3588_vop_video_ports[] = { + { + .id = 0, +- .feature = VOP_FEATURE_OUTPUT_10BIT, ++ .feature = VOP2_VP_FEATURE_OUTPUT_10BIT, + .gamma_lut_len = 1024, + .cubic_lut_len = 9 * 9 * 9, /* 9x9x9 */ + .max_output = { 4096, 2304 }, +@@ -272,7 +272,7 @@ static const struct vop2_video_port_data + .offset = 0xc00, + }, { + .id = 1, +- .feature = VOP_FEATURE_OUTPUT_10BIT, ++ .feature = VOP2_VP_FEATURE_OUTPUT_10BIT, + .gamma_lut_len = 1024, + .cubic_lut_len = 729, /* 9x9x9 */ + .max_output = { 4096, 2304 }, +@@ -280,7 +280,7 @@ static const struct vop2_video_port_data + .offset = 0xd00, + }, { + .id = 2, +- .feature = VOP_FEATURE_OUTPUT_10BIT, ++ .feature = VOP2_VP_FEATURE_OUTPUT_10BIT, + .gamma_lut_len = 1024, + .cubic_lut_len = 17 * 17 * 17, /* 17x17x17 */ + .max_output = { 4096, 2304 }, diff --git a/target/linux/rockchip/patches-6.6/033-30-v6.8-drm-rockchip-vop2-Avoid-use-regmap_reinit_cache-at-runtim.patch b/target/linux/rockchip/patches-6.6/033-30-v6.8-drm-rockchip-vop2-Avoid-use-regmap_reinit_cache-at-runtim.patch new file mode 100644 index 0000000000..d5c1da17ac --- /dev/null +++ b/target/linux/rockchip/patches-6.6/033-30-v6.8-drm-rockchip-vop2-Avoid-use-regmap_reinit_cache-at-runtim.patch @@ -0,0 +1,59 @@ +From 3ee348eb36f14e9303a7e9757efb91b0bbf3f7a9 Mon Sep 17 00:00:00 2001 +From: Andy Yan +Date: Sun, 17 Dec 2023 16:44:15 +0800 +Subject: [PATCH] drm/rockchip: vop2: Avoid use regmap_reinit_cache at runtime + +Marek Report a possible irq lock inversion dependency warning when +commit 81a06f1d02e5 ("Revert "drm/rockchip: vop2: Use regcache_sync() +to fix suspend/resume"") lands linux-next. + +I can reproduce this warning with: +CONFIG_PROVE_LOCKING=y +CONFIG_DEBUG_LOCKDEP=y + +It seems than when use regmap_reinit_cache at runtime whith Mark's +commit 3d59c22bbb8d ("drm/rockchip: vop2: Convert to use maple tree +register cache"), it will trigger a possible irq lock inversion dependency +warning. + +One solution is switch back to REGCACHE_RBTREE, but it seems that +REGCACHE_MAPLE is the future, so I avoid using regmap_reinit_cache, +and drop all the regcache when vop is disabled, then we get a fresh +start at next enbable time. + +Fixes: 81a06f1d02e5 ("Revert "drm/rockchip: vop2: Use regcache_sync() to fix suspend/resume"") +Reported-by: Marek Szyprowski +Closes: https://lore.kernel.org/all/98a9f15d-30ac-47bf-9b93-3aa2c9900f7b@samsung.com/ +Signed-off-by: Andy Yan +Tested-by: Marek Szyprowski +[dropped the large kernel log of the lockdep report from the message] +Signed-off-by: Heiko Stuebner +Link: https://patchwork.freedesktop.org/patch/msgid/20231217084415.2373043-1-andyshrk@163.com +--- + drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 8 ++------ + 1 file changed, 2 insertions(+), 6 deletions(-) + +--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +@@ -959,12 +959,6 @@ static void vop2_enable(struct vop2 *vop + return; + } + +- ret = regmap_reinit_cache(vop2->map, &vop2_regmap_config); +- if (ret) { +- drm_err(vop2->drm, "failed to reinit cache: %d\n", ret); +- return; +- } +- + if (vop2->data->soc_id == 3566) + vop2_writel(vop2, RK3568_OTP_WIN_EN, 1); + +@@ -996,6 +990,8 @@ static void vop2_disable(struct vop2 *vo + + pm_runtime_put_sync(vop2->dev); + ++ regcache_drop_region(vop2->map, 0, vop2_regmap_config.max_register); ++ + clk_disable_unprepare(vop2->pclk); + clk_disable_unprepare(vop2->aclk); + clk_disable_unprepare(vop2->hclk); diff --git a/target/linux/rockchip/patches-6.6/033-31-v6.8-drm-rockchip-vop2-clean-up-some-inconsistent-indenting.patch b/target/linux/rockchip/patches-6.6/033-31-v6.8-drm-rockchip-vop2-clean-up-some-inconsistent-indenting.patch new file mode 100644 index 0000000000..b6fc6c4988 --- /dev/null +++ b/target/linux/rockchip/patches-6.6/033-31-v6.8-drm-rockchip-vop2-clean-up-some-inconsistent-indenting.patch @@ -0,0 +1,31 @@ +From f40e61eb538d35661d6dda1de92867954d776c4a Mon Sep 17 00:00:00 2001 +From: Jiapeng Chong +Date: Tue, 19 Dec 2023 14:26:35 +0800 +Subject: [PATCH] drm/rockchip: vop2: clean up some inconsistent indenting + +No functional modification involved. + +drivers/gpu/drm/rockchip/rockchip_drm_vop2.c:1708 rk3588_calc_cru_cfg() warn: inconsistent indenting. + +Reported-by: Abaci Robot +Closes: https://bugzilla.openanolis.cn/show_bug.cgi?id=7778 +Signed-off-by: Jiapeng Chong +Signed-off-by: Heiko Stuebner +Link: https://patchwork.freedesktop.org/patch/msgid/20231219062635.100718-1-jiapeng.chong@linux.alibaba.com +--- + drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +@@ -1701,8 +1701,8 @@ static unsigned long rk3588_calc_cru_cfg + * *if_pixclk_div = dclk_rate / if_pixclk_rate; + * *if_dclk_div = dclk_rate / if_dclk_rate; + */ +- *if_pixclk_div = 2; +- *if_dclk_div = 4; ++ *if_pixclk_div = 2; ++ *if_dclk_div = 4; + } else if (vop2_output_if_is_edp(id)) { + /* + * edp_pixclk = edp_dclk > dclk_core diff --git a/target/linux/rockchip/patches-6.6/033-32-v6.8-drm-rockchip-vop2-Drop-superfluous-include.patch b/target/linux/rockchip/patches-6.6/033-32-v6.8-drm-rockchip-vop2-Drop-superfluous-include.patch new file mode 100644 index 0000000000..de34da6c06 --- /dev/null +++ b/target/linux/rockchip/patches-6.6/033-32-v6.8-drm-rockchip-vop2-Drop-superfluous-include.patch @@ -0,0 +1,25 @@ +From 38709af26c33e398c3292e96837ccfde41fd9e6b Mon Sep 17 00:00:00 2001 +From: Cristian Ciocaltea +Date: Thu, 4 Jan 2024 16:39:49 +0200 +Subject: [PATCH] drm/rockchip: vop2: Drop superfluous include + +The rockchip_drm_fb.h header contains just a single function which is +not directly used by the VOP2 driver. Drop the unnecessary include. + +Signed-off-by: Cristian Ciocaltea +Signed-off-by: Heiko Stuebner +Link: https://patchwork.freedesktop.org/patch/msgid/20240104143951.85219-1-cristian.ciocaltea@collabora.com +--- + drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +@@ -35,7 +35,6 @@ + + #include "rockchip_drm_drv.h" + #include "rockchip_drm_gem.h" +-#include "rockchip_drm_fb.h" + #include "rockchip_drm_vop2.h" + #include "rockchip_rgb.h" + diff --git a/target/linux/rockchip/patches-6.6/033-33-v6.8-drm-rockchip-vop2-Drop-unused-if_dclk_rate-variable.patch b/target/linux/rockchip/patches-6.6/033-33-v6.8-drm-rockchip-vop2-Drop-unused-if_dclk_rate-variable.patch new file mode 100644 index 0000000000..8b75910c9a --- /dev/null +++ b/target/linux/rockchip/patches-6.6/033-33-v6.8-drm-rockchip-vop2-Drop-unused-if_dclk_rate-variable.patch @@ -0,0 +1,47 @@ +From 196da3f3f76a46905f7daab29c56974f1aba9a7a Mon Sep 17 00:00:00 2001 +From: Cristian Ciocaltea +Date: Fri, 5 Jan 2024 19:40:06 +0200 +Subject: [PATCH] drm/rockchip: vop2: Drop unused if_dclk_rate variable +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Commit 5a028e8f062f ("drm/rockchip: vop2: Add support for rk3588") +introduced a variable which ended up being unused: + +rockchip_drm_vop2.c:1688:23: warning: variable ‘if_dclk_rate’ set but not used [-Wunused-but-set-variable] + +This has been initially used as part of a formula to compute the clock +dividers, but eventually it has been replaced by static values. + +Drop the variable declaration and move its assignment to the comment +block, to serve as documentation of how the constants have been +generated. + +Signed-off-by: Cristian Ciocaltea +Signed-off-by: Heiko Stuebner +Link: https://patchwork.freedesktop.org/patch/msgid/20240105174007.98054-1-cristian.ciocaltea@collabora.com +--- + drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +@@ -1680,7 +1680,6 @@ static unsigned long rk3588_calc_cru_cfg + unsigned long dclk_core_rate = v_pixclk >> 2; + unsigned long dclk_rate = v_pixclk; + unsigned long dclk_out_rate; +- unsigned long if_dclk_rate; + unsigned long if_pixclk_rate; + int K = 1; + +@@ -1695,8 +1694,8 @@ static unsigned long rk3588_calc_cru_cfg + } + + if_pixclk_rate = (dclk_core_rate << 1) / K; +- if_dclk_rate = dclk_core_rate / K; + /* ++ * if_dclk_rate = dclk_core_rate / K; + * *if_pixclk_div = dclk_rate / if_pixclk_rate; + * *if_dclk_div = dclk_rate / if_dclk_rate; + */ diff --git a/target/linux/rockchip/patches-6.6/033-34-v6.8-drm-rockchip-vop2-add-a-missing-unlock-in.patch b/target/linux/rockchip/patches-6.6/033-34-v6.8-drm-rockchip-vop2-add-a-missing-unlock-in.patch new file mode 100644 index 0000000000..326bbb6826 --- /dev/null +++ b/target/linux/rockchip/patches-6.6/033-34-v6.8-drm-rockchip-vop2-add-a-missing-unlock-in.patch @@ -0,0 +1,31 @@ +From b6ddaa63f728d26c12048aed76be99c24f435c41 Mon Sep 17 00:00:00 2001 +From: Harshit Mogalapalli +Date: Fri, 19 Jan 2024 11:08:40 -0800 +Subject: [PATCH] drm/rockchip: vop2: add a missing unlock in + vop2_crtc_atomic_enable() + +Unlock before returning on the error path. + +Fixes: 5a028e8f062f ("drm/rockchip: vop2: Add support for rk3588") +Signed-off-by: Harshit Mogalapalli +Reviewed-by: Sascha Hauer +Signed-off-by: Heiko Stuebner +Link: https://patchwork.freedesktop.org/patch/msgid/20240119190841.1619443-1-harshit.m.mogalapalli@oracle.com +--- + drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +@@ -1985,8 +1985,10 @@ static void vop2_crtc_atomic_enable(stru + clock = vop2_set_intf_mux(vp, rkencoder->crtc_endpoint_id, polflags); + } + +- if (!clock) ++ if (!clock) { ++ vop2_unlock(vop2); + return; ++ } + + if (vcstate->output_mode == ROCKCHIP_OUT_MODE_AAAA && + !(vp_data->feature & VOP2_VP_FEATURE_OUTPUT_10BIT))