Commit 5a028e8f authored by Andy Yan's avatar Andy Yan Committed by Heiko Stuebner

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: default avatarAndy Yan <andy.yan@rock-chips.com>
Reviewed-by: default avatarSascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: default avatarHeiko Stuebner <heiko@sntech.de>
Link: https://patchwork.freedesktop.org/patch/msgid/20231211115919.1785435-1-andyshrk@163.com
parent dc7226ac
......@@ -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)
......
......@@ -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_vop_win_data[] = {
},
};
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",
......@@ -263,6 +481,9 @@ static const struct of_device_id vop2_dt_match[] = {
}, {
.compatible = "rockchip,rk3568-vop",
.data = &rk3568_vop,
}, {
.compatible = "rockchip,rk3588-vop",
.data = &rk3588_vop
}, {
},
};
......
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