[Intel-gfx] [PATCH v7 06/23] drm/i915/icl: Program DSI clock and data lane timing params
Madhav Chauhan
madhav.chauhan at intel.com
Sat Oct 20 10:57:33 UTC 2018
On 10/15/2018 7:57 PM, Jani Nikula wrote:
> From: Madhav Chauhan <madhav.chauhan at intel.com>
>
> 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.
>
> v2: Use newly defined bitfields for data and clock lane
>
> v3 by Jani:
> - Rebase on dphy abstraction
> - Reduce local variables
> - Remove unrelated comment changes (Ville)
> - Use the same style for range checks as VLV (Ville)
> - Assign, don't OR dphy_reg contents
v3 changes looks fine to me.
Regards,
Madhav
>
> Signed-off-by: Madhav Chauhan <madhav.chauhan at intel.com>
> Signed-off-by: Jani Nikula <jani.nikula at intel.com>
> ---
> drivers/gpu/drm/i915/icl_dsi.c | 18 ++++++
> drivers/gpu/drm/i915/intel_dsi.h | 3 +
> drivers/gpu/drm/i915/intel_dsi_vbt.c | 110 ++++++++++++++++++++++++++++++++++-
> 3 files changed, 130 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c
> index ff5b285ca495..9602b6532028 100644
> --- a/drivers/gpu/drm/i915/icl_dsi.c
> +++ b/drivers/gpu/drm/i915/icl_dsi.c
> @@ -291,6 +291,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.h b/drivers/gpu/drm/i915/intel_dsi.h
> index d7c0c599b52d..12b758ebefce 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_vbt.c b/drivers/gpu/drm/i915/intel_dsi_vbt.c
> index 5e16b4c5f531..3035422aa0d6 100644
> --- a/drivers/gpu/drm/i915/intel_dsi_vbt.c
> +++ b/drivers/gpu/drm/i915/intel_dsi_vbt.c
> @@ -510,6 +510,111 @@ int intel_dsi_vbt_get_modes(struct intel_dsi *intel_dsi)
> return 1;
> }
>
> +#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));
> +}
> +
> static void vlv_dphy_param_init(struct intel_dsi *intel_dsi)
> {
> struct drm_device *dev = intel_dsi->base.base.dev;
> @@ -743,7 +848,10 @@ bool intel_dsi_vbt_init(struct intel_dsi *intel_dsi, u16 panel_id)
>
> intel_dsi->burst_mode_ratio = burst_mode_ratio;
>
> - vlv_dphy_param_init(intel_dsi);
> + if (IS_ICELAKE(dev_priv))
> + icl_dphy_param_init(intel_dsi);
> + else
> + vlv_dphy_param_init(intel_dsi);
>
> DRM_DEBUG_KMS("Pclk %d\n", intel_dsi->pclk);
> DRM_DEBUG_KMS("Pixel overlap %d\n", intel_dsi->pixel_overlap);
More information about the Intel-gfx
mailing list