This patch programs D-PHY timing parameters for the
clock and data lane (in escape clocks) of DSI
controller (DSI port 0 and 1).
These programmed timings would be used by DSI Controller
to calculate link transition latencies of the data and
clock lanes.

Signed-off-by: Madhav Chauhan <madhav.chau...@intel.com>
---
 drivers/gpu/drm/i915/intel_dsi.h     |   3 +
 drivers/gpu/drm/i915/intel_dsi_new.c |  18 ++++
 drivers/gpu/drm/i915/intel_dsi_vbt.c | 200 +++++++++++++++++++++++++----------
 3 files changed, 165 insertions(+), 56 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dsi.h b/drivers/gpu/drm/i915/intel_dsi.h
index 7afeb95..12a8154 100644
--- a/drivers/gpu/drm/i915/intel_dsi.h
+++ b/drivers/gpu/drm/i915/intel_dsi.h
@@ -85,6 +85,9 @@ struct intel_dsi {
        u32 port_bits;
        u32 bw_timer;
        u32 dphy_reg;
+
+       /* data lanes dphy timing */
+       u32 dphy_data_lane_reg;
        u32 video_frmt_cfg_bits;
        u16 lp_byte_clk;
 
diff --git a/drivers/gpu/drm/i915/intel_dsi_new.c 
b/drivers/gpu/drm/i915/intel_dsi_new.c
index db65633..ffc17d1 100644
--- a/drivers/gpu/drm/i915/intel_dsi_new.c
+++ b/drivers/gpu/drm/i915/intel_dsi_new.c
@@ -284,6 +284,24 @@ static void gen11_dsi_setup_dphy_timings(struct 
intel_encoder *encoder)
                tmp |= intel_dsi->init_count;
                I915_WRITE(ICL_DSI_T_INIT_MASTER(port), tmp);
        }
+
+       /* Program DPHY clock lanes timings */
+       for_each_dsi_port(port, intel_dsi->ports) {
+               I915_WRITE(DPHY_CLK_TIMING_PARAM(port), intel_dsi->dphy_reg);
+
+               /* shadow register inside display core */
+               I915_WRITE(DSI_CLK_TIMING_PARAM(port), intel_dsi->dphy_reg);
+       }
+
+       /* Program DPHY data lanes timings */
+       for_each_dsi_port(port, intel_dsi->ports) {
+               I915_WRITE(DPHY_DATA_TIMING_PARAM(port),
+                          intel_dsi->dphy_data_lane_reg);
+
+               /* shadow register inside display core */
+               I915_WRITE(DSI_DATA_TIMING_PARAM(port),
+                          intel_dsi->dphy_data_lane_reg);
+       }
 }
 
 static void gen11_dsi_enable_port_and_phy(struct intel_encoder *encoder)
diff --git a/drivers/gpu/drm/i915/intel_dsi_vbt.c 
b/drivers/gpu/drm/i915/intel_dsi_vbt.c
index 4d6ffa7..5cc3dd0 100644
--- a/drivers/gpu/drm/i915/intel_dsi_vbt.c
+++ b/drivers/gpu/drm/i915/intel_dsi_vbt.c
@@ -509,7 +509,9 @@ bool intel_dsi_vbt_init(struct intel_dsi *intel_dsi, u16 
panel_id)
        u32 bpp;
        u32 tlpx_ns, extra_byte_count, bitrate, tlpx_ui;
        u32 ui_num, ui_den;
-       u32 prepare_cnt, exit_zero_cnt, clk_zero_cnt, trail_cnt;
+       u32 prepare_cnt, exit_zero_cnt, clk_zero_cnt, trail_cnt, hs_zero_cnt;
+       u32 tclk_pre_cnt, tclk_post_cnt;
+       u32 tclk_pre_ns, tclk_post_ns;
        u32 ths_prepare_ns, tclk_trail_ns;
        u32 tclk_prepare_clkzero, ths_prepare_hszero;
        u32 lp_to_hs_switch, hs_to_lp_switch;
@@ -624,76 +626,157 @@ bool intel_dsi_vbt_init(struct intel_dsi *intel_dsi, u16 
panel_id)
 
        tclk_prepare_clkzero = mipi_config->tclk_prepare_clkzero;
        ths_prepare_hszero = mipi_config->ths_prepare_hszero;
