drm/rockchip: vop2: Introduce vop hardware version
authorAndy Yan <andy.yan@rock-chips.com>
Tue, 18 Feb 2025 11:27:33 +0000 (19:27 +0800)
committerHeiko Stuebner <heiko@sntech.de>
Sun, 2 Mar 2025 18:32:13 +0000 (19:32 +0100)
There is a version number hardcoded in the VOP VERSION_INFO
register, and the version number increments sequentially based
on the production order of the SoC.

So using this version number to distinguish different VOP features
will simplify the code.

Signed-off-by: Andy Yan <andy.yan@rock-chips.com>
Tested-by: Michael Riesch <michael.riesch@wolfvision.net> # on RK3568
Tested-by: Detlev Casanova <detlev.casanova@collabora.com>
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Link: https://patchwork.freedesktop.org/patch/msgid/20250218112744.34433-7-andyshrk@163.com
drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
drivers/gpu/drm/rockchip/rockchip_vop2_reg.c

index 1f13b942064e0853a726fd6b84d49b45d609ff26..bebe5bd70b90532f3adb3f54b9371b5ad59d3985 100644 (file)
@@ -355,7 +355,7 @@ static bool vop2_output_uv_swap(u32 bus_format, u32 output_mode)
 
 static bool vop2_output_rg_swap(struct vop2 *vop2, u32 bus_format)
 {
-       if (vop2->data->soc_id == 3588) {
+       if (vop2->version == VOP_VERSION_RK3588) {
                if (bus_format == MEDIA_BUS_FMT_YUV8_1X24 ||
                    bus_format == MEDIA_BUS_FMT_YUV10_1X30)
                        return true;
@@ -408,7 +408,7 @@ static bool rockchip_vop2_mod_supported(struct drm_plane *plane, u32 format,
        if (modifier == DRM_FORMAT_MOD_INVALID)
                return false;
 
-       if (vop2->data->soc_id == 3568 || vop2->data->soc_id == 3566) {
+       if (vop2->version == VOP_VERSION_RK3568) {
                if (vop2_cluster_window(win)) {
                        if (modifier == DRM_FORMAT_MOD_LINEAR) {
                                drm_dbg_kms(vop2->drm,
@@ -419,7 +419,7 @@ static bool rockchip_vop2_mod_supported(struct drm_plane *plane, u32 format,
        }
 
        if (format == DRM_FORMAT_XRGB2101010 || format == DRM_FORMAT_XBGR2101010) {
-               if (vop2->data->soc_id == 3588) {
+               if (vop2->version == VOP_VERSION_RK3588) {
                        if (!rockchip_afbc(plane, modifier)) {
                                drm_dbg_kms(vop2->drm, "Only support 32 bpp format with afbc\n");
                                return false;
@@ -818,6 +818,7 @@ static void rk3588_vop2_power_domain_enable_all(struct vop2 *vop2)
 static void vop2_enable(struct vop2 *vop2)
 {
        int ret;
+       u32 version;
 
        ret = pm_runtime_resume_and_get(vop2->dev);
        if (ret < 0) {
@@ -837,10 +838,20 @@ static void vop2_enable(struct vop2 *vop2)
                return;
        }
 
+       version = vop2_readl(vop2, RK3568_VERSION_INFO);
+       if (version != vop2->version) {
+               drm_err(vop2->drm, "Hardware version(0x%08x) mismatch\n", version);
+               return;
+       }
+
+       /*
+        * rk3566 share the same vop version with rk3568, so
+        * we need to use soc_id for identification here.
+        */
        if (vop2->data->soc_id == 3566)
                vop2_writel(vop2, RK3568_OTP_WIN_EN, 1);
 
-       if (vop2->data->soc_id == 3588)
+       if (vop2->version == VOP_VERSION_RK3588)
                rk3588_vop2_power_domain_enable_all(vop2);
 
        vop2_writel(vop2, RK3568_REG_CFG_DONE, RK3568_REG_CFG_DONE__GLB_CFG_DONE_EN);
@@ -921,7 +932,7 @@ static void vop2_vp_dsp_lut_update_enable(struct vop2_video_port *vp)
 
 static inline bool vop2_supports_seamless_gamma_lut_update(struct vop2 *vop2)
 {
-       return (vop2->data->soc_id != 3566 && vop2->data->soc_id != 3568);
+       return vop2->version != VOP_VERSION_RK3568;
 }
 
 static bool vop2_gamma_lut_in_use(struct vop2 *vop2, struct vop2_video_port *vp)
@@ -1263,7 +1274,7 @@ static void vop2_plane_atomic_update(struct drm_plane *plane,
                &fb->format->format,
                afbc_en ? "AFBC" : "", &yrgb_mst);
 
-       if (vop2->data->soc_id > 3568) {
+       if (vop2->version > VOP_VERSION_RK3568) {
                vop2_win_write(win, VOP2_WIN_AXI_BUS_ID, win->data->axi_bus_id);
                vop2_win_write(win, VOP2_WIN_AXI_YRGB_R_ID, win->data->axi_yrgb_r_id);
                vop2_win_write(win, VOP2_WIN_AXI_UV_R_ID, win->data->axi_uv_r_id);
@@ -1323,7 +1334,7 @@ static void vop2_plane_atomic_update(struct drm_plane *plane,
                 * 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)
+               if (vop2->version == VOP_VERSION_RK3568)
                        vop2_win_write(win, VOP2_WIN_AFBC_AUTO_GATING_EN, 0);
                else
                        vop2_win_write(win, VOP2_WIN_AFBC_AUTO_GATING_EN, 1);
@@ -2534,6 +2545,7 @@ static int vop2_bind(struct device *dev, struct device *master, void *data)
        vop2->dev = dev;
        vop2->data = vop2_data;
        vop2->ops = vop2_data->ops;
+       vop2->version = vop2_data->version;
        vop2->drm = drm;
 
        dev_set_drvdata(dev, vop2);
index cae211a558bdd21125dc525a81e74a76d4bc0986..a309042aa8e6133231191a9ba05c6f570eae354c 100644 (file)
 #include "rockchip_drm_drv.h"
 #include "rockchip_drm_vop.h"
 
+#define VOP2_VERSION(major, minor, build)      ((major) << 24 | (minor) << 16 | (build))
+
+/* The VOP version of new SoC is bigger than the old */
+#define VOP_VERSION_RK3568     VOP2_VERSION(0x40, 0x15, 0x8023)
+#define VOP_VERSION_RK3588     VOP2_VERSION(0x40, 0x17, 0x6786)
+#define VOP_VERSION_RK3528     VOP2_VERSION(0x50, 0x17, 0x1263)
+#define VOP_VERSION_RK3562     VOP2_VERSION(0x50, 0x17, 0x4350)
+#define VOP_VERSION_RK3576     VOP2_VERSION(0x50, 0x19, 0x9765)
+
 #define VOP2_VP_FEATURE_OUTPUT_10BIT        BIT(0)
 
 #define VOP2_FEATURE_HAS_SYS_GRF       BIT(0)
@@ -243,6 +252,7 @@ struct vop2_ops {
 struct vop2_data {
        u8 nr_vps;
        u64 feature;
+       u32 version;
        const struct vop2_ops *ops;
        const struct vop2_win_data *win;
        const struct vop2_video_port_data *vp;
@@ -260,6 +270,7 @@ struct vop2_data {
 };
 
 struct vop2 {
+       u32 version;
        struct device *dev;
        struct drm_device *drm;
        struct vop2_video_port vps[ROCKCHIP_MAX_CRTC];
index 31edde7ae6001e23b470aa41ffee90451656165a..0afef24db144a9d1724a94b3c860342945aec731 100644 (file)
@@ -1627,6 +1627,7 @@ static const struct vop2_ops rk3588_vop_ops = {
 };
 
 static const struct vop2_data rk3566_vop = {
+       .version = VOP_VERSION_RK3568,
        .feature = VOP2_FEATURE_HAS_SYS_GRF,
        .nr_vps = 3,
        .max_input = { 4096, 2304 },
@@ -1645,6 +1646,7 @@ static const struct vop2_data rk3566_vop = {
 };
 
 static const struct vop2_data rk3568_vop = {
+       .version = VOP_VERSION_RK3568,
        .feature = VOP2_FEATURE_HAS_SYS_GRF,
        .nr_vps = 3,
        .max_input = { 4096, 2304 },
@@ -1663,6 +1665,7 @@ static const struct vop2_data rk3568_vop = {
 };
 
 static const struct vop2_data rk3588_vop = {
+       .version = VOP_VERSION_RK3588,
        .feature = VOP2_FEATURE_HAS_SYS_GRF | VOP2_FEATURE_HAS_VO1_GRF |
                   VOP2_FEATURE_HAS_VOP_GRF | VOP2_FEATURE_HAS_SYS_PMU,
        .nr_vps = 4,