[Intel-gfx] [v2] drm/i915: Add support for Video Burst Mode for MIPI DSI
Daniel Vetter
daniel at ffwll.ch
Wed Jul 30 22:36:46 CEST 2014
On Wed, Jul 30, 2014 at 08:34:57PM +0530, Shobhit Kumar wrote:
> v2: Updated the error log as suggested by Imre
>
> Signed-off-by: Shobhit Kumar <shobhit.kumar at intel.com>
> Reviewed-by: Imre Deak <imre.deak at intel.com>
Remaining patches merged, thanks.
-Daniel
> ---
> drivers/gpu/drm/i915/intel_bios.h | 3 ++-
> drivers/gpu/drm/i915/intel_dsi.c | 22 ++++++++++-------
> drivers/gpu/drm/i915/intel_dsi.h | 2 ++
> drivers/gpu/drm/i915/intel_dsi_panel_vbt.c | 38 ++++++++++++++++++++++++++++--
> drivers/gpu/drm/i915/intel_dsi_pll.c | 9 +++----
> 5 files changed, 57 insertions(+), 17 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_bios.h b/drivers/gpu/drm/i915/intel_bios.h
> index b986677..905999b 100644
> --- a/drivers/gpu/drm/i915/intel_bios.h
> +++ b/drivers/gpu/drm/i915/intel_bios.h
> @@ -802,7 +802,8 @@ struct mipi_config {
>
> u16 rsvd4;
>
> - u8 rsvd5[5];
> + u8 rsvd5;
> + u32 target_burst_mode_freq;
> u32 dsi_ddr_clk;
> u32 bridge_ref_clk;
>
> diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
> index 670c29a..aea8f33 100644
> --- a/drivers/gpu/drm/i915/intel_dsi.c
> +++ b/drivers/gpu/drm/i915/intel_dsi.c
> @@ -423,9 +423,11 @@ static u16 txclkesc(u32 divider, unsigned int us)
> }
>
> /* return pixels in terms of txbyteclkhs */
> -static u16 txbyteclkhs(u16 pixels, int bpp, int lane_count)
> +static u16 txbyteclkhs(u16 pixels, int bpp, int lane_count,
> + u16 burst_mode_ratio)
> {
> - return DIV_ROUND_UP(DIV_ROUND_UP(pixels * bpp, 8), lane_count);
> + return DIV_ROUND_UP(DIV_ROUND_UP(pixels * bpp * burst_mode_ratio,
> + 8 * 100), lane_count);
> }
>
> static void set_dsi_timings(struct drm_encoder *encoder,
> @@ -451,10 +453,12 @@ static void set_dsi_timings(struct drm_encoder *encoder,
> vbp = mode->vtotal - mode->vsync_end;
>
> /* horizontal values are in terms of high speed byte clock */
> - hactive = txbyteclkhs(hactive, bpp, lane_count);
> - hfp = txbyteclkhs(hfp, bpp, lane_count);
> - hsync = txbyteclkhs(hsync, bpp, lane_count);
> - hbp = txbyteclkhs(hbp, bpp, lane_count);
> + hactive = txbyteclkhs(hactive, bpp, lane_count,
> + intel_dsi->burst_mode_ratio);
> + hfp = txbyteclkhs(hfp, bpp, lane_count, intel_dsi->burst_mode_ratio);
> + hsync = txbyteclkhs(hsync, bpp, lane_count,
> + intel_dsi->burst_mode_ratio);
> + hbp = txbyteclkhs(hbp, bpp, lane_count, intel_dsi->burst_mode_ratio);
>
> I915_WRITE(MIPI_HACTIVE_AREA_COUNT(pipe), hactive);
> I915_WRITE(MIPI_HFP_COUNT(pipe), hfp);
> @@ -541,12 +545,14 @@ static void intel_dsi_prepare(struct intel_encoder *intel_encoder)
> intel_dsi->video_mode_format == VIDEO_MODE_BURST) {
> I915_WRITE(MIPI_HS_TX_TIMEOUT(pipe),
> txbyteclkhs(adjusted_mode->htotal, bpp,
> - intel_dsi->lane_count) + 1);
> + intel_dsi->lane_count,
> + intel_dsi->burst_mode_ratio) + 1);
> } else {
> I915_WRITE(MIPI_HS_TX_TIMEOUT(pipe),
> txbyteclkhs(adjusted_mode->vtotal *
> adjusted_mode->htotal,
> - bpp, intel_dsi->lane_count) + 1);
> + bpp, intel_dsi->lane_count,
> + intel_dsi->burst_mode_ratio) + 1);
> }
> I915_WRITE(MIPI_LP_RX_TIMEOUT(pipe), intel_dsi->lp_rx_timeout);
> I915_WRITE(MIPI_TURN_AROUND_TIMEOUT(pipe), intel_dsi->turn_arnd_val);
> diff --git a/drivers/gpu/drm/i915/intel_dsi.h b/drivers/gpu/drm/i915/intel_dsi.h
> index fd51867..657eb5c 100644
> --- a/drivers/gpu/drm/i915/intel_dsi.h
> +++ b/drivers/gpu/drm/i915/intel_dsi.h
> @@ -116,6 +116,8 @@ struct intel_dsi {
> u16 clk_hs_to_lp_count;
>
> u16 init_count;
> + u32 pclk;
> + u16 burst_mode_ratio;
>
> /* all delays in ms */
> u16 backlight_off_delay;
> diff --git a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
> index 47c7584..f6bdd44 100644
> --- a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
> +++ b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
> @@ -271,6 +271,8 @@ static bool generic_init(struct intel_dsi_device *dsi)
> u32 ths_prepare_ns, tclk_trail_ns;
> u32 tclk_prepare_clkzero, ths_prepare_hszero;
> u32 lp_to_hs_switch, hs_to_lp_switch;
> + u32 pclk, computed_ddr;
> + u16 burst_mode_ratio;
>
> DRM_DEBUG_KMS("\n");
>
> @@ -284,8 +286,6 @@ static bool generic_init(struct intel_dsi_device *dsi)
> else if (intel_dsi->pixel_format == VID_MODE_FORMAT_RGB565)
> bits_per_pixel = 16;
>
> - bitrate = (mode->clock * bits_per_pixel) / intel_dsi->lane_count;
> -
> intel_dsi->operation_mode = mipi_config->is_cmd_mode;
> intel_dsi->video_mode_format = mipi_config->video_transfer_mode;
> intel_dsi->escape_clk_div = mipi_config->byte_clk_sel;
> @@ -297,6 +297,40 @@ static bool generic_init(struct intel_dsi_device *dsi)
> intel_dsi->video_frmt_cfg_bits =
> mipi_config->bta_enabled ? DISABLE_VIDEO_BTA : 0;
>
> + pclk = mode->clock;
> +
> + /* Burst Mode Ratio
> + * Target ddr frequency from VBT / non burst ddr freq
> + * multiply by 100 to preserve remainder
> + */
> + if (intel_dsi->video_mode_format == VIDEO_MODE_BURST) {
> + if (mipi_config->target_burst_mode_freq) {
> + computed_ddr =
> + (pclk * bits_per_pixel) / intel_dsi->lane_count;
> +
> + if (mipi_config->target_burst_mode_freq <
> + computed_ddr) {
> + DRM_ERROR("Burst mode freq is less than computed\n");
> + return false;
> + }
> +
> + burst_mode_ratio = DIV_ROUND_UP(
> + mipi_config->target_burst_mode_freq * 100,
> + computed_ddr);
> +
> + pclk = DIV_ROUND_UP(pclk * burst_mode_ratio, 100);
> + } else {
> + DRM_ERROR("Burst mode target is not set\n");
> + return false;
> + }
> + } else
> + burst_mode_ratio = 100;
> +
> + intel_dsi->burst_mode_ratio = burst_mode_ratio;
> + intel_dsi->pclk = pclk;
> +
> + bitrate = (pclk * bits_per_pixel) / intel_dsi->lane_count;
> +
> switch (intel_dsi->escape_clk_div) {
> case 0:
> tlpx_ns = 50;
> diff --git a/drivers/gpu/drm/i915/intel_dsi_pll.c b/drivers/gpu/drm/i915/intel_dsi_pll.c
> index d8bb1ea..06fad93 100644
> --- a/drivers/gpu/drm/i915/intel_dsi_pll.c
> +++ b/drivers/gpu/drm/i915/intel_dsi_pll.c
> @@ -134,8 +134,7 @@ static u32 dsi_rr_formula(const struct drm_display_mode *mode,
> #else
>
> /* Get DSI clock from pixel clock */
> -static u32 dsi_clk_from_pclk(const struct drm_display_mode *mode,
> - int pixel_format, int lane_count)
> +static u32 dsi_clk_from_pclk(u32 pclk, int pixel_format, int lane_count)
> {
> u32 dsi_clk_khz;
> u32 bpp;
> @@ -156,7 +155,7 @@ static u32 dsi_clk_from_pclk(const struct drm_display_mode *mode,
>
> /* DSI data rate = pixel clock * bits per pixel / lane count
> pixel clock is converted from KHz to Hz */
> - dsi_clk_khz = DIV_ROUND_CLOSEST(mode->clock * bpp, lane_count);
> + dsi_clk_khz = DIV_ROUND_CLOSEST(pclk * bpp, lane_count);
>
> return dsi_clk_khz;
> }
> @@ -228,14 +227,12 @@ static int dsi_calc_mnp(u32 dsi_clk, struct dsi_mnp *dsi_mnp)
> static void vlv_configure_dsi_pll(struct intel_encoder *encoder)
> {
> struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
> - struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
> - const struct drm_display_mode *mode = &intel_crtc->config.adjusted_mode;
> struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
> int ret;
> struct dsi_mnp dsi_mnp;
> u32 dsi_clk;
>
> - dsi_clk = dsi_clk_from_pclk(mode, intel_dsi->pixel_format,
> + dsi_clk = dsi_clk_from_pclk(intel_dsi->pclk, intel_dsi->pixel_format,
> intel_dsi->lane_count);
>
> ret = dsi_calc_mnp(dsi_clk, &dsi_mnp);
> --
> 1.9.1
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
--
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
More information about the Intel-gfx
mailing list