-
+       tclk_trail_ns = max(mipi_config->tclk_trail, mipi_config->ths_trail);
+       ths_prepare_ns = max(mipi_config->ths_prepare,
+                               mipi_config->tclk_prepare);
        /*
         * B060
         * LP byte clock = TLPX/ (8UI)
         */
        intel_dsi->lp_byte_clk = DIV_ROUND_UP(tlpx_ns * ui_den, 8 * ui_num);
 
-       /* DDR clock period = 2 * UI
-        * UI(sec) = 1/(bitrate * 10^3) (bitrate is in KHZ)
-        * UI(nsec) = 10^6 / bitrate
-        * DDR clock period (nsec) = 2 * UI = (2 * 10^6)/ bitrate
-        * DDR clock count  = ns_value / DDR clock period
-        *
+       /*
         * For GEMINILAKE dphy_param_reg will be programmed in terms of
         * HS byte clock count for other platform in HS ddr clock count
         */
        mul = IS_GEMINILAKE(dev_priv) ? 8 : 2;
-       ths_prepare_ns = max(mipi_config->ths_prepare,
-                            mipi_config->tclk_prepare);
 
-       /* prepare count */
-       prepare_cnt = DIV_ROUND_UP(ths_prepare_ns * ui_den, ui_num * mul);
+       if (IS_ICELAKE(dev_priv)) {
+               /*
+                * prepare cnt in escape clocks
+                * this field represents a hexadecimal value with a precision
+                * of 1.2 – i.e. the most significant bit is the integer
+                * and the least significant 2 bits are fraction bits.
+                * so, the field can represent a range of 0.25 to 1.75
+                */
+               prepare_cnt = DIV_ROUND_UP(ths_prepare_ns * 4, tlpx_ns);
+
+               /* clk zero count in escape clocks */
+               clk_zero_cnt = DIV_ROUND_UP(
+                                       (tclk_prepare_clkzero - ths_prepare_ns),
+                                       tlpx_ns);
+
+               /* trail cnt in escape clocks*/
+               trail_cnt = DIV_ROUND_UP(tclk_trail_ns, tlpx_ns);
+
+               /* tclk pre/post count in escape clocks */
+               tclk_post_ns = mipi_config->tclk_post;
+               tclk_pre_ns = mipi_config->tclk_pre;
+               tclk_pre_cnt = DIV_ROUND_UP(tclk_pre_ns, tlpx_ns);
+               tclk_post_cnt = DIV_ROUND_UP(tclk_post_ns, tlpx_ns);
+
+               /* hs zero cnt in escape clocks */
+               hs_zero_cnt = DIV_ROUND_UP(
+                                       (ths_prepare_hszero - ths_prepare_ns),
+                                       tlpx_ns);
+
+               /* hs exit zero cnt in escape clocks */
+               exit_zero_cnt = DIV_ROUND_UP(mipi_config->ths_exit, tlpx_ns);
+
+               if (prepare_cnt > 0x7 ||
+                   clk_zero_cnt > 0xF ||
+                   tclk_pre_cnt > 0x3 ||
+                   tclk_post_cnt > 0x7 ||
+                   trail_cnt > 0x7 ||
+                   hs_zero_cnt > 0xF ||
+                   exit_zero_cnt > 0x7) {
+                       DRM_DEBUG_DRIVER("DPHY values crossing max limits,");
+                       DRM_DEBUG_DRIVER("restricting to max values\n");
+               }
+
+               prepare_cnt = (prepare_cnt > 0x7) ? 0x7 : prepare_cnt;
+               clk_zero_cnt = (clk_zero_cnt > 0xF) ? 0xF : clk_zero_cnt;
+               tclk_pre_cnt = (tclk_pre_cnt > 0x3) ? 0x3 : tclk_pre_cnt;
+               tclk_post_cnt = (tclk_post_cnt > 0x7) ? 0x7 : tclk_post_cnt;
+               trail_cnt = (trail_cnt > 0x7) ? 0x7 : trail_cnt;
+               hs_zero_cnt = (hs_zero_cnt > 0xF) ? 0xF : hs_zero_cnt;
+               exit_zero_cnt = (exit_zero_cnt > 0x7) ? 0x7 : exit_zero_cnt;
+
+               /* clock lane dphy timings */
+               intel_dsi->dphy_reg |= (CLK_PREP_OVERRIDE |
+                                       CLK_PREP_TIME(prepare_cnt) |
+                                       CLK_ZERO_OVERRIDE |
+                                       CLK_ZERO_TIME(clk_zero_cnt) |
+                                       CLK_PRE_OVERRIDE |
+                                       CLK_PRE_TIME(tclk_pre_cnt) |
+                                       CLK_POST_OVERRIDE |
+                                       CLK_POST_TIME(tclk_post_cnt) |
+                                       CLK_TRAIL_OVERRIDE |
+                                       CLK_TRAIL_TIME(trail_cnt));
+
+               /* data lanes dphy timings */
+               intel_dsi->dphy_data_lane_reg = HS_PREP_OVERRIDE |
+                                               HS_PREP_TIME(prepare_cnt) |
+                                               HS_ZERO_OVERRIDE |
+                                               HS_ZERO_TIME(hs_zero_cnt) |
+                                               HS_TRAIL_OVERRIDE |
+                                               HS_TRAIL_TIME(trail_cnt) |
+                                               HS_EXIT_OVERRIDE |
+                                               HS_EXIT_TIME(exit_zero_cnt);
+       } else {
+               /*
+                * DDR clock period = 2 * UI
+                * UI(sec) = 1/(bitrate * 10^3) (bitrate is in KHZ)
+                * UI(nsec) = 10^6 / bitrate
+                * DDR clock period (nsec) = 2 * UI = (2 * 10^6)/ bitrate
+                * DDR clock count  = ns_value / DDR clock period
+                */
 
-       if (prepare_cnt > PREPARE_CNT_MAX) {
-               DRM_DEBUG_KMS("prepare count too high %u\n", prepare_cnt);
-               prepare_cnt = PREPARE_CNT_MAX;
-       }
+               /* prepare count */
+               prepare_cnt = DIV_ROUND_UP(ths_prepare_ns * ui_den,
+                                                       ui_num * mul);
 
-       /* exit zero count */
-       exit_zero_cnt = DIV_ROUND_UP(
+               if (prepare_cnt > PREPARE_CNT_MAX) {
+                       DRM_DEBUG_KMS("prepare count too high %u\n",
+                                                               prepare_cnt);
+                       prepare_cnt = PREPARE_CNT_MAX;
+               }
+
+               /* exit zero count */
+               exit_zero_cnt = DIV_ROUND_UP(
                                (ths_prepare_hszero - ths_prepare_ns) * ui_den,
                                ui_num * mul
                                );
 
-       /*
-        * Exit zero is unified val ths_zero and ths_exit
-        * minimum value for ths_exit = 110ns
-        * min (exit_zero_cnt * 2) = 110/UI
-        * exit_zero_cnt = 55/UI
-        */
-       if (exit_zero_cnt < (55 * ui_den / ui_num) && (55 * ui_den) % ui_num)
-               exit_zero_cnt += 1;
-
-       if (exit_zero_cnt > EXIT_ZERO_CNT_MAX) {
-               DRM_DEBUG_KMS("exit zero count too high %u\n", exit_zero_cnt);
-               exit_zero_cnt = EXIT_ZERO_CNT_MAX;
-       }
+               /*
+                * Exit zero is unified val ths_zero and ths_exit
+                * minimum value for ths_exit = 110ns
+                * min (exit_zero_cnt * 2) = 110/UI
+                * exit_zero_cnt = 55/UI
+                */
+               if (exit_zero_cnt < (55 * ui_den / ui_num) &&
+                                       (55 * ui_den) % ui_num)
+                       exit_zero_cnt += 1;
+
+               if (exit_zero_cnt > EXIT_ZERO_CNT_MAX) {
+                       DRM_DEBUG_KMS("exit zero count too high %u\n",
+                                                               exit_zero_cnt);
+                       exit_zero_cnt = EXIT_ZERO_CNT_MAX;
+               }
 
-       /* clk zero count */
-       clk_zero_cnt = DIV_ROUND_UP(
-                               (tclk_prepare_clkzero - ths_prepare_ns)
-                               * ui_den, ui_num * mul);
+               /* clk zero count */
+               clk_zero_cnt = DIV_ROUND_UP((tclk_prepare_clkzero -
+                                               ths_prepare_ns)
+                                               * ui_den, ui_num * mul);
 
-       if (clk_zero_cnt > CLK_ZERO_CNT_MAX) {
-               DRM_DEBUG_KMS("clock zero count too high %u\n", clk_zero_cnt);
-               clk_zero_cnt = CLK_ZERO_CNT_MAX;
-       }
+               if (clk_zero_cnt > CLK_ZERO_CNT_MAX) {
+                       DRM_DEBUG_KMS("clock zero count too high %u\n",
+                                                               clk_zero_cnt);
+                       clk_zero_cnt = CLK_ZERO_CNT_MAX;
+               }
 
-       /* trail count */
-       tclk_trail_ns = max(mipi_config->tclk_trail, mipi_config->ths_trail);
-       trail_cnt = DIV_ROUND_UP(tclk_trail_ns * ui_den, ui_num * mul);
+               /* trail cnt */
+               trail_cnt = DIV_ROUND_UP(tclk_trail_ns * ui_den, ui_num * mul);
 
-       if (trail_cnt > TRAIL_CNT_MAX) {
-               DRM_DEBUG_KMS("trail count too high %u\n", trail_cnt);
-               trail_cnt = TRAIL_CNT_MAX;
-       }
+               if (trail_cnt > TRAIL_CNT_MAX) {
+                       DRM_DEBUG_KMS("trail count too high %u\n", trail_cnt);
+                       trail_cnt = TRAIL_CNT_MAX;
+               }
 
-       /* B080 */
-       intel_dsi->dphy_reg = exit_zero_cnt << 24 | trail_cnt << 16 |
+               /* B080 */
+               intel_dsi->dphy_reg = exit_zero_cnt << 24 | trail_cnt << 16 |
                                                clk_zero_cnt << 8 | prepare_cnt;
+       }
 
        /*
         * LP to HS switch count = 4TLPX + PREP_COUNT * mul + EXIT_ZERO_COUNT *
@@ -707,9 +790,10 @@ bool intel_dsi_vbt_init(struct intel_dsi *intel_dsi, u16 
panel_id)
         */
        tlpx_ui = DIV_ROUND_UP(tlpx_ns * ui_den, ui_num);
 
-       /* B044 */
-       /* FIXME:
-        * The comment above does not match with the code */
+       /*
+        * B044
+        * FIXME: comment above does not match with the code
+        */
        lp_to_hs_switch = DIV_ROUND_UP(4 * tlpx_ui + prepare_cnt * mul +
                                                exit_zero_cnt * mul + 10, 8);
 
@@ -718,8 +802,9 @@ bool intel_dsi_vbt_init(struct intel_dsi *intel_dsi, u16 
panel_id)
        intel_dsi->hs_to_lp_count = max(lp_to_hs_switch, hs_to_lp_switch);
        intel_dsi->hs_to_lp_count += extra_byte_count;
 
-       /* B088 */
-       /* LP -> HS for clock lanes
+       /*
+        * B088
+        * LP -> HS for clock lanes
         * LP clk sync + LP11 + LP01 + tclk_prepare + tclk_zero +
         *                                              extra byte count
         * 2TPLX + 1TLPX + 1 TPLX(in ns) + prepare_cnt * 2 + clk_zero_cnt *
@@ -735,7 +820,8 @@ bool intel_dsi_vbt_init(struct intel_dsi *intel_dsi, u16 
panel_id)
 
        intel_dsi->clk_lp_to_hs_count += extra_byte_count;
 
-       /* HS->LP for Clock Lanes
+       /*
+        * HS->LP for Clock Lanes
         * Low Power clock synchronisations + 1Tx byteclk + tclk_trail +
         *                                              Extra byte count
         * 2TLPX + 8UI + (trail_count*2)(in UI) + Extra byte count
@@ -782,9 +868,11 @@ bool intel_dsi_vbt_init(struct intel_dsi *intel_dsi, u16 
panel_id)
        DRM_DEBUG_KMS("BTA %s\n",
                        enableddisabled(!(intel_dsi->video_frmt_cfg_bits & 
DISABLE_VIDEO_BTA)));
 
-       /* delays in VBT are in unit of 100us, so need to convert
+       /*
+        * delays in VBT are in unit of 100us, so need to convert
         * here in ms
-        * Delay (100us) * 100 /1000 = Delay / 10 (ms) */
+        * Delay (100us) * 100 /1000 = Delay / 10 (ms)
+        */
        intel_dsi->backlight_off_delay = pps->bl_disable_delay / 10;
        intel_dsi->backlight_on_delay = pps->bl_enable_delay / 10;
        intel_dsi->panel_on_delay = pps->panel_on_delay / 10;
-- 
2.7.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to