[Intel-gfx] [PATCH 04/12] drm/i915/bxt: DSI prepare changes for BXT
Jani Nikula
jani.nikula at linux.intel.com
Mon May 25 09:25:52 PDT 2015
On Fri, 22 May 2015, Uma Shankar <uma.shankar at intel.com> wrote:
> From: Shashank Sharma <shashank.sharma at intel.com>
>
> This patch modifies dsi_prepare() function to support the same
> modeset prepare sequence for BXT also. Main changes are:
> 1. BXT port control register is different than VLV.
> 2. BXT modeset sequence needs vdisplay and hdisplay programmed
> for transcoder.
> 3. BXT can select PIPE for MIPI transcoders.
> 4. BXT needs to program register MIPI_INIT_COUNT for both the ports,
> even if only one is being used.
>
> Signed-off-by: Shashank Sharma <shashank.sharma at intel.com>
> Signed-off-by: Uma Shankar <uma.shankar at intel.com>
> ---
> drivers/gpu/drm/i915/i915_reg.h | 22 +++++++++++
> drivers/gpu/drm/i915/intel_dsi.c | 79 +++++++++++++++++++++++++++++++++-----
> 2 files changed, 91 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index b63bdce..57c3a48 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -7387,6 +7387,22 @@ enum skl_disp_power_wells {
> #define GEN9_FUSE_PG1_ENABLED (1 << 26)
> #define GEN9_FUSE_PG0_ENABLED (1 << 27)
>
> +/* BXT MIPI mode configure */
> +#define _BXT_MIPIA_TRANS_HACTIVE 0x6B0F8
> +#define _BXT_MIPIC_TRANS_HACTIVE 0x6B8F8
> +#define BXT_MIPI_TRANS_HACTIVE(tc) _TRANSCODER(tc, \
> + _BXT_MIPIA_TRANS_HACTIVE, _BXT_MIPIC_TRANS_HACTIVE)
> +
> +#define _BXT_MIPIA_TRANS_VACTIVE 0x6B0FC
> +#define _BXT_MIPIC_TRANS_VACTIVE 0x6B8FC
> +#define BXT_MIPI_TRANS_VACTIVE(tc) _TRANSCODER(tc, \
> + _BXT_MIPIA_TRANS_VACTIVE, _BXT_MIPIC_TRANS_VACTIVE)
> +
> +#define _BXT_MIPIA_TRANS_VTOTAL 0x6B100
> +#define _BXT_MIPIC_TRANS_VTOTAL 0x6B900
> +#define BXT_MIPI_TRANS_VTOTAL(tc) _TRANSCODER(tc, \
> + _BXT_MIPIA_TRANS_VTOTAL, _BXT_MIPIC_TRANS_VTOTAL)
Shouldn't these use _MIPI_PORT, not _TRANSCODER?
> +
> #define _MIPI_PORT(port, a, c) _PORT3(port, a, 0, c) /* ports A and C only */
>
> #define _MIPIA_PORT_CTRL (VLV_DISPLAY_BASE + 0x61190)
> @@ -7802,6 +7818,12 @@ enum skl_disp_power_wells {
> #define READ_REQUEST_PRIORITY_HIGH (3 << 3)
> #define RGB_FLIP_TO_BGR (1 << 2)
>
> +/* BXT has a pipe select field */
It's obvious from the defines. Please put the defines in decreasing bit
shift order, i.e. these will be the first ones.
> +#define BXT_PIPE_SELECT_A (0 << 7)
> +#define BXT_PIPE_SELECT_B (1 << 7)
> +#define BXT_PIPE_SELECT_C (2 << 7)
> +#define BXT_PIPE_SELECT_MASK (7 << 7)
Two spaces after "#define". _MASK goes first.
> +
> #define _MIPIA_DATA_ADDRESS (dev_priv->mipi_mmio_base + 0xb108)
> #define _MIPIC_DATA_ADDRESS (dev_priv->mipi_mmio_base + 0xb908)
> #define MIPI_DATA_ADDRESS(port) _MIPI_PORT(port, _MIPIA_DATA_ADDRESS, \
> diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
> index 2c0ea6f..892b518 100644
> --- a/drivers/gpu/drm/i915/intel_dsi.c
> +++ b/drivers/gpu/drm/i915/intel_dsi.c
> @@ -726,6 +726,21 @@ static void set_dsi_timings(struct drm_encoder *encoder,
> hbp = txbyteclkhs(hbp, bpp, lane_count, intel_dsi->burst_mode_ratio);
>
> for_each_dsi_port(port, intel_dsi->ports) {
> + if (IS_BROXTON(dev)) {
> + /*
> + * Program hdisplay and vdisplay on MIPI transcoder.
> + * This is different from calculated hactive and
> + * vactive, as they are calculated per channel basis,
> + * whereas these values should be based on resolution.
> + */
> + I915_WRITE(BXT_MIPI_TRANS_HACTIVE(port),
> + mode->hdisplay);
> + I915_WRITE(BXT_MIPI_TRANS_VACTIVE(port),
> + mode->vdisplay);
> + I915_WRITE(BXT_MIPI_TRANS_VTOTAL(port),
> + mode->vtotal);
With the current definition of BXT_MIPI_TRANS_* these will fail for port
C.
> + }
> +
> I915_WRITE(MIPI_HACTIVE_AREA_COUNT(port), hactive);
> I915_WRITE(MIPI_HFP_COUNT(port), hfp);
>
> @@ -766,16 +781,38 @@ static void intel_dsi_prepare(struct intel_encoder *intel_encoder)
> }
>
> for_each_dsi_port(port, intel_dsi->ports) {
> - /* escape clock divider, 20MHz, shared for A and C.
> - * device ready must be off when doing this! txclkesc? */
> - tmp = I915_READ(MIPI_CTRL(PORT_A));
> - tmp &= ~ESCAPE_CLOCK_DIVIDER_MASK;
> - I915_WRITE(MIPI_CTRL(PORT_A), tmp | ESCAPE_CLOCK_DIVIDER_1);
> -
> - /* read request priority is per pipe */
> - tmp = I915_READ(MIPI_CTRL(port));
> - tmp &= ~READ_REQUEST_PRIORITY_MASK;
> - I915_WRITE(MIPI_CTRL(port), tmp | READ_REQUEST_PRIORITY_HIGH);
> + if (IS_VALLEYVIEW(dev)) {
> + /*
> + * escape clock divider, 20MHz, shared for A and C.
> + * device ready must be off when doing this! txclkesc?
> + */
> + tmp = I915_READ(MIPI_CTRL(0));
> + tmp &= ~ESCAPE_CLOCK_DIVIDER_MASK;
> + I915_WRITE(MIPI_CTRL(0), tmp |
> + ESCAPE_CLOCK_DIVIDER_1);
> +
> + /* read request priority is per pipe */
> + tmp = I915_READ(MIPI_CTRL(port));
> + tmp &= ~READ_REQUEST_PRIORITY_MASK;
> + I915_WRITE(MIPI_CTRL(port), tmp |
> + READ_REQUEST_PRIORITY_HIGH);
> + } else if (IS_BROXTON(dev)) {
> + /*
> + * FIXME:
> + * BXT can connect any PIPE to any MIPI transcoder.
Do you mean, to any DSI port?
> + * Select the pipe based on the MIPI port read from
> + * VBT for now. Pick PIPE A for MIPI port A and C
> + * for port C.
> + */
> + tmp = I915_READ(MIPI_CTRL(port));
> + tmp &= ~BXT_PIPE_SELECT_MASK;
> + port ? (tmp |= BXT_PIPE_SELECT_C) :
> + (tmp |= BXT_PIPE_SELECT_A);
Please compare with PORT_* explicitly instead of port != 0.
> + I915_WRITE(MIPI_CTRL(port), tmp);
> + } else {
> + DRM_ERROR("Invalid DSI device to prepare seq\n");
> + return;
> + }
Please drop all such else branches.
>
> /* XXX: why here, why like this? handling in irq handler?! */
> I915_WRITE(MIPI_INTR_STAT(port), 0xffffffff);
> @@ -852,6 +889,28 @@ static void intel_dsi_prepare(struct intel_encoder *intel_encoder)
> I915_WRITE(MIPI_INIT_COUNT(port),
> txclkesc(intel_dsi->escape_clk_div, 100));
>
> + if (IS_BROXTON(dev)) {
> +
> + /*
> + * XXX:
> + * PIPE2D says LOW_CONTENTION_RECOVERY_DISABLE is
> + * reqd for BXT, but bspec doesn't mention it.
> + * Lets follow PIPE2D for now.
> + */
> + val |= LOW_CONTENTION_RECOVERY_DISABLE;
> +
> + if (!intel_dsi->dual_link) {
> + /*
> + * BXT spec says write MIPI_INIT_COUNT for
> + * both the ports, even if only one is
> + * getting used. So write the other port
> + * if not in dual link mode.
> + */
> + I915_WRITE(MIPI_INIT_COUNT(port ==
> + PORT_A ? PORT_C : PORT_A),
> + intel_dsi->init_count);
Hmm, why do you write different things to the other port? See above what
gets written normally.
BR,
Jani.
> + }
> + }
>
> /* recovery disables */
> I915_WRITE(MIPI_EOT_DISABLE(port), tmp);
> --
> 1.7.9.5
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
--
Jani Nikula, Intel Open Source Technology Center
More information about the Intel-gfx
mailing list