@@ -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);
@@ -1231,7 +1241,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);
@@ -2320,6 +2330,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)
@@ -235,6 +244,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;
@@ -252,6 +262,7 @@ struct vop2_data {
};
struct vop2 {
+ u32 version;
struct device *dev;
struct drm_device *drm;
struct vop2_video_port vps[ROCKCHIP_MAX_CRTC];
@@ -1593,6 +1593,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 },
@@ -1611,6 +1612,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 },
@@ -1629,6 +1631,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,