From: Jani Nikula <jani.nikula@linux.intel.com>
To: Daniel Vetter <daniel@ffwll.ch>,
Ander Conselvan de Oliveira <conselvan2@gmail.com>
Cc: Ander Conselvan de Oliveira
<ander.conselvan.de.oliveira@intel.com>,
intel-gfx <intel-gfx@lists.freedesktop.org>
Subject: Re: [PATCH 4/4] drm/i915: Compute clocks and choose DPLLs before disabling crtcs
Date: Thu, 09 Oct 2014 11:52:21 +0300 [thread overview]
Message-ID: <874mvdzku2.fsf@intel.com> (raw)
In-Reply-To: <CAKMK7uE1iEhjZ9B-ARtqn66NEoq6bj=uDWJFfGzTEnt7DQE0ag@mail.gmail.com>
On Thu, 09 Oct 2014, Daniel Vetter <daniel@ffwll.ch> wrote:
> On Wed, Oct 08, 2014 at 06:32:23PM +0300, Ander Conselvan de Oliveira wrote:
>> From: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
>>
>> It is possible for a mode set to fail if there aren't shared DPLLS that
>> match the new configuration requirement or other errors in clock
>> computation. Since that step was executed after disabling crtcs, in the
>> failure case the hardware configuration is changed and needs to be
>> restored. Doing those things early allows the mode set to fail before
>> actually touching the hardware.
>>
>> Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
>
> Looks nifty and gets us to the shiny new world without too much fuzz. I
> think for paranoia it would be good to split this patch here per platform
> (i.e. i9xx, ilk+ and hsw+). And if we make the crtc_mode_set hook optional
> we can also get rid of all the dummy functions here. And remove the caller
> (yay!) at the end of the series.
Should we add WARN_ON(!encoder->new_crtc) all around?
Jani.
>
> Longer-term we might still want to shuffle quite a few of the
> encoder-specific pll computation code into encoder->compute_config. But
> that can be done as leisure if someone gets bored ;-)
>
> Cheers, Daniel
>
>
>> ---
>> drivers/gpu/drm/i915/i915_drv.h | 7 +++
>> drivers/gpu/drm/i915/intel_ddi.c | 2 -
>> drivers/gpu/drm/i915/intel_display.c | 113 ++++++++++++++++++++++++++---------
>> 3 files changed, 92 insertions(+), 30 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
>> index cb6df07..0bb3b54 100644
>> --- a/drivers/gpu/drm/i915/i915_drv.h
>> +++ b/drivers/gpu/drm/i915/i915_drv.h
>> @@ -245,6 +245,12 @@ struct intel_shared_dpll {
>> bool (*get_hw_state)(struct drm_i915_private *dev_priv,
>> struct intel_shared_dpll *pll,
>> struct intel_dpll_hw_state *hw_state);
>> +
>> + /* Holds the new configuration of the shared DPLLS during mode set */
>> + struct {
>> + unsigned crtc_mask;
>> + struct intel_dpll_hw_state hw_state;
>> + } staged_config;
>> };
>>
>> /* Used by dp and fdi links */
>> @@ -476,6 +482,7 @@ struct drm_i915_display_funcs {
>> struct intel_crtc_config *);
>> void (*get_plane_config)(struct intel_crtc *,
>> struct intel_plane_config *);
>> + int (*crtc_compute_clock)(struct drm_crtc *crtc);
>> int (*crtc_mode_set)(struct drm_crtc *crtc,
>> int x, int y,
>> struct drm_framebuffer *old_fb);
>> diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
>> index 619723d..fc6f988 100644
>> --- a/drivers/gpu/drm/i915/intel_ddi.c
>> +++ b/drivers/gpu/drm/i915/intel_ddi.c
>> @@ -821,8 +821,6 @@ bool intel_ddi_pll_select(struct intel_crtc *intel_crtc)
>> struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
>> int clock = intel_crtc->config.port_clock;
>>
>> - intel_put_shared_dpll(intel_crtc);
>> -
>> return hsw_ddi_pll_select(intel_crtc, intel_encoder, clock);
>> }
>>
>> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
>> index 46df2db..4a8aff7 100644
>> --- a/drivers/gpu/drm/i915/intel_display.c
>> +++ b/drivers/gpu/drm/i915/intel_display.c
>> @@ -3852,15 +3852,9 @@ void intel_put_shared_dpll(struct intel_crtc *crtc)
>> struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc)
>> {
>> struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
>> - struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc);
>> + struct intel_shared_dpll *pll;
>> enum intel_dpll_id i;
>>
>> - if (pll) {
>> - DRM_DEBUG_KMS("CRTC:%d dropping existing %s\n",
>> - crtc->base.base.id, pll->name);
>> - intel_put_shared_dpll(crtc);
>> - }
>> -
>> if (HAS_PCH_IBX(dev_priv->dev)) {
>> /* Ironlake PCH has a fixed PLL->PCH pipe mapping. */
>> i = (enum intel_dpll_id) crtc->pipe;
>> @@ -3869,7 +3863,7 @@ struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc)
>> DRM_DEBUG_KMS("CRTC:%d using pre-allocated %s\n",
>> crtc->base.base.id, pll->name);
>>
>> - WARN_ON(pll->crtc_mask);
>> + WARN_ON(pll->staged_config.crtc_mask);
>>
>> goto found;
>> }
>> @@ -3878,16 +3872,16 @@ struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc)
>> pll = &dev_priv->shared_dplls[i];
>>
>> /* Only want to check enabled timings first */
>> - if (pll->crtc_mask == 0)
>> + if (pll->staged_config.crtc_mask == 0)
>> continue;
>>
>> - if (memcmp(&crtc->config.dpll_hw_state, &pll->hw_state,
>> - sizeof(pll->hw_state)) == 0) {
>> - DRM_DEBUG_KMS("CRTC:%d sharing existing %s "
>> - "(crtc_mask 0x%08x, active %d)\n",
>> + if (memcmp(&crtc->new_config->dpll_hw_state,
>> + &pll->staged_config.hw_state,
>> + sizeof(pll->staged_config.hw_state)) == 0) {
>> + DRM_DEBUG_KMS("CRTC:%d sharing existing %s (crtc mask 0x%08x, ative %d)\n",
>> crtc->base.base.id, pll->name,
>> - pll->crtc_mask, pll->active);
>> -
>> + pll->staged_config.crtc_mask,
>> + pll->active);
>> goto found;
>> }
>> }
>> @@ -3895,7 +3889,7 @@ struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc)
>> /* Ok no matching timings, maybe there's a free one? */
>> for (i = 0; i < dev_priv->num_shared_dpll; i++) {
>> pll = &dev_priv->shared_dplls[i];
>> - if (pll->crtc_mask == 0) {
>> + if (pll->staged_config.crtc_mask == 0) {
>> DRM_DEBUG_KMS("CRTC:%d allocated %s\n",
>> crtc->base.base.id, pll->name);
>> goto found;
>> @@ -3905,18 +3899,53 @@ struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc)
>> return NULL;
>>
>> found:
>> - if (pll->crtc_mask == 0)
>> - pll->hw_state = crtc->config.dpll_hw_state;
>> + if (pll->staged_config.crtc_mask == 0)
>> + pll->staged_config.hw_state = crtc->new_config->dpll_hw_state;
>>
>> - crtc->config.shared_dpll = i;
>> + crtc->new_config->shared_dpll = i;
>> DRM_DEBUG_DRIVER("using %s for pipe %c\n", pll->name,
>> pipe_name(crtc->pipe));
>>
>> - pll->crtc_mask |= 1 << crtc->pipe;
>> + pll->staged_config.crtc_mask |= 1 << crtc->pipe;
>>
>> return pll;
>> }
>>
>> +/**
>> + * intel_shared_dpll_start_config - start a new PLL staged config
>> + * @dev_priv: DRM device
>> + * @clear_pipes: mask of pipes that will have their PLLs freed
>> + *
>> + * Starts a new PLL staged config, copying the current config but
>> + * releasing the references of pipes specified in clear_pipes.
>> + */
>> +static void intel_shared_dpll_start_config(struct drm_i915_private *dev_priv,
>> + unsigned clear_pipes)
>> +{
>> + struct intel_shared_dpll *pll;
>> + enum intel_dpll_id i;
>> +
>> + for (i = 0; i < dev_priv->num_shared_dpll; i++) {
>> + pll = &dev_priv->shared_dplls[i];
>> +
>> + pll->staged_config.crtc_mask = pll->crtc_mask & ~clear_pipes;
>> + pll->staged_config.hw_state = pll->hw_state;
>> + }
>> +}
>> +
>> +static void intel_shared_dpll_commit(struct drm_i915_private *dev_priv)
>> +{
>> + struct intel_shared_dpll *pll;
>> + enum intel_dpll_id i;
>> +
>> + for (i = 0; i < dev_priv->num_shared_dpll; i++) {
>> + pll = &dev_priv->shared_dplls[i];
>> +
>> + pll->hw_state = pll->staged_config.hw_state;
>> + pll->crtc_mask = pll->staged_config.crtc_mask;
>> + }
>> +}
>> +
>> static void cpt_verify_modeset(struct drm_device *dev, int pipe)
>> {
>> struct drm_i915_private *dev_priv = dev->dev_private;
>> @@ -6272,6 +6301,11 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc,
>> int x, int y,
>> struct drm_framebuffer *fb)
>> {
>> + return 0;
>> +}
>> +
>> +static int i9xx_crtc_compute_clock(struct drm_crtc *crtc)
>> +{
>> struct drm_device *dev = crtc->dev;
>> struct drm_i915_private *dev_priv = dev->dev_private;
>> struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>> @@ -7281,9 +7315,7 @@ static uint32_t ironlake_compute_dpll(struct intel_crtc *intel_crtc,
>> return dpll | DPLL_VCO_ENABLE;
>> }
>>
>> -static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
>> - int x, int y,
>> - struct drm_framebuffer *fb)
>> +static int ironlake_crtc_compute_clock(struct drm_crtc *crtc)
>> {
>> struct drm_device *dev = crtc->dev;
>> struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>> @@ -7336,8 +7368,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
>> pipe_name(intel_crtc->pipe));
>> return -EINVAL;
>> }
>> - } else
>> - intel_put_shared_dpll(intel_crtc);
>> + }
>>
>> if (is_lvds && has_reduced_clock && i915.powersave)
>> intel_crtc->lowfreq_avail = true;
>> @@ -7347,6 +7378,13 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
>> return 0;
>> }
>>
>> +static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
>> + int x, int y,
>> + struct drm_framebuffer *fb)
>> +{
>> + return 0;
>> +}
>> +
>> static void intel_pch_transcoder_get_m_n(struct intel_crtc *crtc,
>> struct intel_link_m_n *m_n)
>> {
>> @@ -7836,9 +7874,7 @@ static void haswell_modeset_global_resources(struct drm_device *dev)
>> modeset_update_crtc_power_domains(dev);
>> }
>>
>> -static int haswell_crtc_mode_set(struct drm_crtc *crtc,
>> - int x, int y,
>> - struct drm_framebuffer *fb)
>> +static int haswell_crtc_compute_clock(struct drm_crtc *crtc)
>> {
>> struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>>
>> @@ -7850,6 +7886,13 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc,
>> return 0;
>> }
>>
>> +static int haswell_crtc_mode_set(struct drm_crtc *crtc,
>> + int x, int y,
>> + struct drm_framebuffer *fb)
>> +{
>> + return 0;
>> +}
>> +
>> static void haswell_get_ddi_pll(struct drm_i915_private *dev_priv,
>> enum port port,
>> struct intel_crtc_config *pipe_config)
>> @@ -10988,6 +11031,14 @@ static int __intel_set_mode(struct drm_crtc *crtc,
>> prepare_pipes &= ~disable_pipes;
>> }
>>
>> + intel_shared_dpll_start_config(dev_priv, modeset_pipes | disable_pipes);
>> +
>> + for_each_intel_crtc_masked(dev, modeset_pipes, intel_crtc) {
>> + ret = dev_priv->display.crtc_compute_clock(&intel_crtc->base);
>> + if (ret)
>> + goto done;
>> + }
>> +
>> for_each_intel_crtc_masked(dev, disable_pipes, intel_crtc)
>> intel_crtc_disable(&intel_crtc->base);
>>
>> @@ -11015,6 +11066,8 @@ static int __intel_set_mode(struct drm_crtc *crtc,
>> &pipe_config->adjusted_mode);
>> }
>>
>> + intel_shared_dpll_commit(dev_priv);
>> +
>> /* Only after disabling all output pipelines that will be changed can we
>> * update the the output configuration. */
>> intel_modeset_update_state(dev, prepare_pipes);
>> @@ -12580,6 +12633,7 @@ static void intel_init_display(struct drm_device *dev)
>> if (HAS_DDI(dev)) {
>> dev_priv->display.get_pipe_config = haswell_get_pipe_config;
>> dev_priv->display.get_plane_config = ironlake_get_plane_config;
>> + dev_priv->display.crtc_compute_clock = haswell_crtc_compute_clock;
>> dev_priv->display.crtc_mode_set = haswell_crtc_mode_set;
>> dev_priv->display.crtc_enable = haswell_crtc_enable;
>> dev_priv->display.crtc_disable = haswell_crtc_disable;
>> @@ -12593,6 +12647,7 @@ static void intel_init_display(struct drm_device *dev)
>> } else if (HAS_PCH_SPLIT(dev)) {
>> dev_priv->display.get_pipe_config = ironlake_get_pipe_config;
>> dev_priv->display.get_plane_config = ironlake_get_plane_config;
>> + dev_priv->display.crtc_compute_clock = ironlake_crtc_compute_clock;
>> dev_priv->display.crtc_mode_set = ironlake_crtc_mode_set;
>> dev_priv->display.crtc_enable = ironlake_crtc_enable;
>> dev_priv->display.crtc_disable = ironlake_crtc_disable;
>> @@ -12602,6 +12657,7 @@ static void intel_init_display(struct drm_device *dev)
>> } else if (IS_VALLEYVIEW(dev)) {
>> dev_priv->display.get_pipe_config = i9xx_get_pipe_config;
>> dev_priv->display.get_plane_config = i9xx_get_plane_config;
>> + dev_priv->display.crtc_compute_clock = i9xx_crtc_compute_clock;
>> dev_priv->display.crtc_mode_set = i9xx_crtc_mode_set;
>> dev_priv->display.crtc_enable = valleyview_crtc_enable;
>> dev_priv->display.crtc_disable = i9xx_crtc_disable;
>> @@ -12611,6 +12667,7 @@ static void intel_init_display(struct drm_device *dev)
>> } else {
>> dev_priv->display.get_pipe_config = i9xx_get_pipe_config;
>> dev_priv->display.get_plane_config = i9xx_get_plane_config;
>> + dev_priv->display.crtc_compute_clock = i9xx_crtc_compute_clock;
>> dev_priv->display.crtc_mode_set = i9xx_crtc_mode_set;
>> dev_priv->display.crtc_enable = i9xx_crtc_enable;
>> dev_priv->display.crtc_disable = i9xx_crtc_disable;
>> --
>> 1.8.3.2
>>
>> _______________________________________________
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>
> --
> Daniel Vetter
> Software Engineer, Intel Corporation
> +41 (0) 79 365 57 48 - http://blog.ffwll.ch
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
--
Jani Nikula, Intel Open Source Technology Center
prev parent reply other threads:[~2014-10-09 8:56 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-10-08 15:32 [PATCH 0/4] [RFC] Stage shared dpll configs Ander Conselvan de Oliveira
2014-10-08 15:32 ` [PATCH 1/4] drm/i915: Replace some loop through encoders with intel_pipe_has_type() Ander Conselvan de Oliveira
2014-10-08 15:32 ` [PATCH 2/4] drm/i915: Make *_crtc_mode_set work on new_config Ander Conselvan de Oliveira
2014-10-09 8:28 ` Daniel Vetter
2014-10-09 9:11 ` Daniel Vetter
2014-10-09 12:18 ` Ander Conselvan de Oliveira
2014-10-19 14:28 ` Daniel Vetter
2014-10-19 14:30 ` Daniel Vetter
2014-10-20 10:49 ` Ander Conselvan de Oliveira
2014-10-08 15:32 ` [PATCH 3/4] drm/i915: Convert shared dpll reference count to a crtc mask Ander Conselvan de Oliveira
2014-10-08 15:32 ` [PATCH 4/4] drm/i915: Compute clocks and choose DPLLs before disabling crtcs Ander Conselvan de Oliveira
2014-10-09 8:34 ` Daniel Vetter
2014-10-09 8:52 ` Jani Nikula [this message]
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=874mvdzku2.fsf@intel.com \
--to=jani.nikula@linux.intel.com \
--cc=ander.conselvan.de.oliveira@intel.com \
--cc=conselvan2@gmail.com \
--cc=daniel@ffwll.ch \
--cc=intel-gfx@lists.freedesktop.org \
/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.