drm/i915: Add support for Video Burst Mode for MIPI DSI
authorShobhit Kumar <shobhit.kumar@intel.com>
Wed, 30 Jul 2014 15:04:57 +0000 (20:34 +0530)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Fri, 8 Aug 2014 15:43:45 +0000 (17:43 +0200)
v2: Updated the error log as suggested by Imre

Signed-off-by: Shobhit Kumar <shobhit.kumar@intel.com>
Reviewed-by: Imre Deak <imre.deak@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
drivers/gpu/drm/i915/intel_bios.h
drivers/gpu/drm/i915/intel_dsi.c
drivers/gpu/drm/i915/intel_dsi.h
drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
drivers/gpu/drm/i915/intel_dsi_pll.c

index b98667796337d776b1d1d39c677a5dfffe6b32b6..905999bee2ac5ee7f7b550f1c3f4fa043f422a97 100644 (file)
@@ -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;
 
index 670c29a7b5dd8e2a10867be9d742ace0e6ad3e11..aea8f3383c2696919d7eeb456d6bc6c6520b7104 100644 (file)
@@ -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);
index fd51867fd0d3157ef849f4f50367e92865932f77..657eb5c1b9d80db7993a28febb8847c2dcf8665f 100644 (file)
@@ -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;
index 47c7584a4aa0336938bb1150cc141e0e1063bfee..f6bdd44069cec77c676b2ac7222642cb5ed76f32 100644 (file)
@@ -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;
index d8bb1ea2f0da5a4be3a7b097cfe9b79bad954795..06fad93a68c8781ba7295c0da5c9124453c972a0 100644 (file)
@@ -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);