Commit eb5cb6aa authored by Mark yao's avatar Mark yao Committed by Mark Yao

drm/rockchip: vop: add a series of vop support

Vop Full framework now has following vops:
IP version    chipname
  3.1           rk3288
  3.2           rk3368
  3.4           rk3366
  3.5           rk3399 big
  3.6           rk3399 lit
  3.7           rk3228
  3.8           rk3328

The above IP version is from H/W define, some of vop support get
the IP version from VERSION_INFO register, some are not.
hardcode the IP version for each vop to identify them.

major version: used for IP structure, Vop full framework is 3,
               vop little framework is 2.
minor version: on same structure, newer design vop will bigger
               then old one.
Signed-off-by: default avatarMark Yao <mark.yao@rock-chips.com>
Reviewed-by: default avatarJeffy Chen <jeffy.chen@rock-chips.com>
Tested-by: default avatarHeiko Stuebner <heiko@sntech.de>
Link: https://patchwork.freedesktop.org/patch/msgid/1501049971-6131-1-git-send-email-mark.yao@rock-chips.com
parent 9a61c54b
...@@ -15,6 +15,14 @@ ...@@ -15,6 +15,14 @@
#ifndef _ROCKCHIP_DRM_VOP_H #ifndef _ROCKCHIP_DRM_VOP_H
#define _ROCKCHIP_DRM_VOP_H #define _ROCKCHIP_DRM_VOP_H
/*
* major: IP major version, used for IP structure
* minor: big feature change under same structure
*/
#define VOP_VERSION(major, minor) ((major) << 8 | (minor))
#define VOP_MAJOR(version) ((version) >> 8)
#define VOP_MINOR(version) ((version) & 0xff)
enum vop_data_format { enum vop_data_format {
VOP_FMT_ARGB8888 = 0, VOP_FMT_ARGB8888 = 0,
VOP_FMT_RGB888, VOP_FMT_RGB888,
...@@ -142,6 +150,7 @@ struct vop_win_data { ...@@ -142,6 +150,7 @@ struct vop_win_data {
}; };
struct vop_data { struct vop_data {
uint32_t version;
const struct vop_intr *intr; const struct vop_intr *intr;
const struct vop_common *common; const struct vop_common *common;
const struct vop_misc *misc; const struct vop_misc *misc;
......
...@@ -277,6 +277,7 @@ static const struct vop_intr rk3288_vop_intr = { ...@@ -277,6 +277,7 @@ static const struct vop_intr rk3288_vop_intr = {
}; };
static const struct vop_data rk3288_vop = { static const struct vop_data rk3288_vop = {
.version = VOP_VERSION(3, 1),
.feature = VOP_FEATURE_OUTPUT_RGB10, .feature = VOP_FEATURE_OUTPUT_RGB10,
.intr = &rk3288_vop_intr, .intr = &rk3288_vop_intr,
.common = &rk3288_common, .common = &rk3288_common,
...@@ -286,7 +287,7 @@ static const struct vop_data rk3288_vop = { ...@@ -286,7 +287,7 @@ static const struct vop_data rk3288_vop = {
.win_size = ARRAY_SIZE(rk3288_vop_win_data), .win_size = ARRAY_SIZE(rk3288_vop_win_data),
}; };
static const int rk3399_vop_intrs[] = { static const int rk3368_vop_intrs[] = {
FS_INTR, FS_INTR,
0, 0, 0, 0,
LINE_FLAG_INTR, LINE_FLAG_INTR,
...@@ -296,22 +297,95 @@ static const int rk3399_vop_intrs[] = { ...@@ -296,22 +297,95 @@ static const int rk3399_vop_intrs[] = {
DSP_HOLD_VALID_INTR, DSP_HOLD_VALID_INTR,
}; };
static const struct vop_intr rk3399_vop_intr = { static const struct vop_intr rk3368_vop_intr = {
.intrs = rk3399_vop_intrs, .intrs = rk3368_vop_intrs,
.nintrs = ARRAY_SIZE(rk3399_vop_intrs), .nintrs = ARRAY_SIZE(rk3368_vop_intrs),
.line_flag_num[0] = VOP_REG(RK3399_LINE_FLAG, 0xffff, 0), .line_flag_num[0] = VOP_REG(RK3368_LINE_FLAG, 0xffff, 0),
.line_flag_num[1] = VOP_REG(RK3399_LINE_FLAG, 0xffff, 16), .line_flag_num[1] = VOP_REG(RK3368_LINE_FLAG, 0xffff, 16),
.status = VOP_REG_MASK_SYNC(RK3399_INTR_STATUS0, 0xffff, 0), .status = VOP_REG_MASK_SYNC(RK3368_INTR_STATUS, 0x3fff, 0),
.enable = VOP_REG_MASK_SYNC(RK3399_INTR_EN0, 0xffff, 0), .enable = VOP_REG_MASK_SYNC(RK3368_INTR_EN, 0x3fff, 0),
.clear = VOP_REG_MASK_SYNC(RK3399_INTR_CLEAR0, 0xffff, 0), .clear = VOP_REG_MASK_SYNC(RK3368_INTR_CLEAR, 0x3fff, 0),
};
static const struct vop_win_phy rk3368_win23_data = {
.data_formats = formats_win_lite,
.nformats = ARRAY_SIZE(formats_win_lite),
.gate = VOP_REG(RK3368_WIN2_CTRL0, 0x1, 0),
.enable = VOP_REG(RK3368_WIN2_CTRL0, 0x1, 4),
.format = VOP_REG(RK3368_WIN2_CTRL0, 0x3, 5),
.rb_swap = VOP_REG(RK3368_WIN2_CTRL0, 0x1, 20),
.dsp_info = VOP_REG(RK3368_WIN2_DSP_INFO0, 0x0fff0fff, 0),
.dsp_st = VOP_REG(RK3368_WIN2_DSP_ST0, 0x1fff1fff, 0),
.yrgb_mst = VOP_REG(RK3368_WIN2_MST0, 0xffffffff, 0),
.yrgb_vir = VOP_REG(RK3368_WIN2_VIR0_1, 0x1fff, 0),
.src_alpha_ctl = VOP_REG(RK3368_WIN2_SRC_ALPHA_CTRL, 0xff, 0),
.dst_alpha_ctl = VOP_REG(RK3368_WIN2_DST_ALPHA_CTRL, 0xff, 0),
};
static const struct vop_win_data rk3368_vop_win_data[] = {
{ .base = 0x00, .phy = &rk3288_win01_data,
.type = DRM_PLANE_TYPE_PRIMARY },
{ .base = 0x40, .phy = &rk3288_win01_data,
.type = DRM_PLANE_TYPE_OVERLAY },
{ .base = 0x00, .phy = &rk3368_win23_data,
.type = DRM_PLANE_TYPE_OVERLAY },
{ .base = 0x50, .phy = &rk3368_win23_data,
.type = DRM_PLANE_TYPE_CURSOR },
};
static const struct vop_output rk3368_output = {
.rgb_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0xf, 16),
.hdmi_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0xf, 20),
.edp_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0xf, 24),
.mipi_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0xf, 28),
.rgb_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 12),
.hdmi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 13),
.edp_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 14),
.mipi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 15),
};
static const struct vop_misc rk3368_misc = {
.global_regdone_en = VOP_REG(RK3368_SYS_CTRL, 0x1, 11),
};
static const struct vop_data rk3368_vop = {
.version = VOP_VERSION(3, 2),
.intr = &rk3368_vop_intr,
.common = &rk3288_common,
.modeset = &rk3288_modeset,
.output = &rk3368_output,
.misc = &rk3368_misc,
.win = rk3368_vop_win_data,
.win_size = ARRAY_SIZE(rk3368_vop_win_data),
};
static const struct vop_intr rk3366_vop_intr = {
.intrs = rk3368_vop_intrs,
.nintrs = ARRAY_SIZE(rk3368_vop_intrs),
.line_flag_num[0] = VOP_REG(RK3366_LINE_FLAG, 0xffff, 0),
.line_flag_num[1] = VOP_REG(RK3366_LINE_FLAG, 0xffff, 16),
.status = VOP_REG_MASK_SYNC(RK3366_INTR_STATUS0, 0xffff, 0),
.enable = VOP_REG_MASK_SYNC(RK3366_INTR_EN0, 0xffff, 0),
.clear = VOP_REG_MASK_SYNC(RK3366_INTR_CLEAR0, 0xffff, 0),
};
static const struct vop_data rk3366_vop = {
.version = VOP_VERSION(3, 4),
.intr = &rk3366_vop_intr,
.common = &rk3288_common,
.modeset = &rk3288_modeset,
.output = &rk3368_output,
.misc = &rk3368_misc,
.win = rk3368_vop_win_data,
.win_size = ARRAY_SIZE(rk3368_vop_win_data),
}; };
static const struct vop_output rk3399_output = { static const struct vop_output rk3399_output = {
.dp_pin_pol = VOP_REG(RK3399_DSP_CTRL1, 0xf, 16), .dp_pin_pol = VOP_REG(RK3399_DSP_CTRL1, 0xf, 16),
.rgb_pin_pol = VOP_REG(RK3399_DSP_CTRL1, 0xf, 16), .rgb_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0xf, 16),
.hdmi_pin_pol = VOP_REG(RK3399_DSP_CTRL1, 0xf, 20), .hdmi_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0xf, 20),
.edp_pin_pol = VOP_REG(RK3399_DSP_CTRL1, 0xf, 24), .edp_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0xf, 24),
.mipi_pin_pol = VOP_REG(RK3399_DSP_CTRL1, 0xf, 28), .mipi_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0xf, 28),
.dp_en = VOP_REG(RK3399_SYS_CTRL, 0x1, 11), .dp_en = VOP_REG(RK3399_SYS_CTRL, 0x1, 11),
.rgb_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 12), .rgb_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 12),
.hdmi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 13), .hdmi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 13),
...@@ -319,54 +393,136 @@ static const struct vop_output rk3399_output = { ...@@ -319,54 +393,136 @@ static const struct vop_output rk3399_output = {
.mipi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 15), .mipi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 15),
}; };
static const struct vop_misc rk3399_misc = {
.global_regdone_en = VOP_REG(RK3399_SYS_CTRL, 0x1, 11),
};
static const struct vop_data rk3399_vop_big = { static const struct vop_data rk3399_vop_big = {
.version = VOP_VERSION(3, 5),
.feature = VOP_FEATURE_OUTPUT_RGB10, .feature = VOP_FEATURE_OUTPUT_RGB10,
.intr = &rk3399_vop_intr, .intr = &rk3366_vop_intr,
.common = &rk3288_common, .common = &rk3288_common,
.modeset = &rk3288_modeset, .modeset = &rk3288_modeset,
.output = &rk3399_output, .output = &rk3399_output,
.misc = &rk3399_misc, .misc = &rk3368_misc,
/* .win = rk3368_vop_win_data,
* rk3399 vop big windows register layout is same as rk3288. .win_size = ARRAY_SIZE(rk3368_vop_win_data),
*/
.win = rk3288_vop_win_data,
.win_size = ARRAY_SIZE(rk3288_vop_win_data),
}; };
static const struct vop_win_data rk3399_vop_lit_win_data[] = { static const struct vop_win_data rk3399_vop_lit_win_data[] = {
{ .base = 0x00, .phy = &rk3288_win01_data, { .base = 0x00, .phy = &rk3288_win01_data,
.type = DRM_PLANE_TYPE_PRIMARY }, .type = DRM_PLANE_TYPE_PRIMARY },
{ .base = 0x00, .phy = &rk3288_win23_data, { .base = 0x00, .phy = &rk3368_win23_data,
.type = DRM_PLANE_TYPE_CURSOR}, .type = DRM_PLANE_TYPE_CURSOR},
}; };
static const struct vop_data rk3399_vop_lit = { static const struct vop_data rk3399_vop_lit = {
.intr = &rk3399_vop_intr, .version = VOP_VERSION(3, 6),
.intr = &rk3366_vop_intr,
.common = &rk3288_common, .common = &rk3288_common,
.modeset = &rk3288_modeset, .modeset = &rk3288_modeset,
.output = &rk3399_output, .output = &rk3399_output,
.misc = &rk3399_misc, .misc = &rk3368_misc,
/*
* rk3399 vop lit windows register layout is same as rk3288,
* but cut off the win1 and win3 windows.
*/
.win = rk3399_vop_lit_win_data, .win = rk3399_vop_lit_win_data,
.win_size = ARRAY_SIZE(rk3399_vop_lit_win_data), .win_size = ARRAY_SIZE(rk3399_vop_lit_win_data),
}; };
static const struct vop_win_data rk3228_vop_win_data[] = {
{ .base = 0x00, .phy = &rk3288_win01_data,
.type = DRM_PLANE_TYPE_PRIMARY },
{ .base = 0x40, .phy = &rk3288_win01_data,
.type = DRM_PLANE_TYPE_CURSOR },
};
static const struct vop_data rk3228_vop = {
.version = VOP_VERSION(3, 7),
.feature = VOP_FEATURE_OUTPUT_RGB10,
.intr = &rk3366_vop_intr,
.common = &rk3288_common,
.modeset = &rk3288_modeset,
.output = &rk3399_output,
.misc = &rk3368_misc,
.win = rk3228_vop_win_data,
.win_size = ARRAY_SIZE(rk3228_vop_win_data),
};
static const struct vop_modeset rk3328_modeset = {
.htotal_pw = VOP_REG(RK3328_DSP_HTOTAL_HS_END, 0x1fff1fff, 0),
.hact_st_end = VOP_REG(RK3328_DSP_HACT_ST_END, 0x1fff1fff, 0),
.vtotal_pw = VOP_REG(RK3328_DSP_VTOTAL_VS_END, 0x1fff1fff, 0),
.vact_st_end = VOP_REG(RK3328_DSP_VACT_ST_END, 0x1fff1fff, 0),
.hpost_st_end = VOP_REG(RK3328_POST_DSP_HACT_INFO, 0x1fff1fff, 0),
.vpost_st_end = VOP_REG(RK3328_POST_DSP_VACT_INFO, 0x1fff1fff, 0),
};
static const struct vop_output rk3328_output = {
.rgb_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 12),
.hdmi_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 13),
.edp_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 14),
.mipi_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 15),
.rgb_pin_pol = VOP_REG(RK3328_DSP_CTRL1, 0xf, 16),
.hdmi_pin_pol = VOP_REG(RK3328_DSP_CTRL1, 0xf, 20),
.edp_pin_pol = VOP_REG(RK3328_DSP_CTRL1, 0xf, 24),
.mipi_pin_pol = VOP_REG(RK3328_DSP_CTRL1, 0xf, 28),
};
static const struct vop_misc rk3328_misc = {
.global_regdone_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 11),
};
static const struct vop_common rk3328_common = {
.standby = VOP_REG_SYNC(RK3328_SYS_CTRL, 0x1, 22),
.dither_down = VOP_REG(RK3328_DSP_CTRL1, 0xf, 1),
.dither_up = VOP_REG(RK3328_DSP_CTRL1, 0x1, 6),
.dsp_blank = VOP_REG(RK3328_DSP_CTRL0, 0x3, 18),
.out_mode = VOP_REG(RK3328_DSP_CTRL0, 0xf, 0),
.cfg_done = VOP_REG_SYNC(RK3328_REG_CFG_DONE, 0x1, 0),
};
static const struct vop_intr rk3328_vop_intr = {
.intrs = rk3368_vop_intrs,
.nintrs = ARRAY_SIZE(rk3368_vop_intrs),
.line_flag_num[0] = VOP_REG(RK3328_LINE_FLAG, 0xffff, 0),
.line_flag_num[1] = VOP_REG(RK3328_LINE_FLAG, 0xffff, 16),
.status = VOP_REG_MASK_SYNC(RK3328_INTR_STATUS0, 0xffff, 0),
.enable = VOP_REG_MASK_SYNC(RK3328_INTR_EN0, 0xffff, 0),
.clear = VOP_REG_MASK_SYNC(RK3328_INTR_CLEAR0, 0xffff, 0),
};
static const struct vop_win_data rk3328_vop_win_data[] = {
{ .base = 0xd0, .phy = &rk3288_win01_data,
.type = DRM_PLANE_TYPE_PRIMARY },
{ .base = 0x1d0, .phy = &rk3288_win01_data,
.type = DRM_PLANE_TYPE_OVERLAY },
{ .base = 0x2d0, .phy = &rk3288_win01_data,
.type = DRM_PLANE_TYPE_CURSOR },
};
static const struct vop_data rk3328_vop = {
.version = VOP_VERSION(3, 8),
.feature = VOP_FEATURE_OUTPUT_RGB10,
.intr = &rk3328_vop_intr,
.common = &rk3328_common,
.modeset = &rk3328_modeset,
.output = &rk3328_output,
.misc = &rk3328_misc,
.win = rk3328_vop_win_data,
.win_size = ARRAY_SIZE(rk3328_vop_win_data),
};
static const struct of_device_id vop_driver_dt_match[] = { static const struct of_device_id vop_driver_dt_match[] = {
{ .compatible = "rockchip,rk3036-vop", { .compatible = "rockchip,rk3036-vop",
.data = &rk3036_vop }, .data = &rk3036_vop },
{ .compatible = "rockchip,rk3288-vop", { .compatible = "rockchip,rk3288-vop",
.data = &rk3288_vop }, .data = &rk3288_vop },
{ .compatible = "rockchip,rk3368-vop",
.data = &rk3368_vop },
{ .compatible = "rockchip,rk3366-vop",
.data = &rk3366_vop },
{ .compatible = "rockchip,rk3399-vop-big", { .compatible = "rockchip,rk3399-vop-big",
.data = &rk3399_vop_big }, .data = &rk3399_vop_big },
{ .compatible = "rockchip,rk3399-vop-lit", { .compatible = "rockchip,rk3399-vop-lit",
.data = &rk3399_vop_lit }, .data = &rk3399_vop_lit },
{ .compatible = "rockchip,rk3228-vop",
.data = &rk3228_vop },
{ .compatible = "rockchip,rk3328-vop",
.data = &rk3328_vop },
{}, {},
}; };
MODULE_DEVICE_TABLE(of, vop_driver_dt_match); MODULE_DEVICE_TABLE(of, vop_driver_dt_match);
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment