From: Xinlei Lee xinlei.lee@mediatek.com
In upstream-v5.8, dsi_enable will operate panel_enable, but this modification has been moved in v5.9. In order to ensure the timing of dsi_power_on/off and the timing of pulling up/down the MIPI signal, the modification of v5.9 is synchronized in this series of patches.
Changes since v4: 1. Dsi func modified to atomic operation. 2. Added fix tag. 3. Removed lane_ready print statement.
Changes since v3: 1. Rebase kernel-5.18-rc1. 2. Added dsi_enable protection. 3. Encapsulates the dsi_lane_ready function.
Changes since v2: 1. Rebase linux-next.
Changes since v1: 1. Dsi sequence marked with patch adjustment. 2. Fixes: mtk_dsi: Use the drm_panel_bridge.
Jitao Shi (3): drm/mediatek: Adjust the timing of mipi signal from LP00 to LP11 drm/mediatek: Separate poweron/poweroff from enable/disable and define new funcs drm/mediatek: keep dsi as LP00 before dcs cmds transfer
Xinlei Lee (2): drm/mediatek: Modify dsi funcs to atomic operations drm/mediatek: Add pull-down MIPI operation in mtk_dsi_poweroff function
drivers/gpu/drm/mediatek/mtk_dsi.c | 94 ++++++++++++++++++++---------- 1 file changed, 64 insertions(+), 30 deletions(-)
From: Jitao Shi jitao.shi@mediatek.com
Old sequence: 1. Pull the MIPI signal high 2. Delay & Dsi_reset 3. Set the dsi timing register 4. dsi clk & lanes leave ulp mode and enter hs mode
The sequence after patching is: 1. Set the dsi timing register 2. Pull the MIPI signal high 3. Delay & Dsi_reset 4. dsi clk & lanes leave ulp mode and enter hs mode
Fixes: 75374fc2c152 ("drm/mediatek: add dphy reset after setting lanes number")
Signed-off-by: Jitao Shi jitao.shi@mediatek.com Signed-off-by: Xinlei Lee xinlei.lee@mediatek.com Reviewed-by: AngeloGioacchino Del Regno angelogioacchino.delregno@collabora.com Reviewed-by: Rex-BC Chen rex-bc.chen@mediatek.com --- drivers/gpu/drm/mediatek/mtk_dsi.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c index bd3f5b485085..02e31a7d9257 100644 --- a/drivers/gpu/drm/mediatek/mtk_dsi.c +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c @@ -661,14 +661,14 @@ static int mtk_dsi_poweron(struct mtk_dsi *dsi) mtk_dsi_reset_engine(dsi); mtk_dsi_phy_timconfig(dsi);
- mtk_dsi_rxtx_control(dsi); - usleep_range(30, 100); - mtk_dsi_reset_dphy(dsi); mtk_dsi_ps_control_vact(dsi); mtk_dsi_set_vm_cmd(dsi); mtk_dsi_config_vdo_timing(dsi); mtk_dsi_set_interrupt_enable(dsi);
+ mtk_dsi_rxtx_control(dsi); + usleep_range(30, 100); + mtk_dsi_reset_dphy(dsi); mtk_dsi_clk_ulp_mode_leave(dsi); mtk_dsi_lane0_ulp_mode_leave(dsi); mtk_dsi_clk_hs_mode(dsi, 0);
From: Xinlei Lee xinlei.lee@mediatek.com
Modify dsi_enable & dsi_disable to dsi_atomic_enable & dsi_atomic_disable funcs.
Signed-off-by: Jitao Shi jitao.shi@mediatek.com Signed-off-by: Xinlei Lee xinlei.lee@mediatek.com --- drivers/gpu/drm/mediatek/mtk_dsi.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c index 02e31a7d9257..82a811801c9f 100644 --- a/drivers/gpu/drm/mediatek/mtk_dsi.c +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c @@ -763,14 +763,16 @@ static void mtk_dsi_bridge_mode_set(struct drm_bridge *bridge, drm_display_mode_to_videomode(adjusted, &dsi->vm); }
-static void mtk_dsi_bridge_disable(struct drm_bridge *bridge) +static void mtk_dsi_bridge_atomic_disable(struct drm_bridge *bridge, + struct drm_bridge_state *old_bridge_state) { struct mtk_dsi *dsi = bridge_to_dsi(bridge);
mtk_output_dsi_disable(dsi); }
-static void mtk_dsi_bridge_enable(struct drm_bridge *bridge) +static void mtk_dsi_bridge_atomic_enable(struct drm_bridge *bridge, + struct drm_bridge_state *old_bridge_state) { struct mtk_dsi *dsi = bridge_to_dsi(bridge);
@@ -779,8 +781,8 @@ static void mtk_dsi_bridge_enable(struct drm_bridge *bridge)
static const struct drm_bridge_funcs mtk_dsi_bridge_funcs = { .attach = mtk_dsi_bridge_attach, - .disable = mtk_dsi_bridge_disable, - .enable = mtk_dsi_bridge_enable, + .atomic_disable = mtk_dsi_bridge_atomic_disable, + .atomic_enable = mtk_dsi_bridge_atomic_enable, .mode_set = mtk_dsi_bridge_mode_set, };
From: Jitao Shi jitao.shi@mediatek.com
In order to match the changes of "Use the drm_panel_bridge API", the poweron/poweroff of dsi is extracted from enable/disable and defined as new funcs (atomic_pre_enable/atomic_post_disable).
Fixes: 2dd8075d2185 ("drm/mediatek: mtk_dsi: Use the drm_panel_bridge API")
Signed-off-by: Jitao Shi jitao.shi@mediatek.com Signed-off-by: Xinlei Lee xinlei.lee@mediatek.com Reviewed-by: AngeloGioacchino Del Regno angelogioacchino.delregno@collabora.com Reviewed-by: Rex-BC Chen rex-bc.chen@mediatek.com --- drivers/gpu/drm/mediatek/mtk_dsi.c | 53 +++++++++++++++++++----------- 1 file changed, 34 insertions(+), 19 deletions(-)
diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c index 82a811801c9f..2dee6632a541 100644 --- a/drivers/gpu/drm/mediatek/mtk_dsi.c +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c @@ -691,16 +691,6 @@ static void mtk_dsi_poweroff(struct mtk_dsi *dsi) if (--dsi->refcount != 0) return;
- /* - * mtk_dsi_stop() and mtk_dsi_start() is asymmetric, since - * mtk_dsi_stop() should be called after mtk_drm_crtc_atomic_disable(), - * which needs irq for vblank, and mtk_dsi_stop() will disable irq. - * mtk_dsi_start() needs to be called in mtk_output_dsi_enable(), - * after dsi is fully set. - */ - mtk_dsi_stop(dsi); - - mtk_dsi_switch_to_cmd_mode(dsi, VM_DONE_INT_FLAG, 500); mtk_dsi_reset_engine(dsi); mtk_dsi_lane0_ulp_mode_enter(dsi); mtk_dsi_clk_ulp_mode_enter(dsi); @@ -715,17 +705,9 @@ static void mtk_dsi_poweroff(struct mtk_dsi *dsi)
static void mtk_output_dsi_enable(struct mtk_dsi *dsi) { - int ret; - if (dsi->enabled) return;
- ret = mtk_dsi_poweron(dsi); - if (ret < 0) { - DRM_ERROR("failed to power on dsi\n"); - return; - } - mtk_dsi_set_mode(dsi); mtk_dsi_clk_hs_mode(dsi, 1);
@@ -739,7 +721,16 @@ static void mtk_output_dsi_disable(struct mtk_dsi *dsi) if (!dsi->enabled) return;
- mtk_dsi_poweroff(dsi); + /* + * mtk_dsi_stop() and mtk_dsi_start() is asymmetric, since + * mtk_dsi_stop() should be called after mtk_drm_crtc_atomic_disable(), + * which needs irq for vblank, and mtk_dsi_stop() will disable irq. + * mtk_dsi_start() needs to be called in mtk_output_dsi_enable(), + * after dsi is fully set. + */ + mtk_dsi_stop(dsi); + + mtk_dsi_switch_to_cmd_mode(dsi, VM_DONE_INT_FLAG, 500);
dsi->enabled = false; } @@ -776,13 +767,37 @@ static void mtk_dsi_bridge_atomic_enable(struct drm_bridge *bridge, { struct mtk_dsi *dsi = bridge_to_dsi(bridge);
+ if (dsi->refcount == 0) + return; + mtk_output_dsi_enable(dsi); }
+static void mtk_dsi_bridge_atomic_pre_enable(struct drm_bridge *bridge, + struct drm_bridge_state *old_bridge_state) +{ + struct mtk_dsi *dsi = bridge_to_dsi(bridge); + int ret; + + ret = mtk_dsi_poweron(dsi); + if (ret < 0) + DRM_ERROR("failed to power on dsi\n"); +} + +static void mtk_dsi_bridge_atomic_post_disable(struct drm_bridge *bridge, + struct drm_bridge_state *old_bridge_state) +{ + struct mtk_dsi *dsi = bridge_to_dsi(bridge); + + mtk_dsi_poweroff(dsi); +} + static const struct drm_bridge_funcs mtk_dsi_bridge_funcs = { .attach = mtk_dsi_bridge_attach, .atomic_disable = mtk_dsi_bridge_atomic_disable, .atomic_enable = mtk_dsi_bridge_atomic_enable, + .atomic_pre_enable = mtk_dsi_bridge_atomic_pre_enable, + .atomic_post_disable = mtk_dsi_bridge_atomic_post_disable, .mode_set = mtk_dsi_bridge_mode_set, };
From: Jitao Shi jitao.shi@mediatek.com
To comply with the panel sequence, hold the mipi signal to LP00 before the dcs cmds transmission, and pull the mipi signal high from LP00 to LP11 until the start of the dcs cmds transmission. The normal panel timing is : (1) pp1800 DC pull up (2) avdd & avee AC pull high (3) lcm_reset pull high -> pull low -> pull high (4) Pull MIPI signal high (LP11) -> initial code -> send video data(HS mode) The power-off sequence is reversed. If dsi is not in cmd mode, then dsi will pull the mipi signal high in the mtk_output_dsi_enable function. The delay in lane_ready func is the reaction time of dsi_rx after pulling up the mipi signal.
Fixes: 2dd8075d2185 ("drm/mediatek: mtk_dsi: Use the drm_panel_bridge API")
Signed-off-by: Jitao Shi jitao.shi@mediatek.com Signed-off-by: Xinlei Lee xinlei.lee@mediatek.com --- drivers/gpu/drm/mediatek/mtk_dsi.c | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c index 2dee6632a541..98b7811502e7 100644 --- a/drivers/gpu/drm/mediatek/mtk_dsi.c +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c @@ -203,6 +203,7 @@ struct mtk_dsi { struct mtk_phy_timing phy_timing; int refcount; bool enabled; + bool lanes_ready; u32 irq_data; wait_queue_head_t irq_wait_queue; const struct mtk_dsi_driver_data *driver_data; @@ -666,13 +667,6 @@ static int mtk_dsi_poweron(struct mtk_dsi *dsi) mtk_dsi_config_vdo_timing(dsi); mtk_dsi_set_interrupt_enable(dsi);
- mtk_dsi_rxtx_control(dsi); - usleep_range(30, 100); - mtk_dsi_reset_dphy(dsi); - mtk_dsi_clk_ulp_mode_leave(dsi); - mtk_dsi_lane0_ulp_mode_leave(dsi); - mtk_dsi_clk_hs_mode(dsi, 0); - return 0; err_disable_engine_clk: clk_disable_unprepare(dsi->engine_clk); @@ -701,6 +695,24 @@ static void mtk_dsi_poweroff(struct mtk_dsi *dsi) clk_disable_unprepare(dsi->digital_clk);
phy_power_off(dsi->phy); + + dsi->lanes_ready = false; + +} + +static void mtk_dsi_lane_ready(struct mtk_dsi *dsi) +{ + if (!dsi->lanes_ready) { + dsi->lanes_ready = true; + mtk_dsi_rxtx_control(dsi); + usleep_range(30, 100); + mtk_dsi_reset_dphy(dsi); + mtk_dsi_clk_ulp_mode_leave(dsi); + mtk_dsi_lane0_ulp_mode_leave(dsi); + mtk_dsi_clk_hs_mode(dsi, 0); + msleep(20); + /* The reaction time after pulling up the mipi signal for dsi_rx */ + } }
static void mtk_output_dsi_enable(struct mtk_dsi *dsi) @@ -708,6 +720,7 @@ static void mtk_output_dsi_enable(struct mtk_dsi *dsi) if (dsi->enabled) return;
+ mtk_dsi_lane_ready(dsi); mtk_dsi_set_mode(dsi); mtk_dsi_clk_hs_mode(dsi, 1);
@@ -1017,6 +1030,8 @@ static ssize_t mtk_dsi_host_transfer(struct mipi_dsi_host *host, if (MTK_DSI_HOST_IS_READ(msg->type)) irq_flag |= LPRX_RD_RDY_INT_FLAG;
+ mtk_dsi_lane_ready(dsi); + ret = mtk_dsi_host_send_cmd(dsi, msg, irq_flag); if (ret) goto restore_dsi_mode;
Il 11/05/22 04:36, xinlei.lee@mediatek.com ha scritto:
From: Jitao Shi jitao.shi@mediatek.com
To comply with the panel sequence, hold the mipi signal to LP00 before the dcs cmds transmission, and pull the mipi signal high from LP00 to LP11 until the start of the dcs cmds transmission. The normal panel timing is : (1) pp1800 DC pull up (2) avdd & avee AC pull high (3) lcm_reset pull high -> pull low -> pull high (4) Pull MIPI signal high (LP11) -> initial code -> send video data(HS mode) The power-off sequence is reversed. If dsi is not in cmd mode, then dsi will pull the mipi signal high in the mtk_output_dsi_enable function. The delay in lane_ready func is the reaction time of dsi_rx after pulling up the mipi signal.
Fixes: 2dd8075d2185 ("drm/mediatek: mtk_dsi: Use the drm_panel_bridge API")
Signed-off-by: Jitao Shi jitao.shi@mediatek.com Signed-off-by: Xinlei Lee xinlei.lee@mediatek.com
Reviewed-by: AngeloGioacchino Del Regno angelogioacchino.delregno@collabora.com
From: Xinlei Lee xinlei.lee@mediatek.com
In the dsi_enable function, mtk_dsi_rxtx_control is to pull up the MIPI signal operation. Before dsi_disable, MIPI should also be pulled down by writing a register instead of disabling dsi.
If disable dsi without pulling the mipi signal low, the value of the register will still maintain the setting of the mipi signal being pulled high. After resume, even if the mipi signal is not pulled high, it will still be in the high state.
Fixes: 2e54c14e310f ("drm/mediatek: Add DSI sub driver")
Signed-off-by: Jitao Shi jitao.shi@mediatek.com Signed-off-by: Xinlei Lee xinlei.lee@mediatek.com Reviewed-by: Rex-BC Chen rex-bc.chen@mediatek.com Reviewed-by: CK Hu ck.hu@mediatek.com --- drivers/gpu/drm/mediatek/mtk_dsi.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c index 98b7811502e7..1035fafdbf7c 100644 --- a/drivers/gpu/drm/mediatek/mtk_dsi.c +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c @@ -688,6 +688,8 @@ static void mtk_dsi_poweroff(struct mtk_dsi *dsi) mtk_dsi_reset_engine(dsi); mtk_dsi_lane0_ulp_mode_enter(dsi); mtk_dsi_clk_ulp_mode_enter(dsi); + /* set the lane number as 0 to pull down mipi */ + writel(0, dsi->regs + DSI_TXRX_CTRL);
mtk_dsi_disable(dsi);
dri-devel@lists.freedesktop.org