@@ -354,7 +354,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;
@@ -798,6 +798,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) {
@@ -817,10 +818,19 @@ 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
+ * wen 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);
@@ -901,7 +911,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)
@@ -1031,7 +1041,7 @@ static int vop2_plane_atomic_check(struct drm_plane *plane,
return -EINVAL;
}
- if (vop2->data->soc_id == 3568 || vop2->data->soc_id == 3566) {
+ if (vop2->version == VOP_VERSION_RK3568) {
if (vop2_cluster_window(win)) {
if (!rockchip_afbc(plane, fb->modifier)) {
drm_err(vop2->drm, "Unsupported linear format for %s\n", win->data->name);
@@ -1041,7 +1051,7 @@ static int vop2_plane_atomic_check(struct drm_plane *plane,
}
if (fb->format->format == DRM_FORMAT_XRGB2101010 || fb->format->format == DRM_FORMAT_XBGR2101010) {
- if (vop2->data->soc_id == 3588) {
+ if (vop2->version == VOP_VERSION_RK3588) {
if (!rockchip_afbc(plane, fb->modifier)) {
drm_err(vop2->drm, "Unsupported linear 32 bpp for %s\n", win->data->name);
return -EINVAL;
@@ -1260,7 +1270,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);
@@ -1320,7 +1330,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);
@@ -2525,6 +2535,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);
@@ -13,6 +13,15 @@
#include "rockchip_drm_drv.h"
#include "rockchip_drm_vop.h"
+#define VOP2_VERSION(major, minor, build) ((major) << 24 | (minor) << 16 | (build))
+
+/* The new SOC VOP version 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)
@@ -242,6 +251,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;
@@ -259,6 +269,7 @@ struct vop2_data {
};
struct vop2 {
+ u32 version;
struct device *dev;
struct drm_device *drm;
struct vop2_video_port vps[ROCKCHIP_MAX_CRTC];
@@ -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,