From: "Ville Syrjälä" <ville.syrjala@linux.intel.com>
To: Jani Nikula <jani.nikula@intel.com>
Cc: Deepak M <m.deepak@intel.com>, intel-gfx@lists.freedesktop.org
Subject: Re: [RFC PATCH 08/10] drm/i915/bxt: add dsi transcoders
Date: Wed, 16 Mar 2016 17:24:54 +0200 [thread overview]
Message-ID: <20160316152454.GM4329@intel.com> (raw)
In-Reply-To: <f98b323ed69f16e31d73dcde46c642fa15b8cb8d.1458070700.git.jani.nikula@intel.com>
On Tue, Mar 15, 2016 at 09:51:16PM +0200, Jani Nikula wrote:
> The BXT display connections have DSI transcoders A and C that can be
> muxed to any pipe, not unlike the eDP transcoder. Add the notion of DSI
> transcoders.
>
> The "normal" transcoders A, B and C are not used with BXT DSI, so care
> must be taken to avoid accessing those registers with DSI transcoders in
> the hardware state readout, modeset, and generally everywhere.
>
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
> ---
> drivers/gpu/drm/i915/i915_drv.h | 10 ++++
> drivers/gpu/drm/i915/intel_ddi.c | 6 +++
> drivers/gpu/drm/i915/intel_display.c | 90 +++++++++++++++++++++++++++++----
> drivers/gpu/drm/i915/intel_drv.h | 3 +-
> drivers/gpu/drm/i915/intel_dsi.c | 9 ++++
> drivers/gpu/drm/i915/intel_runtime_pm.c | 6 +++
> 6 files changed, 112 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 5e4a42d996d8..0ddd0f492ca9 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -123,6 +123,8 @@ enum transcoder {
> TRANSCODER_B,
> TRANSCODER_C,
> TRANSCODER_EDP,
> + TRANSCODER_DSI_A,
> + TRANSCODER_DSI_C,
> I915_MAX_TRANSCODERS
> };
>
> @@ -137,11 +139,17 @@ static inline const char *transcoder_name(enum transcoder transcoder)
> return "C";
> case TRANSCODER_EDP:
> return "eDP";
> + case TRANSCODER_DSI_A:
> + return "DSI A";
> + case TRANSCODER_DSI_C:
> + return "DSI C";
> default:
> return "<invalid>";
> }
> }
>
> +#define IS_DSI_TRANSCODER(t) ((t) == TRANSCODER_DSI_A || (t) == TRANSCODER_DSI_C)
> +
> /*
> * I915_MAX_PLANES in the enum below is the maximum (across all platforms)
> * number of planes per CRTC. Not all platforms really have this many planes,
> @@ -192,6 +200,8 @@ enum intel_display_power_domain {
> POWER_DOMAIN_TRANSCODER_B,
> POWER_DOMAIN_TRANSCODER_C,
> POWER_DOMAIN_TRANSCODER_EDP,
> + POWER_DOMAIN_TRANSCODER_DSI_A,
> + POWER_DOMAIN_TRANSCODER_DSI_C,
> POWER_DOMAIN_PORT_DDI_A_LANES,
> POWER_DOMAIN_PORT_DDI_B_LANES,
> POWER_DOMAIN_PORT_DDI_C_LANES,
> diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
> index 91654ffc3a42..8726711864eb 100644
> --- a/drivers/gpu/drm/i915/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/intel_ddi.c
> @@ -1061,6 +1061,8 @@ void intel_ddi_set_pipe_settings(struct drm_crtc *crtc)
> uint32_t temp;
>
> if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP || type == INTEL_OUTPUT_DP_MST) {
> + WARN_ON(IS_DSI_TRANSCODER(cpu_transcoder));
That all caps IS_DSI_TRANSCODER doesn't really agree with me for some
reason. static inline with lower caps name maybe?
> +
> temp = TRANS_MSA_SYNC_CLK;
> switch (intel_crtc->config->pipe_bpp) {
> case 18:
> @@ -1942,6 +1944,10 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
> struct intel_hdmi *intel_hdmi;
> u32 temp, flags = 0;
>
> + /* XXX: DSI transcoder paranoia */
> + if (WARN_ON(IS_DSI_TRANSCODER(cpu_transcoder)))
> + return;
> +
> temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
> if (temp & TRANS_DDI_PHSYNC)
> flags |= DRM_MODE_FLAG_PHSYNC;
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 842467528892..f1d0a868e80c 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -4906,7 +4906,7 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
>
> intel_set_pipe_timings(intel_crtc);
>
> - if (intel_crtc->config->cpu_transcoder != TRANSCODER_EDP) {
> + if (intel_crtc->config->cpu_transcoder < TRANSCODER_EDP) {
> I915_WRITE(PIPE_MULT(intel_crtc->config->cpu_transcoder),
> intel_crtc->config->pixel_multiplier - 1);
> }
> @@ -4957,7 +4957,10 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
> dev_priv->display.initial_watermarks(pipe_config);
> else
> intel_update_watermarks(crtc);
> - intel_enable_pipe(intel_crtc);
> +
> + /* XXX: Do the pipe assertions at the right place for BXT DSI. */
> + if (!intel_crtc->config->has_dsi_encoder)
> + intel_enable_pipe(intel_crtc);
>
> if (intel_crtc->config->has_pch_encoder)
> lpt_pch_enable(crtc);
> @@ -5090,7 +5093,9 @@ static void haswell_crtc_disable(struct drm_crtc *crtc)
> drm_crtc_vblank_off(crtc);
> assert_vblank_disabled(crtc);
>
> - intel_disable_pipe(intel_crtc);
> + /* XXX: Do the pipe assertions at the right place for BXT DSI. */
> + if (!intel_crtc->config->has_dsi_encoder)
> + intel_disable_pipe(intel_crtc);
>
> if (intel_crtc->config->dp_encoder_is_mst)
> intel_ddi_set_vc_payload_alloc(crtc, false);
> @@ -7707,7 +7712,8 @@ static void intel_set_pipe_timings(struct intel_crtc *intel_crtc)
> enum pipe pipe = intel_crtc->pipe;
> enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
>
> - intel_set_trans_timings(intel_crtc);
> + if (!IS_DSI_TRANSCODER(cpu_transcoder))
> + intel_set_trans_timings(intel_crtc);
I think we should put all the DSI checks to the top level
.crtc_enable/disable hooks. Will need to do the function splitting a bit
differently perhaps, but I've already commented on those. The main
benefit would be a more immediate view on the modeset sequence without
having to go through all the functions that get called. Also I would
expect it would then be easier to start shifting stuff into the encoder
hooks if we choose to go that route.
>
> /* Workaround: when the EDP input selection is B, the VTOTAL_B must be
> * programmed with the VTOTAL_EDP value. Same for VTOTAL_C. This is
> @@ -7765,9 +7771,11 @@ static void intel_get_pipe_timings(struct intel_crtc *crtc,
> {
> struct drm_device *dev = crtc->base.dev;
> struct drm_i915_private *dev_priv = dev->dev_private;
> + enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
> uint32_t tmp;
>
> - intel_get_trans_timings(crtc, pipe_config);
> + if (!IS_DSI_TRANSCODER(cpu_transcoder))
> + intel_get_trans_timings(crtc, pipe_config);
>
> tmp = I915_READ(PIPESRC(crtc->pipe));
> pipe_config->pipe_src_h = (tmp & 0xffff) + 1;
> @@ -8776,9 +8784,11 @@ static void haswell_set_pipeconf(struct drm_crtc *crtc)
> struct drm_i915_private *dev_priv = dev->dev_private;
> struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> enum pipe pipe = intel_crtc->pipe;
> + enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
> u32 val;
>
> - haswell_set_transconf(crtc);
> + if (!IS_DSI_TRANSCODER(cpu_transcoder))
> + haswell_set_transconf(crtc);
>
> I915_WRITE(GAMMA_MODE(intel_crtc->pipe), GAMMA_MODE_MODE_8BIT);
> POSTING_READ(GAMMA_MODE(intel_crtc->pipe));
> @@ -9936,6 +9946,47 @@ static bool hsw_get_trans_config(struct intel_crtc *crtc,
> return tmp & PIPECONF_ENABLE;
> }
>
> +static bool bxt_get_dsi_trans_config(struct intel_crtc *crtc,
> + struct intel_crtc_state *pipe_config,
> + unsigned long *power_domain_mask)
> +{
> + struct drm_device *dev = crtc->base.dev;
> + struct drm_i915_private *dev_priv = dev->dev_private;
> + enum intel_display_power_domain power_domain;
> + enum port port;
> + enum transcoder cpu_transcoder;
> + u32 tmp;
> +
> + pipe_config->has_dsi_encoder = false;
> +
> + for_each_port_masked(port, BIT(PORT_A) | BIT(PORT_C)) {
> + if (port == PORT_A)
> + cpu_transcoder = TRANSCODER_DSI_A;
> + else
> + cpu_transcoder = TRANSCODER_DSI_C;
> +
> + power_domain = POWER_DOMAIN_TRANSCODER(cpu_transcoder);
> + if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
> + continue;
> + *power_domain_mask |= BIT(power_domain);
> +
> + /* XXX: this works for video mode only */
> + tmp = I915_READ(BXT_MIPI_PORT_CTRL(port));
> + if (!(tmp & DPI_ENABLE))
> + continue;
> +
> + tmp = I915_READ(MIPI_CTRL(port));
> + if ((tmp & BXT_PIPE_SELECT_MASK) != BXT_PIPE_SELECT(crtc->pipe))
> + continue;
> +
> + pipe_config->cpu_transcoder = cpu_transcoder;
> + pipe_config->has_dsi_encoder = true;
> + break;
> + }
> +
> + return pipe_config->has_dsi_encoder;
> +}
> +
> static void haswell_get_ddi_port_state(struct intel_crtc *crtc,
> struct intel_crtc_state *pipe_config)
> {
> @@ -9997,10 +10048,18 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc,
>
> active = hsw_get_trans_config(crtc, pipe_config, &power_domain_mask);
>
> + if (IS_BROXTON(dev_priv)) {
> + bxt_get_dsi_trans_config(crtc, pipe_config, &power_domain_mask);
> + WARN_ON(active && pipe_config->has_dsi_encoder);
> + if (pipe_config->has_dsi_encoder)
> + active = true;
> + }
> +
> if (!active)
> goto out;
>
> - haswell_get_ddi_port_state(crtc, pipe_config);
> + if (!pipe_config->has_dsi_encoder)
> + haswell_get_ddi_port_state(crtc, pipe_config);
>
> intel_get_pipe_timings(crtc, pipe_config);
>
> @@ -10026,7 +10085,7 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc,
> pipe_config->ips_enabled = hsw_crtc_supports_ips(crtc) &&
> (I915_READ(IPS_CTL) & IPS_ENABLE);
>
> - if (pipe_config->cpu_transcoder != TRANSCODER_EDP) {
> + if (pipe_config->cpu_transcoder < TRANSCODER_EDP) {
> pipe_config->pixel_multiplier =
> I915_READ(PIPE_MULT(pipe_config->cpu_transcoder)) + 1;
> } else {
> @@ -15516,10 +15575,18 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc)
> {
> struct drm_device *dev = crtc->base.dev;
> struct drm_i915_private *dev_priv = dev->dev_private;
> - i915_reg_t reg = PIPECONF(crtc->config->cpu_transcoder);
> + enum transcoder cpu_transcoder = crtc->config->cpu_transcoder;
>
> - /* Clear any frame start delays used for debugging left by the BIOS */
> - I915_WRITE(reg, I915_READ(reg) & ~PIPECONF_FRAME_START_DELAY_MASK);
> + if (!IS_DSI_TRANSCODER(cpu_transcoder)) {
> + i915_reg_t reg = PIPECONF(cpu_transcoder);
> +
> + /*
> + * Clear any frame start delays used for debugging left by the
> + * BIOS.
> + */
> + I915_WRITE(reg,
> + I915_READ(reg) & ~PIPECONF_FRAME_START_DELAY_MASK);
> + }
>
> /* restore vblank interrupts to correct state */
> drm_crtc_vblank_reset(&crtc->base);
> @@ -16195,6 +16262,7 @@ intel_display_capture_error_state(struct drm_device *dev)
> error->pipe[i].stat = I915_READ(PIPESTAT(i));
> }
>
> + /* Note: this does not include DSI transcoders. */
> error->num_transcoders = INTEL_INFO(dev)->num_pipes;
> if (HAS_DDI(dev_priv->dev))
> error->num_transcoders++; /* Account for eDP. */
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 02b3d22862a1..6e8c1386129e 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -436,7 +436,8 @@ struct intel_crtc_state {
> bool has_infoframe;
>
> /* CPU Transcoder for the pipe. Currently this can only differ from the
> - * pipe on Haswell (where we have a special eDP transcoder). */
> + * pipe on Haswell and later (where we have a special eDP transcoder)
> + * and Broxton (where we have special DSI transcoders). */
> enum transcoder cpu_transcoder;
>
> /*
> diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
> index 73c15210fdb1..47fd0296a05a 100644
> --- a/drivers/gpu/drm/i915/intel_dsi.c
> +++ b/drivers/gpu/drm/i915/intel_dsi.c
> @@ -268,6 +268,7 @@ static inline bool is_cmd_mode(struct intel_dsi *intel_dsi)
> static bool intel_dsi_compute_config(struct intel_encoder *encoder,
> struct intel_crtc_state *pipe_config)
> {
> + struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
> struct intel_dsi *intel_dsi = container_of(encoder, struct intel_dsi,
> base);
> struct intel_connector *intel_connector = intel_dsi->attached_connector;
> @@ -284,6 +285,14 @@ static bool intel_dsi_compute_config(struct intel_encoder *encoder,
> /* DSI uses short packets for sync events, so clear mode flags for DSI */
> adjusted_mode->flags = 0;
>
> + if (IS_BROXTON(dev_priv)) {
> + /* Dual link goes to DSI transcoder A. */
> + if (intel_dsi->ports == BIT(PORT_C))
> + pipe_config->cpu_transcoder = TRANSCODER_DSI_C;
> + else
> + pipe_config->cpu_transcoder = TRANSCODER_DSI_A;
> + }
> +
> return true;
> }
>
> diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c
> index 2e88a5e06884..d189a0012277 100644
> --- a/drivers/gpu/drm/i915/intel_runtime_pm.c
> +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c
> @@ -89,6 +89,10 @@ intel_display_power_domain_str(enum intel_display_power_domain domain)
> return "TRANSCODER_C";
> case POWER_DOMAIN_TRANSCODER_EDP:
> return "TRANSCODER_EDP";
> + case POWER_DOMAIN_TRANSCODER_DSI_A:
> + return "TRANSCODER_DSI_A";
> + case POWER_DOMAIN_TRANSCODER_DSI_C:
> + return "TRANSCODER_DSI_C";
> case POWER_DOMAIN_PORT_DDI_A_LANES:
> return "PORT_DDI_A_LANES";
> case POWER_DOMAIN_PORT_DDI_B_LANES:
> @@ -419,6 +423,8 @@ static void hsw_set_power_well(struct drm_i915_private *dev_priv,
> BXT_DISPLAY_POWERWELL_2_POWER_DOMAINS | \
> BIT(POWER_DOMAIN_PIPE_A) | \
> BIT(POWER_DOMAIN_TRANSCODER_EDP) | \
> + BIT(POWER_DOMAIN_TRANSCODER_DSI_A) | \
> + BIT(POWER_DOMAIN_TRANSCODER_DSI_C) | \
> BIT(POWER_DOMAIN_PIPE_A_PANEL_FITTER) | \
> BIT(POWER_DOMAIN_PORT_DDI_A_LANES) | \
> BIT(POWER_DOMAIN_PORT_DSI) | \
> --
> 2.1.4
--
Ville Syrjälä
Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
next prev parent reply other threads:[~2016-03-16 15:25 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-03-15 19:51 [RFC PATCH 00/10] drm/i915/bxt: add dsi transcoders Jani Nikula
2016-03-15 19:51 ` [RFC PATCH 01/10] drm/i915: add for_each_port_masked macro Jani Nikula
2016-03-16 15:07 ` Ville Syrjälä
2016-03-15 19:51 ` [RFC PATCH 02/10] drm/i915: make transcoder_name return a string Jani Nikula
2016-03-16 14:46 ` Ville Syrjälä
2016-03-15 19:51 ` [RFC PATCH 03/10] drm/i915/dsi: refactor dsi get hw state readout Jani Nikula
2016-03-16 15:09 ` Ville Syrjälä
2016-03-15 19:51 ` [RFC PATCH 04/10] drm/i915/bxt: fix dsi hw state pipe readout Jani Nikula
2016-03-16 15:11 ` Ville Syrjälä
2016-03-16 16:19 ` Jani Nikula
2016-03-15 19:51 ` [RFC PATCH 05/10] drm/i915: split get/set pipe timings to pipe and transcoder parts Jani Nikula
2016-03-16 15:02 ` Ville Syrjälä
2016-03-15 19:51 ` [RFC PATCH 06/10] drm/i915: split set pipeconf " Jani Nikula
2016-03-16 15:15 ` Ville Syrjälä
2016-03-15 19:51 ` [RFC PATCH 07/10] drm/i915: abstract get config for cpu transcoder Jani Nikula
2016-03-16 15:20 ` Ville Syrjälä
2016-03-16 15:26 ` Jani Nikula
2016-03-16 15:32 ` Ville Syrjälä
2016-03-15 19:51 ` [RFC PATCH 08/10] drm/i915/bxt: add dsi transcoders Jani Nikula
2016-03-16 15:24 ` Ville Syrjälä [this message]
2016-03-15 19:51 ` [RFC PATCH 09/10] drm/i915/dsi: use the BIT macro for clarity Jani Nikula
2016-03-15 19:51 ` [RFC PATCH 10/10] drm/i915/bxt: allow dsi on any pipe Jani Nikula
2016-03-16 7:59 ` ✗ Fi.CI.BAT: failure for drm/i915/bxt: add dsi transcoders Patchwork
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20160316152454.GM4329@intel.com \
--to=ville.syrjala@linux.intel.com \
--cc=intel-gfx@lists.freedesktop.org \
--cc=jani.nikula@intel.com \
--cc=m.deepak@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.