From: "Ville Syrjälä" <ville.syrjala@linux.intel.com>
To: Madhav Chauhan <madhav.chauhan@intel.com>
Cc: jani.nikula@intel.com, intel-gfx@lists.freedesktop.org,
paulo.r.zanoni@intel.com, rodrigo.vivi@intel.com
Subject: Re: [PATCH v5 07/13] drm/i915/icl: Program DSI clock and data lane timing params
Date: Thu, 19 Jul 2018 19:17:39 +0300 [thread overview]
Message-ID: <20180719161739.GC5565@intel.com> (raw)
In-Reply-To: <1531215614-6828-8-git-send-email-madhav.chauhan@intel.com>
On Tue, Jul 10, 2018 at 03:10:08PM +0530, Madhav Chauhan wrote:
> 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.chauhan@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 | 200 +++++++++++++++++++++++++----------
> 3 files changed, 165 insertions(+), 56 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c
> index bc27e34..832772d 100644
> --- a/drivers/gpu/drm/i915/icl_dsi.c
> +++ b/drivers/gpu/drm/i915/icl_dsi.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.h b/drivers/gpu/drm/i915/intel_dsi.h
> index ad7c1cb..9fd8526 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 ac83d6b..428290d 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)) {
I'd suggest extracting the icl vs. old things into separate functions.
> + /*
> + * 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");
> + }
This doesn't match how we do it on the older platforms. Would be nice to
stick to a uniform apporoach across the board.
Maybe add some kind of small helper to make this stuff less repetitive:
void clamp_val(u32 *val, u32 limit, const char *name)
{
if (*val <= limit)
return;
DEBUG("%s...\n", name, ...);
*val = limit;
}
Could even mix in some cpp magic to stringify the name automagically.
> +
> + 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
> + */
Unrelated changes.
> 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
--
Ville Syrjälä
Intel
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
next prev parent reply other threads:[~2018-07-19 16:17 UTC|newest]
Thread overview: 63+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-07-10 9:40 [PATCH v5 00/13] ICELAKE DSI DRIVER Madhav Chauhan
2018-07-10 9:40 ` [PATCH v5 01/13] drm/i915/icl: Configure lane sequencing of combo phy transmitter Madhav Chauhan
2018-07-19 16:11 ` Ville Syrjälä
2018-07-19 18:35 ` Chauhan, Madhav
2018-07-27 11:57 ` Chauhan, Madhav
2018-09-11 17:46 ` Jani Nikula
2018-09-12 6:32 ` Madhav Chauhan
2018-09-10 12:20 ` Lisovskiy, Stanislav
2018-09-10 15:27 ` Madhav Chauhan
2018-09-11 8:08 ` Lisovskiy, Stanislav
2018-07-10 9:40 ` [PATCH v5 02/13] drm/i915/icl: DSI vswing programming sequence Madhav Chauhan
2018-09-06 14:01 ` [v5, " Kulkarni, Vandita
2018-09-10 7:43 ` Madhav Chauhan
2018-09-11 18:16 ` Jani Nikula
2018-09-12 6:34 ` Madhav Chauhan
2018-09-11 18:50 ` [PATCH v5 " Jani Nikula
2018-09-12 9:03 ` Madhav Chauhan
2018-09-12 9:10 ` Jani Nikula
2018-07-10 9:40 ` [PATCH v5 03/13] drm/i915/icl: Enable DDI Buffer Madhav Chauhan
2018-09-11 18:54 ` Jani Nikula
2018-09-12 9:06 ` Madhav Chauhan
2018-09-12 9:10 ` Jani Nikula
2018-07-10 9:40 ` [PATCH v5 04/13] drm/i915/icl: Define T_INIT_MASTER registers Madhav Chauhan
2018-09-11 19:18 ` Jani Nikula
2018-07-10 9:40 ` [PATCH v5 05/13] drm/i915/icl: Program " Madhav Chauhan
2018-09-11 19:17 ` Jani Nikula
2018-07-10 9:40 ` [PATCH v5 06/13] drm/i915/icl: Define data/clock lanes dphy timing registers Madhav Chauhan
2018-09-11 19:14 ` Jani Nikula
2018-09-12 9:11 ` Madhav Chauhan
2018-07-10 9:40 ` [PATCH v5 07/13] drm/i915/icl: Program DSI clock and data lane timing params Madhav Chauhan
2018-07-19 16:17 ` Ville Syrjälä [this message]
2018-07-10 9:40 ` [PATCH v5 08/13] drm/i915/icl: Define TA_TIMING_PARAM registers Madhav Chauhan
2018-09-11 19:23 ` Jani Nikula
2018-09-12 9:13 ` Madhav Chauhan
2018-07-10 9:40 ` [PATCH v5 09/13] drm/i915/icl: Program " Madhav Chauhan
2018-07-19 16:21 ` Ville Syrjälä
2018-07-20 8:08 ` Chauhan, Madhav
2018-09-11 19:26 ` Jani Nikula
2018-09-12 9:25 ` Madhav Chauhan
2018-09-12 9:39 ` Jani Nikula
2018-07-10 9:40 ` [PATCH v5 10/13] drm/i915/icl: Get DSI transcoder for a given port Madhav Chauhan
2018-07-10 9:40 ` [PATCH v5 11/13] drm/i915/icl: Add macros for MMIO of DSI transcoder registers Madhav Chauhan
2018-07-19 16:22 ` Ville Syrjälä
2018-07-20 8:55 ` Chauhan, Madhav
2018-09-12 9:36 ` Madhav Chauhan
2018-09-12 18:00 ` Ville Syrjälä
2018-09-14 6:12 ` Madhav Chauhan
2018-09-14 12:25 ` Ville Syrjälä
2018-09-14 13:06 ` Madhav Chauhan
2018-09-14 13:27 ` Madhav Chauhan
2018-09-14 13:41 ` Ville Syrjälä
2018-07-10 9:40 ` [PATCH v5 12/13] drm/i915/icl: Define TRANS_DSI_FUNC_CONF register Madhav Chauhan
2018-09-11 19:30 ` Jani Nikula
2018-09-12 9:35 ` Madhav Chauhan
2018-09-12 9:47 ` Jani Nikula
2018-07-10 9:40 ` [PATCH v5 13/13] drm/i915/icl: Configure DSI transcoders Madhav Chauhan
2018-07-10 10:46 ` ✗ Fi.CI.CHECKPATCH: warning for ICELAKE DSI DRIVER (rev5) Patchwork
2018-07-10 10:51 ` ✗ Fi.CI.SPARSE: " Patchwork
2018-07-10 11:04 ` ✓ Fi.CI.BAT: success " Patchwork
2018-07-10 16:28 ` ✓ Fi.CI.IGT: " Patchwork
2018-09-11 19:35 ` [PATCH v5 00/13] ICELAKE DSI DRIVER Jani Nikula
2018-09-12 6:16 ` Madhav Chauhan
2018-09-12 7:31 ` Jani Nikula
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20180719161739.GC5565@intel.com \
--to=ville.syrjala@linux.intel.com \
--cc=intel-gfx@lists.freedesktop.org \
--cc=jani.nikula@intel.com \
--cc=madhav.chauhan@intel.com \
--cc=paulo.r.zanoni@intel.com \
--cc=rodrigo.vivi@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).