From 5a4712f472bf67dc81b4d7cc571edca11cf52c87 Mon Sep 17 00:00:00 2001 From: Madhav Chauhan Date: Tue, 30 Oct 2018 13:56:22 +0200 Subject: [PATCH] drm/i915/icl: Program HS_TX_TIMEOUT/LP_RX_TIMEOUT/TA_TIMEOUT registers Program the timeout values (in escape clock) for HS TX, LP RX and TA timeout. HX TX: Ensure that host does not continuously transmit in the HS state. If this timer expires, then host will gracefully end its HS transmission and allow the link to enter into LP state. LP RX: Monitor the length of LP receptions from Peripheral. If timeout happens then host will drive the stop state onto all data lanes (only Data Lane 0 should be receiving anything from the Peripheral). This effectively takes back ownership of the bus transmit in the HS state. TA timeout: Timeout valuefor monitoring Bus Turn-Around (BTA) sequence. BTA sequence should complete within a bounded amount of time, with peripheral acknowledging BTA by driving the stop state. v2 by Jani: - Rebase - Use intel_dsi_bitrate() and intel_dsi_tlpx_ns(intel_dsi) - Squash HX TX, LP RX and TA timeout into one patch - Fix bspec mode set sequence reference - Add FIXME about two timeouts Signed-off-by: Madhav Chauhan Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/60e610ccffe5f8c09dee1c65828f28f25227efce.1540900289.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/icl_dsi.c | 52 ++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_dsi.h | 1 + drivers/gpu/drm/i915/intel_dsi_vbt.c | 1 + 3 files changed, 54 insertions(+) diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c index ac22c74ae146..fd82f349ced9 100644 --- a/drivers/gpu/drm/i915/icl_dsi.c +++ b/drivers/gpu/drm/i915/icl_dsi.c @@ -685,6 +685,55 @@ static void gen11_dsi_enable_transcoder(struct intel_encoder *encoder) } } +static void gen11_dsi_setup_timeouts(struct intel_encoder *encoder) +{ + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); + enum port port; + enum transcoder dsi_trans; + u32 tmp, hs_tx_timeout, lp_rx_timeout, ta_timeout, divisor, mul; + + /* + * escape clock count calculation: + * BYTE_CLK_COUNT = TIME_NS/(8 * UI) + * UI (nsec) = (10^6)/Bitrate + * TIME_NS = (BYTE_CLK_COUNT * 8 * 10^6)/ Bitrate + * ESCAPE_CLK_COUNT = TIME_NS/ESC_CLK_NS + */ + divisor = intel_dsi_tlpx_ns(intel_dsi) * intel_dsi_bitrate(intel_dsi) * 1000; + mul = 8 * 1000000; + hs_tx_timeout = DIV_ROUND_UP(intel_dsi->hs_tx_timeout * mul, + divisor); + lp_rx_timeout = DIV_ROUND_UP(intel_dsi->lp_rx_timeout * mul, divisor); + ta_timeout = DIV_ROUND_UP(intel_dsi->turn_arnd_val * mul, divisor); + + for_each_dsi_port(port, intel_dsi->ports) { + dsi_trans = dsi_port_to_transcoder(port); + + /* program hst_tx_timeout */ + tmp = I915_READ(DSI_HSTX_TO(dsi_trans)); + tmp &= ~HSTX_TIMEOUT_VALUE_MASK; + tmp |= HSTX_TIMEOUT_VALUE(hs_tx_timeout); + I915_WRITE(DSI_HSTX_TO(dsi_trans), tmp); + + /* FIXME: DSI_CALIB_TO */ + + /* program lp_rx_host timeout */ + tmp = I915_READ(DSI_LPRX_HOST_TO(dsi_trans)); + tmp &= ~LPRX_TIMEOUT_VALUE_MASK; + tmp |= LPRX_TIMEOUT_VALUE(lp_rx_timeout); + I915_WRITE(DSI_LPRX_HOST_TO(dsi_trans), tmp); + + /* FIXME: DSI_PWAIT_TO */ + + /* program turn around timeout */ + tmp = I915_READ(DSI_TA_TO(dsi_trans)); + tmp &= ~TA_TIMEOUT_VALUE_MASK; + tmp |= TA_TIMEOUT_VALUE(ta_timeout); + I915_WRITE(DSI_TA_TO(dsi_trans), tmp); + } +} + static void gen11_dsi_enable_port_and_phy(struct intel_encoder *encoder, const struct intel_crtc_state *pipe_config) @@ -704,6 +753,9 @@ gen11_dsi_enable_port_and_phy(struct intel_encoder *encoder, /* setup D-PHY timings */ gen11_dsi_setup_dphy_timings(encoder); + /* step 4h: setup DSI protocol timeouts */ + gen11_dsi_setup_timeouts(encoder); + /* Step (4h, 4i, 4j, 4k): Configure transcoder */ gen11_dsi_configure_transcoder(encoder, pipe_config); } diff --git a/drivers/gpu/drm/i915/intel_dsi.h b/drivers/gpu/drm/i915/intel_dsi.h index 10fd1582a8e2..f2a3ddedcc5d 100644 --- a/drivers/gpu/drm/i915/intel_dsi.h +++ b/drivers/gpu/drm/i915/intel_dsi.h @@ -95,6 +95,7 @@ struct intel_dsi { u16 lp_byte_clk; /* timeouts in byte clocks */ + u16 hs_tx_timeout; u16 lp_rx_timeout; u16 turn_arnd_val; u16 rst_timer_val; diff --git a/drivers/gpu/drm/i915/intel_dsi_vbt.c b/drivers/gpu/drm/i915/intel_dsi_vbt.c index cca071406c25..80bd56e96143 100644 --- a/drivers/gpu/drm/i915/intel_dsi_vbt.c +++ b/drivers/gpu/drm/i915/intel_dsi_vbt.c @@ -799,6 +799,7 @@ bool intel_dsi_vbt_init(struct intel_dsi *intel_dsi, u16 panel_id) intel_dsi->video_mode_format = mipi_config->video_transfer_mode; intel_dsi->escape_clk_div = mipi_config->byte_clk_sel; intel_dsi->lp_rx_timeout = mipi_config->lp_rx_timeout; + intel_dsi->hs_tx_timeout = mipi_config->hs_tx_timeout; intel_dsi->turn_arnd_val = mipi_config->turn_around_timeout; intel_dsi->rst_timer_val = mipi_config->device_reset_timer; intel_dsi->init_count = mipi_config->master_init_timer;