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: [PATCH v2 4/6] drm/i915/bxt: add dsi transcoders
Date: Fri, 18 Mar 2016 17:38:27 +0200 [thread overview]
Message-ID: <20160318153827.GK4329@intel.com> (raw)
In-Reply-To: <299740536b7941e31b2744f3ce34f7afe936a771.1458313400.git.jani.nikula@intel.com>
On Fri, Mar 18, 2016 at 05:05:42PM +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.
>
> v2: addressing comments by Ville:
> - rename the dsi get config function to hsw_get_dsi_transcoder_state
> - rebase onto the higher level split of pipe/transcoder functions
> - use more has_dsi_encoder as we can now because of the above,
> with no need to look at the transcoder so much
> - rename IS_DSI_TRANSCODER to transcoder_is_dsi
> - use the above a bit more instead of comparing to < TRANSCODER_EDP
>
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
> ---
> drivers/gpu/drm/i915/i915_drv.h | 13 +++++
> drivers/gpu/drm/i915/intel_ddi.c | 6 +++
> drivers/gpu/drm/i915/intel_display.c | 91 +++++++++++++++++++++++++++++----
> 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, 116 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index f330a53c19b9..5e700770c403 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -127,6 +127,8 @@ enum transcoder {
> TRANSCODER_B,
> TRANSCODER_C,
> TRANSCODER_EDP,
> + TRANSCODER_DSI_A,
> + TRANSCODER_DSI_C,
> I915_MAX_TRANSCODERS
> };
>
> @@ -141,11 +143,20 @@ 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>";
> }
> }
>
> +static inline bool transcoder_is_dsi(enum transcoder transcoder)
> +{
> + return transcoder == TRANSCODER_DSI_A || transcoder == 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,
> @@ -196,6 +207,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..e6c3a80e1360 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(transcoder_is_dsi(cpu_transcoder));
> +
> 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(transcoder_is_dsi(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 98d8b563b9a1..28ead66ed987 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -4900,6 +4900,7 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
> struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> struct intel_encoder *encoder;
> int pipe = intel_crtc->pipe, hsw_workaround_pipe;
> + enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
> struct intel_crtc_state *pipe_config =
> to_intel_crtc_state(crtc->state);
>
> @@ -4916,11 +4917,14 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
> if (intel_crtc->config->has_dp_encoder)
> intel_dp_set_m_n(intel_crtc, M1_N1);
>
> - intel_set_pipe_timings(intel_crtc);
> + if (!intel_crtc->config->has_dsi_encoder)
> + intel_set_pipe_timings(intel_crtc);
> +
> intel_set_pipe_src_size(intel_crtc);
>
> - if (intel_crtc->config->cpu_transcoder != TRANSCODER_EDP) {
> - I915_WRITE(PIPE_MULT(intel_crtc->config->cpu_transcoder),
> + if (cpu_transcoder != TRANSCODER_EDP &&
> + !transcoder_is_dsi(cpu_transcoder)) {
> + I915_WRITE(PIPE_MULT(cpu_transcoder),
> intel_crtc->config->pixel_multiplier - 1);
> }
>
> @@ -4929,7 +4933,9 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
> &intel_crtc->config->fdi_m_n, NULL);
> }
>
> - haswell_set_pipeconf(crtc);
> + if (!intel_crtc->config->has_dsi_encoder)
> + haswell_set_pipeconf(crtc);
> +
> haswell_set_pipe_gamma(crtc);
> haswell_set_pipemisc(crtc);
>
> @@ -4972,7 +4978,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);
> @@ -5105,7 +5114,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);
> @@ -9957,6 +9968,47 @@ static bool hsw_get_transcoder_state(struct intel_crtc *crtc,
> return tmp & PIPECONF_ENABLE;
> }
>
> +static bool bxt_get_dsi_transcoder_state(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)
> {
> @@ -10018,12 +10070,22 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc,
>
> active = hsw_get_transcoder_state(crtc, pipe_config, &power_domain_mask);
>
> + if (IS_BROXTON(dev_priv)) {
> + bxt_get_dsi_transcoder_state(crtc, pipe_config,
> + &power_domain_mask);
> + WARN_ON(active && pipe_config->has_dsi_encoder);
The warn could use a small comment perhaps, explaining that DSI and DDI
transcoders shouldn't be enabled at the same time.
Anyway, patch looks good to me
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> + 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);
> + }
>
> - intel_get_pipe_timings(crtc, pipe_config);
> intel_get_pipe_src_size(crtc, pipe_config);
>
> if (INTEL_INFO(dev)->gen >= 9) {
> @@ -10048,7 +10110,8 @@ 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 &&
> + !transcoder_is_dsi(pipe_config->cpu_transcoder)) {
> pipe_config->pixel_multiplier =
> I915_READ(PIPE_MULT(pipe_config->cpu_transcoder)) + 1;
> } else {
> @@ -15520,10 +15583,15 @@ 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 (!transcoder_is_dsi(cpu_transcoder)) {
> + i915_reg_t reg = PIPECONF(cpu_transcoder);
> +
> + I915_WRITE(reg,
> + I915_READ(reg) & ~PIPECONF_FRAME_START_DELAY_MASK);
> + }
>
> /* restore vblank interrupts to correct state */
> drm_crtc_vblank_reset(&crtc->base);
> @@ -16194,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 5136eeffc24e..ba45245ad6c8 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -437,7 +437,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 3562bf337e62..1981212ffc8d 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-18 15:38 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-03-18 15:05 [PATCH v2 0/6] drm/i915/bxt: add dsi transcoders Jani Nikula
2016-03-18 15:05 ` [PATCH v2 1/6] drm/i915: split get/set pipe timings to timings and src size Jani Nikula
2016-03-18 15:25 ` Ville Syrjälä
2016-03-18 15:05 ` [PATCH v2 2/6] drm/i915: split set pipeconf to pipeconf, pipemisc, pipe_gamma Jani Nikula
2016-03-18 15:29 ` Ville Syrjälä
2016-03-18 15:05 ` [PATCH v2 3/6] drm/i915: abstract get config for cpu transcoder Jani Nikula
2016-03-18 15:31 ` Ville Syrjälä
2016-03-18 15:05 ` [PATCH v2 4/6] drm/i915/bxt: add dsi transcoders Jani Nikula
2016-03-18 15:38 ` Ville Syrjälä [this message]
2016-03-18 15:05 ` [PATCH v2 5/6] drm/i915/dsi: use the BIT macro for clarity Jani Nikula
2016-03-18 15:38 ` Ville Syrjälä
2016-03-18 15:05 ` [PATCH v2 6/6] drm/i915/bxt: allow dsi on any pipe Jani Nikula
2016-03-18 15:39 ` Ville Syrjälä
2016-03-21 9:59 ` ✗ Fi.CI.BAT: failure for drm/i915/bxt: add dsi transcoders (rev2) Patchwork
2016-03-21 13:04 ` Jani Nikula
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=20160318153827.GK4329@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.