Message ID | 20200109110835.29764-3-vandita.kulkarni@intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Add support for mipi dsi cmd mode | expand |
On Thu, 09 Jan 2020, Vandita Kulkarni <vandita.kulkarni@intel.com> wrote: > Transcoder timing calculation differ for command mode. > > v2: Use is_vid_mode, and use same I915_WRITE (Jani) > v3: Adjust the calculations to reflect dsc compression ratio > > Signed-off-by: Vandita Kulkarni <vandita.kulkarni@intel.com> > --- > drivers/gpu/drm/i915/display/icl_dsi.c | 52 +++++++++++++++++--------- > 1 file changed, 35 insertions(+), 17 deletions(-) > > diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c > index ca37beca3e41..66dc8be672b8 100644 > --- a/drivers/gpu/drm/i915/display/icl_dsi.c > +++ b/drivers/gpu/drm/i915/display/icl_dsi.c > @@ -808,9 +808,11 @@ gen11_dsi_set_transcoder_timings(struct intel_encoder *encoder, > enum transcoder dsi_trans; > /* horizontal timings */ > u16 htotal, hactive, hsync_start, hsync_end, hsync_size; > + u16 cal_htotal, cal_vtotal; I don't think you actually need these for anything, you can just use htotal and vtotal directly. This is a function with tons of locals already, gets confusing. > u16 hback_porch; > /* vertical timings */ > u16 vtotal, vactive, vsync_start, vsync_end, vsync_shift; > + int bpp, line_time_us, byte_clk_period_ns; These belong in the if block with smaller scope. > int mul = 1, div = 1; > > /* > @@ -827,14 +829,27 @@ gen11_dsi_set_transcoder_timings(struct intel_encoder *encoder, > } > > hactive = adjusted_mode->crtc_hdisplay; > - htotal = DIV_ROUND_UP(adjusted_mode->crtc_htotal * mul, div); > + vactive = adjusted_mode->crtc_vdisplay; Please keep the horizontal and vertical timing stuff separate. First horizontal, then vertical, like they are. > + if (is_cmd_mode(intel_dsi)) { > + bpp = mipi_dsi_pixel_format_to_bpp(intel_dsi->pixel_format); > + byte_clk_period_ns = 8 * 1000000 / intel_dsi->pclk; > + cal_htotal = hactive + 160; > + line_time_us = (cal_htotal * (bpp / 8) * byte_clk_period_ns) / (1000 * intel_dsi->lane_count); > + cal_vtotal = vactive + DIV_ROUND_UP(460, line_time_us); > + } > + > + if (is_vid_mode(intel_dsi)) > + cal_htotal = adjusted_mode->crtc_htotal; That should be an else branch. Or maybe is_vid_mode() first, and do the command mode stuff in the else branch. > + htotal = DIV_ROUND_UP(cal_htotal * mul, div); > hsync_start = DIV_ROUND_UP(adjusted_mode->crtc_hsync_start * mul, div); > hsync_end = DIV_ROUND_UP(adjusted_mode->crtc_hsync_end * mul, div); > hsync_size = hsync_end - hsync_start; > hback_porch = (adjusted_mode->crtc_htotal - > adjusted_mode->crtc_hsync_end); > - vactive = adjusted_mode->crtc_vdisplay; > - vtotal = adjusted_mode->crtc_vtotal; > + > + if (is_vid_mode(intel_dsi)) > + cal_vtotal = adjusted_mode->crtc_vtotal; > + vtotal = cal_vtotal; This would make more sense if the command mode vtotal stuff was done here instead of in the middle of the horizontal timings. > vsync_start = adjusted_mode->crtc_vsync_start; > vsync_end = adjusted_mode->crtc_vsync_end; > vsync_shift = hsync_start - htotal / 2; > @@ -862,7 +877,7 @@ gen11_dsi_set_transcoder_timings(struct intel_encoder *encoder, > } > > /* TRANS_HSYNC register to be programmed only for video mode */ > - if (intel_dsi->operation_mode == INTEL_DSI_VIDEO_MODE) { > + if (is_vid_mode(intel_dsi)) { > if (intel_dsi->video_mode_format == > VIDEO_MODE_NON_BURST_WITH_SYNC_PULSE) { > /* BSPEC: hsync size should be atleast 16 pixels */ > @@ -885,13 +900,12 @@ gen11_dsi_set_transcoder_timings(struct intel_encoder *encoder, > } > } > > - /* program TRANS_VTOTAL register */ > for_each_dsi_port(port, intel_dsi->ports) { > dsi_trans = dsi_port_to_transcoder(port); > /* > - * FIXME: Programing this by assuming progressive mode, since > - * non-interlaced info from VBT is not saved inside > - * struct drm_display_mode. > + * FIXME: Programing this by assuming progressive mode, > + * since non-interlaced info from VBT is not saved > + * inside struct drm_display_mode. > * For interlace mode: program required pixel minus 2 > */ > I915_WRITE(VTOTAL(dsi_trans), > @@ -904,22 +918,26 @@ gen11_dsi_set_transcoder_timings(struct intel_encoder *encoder, > if (vsync_start < vactive) > DRM_ERROR("vsync_start less than vactive\n"); > > - /* program TRANS_VSYNC register */ > - for_each_dsi_port(port, intel_dsi->ports) { > - dsi_trans = dsi_port_to_transcoder(port); > - I915_WRITE(VSYNC(dsi_trans), > - (vsync_start - 1) | ((vsync_end - 1) << 16)); > + /* program TRANS_VSYNC register for video mode only */ > + if (is_vid_mode(intel_dsi)) { > + for_each_dsi_port(port, intel_dsi->ports) { > + dsi_trans = dsi_port_to_transcoder(port); > + I915_WRITE(VSYNC(dsi_trans), > + (vsync_start - 1) | ((vsync_end - 1) << 16)); > + } > } > > /* > - * FIXME: It has to be programmed only for interlaced > + * FIXME: It has to be programmed only for video modes and interlaced > * modes. Put the check condition here once interlaced > * info available as described above. > * program TRANS_VSYNCSHIFT register > */ > - for_each_dsi_port(port, intel_dsi->ports) { > - dsi_trans = dsi_port_to_transcoder(port); > - I915_WRITE(VSYNCSHIFT(dsi_trans), vsync_shift); > + if (is_vid_mode(intel_dsi)) { > + for_each_dsi_port(port, intel_dsi->ports) { > + dsi_trans = dsi_port_to_transcoder(port); > + I915_WRITE(VSYNCSHIFT(dsi_trans), vsync_shift); > + } > } > > /* program TRANS_VBLANK register, should be same as vtotal programmed */
diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c index ca37beca3e41..66dc8be672b8 100644 --- a/drivers/gpu/drm/i915/display/icl_dsi.c +++ b/drivers/gpu/drm/i915/display/icl_dsi.c @@ -808,9 +808,11 @@ gen11_dsi_set_transcoder_timings(struct intel_encoder *encoder, enum transcoder dsi_trans; /* horizontal timings */ u16 htotal, hactive, hsync_start, hsync_end, hsync_size; + u16 cal_htotal, cal_vtotal; u16 hback_porch; /* vertical timings */ u16 vtotal, vactive, vsync_start, vsync_end, vsync_shift; + int bpp, line_time_us, byte_clk_period_ns; int mul = 1, div = 1; /* @@ -827,14 +829,27 @@ gen11_dsi_set_transcoder_timings(struct intel_encoder *encoder, } hactive = adjusted_mode->crtc_hdisplay; - htotal = DIV_ROUND_UP(adjusted_mode->crtc_htotal * mul, div); + vactive = adjusted_mode->crtc_vdisplay; + if (is_cmd_mode(intel_dsi)) { + bpp = mipi_dsi_pixel_format_to_bpp(intel_dsi->pixel_format); + byte_clk_period_ns = 8 * 1000000 / intel_dsi->pclk; + cal_htotal = hactive + 160; + line_time_us = (cal_htotal * (bpp / 8) * byte_clk_period_ns) / (1000 * intel_dsi->lane_count); + cal_vtotal = vactive + DIV_ROUND_UP(460, line_time_us); + } + + if (is_vid_mode(intel_dsi)) + cal_htotal = adjusted_mode->crtc_htotal; + htotal = DIV_ROUND_UP(cal_htotal * mul, div); hsync_start = DIV_ROUND_UP(adjusted_mode->crtc_hsync_start * mul, div); hsync_end = DIV_ROUND_UP(adjusted_mode->crtc_hsync_end * mul, div); hsync_size = hsync_end - hsync_start; hback_porch = (adjusted_mode->crtc_htotal - adjusted_mode->crtc_hsync_end); - vactive = adjusted_mode->crtc_vdisplay; - vtotal = adjusted_mode->crtc_vtotal; + + if (is_vid_mode(intel_dsi)) + cal_vtotal = adjusted_mode->crtc_vtotal; + vtotal = cal_vtotal; vsync_start = adjusted_mode->crtc_vsync_start; vsync_end = adjusted_mode->crtc_vsync_end; vsync_shift = hsync_start - htotal / 2; @@ -862,7 +877,7 @@ gen11_dsi_set_transcoder_timings(struct intel_encoder *encoder, } /* TRANS_HSYNC register to be programmed only for video mode */ - if (intel_dsi->operation_mode == INTEL_DSI_VIDEO_MODE) { + if (is_vid_mode(intel_dsi)) { if (intel_dsi->video_mode_format == VIDEO_MODE_NON_BURST_WITH_SYNC_PULSE) { /* BSPEC: hsync size should be atleast 16 pixels */ @@ -885,13 +900,12 @@ gen11_dsi_set_transcoder_timings(struct intel_encoder *encoder, } } - /* program TRANS_VTOTAL register */ for_each_dsi_port(port, intel_dsi->ports) { dsi_trans = dsi_port_to_transcoder(port); /* - * FIXME: Programing this by assuming progressive mode, since - * non-interlaced info from VBT is not saved inside - * struct drm_display_mode. + * FIXME: Programing this by assuming progressive mode, + * since non-interlaced info from VBT is not saved + * inside struct drm_display_mode. * For interlace mode: program required pixel minus 2 */ I915_WRITE(VTOTAL(dsi_trans), @@ -904,22 +918,26 @@ gen11_dsi_set_transcoder_timings(struct intel_encoder *encoder, if (vsync_start < vactive) DRM_ERROR("vsync_start less than vactive\n"); - /* program TRANS_VSYNC register */ - for_each_dsi_port(port, intel_dsi->ports) { - dsi_trans = dsi_port_to_transcoder(port); - I915_WRITE(VSYNC(dsi_trans), - (vsync_start - 1) | ((vsync_end - 1) << 16)); + /* program TRANS_VSYNC register for video mode only */ + if (is_vid_mode(intel_dsi)) { + for_each_dsi_port(port, intel_dsi->ports) { + dsi_trans = dsi_port_to_transcoder(port); + I915_WRITE(VSYNC(dsi_trans), + (vsync_start - 1) | ((vsync_end - 1) << 16)); + } } /* - * FIXME: It has to be programmed only for interlaced + * FIXME: It has to be programmed only for video modes and interlaced * modes. Put the check condition here once interlaced * info available as described above. * program TRANS_VSYNCSHIFT register */ - for_each_dsi_port(port, intel_dsi->ports) { - dsi_trans = dsi_port_to_transcoder(port); - I915_WRITE(VSYNCSHIFT(dsi_trans), vsync_shift); + if (is_vid_mode(intel_dsi)) { + for_each_dsi_port(port, intel_dsi->ports) { + dsi_trans = dsi_port_to_transcoder(port); + I915_WRITE(VSYNCSHIFT(dsi_trans), vsync_shift); + } } /* program TRANS_VBLANK register, should be same as vtotal programmed */
Transcoder timing calculation differ for command mode. v2: Use is_vid_mode, and use same I915_WRITE (Jani) v3: Adjust the calculations to reflect dsc compression ratio Signed-off-by: Vandita Kulkarni <vandita.kulkarni@intel.com> --- drivers/gpu/drm/i915/display/icl_dsi.c | 52 +++++++++++++++++--------- 1 file changed, 35 insertions(+), 17 deletions(-)