From dfb726bf21246d6c36ea2d0c084aebd7e435a135 Mon Sep 17 00:00:00 2001 From: Rimon Xu Date: Fri, 17 Nov 2023 16:50:39 +0800 Subject: [PATCH 1/5] video: rockchip: vtunnel: buffer ID should generate by instance When resetting an instance, the buffer generation ID will be changed, but when receiving images, the ID will be used to determine whether it is an expired buffer. Therefore, the ID generator should be placed in the instance instead of the device. Change-Id: I707403dd22dce784dee07654d7333a02f5f35f43 Signed-off-by: Rimon Xu --- drivers/video/rockchip/vtunnel/rkvtunnel.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/video/rockchip/vtunnel/rkvtunnel.c b/drivers/video/rockchip/vtunnel/rkvtunnel.c index a2ce451b7cda..2068e3f05357 100644 --- a/drivers/video/rockchip/vtunnel/rkvtunnel.c +++ b/drivers/video/rockchip/vtunnel/rkvtunnel.c @@ -72,7 +72,6 @@ struct rkvt_dev { char *dev_name; int inst_id_generator; atomic64_t cid_generator; - atomic64_t buf_id_generator; struct dentry *debug_root; }; @@ -123,6 +122,8 @@ struct rkvt_instance { DECLARE_KFIFO_PTR(fifo_to_producer, struct rkvt_buffer*); struct rkvt_buffer vt_buffers[RKVT_POOL_SIZE]; + + atomic64_t buf_id_generator; }; static unsigned int vt_dev_dbg; @@ -740,10 +741,10 @@ rkvt_reset_proc(struct rkvt_ctrl_data *data, struct rkvt_session *session) mutex_lock(&inst->lock); rkvt_inst_clear_consumer(inst); rkvt_inst_clear_producer(inst); - read_buf_id = atomic64_read(&vt_dev->buf_id_generator); + read_buf_id = atomic64_read(&inst->buf_id_generator); read_buf_id += 0x100; read_buf_id &= ~0xff; - atomic64_set(&vt_dev->buf_id_generator, read_buf_id); + atomic64_set(&inst->buf_id_generator, read_buf_id); mutex_unlock(&inst->lock); rkvt_inst_put(inst); @@ -950,7 +951,7 @@ rkvt_queue_buf(struct rkvt_buf_data *data, struct rkvt_session *session) // buffer id is empty, generate a new id if (base->buffer_id == 0) - base->buffer_id = atomic64_inc_return(&vt_dev->buf_id_generator); + base->buffer_id = atomic64_inc_return(&inst->buf_id_generator); buffer->base = *base; buffer->base.buf_status = RKVT_BUF_QUEUE; buffer->session_pro = session; @@ -1234,7 +1235,7 @@ rkvt_release_buf(struct rkvt_buf_data *data, struct rkvt_session *session) buffer->base.buf_status = RKVT_BUF_RELEASE; mutex_lock(&inst->lock); - read_buf_id = atomic64_read(&vt_dev->buf_id_generator); + read_buf_id = atomic64_read(&inst->buf_id_generator); /* if producer has disconnect */ if (!inst->producer) { rkvt_dbg(RKVT_DBG_BUFFERS, "VTRB [%d], buffer no producer\n", inst->id); @@ -1298,7 +1299,7 @@ rkvt_cancel_buf(struct rkvt_buf_data *data, struct rkvt_session *session) } // buffer id is empty, generate a new id if (buf_base->buffer_id == 0) - buf_base->buffer_id = atomic64_inc_return(&vt_dev->buf_id_generator); + buf_base->buffer_id = atomic64_inc_return(&inst->buf_id_generator); buffer->base = *buf_base; buffer->base.buf_status = RKVT_BUF_RELEASE; buffer->session_pro = session; From 90463250cb4f4a3b533d05d7b68a807625290b80 Mon Sep 17 00:00:00 2001 From: Guochun Huang Date: Thu, 16 Nov 2023 11:51:36 +0000 Subject: [PATCH 2/5] drm/rockchip: dsi2: fix IPI_RATIO_MAN_CFG in dsc mode Change-Id: Iad403cca10fb1d9efb84d6b7e6524e22586a2421 Signed-off-by: Guochun Huang --- .../gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c | 38 ++++++++++++++++--- 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c index cae0353ec3e8..65a5d75c2e31 100644 --- a/drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c @@ -271,7 +271,7 @@ struct dw_mipi_dsi2 { u32 lanes; u32 format; unsigned long mode_flags; - + u64 mipi_pixel_rate; const struct dw_mipi_dsi2_plat_data *pdata; struct rockchip_drm_sub_dev sub_dev; @@ -610,9 +610,8 @@ static void dw_mipi_dsi2_phy_clk_mode_cfg(struct dw_mipi_dsi2 *dsi2) static void dw_mipi_dsi2_phy_ratio_cfg(struct dw_mipi_dsi2 *dsi2) { - struct drm_display_mode *mode = &dsi2->mode; u64 sys_clk = clk_get_rate(dsi2->sys_clk); - u64 pixel_clk, ipi_clk, phy_hsclk; + u64 ipi_clk, phy_hsclk; u64 tmp; /* @@ -626,9 +625,7 @@ static void dw_mipi_dsi2_phy_ratio_cfg(struct dw_mipi_dsi2 *dsi2) phy_hsclk = DIV_ROUND_CLOSEST_ULL(dsi2->lane_hs_rate * MSEC_PER_SEC, 16); /* IPI_RATIO_MAN_CFG = PHY_HSTX_CLK / IPI_CLK */ - pixel_clk = mode->crtc_clock * MSEC_PER_SEC; - ipi_clk = pixel_clk / 4; - + ipi_clk = dsi2->mipi_pixel_rate; if (!sys_clk || !ipi_clk) return; @@ -845,6 +842,31 @@ static void dw_mipi_dsi2_enable(struct dw_mipi_dsi2 *dsi2) dw_mipi_dsi2_enable(dsi2->slave); } +static void dw_mipi_dsi2_get_mipi_pixel_clk(struct dw_mipi_dsi2 *dsi2, + struct rockchip_crtc_state *s) +{ + struct drm_display_mode *mode = &dsi2->mode; + u8 k = dsi2->slave ? 2 : 1; + + /* 1.When MIPI works in uncompressed mode: + * (Video Timing Pixel Rate)/(4)=(MIPI Pixel ClockxK)=(dclk_out×K)=dclk_core + * 2.When MIPI works in compressed mode: + * MIPI Pixel Clock = cds_clk / 2 + * MIPI is configured as double channel display mode, K=2, otherwise K=1. + */ + if (dsi2->dsc_enable) { + dsi2->mipi_pixel_rate = s->dsc_cds_clk_rate / 2; + if (dsi2->slave) + dsi2->slave->mipi_pixel_rate = dsi2->mipi_pixel_rate; + + return; + } + + dsi2->mipi_pixel_rate = (mode->crtc_clock * MSEC_PER_SEC) / (4 * k); + if (dsi2->slave) + dsi2->slave->mipi_pixel_rate = dsi2->mipi_pixel_rate; +} + static int dw_mipi_dsi2_encoder_mode_set(struct dw_mipi_dsi2 *dsi2, struct drm_atomic_state *state) { @@ -852,6 +874,7 @@ static int dw_mipi_dsi2_encoder_mode_set(struct dw_mipi_dsi2 *dsi2, struct drm_connector *connector; struct drm_connector_state *conn_state; struct drm_crtc_state *crtc_state; + struct rockchip_crtc_state *vcstate; const struct drm_display_mode *adjusted_mode; struct drm_display_mode *mode = &dsi2->mode; @@ -869,6 +892,7 @@ static int dw_mipi_dsi2_encoder_mode_set(struct dw_mipi_dsi2 *dsi2, return -ENODEV; } + vcstate = to_rockchip_crtc_state(crtc_state); adjusted_mode = &crtc_state->adjusted_mode; drm_mode_copy(mode, adjusted_mode); @@ -878,6 +902,8 @@ static int dw_mipi_dsi2_encoder_mode_set(struct dw_mipi_dsi2 *dsi2, if (dsi2->slave) drm_mode_copy(&dsi2->slave->mode, mode); + dw_mipi_dsi2_get_mipi_pixel_clk(dsi2, vcstate); + return 0; } From 58ca4dfe8929a0fbee364bf23bedd93e259354fd Mon Sep 17 00:00:00 2001 From: Guochun Huang Date: Thu, 16 Nov 2023 07:00:30 +0000 Subject: [PATCH 3/5] drm/rockchip: dsi2: support Auto-Calculation mode the dsi2 controller can be select work in Munual or Automatic mode, by writing in MANUAL_MODE_CFG register. the Auto-Calculation mode has the following advantages: 1.Eliminates the need for the user to configure a set of registers 2.Makes the configuration routine easier, and the controller is less prone to undesired behaviors 3.Allows IPI frames to change dynamically with the controller adapting the output frames Change-Id: I00dfad82f9d5aa27abc4a2b99471ae4d6412d1b0 Signed-off-by: Guochun Huang --- .../gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c index 65a5d75c2e31..e66df80980f4 100644 --- a/drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c @@ -247,6 +247,7 @@ struct dw_mipi_dsi2 { union phy_configure_opts phy_opts; bool disable_hold_mode; + bool auto_calc_mode; bool c_option; bool scrambling_en; unsigned int slice_width; @@ -667,6 +668,10 @@ static void dw_mipi_dsi2_phy_init(struct dw_mipi_dsi2 *dsi2) { dw_mipi_dsi2_phy_mode_cfg(dsi2); dw_mipi_dsi2_phy_clk_mode_cfg(dsi2); + + if (dsi2->auto_calc_mode) + return; + dw_mipi_dsi2_phy_ratio_cfg(dsi2); dw_mipi_dsi2_lp2hs_or_hs2lp_cfg(dsi2); @@ -735,6 +740,9 @@ static void dw_mipi_dsi2_ipi_set(struct dw_mipi_dsi2 *dsi2) dw_mipi_dsi2_ipi_color_coding_cfg(dsi2); + if (dsi2->auto_calc_mode) + return; + /* * if the controller is intended to operate in data stream mode, * no more steps are required. @@ -808,7 +816,7 @@ static void dw_mipi_dsi2_pre_enable(struct dw_mipi_dsi2 *dsi2) /* there may be some timeout registers may be configured if desired */ - dw_mipi_dsi2_work_mode(dsi2, MANUAL_MODE_EN); + dw_mipi_dsi2_work_mode(dsi2, dsi2->auto_calc_mode ? 0 : MANUAL_MODE_EN); dw_mipi_dsi2_phy_init(dsi2); dw_mipi_dsi2_tx_option_set(dsi2); dw_mipi_dsi2_irq_enable(dsi2, 1); @@ -831,8 +839,20 @@ static void dw_mipi_dsi2_pre_enable(struct dw_mipi_dsi2 *dsi2) static void dw_mipi_dsi2_enable(struct dw_mipi_dsi2 *dsi2) { + u32 mode; + int ret; + dw_mipi_dsi2_ipi_set(dsi2); + if (dsi2->auto_calc_mode) { + regmap_write(dsi2->regmap, DSI2_MODE_CTRL, AUTOCALC_MODE); + ret = regmap_read_poll_timeout(dsi2->regmap, DSI2_MODE_STATUS, + mode, mode == IDLE_MODE, + 1000, MODE_STATUS_TIMEOUT_US); + if (ret < 0) + dev_err(dsi2->dev, "auto calculation training failed\n"); + } + if (dsi2->mode_flags & MIPI_DSI_MODE_VIDEO) dw_mipi_dsi2_set_vid_mode(dsi2); else @@ -1194,6 +1214,7 @@ static int dw_mipi_dsi2_dual_channel_probe(struct dw_mipi_dsi2 *dsi2) dsi2->slave->master = dsi2; dsi2->lanes /= 2; + dsi2->slave->auto_calc_mode = dsi2->auto_calc_mode; dsi2->slave->lanes = dsi2->lanes; dsi2->slave->channel = dsi2->channel; dsi2->slave->format = dsi2->format; @@ -1669,6 +1690,9 @@ static int dw_mipi_dsi2_probe(struct platform_device *pdev) dsi2->pdata = of_device_get_match_data(dev); platform_set_drvdata(pdev, dsi2); + if (device_property_read_bool(dev, "auto-calculation-mode")) + dsi2->auto_calc_mode = true; + if (device_property_read_bool(dev, "disable-hold-mode")) dsi2->disable_hold_mode = true; From f946ec433202dd8470981f70d0f50a6f197fde38 Mon Sep 17 00:00:00 2001 From: Damon Ding Date: Mon, 20 Nov 2023 15:13:23 +0800 Subject: [PATCH 4/5] drm/rockchip: vvop: fix compile errors Fixes: 7f0033da72d8 ("drm/rockchip: vvop: fix a potential race condition when vvop_disable_vblank") Change-Id: I63356c83dfca4d6d0c98a23105343a496b760587 Signed-off-by: Damon Ding --- drivers/gpu/drm/rockchip/rockchip_drm_vvop.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vvop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vvop.c index 32e212998fd9..3f4432ad596c 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vvop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vvop.c @@ -461,7 +461,7 @@ static u64 vvop_get_soc_id(void) return 0; } -static int vvop_crtc_deinit(struct drm_crtc *vcrtc) +static void vvop_crtc_deinit(struct drm_crtc *crtc) { struct vvop_crtc *vcrtc = drm_crtc_to_vvop_crtc(crtc); From 0aa6d336c04bba5357c0b0dd2321ace7194cc1b7 Mon Sep 17 00:00:00 2001 From: XiaoDong Huang Date: Mon, 20 Nov 2023 16:41:04 +0800 Subject: [PATCH 5/5] ARM: rockchip: support rv1103 suspend Signed-off-by: XiaoDong Huang Change-Id: I9dc1d71bf0c20b8a48f49c283bc1fdef37be770a --- arch/arm/mach-rockchip/rockchip.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-rockchip/rockchip.c b/arch/arm/mach-rockchip/rockchip.c index c89db60dc86e..3ff8b7044ff9 100644 --- a/arch/arm/mach-rockchip/rockchip.c +++ b/arch/arm/mach-rockchip/rockchip.c @@ -62,6 +62,7 @@ static const char * const rockchip_board_dt_compat[] = { "rockchip,rk3188", "rockchip,rk3228", "rockchip,rk3288", + "rockchip,rv1103", "rockchip,rv1106", "rockchip,rv1108", NULL,