drm/rockchip: MIPI fixes & improvements
Subsystems (4)
v3 cover drm/rockchip: MIPI fixes & improvements
This re-roll mostly just gather up reviewed-by tags, although I have also wrapped some long lines and squashed together some commits as suggested by Chris Zhong.
Version 2 was posted here:
https://www.spinics.net/lists/arm-kernel/msg556683.html
John Keeping (24):
drm/rockchip: dw-mipi-dsi: don't configure hardware in mode_set for
MIPI
drm/rockchip: dw-mipi-dsi: pass mode in where needed drm/rockchip: dw-mipi-dsi: remove mode_set hook drm/rockchip: dw-mipi-dsi: fix command header writes drm/rockchip: dw-mipi-dsi: fix generic packet status check drm/rockchip: dw-mipi-dsi: avoid out-of-bounds read on tx_buf drm/rockchip: dw-mipi-dsi: include bad value in error message drm/rockchip: dw-mipi-dsi: respect message flags drm/rockchip: dw-mipi-dsi: only request HS clock when required drm/rockchip: dw-mipi-dsi: don't assume buffer is aligned drm/rockchip: dw-mipi-dsi: prepare panel after phy init drm/rockchip: dw-mipi-dsi: allow commands in panel_disable drm/rockchip: dw-mipi-dsi: fix escape clock rate drm/rockchip: dw-mipi-dsi: ensure PHY is reset drm/rockchip: dw-mipi-dsi: configure PHY before enabling drm/rockchip: dw-mipi-dsi: properly configure PHY timing drm/rockchip: dw-mipi-dsi: improve PLL configuration drm/rockchip: dw-mipi-dsi: use specific poll helper drm/rockchip: dw-mipi-dsi: use positive check for N{H,V}SYNC drm/rockchip: vop: test for P{H,V}SYNC
drm/rockchip: dw-mipi-dsi: defer probe if panel is not loaded drm/rockchip: dw-mipi-dsi: support non-burst modes drm/rockchip: dw-mipi-dsi: add reset control drm/rockchip: dw-mipi-dsi: support read commands
drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 348 +++++++++++++++++++--------- drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 4 +- 2 files changed, 245 insertions(+), 107 deletions(-)
Signature · 1 line
2.11.0.197.gb556de5.dirty
PATCH v3 1/24 drm/rockchip: dw-mipi-dsi: don't configure hardware in mode_set for MIPI
With atomic modesetting the hardware will be powered off when the mode_set function is called. We should configure the hardware in the enable function, which is the atomic version of "commit" so let's use the enable hook rather than commit while we're at it.
---
v3:
- Squash together with the commit to s/commit/enable/ Unchanged in v2
drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 49 +++++++++++++++------------------- 1 file changed, 21 insertions(+), 28 deletions(-)
drivers/gpu/drm/rockchip/dw-mipi-dsi.c +21 -28
@@ -819,34 +819,8 @@ static void dw_mipi_dsi_encoder_mode_set(struct drm_encoder *encoder, struct drm_display_mode *adjusted_mode) {struct dw_mipi_dsi *dsi =encoder_to_dsi (encoder); -int ret; dsi->mode = adjusted_mode; - - ret =dw_mipi_dsi_get_lane_bps (dsi); -if (ret <0 ) -return ; - -if (clk_prepare_enable (dsi->pclk)) { -dev_err (dsi->dev,"%s: Failed to enable pclk\n" , __func__); -return ; - } - -dw_mipi_dsi_init (dsi); -dw_mipi_dsi_dpi_config (dsi, mode); -dw_mipi_dsi_packet_handler_config (dsi); -dw_mipi_dsi_video_mode_config (dsi); -dw_mipi_dsi_video_packet_config (dsi, mode); -dw_mipi_dsi_command_mode_config (dsi); -dw_mipi_dsi_line_timer_config (dsi); -dw_mipi_dsi_vertical_timing_config (dsi); -dw_mipi_dsi_dphy_timing_config (dsi); -dw_mipi_dsi_dphy_interface_config (dsi); -dw_mipi_dsi_clear_err (dsi); -if (drm_panel_prepare (dsi->panel)) -dev_err (dsi->dev,"failed to prepare panel\n" ); - -clk_disable_unprepare (dsi->pclk); }static void dw_mipi_dsi_encoder_disable (struct drm_encoder *encoder)
@@ -875,17 +849,36 @@ static void dw_mipi_dsi_encoder_disable(struct drm_encoder *encoder)clk_disable_unprepare (dsi->pclk); } -static void dw_mipi_dsi_encoder_commit (struct drm_encoder *encoder) +static void dw_mipi_dsi_encoder_enable (struct drm_encoder *encoder) {struct dw_mipi_dsi *dsi =encoder_to_dsi (encoder);int mux =drm_of_encoder_active_endpoint_id (dsi->dev->of_node, encoder);u32 val; +int ret; + + ret =dw_mipi_dsi_get_lane_bps (dsi); +if (ret <0 ) +return ;if (clk_prepare_enable (dsi->pclk)) {dev_err (dsi->dev,"%s: Failed to enable pclk\n" , __func__);return ; } +dw_mipi_dsi_init (dsi); +dw_mipi_dsi_dpi_config (dsi, dsi->mode); +dw_mipi_dsi_packet_handler_config (dsi); +dw_mipi_dsi_video_mode_config (dsi); +dw_mipi_dsi_video_packet_config (dsi, dsi->mode); +dw_mipi_dsi_command_mode_config (dsi); +dw_mipi_dsi_line_timer_config (dsi); +dw_mipi_dsi_vertical_timing_config (dsi); +dw_mipi_dsi_dphy_timing_config (dsi); +dw_mipi_dsi_dphy_interface_config (dsi); +dw_mipi_dsi_clear_err (dsi); +if (drm_panel_prepare (dsi->panel)) +dev_err (dsi->dev,"failed to prepare panel\n" ); +dw_mipi_dsi_phy_init (dsi);dw_mipi_dsi_wait_for_two_frames (dsi);
@@ -933,7 +926,7 @@ dw_mipi_dsi_encoder_atomic_check(struct drm_encoder *encoder,static struct drm_encoder_helper_funcs dw_mipi_dsi_encoder_helper_funcs = { - .commit = dw_mipi_dsi_encoder_commit, + .enable = dw_mipi_dsi_encoder_enable, .mode_set = dw_mipi_dsi_encoder_mode_set, .disable = dw_mipi_dsi_encoder_disable, .atomic_check = dw_mipi_dsi_encoder_atomic_check,
Signature · 1 line
2.11.0.197.gb556de5.dirty
Re: [PATCH v3 01/24] drm/rockchip: dw-mipi-dsi: don't configure hardware in mode_set for MIPI
Quoted 5 lines · John Keeping
With atomic modesetting the hardware will be powered off when the
mode_setfunction is called. We should configure the hardware in the enable function, which is the atomic version of "commit" so let's use the enable hook rather than commit while we're at it.
Quoted 102 lines
Signed-off-by John Keeping <[email protected]>---
v3:
- Squash together with the commit to s/commit/enable/ Unchanged in v2drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 49 +++++++++++++++------------------- 1 file changed, 21 insertions(+), 28 deletions(-)drivers/gpu/drm/rockchip/dw-mipi-dsi.c +21
-28@@ -819,34 +819,8 @@ static void dw_mipi_dsi_encoder_mode_set(struct drm_encoder *encoder, struct drm_display_mode *adjusted_mode) {struct dw_mipi_dsi *dsi =encoder_to_dsi (encoder); -int ret; dsi->mode = adjusted_mode; - - ret =dw_mipi_dsi_get_lane_bps (dsi); -if (ret <0 ) -return ; - -if (clk_prepare_enable (dsi->pclk)) { -dev_err (dsi->dev,"%s: Failed to enable pclk\n" , __func__); -return ; - } - -dw_mipi_dsi_init (dsi); -dw_mipi_dsi_dpi_config (dsi, mode); -dw_mipi_dsi_packet_handler_config (dsi); -dw_mipi_dsi_video_mode_config (dsi); -dw_mipi_dsi_video_packet_config (dsi, mode); -dw_mipi_dsi_command_mode_config (dsi); -dw_mipi_dsi_line_timer_config (dsi); -dw_mipi_dsi_vertical_timing_config (dsi); -dw_mipi_dsi_dphy_timing_config (dsi); -dw_mipi_dsi_dphy_interface_config (dsi); -dw_mipi_dsi_clear_err (dsi); -if (drm_panel_prepare (dsi->panel)) -dev_err (dsi->dev,"failed to prepare panel\n" ); - -clk_disable_unprepare (dsi->pclk); }static void dw_mipi_dsi_encoder_disable (struct drm_encoder *encoder)@@ -875,17 +849,36 @@ static void dw_mipi_dsi_encoder_disable(struct drm_encoder *encoder)clk_disable_unprepare (dsi->pclk); } -static void dw_mipi_dsi_encoder_commit (struct drm_encoder *encoder) +static void dw_mipi_dsi_encoder_enable (struct drm_encoder *encoder) {struct dw_mipi_dsi *dsi =encoder_to_dsi (encoder);int mux =drm_of_encoder_active_endpoint_id (dsi->dev->of_node, encoder);u32 val; +int ret; + + ret =dw_mipi_dsi_get_lane_bps (dsi); +if (ret <0 ) +return ;if (clk_prepare_enable (dsi->pclk)) {dev_err (dsi->dev,"%s: Failed to enable pclk\n" , __func__);return ; } +dw_mipi_dsi_init (dsi); +dw_mipi_dsi_dpi_config (dsi, dsi->mode); +dw_mipi_dsi_packet_handler_config (dsi); +dw_mipi_dsi_video_mode_config (dsi); +dw_mipi_dsi_video_packet_config (dsi, dsi->mode); +dw_mipi_dsi_command_mode_config (dsi); +dw_mipi_dsi_line_timer_config (dsi); +dw_mipi_dsi_vertical_timing_config (dsi); +dw_mipi_dsi_dphy_timing_config (dsi); +dw_mipi_dsi_dphy_interface_config (dsi); +dw_mipi_dsi_clear_err (dsi); +if (drm_panel_prepare (dsi->panel)) +dev_err (dsi->dev,"failed to prepare panel\n" ); +dw_mipi_dsi_phy_init (dsi);dw_mipi_dsi_wait_for_two_frames (dsi);@@ -933,7 +926,7 @@ dw_mipi_dsi_encoder_atomic_check(struct drm_encoder *encoder,static struct drm_encoder_helper_funcs dw_mipi_dsi_encoder_helper_funcs = { - .commit = dw_mipi_dsi_encoder_commit, + .enable = dw_mipi_dsi_encoder_enable, .mode_set = dw_mipi_dsi_encoder_mode_set, .disable = dw_mipi_dsi_encoder_disable, .atomic_check = dw_mipi_dsi_encoder_atomic_check,Signature · 6 lines
2.11.0.197.gb556de5.dirty _______________________________________________ dri-devel mailing list dri-devel at lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Signature · 1 line
Sean Paul, Software Engineer, Google / Chromium OS
PATCH v3 2/24 drm/rockchip: dw-mipi-dsi: pass mode in where needed
In reply to John KeepingThis shows that we only use the mode from the enable function and prepares us to remove the "mode" field and the mode_set hook in the next commit.
---
v3:
- Add Chris' Reviewed-by
New in v2
drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 41 ++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 19 deletions(-)
drivers/gpu/drm/rockchip/dw-mipi-dsi.c +22 -19
@@ -330,11 +330,11 @@ static int max_mbps_to_testdin(unsigned int max_mbps)* The controller should generate 2 frames before * preparing the peripheral. */ -static void dw_mipi_dsi_wait_for_two_frames (struct dw_mipi_dsi *dsi) +static void dw_mipi_dsi_wait_for_two_frames (struct drm_display_mode *mode) {int refresh, two_frames; - refresh =drm_mode_vrefresh (dsi->mode); + refresh =drm_mode_vrefresh (mode); two_frames =DIV_ROUND_UP (MSEC_PER_SEC , refresh) *2 ;msleep (two_frames); }
@@ -459,7 +459,8 @@ static int dw_mipi_dsi_phy_init(struct dw_mipi_dsi *dsi)return ret; } -static int dw_mipi_dsi_get_lane_bps (struct dw_mipi_dsi *dsi) +static int dw_mipi_dsi_get_lane_bps (struct dw_mipi_dsi *dsi, +struct drm_display_mode *mode) {unsigned int i, pre;unsigned long mpclk, pllref, tmp;
@@ -474,7 +475,7 @@ static int dw_mipi_dsi_get_lane_bps(struct dw_mipi_dsi *dsi)return bpp; } - mpclk =DIV_ROUND_UP (dsi->mode->clock,MSEC_PER_SEC ); + mpclk =DIV_ROUND_UP (mode->clock,MSEC_PER_SEC );if (mpclk) {/* take 1 / 0.9, since mbps must big than bandwidth of RGB */ tmp = mpclk * (bpp / dsi->lanes) *10 /9 ;
@@ -742,43 +743,44 @@ static void dw_mipi_dsi_command_mode_config(struct dw_mipi_dsi *dsi)/* Get lane byte clock cycles. */ static u32 dw_mipi_dsi_get_hcomponent_lbcc (struct dw_mipi_dsi *dsi, +struct drm_display_mode *mode,u32 hcomponent) {u32 frac, lbcc; lbcc = hcomponent * dsi->lane_mbps *MSEC_PER_SEC /8 ; - frac = lbcc % dsi->mode->clock; - lbcc = lbcc / dsi->mode->clock; + frac = lbcc % mode->clock; + lbcc = lbcc / mode->clock;if (frac) lbcc++;return lbcc; } -static void dw_mipi_dsi_line_timer_config (struct dw_mipi_dsi *dsi) +static void dw_mipi_dsi_line_timer_config (struct dw_mipi_dsi *dsi, +struct drm_display_mode *mode) {u32 htotal, hsa, hbp, lbcc; -struct drm_display_mode *mode = dsi->mode; htotal = mode->htotal; hsa = mode->hsync_end - mode->hsync_start; hbp = mode->htotal - mode->hsync_end; - lbcc =dw_mipi_dsi_get_hcomponent_lbcc (dsi, htotal); + lbcc =dw_mipi_dsi_get_hcomponent_lbcc (dsi, mode, htotal);dsi_write (dsi,DSI_VID_HLINE_TIME , lbcc); - lbcc =dw_mipi_dsi_get_hcomponent_lbcc (dsi, hsa); + lbcc =dw_mipi_dsi_get_hcomponent_lbcc (dsi, mode, hsa);dsi_write (dsi,DSI_VID_HSA_TIME , lbcc); - lbcc =dw_mipi_dsi_get_hcomponent_lbcc (dsi, hbp); + lbcc =dw_mipi_dsi_get_hcomponent_lbcc (dsi, mode, hbp);dsi_write (dsi,DSI_VID_HBP_TIME , lbcc); } -static void dw_mipi_dsi_vertical_timing_config (struct dw_mipi_dsi *dsi) +static void dw_mipi_dsi_vertical_timing_config (struct dw_mipi_dsi *dsi, +struct drm_display_mode *mode) {u32 vactive, vsa, vfp, vbp; -struct drm_display_mode *mode = dsi->mode; vactive = mode->vdisplay; vsa = mode->vsync_end - mode->vsync_start;
@@ -852,11 +854,12 @@ static void dw_mipi_dsi_encoder_disable(struct drm_encoder *encoder)static void dw_mipi_dsi_encoder_enable (struct drm_encoder *encoder) {struct dw_mipi_dsi *dsi =encoder_to_dsi (encoder); +struct drm_display_mode *mode = dsi->mode;int mux =drm_of_encoder_active_endpoint_id (dsi->dev->of_node, encoder);u32 val;int ret; - ret =dw_mipi_dsi_get_lane_bps (dsi); + ret =dw_mipi_dsi_get_lane_bps (dsi, mode);if (ret <0 )return ;
@@ -866,13 +869,13 @@ static void dw_mipi_dsi_encoder_enable(struct drm_encoder *encoder) }dw_mipi_dsi_init (dsi); -dw_mipi_dsi_dpi_config (dsi, dsi->mode); +dw_mipi_dsi_dpi_config (dsi, mode);dw_mipi_dsi_packet_handler_config (dsi);dw_mipi_dsi_video_mode_config (dsi); -dw_mipi_dsi_video_packet_config (dsi, dsi->mode); +dw_mipi_dsi_video_packet_config (dsi, mode);dw_mipi_dsi_command_mode_config (dsi); -dw_mipi_dsi_line_timer_config (dsi); -dw_mipi_dsi_vertical_timing_config (dsi); +dw_mipi_dsi_line_timer_config (dsi, mode); +dw_mipi_dsi_vertical_timing_config (dsi, mode);dw_mipi_dsi_dphy_timing_config (dsi);dw_mipi_dsi_dphy_interface_config (dsi);dw_mipi_dsi_clear_err (dsi);
@@ -880,7 +883,7 @@ static void dw_mipi_dsi_encoder_enable(struct drm_encoder *encoder)dev_err (dsi->dev,"failed to prepare panel\n" );dw_mipi_dsi_phy_init (dsi); -dw_mipi_dsi_wait_for_two_frames (dsi); +dw_mipi_dsi_wait_for_two_frames (mode);dw_mipi_dsi_set_mode (dsi,DW_MIPI_DSI_VID_MODE );drm_panel_enable (dsi->panel);
Signature · 1 line
2.11.0.197.gb556de5.dirty
Re: [PATCH v3 02/24] drm/rockchip: dw-mipi-dsi: pass mode in where needed
Quoted 4 lines · John Keeping
This shows that we only use the mode from the enable function and prepares us to remove the "mode" field and the
mode_sethook in the next commit.
Quoted 149 lines
Signed-off-by John Keeping <[email protected]>Reviewed-by Chris Zhong <[email protected]>---
v3:
- Add Chris' Reviewed-by
New in v2drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 41 ++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 19 deletions(-)drivers/gpu/drm/rockchip/dw-mipi-dsi.c +22
-19@@ -330,11 +330,11 @@ static int max_mbps_to_testdin(unsigned int max_mbps)* The controller should generate 2 frames before * preparing the peripheral. */ -static void dw_mipi_dsi_wait_for_two_frames (struct dw_mipi_dsi *dsi) +static void dw_mipi_dsi_wait_for_two_frames (struct drm_display_mode *mode) {int refresh, two_frames; - refresh =drm_mode_vrefresh (dsi->mode); + refresh =drm_mode_vrefresh (mode); two_frames =DIV_ROUND_UP (MSEC_PER_SEC , refresh) *2 ;msleep (two_frames); }@@ -459,7 +459,8 @@ static int dw_mipi_dsi_phy_init(struct dw_mipi_dsi *dsi)return ret; } -static int dw_mipi_dsi_get_lane_bps (struct dw_mipi_dsi *dsi) +static int dw_mipi_dsi_get_lane_bps (struct dw_mipi_dsi *dsi, +struct drm_display_mode *mode) {unsigned int i, pre;unsigned long mpclk, pllref, tmp;@@ -474,7 +475,7 @@ static int dw_mipi_dsi_get_lane_bps(struct dw_mipi_dsi *dsi)return bpp; } - mpclk =DIV_ROUND_UP (dsi->mode->clock,MSEC_PER_SEC ); + mpclk =DIV_ROUND_UP (mode->clock,MSEC_PER_SEC );if (mpclk) {/* take 1 / 0.9, since mbps must big than bandwidth of RGB */ tmp = mpclk * (bpp / dsi->lanes) *10 /9 ;@@ -742,43 +743,44 @@ static void dw_mipi_dsi_command_mode_config(struct dw_mipi_dsi *dsi)/* Get lane byte clock cycles. */ static u32 dw_mipi_dsi_get_hcomponent_lbcc (struct dw_mipi_dsi *dsi, +struct drm_display_mode *mode,u32 hcomponent) {u32 frac, lbcc; lbcc = hcomponent * dsi->lane_mbps *MSEC_PER_SEC /8 ; - frac = lbcc % dsi->mode->clock; - lbcc = lbcc / dsi->mode->clock; + frac = lbcc % mode->clock; + lbcc = lbcc / mode->clock;if (frac) lbcc++;return lbcc; } -static void dw_mipi_dsi_line_timer_config (struct dw_mipi_dsi *dsi) +static void dw_mipi_dsi_line_timer_config (struct dw_mipi_dsi *dsi, +struct drm_display_mode *mode) {u32 htotal, hsa, hbp, lbcc; -struct drm_display_mode *mode = dsi->mode; htotal = mode->htotal; hsa = mode->hsync_end - mode->hsync_start; hbp = mode->htotal - mode->hsync_end; - lbcc =dw_mipi_dsi_get_hcomponent_lbcc (dsi, htotal); + lbcc =dw_mipi_dsi_get_hcomponent_lbcc (dsi, mode, htotal);dsi_write (dsi,DSI_VID_HLINE_TIME , lbcc); - lbcc =dw_mipi_dsi_get_hcomponent_lbcc (dsi, hsa); + lbcc =dw_mipi_dsi_get_hcomponent_lbcc (dsi, mode, hsa);dsi_write (dsi,DSI_VID_HSA_TIME , lbcc); - lbcc =dw_mipi_dsi_get_hcomponent_lbcc (dsi, hbp); + lbcc =dw_mipi_dsi_get_hcomponent_lbcc (dsi, mode, hbp);dsi_write (dsi,DSI_VID_HBP_TIME , lbcc); } -static void dw_mipi_dsi_vertical_timing_config (struct dw_mipi_dsi *dsi) +static void dw_mipi_dsi_vertical_timing_config (struct dw_mipi_dsi *dsi, +struct drm_display_mode *mode) {u32 vactive, vsa, vfp, vbp; -struct drm_display_mode *mode = dsi->mode; vactive = mode->vdisplay; vsa = mode->vsync_end - mode->vsync_start;@@ -852,11 +854,12 @@ static void dw_mipi_dsi_encoder_disable(struct drm_encoder *encoder)static void dw_mipi_dsi_encoder_enable (struct drm_encoder *encoder) {struct dw_mipi_dsi *dsi =encoder_to_dsi (encoder); +struct drm_display_mode *mode = dsi->mode;int mux =drm_of_encoder_active_endpoint_id (dsi->dev->of_node, encoder);u32 val;int ret; - ret =dw_mipi_dsi_get_lane_bps (dsi); + ret =dw_mipi_dsi_get_lane_bps (dsi, mode);if (ret <0 )return ;@@ -866,13 +869,13 @@ static void dw_mipi_dsi_encoder_enable(struct drm_encoder *encoder) }dw_mipi_dsi_init (dsi); -dw_mipi_dsi_dpi_config (dsi, dsi->mode); +dw_mipi_dsi_dpi_config (dsi, mode);dw_mipi_dsi_packet_handler_config (dsi);dw_mipi_dsi_video_mode_config (dsi); -dw_mipi_dsi_video_packet_config (dsi, dsi->mode); +dw_mipi_dsi_video_packet_config (dsi, mode);dw_mipi_dsi_command_mode_config (dsi); -dw_mipi_dsi_line_timer_config (dsi); -dw_mipi_dsi_vertical_timing_config (dsi); +dw_mipi_dsi_line_timer_config (dsi, mode); +dw_mipi_dsi_vertical_timing_config (dsi, mode);dw_mipi_dsi_dphy_timing_config (dsi);dw_mipi_dsi_dphy_interface_config (dsi);dw_mipi_dsi_clear_err (dsi);@@ -880,7 +883,7 @@ static void dw_mipi_dsi_encoder_enable(struct drm_encoder *encoder)dev_err (dsi->dev,"failed to prepare panel\n" );dw_mipi_dsi_phy_init (dsi); -dw_mipi_dsi_wait_for_two_frames (dsi); +dw_mipi_dsi_wait_for_two_frames (mode);dw_mipi_dsi_set_mode (dsi,DW_MIPI_DSI_VID_MODE );drm_panel_enable (dsi->panel);Signature · 6 lines
2.11.0.197.gb556de5.dirty _______________________________________________ dri-devel mailing list dri-devel at lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Signature · 1 line
Sean Paul, Software Engineer, Google / Chromium OS
PATCH v3 3/24 drm/rockchip: dw-mipi-dsi: remove mode_set hook
In reply to John KeepingThis is not needed since we can access the mode via the CRTC from the enable hook. Also remove the "mode" field that is no longer used.
---
v3:
- Add Chris' Reviewed-by
New in v2
drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-)
drivers/gpu/drm/rockchip/dw-mipi-dsi.c +1 -12
@@ -286,7 +286,6 @@ struct dw_mipi_dsi {u32 format;u16 input_div;u16 feedback_div; -struct drm_display_mode *mode;const struct dw_mipi_dsi_plat_data *pdata; };
@@ -816,15 +815,6 @@ static void dw_mipi_dsi_clear_err(struct dw_mipi_dsi *dsi)dsi_write (dsi,DSI_INT_MSK1 ,0 ); } -static void dw_mipi_dsi_encoder_mode_set (struct drm_encoder *encoder, -struct drm_display_mode *mode, -struct drm_display_mode *adjusted_mode) -{ -struct dw_mipi_dsi *dsi =encoder_to_dsi (encoder); - - dsi->mode = adjusted_mode; -} -static void dw_mipi_dsi_encoder_disable (struct drm_encoder *encoder) {struct dw_mipi_dsi *dsi =encoder_to_dsi (encoder);
@@ -854,7 +844,7 @@ static void dw_mipi_dsi_encoder_disable(struct drm_encoder *encoder)static void dw_mipi_dsi_encoder_enable (struct drm_encoder *encoder) {struct dw_mipi_dsi *dsi =encoder_to_dsi (encoder); -struct drm_display_mode *mode = dsi->mode; +struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode;int mux =drm_of_encoder_active_endpoint_id (dsi->dev->of_node, encoder);u32 val;int ret;
@@ -930,7 +920,6 @@ dw_mipi_dsi_encoder_atomic_check(struct drm_encoder *encoder,static struct drm_encoder_helper_funcs dw_mipi_dsi_encoder_helper_funcs = { .enable = dw_mipi_dsi_encoder_enable, - .mode_set = dw_mipi_dsi_encoder_mode_set, .disable = dw_mipi_dsi_encoder_disable, .atomic_check = dw_mipi_dsi_encoder_atomic_check, };
Signature · 1 line
2.11.0.197.gb556de5.dirty
Re: [PATCH v3 03/24] drm/rockchip: dw-mipi-dsi: remove mode_set hook
Quoted 3 lines · John Keeping
This is not needed since we can access the mode via the CRTC from the enable hook. Also remove the "mode" field that is no longer used.
Quoted 62 lines
Signed-off-by John Keeping <[email protected]>Reviewed-by Chris Zhong <[email protected]>---
v3:
- Add Chris' Reviewed-by
New in v2drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-)drivers/gpu/drm/rockchip/dw-mipi-dsi.c +1
-12@@ -286,7 +286,6 @@ struct dw_mipi_dsi {u32 format;u16 input_div;u16 feedback_div; -struct drm_display_mode *mode;const struct dw_mipi_dsi_plat_data *pdata; };@@ -816,15 +815,6 @@ static void dw_mipi_dsi_clear_err(struct dw_mipi_dsi *dsi)dsi_write (dsi,DSI_INT_MSK1 ,0 ); } -static void dw_mipi_dsi_encoder_mode_set (struct drm_encoder *encoder, -struct drm_display_mode *mode, -struct drm_display_mode *adjusted_mode) -{ -struct dw_mipi_dsi *dsi =encoder_to_dsi (encoder); - - dsi->mode = adjusted_mode; -} -static void dw_mipi_dsi_encoder_disable (struct drm_encoder *encoder) {struct dw_mipi_dsi *dsi =encoder_to_dsi (encoder);@@ -854,7 +844,7 @@ static void dw_mipi_dsi_encoder_disable(struct drm_encoder *encoder)static void dw_mipi_dsi_encoder_enable (struct drm_encoder *encoder) {struct dw_mipi_dsi *dsi =encoder_to_dsi (encoder); -struct drm_display_mode *mode = dsi->mode; +struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode;int mux =drm_of_encoder_active_endpoint_id (dsi->dev->of_node, encoder);u32 val;int ret;@@ -930,7 +920,6 @@ dw_mipi_dsi_encoder_atomic_check(struct drm_encoder *encoder,static struct drm_encoder_helper_funcs dw_mipi_dsi_encoder_helper_funcs = { .enable = dw_mipi_dsi_encoder_enable, - .mode_set = dw_mipi_dsi_encoder_mode_set, .disable = dw_mipi_dsi_encoder_disable, .atomic_check = dw_mipi_dsi_encoder_atomic_check, };Signature · 6 lines
2.11.0.197.gb556de5.dirty _______________________________________________ dri-devel mailing list dri-devel at lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Signature · 1 line
Sean Paul, Software Engineer, Google / Chromium OS
PATCH v3 4/24 drm/rockchip: dw-mipi-dsi: fix command header writes
In reply to John KeepingIn a couple of places here we use "val" for the value that is about to be written to a register but then reuse the same variable for the value of a status register before we get around to writing it. Rename the value to be written to so that we write the value we intend to and not what we have just read from the status register.
---
Unchanged in v3
Unchanged in v2
drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
drivers/gpu/drm/rockchip/dw-mipi-dsi.c +6 -4
@@ -542,9 +542,10 @@ static int dw_mipi_dsi_host_detach(struct mipi_dsi_host *host,return 0 ; } -static int dw_mipi_dsi_gen_pkt_hdr_write (struct dw_mipi_dsi *dsi,u32 val) +static int dw_mipi_dsi_gen_pkt_hdr_write (struct dw_mipi_dsi *dsi,u32 hdr_val) {int ret; +u32 val; ret = readx_poll_timeout(readl, dsi->base + DSI_CMD_PKT_STATUS, val, !(val & GEN_CMD_FULL), 1000,
@@ -554,7 +555,7 @@ static int dw_mipi_dsi_gen_pkt_hdr_write(struct dw_mipi_dsi *dsi, u32 val)return ret; } -dsi_write (dsi,DSI_GEN_HDR , val); +dsi_write (dsi,DSI_GEN_HDR , hdr_val); ret = readx_poll_timeout(readl, dsi->base + DSI_CMD_PKT_STATUS, val, val & (GEN_CMD_EMPTY | GEN_PLD_W_EMPTY),
@@ -587,8 +588,9 @@ static int dw_mipi_dsi_dcs_long_write(struct dw_mipi_dsi *dsi, {const u32 *tx_buf = msg->tx_buf;int len = msg->tx_len, pld_data_bytes =sizeof (*tx_buf), ret; -u32 val =GEN_HDATA (msg->tx_len) |GEN_HTYPE (msg->type); +u32 hdr_val =GEN_HDATA (msg->tx_len) |GEN_HTYPE (msg->type);u32 remainder =0 ; +u32 val;if (msg->tx_len <3 ) { dev_err(dsi->dev, "wrong tx buf length %zu for long write\n",
@@ -617,7 +619,7 @@ static int dw_mipi_dsi_dcs_long_write(struct dw_mipi_dsi *dsi, } } -return dw_mipi_dsi_gen_pkt_hdr_write (dsi, val); +return dw_mipi_dsi_gen_pkt_hdr_write (dsi, hdr_val); } static ssize_t dw_mipi_dsi_host_transfer(struct mipi_dsi_host *host,
Signature · 1 line
2.11.0.197.gb556de5.dirty
Re: [PATCH v3 04/24] drm/rockchip: dw-mipi-dsi: fix command header writes
Quoted 6 lines · John Keeping
In a couple of places here we use "val" for the value that is about to be written to a register but then reuse the same variable for the value of a status register before we get around to writing it. Rename the value to be written to so that we write the value we intend to and not what we have just read from the status register.
Oh my.
Quoted 62 lines
Signed-off-by John Keeping <[email protected]>Tested-by Chris Zhong <[email protected]>Reviewed-by Chris Zhong <[email protected]>---
Unchanged in v3
Unchanged in v2drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)drivers/gpu/drm/rockchip/dw-mipi-dsi.c +6
-4@@ -542,9 +542,10 @@ static int dw_mipi_dsi_host_detach(struct mipi_dsi_host *host,return 0 ; } -static int dw_mipi_dsi_gen_pkt_hdr_write (struct dw_mipi_dsi *dsi,u32 val) +static int dw_mipi_dsi_gen_pkt_hdr_write (struct dw_mipi_dsi *dsi,u32 hdr_val) {int ret; +u32 val; ret = readx_poll_timeout(readl, dsi->base + DSI_CMD_PKT_STATUS, val, !(val & GEN_CMD_FULL), 1000,@@ -554,7 +555,7 @@ static int dw_mipi_dsi_gen_pkt_hdr_write(struct dw_mipi_dsi *dsi, u32 val)return ret; } -dsi_write (dsi,DSI_GEN_HDR , val); +dsi_write (dsi,DSI_GEN_HDR , hdr_val); ret = readx_poll_timeout(readl, dsi->base + DSI_CMD_PKT_STATUS, val, val & (GEN_CMD_EMPTY | GEN_PLD_W_EMPTY),@@ -587,8 +588,9 @@ static int dw_mipi_dsi_dcs_long_write(struct dw_mipi_dsi *dsi, {const u32 *tx_buf = msg->tx_buf;int len = msg->tx_len, pld_data_bytes =sizeof (*tx_buf), ret; -u32 val =GEN_HDATA (msg->tx_len) |GEN_HTYPE (msg->type); +u32 hdr_val =GEN_HDATA (msg->tx_len) |GEN_HTYPE (msg->type);u32 remainder =0 ; +u32 val;if (msg->tx_len <3 ) { dev_err(dsi->dev, "wrong tx buf length %zu for long write\n",@@ -617,7 +619,7 @@ static int dw_mipi_dsi_dcs_long_write(struct dw_mipi_dsi *dsi, } } -return dw_mipi_dsi_gen_pkt_hdr_write (dsi, val); +return dw_mipi_dsi_gen_pkt_hdr_write (dsi, hdr_val); } static ssize_t dw_mipi_dsi_host_transfer(struct mipi_dsi_host *host,Signature · 6 lines
2.11.0.197.gb556de5.dirty _______________________________________________ dri-devel mailing list dri-devel at lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Signature · 1 line
Sean Paul, Software Engineer, Google / Chromium OS
PATCH v3 5/24 drm/rockchip: dw-mipi-dsi: fix generic packet status check
In reply to John KeepingWe want to check that both the GEN_CMD_EMPTY and GEN_PLD_W_EMPTY bits are set so we can't just check "val & mask" because that will be true if either bit is set.
---
v3:
- Add Chris' Reviewed-by
Unchanged in v2
drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/gpu/drm/rockchip/dw-mipi-dsi.c +3 -2
@@ -545,7 +545,7 @@ static int dw_mipi_dsi_host_detach(struct mipi_dsi_host *host,static int dw_mipi_dsi_gen_pkt_hdr_write (struct dw_mipi_dsi *dsi,u32 hdr_val) {int ret; -u32 val; +u32 val, mask; ret = readx_poll_timeout(readl, dsi->base + DSI_CMD_PKT_STATUS, val, !(val & GEN_CMD_FULL), 1000,
@@ -557,8 +557,9 @@ static int dw_mipi_dsi_gen_pkt_hdr_write(struct dw_mipi_dsi *dsi, u32 hdr_val)dsi_write (dsi,DSI_GEN_HDR , hdr_val); + mask =GEN_CMD_EMPTY |GEN_PLD_W_EMPTY ; ret =readx_poll_timeout (readl, dsi->base +DSI_CMD_PKT_STATUS , - val, val & (GEN_CMD_EMPTY |GEN_PLD_W_EMPTY ), + val, (val & mask) == mask,1000 ,CMD_PKT_STATUS_TIMEOUT_US );if (ret <0 ) {dev_err (dsi->dev,"failed to write command FIFO\n" );
Signature · 1 line
2.11.0.197.gb556de5.dirty
Re: [PATCH v3 05/24] drm/rockchip: dw-mipi-dsi: fix generic packet status check
Quoted 4 lines · John Keeping
We want to check that both the
GEN_CMD_EMPTYandGEN_PLD_W_EMPTYbits are set so we can't just check "val & mask" because that will be true if either bit is set.
Quoted 41 lines
Signed-off-by John Keeping <[email protected]>Reviewed-by Chris Zhong <[email protected]>---
v3:
- Add Chris' Reviewed-by
Unchanged in v2drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)drivers/gpu/drm/rockchip/dw-mipi-dsi.c +3
-2@@ -545,7 +545,7 @@ static int dw_mipi_dsi_host_detach(struct mipi_dsi_host *host,static int dw_mipi_dsi_gen_pkt_hdr_write (struct dw_mipi_dsi *dsi,u32 hdr_val) {int ret; -u32 val; +u32 val, mask; ret = readx_poll_timeout(readl, dsi->base + DSI_CMD_PKT_STATUS, val, !(val & GEN_CMD_FULL), 1000,@@ -557,8 +557,9 @@ static int dw_mipi_dsi_gen_pkt_hdr_write(struct dw_mipi_dsi *dsi, u32 hdr_val)dsi_write (dsi,DSI_GEN_HDR , hdr_val); + mask =GEN_CMD_EMPTY |GEN_PLD_W_EMPTY ; ret =readx_poll_timeout (readl, dsi->base +DSI_CMD_PKT_STATUS , - val, val & (GEN_CMD_EMPTY |GEN_PLD_W_EMPTY ), + val, (val & mask) == mask,1000 ,CMD_PKT_STATUS_TIMEOUT_US );if (ret <0 ) {dev_err (dsi->dev,"failed to write command FIFO\n" );Signature · 6 lines
2.11.0.197.gb556de5.dirty _______________________________________________ dri-devel mailing list dri-devel at lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Signature · 1 line
Sean Paul, Software Engineer, Google / Chromium OS
PATCH v3 6/24 drm/rockchip: dw-mipi-dsi: avoid out-of-bounds read on tx_buf
In reply to John KeepingAs a side-effect of this, encode the endianness explicitly rather than casting a u16.
---
v3:
- Add Chris' Reviewed-by
Unchanged in v2
drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
drivers/gpu/drm/rockchip/dw-mipi-dsi.c +7 -2
@@ -572,8 +572,13 @@ static int dw_mipi_dsi_gen_pkt_hdr_write(struct dw_mipi_dsi *dsi, u32 hdr_val)static int dw_mipi_dsi_dcs_short_write (struct dw_mipi_dsi *dsi,const struct mipi_dsi_msg *msg) { -const u16 *tx_buf = msg->tx_buf; -u32 val =GEN_HDATA (*tx_buf) |GEN_HTYPE (msg->type); +const u8 *tx_buf = msg->tx_buf; +u32 val =GEN_HTYPE (msg->type); + +if (msg->tx_len >0 ) + val |=GEN_HDATA (tx_buf[0 ]); +if (msg->tx_len >1 ) + val |=GEN_HDATA (tx_buf[1 ] <<8 );if (msg->tx_len >2 ) { dev_err(dsi->dev, "too long tx buf length %zu for short write\n",
Signature · 1 line
2.11.0.197.gb556de5.dirty
Re: [PATCH v3 06/24] drm/rockchip: dw-mipi-dsi: avoid out-of-bounds read on tx_buf
Quoted 20 lines · John Keeping
As a side-effect of this, encode the endianness explicitly rather than casting a u16.
Signed-off-by John Keeping <[email protected]>Reviewed-by Chris Zhong <[email protected]>---
v3:
- Add Chris' Reviewed-by
Unchanged in v2drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)drivers/gpu/drm/rockchip/dw-mipi-dsi.c +0
-0@@ -572,8 +572,13 @@ static int dw_mipi_dsi_gen_pkt_hdr_write(struct dw_mipi_dsi *dsi, u32 hdr_val)static int dw_mipi_dsi_dcs_short_write (struct dw_mipi_dsi *dsi,const struct mipi_dsi_msg *msg)
drivers/gpu/drm/rockchip/dw-mipi-dsi.c static int dw_mipi_dsi_gen_pkt_hdr_write(struct dw_mipi_dsi *dsi, u32 hdr_val) · line 581
Quoted 10 lines
drivers/gpu/drm/rockchip/dw-mipi-dsi.c +7
-2{ -const u16 *tx_buf = msg->tx_buf; -u32 val =GEN_HDATA (*tx_buf) |GEN_HTYPE (msg->type); +const u8 *tx_buf = msg->tx_buf; +u32 val =GEN_HTYPE (msg->type); + +if (msg->tx_len >0 ) + val |=GEN_HDATA (tx_buf[0 ]); +if (msg->tx_len >1 ) + val |=GEN_HDATA (tx_buf[1 ] <<8 );
You should probably update the mask inside GEN_HDATA to mask off 8 bits instead of 16.
Sean
Quoted 10 lines
drivers/gpu/drm/rockchip/dw-mipi-dsi.c +0
-0if (msg->tx_len >2 ) { dev_err(dsi->dev, "too long tx buf length %zu for short write\n",Signature · 6 lines
2.11.0.197.gb556de5.dirty _______________________________________________ dri-devel mailing list dri-devel at lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Signature · 1 line
Sean Paul, Software Engineer, Google / Chromium OS
Re: [PATCH v3 06/24] drm/rockchip: dw-mipi-dsi: avoid out-of-bounds read on tx_buf
Quoted 26 lines · Sean Paul
Quoted 25 lines · John Keeping
As a side-effect of this, encode the endianness explicitly rather than casting a u16.
Signed-off-by John Keeping <[email protected]>Reviewed-by Chris Zhong <[email protected]>---
v3:
- Add Chris' Reviewed-by
Unchanged in v2drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)drivers/gpu/drm/rockchip/dw-mipi-dsi.c +2
-2@@ -572,8 +572,13 @@ static int dw_mipi_dsi_gen_pkt_hdr_write(struct dw_mipi_dsi *dsi, u32 hdr_val)static int dw_mipi_dsi_dcs_short_write (struct dw_mipi_dsi *dsi,const struct mipi_dsi_msg *msg) { -const u16 *tx_buf = msg->tx_buf; -u32 val =GEN_HDATA (*tx_buf) |GEN_HTYPE (msg->type); +const u8 *tx_buf = msg->tx_buf; +u32 val =GEN_HTYPE (msg->type);
Quoted 8 lines
drivers/gpu/drm/rockchip/dw-mipi-dsi.c static int dw_mipi_dsi_gen_pkt_hdr_write(struct dw_mipi_dsi *dsi, u32 hdr_val) · line 581
Quoted 5 lines
drivers/gpu/drm/rockchip/dw-mipi-dsi.c +5
-0+ +if (msg->tx_len >0 ) + val |=GEN_HDATA (tx_buf[0 ]); +if (msg->tx_len >1 ) + val |=GEN_HDATA (tx_buf[1 ] <<8 );You should probably update the mask inside
GEN_HDATAto mask off 8 bits instead of 16.
Won't that mask off the data written by "tx_buf[1] << 8"?
Re: [PATCH v3 06/24] drm/rockchip: dw-mipi-dsi: avoid out-of-bounds read on tx_buf
Quoted 37 lines · John Keeping
Quoted 26 lines · Sean Paul
Quoted 25 lines · John Keeping
As a side-effect of this, encode the endianness explicitly rather than casting a u16.
Signed-off-by John Keeping <[email protected]>Reviewed-by Chris Zhong <[email protected]>---
v3:
- Add Chris' Reviewed-by
Unchanged in v2drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)drivers/gpu/drm/rockchip/dw-mipi-dsi.c +2
-2@@ -572,8 +572,13 @@ static int dw_mipi_dsi_gen_pkt_hdr_write(struct dw_mipi_dsi *dsi, u32 hdr_val)static int dw_mipi_dsi_dcs_short_write (struct dw_mipi_dsi *dsi,const struct mipi_dsi_msg *msg) { -const u16 *tx_buf = msg->tx_buf; -u32 val =GEN_HDATA (*tx_buf) |GEN_HTYPE (msg->type); +const u8 *tx_buf = msg->tx_buf; +u32 val =GEN_HTYPE (msg->type);Quoted 8 lines
drivers/gpu/drm/rockchip/dw-mipi-dsi.c static int dw_mipi_dsi_gen_pkt_hdr_write(struct dw_mipi_dsi *dsi, u32 hdr_val) · line 581
Quoted 5 lines
drivers/gpu/drm/rockchip/dw-mipi-dsi.c +5
-0+ +if (msg->tx_len >0 ) + val |=GEN_HDATA (tx_buf[0 ]); +if (msg->tx_len >1 ) + val |=GEN_HDATA (tx_buf[1 ] <<8 );You should probably update the mask inside
GEN_HDATAto mask off 8 bits instead of 16.
Quoted 1 line
Won't that mask off the data written by "tx_buf[1] << 8"?
I would move the shift outside the mask, ie:
val |= GEN_HDATA(tx_buf[1]) << 8;
Sean
Quoted 4 lines
_______________________________________________
dri-devel mailing list
dri-devel at lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
Signature · 1 line
Sean Paul, Software Engineer, Google / Chromium OS
Re: [PATCH v3 06/24] drm/rockchip: dw-mipi-dsi: avoid out-of-bounds read on tx_buf
Quoted 38 lines · Sean Paul
Quoted 37 lines · John Keeping
Quoted 34 lines · Sean Paul
Quoted 20 lines · John Keeping
As a side-effect of this, encode the endianness explicitly rather than casting a u16.
Signed-off-by John Keeping <[email protected]>Reviewed-by Chris Zhong <[email protected]>---
v3:
- Add Chris' Reviewed-by
Unchanged in v2drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)drivers/gpu/drm/rockchip/dw-mipi-dsi.c +0
-0@@ -572,8 +572,13 @@ static int dw_mipi_dsi_gen_pkt_hdr_write(struct dw_mipi_dsi *dsi, u32 hdr_val)static int dw_mipi_dsi_dcs_short_write (struct dw_mipi_dsi *dsi,const struct mipi_dsi_msg *msg)drivers/gpu/drm/rockchip/dw-mipi-dsi.c static int dw_mipi_dsi_gen_pkt_hdr_write(struct dw_mipi_dsi *dsi, u32 hdr_val) · line 581
Quoted 10 lines
drivers/gpu/drm/rockchip/dw-mipi-dsi.c +7
-2{ -const u16 *tx_buf = msg->tx_buf; -u32 val =GEN_HDATA (*tx_buf) |GEN_HTYPE (msg->type); +const u8 *tx_buf = msg->tx_buf; +u32 val =GEN_HTYPE (msg->type); + +if (msg->tx_len >0 ) + val |=GEN_HDATA (tx_buf[0 ]); +if (msg->tx_len >1 ) + val |=GEN_HDATA (tx_buf[1 ] <<8 );You should probably update the mask inside
GEN_HDATAto mask off 8 bits instead of 16.
Quoted 5 lines
Quoted 1 line
Won't that mask off the data written by "tx_buf[1] << 8"?
I would move the shift outside the mask, ie:
val |=
GEN_HDATA(tx_buf[1])<< 8;
I can do that, but that doesn't seem to match the intention of the macros which are about encoding the placement and size of fields within registers.
Maybe it would be clearer to do:
u16 data = 0;
if (msg->tx_len > 0)
data |= tx_buf[0];
if (msg->tx_len > 1)
data |= tx_buf[1];
val = GEN_HDATA(data) | GEN_HTYPE(msg->type);?
Re: [PATCH v3 06/24] drm/rockchip: dw-mipi-dsi: avoid out-of-bounds read on tx_buf
Quoted 50 lines · John Keeping
Quoted 38 lines · Sean Paul
Quoted 37 lines · John Keeping
Quoted 34 lines · Sean Paul
Quoted 20 lines · John Keeping
As a side-effect of this, encode the endianness explicitly rather than casting a u16.
Signed-off-by John Keeping <[email protected]>Reviewed-by Chris Zhong <[email protected]>---
v3:
- Add Chris' Reviewed-by
Unchanged in v2drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)drivers/gpu/drm/rockchip/dw-mipi-dsi.c +0
-0@@ -572,8 +572,13 @@ static int dw_mipi_dsi_gen_pkt_hdr_write(struct dw_mipi_dsi *dsi, u32 hdr_val)static int dw_mipi_dsi_dcs_short_write (struct dw_mipi_dsi *dsi,const struct mipi_dsi_msg *msg)drivers/gpu/drm/rockchip/dw-mipi-dsi.c static int dw_mipi_dsi_gen_pkt_hdr_write(struct dw_mipi_dsi *dsi, u32 hdr_val) · line 581
Quoted 10 lines
drivers/gpu/drm/rockchip/dw-mipi-dsi.c +7
-2{ -const u16 *tx_buf = msg->tx_buf; -u32 val =GEN_HDATA (*tx_buf) |GEN_HTYPE (msg->type); +const u8 *tx_buf = msg->tx_buf; +u32 val =GEN_HTYPE (msg->type); + +if (msg->tx_len >0 ) + val |=GEN_HDATA (tx_buf[0 ]); +if (msg->tx_len >1 ) + val |=GEN_HDATA (tx_buf[1 ] <<8 );You should probably update the mask inside
GEN_HDATAto mask off 8 bits instead of 16.Quoted 5 lines
Quoted 1 line
Won't that mask off the data written by "tx_buf[1] << 8"?
I would move the shift outside the mask, ie:
val |=
GEN_HDATA(tx_buf[1])<< 8;I can do that, but that doesn't seem to match the intention of the macros which are about encoding the placement and size of fields within registers.
Quoted 8 lines
Maybe it would be clearer to do:
u16 data = 0; if (msg->tx_len > 0) data |= tx_buf[0]; if (msg->tx_len > 1) data |= tx_buf[1];
Yep, this looks good to me, but I think you need:
data |= tx_buf[1] << 8;
Sean
Quoted 8 lines
val = GEN_HDATA(data) | GEN_HTYPE(msg->type);?
_______________________________________________
dri-devel mailing list
dri-devel at lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
Signature · 1 line
Sean Paul, Software Engineer, Google / Chromium OS
PATCH v3 7/24 drm/rockchip: dw-mipi-dsi: include bad value in error message
In reply to John KeepingAs an aid to debugging.
---
v3:
- Add Chris' Reviewed-by
Unchanged in v2
drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/gpu/drm/rockchip/dw-mipi-dsi.c +2 -1
@@ -644,7 +644,8 @@ static ssize_t dw_mipi_dsi_host_transfer(struct mipi_dsi_host *host, ret =dw_mipi_dsi_dcs_long_write (dsi, msg);break ;default : -dev_err (dsi->dev,"unsupported message type\n" ); +dev_err (dsi->dev,"unsupported message type 0x%02x\n" , + msg->type); ret = -EINVAL ; }
Signature · 1 line
2.11.0.197.gb556de5.dirty
Re: [PATCH v3 07/24] drm/rockchip: dw-mipi-dsi: include bad value in error message
Quoted 1 line · John Keeping
As an aid to debugging.
Quoted 32 lines
Signed-off-by John Keeping <[email protected]>Reviewed-by Chris Zhong <[email protected]>---
v3:
- Add Chris' Reviewed-by
Unchanged in v2drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)drivers/gpu/drm/rockchip/dw-mipi-dsi.c +2
-1@@ -644,7 +644,8 @@ static ssize_t dw_mipi_dsi_host_transfer(struct mipi_dsi_host *host, ret =dw_mipi_dsi_dcs_long_write (dsi, msg);break ;default : -dev_err (dsi->dev,"unsupported message type\n" ); +dev_err (dsi->dev,"unsupported message type 0x%02x\n" , + msg->type); ret = -EINVAL ; }Signature · 6 lines
2.11.0.197.gb556de5.dirty _______________________________________________ dri-devel mailing list dri-devel at lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Signature · 1 line
Sean Paul, Software Engineer, Google / Chromium OS
PATCH v3 8/24 drm/rockchip: dw-mipi-dsi: respect message flags
In reply to John KeepingInstead of always sending commands in LP mode, respect the MIPI_DSI_MSG_USE_LPM flag to decide how to send each message. Also request acks if MIPI_DSI_MSG_REQ_ACK is set.
---
v3:
- Add Chris' Reviewed-by
Unchanged in v2
drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-)
drivers/gpu/drm/rockchip/dw-mipi-dsi.c +15 -1
@@ -542,6 +542,19 @@ static int dw_mipi_dsi_host_detach(struct mipi_dsi_host *host,return 0 ; } +static void dw_mipi_message_config (struct dw_mipi_dsi *dsi, +const struct mipi_dsi_msg *msg) +{ +u32 val =0 ; + +if (msg->flags &MIPI_DSI_MSG_REQ_ACK ) + val |=EN_ACK_RQST ; +if (msg->flags &MIPI_DSI_MSG_USE_LPM ) + val |=CMD_MODE_ALL_LP ; + +dsi_write (dsi,DSI_CMD_MODE_CFG , val); +} +static int dw_mipi_dsi_gen_pkt_hdr_write (struct dw_mipi_dsi *dsi,u32 hdr_val) {int ret;
@@ -634,6 +647,8 @@ static ssize_t dw_mipi_dsi_host_transfer(struct mipi_dsi_host *host,struct dw_mipi_dsi *dsi =host_to_dsi (host);int ret; +dw_mipi_message_config (dsi, msg); +switch (msg->type) {case MIPI_DSI_DCS_SHORT_WRITE :case MIPI_DSI_DCS_SHORT_WRITE_PARAM :
@@ -745,7 +760,6 @@ static void dw_mipi_dsi_command_mode_config(struct dw_mipi_dsi *dsi) {dsi_write (dsi,DSI_TO_CNT_CFG ,HSTX_TO_CNT (1000 ) |LPRX_TO_CNT (1000 ));dsi_write (dsi,DSI_BTA_TO_CNT ,0xd00 ); -dsi_write (dsi,DSI_CMD_MODE_CFG ,CMD_MODE_ALL_LP );dsi_write (dsi,DSI_MODE_CFG ,ENABLE_CMD_MODE ); }
Signature · 1 line
2.11.0.197.gb556de5.dirty
Re: [PATCH v3 08/24] drm/rockchip: dw-mipi-dsi: respect message flags
Quoted 4 lines · John Keeping
Instead of always sending commands in LP mode, respect the
MIPI_DSI_MSG_USE_LPMflag to decide how to send each message. Also request acks ifMIPI_DSI_MSG_REQ_ACKis set.
Quoted 58 lines
Signed-off-by John Keeping <[email protected]>Reviewed-by Chris Zhong <[email protected]>---
v3:
- Add Chris' Reviewed-by
Unchanged in v2drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-)drivers/gpu/drm/rockchip/dw-mipi-dsi.c +15
-1@@ -542,6 +542,19 @@ static int dw_mipi_dsi_host_detach(struct mipi_dsi_host *host,return 0 ; } +static void dw_mipi_message_config (struct dw_mipi_dsi *dsi, +const struct mipi_dsi_msg *msg) +{ +u32 val =0 ; + +if (msg->flags &MIPI_DSI_MSG_REQ_ACK ) + val |=EN_ACK_RQST ; +if (msg->flags &MIPI_DSI_MSG_USE_LPM ) + val |=CMD_MODE_ALL_LP ; + +dsi_write (dsi,DSI_CMD_MODE_CFG , val); +} +static int dw_mipi_dsi_gen_pkt_hdr_write (struct dw_mipi_dsi *dsi,u32 hdr_val) {int ret;@@ -634,6 +647,8 @@ static ssize_t dw_mipi_dsi_host_transfer(struct mipi_dsi_host *host,struct dw_mipi_dsi *dsi =host_to_dsi (host);int ret; +dw_mipi_message_config (dsi, msg); +switch (msg->type) {case MIPI_DSI_DCS_SHORT_WRITE :case MIPI_DSI_DCS_SHORT_WRITE_PARAM :@@ -745,7 +760,6 @@ static void dw_mipi_dsi_command_mode_config(struct dw_mipi_dsi *dsi) {dsi_write (dsi,DSI_TO_CNT_CFG ,HSTX_TO_CNT (1000 ) |LPRX_TO_CNT (1000 ));dsi_write (dsi,DSI_BTA_TO_CNT ,0xd00 ); -dsi_write (dsi,DSI_CMD_MODE_CFG ,CMD_MODE_ALL_LP );dsi_write (dsi,DSI_MODE_CFG ,ENABLE_CMD_MODE ); }Signature · 6 lines
2.11.0.197.gb556de5.dirty _______________________________________________ dri-devel mailing list dri-devel at lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Signature · 1 line
Sean Paul, Software Engineer, Google / Chromium OS
PATCH v3 9/24 drm/rockchip: dw-mipi-dsi: only request HS clock when required
In reply to John KeepingRequesting the HS clock from the PHY before we initialize it causes an invalid signal to be sent out since the input clock is not yet configured. The PHY databook suggests only asserting this signal when performing HS transfers, so let's do that.
---
v3:
- Add Chris' Reviewed-by
Unchanged in v2
drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/gpu/drm/rockchip/dw-mipi-dsi.c +4 -2
@@ -545,13 +545,15 @@ static int dw_mipi_dsi_host_detach(struct mipi_dsi_host *host,static void dw_mipi_message_config (struct dw_mipi_dsi *dsi,const struct mipi_dsi_msg *msg) { +bool lpm = msg->flags &MIPI_DSI_MSG_USE_LPM ;u32 val =0 ;if (msg->flags &MIPI_DSI_MSG_REQ_ACK ) val |=EN_ACK_RQST ; -if (msg->flags &MIPI_DSI_MSG_USE_LPM ) +if (lpm) val |=CMD_MODE_ALL_LP ; +dsi_write (dsi,DSI_LPCLK_CTRL , lpm ?0 :PHY_TXREQUESTCLKHS );dsi_write (dsi,DSI_CMD_MODE_CFG , val); }
@@ -693,6 +695,7 @@ static void dw_mipi_dsi_set_mode(struct dw_mipi_dsi *dsi,dsi_write (dsi,DSI_PWR_UP ,RESET );dsi_write (dsi,DSI_MODE_CFG ,ENABLE_VIDEO_MODE );dw_mipi_dsi_video_mode_config (dsi); +dsi_write (dsi,DSI_LPCLK_CTRL ,PHY_TXREQUESTCLKHS );dsi_write (dsi,DSI_PWR_UP ,POWERUP ); } }
@@ -710,7 +713,6 @@ static void dw_mipi_dsi_init(struct dw_mipi_dsi *dsi) | PHY_RSTZ | PHY_SHUTDOWNZ);dsi_write (dsi,DSI_CLKMGR_CFG ,TO_CLK_DIVIDSION (10 ) |TX_ESC_CLK_DIVIDSION (7 )); -dsi_write (dsi,DSI_LPCLK_CTRL ,PHY_TXREQUESTCLKHS ); } static void dw_mipi_dsi_dpi_config(struct dw_mipi_dsi *dsi,
Signature · 1 line
2.11.0.197.gb556de5.dirty
Re: [PATCH v3 09/24] drm/rockchip: dw-mipi-dsi: only request HS clock when required
Quoted 5 lines · John Keeping
Requesting the HS clock from the PHY before we initialize it causes an invalid signal to be sent out since the input clock is not yet configured. The PHY databook suggests only asserting this signal when performing HS transfers, so let's do that.
Quoted 54 lines
Signed-off-by John Keeping <[email protected]>Reviewed-by Chris Zhong <[email protected]>---
v3:
- Add Chris' Reviewed-by
Unchanged in v2drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)drivers/gpu/drm/rockchip/dw-mipi-dsi.c +4
-2@@ -545,13 +545,15 @@ static int dw_mipi_dsi_host_detach(struct mipi_dsi_host *host,static void dw_mipi_message_config (struct dw_mipi_dsi *dsi,const struct mipi_dsi_msg *msg) { +bool lpm = msg->flags &MIPI_DSI_MSG_USE_LPM ;u32 val =0 ;if (msg->flags &MIPI_DSI_MSG_REQ_ACK ) val |=EN_ACK_RQST ; -if (msg->flags &MIPI_DSI_MSG_USE_LPM ) +if (lpm) val |=CMD_MODE_ALL_LP ; +dsi_write (dsi,DSI_LPCLK_CTRL , lpm ?0 :PHY_TXREQUESTCLKHS );dsi_write (dsi,DSI_CMD_MODE_CFG , val); }@@ -693,6 +695,7 @@ static void dw_mipi_dsi_set_mode(struct dw_mipi_dsi *dsi,dsi_write (dsi,DSI_PWR_UP ,RESET );dsi_write (dsi,DSI_MODE_CFG ,ENABLE_VIDEO_MODE );dw_mipi_dsi_video_mode_config (dsi); +dsi_write (dsi,DSI_LPCLK_CTRL ,PHY_TXREQUESTCLKHS );dsi_write (dsi,DSI_PWR_UP ,POWERUP ); } }@@ -710,7 +713,6 @@ static void dw_mipi_dsi_init(struct dw_mipi_dsi *dsi) | PHY_RSTZ | PHY_SHUTDOWNZ);dsi_write (dsi,DSI_CLKMGR_CFG ,TO_CLK_DIVIDSION (10 ) |TX_ESC_CLK_DIVIDSION (7 )); -dsi_write (dsi,DSI_LPCLK_CTRL ,PHY_TXREQUESTCLKHS ); } static void dw_mipi_dsi_dpi_config(struct dw_mipi_dsi *dsi,Signature · 6 lines
2.11.0.197.gb556de5.dirty _______________________________________________ dri-devel mailing list dri-devel at lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Signature · 1 line
Sean Paul, Software Engineer, Google / Chromium OS
PATCH v3 10/24 drm/rockchip: dw-mipi-dsi: don't assume buffer is aligned
In reply to John KeepingBy dereferencing the MIPI command buffer as a u32* we rely on it being correctly aligned on ARM, but this may not be the case. Copy it into a stack variable that will be correctly aligned.
---
v3:
- Add Chris' Reviewed-by
Unchanged in v2
drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
drivers/gpu/drm/rockchip/dw-mipi-dsi.c +7 -5
@@ -607,10 +607,10 @@ static int dw_mipi_dsi_dcs_short_write(struct dw_mipi_dsi *dsi,static int dw_mipi_dsi_dcs_long_write (struct dw_mipi_dsi *dsi,const struct mipi_dsi_msg *msg) { -const u32 *tx_buf = msg->tx_buf; -int len = msg->tx_len, pld_data_bytes =sizeof (*tx_buf), ret; +const u8 *tx_buf = msg->tx_buf; +int len = msg->tx_len, pld_data_bytes =sizeof (u32), ret;u32 hdr_val =GEN_HDATA (msg->tx_len) |GEN_HTYPE (msg->type); -u32 remainder =0 ; +u32 remainder;u32 val;if (msg->tx_len <3 ) {
@@ -621,12 +621,14 @@ static int dw_mipi_dsi_dcs_long_write(struct dw_mipi_dsi *dsi,while (DIV_ROUND_UP (len, pld_data_bytes)) {if (len < pld_data_bytes) { + remainder =0 ;memcpy (&remainder, tx_buf, len);dsi_write (dsi,DSI_GEN_PLD_DATA , remainder); len =0 ; }else { -dsi_write (dsi,DSI_GEN_PLD_DATA , *tx_buf); - tx_buf++; +memcpy (&remainder, tx_buf, pld_data_bytes); +dsi_write (dsi,DSI_GEN_PLD_DATA , remainder); + tx_buf += pld_data_bytes; len -= pld_data_bytes; }
Signature · 1 line
2.11.0.197.gb556de5.dirty
Re: [PATCH v3 10/24] drm/rockchip: dw-mipi-dsi: don't assume buffer is aligned
Quoted 38 lines · John Keeping
By dereferencing the MIPI command buffer as a u32* we rely on it being correctly aligned on ARM, but this may not be the case. Copy it into a stack variable that will be correctly aligned.
Signed-off-by John Keeping <[email protected]>Reviewed-by Chris Zhong <[email protected]>---
v3:
- Add Chris' Reviewed-by
Unchanged in v2drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)drivers/gpu/drm/rockchip/dw-mipi-dsi.c +4
-3@@ -607,10 +607,10 @@ static int dw_mipi_dsi_dcs_short_write(struct dw_mipi_dsi *dsi,static int dw_mipi_dsi_dcs_long_write (struct dw_mipi_dsi *dsi,const struct mipi_dsi_msg *msg) { -const u32 *tx_buf = msg->tx_buf; -int len = msg->tx_len, pld_data_bytes =sizeof (*tx_buf), ret; +const u8 *tx_buf = msg->tx_buf; +int len = msg->tx_len, pld_data_bytes =sizeof (u32), ret;u32 hdr_val =GEN_HDATA (msg->tx_len) |GEN_HTYPE (msg->type); -u32 remainder =0 ; +u32 remainder;u32 val;if (msg->tx_len <3 ) {@@ -621,12 +621,14 @@ static int dw_mipi_dsi_dcs_long_write(struct dw_mipi_dsi *dsi,while (DIV_ROUND_UP (len, pld_data_bytes)) {if (len < pld_data_bytes) { + remainder =0 ;memcpy (&remainder, tx_buf, len);
drivers/gpu/drm/rockchip/dw-mipi-dsi.c static int dw_mipi_dsi_dcs_long_write(struct dw_mipi_dsi *dsi, · line 633
Quoted 10 lines
drivers/gpu/drm/rockchip/dw-mipi-dsi.c +3
-2dsi_write (dsi,DSI_GEN_PLD_DATA , remainder); len =0 ; }else { -dsi_write (dsi,DSI_GEN_PLD_DATA , *tx_buf); - tx_buf++; +memcpy (&remainder, tx_buf, pld_data_bytes); +dsi_write (dsi,DSI_GEN_PLD_DATA , remainder); + tx_buf += pld_data_bytes; len -= pld_data_bytes; }
You can clean this up further by removing a couple of the locals, the conditional and the division:
while(len < msg->tx_len) {
size_t to_write = MIN(msg->tx_len - len, sizeof(remainder));
memcpy(&remainder, msg->tx_buf + len, to_write);
dsi_write(dsi, DSI_GEN_PLD_DATA, remainder);
len += to_write;
...
}Sean
Quoted 8 lines
Signature · 7 lines
-- 2.11.0.197.gb556de5.dirty _______________________________________________ dri-devel mailing list dri-devel at lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Signature · 1 line
Sean Paul, Software Engineer, Google / Chromium OS
Re: [PATCH v3 10/24] drm/rockchip: dw-mipi-dsi: don't assume buffer is aligned
Quoted 54 lines · Sean Paul
Quoted 38 lines · John Keeping
By dereferencing the MIPI command buffer as a u32* we rely on it being correctly aligned on ARM, but this may not be the case. Copy it into a stack variable that will be correctly aligned.
Signed-off-by John Keeping <[email protected]>Reviewed-by Chris Zhong <[email protected]>---
v3:
- Add Chris' Reviewed-by
Unchanged in v2drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)drivers/gpu/drm/rockchip/dw-mipi-dsi.c +4
-3@@ -607,10 +607,10 @@ static int dw_mipi_dsi_dcs_short_write(struct dw_mipi_dsi *dsi,static int dw_mipi_dsi_dcs_long_write (struct dw_mipi_dsi *dsi,const struct mipi_dsi_msg *msg) { -const u32 *tx_buf = msg->tx_buf; -int len = msg->tx_len, pld_data_bytes =sizeof (*tx_buf), ret; +const u8 *tx_buf = msg->tx_buf; +int len = msg->tx_len, pld_data_bytes =sizeof (u32), ret;u32 hdr_val =GEN_HDATA (msg->tx_len) |GEN_HTYPE (msg->type); -u32 remainder =0 ; +u32 remainder;u32 val;if (msg->tx_len <3 ) {@@ -621,12 +621,14 @@ static int dw_mipi_dsi_dcs_long_write(struct dw_mipi_dsi *dsi,while (DIV_ROUND_UP (len, pld_data_bytes)) {if (len < pld_data_bytes) { + remainder =0 ;memcpy (&remainder, tx_buf, len);drivers/gpu/drm/rockchip/dw-mipi-dsi.c static int dw_mipi_dsi_dcs_long_write(struct dw_mipi_dsi *dsi, · line 633
Quoted 10 lines
drivers/gpu/drm/rockchip/dw-mipi-dsi.c +3
-2dsi_write (dsi,DSI_GEN_PLD_DATA , remainder); len =0 ; }else { -dsi_write (dsi,DSI_GEN_PLD_DATA , *tx_buf); - tx_buf++; +memcpy (&remainder, tx_buf, pld_data_bytes); +dsi_write (dsi,DSI_GEN_PLD_DATA , remainder); + tx_buf += pld_data_bytes; len -= pld_data_bytes; }You can clean this up further by removing a couple of the locals, the conditional and the division:
Quoted 9 lines
while(len < msg->tx_len) {
size_t to_write = MIN(msg->tx_len - len, sizeof(remainder));
memcpy(&remainder, msg->tx_buf + len, to_write);
dsi_write(dsi, DSI_GEN_PLD_DATA, remainder);
len += to_write;
...
}That's a nice simplification, but it's more than I was trying to do with this patch. I can add a cleanup patch on top to simplify the function, but I don't have that much time to spend on this at the moment and I'd rather not block this fix because the original code structure could be improved.
Re: [PATCH v3 10/24] drm/rockchip: dw-mipi-dsi: don't assume buffer is aligned
Quoted 63 lines · John Keeping
Quoted 61 lines · Sean Paul
Quoted 38 lines · John Keeping
By dereferencing the MIPI command buffer as a u32* we rely on it being correctly aligned on ARM, but this may not be the case. Copy it into a stack variable that will be correctly aligned.
Signed-off-by John Keeping <[email protected]>Reviewed-by Chris Zhong <[email protected]>---
v3:
- Add Chris' Reviewed-by
Unchanged in v2drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)drivers/gpu/drm/rockchip/dw-mipi-dsi.c +4
-3@@ -607,10 +607,10 @@ static int dw_mipi_dsi_dcs_short_write(struct dw_mipi_dsi *dsi,static int dw_mipi_dsi_dcs_long_write (struct dw_mipi_dsi *dsi,const struct mipi_dsi_msg *msg) { -const u32 *tx_buf = msg->tx_buf; -int len = msg->tx_len, pld_data_bytes =sizeof (*tx_buf), ret; +const u8 *tx_buf = msg->tx_buf; +int len = msg->tx_len, pld_data_bytes =sizeof (u32), ret;u32 hdr_val =GEN_HDATA (msg->tx_len) |GEN_HTYPE (msg->type); -u32 remainder =0 ; +u32 remainder;u32 val;if (msg->tx_len <3 ) {@@ -621,12 +621,14 @@ static int dw_mipi_dsi_dcs_long_write(struct dw_mipi_dsi *dsi,while (DIV_ROUND_UP (len, pld_data_bytes)) {if (len < pld_data_bytes) { + remainder =0 ;memcpy (&remainder, tx_buf, len);drivers/gpu/drm/rockchip/dw-mipi-dsi.c static int dw_mipi_dsi_dcs_long_write(struct dw_mipi_dsi *dsi, · line 633
Quoted 10 lines
drivers/gpu/drm/rockchip/dw-mipi-dsi.c +3
-2dsi_write (dsi,DSI_GEN_PLD_DATA , remainder); len =0 ; }else { -dsi_write (dsi,DSI_GEN_PLD_DATA , *tx_buf); - tx_buf++; +memcpy (&remainder, tx_buf, pld_data_bytes); +dsi_write (dsi,DSI_GEN_PLD_DATA , remainder); + tx_buf += pld_data_bytes; len -= pld_data_bytes; }You can clean this up further by removing a couple of the locals, the conditional and the division:
while(len < msg->tx_len) { size_t to_write = MIN(msg->tx_len - len, sizeof(remainder)); memcpy(&remainder, msg->tx_buf + len, to_write); dsi_write(dsi, DSI_GEN_PLD_DATA, remainder); len += to_write;
Quoted 8 lines
Quoted 2 lines
... }That's a nice simplification, but it's more than I was trying to do with this patch. I can add a cleanup patch on top to simplify the function, but I don't have that much time to spend on this at the moment and I'd rather not block this fix because the original code structure could be improved.
Ok. I'm inclined to argue that writing your response probably took more time than the copy/paste to fix it, but *shrug*.
Sean
Quoted 4 lines
_______________________________________________
dri-devel mailing list
dri-devel at lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
Signature · 1 line
Sean Paul, Software Engineer, Google / Chromium OS
PATCH v3 11/24 drm/rockchip: dw-mipi-dsi: prepare panel after phy init
In reply to John KeepingSome panels need to be configured with commands sent over the MIPI link, which they will do in the prepare hook. Call this after the PHY has been initialized so that we are able to send commands to the panel.
---
v3:
- Add Chris' Reviewed-by
Unchanged in v2
drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/gpu/drm/rockchip/dw-mipi-dsi.c +4 -2
@@ -896,12 +896,14 @@ static void dw_mipi_dsi_encoder_enable(struct drm_encoder *encoder)dw_mipi_dsi_dphy_timing_config (dsi);dw_mipi_dsi_dphy_interface_config (dsi);dw_mipi_dsi_clear_err (dsi); -if (drm_panel_prepare (dsi->panel)) -dev_err (dsi->dev,"failed to prepare panel\n" );dw_mipi_dsi_phy_init (dsi);dw_mipi_dsi_wait_for_two_frames (mode); +dw_mipi_dsi_set_mode (dsi,DW_MIPI_DSI_CMD_MODE ); +if (drm_panel_prepare (dsi->panel)) +dev_err (dsi->dev,"failed to prepare panel\n" ); +dw_mipi_dsi_set_mode (dsi,DW_MIPI_DSI_VID_MODE );drm_panel_enable (dsi->panel);
Signature · 1 line
2.11.0.197.gb556de5.dirty
Re: [PATCH v3 11/24] drm/rockchip: dw-mipi-dsi: prepare panel after phy init
Quoted 4 lines · John Keeping
Some panels need to be configured with commands sent over the MIPI link, which they will do in the prepare hook. Call this after the PHY has been initialized so that we are able to send commands to the panel.
Quoted 38 lines
Signed-off-by John Keeping <[email protected]>Reviewed-by Chris Zhong <[email protected]>---
v3:
- Add Chris' Reviewed-by
Unchanged in v2drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)drivers/gpu/drm/rockchip/dw-mipi-dsi.c +4
-2@@ -896,12 +896,14 @@ static void dw_mipi_dsi_encoder_enable(struct drm_encoder *encoder)dw_mipi_dsi_dphy_timing_config (dsi);dw_mipi_dsi_dphy_interface_config (dsi);dw_mipi_dsi_clear_err (dsi); -if (drm_panel_prepare (dsi->panel)) -dev_err (dsi->dev,"failed to prepare panel\n" );dw_mipi_dsi_phy_init (dsi);dw_mipi_dsi_wait_for_two_frames (mode); +dw_mipi_dsi_set_mode (dsi,DW_MIPI_DSI_CMD_MODE ); +if (drm_panel_prepare (dsi->panel)) +dev_err (dsi->dev,"failed to prepare panel\n" ); +dw_mipi_dsi_set_mode (dsi,DW_MIPI_DSI_VID_MODE );drm_panel_enable (dsi->panel);Signature · 6 lines
2.11.0.197.gb556de5.dirty _______________________________________________ dri-devel mailing list dri-devel at lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Signature · 1 line
Sean Paul, Software Engineer, Google / Chromium OS
PATCH v3 12/24 drm/rockchip: dw-mipi-dsi: allow commands in panel_disable
In reply to John KeepingPanel drivers may want to sent commands during the disable function, for example MIPI_DCS_SET_DISPLAY_OFF before the video signal ends. In order to send commands we need to write to registers, so pclk must be enabled.
While changing this, remove the unnecessary code after the panel unprepare call which seems to be a workaround for a specific panel and thus belongs in the panel driver.
---
v3:
- Add Chris' Reviewed-by
Unchanged in v2
drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-)
drivers/gpu/drm/rockchip/dw-mipi-dsi.c +2 -10
@@ -846,24 +846,16 @@ static void dw_mipi_dsi_encoder_disable(struct drm_encoder *encoder) {struct dw_mipi_dsi *dsi =encoder_to_dsi (encoder); -drm_panel_disable (dsi->panel); -if (clk_prepare_enable (dsi->pclk)) {dev_err (dsi->dev,"%s: Failed to enable pclk\n" , __func__);return ; } +drm_panel_disable (dsi->panel); +dw_mipi_dsi_set_mode (dsi,DW_MIPI_DSI_CMD_MODE );drm_panel_unprepare (dsi->panel); -dw_mipi_dsi_set_mode (dsi,DW_MIPI_DSI_VID_MODE ); -/* -* This is necessary to make sure the peripheral will be driven -* normally when the display is enabled again later. -*/ -msleep (120 ); - -dw_mipi_dsi_set_mode (dsi,DW_MIPI_DSI_CMD_MODE );dw_mipi_dsi_disable (dsi);clk_disable_unprepare (dsi->pclk); }
Signature · 1 line
2.11.0.197.gb556de5.dirty
Re: [PATCH v3 12/24] drm/rockchip: dw-mipi-dsi: allow commands in panel_disable
Quoted 7 lines · John Keeping
Panel drivers may want to sent commands during the disable function, for example
MIPI_DCS_SET_DISPLAY_OFFbefore the video signal ends. In order to send commands we need to write to registers, so pclk must be enabled.While changing this, remove the unnecessary code after the panel unprepare call which seems to be a workaround for a specific panel and thus belongs in the panel driver.
Do you know which panel? If the panel driver is upstream, we should make sure we migrate this hack before removing it here. If it's downstream somewhere,
Quoted 49 lines
Signed-off-by John Keeping <[email protected]>Reviewed-by Chris Zhong <[email protected]>---
v3:
- Add Chris' Reviewed-by
Unchanged in v2drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-)drivers/gpu/drm/rockchip/dw-mipi-dsi.c +2
-10@@ -846,24 +846,16 @@ static void dw_mipi_dsi_encoder_disable(struct drm_encoder *encoder) {struct dw_mipi_dsi *dsi =encoder_to_dsi (encoder); -drm_panel_disable (dsi->panel); -if (clk_prepare_enable (dsi->pclk)) {dev_err (dsi->dev,"%s: Failed to enable pclk\n" , __func__);return ; } +drm_panel_disable (dsi->panel); +dw_mipi_dsi_set_mode (dsi,DW_MIPI_DSI_CMD_MODE );drm_panel_unprepare (dsi->panel); -dw_mipi_dsi_set_mode (dsi,DW_MIPI_DSI_VID_MODE ); -/* -* This is necessary to make sure the peripheral will be driven -* normally when the display is enabled again later. -*/ -msleep (120 ); - -dw_mipi_dsi_set_mode (dsi,DW_MIPI_DSI_CMD_MODE );dw_mipi_dsi_disable (dsi);clk_disable_unprepare (dsi->pclk); }Signature · 6 lines
2.11.0.197.gb556de5.dirty _______________________________________________ dri-devel mailing list dri-devel at lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Signature · 1 line
Sean Paul, Software Engineer, Google / Chromium OS
Re: [PATCH v3 12/24] drm/rockchip: dw-mipi-dsi: allow commands in panel_disable
Quoted 11 lines · Sean Paul
Quoted 7 lines · John Keeping
Panel drivers may want to sent commands during the disable function, for example
MIPI_DCS_SET_DISPLAY_OFFbefore the video signal ends. In order to send commands we need to write to registers, so pclk must be enabled.While changing this, remove the unnecessary code after the panel unprepare call which seems to be a workaround for a specific panel and thus belongs in the panel driver.
Do you know which panel? If the panel driver is upstream, we should make sure we migrate this hack before removing it here. If it's downstream somewhere,
I'm just going by the comment in the code that this patch deletes and the fact that this delay was not needed on any of the three panels I tested.
Given the way the modes change, I think this should be a 120ms disable delay if the affected panel is supported by the simple-panel driver.
Quoted 52 lines
Reviewed-by Sean Paul <[email protected]>Quoted 49 lines
Signed-off-by John Keeping <[email protected]>Reviewed-by Chris Zhong <[email protected]>---
v3:
- Add Chris' Reviewed-by
Unchanged in v2drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-)drivers/gpu/drm/rockchip/dw-mipi-dsi.c +2
-10@@ -846,24 +846,16 @@ static void dw_mipi_dsi_encoder_disable(struct drm_encoder *encoder) {struct dw_mipi_dsi *dsi =encoder_to_dsi (encoder); -drm_panel_disable (dsi->panel); -if (clk_prepare_enable (dsi->pclk)) {dev_err (dsi->dev,"%s: Failed to enable pclk\n" , __func__);return ; } +drm_panel_disable (dsi->panel); +dw_mipi_dsi_set_mode (dsi,DW_MIPI_DSI_CMD_MODE );drm_panel_unprepare (dsi->panel); -dw_mipi_dsi_set_mode (dsi,DW_MIPI_DSI_VID_MODE ); -/* -* This is necessary to make sure the peripheral will be driven -* normally when the display is enabled again later. -*/ -msleep (120 ); - -dw_mipi_dsi_set_mode (dsi,DW_MIPI_DSI_CMD_MODE );dw_mipi_dsi_disable (dsi);clk_disable_unprepare (dsi->pclk); }Signature · 6 lines
2.11.0.197.gb556de5.dirty _______________________________________________ dri-devel mailing list dri-devel at lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
PATCH v3 13/24 drm/rockchip: dw-mipi-dsi: fix escape clock rate
In reply to John KeepingThis clock rate is derived from the PHY PLL, so it should be calculated dynamically. Use the same calculation as the vendor kernel to derive the escape clock speed.
---
v3:
- Improve the commit message a bit
- Add Chris' Reviewed-by
Unchanged in v2
drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/gpu/drm/rockchip/dw-mipi-dsi.c +3 -1
@@ -710,11 +710,13 @@ static void dw_mipi_dsi_disable(struct dw_mipi_dsi *dsi)static void dw_mipi_dsi_init (struct dw_mipi_dsi *dsi) { +u32 esc_clk_division = (dsi->lane_mbps >>3 ) /20 +1 ; +dsi_write (dsi,DSI_PWR_UP ,RESET );dsi_write (dsi,DSI_PHY_RSTZ ,PHY_DISFORCEPLL |PHY_DISABLECLK |PHY_RSTZ |PHY_SHUTDOWNZ );dsi_write (dsi,DSI_CLKMGR_CFG ,TO_CLK_DIVIDSION (10 ) | -TX_ESC_CLK_DIVIDSION (7 )); +TX_ESC_CLK_DIVIDSION (esc_clk_division)); } static void dw_mipi_dsi_dpi_config(struct dw_mipi_dsi *dsi,
Signature · 1 line
2.11.0.197.gb556de5.dirty
Re: [PATCH v3 13/24] drm/rockchip: dw-mipi-dsi: fix escape clock rate
Quoted 4 lines · John Keeping
This clock rate is derived from the PHY PLL, so it should be calculated dynamically. Use the same calculation as the vendor kernel to derive the escape clock speed.
Nit below, but
Quoted 16 lines
Signed-off-by John Keeping <[email protected]>Reviewed-by Chris Zhong <[email protected]>---
v3:
- Improve the commit message a bit
- Add Chris' Reviewed-by
Unchanged in v2drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)drivers/gpu/drm/rockchip/dw-mipi-dsi.c +0
-0
drivers/gpu/drm/rockchip/dw-mipi-dsi.c static void dw_mipi_dsi_disable(struct dw_mipi_dsi *dsi) · line 712
Quoted 3 lines
drivers/gpu/drm/rockchip/dw-mipi-dsi.c +0
-0@@ -710,11 +710,13 @@ static void dw_mipi_dsi_disable(struct dw_mipi_dsi *dsi)static void dw_mipi_dsi_init (struct dw_mipi_dsi *dsi) {
Nit: It would be nice to add a comment to the effect of "You are not meant to understand this, it comes from the vendor kernel"
Quoted 18 lines
drivers/gpu/drm/rockchip/dw-mipi-dsi.c +3
-1+u32 esc_clk_division = (dsi->lane_mbps >>3 ) /20 +1 ; +dsi_write (dsi,DSI_PWR_UP ,RESET );dsi_write (dsi,DSI_PHY_RSTZ ,PHY_DISFORCEPLL |PHY_DISABLECLK |PHY_RSTZ |PHY_SHUTDOWNZ );dsi_write (dsi,DSI_CLKMGR_CFG ,TO_CLK_DIVIDSION (10 ) | -TX_ESC_CLK_DIVIDSION (7 )); +TX_ESC_CLK_DIVIDSION (esc_clk_division)); } static void dw_mipi_dsi_dpi_config(struct dw_mipi_dsi *dsi,Signature · 6 lines
2.11.0.197.gb556de5.dirty _______________________________________________ dri-devel mailing list dri-devel at lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Signature · 1 line
Sean Paul, Software Engineer, Google / Chromium OS
Re: [PATCH v3 13/24] drm/rockchip: dw-mipi-dsi: fix escape clock rate
Quoted 27 lines · Sean Paul
Quoted 4 lines · John Keeping
This clock rate is derived from the PHY PLL, so it should be calculated dynamically. Use the same calculation as the vendor kernel to derive the escape clock speed.
Nit below, but
Reviewed-by Sean Paul <[email protected]>Quoted 17 lines
Signed-off-by John Keeping <[email protected]>Reviewed-by Chris Zhong <[email protected]>---
v3:
- Improve the commit message a bit
- Add Chris' Reviewed-by
Unchanged in v2drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)drivers/gpu/drm/rockchip/dw-mipi-dsi.c +0
-0@@ -710,11 +710,13 @@ static void dw_mipi_dsi_disable(struct dw_mipi_dsi *dsi)
Quoted 5 lines
drivers/gpu/drm/rockchip/dw-mipi-dsi.c static void dw_mipi_dsi_disable(struct dw_mipi_dsi *dsi) · line 712
Quoted 2 lines
drivers/gpu/drm/rockchip/dw-mipi-dsi.c +0
-0static void dw_mipi_dsi_init (struct dw_mipi_dsi *dsi) {Nit: It would be nice to add a comment to the effect of "You are not meant to understand this, it comes from the vendor kernel"
Actually, I think my commit message was misleading. I think I do understand the calculation, although the TRM is not particularly clear about it. TX_ESC_CLK_DIVISION is described as:
the division factor for the TX_Escape clock source (lanebyteclk). The value 0 and 1 stop the TX_ESC clock generation
Now lanebyteclk is (dsi->lane_mbps >> 3) since lane_mbps is the lane bit clock. The maximum escape mode clock from the MIPI specification is 20MHz, so we end up needing
lanebyteclk / esc_clk_division < 20
thus:
esc_clk_division > lanebyteclk / 20
and we want esc_clk_division >= 2 to avoid disabling the clock generation.
I'll add a comment to this effect.
Quoted 19 lines
Quoted 18 lines
drivers/gpu/drm/rockchip/dw-mipi-dsi.c +3
-1+u32 esc_clk_division = (dsi->lane_mbps >>3 ) /20 +1 ; +dsi_write (dsi,DSI_PWR_UP ,RESET );dsi_write (dsi,DSI_PHY_RSTZ ,PHY_DISFORCEPLL |PHY_DISABLECLK |PHY_RSTZ |PHY_SHUTDOWNZ );dsi_write (dsi,DSI_CLKMGR_CFG ,TO_CLK_DIVIDSION (10 ) | -TX_ESC_CLK_DIVIDSION (7 )); +TX_ESC_CLK_DIVIDSION (esc_clk_division)); } static void dw_mipi_dsi_dpi_config(struct dw_mipi_dsi *dsi,Signature · 6 lines
2.11.0.197.gb556de5.dirty _______________________________________________ dri-devel mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/dri-devel
PATCH v3 14/24 drm/rockchip: dw-mipi-dsi: ensure PHY is reset
In reply to John KeepingAlso don't power up the DSI host at this point since this is not necessary in order to configure the PHY and we do so later when selecting video or command mode.
---
v3:
- Add Chris' Reviewed-by
Unchanged in v2
drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/gpu/drm/rockchip/dw-mipi-dsi.c +4 -1
@@ -397,7 +397,10 @@ static int dw_mipi_dsi_phy_init(struct dw_mipi_dsi *dsi)return testdin; } -dsi_write (dsi,DSI_PWR_UP ,POWERUP ); +/* Start by clearing PHY state */ +dsi_write (dsi,DSI_PHY_TST_CTRL0 ,PHY_UNTESTCLR ); +dsi_write (dsi,DSI_PHY_TST_CTRL0 ,PHY_TESTCLR ); +dsi_write (dsi,DSI_PHY_TST_CTRL0 ,PHY_UNTESTCLR ); dw_mipi_dsi_phy_write(dsi, 0x10, BYPASS_VCO_RANGE | VCO_RANGE_CON_SEL(vco) |
Signature · 1 line
2.11.0.197.gb556de5.dirty
Re: [PATCH v3 14/24] drm/rockchip: dw-mipi-dsi: ensure PHY is reset
Quoted 4 lines · John Keeping
Also don't power up the DSI host at this point since this is not necessary in order to configure the PHY and we do so later when selecting video or command mode.
Quoted 33 lines
Signed-off-by John Keeping <[email protected]>Reviewed-by Chris Zhong <[email protected]>---
v3:
- Add Chris' Reviewed-by
Unchanged in v2drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)drivers/gpu/drm/rockchip/dw-mipi-dsi.c +4
-1@@ -397,7 +397,10 @@ static int dw_mipi_dsi_phy_init(struct dw_mipi_dsi *dsi)return testdin; } -dsi_write (dsi,DSI_PWR_UP ,POWERUP ); +/* Start by clearing PHY state */ +dsi_write (dsi,DSI_PHY_TST_CTRL0 ,PHY_UNTESTCLR ); +dsi_write (dsi,DSI_PHY_TST_CTRL0 ,PHY_TESTCLR ); +dsi_write (dsi,DSI_PHY_TST_CTRL0 ,PHY_UNTESTCLR ); dw_mipi_dsi_phy_write(dsi, 0x10, BYPASS_VCO_RANGE | VCO_RANGE_CON_SEL(vco) |Signature · 6 lines
2.11.0.197.gb556de5.dirty _______________________________________________ dri-devel mailing list dri-devel at lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Signature · 1 line
Sean Paul, Software Engineer, Google / Chromium OS
PATCH v3 15/24 drm/rockchip: dw-mipi-dsi: configure PHY before enabling
In reply to John KeepingThe bias, bandgap and PLL should all be configured before we enable them.
---
v3:
- Squash together two patches that both affect initialization order of the PHY
Unchanged in v2
drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
drivers/gpu/drm/rockchip/dw-mipi-dsi.c +6 -5
@@ -413,12 +413,17 @@ static int dw_mipi_dsi_phy_init(struct dw_mipi_dsi *dsi)dw_mipi_dsi_phy_write (dsi,0x44 ,HSFREQRANGE_SEL (testdin)); -dw_mipi_dsi_phy_write (dsi,0x19 ,PLL_LOOP_DIV_EN |PLL_INPUT_DIV_EN );dw_mipi_dsi_phy_write (dsi,0x17 ,INPUT_DIVIDER (dsi->input_div));dw_mipi_dsi_phy_write (dsi,0x18 ,LOOP_DIV_LOW_SEL (dsi->feedback_div) |LOW_PROGRAM_EN );dw_mipi_dsi_phy_write (dsi,0x18 ,LOOP_DIV_HIGH_SEL (dsi->feedback_div) |HIGH_PROGRAM_EN ); +dw_mipi_dsi_phy_write (dsi,0x19 ,PLL_LOOP_DIV_EN |PLL_INPUT_DIV_EN ); + +dw_mipi_dsi_phy_write (dsi,0x22 ,LOW_PROGRAM_EN | +BIASEXTR_SEL (BIASEXTR_127_7 )); +dw_mipi_dsi_phy_write (dsi,0x22 ,HIGH_PROGRAM_EN | +BANDGAP_SEL (BANDGAP_96_10 ));dw_mipi_dsi_phy_write (dsi,0x20 ,POWER_CONTROL |INTERNAL_REG_CURRENT |BIAS_BLOCK_ON |BANDGAP_ON );
@@ -429,10 +434,6 @@ static int dw_mipi_dsi_phy_init(struct dw_mipi_dsi *dsi)SETRD_MAX |POWER_MANAGE | TER_RESISTORS_ON); -dw_mipi_dsi_phy_write (dsi,0x22 ,LOW_PROGRAM_EN | -BIASEXTR_SEL (BIASEXTR_127_7 )); -dw_mipi_dsi_phy_write (dsi,0x22 ,HIGH_PROGRAM_EN | -BANDGAP_SEL (BANDGAP_96_10 ));dw_mipi_dsi_phy_write (dsi,0x70 ,TLP_PROGRAM_EN |0xf );dw_mipi_dsi_phy_write (dsi,0x71 ,THS_PRE_PROGRAM_EN |0x55 );
Signature · 1 line
2.11.0.197.gb556de5.dirty
Re: [PATCH v3 15/24] drm/rockchip: dw-mipi-dsi: configure PHY before enabling
Quoted 3 lines · John Keeping
The bias, bandgap and PLL should all be configured before we enable them.
Do you know why the test codes are hard-coded magic? It'd be nice to make some sense of them in a future patch.
Quoted 51 lines
Signed-off-by John Keeping <[email protected]>---
v3:
- Squash together two patches that both affect initialization order of the PHY
Unchanged in v2drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)drivers/gpu/drm/rockchip/dw-mipi-dsi.c +6
-5@@ -413,12 +413,17 @@ static int dw_mipi_dsi_phy_init(struct dw_mipi_dsi *dsi)dw_mipi_dsi_phy_write (dsi,0x44 ,HSFREQRANGE_SEL (testdin)); -dw_mipi_dsi_phy_write (dsi,0x19 ,PLL_LOOP_DIV_EN |PLL_INPUT_DIV_EN );dw_mipi_dsi_phy_write (dsi,0x17 ,INPUT_DIVIDER (dsi->input_div));dw_mipi_dsi_phy_write (dsi,0x18 ,LOOP_DIV_LOW_SEL (dsi->feedback_div) |LOW_PROGRAM_EN );dw_mipi_dsi_phy_write (dsi,0x18 ,LOOP_DIV_HIGH_SEL (dsi->feedback_div) |HIGH_PROGRAM_EN ); +dw_mipi_dsi_phy_write (dsi,0x19 ,PLL_LOOP_DIV_EN |PLL_INPUT_DIV_EN ); + +dw_mipi_dsi_phy_write (dsi,0x22 ,LOW_PROGRAM_EN | +BIASEXTR_SEL (BIASEXTR_127_7 )); +dw_mipi_dsi_phy_write (dsi,0x22 ,HIGH_PROGRAM_EN | +BANDGAP_SEL (BANDGAP_96_10 ));dw_mipi_dsi_phy_write (dsi,0x20 ,POWER_CONTROL |INTERNAL_REG_CURRENT |BIAS_BLOCK_ON |BANDGAP_ON );@@ -429,10 +434,6 @@ static int dw_mipi_dsi_phy_init(struct dw_mipi_dsi *dsi)SETRD_MAX |POWER_MANAGE | TER_RESISTORS_ON); -dw_mipi_dsi_phy_write (dsi,0x22 ,LOW_PROGRAM_EN | -BIASEXTR_SEL (BIASEXTR_127_7 )); -dw_mipi_dsi_phy_write (dsi,0x22 ,HIGH_PROGRAM_EN | -BANDGAP_SEL (BANDGAP_96_10 ));dw_mipi_dsi_phy_write (dsi,0x70 ,TLP_PROGRAM_EN |0xf );dw_mipi_dsi_phy_write (dsi,0x71 ,THS_PRE_PROGRAM_EN |0x55 );Signature · 6 lines
2.11.0.197.gb556de5.dirty _______________________________________________ dri-devel mailing list dri-devel at lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Signature · 1 line
Sean Paul, Software Engineer, Google / Chromium OS
Re: [PATCH v3 15/24] drm/rockchip: dw-mipi-dsi: configure PHY before enabling
Quoted 7 lines · Sean Paul
Quoted 3 lines · John Keeping
The bias, bandgap and PLL should all be configured before we enable them.
Do you know why the test codes are hard-coded magic? It'd be nice to make some sense of them in a future patch.
I just kept with the existing style of the code, but it should be straightforward to add some defines with sensible names.
Quoted 54 lines
Reviewed-by Sean Paul <[email protected]>Quoted 51 lines
Signed-off-by John Keeping <[email protected]>---
v3:
- Squash together two patches that both affect initialization order of the PHY
Unchanged in v2drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)drivers/gpu/drm/rockchip/dw-mipi-dsi.c +6
-5@@ -413,12 +413,17 @@ static int dw_mipi_dsi_phy_init(struct dw_mipi_dsi *dsi)dw_mipi_dsi_phy_write (dsi,0x44 ,HSFREQRANGE_SEL (testdin)); -dw_mipi_dsi_phy_write (dsi,0x19 ,PLL_LOOP_DIV_EN |PLL_INPUT_DIV_EN );dw_mipi_dsi_phy_write (dsi,0x17 ,INPUT_DIVIDER (dsi->input_div));dw_mipi_dsi_phy_write (dsi,0x18 ,LOOP_DIV_LOW_SEL (dsi->feedback_div) |LOW_PROGRAM_EN );dw_mipi_dsi_phy_write (dsi,0x18 ,LOOP_DIV_HIGH_SEL (dsi->feedback_div) |HIGH_PROGRAM_EN ); +dw_mipi_dsi_phy_write (dsi,0x19 ,PLL_LOOP_DIV_EN |PLL_INPUT_DIV_EN ); + +dw_mipi_dsi_phy_write (dsi,0x22 ,LOW_PROGRAM_EN | +BIASEXTR_SEL (BIASEXTR_127_7 )); +dw_mipi_dsi_phy_write (dsi,0x22 ,HIGH_PROGRAM_EN | +BANDGAP_SEL (BANDGAP_96_10 ));dw_mipi_dsi_phy_write (dsi,0x20 ,POWER_CONTROL |INTERNAL_REG_CURRENT |BIAS_BLOCK_ON |BANDGAP_ON );@@ -429,10 +434,6 @@ static int dw_mipi_dsi_phy_init(struct dw_mipi_dsi *dsi)SETRD_MAX |POWER_MANAGE | TER_RESISTORS_ON); -dw_mipi_dsi_phy_write (dsi,0x22 ,LOW_PROGRAM_EN | -BIASEXTR_SEL (BIASEXTR_127_7 )); -dw_mipi_dsi_phy_write (dsi,0x22 ,HIGH_PROGRAM_EN | -BANDGAP_SEL (BANDGAP_96_10 ));dw_mipi_dsi_phy_write (dsi,0x70 ,TLP_PROGRAM_EN |0xf );dw_mipi_dsi_phy_write (dsi,0x71 ,THS_PRE_PROGRAM_EN |0x55 );Signature · 6 lines
2.11.0.197.gb556de5.dirty _______________________________________________ dri-devel mailing list dri-devel at lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
PATCH v3 16/24 drm/rockchip: dw-mipi-dsi: properly configure PHY timing
In reply to John KeepingThese values are specified as constant time periods but the PHY configuration is in terms of the current lane byte clock so using constant values guarantees that the timings will be outside the specification with some display configurations.
Derive the necessary configuration from the byte clock in order to ensure that the PHY configuration is correct.
---
v3:
- Wrap some long lines
Unchanged in v2
drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 39 ++++++++++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 4 deletions(-)
drivers/gpu/drm/rockchip/dw-mipi-dsi.c +35 -4
@@ -383,6 +383,26 @@ static void dw_mipi_dsi_phy_write(struct dw_mipi_dsi *dsi, u8 test_code,dsi_write (dsi,DSI_PHY_TST_CTRL0 ,PHY_TESTCLK |PHY_UNTESTCLR ); } +/** +* ns2bc - Nanoseconds to byte clock cycles +*/ +static inline unsigned int ns2bc (struct dw_mipi_dsi *dsi,int ns) +{ +unsigned long byte_clk_khz = dsi->lane_mbps *MSEC_PER_SEC /8 ; + +return (ns * (byte_clk_khz /1000 ) +999 ) /1000 ; +} + +/** +* ns2ui - Nanoseconds to UI time periods +*/ +static inline unsigned int ns2ui (struct dw_mipi_dsi *dsi,int ns) +{ +unsigned long byte_clk_khz = dsi->lane_mbps *MSEC_PER_SEC ; + +return (ns * (byte_clk_khz /1000 ) +999 ) /1000 ; +} +static int dw_mipi_dsi_phy_init (struct dw_mipi_dsi *dsi) {int ret, testdin, vco, val;
@@ -434,10 +454,21 @@ static int dw_mipi_dsi_phy_init(struct dw_mipi_dsi *dsi)SETRD_MAX |POWER_MANAGE | TER_RESISTORS_ON); - -dw_mipi_dsi_phy_write (dsi,0x70 ,TLP_PROGRAM_EN |0xf ); -dw_mipi_dsi_phy_write (dsi,0x71 ,THS_PRE_PROGRAM_EN |0x55 ); -dw_mipi_dsi_phy_write (dsi,0x72 ,THS_ZERO_PROGRAM_EN |0xa ); +dw_mipi_dsi_phy_write (dsi,0x60 ,TLP_PROGRAM_EN |ns2bc (dsi,500 )); +dw_mipi_dsi_phy_write (dsi,0x61 ,THS_PRE_PROGRAM_EN |ns2ui (dsi,40 )); +dw_mipi_dsi_phy_write (dsi,0x62 ,THS_ZERO_PROGRAM_EN |ns2bc (dsi,300 )); +dw_mipi_dsi_phy_write (dsi,0x63 ,THS_PRE_PROGRAM_EN |ns2ui (dsi,100 )); +dw_mipi_dsi_phy_write (dsi,0x64 ,BIT (5 ) |ns2bc (dsi,100 )); +dw_mipi_dsi_phy_write (dsi,0x65 ,BIT (5 ) | (ns2bc (dsi,60 ) +7 )); + +dw_mipi_dsi_phy_write (dsi,0x70 ,TLP_PROGRAM_EN |ns2bc (dsi,500 )); +dw_mipi_dsi_phy_write (dsi,0x71 , +THS_PRE_PROGRAM_EN | (ns2ui (dsi,50 ) +5 )); +dw_mipi_dsi_phy_write (dsi,0x72 , +THS_ZERO_PROGRAM_EN | (ns2bc (dsi,140 ) +2 )); +dw_mipi_dsi_phy_write (dsi,0x73 , +THS_PRE_PROGRAM_EN | (ns2ui (dsi,60 ) +8 )); +dw_mipi_dsi_phy_write (dsi,0x74 ,BIT (5 ) |ns2bc (dsi,100 ));dsi_write (dsi,DSI_PHY_RSTZ ,PHY_ENFORCEPLL |PHY_ENABLECLK |PHY_UNRSTZ |PHY_UNSHUTDOWNZ );
Signature · 1 line
2.11.0.197.gb556de5.dirty
Re: [PATCH v3 16/24] drm/rockchip: dw-mipi-dsi: properly configure PHY timing
Quoted 22 lines · John Keeping
These values are specified as constant time periods but the PHY configuration is in terms of the current lane byte clock so using constant values guarantees that the timings will be outside the specification with some display configurations.
Derive the necessary configuration from the byte clock in order to ensure that the PHY configuration is correct.
Signed-off-by John Keeping <[email protected]>---
v3:
- Wrap some long lines
Unchanged in v2drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 39 ++++++++++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 4 deletions(-)drivers/gpu/drm/rockchip/dw-mipi-dsi.c +0
-0
drivers/gpu/drm/rockchip/dw-mipi-dsi.c static void dw_mipi_dsi_phy_write(struct dw_mipi_dsi *dsi, u8 test_code, · line 391
Quoted 9 lines
drivers/gpu/drm/rockchip/dw-mipi-dsi.c +6
-0@@ -383,6 +383,26 @@ static void dw_mipi_dsi_phy_write(struct dw_mipi_dsi *dsi, u8 test_code,dsi_write (dsi,DSI_PHY_TST_CTRL0 ,PHY_TESTCLK |PHY_UNTESTCLR ); } +/** +* ns2bc - Nanoseconds to byte clock cycles +*/ +static inline unsigned int ns2bc (struct dw_mipi_dsi *dsi,int ns) +{ +unsigned long byte_clk_khz = dsi->lane_mbps *MSEC_PER_SEC /8 ;
Why multiply by 1000 (MSEC_PER_SEC) only to immediately divide by 1000?
drivers/gpu/drm/rockchip/dw-mipi-dsi.c static void dw_mipi_dsi_phy_write(struct dw_mipi_dsi *dsi, u8 test_code, · line 393
Quoted 2 lines
drivers/gpu/drm/rockchip/dw-mipi-dsi.c +2
-0+ +return (ns * (byte_clk_khz /1000 ) +999 ) /1000 ;
Can you replace this whole function with:
return DIV_ROUND_UP(ns * dsi->lane_mbps / 8, 1000);
drivers/gpu/drm/rockchip/dw-mipi-dsi.c static void dw_mipi_dsi_phy_write(struct dw_mipi_dsi *dsi, u8 test_code, · line 403
Quoted 10 lines
drivers/gpu/drm/rockchip/dw-mipi-dsi.c +10
-0+} + +/** +* ns2ui - Nanoseconds to UI time periods +*/ +static inline unsigned int ns2ui (struct dw_mipi_dsi *dsi,int ns) +{ +unsigned long byte_clk_khz = dsi->lane_mbps *MSEC_PER_SEC ; + +return (ns * (byte_clk_khz /1000 ) +999 ) /1000 ;
Same remarks here.
Sean
Quoted 38 lines
drivers/gpu/drm/rockchip/dw-mipi-dsi.c +17
-4+} +static int dw_mipi_dsi_phy_init (struct dw_mipi_dsi *dsi) {int ret, testdin, vco, val;@@ -434,10 +454,21 @@ static int dw_mipi_dsi_phy_init(struct dw_mipi_dsi *dsi)SETRD_MAX |POWER_MANAGE | TER_RESISTORS_ON); - -dw_mipi_dsi_phy_write (dsi,0x70 ,TLP_PROGRAM_EN |0xf ); -dw_mipi_dsi_phy_write (dsi,0x71 ,THS_PRE_PROGRAM_EN |0x55 ); -dw_mipi_dsi_phy_write (dsi,0x72 ,THS_ZERO_PROGRAM_EN |0xa ); +dw_mipi_dsi_phy_write (dsi,0x60 ,TLP_PROGRAM_EN |ns2bc (dsi,500 )); +dw_mipi_dsi_phy_write (dsi,0x61 ,THS_PRE_PROGRAM_EN |ns2ui (dsi,40 )); +dw_mipi_dsi_phy_write (dsi,0x62 ,THS_ZERO_PROGRAM_EN |ns2bc (dsi,300 )); +dw_mipi_dsi_phy_write (dsi,0x63 ,THS_PRE_PROGRAM_EN |ns2ui (dsi,100 )); +dw_mipi_dsi_phy_write (dsi,0x64 ,BIT (5 ) |ns2bc (dsi,100 )); +dw_mipi_dsi_phy_write (dsi,0x65 ,BIT (5 ) | (ns2bc (dsi,60 ) +7 )); + +dw_mipi_dsi_phy_write (dsi,0x70 ,TLP_PROGRAM_EN |ns2bc (dsi,500 )); +dw_mipi_dsi_phy_write (dsi,0x71 , +THS_PRE_PROGRAM_EN | (ns2ui (dsi,50 ) +5 )); +dw_mipi_dsi_phy_write (dsi,0x72 , +THS_ZERO_PROGRAM_EN | (ns2bc (dsi,140 ) +2 )); +dw_mipi_dsi_phy_write (dsi,0x73 , +THS_PRE_PROGRAM_EN | (ns2ui (dsi,60 ) +8 )); +dw_mipi_dsi_phy_write (dsi,0x74 ,BIT (5 ) |ns2bc (dsi,100 ));dsi_write (dsi,DSI_PHY_RSTZ ,PHY_ENFORCEPLL |PHY_ENABLECLK |PHY_UNRSTZ |PHY_UNSHUTDOWNZ );Signature · 6 lines
2.11.0.197.gb556de5.dirty _______________________________________________ dri-devel mailing list dri-devel at lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Signature · 1 line
Sean Paul, Software Engineer, Google / Chromium OS
Re: [PATCH v3 16/24] drm/rockchip: dw-mipi-dsi: properly configure PHY timing
Quoted 35 lines · Sean Paul
Quoted 22 lines · John Keeping
These values are specified as constant time periods but the PHY configuration is in terms of the current lane byte clock so using constant values guarantees that the timings will be outside the specification with some display configurations.
Derive the necessary configuration from the byte clock in order to ensure that the PHY configuration is correct.
Signed-off-by John Keeping <[email protected]>---
v3:
- Wrap some long lines
Unchanged in v2drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 39 ++++++++++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 4 deletions(-)drivers/gpu/drm/rockchip/dw-mipi-dsi.c +0
-0drivers/gpu/drm/rockchip/dw-mipi-dsi.c static void dw_mipi_dsi_phy_write(struct dw_mipi_dsi *dsi, u8 test_code, · line 391
Quoted 9 lines
drivers/gpu/drm/rockchip/dw-mipi-dsi.c +6
-0@@ -383,6 +383,26 @@ static void dw_mipi_dsi_phy_write(struct dw_mipi_dsi *dsi, u8 test_code,dsi_write (dsi,DSI_PHY_TST_CTRL0 ,PHY_TESTCLK |PHY_UNTESTCLR ); } +/** +* ns2bc - Nanoseconds to byte clock cycles +*/ +static inline unsigned int ns2bc (struct dw_mipi_dsi *dsi,int ns) +{ +unsigned long byte_clk_khz = dsi->lane_mbps *MSEC_PER_SEC /8 ;Why multiply by 1000 (
MSEC_PER_SEC) only to immediately divide by 1000?
Quoted 6 lines
drivers/gpu/drm/rockchip/dw-mipi-dsi.c static void dw_mipi_dsi_phy_write(struct dw_mipi_dsi *dsi, u8 test_code, · line 393
Quoted 2 lines
drivers/gpu/drm/rockchip/dw-mipi-dsi.c +2
-0+ +return (ns * (byte_clk_khz /1000 ) +999 ) /1000 ;Can you replace this whole function with:
return
DIV_ROUND_UP(ns * dsi->lane_mbps / 8, 1000);
Yes, I'll make this simplification.
Quoted 55 lines
drivers/gpu/drm/rockchip/dw-mipi-dsi.c static void dw_mipi_dsi_phy_write(struct dw_mipi_dsi *dsi, u8 test_code, · line 403
Quoted 10 lines
drivers/gpu/drm/rockchip/dw-mipi-dsi.c +10
-0+} + +/** +* ns2ui - Nanoseconds to UI time periods +*/ +static inline unsigned int ns2ui (struct dw_mipi_dsi *dsi,int ns) +{ +unsigned long byte_clk_khz = dsi->lane_mbps *MSEC_PER_SEC ; + +return (ns * (byte_clk_khz /1000 ) +999 ) /1000 ;Same remarks here.
Sean
Quoted 38 lines
drivers/gpu/drm/rockchip/dw-mipi-dsi.c +17
-4+} +static int dw_mipi_dsi_phy_init (struct dw_mipi_dsi *dsi) {int ret, testdin, vco, val;@@ -434,10 +454,21 @@ static int dw_mipi_dsi_phy_init(struct dw_mipi_dsi *dsi)SETRD_MAX |POWER_MANAGE | TER_RESISTORS_ON); - -dw_mipi_dsi_phy_write (dsi,0x70 ,TLP_PROGRAM_EN |0xf ); -dw_mipi_dsi_phy_write (dsi,0x71 ,THS_PRE_PROGRAM_EN |0x55 ); -dw_mipi_dsi_phy_write (dsi,0x72 ,THS_ZERO_PROGRAM_EN |0xa ); +dw_mipi_dsi_phy_write (dsi,0x60 ,TLP_PROGRAM_EN |ns2bc (dsi,500 )); +dw_mipi_dsi_phy_write (dsi,0x61 ,THS_PRE_PROGRAM_EN |ns2ui (dsi,40 )); +dw_mipi_dsi_phy_write (dsi,0x62 ,THS_ZERO_PROGRAM_EN |ns2bc (dsi,300 )); +dw_mipi_dsi_phy_write (dsi,0x63 ,THS_PRE_PROGRAM_EN |ns2ui (dsi,100 )); +dw_mipi_dsi_phy_write (dsi,0x64 ,BIT (5 ) |ns2bc (dsi,100 )); +dw_mipi_dsi_phy_write (dsi,0x65 ,BIT (5 ) | (ns2bc (dsi,60 ) +7 )); + +dw_mipi_dsi_phy_write (dsi,0x70 ,TLP_PROGRAM_EN |ns2bc (dsi,500 )); +dw_mipi_dsi_phy_write (dsi,0x71 , +THS_PRE_PROGRAM_EN | (ns2ui (dsi,50 ) +5 )); +dw_mipi_dsi_phy_write (dsi,0x72 , +THS_ZERO_PROGRAM_EN | (ns2bc (dsi,140 ) +2 )); +dw_mipi_dsi_phy_write (dsi,0x73 , +THS_PRE_PROGRAM_EN | (ns2ui (dsi,60 ) +8 )); +dw_mipi_dsi_phy_write (dsi,0x74 ,BIT (5 ) |ns2bc (dsi,100 ));dsi_write (dsi,DSI_PHY_RSTZ ,PHY_ENFORCEPLL |PHY_ENABLECLK |PHY_UNRSTZ |PHY_UNSHUTDOWNZ );Signature · 6 lines
2.11.0.197.gb556de5.dirty _______________________________________________ dri-devel mailing list dri-devel at lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
PATCH v3 17/24 drm/rockchip: dw-mipi-dsi: improve PLL configuration
In reply to John KeepingThe multiplication ratio for the PLL is required to be even due to the use of a "by 2 pre-scaler". Currently we are likely to end up with an odd multiplier even though there is an equivalent set of parameters with an even multiplier.
For example, using the 324MHz bit rate with a reference clock of 24MHz we end up with M = 27, N = 2 whereas the example in the PHY databook gives M = 54, N = 4 for this bit rate and reference clock.
By walking down through the available multiplier instead of up we are more likely to hit an even multiplier. With the above example we do now get M = 54, N = 4 as given by the databook.
While doing this, change the loop limits to encode the actual limits on the divisor, which are:
40MHz >= (pllref / N) >= 5MHz
---
Unchanged in v3
Unchanged in v2
drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/rockchip/dw-mipi-dsi.c +1 -1
@@ -522,7 +522,7 @@ static int dw_mipi_dsi_get_lane_bps(struct dw_mipi_dsi *dsi, pllref =DIV_ROUND_UP (clk_get_rate (dsi->pllref_clk),USEC_PER_SEC ); tmp = pllref; -for (i =1 ; i <6 ; i++) { +for (i = pllref /5 ; i > (pllref /40 ); i--) { pre = pllref / i;if ((tmp > (target_mbps % pre)) && (target_mbps / pre <512 )) { tmp = target_mbps % pre;
Signature · 1 line
2.11.0.197.gb556de5.dirty
Re: [PATCH v3 17/24] drm/rockchip: dw-mipi-dsi: improve PLL configuration
Quoted 31 lines · John Keeping
The multiplication ratio for the PLL is required to be even due to the use of a "by 2 pre-scaler". Currently we are likely to end up with an odd multiplier even though there is an equivalent set of parameters with an even multiplier.
For example, using the 324MHz bit rate with a reference clock of 24MHz we end up with M = 27, N = 2 whereas the example in the PHY databook gives M = 54, N = 4 for this bit rate and reference clock.
By walking down through the available multiplier instead of up we are more likely to hit an even multiplier. With the above example we do now get M = 54, N = 4 as given by the databook.
While doing this, change the loop limits to encode the actual limits on the divisor, which are:
40MHz >= (pllref / N) >= 5MHzSigned-off-by John Keeping <[email protected]>---
Unchanged in v3
Unchanged in v2drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)drivers/gpu/drm/rockchip/dw-mipi-dsi.c +0
-0
drivers/gpu/drm/rockchip/dw-mipi-dsi.c static int dw_mipi_dsi_get_lane_bps(struct dw_mipi_dsi *dsi, · line 525
Quoted 5 lines
drivers/gpu/drm/rockchip/dw-mipi-dsi.c +1
-1@@ -522,7 +522,7 @@ static int dw_mipi_dsi_get_lane_bps(struct dw_mipi_dsi *dsi, pllref =DIV_ROUND_UP (clk_get_rate (dsi->pllref_clk),USEC_PER_SEC ); tmp = pllref; -for (i =1 ; i <6 ; i++) { +for (i = pllref /5 ; i > (pllref /40 ); i--) {
I've convinced myself that this is right, but it took reading through the commit message a few times. I think this code would benefit greatly from a comment so readers don't need to go through git history.
With that,
Quoted 10 lines
drivers/gpu/drm/rockchip/dw-mipi-dsi.c +0
-0pre = pllref / i;if ((tmp > (target_mbps % pre)) && (target_mbps / pre <512 )) { tmp = target_mbps % pre;Signature · 6 lines
2.11.0.197.gb556de5.dirty _______________________________________________ dri-devel mailing list dri-devel at lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Signature · 1 line
Sean Paul, Software Engineer, Google / Chromium OS
PATCH v3 18/24 drm/rockchip: dw-mipi-dsi: use specific poll helper
In reply to John KeepingAs the documentation for readx_poll_timeout says, we want to use the specialized macro for readl rather than using the generic version directly.
---
v3:
- Add Chris' Reviewed-by
Unchanged in v2
drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
drivers/gpu/drm/rockchip/dw-mipi-dsi.c +5 -5
@@ -474,14 +474,14 @@ static int dw_mipi_dsi_phy_init(struct dw_mipi_dsi *dsi) PHY_UNRSTZ | PHY_UNSHUTDOWNZ); - ret =readx_poll_timeout (readl, dsi->base +DSI_PHY_STATUS , + ret =readl_poll_timeout (dsi->base +DSI_PHY_STATUS , val, val &LOCK ,1000 ,PHY_STATUS_TIMEOUT_US );if (ret <0 ) {dev_err (dsi->dev,"failed to wait for phy lock state\n" );return ret; } - ret =readx_poll_timeout (readl, dsi->base +DSI_PHY_STATUS , + ret =readl_poll_timeout (dsi->base +DSI_PHY_STATUS , val, val &STOP_STATE_CLK_LANE ,1000 ,PHY_STATUS_TIMEOUT_US );if (ret <0 ) {
@@ -597,7 +597,7 @@ static int dw_mipi_dsi_gen_pkt_hdr_write(struct dw_mipi_dsi *dsi, u32 hdr_val)int ret;u32 val, mask; - ret =readx_poll_timeout (readl, dsi->base +DSI_CMD_PKT_STATUS , + ret =readl_poll_timeout (dsi->base +DSI_CMD_PKT_STATUS , val, !(val &GEN_CMD_FULL ),1000 ,CMD_PKT_STATUS_TIMEOUT_US );if (ret <0 ) {
@@ -608,7 +608,7 @@ static int dw_mipi_dsi_gen_pkt_hdr_write(struct dw_mipi_dsi *dsi, u32 hdr_val)dsi_write (dsi,DSI_GEN_HDR , hdr_val); mask =GEN_CMD_EMPTY |GEN_PLD_W_EMPTY ; - ret =readx_poll_timeout (readl, dsi->base +DSI_CMD_PKT_STATUS , + ret =readl_poll_timeout (dsi->base +DSI_CMD_PKT_STATUS , val, (val & mask) == mask,1000 ,CMD_PKT_STATUS_TIMEOUT_US );if (ret <0 ) {
@@ -667,7 +667,7 @@ static int dw_mipi_dsi_dcs_long_write(struct dw_mipi_dsi *dsi, len -= pld_data_bytes; } - ret =readx_poll_timeout (readl, dsi->base +DSI_CMD_PKT_STATUS , + ret =readl_poll_timeout (dsi->base +DSI_CMD_PKT_STATUS , val, !(val &GEN_PLD_W_FULL ),1000 ,CMD_PKT_STATUS_TIMEOUT_US );if (ret <0 ) {
Signature · 1 line
2.11.0.197.gb556de5.dirty
Re: [PATCH v3 18/24] drm/rockchip: dw-mipi-dsi: use specific poll helper
Quoted 4 lines · John Keeping
As the documentation for
readx_poll_timeoutsays, we want to use the specialized macro for readl rather than using the generic version directly.
Quoted 65 lines
Signed-off-by John Keeping <[email protected]>Reviewed-by Chris Zhong <[email protected]>---
v3:
- Add Chris' Reviewed-by
Unchanged in v2drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)drivers/gpu/drm/rockchip/dw-mipi-dsi.c +5
-5@@ -474,14 +474,14 @@ static int dw_mipi_dsi_phy_init(struct dw_mipi_dsi *dsi) PHY_UNRSTZ | PHY_UNSHUTDOWNZ); - ret =readx_poll_timeout (readl, dsi->base +DSI_PHY_STATUS , + ret =readl_poll_timeout (dsi->base +DSI_PHY_STATUS , val, val &LOCK ,1000 ,PHY_STATUS_TIMEOUT_US );if (ret <0 ) {dev_err (dsi->dev,"failed to wait for phy lock state\n" );return ret; } - ret =readx_poll_timeout (readl, dsi->base +DSI_PHY_STATUS , + ret =readl_poll_timeout (dsi->base +DSI_PHY_STATUS , val, val &STOP_STATE_CLK_LANE ,1000 ,PHY_STATUS_TIMEOUT_US );if (ret <0 ) {@@ -597,7 +597,7 @@ static int dw_mipi_dsi_gen_pkt_hdr_write(struct dw_mipi_dsi *dsi, u32 hdr_val)int ret;u32 val, mask; - ret =readx_poll_timeout (readl, dsi->base +DSI_CMD_PKT_STATUS , + ret =readl_poll_timeout (dsi->base +DSI_CMD_PKT_STATUS , val, !(val &GEN_CMD_FULL ),1000 ,CMD_PKT_STATUS_TIMEOUT_US );if (ret <0 ) {@@ -608,7 +608,7 @@ static int dw_mipi_dsi_gen_pkt_hdr_write(struct dw_mipi_dsi *dsi, u32 hdr_val)dsi_write (dsi,DSI_GEN_HDR , hdr_val); mask =GEN_CMD_EMPTY |GEN_PLD_W_EMPTY ; - ret =readx_poll_timeout (readl, dsi->base +DSI_CMD_PKT_STATUS , + ret =readl_poll_timeout (dsi->base +DSI_CMD_PKT_STATUS , val, (val & mask) == mask,1000 ,CMD_PKT_STATUS_TIMEOUT_US );if (ret <0 ) {@@ -667,7 +667,7 @@ static int dw_mipi_dsi_dcs_long_write(struct dw_mipi_dsi *dsi, len -= pld_data_bytes; } - ret =readx_poll_timeout (readl, dsi->base +DSI_CMD_PKT_STATUS , + ret =readl_poll_timeout (dsi->base +DSI_CMD_PKT_STATUS , val, !(val &GEN_PLD_W_FULL ),1000 ,CMD_PKT_STATUS_TIMEOUT_US );if (ret <0 ) {Signature · 6 lines
2.11.0.197.gb556de5.dirty _______________________________________________ dri-devel mailing list dri-devel at lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Signature · 1 line
Sean Paul, Software Engineer, Google / Chromium OS
PATCH v3 19/24 drm/rockchip: dw-mipi-dsi: use positive check for N{H,V}SYNC
In reply to John KeepingThis matches other drivers.
---
Unchanged in v3
Unchanged in v2
drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/gpu/drm/rockchip/dw-mipi-dsi.c +2 -2
@@ -774,9 +774,9 @@ static void dw_mipi_dsi_dpi_config(struct dw_mipi_dsi *dsi,break ; } -if (!(mode->flags &DRM_MODE_FLAG_PVSYNC )) +if (mode->flags &DRM_MODE_FLAG_NVSYNC ) val |=VSYNC_ACTIVE_LOW ; -if (!(mode->flags &DRM_MODE_FLAG_PHSYNC )) +if (mode->flags &DRM_MODE_FLAG_NHSYNC ) val |=HSYNC_ACTIVE_LOW ;dsi_write (dsi,DSI_DPI_VCID ,DPI_VID (dsi->channel));
Signature · 1 line
2.11.0.197.gb556de5.dirty
Re: [PATCH v3 19/24] drm/rockchip: dw-mipi-dsi: use positive check for N{H, V}SYNC
Quoted 2 lines · John Keeping
This matches other drivers.
Quoted 31 lines
Signed-off-by John Keeping <[email protected]>---
Unchanged in v3
Unchanged in v2drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)drivers/gpu/drm/rockchip/dw-mipi-dsi.c +2
-2@@ -774,9 +774,9 @@ static void dw_mipi_dsi_dpi_config(struct dw_mipi_dsi *dsi,break ; } -if (!(mode->flags &DRM_MODE_FLAG_PVSYNC )) +if (mode->flags &DRM_MODE_FLAG_NVSYNC ) val |=VSYNC_ACTIVE_LOW ; -if (!(mode->flags &DRM_MODE_FLAG_PHSYNC )) +if (mode->flags &DRM_MODE_FLAG_NHSYNC ) val |=HSYNC_ACTIVE_LOW ;dsi_write (dsi,DSI_DPI_VCID ,DPI_VID (dsi->channel));Signature · 6 lines
2.11.0.197.gb556de5.dirty _______________________________________________ dri-devel mailing list dri-devel at lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Signature · 1 line
Sean Paul, Software Engineer, Google / Chromium OS
PATCH v3 20/24 drm/rockchip: vop: test for P{H,V}SYNC
In reply to John KeepingWhen connected to the MIPI DSI output, we need to use N{H,V}SYNC for the internal connection but these flags are meaningless for DSI panels. Switch the test so that we do not set the P{H,V}SYNC bits unless the mode requires it.
---
v3:
- Add Mark's Reviewed-by
Unchanged in v2
drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/gpu/drm/rockchip/rockchip_drm_vop.c +2 -2
@@ -933,8 +933,8 @@ static void vop_crtc_enable(struct drm_crtc *crtc) } pin_pol =0x8 ; - pin_pol |= (adjusted_mode->flags &DRM_MODE_FLAG_NHSYNC ) ?0 :1 ; - pin_pol |= (adjusted_mode->flags &DRM_MODE_FLAG_NVSYNC ) ?0 : (1 <<1 ); + pin_pol |= (adjusted_mode->flags &DRM_MODE_FLAG_PHSYNC ) ?1 :0 ; + pin_pol |= (adjusted_mode->flags &DRM_MODE_FLAG_PVSYNC ) ? (1 <<1 ) :0 ;VOP_CTRL_SET (vop, pin_pol, pin_pol);switch (s->output_type) {
Signature · 1 line
2.11.0.197.gb556de5.dirty
Re: [PATCH v3 20/24] drm/rockchip: vop: test for P{H,V}SYNC
Quoted 5 lines · John Keeping
When connected to the MIPI DSI output, we need to use N{H,V}SYNC for the internal connection but these flags are meaningless for DSI panels. Switch the test so that we do not set the P{H,V}SYNC bits unless the mode requires it.
Quoted 32 lines
Signed-off-by John Keeping <[email protected]>Reviewed-by Mark Yao <[email protected]>---
v3:
- Add Mark's Reviewed-by
Unchanged in v2drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)drivers/gpu/drm/rockchip/rockchip_drm_vop.c +2
-2@@ -933,8 +933,8 @@ static void vop_crtc_enable(struct drm_crtc *crtc) } pin_pol =0x8 ; - pin_pol |= (adjusted_mode->flags &DRM_MODE_FLAG_NHSYNC ) ?0 :1 ; - pin_pol |= (adjusted_mode->flags &DRM_MODE_FLAG_NVSYNC ) ?0 : (1 <<1 ); + pin_pol |= (adjusted_mode->flags &DRM_MODE_FLAG_PHSYNC ) ?1 :0 ; + pin_pol |= (adjusted_mode->flags &DRM_MODE_FLAG_PVSYNC ) ? (1 <<1 ) :0 ;VOP_CTRL_SET (vop, pin_pol, pin_pol);switch (s->output_type) {Signature · 6 lines
2.11.0.197.gb556de5.dirty _______________________________________________ dri-devel mailing list dri-devel at lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Signature · 1 line
Sean Paul, Software Engineer, Google / Chromium OS
PATCH v3 21/24 drm/rockchip: dw-mipi-dsi: defer probe if panel is not loaded
In reply to John KeepingThis ensures that the output resolution is known before fbcon loads.
---
Unchanged in v3
Unchanged in v2
drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-)
drivers/gpu/drm/rockchip/dw-mipi-dsi.c +9 -2
@@ -1176,10 +1176,17 @@ static int dw_mipi_dsi_bind(struct device *dev, struct device *master, dsi->dsi_host.ops = &dw_mipi_dsi_host_ops; dsi->dsi_host.dev = dev; -return mipi_dsi_host_register (&dsi->dsi_host); + ret =mipi_dsi_host_register (&dsi->dsi_host); +if (!ret && !dsi->panel) { +mipi_dsi_host_unregister (&dsi->dsi_host); +drm_encoder_cleanup (&dsi->encoder); +drm_connector_cleanup (&dsi->connector); + ret = -EPROBE_DEFER ; + } err_pllref: -clk_disable_unprepare (dsi->pllref_clk); +if (ret) +clk_disable_unprepare (dsi->pllref_clk);return ret; }
Signature · 1 line
2.11.0.197.gb556de5.dirty
Re: [PATCH v3 21/24] drm/rockchip: dw-mipi-dsi: defer probe if panel is not loaded
Quoted 15 lines · John Keeping
This ensures that the output resolution is known before fbcon loads.
Signed-off-by John Keeping <[email protected]>---
Unchanged in v3
Unchanged in v2drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-)drivers/gpu/drm/rockchip/dw-mipi-dsi.c +0
-0
drivers/gpu/drm/rockchip/dw-mipi-dsi.c static int dw_mipi_dsi_bind(struct device *dev, struct device *master, · line 1183
Quoted 9 lines
drivers/gpu/drm/rockchip/dw-mipi-dsi.c +5
-1@@ -1176,10 +1176,17 @@ static int dw_mipi_dsi_bind(struct device *dev, struct device *master, dsi->dsi_host.ops = &dw_mipi_dsi_host_ops; dsi->dsi_host.dev = dev; -return mipi_dsi_host_register (&dsi->dsi_host); + ret =mipi_dsi_host_register (&dsi->dsi_host); +if (!ret && !dsi->panel) { +mipi_dsi_host_unregister (&dsi->dsi_host); +drm_encoder_cleanup (&dsi->encoder); +drm_connector_cleanup (&dsi->connector);
Move the host registration up before dw_mipi_dsi_register() to avoid having to clean up the encoder and connector?
drivers/gpu/drm/rockchip/dw-mipi-dsi.c static int dw_mipi_dsi_bind(struct device *dev, struct device *master, · line 1188
Quoted 6 lines
drivers/gpu/drm/rockchip/dw-mipi-dsi.c +3
-1+ ret = -EPROBE_DEFER ; + } err_pllref: -clk_disable_unprepare (dsi->pllref_clk); +if (ret)
I personally think it's cleaner to explicitly goto in the error conditional (or in this case, the defer conditional) and have a return 0; right before the err_* labels. Then you don't need to worry about a) checking ret in all of your cleanups and b) someone adding code above the labels that you don't intend to run.
Sean
Quoted 11 lines
drivers/gpu/drm/rockchip/dw-mipi-dsi.c +1
-0+clk_disable_unprepare (dsi->pllref_clk);return ret; }Signature · 6 lines
2.11.0.197.gb556de5.dirty _______________________________________________ dri-devel mailing list dri-devel at lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Signature · 1 line
Sean Paul, Software Engineer, Google / Chromium OS
Re: [PATCH v3 21/24] drm/rockchip: dw-mipi-dsi: defer probe if panel is not loaded
Quoted 17 lines · Sean Paul
Quoted 16 lines · John Keeping
This ensures that the output resolution is known before fbcon loads.
Signed-off-by John Keeping <[email protected]>---
Unchanged in v3
Unchanged in v2drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-)drivers/gpu/drm/rockchip/dw-mipi-dsi.c +0
-0@@ -1176,10 +1176,17 @@ static int dw_mipi_dsi_bind(struct device *dev, struct device *master,
Quoted 11 lines
drivers/gpu/drm/rockchip/dw-mipi-dsi.c static int dw_mipi_dsi_bind(struct device *dev, struct device *master, · line 1183
Quoted 8 lines
drivers/gpu/drm/rockchip/dw-mipi-dsi.c +5
-1dsi->dsi_host.ops = &dw_mipi_dsi_host_ops; dsi->dsi_host.dev = dev; -return mipi_dsi_host_register (&dsi->dsi_host); + ret =mipi_dsi_host_register (&dsi->dsi_host); +if (!ret && !dsi->panel) { +mipi_dsi_host_unregister (&dsi->dsi_host); +drm_encoder_cleanup (&dsi->encoder); +drm_connector_cleanup (&dsi->connector);Move the host registration up before
dw_mipi_dsi_register()to avoid having to clean up the encoder and connector?
No, mipi_dsi_host_register() has to be called after the connector is registered because it is likely to result in a call to dw_mipi_dsi_host_attach() which attaches a panel to the connector.
Quoted 12 lines
drivers/gpu/drm/rockchip/dw-mipi-dsi.c static int dw_mipi_dsi_bind(struct device *dev, struct device *master, · line 1188
Quoted 6 lines
drivers/gpu/drm/rockchip/dw-mipi-dsi.c +3
-1+ ret = -EPROBE_DEFER ; + } err_pllref: -clk_disable_unprepare (dsi->pllref_clk); +if (ret)I personally think it's cleaner to explicitly goto in the error conditional (or in this case, the defer conditional) and have a return 0; right before the err_* labels. Then you don't need to worry about a) checking ret in all of your cleanups and b) someone adding code above the labels that you don't intend to run.
Agreed. I'll change this to use a goto if we hit the EPROBE_DEFER case and keep all the cleanup together.
Quoted 3 lines
Quoted 3 lines
drivers/gpu/drm/rockchip/dw-mipi-dsi.c +1
-0+clk_disable_unprepare (dsi->pllref_clk);return ret; }
PATCH v3 22/24 drm/rockchip: dw-mipi-dsi: support non-burst modes
In reply to John Keeping---
v3:
- Add Chris' Reviewed-by
Unchanged in v2
drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-)
drivers/gpu/drm/rockchip/dw-mipi-dsi.c +9 -7
@@ -82,6 +82,7 @@#define FRAME_BTA_ACK BIT(14)#define ENABLE_LOW_POWER (0x3f << 8)#define ENABLE_LOW_POWER_MASK (0x3f << 8) +#define VID_MODE_TYPE_NON_BURST_SYNC_EVENTS 0x1#define VID_MODE_TYPE_BURST_SYNC_PULSES 0x2#define VID_MODE_TYPE_MASK 0x3
@@ -286,6 +287,7 @@ struct dw_mipi_dsi {u32 format;u16 input_div;u16 feedback_div; +unsigned long mode_flags;const struct dw_mipi_dsi_plat_data *pdata; };
@@ -551,15 +553,10 @@ static int dw_mipi_dsi_host_attach(struct mipi_dsi_host *host,return -EINVAL ; } -if (!(device->mode_flags &MIPI_DSI_MODE_VIDEO_BURST ) || - !(device->mode_flags &MIPI_DSI_MODE_VIDEO_SYNC_PULSE )) { -dev_err (dsi->dev,"device mode is unsupported\n" ); -return -EINVAL ; - } - dsi->lanes = device->lanes; dsi->channel = device->channel; dsi->format = device->format; + dsi->mode_flags = device->mode_flags; dsi->panel =of_drm_find_panel (device->dev.of_node);if (dsi->panel)return drm_panel_attach (dsi->panel, &dsi->connector);
@@ -716,7 +713,12 @@ static void dw_mipi_dsi_video_mode_config(struct dw_mipi_dsi *dsi) {u32 val; - val =VID_MODE_TYPE_BURST_SYNC_PULSES |ENABLE_LOW_POWER ; + val =ENABLE_LOW_POWER ; + +if (dsi->mode_flags &MIPI_DSI_MODE_VIDEO_BURST ) + val |=VID_MODE_TYPE_BURST_SYNC_PULSES ; +else if (!(dsi->mode_flags &MIPI_DSI_MODE_VIDEO_SYNC_PULSE )) + val |=VID_MODE_TYPE_NON_BURST_SYNC_EVENTS ;dsi_write (dsi,DSI_VID_MODE_CFG , val); }
Signature · 1 line
2.11.0.197.gb556de5.dirty
Re: [PATCH v3 22/24] drm/rockchip: dw-mipi-dsi: support non-burst modes
On Sun, Jan 29, 2017 at 01:24:42PM +0000, John Keeping wrote:
Quoted 68 lines
Signed-off-by John Keeping <[email protected]>Reviewed-by Chris Zhong <[email protected]>---
v3:
- Add Chris' Reviewed-by
Unchanged in v2drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-)drivers/gpu/drm/rockchip/dw-mipi-dsi.c +9
-7@@ -82,6 +82,7 @@#define FRAME_BTA_ACK BIT(14)#define ENABLE_LOW_POWER (0x3f << 8)#define ENABLE_LOW_POWER_MASK (0x3f << 8) +#define VID_MODE_TYPE_NON_BURST_SYNC_EVENTS 0x1#define VID_MODE_TYPE_BURST_SYNC_PULSES 0x2#define VID_MODE_TYPE_MASK 0x3@@ -286,6 +287,7 @@ struct dw_mipi_dsi {u32 format;u16 input_div;u16 feedback_div; +unsigned long mode_flags;const struct dw_mipi_dsi_plat_data *pdata; };@@ -551,15 +553,10 @@ static int dw_mipi_dsi_host_attach(struct mipi_dsi_host *host,return -EINVAL ; } -if (!(device->mode_flags &MIPI_DSI_MODE_VIDEO_BURST ) || - !(device->mode_flags &MIPI_DSI_MODE_VIDEO_SYNC_PULSE )) { -dev_err (dsi->dev,"device mode is unsupported\n" ); -return -EINVAL ; - } - dsi->lanes = device->lanes; dsi->channel = device->channel; dsi->format = device->format; + dsi->mode_flags = device->mode_flags; dsi->panel =of_drm_find_panel (device->dev.of_node);if (dsi->panel)return drm_panel_attach (dsi->panel, &dsi->connector);@@ -716,7 +713,12 @@ static void dw_mipi_dsi_video_mode_config(struct dw_mipi_dsi *dsi) {u32 val; - val =VID_MODE_TYPE_BURST_SYNC_PULSES |ENABLE_LOW_POWER ; + val =ENABLE_LOW_POWER ; + +if (dsi->mode_flags &MIPI_DSI_MODE_VIDEO_BURST ) + val |=VID_MODE_TYPE_BURST_SYNC_PULSES ; +else if (!(dsi->mode_flags &MIPI_DSI_MODE_VIDEO_SYNC_PULSE )) + val |=VID_MODE_TYPE_NON_BURST_SYNC_EVENTS ;dsi_write (dsi,DSI_VID_MODE_CFG , val); }Signature · 6 lines
2.11.0.197.gb556de5.dirty _______________________________________________ dri-devel mailing list dri-devel at lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Signature · 1 line
Sean Paul, Software Engineer, Google / Chromium OS
Re: [PATCH v3 22/24] drm/rockchip: dw-mipi-dsi: support non-burst modes
Hi John
Quoted 14 lines · Sean Paul
On Sun, Jan 29, 2017 at 01:24:42PM +0000, John Keeping wrote:
Reviewed-by Sean Paul <[email protected]>Quoted 10 lines
Signed-off-by John Keeping <[email protected]>Reviewed-by Chris Zhong <[email protected]>---
v3:
- Add Chris' Reviewed-by
Unchanged in v2drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-)
Quoted 10 lines
drivers/gpu/drm/rockchip/dw-mipi-dsi.c line 86
Quoted 10 lines
drivers/gpu/drm/rockchip/dw-mipi-dsi.c +1
-0@@ -82,6 +82,7 @@#define FRAME_BTA_ACK BIT(14)#define ENABLE_LOW_POWER (0x3f << 8)#define ENABLE_LOW_POWER_MASK (0x3f << 8) +#define VID_MODE_TYPE_NON_BURST_SYNC_EVENTS 0x1#define VID_MODE_TYPE_BURST_SYNC_PULSES 0x2
This field indicates the video mode transmission type as follows:
00: Non-burst with sync pulses
01: Non-burst with sync events
10 and 11: Burst mode
So, I think define the macro like this is better:
#define VID_MODE_TYPE_NON_BURST_SYNC_PULSES 0x0
#define VID_MODE_TYPE_NON_BURST_SYNC_EVENTS 0x1
#define VID_MODE_TYPE_BURST 0x2
Quoted 31 lines
Quoted 31 lines
drivers/gpu/drm/rockchip/dw-mipi-dsi.c +2
-6#define VID_MODE_TYPE_MASK 0x3@@ -286,6 +287,7 @@ struct dw_mipi_dsi {u32 format;u16 input_div;u16 feedback_div; +unsigned long mode_flags;const struct dw_mipi_dsi_plat_data *pdata; };@@ -551,15 +553,10 @@ static int dw_mipi_dsi_host_attach(struct mipi_dsi_host *host,return -EINVAL ; } -if (!(device->mode_flags &MIPI_DSI_MODE_VIDEO_BURST ) || - !(device->mode_flags &MIPI_DSI_MODE_VIDEO_SYNC_PULSE )) { -dev_err (dsi->dev,"device mode is unsupported\n" ); -return -EINVAL ; - } - dsi->lanes = device->lanes; dsi->channel = device->channel; dsi->format = device->format; + dsi->mode_flags = device->mode_flags; dsi->panel =of_drm_find_panel (device->dev.of_node);if (dsi->panel)return drm_panel_attach (dsi->panel, &dsi->connector);@@ -716,7 +713,12 @@ static void dw_mipi_dsi_video_mode_config(struct dw_mipi_dsi *dsi) {u32 val;
Quoted 7 lines
drivers/gpu/drm/rockchip/dw-mipi-dsi.c static void dw_mipi_dsi_video_mode_config(struct dw_mipi_dsi *dsi) · line 721
Quoted 7 lines
drivers/gpu/drm/rockchip/dw-mipi-dsi.c +6
-1- val =VID_MODE_TYPE_BURST_SYNC_PULSES |ENABLE_LOW_POWER ; + val =ENABLE_LOW_POWER ; + +if (dsi->mode_flags &MIPI_DSI_MODE_VIDEO_BURST ) + val |=VID_MODE_TYPE_BURST_SYNC_PULSES ; +else if (!(dsi->mode_flags &MIPI_DSI_MODE_VIDEO_SYNC_PULSE )) + val |=VID_MODE_TYPE_NON_BURST_SYNC_EVENTS ;
if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_BURST)
val |= VID_MODE_TYPE_BURST; else if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE) val |= VID_MODE_TYPE_NON_BURST_SYNC_PULSES; else val |= VID_MODE_TYPE_NON_BURST_SYNC_EVENTS;
Quoted 10 lines
Quoted 10 lines
drivers/gpu/drm/rockchip/dw-mipi-dsi.c +0
-0dsi_write (dsi,DSI_VID_MODE_CFG , val); }Signature · 6 lines
2.11.0.197.gb556de5.dirty _______________________________________________ dri-devel mailing list dri-devel at lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v3 22/24] drm/rockchip: dw-mipi-dsi: support non-burst modes
Quoted 77 lines · Chris Zhong
Quoted 14 lines · Sean Paul
On Sun, Jan 29, 2017 at 01:24:42PM +0000, John Keeping wrote:
Reviewed-by Sean Paul <[email protected]>Quoted 10 lines
Signed-off-by John Keeping <[email protected]>Reviewed-by Chris Zhong <[email protected]>---
v3:
- Add Chris' Reviewed-by
Unchanged in v2drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-)Quoted 10 lines
drivers/gpu/drm/rockchip/dw-mipi-dsi.c line 86
Quoted 10 lines
drivers/gpu/drm/rockchip/dw-mipi-dsi.c +1
-0@@ -82,6 +82,7 @@#define FRAME_BTA_ACK BIT(14)#define ENABLE_LOW_POWER (0x3f << 8)#define ENABLE_LOW_POWER_MASK (0x3f << 8) +#define VID_MODE_TYPE_NON_BURST_SYNC_EVENTS 0x1#define VID_MODE_TYPE_BURST_SYNC_PULSES 0x2This field indicates the video mode transmission type as follows:
00: Non-burst with sync pulses
01: Non-burst with sync events
10 and 11: Burst modeSo, I think define the macro like this is better:
#define
VID_MODE_TYPE_NON_BURST_SYNC_PULSES0x0
#defineVID_MODE_TYPE_NON_BURST_SYNC_EVENTS0x1
#defineVID_MODE_TYPE_BURST0x2Quoted 31 lines
Quoted 31 lines
drivers/gpu/drm/rockchip/dw-mipi-dsi.c +2
-6#define VID_MODE_TYPE_MASK 0x3@@ -286,6 +287,7 @@ struct dw_mipi_dsi {u32 format;u16 input_div;u16 feedback_div; +unsigned long mode_flags;const struct dw_mipi_dsi_plat_data *pdata; };@@ -551,15 +553,10 @@ static int dw_mipi_dsi_host_attach(struct mipi_dsi_host *host,return -EINVAL ; } -if (!(device->mode_flags &MIPI_DSI_MODE_VIDEO_BURST ) || - !(device->mode_flags &MIPI_DSI_MODE_VIDEO_SYNC_PULSE )) { -dev_err (dsi->dev,"device mode is unsupported\n" ); -return -EINVAL ; - } - dsi->lanes = device->lanes; dsi->channel = device->channel; dsi->format = device->format; + dsi->mode_flags = device->mode_flags; dsi->panel =of_drm_find_panel (device->dev.of_node);if (dsi->panel)return drm_panel_attach (dsi->panel, &dsi->connector);@@ -716,7 +713,12 @@ static void dw_mipi_dsi_video_mode_config(struct dw_mipi_dsi *dsi) {u32 val;Quoted 7 lines
drivers/gpu/drm/rockchip/dw-mipi-dsi.c static void dw_mipi_dsi_video_mode_config(struct dw_mipi_dsi *dsi) · line 721
Quoted 7 lines
drivers/gpu/drm/rockchip/dw-mipi-dsi.c +6
-1- val =VID_MODE_TYPE_BURST_SYNC_PULSES |ENABLE_LOW_POWER ; + val =ENABLE_LOW_POWER ; + +if (dsi->mode_flags &MIPI_DSI_MODE_VIDEO_BURST ) + val |=VID_MODE_TYPE_BURST_SYNC_PULSES ; +else if (!(dsi->mode_flags &MIPI_DSI_MODE_VIDEO_SYNC_PULSE )) + val |=VID_MODE_TYPE_NON_BURST_SYNC_EVENTS ;if (
dsi->mode_flags&MIPI_DSI_MODE_VIDEO_BURST)
Quoted 5 lines
val |= VID_MODE_TYPE_BURST; else if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE) val |= VID_MODE_TYPE_NON_BURST_SYNC_PULSES; else val |= VID_MODE_TYPE_NON_BURST_SYNC_EVENTS;
OK, this is definitely clearer now that I've forgotten most of the datasheet; without your definitions at the top it's not clear that VID_MODE_TYPE_BURST_SYNC_PULSES is zero.
PATCH v3 23/24 drm/rockchip: dw-mipi-dsi: add reset control
In reply to John KeepingIn order to fully reset the state of the MIPI controller we must assert this reset.
This is slightly more complicated than it could be in order to maintain compatibility with device trees that do not specify the reset property.
---
v3:
- Add Chris' Reviewed-by
Unchanged in v2
drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+)
drivers/gpu/drm/rockchip/dw-mipi-dsi.c +30 -0
@@ -13,6 +13,7 @@#include <linux/module.h> #include <linux/of_device.h> #include <linux/regmap.h> +#include <linux/reset.h> #include <linux/mfd/syscon.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_crtc.h>
@@ -1124,6 +1125,7 @@ static int dw_mipi_dsi_bind(struct device *dev, struct device *master,of_match_device (dw_mipi_dsi_dt_ids, dev);const struct dw_mipi_dsi_plat_data *pdata = of_id->data;struct platform_device *pdev =to_platform_device (dev); +struct reset_control *apb_rst;struct drm_device *drm = data;struct dw_mipi_dsi *dsi;struct resource *res;
@@ -1162,6 +1164,34 @@ static int dw_mipi_dsi_bind(struct device *dev, struct device *master,return ret; } +/* +* Note that the reset was not defined in the initial device tree, so +* we have to be prepared for it not being found. +*/ + apb_rst =devm_reset_control_get (dev,"apb" ); +if (IS_ERR (apb_rst)) { +if (PTR_ERR (apb_rst) == -ENODEV ) { + apb_rst =NULL ; + }else { +dev_err (dev,"Unable to get reset control: %d\n" , ret); +return PTR_ERR (apb_rst); + } + } + +if (apb_rst) { + ret =clk_prepare_enable (dsi->pclk); +if (ret) { +dev_err (dev,"%s: Failed to enable pclk\n" , __func__); +return ret; + } + +reset_control_assert (apb_rst); +usleep_range (10 ,20 ); +reset_control_deassert (apb_rst); + +clk_disable_unprepare (dsi->pclk); + } + ret =clk_prepare_enable (dsi->pllref_clk);if (ret) {dev_err (dev,"%s: Failed to enable pllref_clk\n" , __func__);
Signature · 1 line
2.11.0.197.gb556de5.dirty
Re: [PATCH v3 23/24] drm/rockchip: dw-mipi-dsi: add reset control
Quoted 6 lines · John Keeping
In order to fully reset the state of the MIPI controller we must assert this reset.
This is slightly more complicated than it could be in order to maintain compatibility with device trees that do not specify the reset property.
I always find it a little grating to see a device managed resource given to a local variable that is used immediately and only once. However, I think this might just be one of my twitches. So now that I've aired my grievance,
Quoted 72 lines
Signed-off-by John Keeping <[email protected]>Reviewed-by Chris Zhong <[email protected]>---
v3:
- Add Chris' Reviewed-by
Unchanged in v2drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+)drivers/gpu/drm/rockchip/dw-mipi-dsi.c +30
-0@@ -13,6 +13,7 @@#include <linux/module.h> #include <linux/of_device.h> #include <linux/regmap.h> +#include <linux/reset.h> #include <linux/mfd/syscon.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_crtc.h> @@ -1124,6 +1125,7 @@ static int dw_mipi_dsi_bind(struct device *dev, struct device *master,of_match_device (dw_mipi_dsi_dt_ids, dev);const struct dw_mipi_dsi_plat_data *pdata = of_id->data;struct platform_device *pdev =to_platform_device (dev); +struct reset_control *apb_rst;struct drm_device *drm = data;struct dw_mipi_dsi *dsi;struct resource *res;@@ -1162,6 +1164,34 @@ static int dw_mipi_dsi_bind(struct device *dev, struct device *master,return ret; } +/* +* Note that the reset was not defined in the initial device tree, so +* we have to be prepared for it not being found. +*/ + apb_rst =devm_reset_control_get (dev,"apb" ); +if (IS_ERR (apb_rst)) { +if (PTR_ERR (apb_rst) == -ENODEV ) { + apb_rst =NULL ; + }else { +dev_err (dev,"Unable to get reset control: %d\n" , ret); +return PTR_ERR (apb_rst); + } + } + +if (apb_rst) { + ret =clk_prepare_enable (dsi->pclk); +if (ret) { +dev_err (dev,"%s: Failed to enable pclk\n" , __func__); +return ret; + } + +reset_control_assert (apb_rst); +usleep_range (10 ,20 ); +reset_control_deassert (apb_rst); + +clk_disable_unprepare (dsi->pclk); + } + ret =clk_prepare_enable (dsi->pllref_clk);if (ret) {dev_err (dev,"%s: Failed to enable pllref_clk\n" , __func__);Signature · 6 lines
2.11.0.197.gb556de5.dirty _______________________________________________ dri-devel mailing list dri-devel at lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Signature · 1 line
Sean Paul, Software Engineer, Google / Chromium OS
Re: [PATCH v3 23/24] drm/rockchip: dw-mipi-dsi: add reset control
In reply to John KeepingHi John
Quoted 37 lines · John Keeping
In order to fully reset the state of the MIPI controller we must assert this reset.
This is slightly more complicated than it could be in order to maintain compatibility with device trees that do not specify the reset property.
Signed-off-by John Keeping <[email protected]>Reviewed-by Chris Zhong <[email protected]>---
v3:
- Add Chris' Reviewed-by
Unchanged in v2drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+)drivers/gpu/drm/rockchip/dw-mipi-dsi.c +2
-0@@ -13,6 +13,7 @@#include <linux/module.h> #include <linux/of_device.h> #include <linux/regmap.h> +#include <linux/reset.h> #include <linux/mfd/syscon.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_crtc.h> @@ -1124,6 +1125,7 @@ static int dw_mipi_dsi_bind(struct device *dev, struct device *master,of_match_device (dw_mipi_dsi_dt_ids, dev);const struct dw_mipi_dsi_plat_data *pdata = of_id->data;struct platform_device *pdev =to_platform_device (dev); +struct reset_control *apb_rst;struct drm_device *drm = data;struct dw_mipi_dsi *dsi;struct resource *res;
drivers/gpu/drm/rockchip/dw-mipi-dsi.c static int dw_mipi_dsi_bind(struct device *dev, struct device *master, · line 1173
Quoted 10 lines
drivers/gpu/drm/rockchip/dw-mipi-dsi.c +7
-0@@ -1162,6 +1164,34 @@ static int dw_mipi_dsi_bind(struct device *dev, struct device *master,return ret; } +/* +* Note that the reset was not defined in the initial device tree, so +* we have to be prepared for it not being found. +*/ + apb_rst =devm_reset_control_get (dev,"apb" ); +if (IS_ERR (apb_rst)) { +if (PTR_ERR (apb_rst) == -ENODEV ) {
According to [0], I think it should be -ENOENT here.
commit 3d81216fde465e76c5eae98f61d3666163634395
Author: Alban Bedel <[email protected]> Date: Tue Sep 1 17:28:31 2015 +0200
reset: Fix of_reset_control_get() for consistent return values
When of_reset_control_get() is called without connection ID it returns -ENOENT when the 'resets' property doesn't exists or is an empty entry. However when a connection ID is given it returns -EINVAL when the
'resets'
property doesn't exists or the requested name can't be found. This is because the error code returned by of_property_match_string() is just passed down as an index to of_parse_phandle_with_args(), which then returns -EINVAL.
To get a consistent return value with both code paths we must return -ENOENT when of_property_match_string() fails.
Quoted 24 lines
drivers/gpu/drm/rockchip/dw-mipi-dsi.c +21
-0+ apb_rst =NULL ; + }else { +dev_err (dev,"Unable to get reset control: %d\n" , ret); +return PTR_ERR (apb_rst); + } + } + +if (apb_rst) { + ret =clk_prepare_enable (dsi->pclk); +if (ret) { +dev_err (dev,"%s: Failed to enable pclk\n" , __func__); +return ret; + } + +reset_control_assert (apb_rst); +usleep_range (10 ,20 ); +reset_control_deassert (apb_rst); + +clk_disable_unprepare (dsi->pclk); + } + ret =clk_prepare_enable (dsi->pllref_clk);if (ret) {dev_err (dev,"%s: Failed to enable pllref_clk\n" , __func__);
Re: [PATCH v3 23/24] drm/rockchip: dw-mipi-dsi: add reset control
Quoted 41 lines · Chris Zhong
Quoted 40 lines · John Keeping
In order to fully reset the state of the MIPI controller we must assert this reset.
This is slightly more complicated than it could be in order to maintain compatibility with device trees that do not specify the reset property.
Signed-off-by John Keeping <[email protected]>Reviewed-by Chris Zhong <[email protected]>---
v3:
- Add Chris' Reviewed-by
Unchanged in v2drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+)drivers/gpu/drm/rockchip/dw-mipi-dsi.c +2
-0@@ -13,6 +13,7 @@#include <linux/module.h> #include <linux/of_device.h> #include <linux/regmap.h> +#include <linux/reset.h> #include <linux/mfd/syscon.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_crtc.h> @@ -1124,6 +1125,7 @@ static int dw_mipi_dsi_bind(struct device *dev, struct device *master,of_match_device (dw_mipi_dsi_dt_ids, dev);const struct dw_mipi_dsi_plat_data *pdata = of_id->data;struct platform_device *pdev =to_platform_device (dev); +struct reset_control *apb_rst;struct drm_device *drm = data;struct dw_mipi_dsi *dsi;struct resource *res;@@ -1162,6 +1164,34 @@ static int dw_mipi_dsi_bind(struct device *dev, struct device *master,return ret; }
Quoted 8 lines
drivers/gpu/drm/rockchip/dw-mipi-dsi.c static int dw_mipi_dsi_bind(struct device *dev, struct device *master, · line 1173
Quoted 7 lines
drivers/gpu/drm/rockchip/dw-mipi-dsi.c +7
-0+/* +* Note that the reset was not defined in the initial device tree, so +* we have to be prepared for it not being found. +*/ + apb_rst =devm_reset_control_get (dev,"apb" ); +if (IS_ERR (apb_rst)) { +if (PTR_ERR (apb_rst) == -ENODEV ) {According to [0], I think it should be
-ENOENThere.
Nice catch, I'll fix this.
Quoted 51 lines
commit
3d81216fde465e76c5eae98f61d3666163634395Author: Alban Bedel <[email protected]> Date: Tue Sep 1 17:28:31 2015 +0200reset: Fix
of_reset_control_get()for consistent return valuesWhen
of_reset_control_get()is called without connection ID it returns-ENOENTwhen the 'resets' property doesn't exists or is an empty entry. However when a connection ID is given it returns-EINVALwhen the
'resets'
property doesn't exists or the requested name can't be found. This is because the error code returned byof_property_match_string()is just passed down as an index toof_parse_phandle_with_args(), which then returns-EINVAL.To get a consistent return value with both code paths we must return
-ENOENTwhenof_property_match_string()fails.Signed-off-by Alban Bedel <[email protected]>Signed-off-by Philipp Zabel <[email protected]>Quoted 24 lines
drivers/gpu/drm/rockchip/dw-mipi-dsi.c +21
-0+ apb_rst =NULL ; + }else { +dev_err (dev,"Unable to get reset control: %d\n" , ret); +return PTR_ERR (apb_rst); + } + } + +if (apb_rst) { + ret =clk_prepare_enable (dsi->pclk); +if (ret) { +dev_err (dev,"%s: Failed to enable pclk\n" , __func__); +return ret; + } + +reset_control_assert (apb_rst); +usleep_range (10 ,20 ); +reset_control_deassert (apb_rst); + +clk_disable_unprepare (dsi->pclk); + } + ret =clk_prepare_enable (dsi->pllref_clk);if (ret) {dev_err (dev,"%s: Failed to enable pllref_clk\n" , __func__);
Re: [PATCH v3 23/24] drm/rockchip: dw-mipi-dsi: add reset control
Hi John
Quoted 74 lines · John Keeping
Quoted 41 lines · Chris Zhong
Quoted 40 lines · John Keeping
In order to fully reset the state of the MIPI controller we must assert this reset.
This is slightly more complicated than it could be in order to maintain compatibility with device trees that do not specify the reset property.
Signed-off-by John Keeping <[email protected]>Reviewed-by Chris Zhong <[email protected]>---
v3:
- Add Chris' Reviewed-by
Unchanged in v2drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+)drivers/gpu/drm/rockchip/dw-mipi-dsi.c +2
-0@@ -13,6 +13,7 @@#include <linux/module.h> #include <linux/of_device.h> #include <linux/regmap.h> +#include <linux/reset.h> #include <linux/mfd/syscon.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_crtc.h> @@ -1124,6 +1125,7 @@ static int dw_mipi_dsi_bind(struct device *dev, struct device *master,of_match_device (dw_mipi_dsi_dt_ids, dev);const struct dw_mipi_dsi_plat_data *pdata = of_id->data;struct platform_device *pdev =to_platform_device (dev); +struct reset_control *apb_rst;struct drm_device *drm = data;struct dw_mipi_dsi *dsi;struct resource *res;@@ -1162,6 +1164,34 @@ static int dw_mipi_dsi_bind(struct device *dev, struct device *master,return ret; }Quoted 8 lines
drivers/gpu/drm/rockchip/dw-mipi-dsi.c static int dw_mipi_dsi_bind(struct device *dev, struct device *master, · line 1173
Quoted 7 lines
drivers/gpu/drm/rockchip/dw-mipi-dsi.c +7
-0+/* +* Note that the reset was not defined in the initial device tree, so +* we have to be prepared for it not being found. +*/ + apb_rst =devm_reset_control_get (dev,"apb" ); +if (IS_ERR (apb_rst)) { +if (PTR_ERR (apb_rst) == -ENODEV ) {According to [0], I think it should be
-ENOENThere.Nice catch, I'll fix this.
Quoted 21 lines
commit
3d81216fde465e76c5eae98f61d3666163634395Author: Alban Bedel <[email protected]> Date: Tue Sep 1 17:28:31 2015 +0200reset: Fix
of_reset_control_get()for consistent return valuesWhen
of_reset_control_get()is called without connection ID it returns-ENOENTwhen the 'resets' property doesn't exists or is an empty entry. However when a connection ID is given it returns-EINVALwhen the
'resets'
property doesn't exists or the requested name can't be found. This is because the error code returned byof_property_match_string()is just passed down as an index toof_parse_phandle_with_args(), which then returns-EINVAL.To get a consistent return value with both code paths we must return
-ENOENTwhenof_property_match_string()fails.
Quoted 7 lines
Quoted 7 lines
Signed-off-by Alban Bedel <[email protected]>Signed-off-by Philipp Zabel <[email protected]>drivers/gpu/drm/rockchip/dw-mipi-dsi.c static int dw_mipi_dsi_bind(struct device *dev, struct device *master, · line 1176
Quoted 3 lines
drivers/gpu/drm/rockchip/dw-mipi-dsi.c +3
-0+ apb_rst =NULL ; + }else { +dev_err (dev,"Unable to get reset control: %d\n" , ret);
Also, we can not get error number from "ret" here.
Quoted 24 lines
Quoted 22 lines
Quoted 21 lines
drivers/gpu/drm/rockchip/dw-mipi-dsi.c +18
-0+return PTR_ERR (apb_rst); + } + } + +if (apb_rst) { + ret =clk_prepare_enable (dsi->pclk); +if (ret) { +dev_err (dev,"%s: Failed to enable pclk\n" , __func__); +return ret; + } + +reset_control_assert (apb_rst); +usleep_range (10 ,20 ); +reset_control_deassert (apb_rst); + +clk_disable_unprepare (dsi->pclk); + } + ret =clk_prepare_enable (dsi->pllref_clk);if (ret) {dev_err (dev,"%s: Failed to enable pllref_clk\n" , __func__);
Re: [PATCH v3 23/24] drm/rockchip: dw-mipi-dsi: add reset control
Quoted 75 lines · Chris Zhong
Quoted 74 lines · John Keeping
Quoted 41 lines · Chris Zhong
Quoted 40 lines · John Keeping
In order to fully reset the state of the MIPI controller we must assert this reset.
This is slightly more complicated than it could be in order to maintain compatibility with device trees that do not specify the reset property.
Signed-off-by John Keeping <[email protected]>Reviewed-by Chris Zhong <[email protected]>---
v3:
- Add Chris' Reviewed-by
Unchanged in v2drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+)drivers/gpu/drm/rockchip/dw-mipi-dsi.c +2
-0@@ -13,6 +13,7 @@#include <linux/module.h> #include <linux/of_device.h> #include <linux/regmap.h> +#include <linux/reset.h> #include <linux/mfd/syscon.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_crtc.h> @@ -1124,6 +1125,7 @@ static int dw_mipi_dsi_bind(struct device *dev, struct device *master,of_match_device (dw_mipi_dsi_dt_ids, dev);const struct dw_mipi_dsi_plat_data *pdata = of_id->data;struct platform_device *pdev =to_platform_device (dev); +struct reset_control *apb_rst;struct drm_device *drm = data;struct dw_mipi_dsi *dsi;struct resource *res;@@ -1162,6 +1164,34 @@ static int dw_mipi_dsi_bind(struct device *dev, struct device *master,return ret; }Quoted 8 lines
drivers/gpu/drm/rockchip/dw-mipi-dsi.c static int dw_mipi_dsi_bind(struct device *dev, struct device *master, · line 1173
Quoted 7 lines
drivers/gpu/drm/rockchip/dw-mipi-dsi.c +7
-0+/* +* Note that the reset was not defined in the initial device tree, so +* we have to be prepared for it not being found. +*/ + apb_rst =devm_reset_control_get (dev,"apb" ); +if (IS_ERR (apb_rst)) { +if (PTR_ERR (apb_rst) == -ENODEV ) {According to [0], I think it should be
-ENOENThere.Nice catch, I'll fix this.
Quoted 21 lines
commit
3d81216fde465e76c5eae98f61d3666163634395Author: Alban Bedel <[email protected]> Date: Tue Sep 1 17:28:31 2015 +0200reset: Fix
of_reset_control_get()for consistent return valuesWhen
of_reset_control_get()is called without connection ID it returns-ENOENTwhen the 'resets' property doesn't exists or is an empty entry. However when a connection ID is given it returns-EINVALwhen the
'resets'
property doesn't exists or the requested name can't be found. This is because the error code returned byof_property_match_string()is just passed down as an index toof_parse_phandle_with_args(), which then returns-EINVAL.To get a consistent return value with both code paths we must return
-ENOENTwhenof_property_match_string()fails.
Quoted 8 lines
Quoted 7 lines
Quoted 7 lines
Signed-off-by Alban Bedel <[email protected]>Signed-off-by Philipp Zabel <[email protected]>drivers/gpu/drm/rockchip/dw-mipi-dsi.c static int dw_mipi_dsi_bind(struct device *dev, struct device *master, · line 1176
Quoted 3 lines
drivers/gpu/drm/rockchip/dw-mipi-dsi.c +3
-0+ apb_rst =NULL ; + }else { +dev_err (dev,"Unable to get reset control: %d\n" , ret);Also, we can not get error number from "ret" here.
Good point, I'll fix this.
John
PATCH v3 24/24 drm/rockchip: dw-mipi-dsi: support read commands
In reply to John KeepingI haven't found any method for getting the length of a response, so this just uses the requested rx_len
---
v3:
- Fix checkpatch warnings
Unchanged in v2
drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 56 ++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+)
drivers/gpu/drm/rockchip/dw-mipi-dsi.c +56 -0
@@ -678,6 +678,56 @@ static int dw_mipi_dsi_dcs_long_write(struct dw_mipi_dsi *dsi,return dw_mipi_dsi_gen_pkt_hdr_write (dsi, hdr_val); } +static int dw_mipi_dsi_dcs_read (struct dw_mipi_dsi *dsi, +const struct mipi_dsi_msg *msg) +{ +const u8 *tx_buf = msg->tx_buf; +u8 *rx_buf = msg->rx_buf; +size_t i; +int ret, val; + +dsi_write (dsi,DSI_PCKHDL_CFG ,EN_CRC_RX |EN_ECC_RX |EN_BTA ); +dsi_write (dsi,DSI_GEN_HDR , +GEN_HDATA (tx_buf[0 ]) |GEN_HTYPE (msg->type)); + + ret =readl_poll_timeout (dsi->base +DSI_CMD_PKT_STATUS , + val, !(val &GEN_RD_CMD_BUSY ),1000 , +CMD_PKT_STATUS_TIMEOUT_US ); +if (ret <0 ) { +dev_err (dsi->dev,"failed to read command response\n" ); +return ret; + } + +for (i =0 ; i < msg->rx_len;) { +u32 pld =dsi_read (dsi,DSI_GEN_PLD_DATA ); + +while (i < msg->rx_len) { + rx_buf[i] = pld &0xff ; + pld >>=8 ; + i++; + } + } + +return msg->rx_len; +} + +static int dw_mipi_dsi_set_max_return_packet_size (struct dw_mipi_dsi *dsi, +size_t len) +{ +u8 val[] = { len &0xff , (len >>8 ) &0xff }; +struct mipi_dsi_msg msg = { + .channel = dsi->channel, + .type =MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE , + .tx_buf = val, + .tx_len =2 , + }; + +if (len >0xffff ) +return -EINVAL ; + +return dw_mipi_dsi_dcs_short_write (dsi, &msg); +} +static ssize_t dw_mipi_dsi_host_transfer (struct mipi_dsi_host *host,const struct mipi_dsi_msg *msg) {
@@ -695,6 +745,12 @@ static ssize_t dw_mipi_dsi_host_transfer(struct mipi_dsi_host *host,case MIPI_DSI_DCS_LONG_WRITE : ret =dw_mipi_dsi_dcs_long_write (dsi, msg);break ; +case MIPI_DSI_DCS_READ : + ret =dw_mipi_dsi_set_max_return_packet_size (dsi, msg->rx_len); +if (ret <0 ) +return ret; + ret =dw_mipi_dsi_dcs_read (dsi, msg); +break ;default :dev_err (dsi->dev,"unsupported message type 0x%02x\n" , msg->type);
Signature · 1 line
2.11.0.197.gb556de5.dirty
Re: [PATCH v3 24/24] drm/rockchip: dw-mipi-dsi: support read commands
Quoted 39 lines · John Keeping
I haven't found any method for getting the length of a response, so this just uses the requested
rx_lenSigned-off-by John Keeping <[email protected]>---
v3:
- Fix checkpatch warnings
Unchanged in v2drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 56 ++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+)drivers/gpu/drm/rockchip/dw-mipi-dsi.c +19
-0@@ -678,6 +678,56 @@ static int dw_mipi_dsi_dcs_long_write(struct dw_mipi_dsi *dsi,return dw_mipi_dsi_gen_pkt_hdr_write (dsi, hdr_val); } +static int dw_mipi_dsi_dcs_read (struct dw_mipi_dsi *dsi, +const struct mipi_dsi_msg *msg) +{ +const u8 *tx_buf = msg->tx_buf; +u8 *rx_buf = msg->rx_buf; +size_t i; +int ret, val; + +dsi_write (dsi,DSI_PCKHDL_CFG ,EN_CRC_RX |EN_ECC_RX |EN_BTA ); +dsi_write (dsi,DSI_GEN_HDR , +GEN_HDATA (tx_buf[0 ]) |GEN_HTYPE (msg->type)); + + ret =readl_poll_timeout (dsi->base +DSI_CMD_PKT_STATUS , + val, !(val &GEN_RD_CMD_BUSY ),1000 , +CMD_PKT_STATUS_TIMEOUT_US ); +if (ret <0 ) { +dev_err (dsi->dev,"failed to read command response\n" ); +return ret; + }
drivers/gpu/drm/rockchip/dw-mipi-dsi.c static int dw_mipi_dsi_dcs_long_write(struct dw_mipi_dsi *dsi, · line 709
Quoted 10 lines
drivers/gpu/drm/rockchip/dw-mipi-dsi.c +10
-0+ +for (i =0 ; i < msg->rx_len;) { +u32 pld =dsi_read (dsi,DSI_GEN_PLD_DATA ); + +while (i < msg->rx_len) { + rx_buf[i] = pld &0xff ; + pld >>=8 ; + i++; + } + }
AFAICT, the outer for loop just initializes i and ensures msg->rx_len is non-zero?
I think the following would be easier to read (and safe against the case where msg->rx_len > sizeof(pld) (even though this shouldn't happen according to DCS spec)).
if (msg->rx_len > 0) {
u32 pld = dsi_read(dsi, DSI_GEN_PLD_DATA);
memcpy(rx_buf, &pld, MIN(msg->rx_len, sizeof(pld));
}Quoted 44 lines
drivers/gpu/drm/rockchip/dw-mipi-dsi.c +27
-0+ +return msg->rx_len; +} + +static int dw_mipi_dsi_set_max_return_packet_size (struct dw_mipi_dsi *dsi, +size_t len) +{ +u8 val[] = { len &0xff , (len >>8 ) &0xff }; +struct mipi_dsi_msg msg = { + .channel = dsi->channel, + .type =MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE , + .tx_buf = val, + .tx_len =2 , + }; + +if (len >0xffff ) +return -EINVAL ; + +return dw_mipi_dsi_dcs_short_write (dsi, &msg); +} +static ssize_t dw_mipi_dsi_host_transfer (struct mipi_dsi_host *host,const struct mipi_dsi_msg *msg) {@@ -695,6 +745,12 @@ static ssize_t dw_mipi_dsi_host_transfer(struct mipi_dsi_host *host,case MIPI_DSI_DCS_LONG_WRITE : ret =dw_mipi_dsi_dcs_long_write (dsi, msg);break ; +case MIPI_DSI_DCS_READ : + ret =dw_mipi_dsi_set_max_return_packet_size (dsi, msg->rx_len); +if (ret <0 ) +return ret; + ret =dw_mipi_dsi_dcs_read (dsi, msg); +break ;default :dev_err (dsi->dev,"unsupported message type 0x%02x\n" , msg->type);Signature · 6 lines
2.11.0.197.gb556de5.dirty _______________________________________________ dri-devel mailing list dri-devel at lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Signature · 1 line
Sean Paul, Software Engineer, Google / Chromium OS
Re: [PATCH v3 24/24] drm/rockchip: dw-mipi-dsi: support read commands
Quoted 54 lines · Sean Paul
Quoted 39 lines · John Keeping
I haven't found any method for getting the length of a response, so this just uses the requested
rx_lenSigned-off-by John Keeping <[email protected]>---
v3:
- Fix checkpatch warnings
Unchanged in v2drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 56 ++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+)drivers/gpu/drm/rockchip/dw-mipi-dsi.c +19
-0@@ -678,6 +678,56 @@ static int dw_mipi_dsi_dcs_long_write(struct dw_mipi_dsi *dsi,return dw_mipi_dsi_gen_pkt_hdr_write (dsi, hdr_val); } +static int dw_mipi_dsi_dcs_read (struct dw_mipi_dsi *dsi, +const struct mipi_dsi_msg *msg) +{ +const u8 *tx_buf = msg->tx_buf; +u8 *rx_buf = msg->rx_buf; +size_t i; +int ret, val; + +dsi_write (dsi,DSI_PCKHDL_CFG ,EN_CRC_RX |EN_ECC_RX |EN_BTA ); +dsi_write (dsi,DSI_GEN_HDR , +GEN_HDATA (tx_buf[0 ]) |GEN_HTYPE (msg->type)); + + ret =readl_poll_timeout (dsi->base +DSI_CMD_PKT_STATUS , + val, !(val &GEN_RD_CMD_BUSY ),1000 , +CMD_PKT_STATUS_TIMEOUT_US ); +if (ret <0 ) { +dev_err (dsi->dev,"failed to read command response\n" ); +return ret; + }drivers/gpu/drm/rockchip/dw-mipi-dsi.c static int dw_mipi_dsi_dcs_long_write(struct dw_mipi_dsi *dsi, · line 709
Quoted 10 lines
drivers/gpu/drm/rockchip/dw-mipi-dsi.c +10
-0+ +for (i =0 ; i < msg->rx_len;) { +u32 pld =dsi_read (dsi,DSI_GEN_PLD_DATA ); + +while (i < msg->rx_len) { + rx_buf[i] = pld &0xff ; + pld >>=8 ; + i++; + } + }AFAICT, the outer for loop just initializes i and ensures
msg->rx_lenis non-zero?
Quoted 8 lines
I think the following would be easier to read (and safe against the case where
msg->rx_len> sizeof(pld) (even though this shouldn't happen according to DCS spec)).if (msg->rx_len > 0) { u32 pld = dsi_read(dsi, DSI_GEN_PLD_DATA); memcpy(rx_buf, &pld, MIN(msg->rx_len, sizeof(pld)); }
I think the intent was to handle rx_len > 4, but the patch is obvously completely broken regarding that. As far as I can tell, rx_len is limited by the maximum return packet size which can be any value up to the maximum size of a long packet, so we may need to read from the FIFO multiple times.
The loop should be something like this:
for (i = 0; i < msg->rx_len;) {
u32 pld = dsi_read(dsi, DSI_GEN_PLD_DATA);
int j;
for (j = 0; j < 4 && i < msg->rx_len; i++, j++) {
rx_buf[i] = pld & 0xff;
pld >>= 8;
}
}I have successfully read 5 bytes from a DSI display using this code, but I'm tempted to just drop this patch since I only used it for debugging while bringing up a new panel.
Re: [PATCH v3 24/24] drm/rockchip: dw-mipi-dsi: support read commands
Quoted 73 lines · John Keeping
Quoted 54 lines · Sean Paul
Quoted 39 lines · John Keeping
I haven't found any method for getting the length of a response, so this just uses the requested
rx_lenSigned-off-by John Keeping <[email protected]>---
v3:
- Fix checkpatch warnings
Unchanged in v2drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 56 ++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+)drivers/gpu/drm/rockchip/dw-mipi-dsi.c +19
-0@@ -678,6 +678,56 @@ static int dw_mipi_dsi_dcs_long_write(struct dw_mipi_dsi *dsi,return dw_mipi_dsi_gen_pkt_hdr_write (dsi, hdr_val); } +static int dw_mipi_dsi_dcs_read (struct dw_mipi_dsi *dsi, +const struct mipi_dsi_msg *msg) +{ +const u8 *tx_buf = msg->tx_buf; +u8 *rx_buf = msg->rx_buf; +size_t i; +int ret, val; + +dsi_write (dsi,DSI_PCKHDL_CFG ,EN_CRC_RX |EN_ECC_RX |EN_BTA ); +dsi_write (dsi,DSI_GEN_HDR , +GEN_HDATA (tx_buf[0 ]) |GEN_HTYPE (msg->type)); + + ret =readl_poll_timeout (dsi->base +DSI_CMD_PKT_STATUS , + val, !(val &GEN_RD_CMD_BUSY ),1000 , +CMD_PKT_STATUS_TIMEOUT_US ); +if (ret <0 ) { +dev_err (dsi->dev,"failed to read command response\n" ); +return ret; + }drivers/gpu/drm/rockchip/dw-mipi-dsi.c static int dw_mipi_dsi_dcs_long_write(struct dw_mipi_dsi *dsi, · line 709
Quoted 10 lines
drivers/gpu/drm/rockchip/dw-mipi-dsi.c +10
-0+ +for (i =0 ; i < msg->rx_len;) { +u32 pld =dsi_read (dsi,DSI_GEN_PLD_DATA ); + +while (i < msg->rx_len) { + rx_buf[i] = pld &0xff ; + pld >>=8 ; + i++; + } + }AFAICT, the outer for loop just initializes i and ensures
msg->rx_lenis non-zero?Quoted 8 lines
I think the following would be easier to read (and safe against the case where
msg->rx_len> sizeof(pld) (even though this shouldn't happen according to DCS spec)).if (msg->rx_len > 0) { u32 pld = dsi_read(dsi, DSI_GEN_PLD_DATA); memcpy(rx_buf, &pld, MIN(msg->rx_len, sizeof(pld)); }I think the intent was to handle
rx_len> 4, but the patch is obvously completely broken regarding that. As far as I can tell,rx_lenis limited by the maximum return packet size which can be any value up to the maximum size of a long packet, so we may need to read from the FIFO multiple times.The loop should be something like this:
Quoted 9 lines
for (i = 0; i < msg->rx_len;) {
u32 pld = dsi_read(dsi, DSI_GEN_PLD_DATA);
int j;
for (j = 0; j < 4 && i < msg->rx_len; i++, j++) {
rx_buf[i] = pld & 0xff;
pld >>= 8;
}
}Short packets should never exceed 32 bits, so I don't think you need to add the nested loop.
Sean
Quoted 8 lines
I have successfully read 5 bytes from a DSI display using this code, but I'm tempted to just drop this patch since I only used it for debugging while bringing up a new panel.
_______________________________________________
dri-devel mailing list
dri-devel at lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
Signature · 1 line
Sean Paul, Software Engineer, Google / Chromium OS
Re: [PATCH v3 24/24] drm/rockchip: dw-mipi-dsi: support read commands
Quoted 78 lines · Sean Paul
Quoted 77 lines · John Keeping
Quoted 54 lines · Sean Paul
Quoted 39 lines · John Keeping
I haven't found any method for getting the length of a response, so this just uses the requested
rx_lenSigned-off-by John Keeping <[email protected]>---
v3:
- Fix checkpatch warnings
Unchanged in v2drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 56 ++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+)drivers/gpu/drm/rockchip/dw-mipi-dsi.c +19
-0@@ -678,6 +678,56 @@ static int dw_mipi_dsi_dcs_long_write(struct dw_mipi_dsi *dsi,return dw_mipi_dsi_gen_pkt_hdr_write (dsi, hdr_val); } +static int dw_mipi_dsi_dcs_read (struct dw_mipi_dsi *dsi, +const struct mipi_dsi_msg *msg) +{ +const u8 *tx_buf = msg->tx_buf; +u8 *rx_buf = msg->rx_buf; +size_t i; +int ret, val; + +dsi_write (dsi,DSI_PCKHDL_CFG ,EN_CRC_RX |EN_ECC_RX |EN_BTA ); +dsi_write (dsi,DSI_GEN_HDR , +GEN_HDATA (tx_buf[0 ]) |GEN_HTYPE (msg->type)); + + ret =readl_poll_timeout (dsi->base +DSI_CMD_PKT_STATUS , + val, !(val &GEN_RD_CMD_BUSY ),1000 , +CMD_PKT_STATUS_TIMEOUT_US ); +if (ret <0 ) { +dev_err (dsi->dev,"failed to read command response\n" ); +return ret; + }drivers/gpu/drm/rockchip/dw-mipi-dsi.c static int dw_mipi_dsi_dcs_long_write(struct dw_mipi_dsi *dsi, · line 709
Quoted 10 lines
drivers/gpu/drm/rockchip/dw-mipi-dsi.c +10
-0+ +for (i =0 ; i < msg->rx_len;) { +u32 pld =dsi_read (dsi,DSI_GEN_PLD_DATA ); + +while (i < msg->rx_len) { + rx_buf[i] = pld &0xff ; + pld >>=8 ; + i++; + } + }AFAICT, the outer for loop just initializes i and ensures
msg->rx_lenis non-zero?Quoted 8 lines
I think the following would be easier to read (and safe against the case where
msg->rx_len> sizeof(pld) (even though this shouldn't happen according to DCS spec)).if (msg->rx_len > 0) { u32 pld = dsi_read(dsi, DSI_GEN_PLD_DATA); memcpy(rx_buf, &pld, MIN(msg->rx_len, sizeof(pld)); }I think the intent was to handle
rx_len> 4, but the patch is obvously completely broken regarding that. As far as I can tell,rx_lenis limited by the maximum return packet size which can be any value up to the maximum size of a long packet, so we may need to read from the FIFO multiple times.The loop should be something like this:
for (i = 0; i < msg->rx_len;) { u32 pld = dsi_read(dsi, DSI_GEN_PLD_DATA); int j;
Quoted 8 lines
Quoted 5 lines
for (j = 0; j < 4 && i < msg->rx_len; i++, j++) { rx_buf[i] = pld & 0xff; pld >>= 8; } }Short packets should never exceed 32 bits, so I don't think you need to add the nested loop.
The read response is not restricted to a short packet. I have a panel that documents a read request that returns up to 64KiB, admittedly with a continuation command and the panels I have seem to only be programmed to return 5 bytes of meaningful data, but they do return all of those bytes in a single read response.
Re: [PATCH v3 24/24] drm/rockchip: dw-mipi-dsi: support read commands
Quoted 86 lines · John Keeping
Quoted 84 lines · Sean Paul
Quoted 82 lines · John Keeping
Quoted 54 lines · Sean Paul
Quoted 39 lines · John Keeping
I haven't found any method for getting the length of a response, so this just uses the requested
rx_lenSigned-off-by John Keeping <[email protected]>---
v3:
- Fix checkpatch warnings
Unchanged in v2drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 56 ++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+)drivers/gpu/drm/rockchip/dw-mipi-dsi.c +19
-0@@ -678,6 +678,56 @@ static int dw_mipi_dsi_dcs_long_write(struct dw_mipi_dsi *dsi,return dw_mipi_dsi_gen_pkt_hdr_write (dsi, hdr_val); } +static int dw_mipi_dsi_dcs_read (struct dw_mipi_dsi *dsi, +const struct mipi_dsi_msg *msg) +{ +const u8 *tx_buf = msg->tx_buf; +u8 *rx_buf = msg->rx_buf; +size_t i; +int ret, val; + +dsi_write (dsi,DSI_PCKHDL_CFG ,EN_CRC_RX |EN_ECC_RX |EN_BTA ); +dsi_write (dsi,DSI_GEN_HDR , +GEN_HDATA (tx_buf[0 ]) |GEN_HTYPE (msg->type)); + + ret =readl_poll_timeout (dsi->base +DSI_CMD_PKT_STATUS , + val, !(val &GEN_RD_CMD_BUSY ),1000 , +CMD_PKT_STATUS_TIMEOUT_US ); +if (ret <0 ) { +dev_err (dsi->dev,"failed to read command response\n" ); +return ret; + }drivers/gpu/drm/rockchip/dw-mipi-dsi.c static int dw_mipi_dsi_dcs_long_write(struct dw_mipi_dsi *dsi, · line 709
Quoted 10 lines
drivers/gpu/drm/rockchip/dw-mipi-dsi.c +10
-0+ +for (i =0 ; i < msg->rx_len;) { +u32 pld =dsi_read (dsi,DSI_GEN_PLD_DATA ); + +while (i < msg->rx_len) { + rx_buf[i] = pld &0xff ; + pld >>=8 ; + i++; + } + }AFAICT, the outer for loop just initializes i and ensures
msg->rx_lenis non-zero?Quoted 8 lines
I think the following would be easier to read (and safe against the case where
msg->rx_len> sizeof(pld) (even though this shouldn't happen according to DCS spec)).if (msg->rx_len > 0) { u32 pld = dsi_read(dsi, DSI_GEN_PLD_DATA); memcpy(rx_buf, &pld, MIN(msg->rx_len, sizeof(pld)); }I think the intent was to handle
rx_len> 4, but the patch is obvously completely broken regarding that. As far as I can tell,rx_lenis limited by the maximum return packet size which can be any value up to the maximum size of a long packet, so we may need to read from the FIFO multiple times.The loop should be something like this:
for (i = 0; i < msg->rx_len;) { u32 pld = dsi_read(dsi, DSI_GEN_PLD_DATA); int j; for (j = 0; j < 4 && i < msg->rx_len; i++, j++) { rx_buf[i] = pld & 0xff; pld >>= 8; } }
Quoted 8 lines
Quoted 2 lines
Short packets should never exceed 32 bits, so I don't think you need to add the nested loop.
The read response is not restricted to a short packet. I have a panel that documents a read request that returns up to 64KiB, admittedly with a continuation command and the panels I have seem to only be programmed to return 5 bytes of meaningful data, but they do return all of those bytes in a single read response.
Ah, apologies for the misunderstanding. In that case, I think you can get away with replacing the inner loop in your snippet with a memcpy and call it a day.
Sean
Quoted 4 lines
_______________________________________________
dri-devel mailing list
dri-devel at lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
Signature · 1 line
Sean Paul, Software Engineer, Google / Chromium OS