[Intel-gfx] [V6 2/9] drm/i915/dsi: Add vblank calculation for command mode
Jani Nikula
jani.nikula at intel.com
Fri Jan 17 10:49:55 UTC 2020
On Thu, 09 Jan 2020, Vandita Kulkarni <vandita.kulkarni at 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 at 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 */
--
Jani Nikula, Intel Open Source Graphics Center
More information about the Intel-gfx
mailing list