drm/i915/icl: Program HS_TX_TIMEOUT/LP_RX_TIMEOUT/TA_TIMEOUT registers
authorMadhav Chauhan <madhav.chauhan@intel.com>
Tue, 30 Oct 2018 11:56:22 +0000 (13:56 +0200)
committerJani Nikula <jani.nikula@intel.com>
Wed, 31 Oct 2018 11:17:30 +0000 (13:17 +0200)
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 <madhav.chauhan@intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/60e610ccffe5f8c09dee1c65828f28f25227efce.1540900289.git.jani.nikula@intel.com
drivers/gpu/drm/i915/icl_dsi.c
drivers/gpu/drm/i915/intel_dsi.h
drivers/gpu/drm/i915/intel_dsi_vbt.c

index ac22c74ae1467f626b8682e1bdad98544a4e3a6a..fd82f349ced9265f8460ed5178d1355804b5c4a1 100644 (file)
@@ -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);
 }
index 10fd1582a8e27b96f92e3e9ac16d9ad2b6c60019..f2a3ddedcc5dbb4e5878187f982cdec20fee842a 100644 (file)
@@ -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;
index cca071406c25ac09c4df6db165df82bd49bd4e6d..80bd56e96143f0e92c415ce7acf85e1e5dec65ed 100644 (file)
@@ -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;