Message ID | 20191014110122.31923-4-vandita.kulkarni@intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Add mipi dsi command mode support. | expand |
On Mon, 14 Oct 2019, Vandita Kulkarni <vandita.kulkarni@intel.com> wrote: > Transcoder timing calculation differ for command mode. > > Signed-off-by: Vandita Kulkarni <vandita.kulkarni@intel.com> > --- > drivers/gpu/drm/i915/display/icl_dsi.c | 56 +++++++++++++++++--------- > 1 file changed, 37 insertions(+), 19 deletions(-) > > diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c > index 8e6c09a1db78..5dd9eebab6b1 100644 > --- a/drivers/gpu/drm/i915/display/icl_dsi.c > +++ b/drivers/gpu/drm/i915/display/icl_dsi.c > @@ -780,6 +780,7 @@ gen11_dsi_set_transcoder_timings(struct intel_encoder *encoder, > u16 hback_porch; > /* vertical timings */ > u16 vtotal, vactive, vsync_start, vsync_end, vsync_shift; > + int bpp, line_time_us, byte_clk_period_ns; > > hactive = adjusted_mode->crtc_hdisplay; > htotal = adjusted_mode->crtc_htotal; > @@ -841,40 +842,57 @@ 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. > - * For interlace mode: program required pixel minus 2 > - */ > - I915_WRITE(VTOTAL(dsi_trans), > - (vactive - 1) | ((vtotal - 1) << 16)); > + if (intel_dsi->operation_mode == INTEL_DSI_VIDEO_MODE) { There's is_vid_mode() and is_cmd_mode(). Use them throughout the series instead of the above. > + 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. > + * For interlace mode: program required pixel minus 2 > + */ > + I915_WRITE(VTOTAL(dsi_trans), > + (vactive - 1) | ((vtotal - 1) << 16)); > + } > + } else { > + for_each_dsi_port(port, intel_dsi->ports) { > + bpp = mipi_dsi_pixel_format_to_bpp(intel_dsi->pixel_format); > + byte_clk_period_ns = 8 * 1000000 / intel_dsi->pclk; > + htotal = hactive + 160; > + line_time_us = (htotal * (bpp / 8) * byte_clk_period_ns) / (1000 * intel_dsi->lane_count); > + vtotal = vactive + DIV_ROUND_UP(460, line_time_us); This is a bit hand-wavy, but some of these seem suspicious. Someone(tm) needs to go through these in detail. > + I915_WRITE(VTOTAL(dsi_trans), > + (vactive - 1) | ((vtotal - 1) << 16)); > + } > } As the I915_WRITE() is the same for both, albeit with changed values for cmd mode, I think it would be better to have the mode check within the for_each_dsi_port() block. > > + > if (vsync_end < vsync_start || vsync_end > vtotal) > DRM_ERROR("Invalid vsync_end value\n"); > > 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 (intel_dsi->operation_mode == INTEL_DSI_VIDEO_MODE) { > + 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 (intel_dsi->operation_mode == INTEL_DSI_VIDEO_MODE) { > + 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 8e6c09a1db78..5dd9eebab6b1 100644 --- a/drivers/gpu/drm/i915/display/icl_dsi.c +++ b/drivers/gpu/drm/i915/display/icl_dsi.c @@ -780,6 +780,7 @@ gen11_dsi_set_transcoder_timings(struct intel_encoder *encoder, u16 hback_porch; /* vertical timings */ u16 vtotal, vactive, vsync_start, vsync_end, vsync_shift; + int bpp, line_time_us, byte_clk_period_ns; hactive = adjusted_mode->crtc_hdisplay; htotal = adjusted_mode->crtc_htotal; @@ -841,40 +842,57 @@ 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. - * For interlace mode: program required pixel minus 2 - */ - I915_WRITE(VTOTAL(dsi_trans), - (vactive - 1) | ((vtotal - 1) << 16)); + if (intel_dsi->operation_mode == INTEL_DSI_VIDEO_MODE) { + 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. + * For interlace mode: program required pixel minus 2 + */ + I915_WRITE(VTOTAL(dsi_trans), + (vactive - 1) | ((vtotal - 1) << 16)); + } + } else { + for_each_dsi_port(port, intel_dsi->ports) { + bpp = mipi_dsi_pixel_format_to_bpp(intel_dsi->pixel_format); + byte_clk_period_ns = 8 * 1000000 / intel_dsi->pclk; + htotal = hactive + 160; + line_time_us = (htotal * (bpp / 8) * byte_clk_period_ns) / (1000 * intel_dsi->lane_count); + vtotal = vactive + DIV_ROUND_UP(460, line_time_us); + I915_WRITE(VTOTAL(dsi_trans), + (vactive - 1) | ((vtotal - 1) << 16)); + } } + if (vsync_end < vsync_start || vsync_end > vtotal) DRM_ERROR("Invalid vsync_end value\n"); 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 (intel_dsi->operation_mode == INTEL_DSI_VIDEO_MODE) { + 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 (intel_dsi->operation_mode == INTEL_DSI_VIDEO_MODE) { + 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. Signed-off-by: Vandita Kulkarni <vandita.kulkarni@intel.com> --- drivers/gpu/drm/i915/display/icl_dsi.c | 56 +++++++++++++++++--------- 1 file changed, 37 insertions(+), 19 deletions(-)