Message ID | 1537095223-5184-7-git-send-email-madhav.chauhan@intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | ICELAKE DSI DRIVER | expand |
On Sun, 16 Sep 2018, Madhav Chauhan <madhav.chauhan@intel.com> 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. > > v2: Use newly defined bitfields for data and clock lane Ville's review [1] hasn't been addressed. BR, Jani. [1] http://mid.mail-archive.com/20180719161739.GC5565@intel.com > > 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 ff5b285..9602b65 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 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..fbb159b 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_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); > + } 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;
> -----Original Message----- > From: Nikula, Jani > Sent: Wednesday, September 26, 2018 6:29 PM > To: Chauhan, Madhav <madhav.chauhan@intel.com>; intel- > gfx@lists.freedesktop.org > Cc: Kulkarni, Vandita <vandita.kulkarni@intel.com>; Vivi, Rodrigo > <rodrigo.vivi@intel.com>; Rangappa, Komala B > <komala.b.rangappa@intel.com>; Chauhan, Madhav > <madhav.chauhan@intel.com> > Subject: Re: [PATCH v6 06/20] drm/i915/icl: Program DSI clock and data lane > timing params > > On Sun, 16 Sep 2018, Madhav Chauhan <madhav.chauhan@intel.com> > 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. > > > > v2: Use newly defined bitfields for data and clock lane > > Ville's review [1] hasn't been addressed. Oh..Overlooked the comments. My bad. Will address them while publishing v7. Regards, Madhav > > BR, > Jani. > > [1] http://mid.mail-archive.com/20180719161739.GC5565@intel.com > > > > > 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 ff5b285..9602b65 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 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..fbb159b 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_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); > > + } 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; > > -- > Jani Nikula, Intel Open Source Graphics Center
diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c index ff5b285..9602b65 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 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..fbb159b 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_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); + } 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;
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 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(-)