drm/rockchip: vop2: Add VOP_GRF and SYS_GRF support

Some clk invert(dclk invert) control in SYS_GRF
Some interface enable(hdmi/edp enable) control in VOP_GRF
hdmi_vsync/hsync_pol control in VO1_GRF

Signed-off-by: Andy Yan <andy.yan@rock-chips.com>
Change-Id: Ia3972c9d207c9385b4512c96ea8e2d66e8fa03d5
This commit is contained in:
Andy Yan
2021-11-05 17:53:06 +08:00
committed by Tao Huang
parent bfe47a132f
commit 265d675c1a
4 changed files with 113 additions and 24 deletions

View File

@@ -876,6 +876,14 @@ struct vop_grf_ctrl {
struct vop_reg grf_dclk_inv;
struct vop_reg grf_bt1120_clk_inv;
struct vop_reg grf_bt656_clk_inv;
struct vop_reg grf_edp0_en;
struct vop_reg grf_edp1_en;
struct vop_reg grf_hdmi0_en;
struct vop_reg grf_hdmi1_en;
struct vop_reg grf_hdmi0_dsc_en;
struct vop_reg grf_hdmi1_dsc_en;
struct vop_reg grf_hdmi0_pin_pol;
struct vop_reg grf_hdmi1_pin_pol;
};
struct vop_data {
@@ -936,8 +944,10 @@ struct vop2_ctrl {
struct vop_reg edp_pin_pol;
struct vop_reg mipi_dclk_pol;
struct vop_reg mipi_pin_pol;
struct vop_reg dp_dclk_pol;
struct vop_reg dp_pin_pol;
struct vop_reg dp0_dclk_pol;
struct vop_reg dp0_pin_pol;
struct vop_reg dp1_dclk_pol;
struct vop_reg dp1_pin_pol;
/* This will be reference by win_phy_id */
struct vop_reg win_vp_id[16];
@@ -1030,7 +1040,10 @@ struct vop2_data {
const struct vop2_power_domain_data *pd;
const struct vop_csc_table *csc_table;
const struct vop_hdr_table *hdr_table;
const struct vop_grf_ctrl *grf_ctrl;
const struct vop_grf_ctrl *sys_grf;
const struct vop_grf_ctrl *grf;
const struct vop_grf_ctrl *vo0_grf;
const struct vop_grf_ctrl *vo1_grf;
struct vop_rect max_input;
struct vop_rect max_output;

View File

@@ -120,10 +120,10 @@
#define VOP_WIN_TO_INDEX(vop2_win) \
((vop2_win) - (vop2_win)->vop2->win)
#define VOP_GRF_SET(vop2, reg, v) \
#define VOP_GRF_SET(vop2, grf, reg, v) \
do { \
if (vop2->data->grf_ctrl) { \
vop2_grf_writel(vop2, vop2->data->grf_ctrl->reg, v); \
if (vop2->data->grf) { \
vop2_grf_writel(vop2->grf, vop2->data->grf->reg, v); \
} \
} while (0)
@@ -544,6 +544,12 @@ struct vop2_video_port {
uint8_t nr_layers;
int cursor_win_id;
/**
* @output_if: output connector attached to the video port,
* this flag is maintained in vop driver, updated in crtc_atomic_enable,
* cleared in crtc_atomic_disable;
*/
u32 output_if;
/**
* @active_tv_state: TV connector related states
@@ -646,6 +652,9 @@ struct vop2 {
uint32_t *regsbak;
void __iomem *regs;
struct regmap *grf;
struct regmap *sys_grf;
struct regmap *vo0_grf;
struct regmap *vo1_grf;
/* physical map length of vop2 register */
uint32_t len;
@@ -740,16 +749,16 @@ static void vop2_unlock(struct vop2 *vop2)
mutex_unlock(&vop2->vop2_lock);
}
static inline void vop2_grf_writel(struct vop2 *vop2, struct vop_reg reg, u32 v)
static inline void vop2_grf_writel(struct regmap *regmap, struct vop_reg reg, u32 v)
{
u32 val = 0;
if (IS_ERR_OR_NULL(vop2->grf))
if (IS_ERR_OR_NULL(regmap))
return;
if (reg.mask) {
val = (v << reg.shift) | (reg.mask << (reg.shift + 16));
regmap_write(vop2->grf, reg.offset, val);
regmap_write(regmap, reg.offset, val);
}
}
@@ -3081,6 +3090,25 @@ static void vop2_crtc_atomic_disable(struct drm_crtc *crtc,
dsc->enabled = false;
vcstate->dsc_enable = false;
}
if (vp->output_if & VOP_OUTPUT_IF_eDP0)
VOP_GRF_SET(vop2, grf, grf_edp0_en, 0);
if (vp->output_if & VOP_OUTPUT_IF_eDP1)
VOP_GRF_SET(vop2, grf, grf_edp1_en, 0);
if (vp->output_if & VOP_OUTPUT_IF_HDMI0) {
VOP_GRF_SET(vop2, grf, grf_hdmi0_dsc_en, 0);
VOP_GRF_SET(vop2, grf, grf_hdmi0_en, 0);
}
if (vp->output_if & VOP_OUTPUT_IF_HDMI1) {
VOP_GRF_SET(vop2, grf, grf_hdmi1_dsc_en, 0);
VOP_GRF_SET(vop2, grf, grf_hdmi1_en, 0);
}
vp->output_if = 0;
/*
* Vop standby will take effect at end of current frame,
* if dsp hold valid irq happen, it means standby complete.
@@ -5278,6 +5306,8 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc, struct drm_crtc_state
val = (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC) ? 0 : BIT(HSYNC_POSITIVE);
val |= (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC) ? 0 : BIT(VSYNC_POSITIVE);
vp->output_if = vcstate->output_if;
if (vcstate->output_if & VOP_OUTPUT_IF_RGB) {
ret = vop2_calc_cru_cfg(crtc, VOP_OUTPUT_IF_RGB, &if_pixclk, &if_dclk);
if (ret < 0)
@@ -5285,7 +5315,7 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc, struct drm_crtc_state
VOP_CTRL_SET(vop2, rgb_en, 1);
VOP_CTRL_SET(vop2, rgb_mux, vp_data->id);
VOP_GRF_SET(vop2, grf_dclk_inv, dclk_inv);
VOP_GRF_SET(vop2, sys_grf, grf_dclk_inv, dclk_inv);
}
if (vcstate->output_if & VOP_OUTPUT_IF_BT1120) {
@@ -5296,7 +5326,7 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc, struct drm_crtc_state
VOP_CTRL_SET(vop2, rgb_en, 1);
VOP_CTRL_SET(vop2, bt1120_en, 1);
VOP_CTRL_SET(vop2, rgb_mux, vp_data->id);
VOP_GRF_SET(vop2, grf_bt1120_clk_inv, !dclk_inv);
VOP_GRF_SET(vop2, sys_grf, grf_bt1120_clk_inv, !dclk_inv);
yc_swap = vop2_output_yc_swap(vcstate->bus_format);
VOP_CTRL_SET(vop2, bt1120_yc_swap, yc_swap);
}
@@ -5308,7 +5338,7 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc, struct drm_crtc_state
VOP_CTRL_SET(vop2, bt656_en, 1);
VOP_CTRL_SET(vop2, rgb_mux, vp_data->id);
VOP_GRF_SET(vop2, grf_bt656_clk_inv, !dclk_inv);
VOP_GRF_SET(vop2, sys_grf, grf_bt656_clk_inv, !dclk_inv);
yc_swap = vop2_output_yc_swap(vcstate->bus_format);
VOP_CTRL_SET(vop2, bt656_yc_swap, yc_swap);
}
@@ -5387,6 +5417,7 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc, struct drm_crtc_state
VOP_CTRL_SET(vop2, edp0_mux, vp_data->id);
VOP_CTRL_SET(vop2, edp_pin_pol, val);
VOP_CTRL_SET(vop2, edp_dclk_pol, dclk_inv);
VOP_GRF_SET(vop2, grf, grf_edp0_en, 1);
}
if (vcstate->output_if & VOP_OUTPUT_IF_eDP1) {
@@ -5402,6 +5433,7 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc, struct drm_crtc_state
VOP_CTRL_SET(vop2, edp1_mux, vp_data->id);
VOP_CTRL_SET(vop2, edp_pin_pol, val);
VOP_CTRL_SET(vop2, edp_dclk_pol, dclk_inv);
VOP_GRF_SET(vop2, grf, grf_edp1_en, 1);
}
if (vcstate->output_if & VOP_OUTPUT_IF_DP0) {
@@ -5410,8 +5442,8 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc, struct drm_crtc_state
goto out;
VOP_CTRL_SET(vop2, dp0_en, 1);
VOP_CTRL_SET(vop2, dp0_mux, vp_data->id);
VOP_CTRL_SET(vop2, dp_dclk_pol, 0);
VOP_CTRL_SET(vop2, dp_pin_pol, val);
VOP_CTRL_SET(vop2, dp0_dclk_pol, 0);
VOP_CTRL_SET(vop2, dp0_pin_pol, val);
}
if (vcstate->output_if & VOP_OUTPUT_IF_DP1) {
@@ -5421,8 +5453,8 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc, struct drm_crtc_state
VOP_CTRL_SET(vop2, dp1_en, 1);
VOP_CTRL_SET(vop2, dp1_mux, vp_data->id);
VOP_CTRL_SET(vop2, dp_dclk_pol, 0);
VOP_CTRL_SET(vop2, dp_pin_pol, val);
VOP_CTRL_SET(vop2, dp1_dclk_pol, 0);
VOP_CTRL_SET(vop2, dp1_pin_pol, val);
}
if (vcstate->output_if & VOP_OUTPUT_IF_HDMI0) {
@@ -5434,6 +5466,12 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc, struct drm_crtc_state
VOP_CTRL_SET(vop2, hdmi0_dclk_div, if_dclk->div_val);
}
if (vcstate->dsc_enable)
VOP_GRF_SET(vop2, grf, grf_hdmi0_dsc_en, 1);
VOP_GRF_SET(vop2, grf, grf_hdmi0_en, 1);
VOP_GRF_SET(vop2, vo1_grf, grf_hdmi0_pin_pol, val);
VOP_CTRL_SET(vop2, hdmi0_en, 1);
VOP_CTRL_SET(vop2, hdmi0_en, 1);
VOP_CTRL_SET(vop2, hdmi0_mux, vp_data->id);
@@ -5451,6 +5489,12 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc, struct drm_crtc_state
VOP_CTRL_SET(vop2, hdmi1_dclk_div, if_dclk->div_val);
}
if (vcstate->dsc_enable)
VOP_GRF_SET(vop2, grf, grf_hdmi1_dsc_en, 1);
VOP_GRF_SET(vop2, grf, grf_hdmi1_en, 1);
VOP_GRF_SET(vop2, vo1_grf, grf_hdmi1_pin_pol, val);
VOP_CTRL_SET(vop2, hdmi1_en, 1);
VOP_CTRL_SET(vop2, hdmi1_mux, vp_data->id);
VOP_CTRL_SET(vop2, hdmi_pin_pol, val);
@@ -7810,7 +7854,9 @@ static int vop2_bind(struct device *dev, struct device *master, void *data)
return PTR_ERR(vop2->lut_regs);
}
vop2->grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,grf");
vop2->sys_grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,grf");
vop2->grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,vop-grf");
vop2->vo1_grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,vo1-grf");
vop2->hclk = devm_clk_get(vop2->dev, "hclk_vop");
if (IS_ERR(vop2->hclk)) {

View File

@@ -2288,7 +2288,7 @@ static const struct vop2_win_data rk3588_vop_win_data[] = {
},
};
static const struct vop_grf_ctrl rk3568_grf_ctrl = {
static const struct vop_grf_ctrl rk3568_sys_grf_ctrl = {
.grf_bt656_clk_inv = VOP_REG(RK3568_GRF_VO_CON1, 0x1, 1),
.grf_bt1120_clk_inv = VOP_REG(RK3568_GRF_VO_CON1, 0x1, 2),
.grf_dclk_inv = VOP_REG(RK3568_GRF_VO_CON1, 0x1, 3),
@@ -2359,6 +2359,26 @@ static const struct vop2_ctrl rk3568_vop_ctrl = {
.otp_en = VOP_REG(RK3568_OTP_WIN_EN, 0x1, 0),
};
static const struct vop_grf_ctrl rk3588_sys_grf_ctrl = {
.grf_bt656_clk_inv = VOP_REG(RK3588_GRF_SOC_CON1, 0x1, 14),
.grf_bt1120_clk_inv = VOP_REG(RK3588_GRF_SOC_CON1, 0x1, 14),
.grf_dclk_inv = VOP_REG(RK3588_GRF_SOC_CON1, 0x1, 14),
};
static const struct vop_grf_ctrl rk3588_vop_grf_ctrl = {
.grf_edp0_en = VOP_REG(RK3588_GRF_VOP_CON2, 0x1, 0),
.grf_hdmi0_en = VOP_REG(RK3588_GRF_VOP_CON2, 0x1, 1),
.grf_hdmi0_dsc_en = VOP_REG(RK3588_GRF_VOP_CON2, 0x1, 2),
.grf_edp1_en = VOP_REG(RK3588_GRF_VOP_CON2, 0x1, 3),
.grf_hdmi1_en = VOP_REG(RK3588_GRF_VOP_CON2, 0x1, 4),
.grf_hdmi1_dsc_en = VOP_REG(RK3588_GRF_VOP_CON2, 0x1, 4),
};
static const struct vop_grf_ctrl rk3588_vo1_grf_ctrl = {
.grf_hdmi0_pin_pol = VOP_REG(RK3588_GRF_VO1_CON0, 0x3, 5),
.grf_hdmi1_pin_pol = VOP_REG(RK3588_GRF_VO1_CON0, 0x3, 7),
};
static const struct vop2_ctrl rk3588_vop_ctrl = {
.cfg_done_en = VOP_REG(RK3568_REG_CFG_DONE, 0x1, 15),
.wb_cfg_done = VOP_REG_MASK(RK3568_REG_CFG_DONE, 0x1, 14),
@@ -2414,11 +2434,14 @@ static const struct vop2_ctrl rk3588_vop_ctrl = {
.mipi0_pixclk_div = VOP_REG(RK3568_DSP_IF_CTRL, 0x3, 24),
.mipi1_pixclk_div = VOP_REG(RK3568_DSP_IF_CTRL, 0x3, 26),
.hdmi_pin_pol = VOP_REG(RK3568_DSP_IF_POL, 0x7, 4),
.hdmi_dclk_pol = VOP_REG(RK3568_DSP_IF_POL, 0x1, 7),
.edp_pin_pol = VOP_REG(RK3568_DSP_IF_POL, 0x3, 12),
.edp_dclk_pol = VOP_REG(RK3568_DSP_IF_POL, 0x1, 15),
.mipi_pin_pol = VOP_REG(RK3568_DSP_IF_POL, 0x7, 16),
/* HDMI pol control by GRF_VO1_CON0
* DP0/1 clk pol is fixed
* MIPI/eDP pol is fixed
*/
.rgb_pin_pol = VOP_REG(RK3568_DSP_IF_POL, 0x7, 0),
.rgb_dclk_pol = VOP_REG(RK3568_DSP_IF_POL, 0x1, 3),
.dp0_pin_pol = VOP_REG(RK3568_DSP_IF_POL, 0x7, 8),
.dp1_pin_pol = VOP_REG(RK3568_DSP_IF_POL, 0x7, 12),
.mipi_dclk_pol = VOP_REG(RK3568_DSP_IF_POL, 0x1, 19),
.win_vp_id[ROCKCHIP_VOP2_CLUSTER0] = VOP_REG(RK3568_OVL_PORT_SEL, 0x3, 16),
.win_vp_id[ROCKCHIP_VOP2_CLUSTER1] = VOP_REG(RK3568_OVL_PORT_SEL, 0x3, 18),
@@ -2447,7 +2470,7 @@ static const struct vop2_data rk3568_vop = {
.max_input = { 4096, 2304 },
.max_output = { 4096, 2304 },
.ctrl = &rk3568_vop_ctrl,
.grf_ctrl = &rk3568_grf_ctrl,
.sys_grf = &rk3568_sys_grf_ctrl,
.axi_intr = rk3568_vop_axi_intr,
.nr_axi_intr = ARRAY_SIZE(rk3568_vop_axi_intr),
.vp = rk3568_vop_video_ports,
@@ -2470,6 +2493,9 @@ static const struct vop2_data rk3588_vop = {
.max_input = { 8192, 4320 },
.max_output = { 4096, 2304 },
.ctrl = &rk3588_vop_ctrl,
.grf = &rk3588_vop_grf_ctrl,
.sys_grf = &rk3588_sys_grf_ctrl,
.vo1_grf = &rk3588_vo1_grf_ctrl,
.axi_intr = rk3568_vop_axi_intr,
.nr_axi_intr = ARRAY_SIZE(rk3568_vop_axi_intr),
.dsc = rk3588_vop_dsc_data,

View File

@@ -1609,4 +1609,8 @@
#define RK3588_DSC_4K_STS0 0x41A8
#define RK3588_DSC_4K_ERS 0x41C4
#define RK3588_GRF_SOC_CON1 0x0304
#define RK3588_GRF_VOP_CON2 0x08
#define RK3588_GRF_VO1_CON0 0x00
#endif /* _ROCKCHIP_VOP_REG_H */