Commit 7f0c8605 authored by Shobhit Kumar's avatar Shobhit Kumar Committed by Daniel Vetter

drm/i915: Add support for Video Burst Mode for MIPI DSI

v2: Updated the error log as suggested by Imre
Signed-off-by: default avatarShobhit Kumar <shobhit.kumar@intel.com>
Reviewed-by: default avatarImre Deak <imre.deak@intel.com>
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent 1fb44505
...@@ -802,7 +802,8 @@ struct mipi_config { ...@@ -802,7 +802,8 @@ struct mipi_config {
u16 rsvd4; u16 rsvd4;
u8 rsvd5[5]; u8 rsvd5;
u32 target_burst_mode_freq;
u32 dsi_ddr_clk; u32 dsi_ddr_clk;
u32 bridge_ref_clk; u32 bridge_ref_clk;
......
...@@ -423,9 +423,11 @@ static u16 txclkesc(u32 divider, unsigned int us) ...@@ -423,9 +423,11 @@ static u16 txclkesc(u32 divider, unsigned int us)
} }
/* return pixels in terms of txbyteclkhs */ /* 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, static void set_dsi_timings(struct drm_encoder *encoder,
...@@ -451,10 +453,12 @@ 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; vbp = mode->vtotal - mode->vsync_end;
/* horizontal values are in terms of high speed byte clock */ /* horizontal values are in terms of high speed byte clock */
hactive = txbyteclkhs(hactive, bpp, lane_count); hactive = txbyteclkhs(hactive, bpp, lane_count,
hfp = txbyteclkhs(hfp, bpp, lane_count); intel_dsi->burst_mode_ratio);
hsync = txbyteclkhs(hsync, bpp, lane_count); hfp = txbyteclkhs(hfp, bpp, lane_count, intel_dsi->burst_mode_ratio);
hbp = txbyteclkhs(hbp, bpp, lane_count); 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_HACTIVE_AREA_COUNT(pipe), hactive);
I915_WRITE(MIPI_HFP_COUNT(pipe), hfp); I915_WRITE(MIPI_HFP_COUNT(pipe), hfp);
...@@ -541,12 +545,14 @@ static void intel_dsi_prepare(struct intel_encoder *intel_encoder) ...@@ -541,12 +545,14 @@ static void intel_dsi_prepare(struct intel_encoder *intel_encoder)
intel_dsi->video_mode_format == VIDEO_MODE_BURST) { intel_dsi->video_mode_format == VIDEO_MODE_BURST) {
I915_WRITE(MIPI_HS_TX_TIMEOUT(pipe), I915_WRITE(MIPI_HS_TX_TIMEOUT(pipe),
txbyteclkhs(adjusted_mode->htotal, bpp, txbyteclkhs(adjusted_mode->htotal, bpp,
intel_dsi->lane_count) + 1); intel_dsi->lane_count,
intel_dsi->burst_mode_ratio) + 1);
} else { } else {
I915_WRITE(MIPI_HS_TX_TIMEOUT(pipe), I915_WRITE(MIPI_HS_TX_TIMEOUT(pipe),
txbyteclkhs(adjusted_mode->vtotal * txbyteclkhs(adjusted_mode->vtotal *
adjusted_mode->htotal, 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_LP_RX_TIMEOUT(pipe), intel_dsi->lp_rx_timeout);
I915_WRITE(MIPI_TURN_AROUND_TIMEOUT(pipe), intel_dsi->turn_arnd_val); I915_WRITE(MIPI_TURN_AROUND_TIMEOUT(pipe), intel_dsi->turn_arnd_val);
......
...@@ -116,6 +116,8 @@ struct intel_dsi { ...@@ -116,6 +116,8 @@ struct intel_dsi {
u16 clk_hs_to_lp_count; u16 clk_hs_to_lp_count;
u16 init_count; u16 init_count;
u32 pclk;
u16 burst_mode_ratio;
/* all delays in ms */ /* all delays in ms */
u16 backlight_off_delay; u16 backlight_off_delay;
......
...@@ -271,6 +271,8 @@ static bool generic_init(struct intel_dsi_device *dsi) ...@@ -271,6 +271,8 @@ static bool generic_init(struct intel_dsi_device *dsi)
u32 ths_prepare_ns, tclk_trail_ns; u32 ths_prepare_ns, tclk_trail_ns;
u32 tclk_prepare_clkzero, ths_prepare_hszero; u32 tclk_prepare_clkzero, ths_prepare_hszero;
u32 lp_to_hs_switch, hs_to_lp_switch; u32 lp_to_hs_switch, hs_to_lp_switch;
u32 pclk, computed_ddr;
u16 burst_mode_ratio;
DRM_DEBUG_KMS("\n"); DRM_DEBUG_KMS("\n");
...@@ -284,8 +286,6 @@ static bool generic_init(struct intel_dsi_device *dsi) ...@@ -284,8 +286,6 @@ static bool generic_init(struct intel_dsi_device *dsi)
else if (intel_dsi->pixel_format == VID_MODE_FORMAT_RGB565) else if (intel_dsi->pixel_format == VID_MODE_FORMAT_RGB565)
bits_per_pixel = 16; 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->operation_mode = mipi_config->is_cmd_mode;
intel_dsi->video_mode_format = mipi_config->video_transfer_mode; intel_dsi->video_mode_format = mipi_config->video_transfer_mode;
intel_dsi->escape_clk_div = mipi_config->byte_clk_sel; intel_dsi->escape_clk_div = mipi_config->byte_clk_sel;
...@@ -297,6 +297,40 @@ static bool generic_init(struct intel_dsi_device *dsi) ...@@ -297,6 +297,40 @@ static bool generic_init(struct intel_dsi_device *dsi)
intel_dsi->video_frmt_cfg_bits = intel_dsi->video_frmt_cfg_bits =
mipi_config->bta_enabled ? DISABLE_VIDEO_BTA : 0; 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) { switch (intel_dsi->escape_clk_div) {
case 0: case 0:
tlpx_ns = 50; tlpx_ns = 50;
......
...@@ -134,8 +134,7 @@ static u32 dsi_rr_formula(const struct drm_display_mode *mode, ...@@ -134,8 +134,7 @@ static u32 dsi_rr_formula(const struct drm_display_mode *mode,
#else #else
/* Get DSI clock from pixel clock */ /* Get DSI clock from pixel clock */
static u32 dsi_clk_from_pclk(const struct drm_display_mode *mode, static u32 dsi_clk_from_pclk(u32 pclk, int pixel_format, int lane_count)
int pixel_format, int lane_count)
{ {
u32 dsi_clk_khz; u32 dsi_clk_khz;
u32 bpp; u32 bpp;
...@@ -156,7 +155,7 @@ static u32 dsi_clk_from_pclk(const struct drm_display_mode *mode, ...@@ -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 /* DSI data rate = pixel clock * bits per pixel / lane count
pixel clock is converted from KHz to Hz */ 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; return dsi_clk_khz;
} }
...@@ -228,14 +227,12 @@ static int dsi_calc_mnp(u32 dsi_clk, struct dsi_mnp *dsi_mnp) ...@@ -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) static void vlv_configure_dsi_pll(struct intel_encoder *encoder)
{ {
struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; 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); struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
int ret; int ret;
struct dsi_mnp dsi_mnp; struct dsi_mnp dsi_mnp;
u32 dsi_clk; 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); intel_dsi->lane_count);
ret = dsi_calc_mnp(dsi_clk, &dsi_mnp); ret = dsi_calc_mnp(dsi_clk, &dsi_mnp);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment