Message ID | 20190605181735.7020-2-hdegoede@redhat.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [1/3] drm/i915/dsi: Move logging of DSI VBT parameters to a helper function | expand |
On Wed, Jun 05, 2019 at 08:17:34PM +0200, Hans de Goede wrote: > The vlv/icl_dphy_param_init calls do various calculations to set dphy > parameters based on the pclk. > > Move the calling of vlv/icl_dphy_param_init to vlv_dsi_init to give > vlv_dsi_init a chance to tweak the pclk before these calculations are done. > > Changes in v2: > -Also moves the icl and vlv specific dphy_param_init functions from the > generic intel_dsi_vbt.c file into the icl_ and vlv_dsi.c specific files. > > Note icl_dphy_param_init() and vlv_dphy_param_init() are only moved, > otherwise they are completely unchanged. > > Signed-off-by: Hans de Goede <hdegoede@redhat.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> > --- > drivers/gpu/drm/i915/icl_dsi.c | 108 ++++++++++ > drivers/gpu/drm/i915/intel_dsi.h | 1 + > drivers/gpu/drm/i915/intel_dsi_vbt.c | 282 +-------------------------- > drivers/gpu/drm/i915/vlv_dsi.c | 170 ++++++++++++++++ > 4 files changed, 280 insertions(+), 281 deletions(-) > > diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c > index 9d962ea1e635..511c76e788ef 100644 > --- a/drivers/gpu/drm/i915/icl_dsi.c > +++ b/drivers/gpu/drm/i915/icl_dsi.c > @@ -1363,6 +1363,113 @@ static const struct mipi_dsi_host_ops gen11_dsi_host_ops = { > .transfer = gen11_dsi_host_transfer, > }; > > +#define ICL_PREPARE_CNT_MAX 0x7 > +#define ICL_CLK_ZERO_CNT_MAX 0xf > +#define ICL_TRAIL_CNT_MAX 0x7 > +#define ICL_TCLK_PRE_CNT_MAX 0x3 > +#define ICL_TCLK_POST_CNT_MAX 0x7 > +#define ICL_HS_ZERO_CNT_MAX 0xf > +#define ICL_EXIT_ZERO_CNT_MAX 0x7 > + > +static void icl_dphy_param_init(struct intel_dsi *intel_dsi) > +{ > + struct drm_device *dev = intel_dsi->base.base.dev; > + struct drm_i915_private *dev_priv = to_i915(dev); > + struct mipi_config *mipi_config = dev_priv->vbt.dsi.config; > + u32 tlpx_ns; > + u32 prepare_cnt, exit_zero_cnt, clk_zero_cnt, trail_cnt; > + u32 ths_prepare_ns, tclk_trail_ns; > + u32 hs_zero_cnt; > + u32 tclk_pre_cnt, tclk_post_cnt; > + > + tlpx_ns = intel_dsi_tlpx_ns(intel_dsi); > + > + tclk_trail_ns = max(mipi_config->tclk_trail, mipi_config->ths_trail); > + ths_prepare_ns = max(mipi_config->ths_prepare, > + mipi_config->tclk_prepare); > + > + /* > + * 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); > + if (prepare_cnt > ICL_PREPARE_CNT_MAX) { > + DRM_DEBUG_KMS("prepare_cnt out of range (%d)\n", prepare_cnt); > + prepare_cnt = ICL_PREPARE_CNT_MAX; > + } > + > + /* clk zero count in escape clocks */ > + clk_zero_cnt = DIV_ROUND_UP(mipi_config->tclk_prepare_clkzero - > + ths_prepare_ns, tlpx_ns); > + if (clk_zero_cnt > ICL_CLK_ZERO_CNT_MAX) { > + DRM_DEBUG_KMS("clk_zero_cnt out of range (%d)\n", clk_zero_cnt); > + clk_zero_cnt = ICL_CLK_ZERO_CNT_MAX; > + } > + > + /* trail cnt in escape clocks*/ > + trail_cnt = DIV_ROUND_UP(tclk_trail_ns, tlpx_ns); > + if (trail_cnt > ICL_TRAIL_CNT_MAX) { > + DRM_DEBUG_KMS("trail_cnt out of range (%d)\n", trail_cnt); > + trail_cnt = ICL_TRAIL_CNT_MAX; > + } > + > + /* tclk pre count in escape clocks */ > + tclk_pre_cnt = DIV_ROUND_UP(mipi_config->tclk_pre, tlpx_ns); > + if (tclk_pre_cnt > ICL_TCLK_PRE_CNT_MAX) { > + DRM_DEBUG_KMS("tclk_pre_cnt out of range (%d)\n", tclk_pre_cnt); > + tclk_pre_cnt = ICL_TCLK_PRE_CNT_MAX; > + } > + > + /* tclk post count in escape clocks */ > + tclk_post_cnt = DIV_ROUND_UP(mipi_config->tclk_post, tlpx_ns); > + if (tclk_post_cnt > ICL_TCLK_POST_CNT_MAX) { > + DRM_DEBUG_KMS("tclk_post_cnt out of range (%d)\n", tclk_post_cnt); > + tclk_post_cnt = ICL_TCLK_POST_CNT_MAX; > + } > + > + /* hs zero cnt in escape clocks */ > + hs_zero_cnt = DIV_ROUND_UP(mipi_config->ths_prepare_hszero - > + ths_prepare_ns, tlpx_ns); > + if (hs_zero_cnt > ICL_HS_ZERO_CNT_MAX) { > + DRM_DEBUG_KMS("hs_zero_cnt out of range (%d)\n", hs_zero_cnt); > + hs_zero_cnt = ICL_HS_ZERO_CNT_MAX; > + } > + > + /* hs exit zero cnt in escape clocks */ > + exit_zero_cnt = DIV_ROUND_UP(mipi_config->ths_exit, tlpx_ns); > + if (exit_zero_cnt > ICL_EXIT_ZERO_CNT_MAX) { > + DRM_DEBUG_KMS("exit_zero_cnt out of range (%d)\n", exit_zero_cnt); > + exit_zero_cnt = ICL_EXIT_ZERO_CNT_MAX; > + } > + > + /* clock lane dphy timings */ > + intel_dsi->dphy_reg = (CLK_PREPARE_OVERRIDE | > + CLK_PREPARE(prepare_cnt) | > + CLK_ZERO_OVERRIDE | > + CLK_ZERO(clk_zero_cnt) | > + CLK_PRE_OVERRIDE | > + CLK_PRE(tclk_pre_cnt) | > + CLK_POST_OVERRIDE | > + CLK_POST(tclk_post_cnt) | > + CLK_TRAIL_OVERRIDE | > + CLK_TRAIL(trail_cnt)); > + > + /* data lanes dphy timings */ > + intel_dsi->dphy_data_lane_reg = (HS_PREPARE_OVERRIDE | > + HS_PREPARE(prepare_cnt) | > + HS_ZERO_OVERRIDE | > + HS_ZERO(hs_zero_cnt) | > + HS_TRAIL_OVERRIDE | > + HS_TRAIL(trail_cnt) | > + HS_EXIT_OVERRIDE | > + HS_EXIT(exit_zero_cnt)); > + > + intel_dsi_log_params(intel_dsi); > +} > + > void icl_dsi_init(struct drm_i915_private *dev_priv) > { > struct drm_device *dev = &dev_priv->drm; > @@ -1455,6 +1562,7 @@ void icl_dsi_init(struct drm_i915_private *dev_priv) > goto err; > } > > + icl_dphy_param_init(intel_dsi); > return; > > err: > diff --git a/drivers/gpu/drm/i915/intel_dsi.h b/drivers/gpu/drm/i915/intel_dsi.h > index 705a609050c0..2e997187fed5 100644 > --- a/drivers/gpu/drm/i915/intel_dsi.h > +++ b/drivers/gpu/drm/i915/intel_dsi.h > @@ -192,5 +192,6 @@ bool intel_dsi_vbt_init(struct intel_dsi *intel_dsi, u16 panel_id); > void intel_dsi_vbt_exec_sequence(struct intel_dsi *intel_dsi, > enum mipi_seq seq_id); > void intel_dsi_msleep(struct intel_dsi *intel_dsi, int msec); > +void intel_dsi_log_params(struct intel_dsi *intel_dsi); > > #endif /* _INTEL_DSI_H */ > diff --git a/drivers/gpu/drm/i915/intel_dsi_vbt.c b/drivers/gpu/drm/i915/intel_dsi_vbt.c > index 3a187ffabfbd..26fcb3344ebb 100644 > --- a/drivers/gpu/drm/i915/intel_dsi_vbt.c > +++ b/drivers/gpu/drm/i915/intel_dsi_vbt.c > @@ -41,13 +41,6 @@ > #define MIPI_VIRTUAL_CHANNEL_SHIFT 1 > #define MIPI_PORT_SHIFT 3 > > -#define PREPARE_CNT_MAX 0x3F > -#define EXIT_ZERO_CNT_MAX 0x3F > -#define CLK_ZERO_CNT_MAX 0xFF > -#define TRAIL_CNT_MAX 0x1F > - > -#define NS_KHZ_RATIO 1000000 > - > /* base offsets for gpio pads */ > #define VLV_GPIO_NC_0_HV_DDI0_HPD 0x4130 > #define VLV_GPIO_NC_1_HV_DDI0_DDC_SDA 0x4120 > @@ -532,7 +525,7 @@ void intel_dsi_msleep(struct intel_dsi *intel_dsi, int msec) > msleep(msec); > } > > -static void intel_dsi_log_params(struct intel_dsi *intel_dsi) > +void intel_dsi_log_params(struct intel_dsi *intel_dsi) > { > DRM_DEBUG_KMS("Pclk %d\n", intel_dsi->pclk); > DRM_DEBUG_KMS("Pixel overlap %d\n", intel_dsi->pixel_overlap); > @@ -570,274 +563,6 @@ static void intel_dsi_log_params(struct intel_dsi *intel_dsi) > enableddisabled(!(intel_dsi->video_frmt_cfg_bits & DISABLE_VIDEO_BTA))); > } > > -#define ICL_PREPARE_CNT_MAX 0x7 > -#define ICL_CLK_ZERO_CNT_MAX 0xf > -#define ICL_TRAIL_CNT_MAX 0x7 > -#define ICL_TCLK_PRE_CNT_MAX 0x3 > -#define ICL_TCLK_POST_CNT_MAX 0x7 > -#define ICL_HS_ZERO_CNT_MAX 0xf > -#define ICL_EXIT_ZERO_CNT_MAX 0x7 > - > -static void icl_dphy_param_init(struct intel_dsi *intel_dsi) > -{ > - struct drm_device *dev = intel_dsi->base.base.dev; > - struct drm_i915_private *dev_priv = to_i915(dev); > - struct mipi_config *mipi_config = dev_priv->vbt.dsi.config; > - u32 tlpx_ns; > - u32 prepare_cnt, exit_zero_cnt, clk_zero_cnt, trail_cnt; > - u32 ths_prepare_ns, tclk_trail_ns; > - u32 hs_zero_cnt; > - u32 tclk_pre_cnt, tclk_post_cnt; > - > - tlpx_ns = intel_dsi_tlpx_ns(intel_dsi); > - > - tclk_trail_ns = max(mipi_config->tclk_trail, mipi_config->ths_trail); > - ths_prepare_ns = max(mipi_config->ths_prepare, > - mipi_config->tclk_prepare); > - > - /* > - * 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); > - if (prepare_cnt > ICL_PREPARE_CNT_MAX) { > - DRM_DEBUG_KMS("prepare_cnt out of range (%d)\n", prepare_cnt); > - prepare_cnt = ICL_PREPARE_CNT_MAX; > - } > - > - /* clk zero count in escape clocks */ > - clk_zero_cnt = DIV_ROUND_UP(mipi_config->tclk_prepare_clkzero - > - ths_prepare_ns, tlpx_ns); > - if (clk_zero_cnt > ICL_CLK_ZERO_CNT_MAX) { > - DRM_DEBUG_KMS("clk_zero_cnt out of range (%d)\n", clk_zero_cnt); > - clk_zero_cnt = ICL_CLK_ZERO_CNT_MAX; > - } > - > - /* trail cnt in escape clocks*/ > - trail_cnt = DIV_ROUND_UP(tclk_trail_ns, tlpx_ns); > - if (trail_cnt > ICL_TRAIL_CNT_MAX) { > - DRM_DEBUG_KMS("trail_cnt out of range (%d)\n", trail_cnt); > - trail_cnt = ICL_TRAIL_CNT_MAX; > - } > - > - /* tclk pre count in escape clocks */ > - tclk_pre_cnt = DIV_ROUND_UP(mipi_config->tclk_pre, tlpx_ns); > - if (tclk_pre_cnt > ICL_TCLK_PRE_CNT_MAX) { > - DRM_DEBUG_KMS("tclk_pre_cnt out of range (%d)\n", tclk_pre_cnt); > - tclk_pre_cnt = ICL_TCLK_PRE_CNT_MAX; > - } > - > - /* tclk post count in escape clocks */ > - tclk_post_cnt = DIV_ROUND_UP(mipi_config->tclk_post, tlpx_ns); > - if (tclk_post_cnt > ICL_TCLK_POST_CNT_MAX) { > - DRM_DEBUG_KMS("tclk_post_cnt out of range (%d)\n", tclk_post_cnt); > - tclk_post_cnt = ICL_TCLK_POST_CNT_MAX; > - } > - > - /* hs zero cnt in escape clocks */ > - hs_zero_cnt = DIV_ROUND_UP(mipi_config->ths_prepare_hszero - > - ths_prepare_ns, tlpx_ns); > - if (hs_zero_cnt > ICL_HS_ZERO_CNT_MAX) { > - DRM_DEBUG_KMS("hs_zero_cnt out of range (%d)\n", hs_zero_cnt); > - hs_zero_cnt = ICL_HS_ZERO_CNT_MAX; > - } > - > - /* hs exit zero cnt in escape clocks */ > - exit_zero_cnt = DIV_ROUND_UP(mipi_config->ths_exit, tlpx_ns); > - if (exit_zero_cnt > ICL_EXIT_ZERO_CNT_MAX) { > - DRM_DEBUG_KMS("exit_zero_cnt out of range (%d)\n", exit_zero_cnt); > - exit_zero_cnt = ICL_EXIT_ZERO_CNT_MAX; > - } > - > - /* clock lane dphy timings */ > - intel_dsi->dphy_reg = (CLK_PREPARE_OVERRIDE | > - CLK_PREPARE(prepare_cnt) | > - CLK_ZERO_OVERRIDE | > - CLK_ZERO(clk_zero_cnt) | > - CLK_PRE_OVERRIDE | > - CLK_PRE(tclk_pre_cnt) | > - CLK_POST_OVERRIDE | > - CLK_POST(tclk_post_cnt) | > - CLK_TRAIL_OVERRIDE | > - CLK_TRAIL(trail_cnt)); > - > - /* data lanes dphy timings */ > - intel_dsi->dphy_data_lane_reg = (HS_PREPARE_OVERRIDE | > - HS_PREPARE(prepare_cnt) | > - HS_ZERO_OVERRIDE | > - HS_ZERO(hs_zero_cnt) | > - HS_TRAIL_OVERRIDE | > - HS_TRAIL(trail_cnt) | > - HS_EXIT_OVERRIDE | > - HS_EXIT(exit_zero_cnt)); > - > - intel_dsi_log_params(intel_dsi); > -} > - > -static void vlv_dphy_param_init(struct intel_dsi *intel_dsi) > -{ > - struct drm_device *dev = intel_dsi->base.base.dev; > - struct drm_i915_private *dev_priv = to_i915(dev); > - struct mipi_config *mipi_config = dev_priv->vbt.dsi.config; > - u32 tlpx_ns, extra_byte_count, tlpx_ui; > - u32 ui_num, ui_den; > - u32 prepare_cnt, exit_zero_cnt, clk_zero_cnt, trail_cnt; > - u32 ths_prepare_ns, tclk_trail_ns; > - u32 tclk_prepare_clkzero, ths_prepare_hszero; > - u32 lp_to_hs_switch, hs_to_lp_switch; > - u32 mul; > - > - tlpx_ns = intel_dsi_tlpx_ns(intel_dsi); > - > - switch (intel_dsi->lane_count) { > - case 1: > - case 2: > - extra_byte_count = 2; > - break; > - case 3: > - extra_byte_count = 4; > - break; > - case 4: > - default: > - extra_byte_count = 3; > - break; > - } > - > - /* in Kbps */ > - ui_num = NS_KHZ_RATIO; > - ui_den = intel_dsi_bitrate(intel_dsi); > - > - tclk_prepare_clkzero = mipi_config->tclk_prepare_clkzero; > - ths_prepare_hszero = mipi_config->ths_prepare_hszero; > - > - /* > - * 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 (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; > - } > - > - /* 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; > - } > - > - /* 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); > - > - 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 | > - clk_zero_cnt << 8 | prepare_cnt; > - > - /* > - * LP to HS switch count = 4TLPX + PREP_COUNT * mul + EXIT_ZERO_COUNT * > - * mul + 10UI + Extra Byte Count > - * > - * HS to LP switch count = THS-TRAIL + 2TLPX + Extra Byte Count > - * Extra Byte Count is calculated according to number of lanes. > - * High Low Switch Count is the Max of LP to HS and > - * HS to LP switch count > - * > - */ > - tlpx_ui = DIV_ROUND_UP(tlpx_ns * ui_den, ui_num); > - > - /* B044 */ > - /* FIXME: > - * The 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); > - > - hs_to_lp_switch = DIV_ROUND_UP(mipi_config->ths_trail + 2 * tlpx_ui, 8); > - > - 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 > - * LP clk sync + LP11 + LP01 + tclk_prepare + tclk_zero + > - * extra byte count > - * 2TPLX + 1TLPX + 1 TPLX(in ns) + prepare_cnt * 2 + clk_zero_cnt * > - * 2(in UI) + extra byte count > - * In byteclks = (4TLPX + prepare_cnt * 2 + clk_zero_cnt *2 (in UI)) / > - * 8 + extra byte count > - */ > - intel_dsi->clk_lp_to_hs_count = > - DIV_ROUND_UP( > - 4 * tlpx_ui + prepare_cnt * 2 + > - clk_zero_cnt * 2, > - 8); > - > - intel_dsi->clk_lp_to_hs_count += extra_byte_count; > - > - /* 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 > - * In byteclks = (2*TLpx(in UI) + trail_count*2 +8)(in UI)/8 + > - * Extra byte count > - */ > - intel_dsi->clk_hs_to_lp_count = > - DIV_ROUND_UP(2 * tlpx_ui + trail_cnt * 2 + 8, > - 8); > - intel_dsi->clk_hs_to_lp_count += extra_byte_count; > - > - intel_dsi_log_params(intel_dsi); > -} > - > bool intel_dsi_vbt_init(struct intel_dsi *intel_dsi, u16 panel_id) > { > struct drm_device *dev = intel_dsi->base.base.dev; > @@ -925,11 +650,6 @@ bool intel_dsi_vbt_init(struct intel_dsi *intel_dsi, u16 panel_id) > > intel_dsi->burst_mode_ratio = burst_mode_ratio; > > - if (INTEL_GEN(dev_priv) >= 11) > - icl_dphy_param_init(intel_dsi); > - else > - vlv_dphy_param_init(intel_dsi); > - > /* delays in VBT are in unit of 100us, so need to convert > * here in ms > * Delay (100us) * 100 /1000 = Delay / 10 (ms) */ > diff --git a/drivers/gpu/drm/i915/vlv_dsi.c b/drivers/gpu/drm/i915/vlv_dsi.c > index 255996a71b91..59500c838b9d 100644 > --- a/drivers/gpu/drm/i915/vlv_dsi.c > +++ b/drivers/gpu/drm/i915/vlv_dsi.c > @@ -1689,6 +1689,174 @@ static void intel_dsi_add_properties(struct intel_connector *connector) > } > } > > +#define NS_KHZ_RATIO 1000000 > + > +#define PREPARE_CNT_MAX 0x3F > +#define EXIT_ZERO_CNT_MAX 0x3F > +#define CLK_ZERO_CNT_MAX 0xFF > +#define TRAIL_CNT_MAX 0x1F > + > +static void vlv_dphy_param_init(struct intel_dsi *intel_dsi) > +{ > + struct drm_device *dev = intel_dsi->base.base.dev; > + struct drm_i915_private *dev_priv = to_i915(dev); > + struct mipi_config *mipi_config = dev_priv->vbt.dsi.config; > + u32 tlpx_ns, extra_byte_count, tlpx_ui; > + u32 ui_num, ui_den; > + u32 prepare_cnt, exit_zero_cnt, clk_zero_cnt, trail_cnt; > + u32 ths_prepare_ns, tclk_trail_ns; > + u32 tclk_prepare_clkzero, ths_prepare_hszero; > + u32 lp_to_hs_switch, hs_to_lp_switch; > + u32 mul; > + > + tlpx_ns = intel_dsi_tlpx_ns(intel_dsi); > + > + switch (intel_dsi->lane_count) { > + case 1: > + case 2: > + extra_byte_count = 2; > + break; > + case 3: > + extra_byte_count = 4; > + break; > + case 4: > + default: > + extra_byte_count = 3; > + break; > + } > + > + /* in Kbps */ > + ui_num = NS_KHZ_RATIO; > + ui_den = intel_dsi_bitrate(intel_dsi); > + > + tclk_prepare_clkzero = mipi_config->tclk_prepare_clkzero; > + ths_prepare_hszero = mipi_config->ths_prepare_hszero; > + > + /* > + * 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 (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; > + } > + > + /* 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; > + } > + > + /* 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); > + > + 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 | > + clk_zero_cnt << 8 | prepare_cnt; > + > + /* > + * LP to HS switch count = 4TLPX + PREP_COUNT * mul + EXIT_ZERO_COUNT * > + * mul + 10UI + Extra Byte Count > + * > + * HS to LP switch count = THS-TRAIL + 2TLPX + Extra Byte Count > + * Extra Byte Count is calculated according to number of lanes. > + * High Low Switch Count is the Max of LP to HS and > + * HS to LP switch count > + * > + */ > + tlpx_ui = DIV_ROUND_UP(tlpx_ns * ui_den, ui_num); > + > + /* B044 */ > + /* FIXME: > + * The 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); > + > + hs_to_lp_switch = DIV_ROUND_UP(mipi_config->ths_trail + 2 * tlpx_ui, 8); > + > + 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 > + * LP clk sync + LP11 + LP01 + tclk_prepare + tclk_zero + > + * extra byte count > + * 2TPLX + 1TLPX + 1 TPLX(in ns) + prepare_cnt * 2 + clk_zero_cnt * > + * 2(in UI) + extra byte count > + * In byteclks = (4TLPX + prepare_cnt * 2 + clk_zero_cnt *2 (in UI)) / > + * 8 + extra byte count > + */ > + intel_dsi->clk_lp_to_hs_count = > + DIV_ROUND_UP( > + 4 * tlpx_ui + prepare_cnt * 2 + > + clk_zero_cnt * 2, > + 8); > + > + intel_dsi->clk_lp_to_hs_count += extra_byte_count; > + > + /* 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 > + * In byteclks = (2*TLpx(in UI) + trail_count*2 +8)(in UI)/8 + > + * Extra byte count > + */ > + intel_dsi->clk_hs_to_lp_count = > + DIV_ROUND_UP(2 * tlpx_ui + trail_cnt * 2 + 8, > + 8); > + intel_dsi->clk_hs_to_lp_count += extra_byte_count; > + > + intel_dsi_log_params(intel_dsi); > +} > + > void vlv_dsi_init(struct drm_i915_private *dev_priv) > { > struct drm_device *dev = &dev_priv->drm; > @@ -1778,6 +1946,8 @@ void vlv_dsi_init(struct drm_i915_private *dev_priv) > goto err; > } > > + vlv_dphy_param_init(intel_dsi); > + > /* > * In case of BYT with CRC PMIC, we need to use GPIO for > * Panel control. > -- > 2.21.0
Hi all, On 05-06-19 20:37, Ville Syrjälä wrote: > On Wed, Jun 05, 2019 at 08:17:34PM +0200, Hans de Goede wrote: >> The vlv/icl_dphy_param_init calls do various calculations to set dphy >> parameters based on the pclk. >> >> Move the calling of vlv/icl_dphy_param_init to vlv_dsi_init to give >> vlv_dsi_init a chance to tweak the pclk before these calculations are done. >> >> Changes in v2: >> -Also moves the icl and vlv specific dphy_param_init functions from the >> generic intel_dsi_vbt.c file into the icl_ and vlv_dsi.c specific files. >> >> Note icl_dphy_param_init() and vlv_dphy_param_init() are only moved, >> otherwise they are completely unchanged. >> >> Signed-off-by: Hans de Goede <hdegoede@redhat.com> > > Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Thanks, I've just pushed this series to dinq (now that the CI is done and happy with it). Regards, Hans > >> --- >> drivers/gpu/drm/i915/icl_dsi.c | 108 ++++++++++ >> drivers/gpu/drm/i915/intel_dsi.h | 1 + >> drivers/gpu/drm/i915/intel_dsi_vbt.c | 282 +-------------------------- >> drivers/gpu/drm/i915/vlv_dsi.c | 170 ++++++++++++++++ >> 4 files changed, 280 insertions(+), 281 deletions(-) >> >> diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c >> index 9d962ea1e635..511c76e788ef 100644 >> --- a/drivers/gpu/drm/i915/icl_dsi.c >> +++ b/drivers/gpu/drm/i915/icl_dsi.c >> @@ -1363,6 +1363,113 @@ static const struct mipi_dsi_host_ops gen11_dsi_host_ops = { >> .transfer = gen11_dsi_host_transfer, >> }; >> >> +#define ICL_PREPARE_CNT_MAX 0x7 >> +#define ICL_CLK_ZERO_CNT_MAX 0xf >> +#define ICL_TRAIL_CNT_MAX 0x7 >> +#define ICL_TCLK_PRE_CNT_MAX 0x3 >> +#define ICL_TCLK_POST_CNT_MAX 0x7 >> +#define ICL_HS_ZERO_CNT_MAX 0xf >> +#define ICL_EXIT_ZERO_CNT_MAX 0x7 >> + >> +static void icl_dphy_param_init(struct intel_dsi *intel_dsi) >> +{ >> + struct drm_device *dev = intel_dsi->base.base.dev; >> + struct drm_i915_private *dev_priv = to_i915(dev); >> + struct mipi_config *mipi_config = dev_priv->vbt.dsi.config; >> + u32 tlpx_ns; >> + u32 prepare_cnt, exit_zero_cnt, clk_zero_cnt, trail_cnt; >> + u32 ths_prepare_ns, tclk_trail_ns; >> + u32 hs_zero_cnt; >> + u32 tclk_pre_cnt, tclk_post_cnt; >> + >> + tlpx_ns = intel_dsi_tlpx_ns(intel_dsi); >> + >> + tclk_trail_ns = max(mipi_config->tclk_trail, mipi_config->ths_trail); >> + ths_prepare_ns = max(mipi_config->ths_prepare, >> + mipi_config->tclk_prepare); >> + >> + /* >> + * 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); >> + if (prepare_cnt > ICL_PREPARE_CNT_MAX) { >> + DRM_DEBUG_KMS("prepare_cnt out of range (%d)\n", prepare_cnt); >> + prepare_cnt = ICL_PREPARE_CNT_MAX; >> + } >> + >> + /* clk zero count in escape clocks */ >> + clk_zero_cnt = DIV_ROUND_UP(mipi_config->tclk_prepare_clkzero - >> + ths_prepare_ns, tlpx_ns); >> + if (clk_zero_cnt > ICL_CLK_ZERO_CNT_MAX) { >> + DRM_DEBUG_KMS("clk_zero_cnt out of range (%d)\n", clk_zero_cnt); >> + clk_zero_cnt = ICL_CLK_ZERO_CNT_MAX; >> + } >> + >> + /* trail cnt in escape clocks*/ >> + trail_cnt = DIV_ROUND_UP(tclk_trail_ns, tlpx_ns); >> + if (trail_cnt > ICL_TRAIL_CNT_MAX) { >> + DRM_DEBUG_KMS("trail_cnt out of range (%d)\n", trail_cnt); >> + trail_cnt = ICL_TRAIL_CNT_MAX; >> + } >> + >> + /* tclk pre count in escape clocks */ >> + tclk_pre_cnt = DIV_ROUND_UP(mipi_config->tclk_pre, tlpx_ns); >> + if (tclk_pre_cnt > ICL_TCLK_PRE_CNT_MAX) { >> + DRM_DEBUG_KMS("tclk_pre_cnt out of range (%d)\n", tclk_pre_cnt); >> + tclk_pre_cnt = ICL_TCLK_PRE_CNT_MAX; >> + } >> + >> + /* tclk post count in escape clocks */ >> + tclk_post_cnt = DIV_ROUND_UP(mipi_config->tclk_post, tlpx_ns); >> + if (tclk_post_cnt > ICL_TCLK_POST_CNT_MAX) { >> + DRM_DEBUG_KMS("tclk_post_cnt out of range (%d)\n", tclk_post_cnt); >> + tclk_post_cnt = ICL_TCLK_POST_CNT_MAX; >> + } >> + >> + /* hs zero cnt in escape clocks */ >> + hs_zero_cnt = DIV_ROUND_UP(mipi_config->ths_prepare_hszero - >> + ths_prepare_ns, tlpx_ns); >> + if (hs_zero_cnt > ICL_HS_ZERO_CNT_MAX) { >> + DRM_DEBUG_KMS("hs_zero_cnt out of range (%d)\n", hs_zero_cnt); >> + hs_zero_cnt = ICL_HS_ZERO_CNT_MAX; >> + } >> + >> + /* hs exit zero cnt in escape clocks */ >> + exit_zero_cnt = DIV_ROUND_UP(mipi_config->ths_exit, tlpx_ns); >> + if (exit_zero_cnt > ICL_EXIT_ZERO_CNT_MAX) { >> + DRM_DEBUG_KMS("exit_zero_cnt out of range (%d)\n", exit_zero_cnt); >> + exit_zero_cnt = ICL_EXIT_ZERO_CNT_MAX; >> + } >> + >> + /* clock lane dphy timings */ >> + intel_dsi->dphy_reg = (CLK_PREPARE_OVERRIDE | >> + CLK_PREPARE(prepare_cnt) | >> + CLK_ZERO_OVERRIDE | >> + CLK_ZERO(clk_zero_cnt) | >> + CLK_PRE_OVERRIDE | >> + CLK_PRE(tclk_pre_cnt) | >> + CLK_POST_OVERRIDE | >> + CLK_POST(tclk_post_cnt) | >> + CLK_TRAIL_OVERRIDE | >> + CLK_TRAIL(trail_cnt)); >> + >> + /* data lanes dphy timings */ >> + intel_dsi->dphy_data_lane_reg = (HS_PREPARE_OVERRIDE | >> + HS_PREPARE(prepare_cnt) | >> + HS_ZERO_OVERRIDE | >> + HS_ZERO(hs_zero_cnt) | >> + HS_TRAIL_OVERRIDE | >> + HS_TRAIL(trail_cnt) | >> + HS_EXIT_OVERRIDE | >> + HS_EXIT(exit_zero_cnt)); >> + >> + intel_dsi_log_params(intel_dsi); >> +} >> + >> void icl_dsi_init(struct drm_i915_private *dev_priv) >> { >> struct drm_device *dev = &dev_priv->drm; >> @@ -1455,6 +1562,7 @@ void icl_dsi_init(struct drm_i915_private *dev_priv) >> goto err; >> } >> >> + icl_dphy_param_init(intel_dsi); >> return; >> >> err: >> diff --git a/drivers/gpu/drm/i915/intel_dsi.h b/drivers/gpu/drm/i915/intel_dsi.h >> index 705a609050c0..2e997187fed5 100644 >> --- a/drivers/gpu/drm/i915/intel_dsi.h >> +++ b/drivers/gpu/drm/i915/intel_dsi.h >> @@ -192,5 +192,6 @@ bool intel_dsi_vbt_init(struct intel_dsi *intel_dsi, u16 panel_id); >> void intel_dsi_vbt_exec_sequence(struct intel_dsi *intel_dsi, >> enum mipi_seq seq_id); >> void intel_dsi_msleep(struct intel_dsi *intel_dsi, int msec); >> +void intel_dsi_log_params(struct intel_dsi *intel_dsi); >> >> #endif /* _INTEL_DSI_H */ >> diff --git a/drivers/gpu/drm/i915/intel_dsi_vbt.c b/drivers/gpu/drm/i915/intel_dsi_vbt.c >> index 3a187ffabfbd..26fcb3344ebb 100644 >> --- a/drivers/gpu/drm/i915/intel_dsi_vbt.c >> +++ b/drivers/gpu/drm/i915/intel_dsi_vbt.c >> @@ -41,13 +41,6 @@ >> #define MIPI_VIRTUAL_CHANNEL_SHIFT 1 >> #define MIPI_PORT_SHIFT 3 >> >> -#define PREPARE_CNT_MAX 0x3F >> -#define EXIT_ZERO_CNT_MAX 0x3F >> -#define CLK_ZERO_CNT_MAX 0xFF >> -#define TRAIL_CNT_MAX 0x1F >> - >> -#define NS_KHZ_RATIO 1000000 >> - >> /* base offsets for gpio pads */ >> #define VLV_GPIO_NC_0_HV_DDI0_HPD 0x4130 >> #define VLV_GPIO_NC_1_HV_DDI0_DDC_SDA 0x4120 >> @@ -532,7 +525,7 @@ void intel_dsi_msleep(struct intel_dsi *intel_dsi, int msec) >> msleep(msec); >> } >> >> -static void intel_dsi_log_params(struct intel_dsi *intel_dsi) >> +void intel_dsi_log_params(struct intel_dsi *intel_dsi) >> { >> DRM_DEBUG_KMS("Pclk %d\n", intel_dsi->pclk); >> DRM_DEBUG_KMS("Pixel overlap %d\n", intel_dsi->pixel_overlap); >> @@ -570,274 +563,6 @@ static void intel_dsi_log_params(struct intel_dsi *intel_dsi) >> enableddisabled(!(intel_dsi->video_frmt_cfg_bits & DISABLE_VIDEO_BTA))); >> } >> >> -#define ICL_PREPARE_CNT_MAX 0x7 >> -#define ICL_CLK_ZERO_CNT_MAX 0xf >> -#define ICL_TRAIL_CNT_MAX 0x7 >> -#define ICL_TCLK_PRE_CNT_MAX 0x3 >> -#define ICL_TCLK_POST_CNT_MAX 0x7 >> -#define ICL_HS_ZERO_CNT_MAX 0xf >> -#define ICL_EXIT_ZERO_CNT_MAX 0x7 >> - >> -static void icl_dphy_param_init(struct intel_dsi *intel_dsi) >> -{ >> - struct drm_device *dev = intel_dsi->base.base.dev; >> - struct drm_i915_private *dev_priv = to_i915(dev); >> - struct mipi_config *mipi_config = dev_priv->vbt.dsi.config; >> - u32 tlpx_ns; >> - u32 prepare_cnt, exit_zero_cnt, clk_zero_cnt, trail_cnt; >> - u32 ths_prepare_ns, tclk_trail_ns; >> - u32 hs_zero_cnt; >> - u32 tclk_pre_cnt, tclk_post_cnt; >> - >> - tlpx_ns = intel_dsi_tlpx_ns(intel_dsi); >> - >> - tclk_trail_ns = max(mipi_config->tclk_trail, mipi_config->ths_trail); >> - ths_prepare_ns = max(mipi_config->ths_prepare, >> - mipi_config->tclk_prepare); >> - >> - /* >> - * 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); >> - if (prepare_cnt > ICL_PREPARE_CNT_MAX) { >> - DRM_DEBUG_KMS("prepare_cnt out of range (%d)\n", prepare_cnt); >> - prepare_cnt = ICL_PREPARE_CNT_MAX; >> - } >> - >> - /* clk zero count in escape clocks */ >> - clk_zero_cnt = DIV_ROUND_UP(mipi_config->tclk_prepare_clkzero - >> - ths_prepare_ns, tlpx_ns); >> - if (clk_zero_cnt > ICL_CLK_ZERO_CNT_MAX) { >> - DRM_DEBUG_KMS("clk_zero_cnt out of range (%d)\n", clk_zero_cnt); >> - clk_zero_cnt = ICL_CLK_ZERO_CNT_MAX; >> - } >> - >> - /* trail cnt in escape clocks*/ >> - trail_cnt = DIV_ROUND_UP(tclk_trail_ns, tlpx_ns); >> - if (trail_cnt > ICL_TRAIL_CNT_MAX) { >> - DRM_DEBUG_KMS("trail_cnt out of range (%d)\n", trail_cnt); >> - trail_cnt = ICL_TRAIL_CNT_MAX; >> - } >> - >> - /* tclk pre count in escape clocks */ >> - tclk_pre_cnt = DIV_ROUND_UP(mipi_config->tclk_pre, tlpx_ns); >> - if (tclk_pre_cnt > ICL_TCLK_PRE_CNT_MAX) { >> - DRM_DEBUG_KMS("tclk_pre_cnt out of range (%d)\n", tclk_pre_cnt); >> - tclk_pre_cnt = ICL_TCLK_PRE_CNT_MAX; >> - } >> - >> - /* tclk post count in escape clocks */ >> - tclk_post_cnt = DIV_ROUND_UP(mipi_config->tclk_post, tlpx_ns); >> - if (tclk_post_cnt > ICL_TCLK_POST_CNT_MAX) { >> - DRM_DEBUG_KMS("tclk_post_cnt out of range (%d)\n", tclk_post_cnt); >> - tclk_post_cnt = ICL_TCLK_POST_CNT_MAX; >> - } >> - >> - /* hs zero cnt in escape clocks */ >> - hs_zero_cnt = DIV_ROUND_UP(mipi_config->ths_prepare_hszero - >> - ths_prepare_ns, tlpx_ns); >> - if (hs_zero_cnt > ICL_HS_ZERO_CNT_MAX) { >> - DRM_DEBUG_KMS("hs_zero_cnt out of range (%d)\n", hs_zero_cnt); >> - hs_zero_cnt = ICL_HS_ZERO_CNT_MAX; >> - } >> - >> - /* hs exit zero cnt in escape clocks */ >> - exit_zero_cnt = DIV_ROUND_UP(mipi_config->ths_exit, tlpx_ns); >> - if (exit_zero_cnt > ICL_EXIT_ZERO_CNT_MAX) { >> - DRM_DEBUG_KMS("exit_zero_cnt out of range (%d)\n", exit_zero_cnt); >> - exit_zero_cnt = ICL_EXIT_ZERO_CNT_MAX; >> - } >> - >> - /* clock lane dphy timings */ >> - intel_dsi->dphy_reg = (CLK_PREPARE_OVERRIDE | >> - CLK_PREPARE(prepare_cnt) | >> - CLK_ZERO_OVERRIDE | >> - CLK_ZERO(clk_zero_cnt) | >> - CLK_PRE_OVERRIDE | >> - CLK_PRE(tclk_pre_cnt) | >> - CLK_POST_OVERRIDE | >> - CLK_POST(tclk_post_cnt) | >> - CLK_TRAIL_OVERRIDE | >> - CLK_TRAIL(trail_cnt)); >> - >> - /* data lanes dphy timings */ >> - intel_dsi->dphy_data_lane_reg = (HS_PREPARE_OVERRIDE | >> - HS_PREPARE(prepare_cnt) | >> - HS_ZERO_OVERRIDE | >> - HS_ZERO(hs_zero_cnt) | >> - HS_TRAIL_OVERRIDE | >> - HS_TRAIL(trail_cnt) | >> - HS_EXIT_OVERRIDE | >> - HS_EXIT(exit_zero_cnt)); >> - >> - intel_dsi_log_params(intel_dsi); >> -} >> - >> -static void vlv_dphy_param_init(struct intel_dsi *intel_dsi) >> -{ >> - struct drm_device *dev = intel_dsi->base.base.dev; >> - struct drm_i915_private *dev_priv = to_i915(dev); >> - struct mipi_config *mipi_config = dev_priv->vbt.dsi.config; >> - u32 tlpx_ns, extra_byte_count, tlpx_ui; >> - u32 ui_num, ui_den; >> - u32 prepare_cnt, exit_zero_cnt, clk_zero_cnt, trail_cnt; >> - u32 ths_prepare_ns, tclk_trail_ns; >> - u32 tclk_prepare_clkzero, ths_prepare_hszero; >> - u32 lp_to_hs_switch, hs_to_lp_switch; >> - u32 mul; >> - >> - tlpx_ns = intel_dsi_tlpx_ns(intel_dsi); >> - >> - switch (intel_dsi->lane_count) { >> - case 1: >> - case 2: >> - extra_byte_count = 2; >> - break; >> - case 3: >> - extra_byte_count = 4; >> - break; >> - case 4: >> - default: >> - extra_byte_count = 3; >> - break; >> - } >> - >> - /* in Kbps */ >> - ui_num = NS_KHZ_RATIO; >> - ui_den = intel_dsi_bitrate(intel_dsi); >> - >> - tclk_prepare_clkzero = mipi_config->tclk_prepare_clkzero; >> - ths_prepare_hszero = mipi_config->ths_prepare_hszero; >> - >> - /* >> - * 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 (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; >> - } >> - >> - /* 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; >> - } >> - >> - /* 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); >> - >> - 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 | >> - clk_zero_cnt << 8 | prepare_cnt; >> - >> - /* >> - * LP to HS switch count = 4TLPX + PREP_COUNT * mul + EXIT_ZERO_COUNT * >> - * mul + 10UI + Extra Byte Count >> - * >> - * HS to LP switch count = THS-TRAIL + 2TLPX + Extra Byte Count >> - * Extra Byte Count is calculated according to number of lanes. >> - * High Low Switch Count is the Max of LP to HS and >> - * HS to LP switch count >> - * >> - */ >> - tlpx_ui = DIV_ROUND_UP(tlpx_ns * ui_den, ui_num); >> - >> - /* B044 */ >> - /* FIXME: >> - * The 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); >> - >> - hs_to_lp_switch = DIV_ROUND_UP(mipi_config->ths_trail + 2 * tlpx_ui, 8); >> - >> - 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 >> - * LP clk sync + LP11 + LP01 + tclk_prepare + tclk_zero + >> - * extra byte count >> - * 2TPLX + 1TLPX + 1 TPLX(in ns) + prepare_cnt * 2 + clk_zero_cnt * >> - * 2(in UI) + extra byte count >> - * In byteclks = (4TLPX + prepare_cnt * 2 + clk_zero_cnt *2 (in UI)) / >> - * 8 + extra byte count >> - */ >> - intel_dsi->clk_lp_to_hs_count = >> - DIV_ROUND_UP( >> - 4 * tlpx_ui + prepare_cnt * 2 + >> - clk_zero_cnt * 2, >> - 8); >> - >> - intel_dsi->clk_lp_to_hs_count += extra_byte_count; >> - >> - /* 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 >> - * In byteclks = (2*TLpx(in UI) + trail_count*2 +8)(in UI)/8 + >> - * Extra byte count >> - */ >> - intel_dsi->clk_hs_to_lp_count = >> - DIV_ROUND_UP(2 * tlpx_ui + trail_cnt * 2 + 8, >> - 8); >> - intel_dsi->clk_hs_to_lp_count += extra_byte_count; >> - >> - intel_dsi_log_params(intel_dsi); >> -} >> - >> bool intel_dsi_vbt_init(struct intel_dsi *intel_dsi, u16 panel_id) >> { >> struct drm_device *dev = intel_dsi->base.base.dev; >> @@ -925,11 +650,6 @@ bool intel_dsi_vbt_init(struct intel_dsi *intel_dsi, u16 panel_id) >> >> intel_dsi->burst_mode_ratio = burst_mode_ratio; >> >> - if (INTEL_GEN(dev_priv) >= 11) >> - icl_dphy_param_init(intel_dsi); >> - else >> - vlv_dphy_param_init(intel_dsi); >> - >> /* delays in VBT are in unit of 100us, so need to convert >> * here in ms >> * Delay (100us) * 100 /1000 = Delay / 10 (ms) */ >> diff --git a/drivers/gpu/drm/i915/vlv_dsi.c b/drivers/gpu/drm/i915/vlv_dsi.c >> index 255996a71b91..59500c838b9d 100644 >> --- a/drivers/gpu/drm/i915/vlv_dsi.c >> +++ b/drivers/gpu/drm/i915/vlv_dsi.c >> @@ -1689,6 +1689,174 @@ static void intel_dsi_add_properties(struct intel_connector *connector) >> } >> } >> >> +#define NS_KHZ_RATIO 1000000 >> + >> +#define PREPARE_CNT_MAX 0x3F >> +#define EXIT_ZERO_CNT_MAX 0x3F >> +#define CLK_ZERO_CNT_MAX 0xFF >> +#define TRAIL_CNT_MAX 0x1F >> + >> +static void vlv_dphy_param_init(struct intel_dsi *intel_dsi) >> +{ >> + struct drm_device *dev = intel_dsi->base.base.dev; >> + struct drm_i915_private *dev_priv = to_i915(dev); >> + struct mipi_config *mipi_config = dev_priv->vbt.dsi.config; >> + u32 tlpx_ns, extra_byte_count, tlpx_ui; >> + u32 ui_num, ui_den; >> + u32 prepare_cnt, exit_zero_cnt, clk_zero_cnt, trail_cnt; >> + u32 ths_prepare_ns, tclk_trail_ns; >> + u32 tclk_prepare_clkzero, ths_prepare_hszero; >> + u32 lp_to_hs_switch, hs_to_lp_switch; >> + u32 mul; >> + >> + tlpx_ns = intel_dsi_tlpx_ns(intel_dsi); >> + >> + switch (intel_dsi->lane_count) { >> + case 1: >> + case 2: >> + extra_byte_count = 2; >> + break; >> + case 3: >> + extra_byte_count = 4; >> + break; >> + case 4: >> + default: >> + extra_byte_count = 3; >> + break; >> + } >> + >> + /* in Kbps */ >> + ui_num = NS_KHZ_RATIO; >> + ui_den = intel_dsi_bitrate(intel_dsi); >> + >> + tclk_prepare_clkzero = mipi_config->tclk_prepare_clkzero; >> + ths_prepare_hszero = mipi_config->ths_prepare_hszero; >> + >> + /* >> + * 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 (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; >> + } >> + >> + /* 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; >> + } >> + >> + /* 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); >> + >> + 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 | >> + clk_zero_cnt << 8 | prepare_cnt; >> + >> + /* >> + * LP to HS switch count = 4TLPX + PREP_COUNT * mul + EXIT_ZERO_COUNT * >> + * mul + 10UI + Extra Byte Count >> + * >> + * HS to LP switch count = THS-TRAIL + 2TLPX + Extra Byte Count >> + * Extra Byte Count is calculated according to number of lanes. >> + * High Low Switch Count is the Max of LP to HS and >> + * HS to LP switch count >> + * >> + */ >> + tlpx_ui = DIV_ROUND_UP(tlpx_ns * ui_den, ui_num); >> + >> + /* B044 */ >> + /* FIXME: >> + * The 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); >> + >> + hs_to_lp_switch = DIV_ROUND_UP(mipi_config->ths_trail + 2 * tlpx_ui, 8); >> + >> + 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 >> + * LP clk sync + LP11 + LP01 + tclk_prepare + tclk_zero + >> + * extra byte count >> + * 2TPLX + 1TLPX + 1 TPLX(in ns) + prepare_cnt * 2 + clk_zero_cnt * >> + * 2(in UI) + extra byte count >> + * In byteclks = (4TLPX + prepare_cnt * 2 + clk_zero_cnt *2 (in UI)) / >> + * 8 + extra byte count >> + */ >> + intel_dsi->clk_lp_to_hs_count = >> + DIV_ROUND_UP( >> + 4 * tlpx_ui + prepare_cnt * 2 + >> + clk_zero_cnt * 2, >> + 8); >> + >> + intel_dsi->clk_lp_to_hs_count += extra_byte_count; >> + >> + /* 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 >> + * In byteclks = (2*TLpx(in UI) + trail_count*2 +8)(in UI)/8 + >> + * Extra byte count >> + */ >> + intel_dsi->clk_hs_to_lp_count = >> + DIV_ROUND_UP(2 * tlpx_ui + trail_cnt * 2 + 8, >> + 8); >> + intel_dsi->clk_hs_to_lp_count += extra_byte_count; >> + >> + intel_dsi_log_params(intel_dsi); >> +} >> + >> void vlv_dsi_init(struct drm_i915_private *dev_priv) >> { >> struct drm_device *dev = &dev_priv->drm; >> @@ -1778,6 +1946,8 @@ void vlv_dsi_init(struct drm_i915_private *dev_priv) >> goto err; >> } >> >> + vlv_dphy_param_init(intel_dsi); >> + >> /* >> * In case of BYT with CRC PMIC, we need to use GPIO for >> * Panel control. >> -- >> 2.21.0 >
diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c index 9d962ea1e635..511c76e788ef 100644 --- a/drivers/gpu/drm/i915/icl_dsi.c +++ b/drivers/gpu/drm/i915/icl_dsi.c @@ -1363,6 +1363,113 @@ static const struct mipi_dsi_host_ops gen11_dsi_host_ops = { .transfer = gen11_dsi_host_transfer, }; +#define ICL_PREPARE_CNT_MAX 0x7 +#define ICL_CLK_ZERO_CNT_MAX 0xf +#define ICL_TRAIL_CNT_MAX 0x7 +#define ICL_TCLK_PRE_CNT_MAX 0x3 +#define ICL_TCLK_POST_CNT_MAX 0x7 +#define ICL_HS_ZERO_CNT_MAX 0xf +#define ICL_EXIT_ZERO_CNT_MAX 0x7 + +static void icl_dphy_param_init(struct intel_dsi *intel_dsi) +{ + struct drm_device *dev = intel_dsi->base.base.dev; + struct drm_i915_private *dev_priv = to_i915(dev); + struct mipi_config *mipi_config = dev_priv->vbt.dsi.config; + u32 tlpx_ns; + u32 prepare_cnt, exit_zero_cnt, clk_zero_cnt, trail_cnt; + u32 ths_prepare_ns, tclk_trail_ns; + u32 hs_zero_cnt; + u32 tclk_pre_cnt, tclk_post_cnt; + + tlpx_ns = intel_dsi_tlpx_ns(intel_dsi); + + tclk_trail_ns = max(mipi_config->tclk_trail, mipi_config->ths_trail); + ths_prepare_ns = max(mipi_config->ths_prepare, + mipi_config->tclk_prepare); + + /* + * 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); + if (prepare_cnt > ICL_PREPARE_CNT_MAX) { + DRM_DEBUG_KMS("prepare_cnt out of range (%d)\n", prepare_cnt); + prepare_cnt = ICL_PREPARE_CNT_MAX; + } + + /* clk zero count in escape clocks */ + clk_zero_cnt = DIV_ROUND_UP(mipi_config->tclk_prepare_clkzero - + ths_prepare_ns, tlpx_ns); + if (clk_zero_cnt > ICL_CLK_ZERO_CNT_MAX) { + DRM_DEBUG_KMS("clk_zero_cnt out of range (%d)\n", clk_zero_cnt); + clk_zero_cnt = ICL_CLK_ZERO_CNT_MAX; + } + + /* trail cnt in escape clocks*/ + trail_cnt = DIV_ROUND_UP(tclk_trail_ns, tlpx_ns); + if (trail_cnt > ICL_TRAIL_CNT_MAX) { + DRM_DEBUG_KMS("trail_cnt out of range (%d)\n", trail_cnt); + trail_cnt = ICL_TRAIL_CNT_MAX; + } + + /* tclk pre count in escape clocks */ + tclk_pre_cnt = DIV_ROUND_UP(mipi_config->tclk_pre, tlpx_ns); + if (tclk_pre_cnt > ICL_TCLK_PRE_CNT_MAX) { + DRM_DEBUG_KMS("tclk_pre_cnt out of range (%d)\n", tclk_pre_cnt); + tclk_pre_cnt = ICL_TCLK_PRE_CNT_MAX; + } + + /* tclk post count in escape clocks */ + tclk_post_cnt = DIV_ROUND_UP(mipi_config->tclk_post, tlpx_ns); + if (tclk_post_cnt > ICL_TCLK_POST_CNT_MAX) { + DRM_DEBUG_KMS("tclk_post_cnt out of range (%d)\n", tclk_post_cnt); + tclk_post_cnt = ICL_TCLK_POST_CNT_MAX; + } + + /* hs zero cnt in escape clocks */ + hs_zero_cnt = DIV_ROUND_UP(mipi_config->ths_prepare_hszero - + ths_prepare_ns, tlpx_ns); + if (hs_zero_cnt > ICL_HS_ZERO_CNT_MAX) { + DRM_DEBUG_KMS("hs_zero_cnt out of range (%d)\n", hs_zero_cnt); + hs_zero_cnt = ICL_HS_ZERO_CNT_MAX; + } + + /* hs exit zero cnt in escape clocks */ + exit_zero_cnt = DIV_ROUND_UP(mipi_config->ths_exit, tlpx_ns); + if (exit_zero_cnt > ICL_EXIT_ZERO_CNT_MAX) { + DRM_DEBUG_KMS("exit_zero_cnt out of range (%d)\n", exit_zero_cnt); + exit_zero_cnt = ICL_EXIT_ZERO_CNT_MAX; + } + + /* clock lane dphy timings */ + intel_dsi->dphy_reg = (CLK_PREPARE_OVERRIDE | + CLK_PREPARE(prepare_cnt) | + CLK_ZERO_OVERRIDE | + CLK_ZERO(clk_zero_cnt) | + CLK_PRE_OVERRIDE | + CLK_PRE(tclk_pre_cnt) | + CLK_POST_OVERRIDE | + CLK_POST(tclk_post_cnt) | + CLK_TRAIL_OVERRIDE | + CLK_TRAIL(trail_cnt)); + + /* data lanes dphy timings */ + intel_dsi->dphy_data_lane_reg = (HS_PREPARE_OVERRIDE | + HS_PREPARE(prepare_cnt) | + HS_ZERO_OVERRIDE | + HS_ZERO(hs_zero_cnt) | + HS_TRAIL_OVERRIDE | + HS_TRAIL(trail_cnt) | + HS_EXIT_OVERRIDE | + HS_EXIT(exit_zero_cnt)); + + intel_dsi_log_params(intel_dsi); +} + void icl_dsi_init(struct drm_i915_private *dev_priv) { struct drm_device *dev = &dev_priv->drm; @@ -1455,6 +1562,7 @@ void icl_dsi_init(struct drm_i915_private *dev_priv) goto err; } + icl_dphy_param_init(intel_dsi); return; err: diff --git a/drivers/gpu/drm/i915/intel_dsi.h b/drivers/gpu/drm/i915/intel_dsi.h index 705a609050c0..2e997187fed5 100644 --- a/drivers/gpu/drm/i915/intel_dsi.h +++ b/drivers/gpu/drm/i915/intel_dsi.h @@ -192,5 +192,6 @@ bool intel_dsi_vbt_init(struct intel_dsi *intel_dsi, u16 panel_id); void intel_dsi_vbt_exec_sequence(struct intel_dsi *intel_dsi, enum mipi_seq seq_id); void intel_dsi_msleep(struct intel_dsi *intel_dsi, int msec); +void intel_dsi_log_params(struct intel_dsi *intel_dsi); #endif /* _INTEL_DSI_H */ diff --git a/drivers/gpu/drm/i915/intel_dsi_vbt.c b/drivers/gpu/drm/i915/intel_dsi_vbt.c index 3a187ffabfbd..26fcb3344ebb 100644 --- a/drivers/gpu/drm/i915/intel_dsi_vbt.c +++ b/drivers/gpu/drm/i915/intel_dsi_vbt.c @@ -41,13 +41,6 @@ #define MIPI_VIRTUAL_CHANNEL_SHIFT 1 #define MIPI_PORT_SHIFT 3 -#define PREPARE_CNT_MAX 0x3F -#define EXIT_ZERO_CNT_MAX 0x3F -#define CLK_ZERO_CNT_MAX 0xFF -#define TRAIL_CNT_MAX 0x1F - -#define NS_KHZ_RATIO 1000000 - /* base offsets for gpio pads */ #define VLV_GPIO_NC_0_HV_DDI0_HPD 0x4130 #define VLV_GPIO_NC_1_HV_DDI0_DDC_SDA 0x4120 @@ -532,7 +525,7 @@ void intel_dsi_msleep(struct intel_dsi *intel_dsi, int msec) msleep(msec); } -static void intel_dsi_log_params(struct intel_dsi *intel_dsi) +void intel_dsi_log_params(struct intel_dsi *intel_dsi) { DRM_DEBUG_KMS("Pclk %d\n", intel_dsi->pclk); DRM_DEBUG_KMS("Pixel overlap %d\n", intel_dsi->pixel_overlap); @@ -570,274 +563,6 @@ static void intel_dsi_log_params(struct intel_dsi *intel_dsi) enableddisabled(!(intel_dsi->video_frmt_cfg_bits & DISABLE_VIDEO_BTA))); } -#define ICL_PREPARE_CNT_MAX 0x7 -#define ICL_CLK_ZERO_CNT_MAX 0xf -#define ICL_TRAIL_CNT_MAX 0x7 -#define ICL_TCLK_PRE_CNT_MAX 0x3 -#define ICL_TCLK_POST_CNT_MAX 0x7 -#define ICL_HS_ZERO_CNT_MAX 0xf -#define ICL_EXIT_ZERO_CNT_MAX 0x7 - -static void icl_dphy_param_init(struct intel_dsi *intel_dsi) -{ - struct drm_device *dev = intel_dsi->base.base.dev; - struct drm_i915_private *dev_priv = to_i915(dev); - struct mipi_config *mipi_config = dev_priv->vbt.dsi.config; - u32 tlpx_ns; - u32 prepare_cnt, exit_zero_cnt, clk_zero_cnt, trail_cnt; - u32 ths_prepare_ns, tclk_trail_ns; - u32 hs_zero_cnt; - u32 tclk_pre_cnt, tclk_post_cnt; - - tlpx_ns = intel_dsi_tlpx_ns(intel_dsi); - - tclk_trail_ns = max(mipi_config->tclk_trail, mipi_config->ths_trail); - ths_prepare_ns = max(mipi_config->ths_prepare, - mipi_config->tclk_prepare); - - /* - * 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); - if (prepare_cnt > ICL_PREPARE_CNT_MAX) { - DRM_DEBUG_KMS("prepare_cnt out of range (%d)\n", prepare_cnt); - prepare_cnt = ICL_PREPARE_CNT_MAX; - } - - /* clk zero count in escape clocks */ - clk_zero_cnt = DIV_ROUND_UP(mipi_config->tclk_prepare_clkzero - - ths_prepare_ns, tlpx_ns); - if (clk_zero_cnt > ICL_CLK_ZERO_CNT_MAX) { - DRM_DEBUG_KMS("clk_zero_cnt out of range (%d)\n", clk_zero_cnt); - clk_zero_cnt = ICL_CLK_ZERO_CNT_MAX; - } - - /* trail cnt in escape clocks*/ - trail_cnt = DIV_ROUND_UP(tclk_trail_ns, tlpx_ns); - if (trail_cnt > ICL_TRAIL_CNT_MAX) { - DRM_DEBUG_KMS("trail_cnt out of range (%d)\n", trail_cnt); - trail_cnt = ICL_TRAIL_CNT_MAX; - } - - /* tclk pre count in escape clocks */ - tclk_pre_cnt = DIV_ROUND_UP(mipi_config->tclk_pre, tlpx_ns); - if (tclk_pre_cnt > ICL_TCLK_PRE_CNT_MAX) { - DRM_DEBUG_KMS("tclk_pre_cnt out of range (%d)\n", tclk_pre_cnt); - tclk_pre_cnt = ICL_TCLK_PRE_CNT_MAX; - } - - /* tclk post count in escape clocks */ - tclk_post_cnt = DIV_ROUND_UP(mipi_config->tclk_post, tlpx_ns); - if (tclk_post_cnt > ICL_TCLK_POST_CNT_MAX) { - DRM_DEBUG_KMS("tclk_post_cnt out of range (%d)\n", tclk_post_cnt); - tclk_post_cnt = ICL_TCLK_POST_CNT_MAX; - } - - /* hs zero cnt in escape clocks */ - hs_zero_cnt = DIV_ROUND_UP(mipi_config->ths_prepare_hszero - - ths_prepare_ns, tlpx_ns); - if (hs_zero_cnt > ICL_HS_ZERO_CNT_MAX) { - DRM_DEBUG_KMS("hs_zero_cnt out of range (%d)\n", hs_zero_cnt); - hs_zero_cnt = ICL_HS_ZERO_CNT_MAX; - } - - /* hs exit zero cnt in escape clocks */ - exit_zero_cnt = DIV_ROUND_UP(mipi_config->ths_exit, tlpx_ns); - if (exit_zero_cnt > ICL_EXIT_ZERO_CNT_MAX) { - DRM_DEBUG_KMS("exit_zero_cnt out of range (%d)\n", exit_zero_cnt); - exit_zero_cnt = ICL_EXIT_ZERO_CNT_MAX; - } - - /* clock lane dphy timings */ - intel_dsi->dphy_reg = (CLK_PREPARE_OVERRIDE | - CLK_PREPARE(prepare_cnt) | - CLK_ZERO_OVERRIDE | - CLK_ZERO(clk_zero_cnt) | - CLK_PRE_OVERRIDE | - CLK_PRE(tclk_pre_cnt) | - CLK_POST_OVERRIDE | - CLK_POST(tclk_post_cnt) | - CLK_TRAIL_OVERRIDE | - CLK_TRAIL(trail_cnt)); - - /* data lanes dphy timings */ - intel_dsi->dphy_data_lane_reg = (HS_PREPARE_OVERRIDE | - HS_PREPARE(prepare_cnt) | - HS_ZERO_OVERRIDE | - HS_ZERO(hs_zero_cnt) | - HS_TRAIL_OVERRIDE | - HS_TRAIL(trail_cnt) | - HS_EXIT_OVERRIDE | - HS_EXIT(exit_zero_cnt)); - - intel_dsi_log_params(intel_dsi); -} - -static void vlv_dphy_param_init(struct intel_dsi *intel_dsi) -{ - struct drm_device *dev = intel_dsi->base.base.dev; - struct drm_i915_private *dev_priv = to_i915(dev); - struct mipi_config *mipi_config = dev_priv->vbt.dsi.config; - u32 tlpx_ns, extra_byte_count, tlpx_ui; - u32 ui_num, ui_den; - u32 prepare_cnt, exit_zero_cnt, clk_zero_cnt, trail_cnt; - u32 ths_prepare_ns, tclk_trail_ns; - u32 tclk_prepare_clkzero, ths_prepare_hszero; - u32 lp_to_hs_switch, hs_to_lp_switch; - u32 mul; - - tlpx_ns = intel_dsi_tlpx_ns(intel_dsi); - - switch (intel_dsi->lane_count) { - case 1: - case 2: - extra_byte_count = 2; - break; - case 3: - extra_byte_count = 4; - break; - case 4: - default: - extra_byte_count = 3; - break; - } - - /* in Kbps */ - ui_num = NS_KHZ_RATIO; - ui_den = intel_dsi_bitrate(intel_dsi); - - tclk_prepare_clkzero = mipi_config->tclk_prepare_clkzero; - ths_prepare_hszero = mipi_config->ths_prepare_hszero; - - /* - * 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 (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; - } - - /* 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; - } - - /* 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); - - 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 | - clk_zero_cnt << 8 | prepare_cnt; - - /* - * LP to HS switch count = 4TLPX + PREP_COUNT * mul + EXIT_ZERO_COUNT * - * mul + 10UI + Extra Byte Count - * - * HS to LP switch count = THS-TRAIL + 2TLPX + Extra Byte Count - * Extra Byte Count is calculated according to number of lanes. - * High Low Switch Count is the Max of LP to HS and - * HS to LP switch count - * - */ - tlpx_ui = DIV_ROUND_UP(tlpx_ns * ui_den, ui_num); - - /* B044 */ - /* FIXME: - * The 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); - - hs_to_lp_switch = DIV_ROUND_UP(mipi_config->ths_trail + 2 * tlpx_ui, 8); - - 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 - * LP clk sync + LP11 + LP01 + tclk_prepare + tclk_zero + - * extra byte count - * 2TPLX + 1TLPX + 1 TPLX(in ns) + prepare_cnt * 2 + clk_zero_cnt * - * 2(in UI) + extra byte count - * In byteclks = (4TLPX + prepare_cnt * 2 + clk_zero_cnt *2 (in UI)) / - * 8 + extra byte count - */ - intel_dsi->clk_lp_to_hs_count = - DIV_ROUND_UP( - 4 * tlpx_ui + prepare_cnt * 2 + - clk_zero_cnt * 2, - 8); - - intel_dsi->clk_lp_to_hs_count += extra_byte_count; - - /* 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 - * In byteclks = (2*TLpx(in UI) + trail_count*2 +8)(in UI)/8 + - * Extra byte count - */ - intel_dsi->clk_hs_to_lp_count = - DIV_ROUND_UP(2 * tlpx_ui + trail_cnt * 2 + 8, - 8); - intel_dsi->clk_hs_to_lp_count += extra_byte_count; - - intel_dsi_log_params(intel_dsi); -} - bool intel_dsi_vbt_init(struct intel_dsi *intel_dsi, u16 panel_id) { struct drm_device *dev = intel_dsi->base.base.dev; @@ -925,11 +650,6 @@ bool intel_dsi_vbt_init(struct intel_dsi *intel_dsi, u16 panel_id) intel_dsi->burst_mode_ratio = burst_mode_ratio; - if (INTEL_GEN(dev_priv) >= 11) - icl_dphy_param_init(intel_dsi); - else - vlv_dphy_param_init(intel_dsi); - /* delays in VBT are in unit of 100us, so need to convert * here in ms * Delay (100us) * 100 /1000 = Delay / 10 (ms) */ diff --git a/drivers/gpu/drm/i915/vlv_dsi.c b/drivers/gpu/drm/i915/vlv_dsi.c index 255996a71b91..59500c838b9d 100644 --- a/drivers/gpu/drm/i915/vlv_dsi.c +++ b/drivers/gpu/drm/i915/vlv_dsi.c @@ -1689,6 +1689,174 @@ static void intel_dsi_add_properties(struct intel_connector *connector) } } +#define NS_KHZ_RATIO 1000000 + +#define PREPARE_CNT_MAX 0x3F +#define EXIT_ZERO_CNT_MAX 0x3F +#define CLK_ZERO_CNT_MAX 0xFF +#define TRAIL_CNT_MAX 0x1F + +static void vlv_dphy_param_init(struct intel_dsi *intel_dsi) +{ + struct drm_device *dev = intel_dsi->base.base.dev; + struct drm_i915_private *dev_priv = to_i915(dev); + struct mipi_config *mipi_config = dev_priv->vbt.dsi.config; + u32 tlpx_ns, extra_byte_count, tlpx_ui; + u32 ui_num, ui_den; + u32 prepare_cnt, exit_zero_cnt, clk_zero_cnt, trail_cnt; + u32 ths_prepare_ns, tclk_trail_ns; + u32 tclk_prepare_clkzero, ths_prepare_hszero; + u32 lp_to_hs_switch, hs_to_lp_switch; + u32 mul; + + tlpx_ns = intel_dsi_tlpx_ns(intel_dsi); + + switch (intel_dsi->lane_count) { + case 1: + case 2: + extra_byte_count = 2; + break; + case 3: + extra_byte_count = 4; + break; + case 4: + default: + extra_byte_count = 3; + break; + } + + /* in Kbps */ + ui_num = NS_KHZ_RATIO; + ui_den = intel_dsi_bitrate(intel_dsi); + + tclk_prepare_clkzero = mipi_config->tclk_prepare_clkzero; + ths_prepare_hszero = mipi_config->ths_prepare_hszero; + + /* + * 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 (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; + } + + /* 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; + } + + /* 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); + + 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 | + clk_zero_cnt << 8 | prepare_cnt; + + /* + * LP to HS switch count = 4TLPX + PREP_COUNT * mul + EXIT_ZERO_COUNT * + * mul + 10UI + Extra Byte Count + * + * HS to LP switch count = THS-TRAIL + 2TLPX + Extra Byte Count + * Extra Byte Count is calculated according to number of lanes. + * High Low Switch Count is the Max of LP to HS and + * HS to LP switch count + * + */ + tlpx_ui = DIV_ROUND_UP(tlpx_ns * ui_den, ui_num); + + /* B044 */ + /* FIXME: + * The 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); + + hs_to_lp_switch = DIV_ROUND_UP(mipi_config->ths_trail + 2 * tlpx_ui, 8); + + 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 + * LP clk sync + LP11 + LP01 + tclk_prepare + tclk_zero + + * extra byte count + * 2TPLX + 1TLPX + 1 TPLX(in ns) + prepare_cnt * 2 + clk_zero_cnt * + * 2(in UI) + extra byte count + * In byteclks = (4TLPX + prepare_cnt * 2 + clk_zero_cnt *2 (in UI)) / + * 8 + extra byte count + */ + intel_dsi->clk_lp_to_hs_count = + DIV_ROUND_UP( + 4 * tlpx_ui + prepare_cnt * 2 + + clk_zero_cnt * 2, + 8); + + intel_dsi->clk_lp_to_hs_count += extra_byte_count; + + /* 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 + * In byteclks = (2*TLpx(in UI) + trail_count*2 +8)(in UI)/8 + + * Extra byte count + */ + intel_dsi->clk_hs_to_lp_count = + DIV_ROUND_UP(2 * tlpx_ui + trail_cnt * 2 + 8, + 8); + intel_dsi->clk_hs_to_lp_count += extra_byte_count; + + intel_dsi_log_params(intel_dsi); +} + void vlv_dsi_init(struct drm_i915_private *dev_priv) { struct drm_device *dev = &dev_priv->drm; @@ -1778,6 +1946,8 @@ void vlv_dsi_init(struct drm_i915_private *dev_priv) goto err; } + vlv_dphy_param_init(intel_dsi); + /* * In case of BYT with CRC PMIC, we need to use GPIO for * Panel control.
The vlv/icl_dphy_param_init calls do various calculations to set dphy parameters based on the pclk. Move the calling of vlv/icl_dphy_param_init to vlv_dsi_init to give vlv_dsi_init a chance to tweak the pclk before these calculations are done. Changes in v2: -Also moves the icl and vlv specific dphy_param_init functions from the generic intel_dsi_vbt.c file into the icl_ and vlv_dsi.c specific files. Note icl_dphy_param_init() and vlv_dphy_param_init() are only moved, otherwise they are completely unchanged. Signed-off-by: Hans de Goede <hdegoede@redhat.com> --- drivers/gpu/drm/i915/icl_dsi.c | 108 ++++++++++ drivers/gpu/drm/i915/intel_dsi.h | 1 + drivers/gpu/drm/i915/intel_dsi_vbt.c | 282 +-------------------------- drivers/gpu/drm/i915/vlv_dsi.c | 170 ++++++++++++++++ 4 files changed, 280 insertions(+), 281 deletions(-)