From: Vandana Kannan <vandana.kannan@intel.com>
To: Jani Nikula <jani.nikula@linux.intel.com>
Cc: "intel-gfx@lists.freedesktop.org" <intel-gfx@lists.freedesktop.org>
Subject: Re: [PATCH 3/6] drm/i915: Add support for DRRS to switch RR
Date: Thu, 27 Mar 2014 14:29:46 +0530 [thread overview]
Message-ID: <5333E882.2010906@intel.com> (raw)
In-Reply-To: <87eh1pglvv.fsf@intel.com>
On Mar-26-2014 6:25 PM, Jani Nikula wrote:
> On Fri, 07 Mar 2014, Vandana Kannan <vandana.kannan@intel.com> wrote:
>> From: Pradeep Bhat <pradeep.bhat@intel.com>
>>
>> This patch computes and stored 2nd M/N/TU for switching to different
>> refresh rate dynamically. PIPECONF_EDP_RR_MODE_SWITCH bit helps toggle
>> between alternate refresh rates programmed in 2nd M/N/TU registers.
>>
>> v2: Daniel's review comments
>> Computing M2/N2 in compute_config and storing it in crtc_config
>>
>> v3: Modified reference to edp_downclock and edp_downclock_avail based on the
>> changes made to move them from dev_private to intel_panel.
>>
>> v4: Modified references to is_drrs_supported based on the changes made to
>> rename it to drrs_support.
>>
>> v5: Jani's review comments
>> Removed superfluous return statements. Changed support for Gen 7 and above.
>> Corrected indentation. Re-structured the code which finds crtc and connector
>> from encoder. Changed some logs to be less verbose.
>>
>> v6: Modifying i915_drrs to include only intel connector as intel_dp can be
>> derived from intel connector when required.
>>
>> v7: As per internal review comments, acquiring mutex just before accessing
>> drrs RR. As per Chris's review comments, added documentation about the use
>> of locking in the function.
>>
>> Signed-off-by: Pradeep Bhat <pradeep.bhat@intel.com>
>> Signed-off-by: Vandana Kannan <vandana.kannan@intel.com>
>> ---
>> drivers/gpu/drm/i915/i915_drv.h | 5 ++
>> drivers/gpu/drm/i915/i915_reg.h | 1 +
>> drivers/gpu/drm/i915/intel_dp.c | 108 ++++++++++++++++++++++++++++++++++++++
>> drivers/gpu/drm/i915/intel_drv.h | 6 ++-
>> 4 files changed, 119 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
>> index 6b4d0b20..43d3dfe 100644
>> --- a/drivers/gpu/drm/i915/i915_drv.h
>> +++ b/drivers/gpu/drm/i915/i915_drv.h
>> @@ -774,6 +774,10 @@ struct i915_fbc {
>> } no_fbc_reason;
>> };
>>
>> +struct i915_drrs {
>> + struct intel_connector *connector;
>> +};
>> +
>> struct i915_psr {
>> bool sink_support;
>> bool source_ok;
>> @@ -1466,6 +1470,7 @@ typedef struct drm_i915_private {
>> int num_plane;
>>
>> struct i915_fbc fbc;
>> + struct i915_drrs drrs;
>> struct intel_opregion opregion;
>> struct intel_vbt_data vbt;
>>
>> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
>> index f73a49d..bfd7703 100644
>> --- a/drivers/gpu/drm/i915/i915_reg.h
>> +++ b/drivers/gpu/drm/i915/i915_reg.h
>> @@ -3225,6 +3225,7 @@
>> #define PIPECONF_INTERLACED_DBL_ILK (4 << 21) /* ilk/snb only */
>> #define PIPECONF_PFIT_PF_INTERLACED_DBL_ILK (5 << 21) /* ilk/snb only */
>> #define PIPECONF_INTERLACE_MODE_MASK (7 << 21)
>> +#define PIPECONF_EDP_RR_MODE_SWITCH (1 << 20)
>> #define PIPECONF_CXSR_DOWNCLOCK (1<<16)
>> #define PIPECONF_COLOR_RANGE_SELECT (1 << 13)
>> #define PIPECONF_BPC_MASK (0x7 << 5)
>> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
>> index 39365bf..54cde57 100644
>> --- a/drivers/gpu/drm/i915/intel_dp.c
>> +++ b/drivers/gpu/drm/i915/intel_dp.c
>> @@ -832,6 +832,20 @@ intel_dp_set_clock(struct intel_encoder *encoder,
>> }
>> }
>>
>> +static void
>> +intel_dp_set_m2_n2(struct intel_crtc *crtc, struct intel_link_m_n *m_n)
>> +{
>> + struct drm_device *dev = crtc->base.dev;
>> + struct drm_i915_private *dev_priv = dev->dev_private;
>> + enum transcoder transcoder = crtc->config.cpu_transcoder;
>> +
>> + I915_WRITE(PIPE_DATA_M2(transcoder),
>> + TU_SIZE(m_n->tu) | m_n->gmch_m);
>> + I915_WRITE(PIPE_DATA_N2(transcoder), m_n->gmch_n);
>> + I915_WRITE(PIPE_LINK_M2(transcoder), m_n->link_m);
>> + I915_WRITE(PIPE_LINK_N2(transcoder), m_n->link_n);
>> +}
>> +
>> bool
>> intel_dp_compute_config(struct intel_encoder *encoder,
>> struct intel_crtc_config *pipe_config)
>> @@ -936,6 +950,15 @@ found:
>> pipe_config->port_clock,
>> &pipe_config->dp_m_n);
>>
>> + if (intel_connector->panel.edp_downclock_avail &&
>> + intel_dp->drrs_state.type == SEAMLESS_DRRS_SUPPORT) {
>
> Again, seems like intel_connector->panel.edp_downclock_avail is useless
> state. Why not just look at intel_connector->panel.downclock_mode !=
> NULL?
>
I will make this change..
>> + intel_link_compute_m_n(bpp, lane_count,
>> + intel_connector->panel.edp_downclock,
>> + pipe_config->port_clock,
>> + &pipe_config->dp_m2_n2);
>> + }
>> +
>> +
>> intel_dp_set_clock(encoder, pipe_config, intel_dp->link_bw);
>>
>> return true;
>> @@ -3666,6 +3689,87 @@ intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev,
>> I915_READ(pp_div_reg));
>> }
>>
>> +void intel_dp_set_drrs_state(struct drm_device *dev, int refresh_rate)
>> +{
>> + struct drm_i915_private *dev_priv = dev->dev_private;
>> + struct intel_encoder *encoder;
>> + struct intel_dp *intel_dp = NULL;
>> + struct intel_crtc_config *config = NULL;
>> + struct intel_crtc *intel_crtc = NULL;
>> + struct intel_connector *intel_connector = dev_priv->drrs.connector;
>
> This drrs.connector is also starting to look like extra state that could
> be derived from somewhere else.
>
Yes, it can be derived from dev. To avoid iterating through the
connector list each time, I have saved the state here..
>> + u32 reg, val;
>> + int index = 0;
>> +
>> + if (refresh_rate <= 0) {
>> + DRM_DEBUG_KMS("Refresh rate should be positive non-zero.\n");
>> + return;
>> + }
>> +
>> + if (intel_connector == NULL) {
>> + DRM_DEBUG_KMS("DRRS supported for eDP only.\n");
>> + return;
>> + }
>> +
>> + encoder = intel_attached_encoder(&intel_connector->base);
>> + intel_dp = enc_to_intel_dp(&encoder->base);
>> + intel_crtc = encoder->new_crtc;
>> +
>> + if (!intel_crtc) {
>> + DRM_DEBUG_KMS("DRRS: intel_crtc not initialized\n");
>> + return;
>> + }
>> +
>> + config = &intel_crtc->config;
>> +
>> + if (intel_dp->drrs_state.type < SEAMLESS_DRRS_SUPPORT) {
>> + DRM_DEBUG_KMS("Seamless DRRS not supported.\n");
>> + return;
>> + }
>> +
>> + if (intel_connector->panel.fixed_mode->vrefresh == refresh_rate)
>> + index = DRRS_HIGH_RR;
>> + else
>> + index = DRRS_LOW_RR;
>> +
>> + if (index == intel_dp->drrs_state.refresh_rate_type) {
>> + DRM_DEBUG_KMS(
>> + "DRRS requested for previously set RR...ignoring\n");
>> + return;
>> + }
>> +
>> + if (!intel_crtc->active) {
>> + DRM_DEBUG_KMS("eDP encoder disabled. CRTC not Active\n");
>> + return;
>> + }
>> +
>> + if (INTEL_INFO(dev)->gen > 6 && INTEL_INFO(dev)->gen < 8) {
>> + reg = PIPECONF(intel_crtc->config.cpu_transcoder);
>> + val = I915_READ(reg);
>> + if (index > DRRS_HIGH_RR) {
>> + val |= PIPECONF_EDP_RR_MODE_SWITCH;
>> + intel_dp_set_m2_n2(intel_crtc, &config->dp_m2_n2);
>> + } else {
>> + val &= ~PIPECONF_EDP_RR_MODE_SWITCH;
>> + }
>> + I915_WRITE(reg, val);
>> + }
>> +
>> + /*
>> + * mutex taken to ensure that there is no race between differnt
>> + * drrs calls trying to update refresh rate. This scenario may occur
>> + * in future when idleness detection based DRRS in kernel and
>> + * possible calls from user space to set differnt RR are made.
>> + */
>> +
>> + mutex_lock(&intel_dp->drrs_state.mutex);
>
> Isn't this always done with dev->struct_mutex held? Why extra locking?
>
This has been added to take care of scenarios that may occur in future
based on user space implementation.
>> +
>> + intel_dp->drrs_state.refresh_rate_type = index;
>> +
>> + mutex_unlock(&intel_dp->drrs_state.mutex);
>> +
>> + DRM_DEBUG_KMS("eDP Refresh Rate set to : %dHz\n", refresh_rate);
>> +}
>> +
>> static struct drm_display_mode *
>> intel_dp_drrs_init(struct intel_digital_port *intel_dig_port,
>> struct intel_connector *intel_connector,
>> @@ -3701,6 +3805,10 @@ intel_dp_drrs_init(struct intel_digital_port *intel_dig_port,
>> intel_connector->panel.edp_downclock =
>> downclock_mode->clock;
>>
>> + dev_priv->drrs.connector = intel_connector;
>> +
>> + mutex_init(&intel_dp->drrs_state.mutex);
>> +
>> intel_dp->drrs_state.type = dev_priv->vbt.drrs_type;
>>
>> intel_dp->drrs_state.refresh_rate_type = DRRS_HIGH_RR;
>> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
>> index c41c735..4f7c816 100644
>> --- a/drivers/gpu/drm/i915/intel_drv.h
>> +++ b/drivers/gpu/drm/i915/intel_drv.h
>> @@ -291,6 +291,9 @@ struct intel_crtc_config {
>> int pipe_bpp;
>> struct intel_link_m_n dp_m_n;
>>
>> + /* m2_n2 for eDP downclock */
>> + struct intel_link_m_n dp_m2_n2;
>> +
>> /*
>> * Frequence the dpll for the port should run at. Differs from the
>> * adjusted dotclock e.g. for DP or 12bpc hdmi mode. This is also
>> @@ -481,6 +484,7 @@ enum edp_drrs_refresh_rate_type {
>> struct drrs_info {
>> enum drrs_support_type type;
>> enum edp_drrs_refresh_rate_type refresh_rate_type;
>> + struct mutex mutex;
>> };
>>
>> struct intel_dp {
>> @@ -769,7 +773,7 @@ void intel_edp_panel_off(struct intel_dp *intel_dp);
>> void intel_edp_psr_enable(struct intel_dp *intel_dp);
>> void intel_edp_psr_disable(struct intel_dp *intel_dp);
>> void intel_edp_psr_update(struct drm_device *dev);
>> -
>> +void intel_dp_set_drrs_state(struct drm_device *dev, int refresh_rate);
>>
>> /* intel_dsi.c */
>> bool intel_dsi_init(struct drm_device *dev);
>> --
>> 1.7.9.5
>>
>> _______________________________________________
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>
next prev parent reply other threads:[~2014-03-27 8:59 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-03-07 5:17 [PATCH 0/6] v6: Enabling DRRS in the kernel Vandana Kannan
2014-03-07 5:17 ` [PATCH 1/6] drm/i915: Adding VBT fields to support eDP DRRS feature Vandana Kannan
2014-03-26 12:36 ` Jani Nikula
2014-03-27 9:17 ` Vandana Kannan
2014-03-27 10:39 ` Jani Nikula
2014-03-07 5:17 ` [PATCH 2/6] drm/i915: Parse EDID probed modes for DRRS support Vandana Kannan
2014-03-26 12:45 ` Jani Nikula
2014-03-26 12:49 ` Jani Nikula
2014-03-27 8:32 ` Vandana Kannan
2014-03-07 5:17 ` [PATCH 3/6] drm/i915: Add support for DRRS to switch RR Vandana Kannan
2014-03-26 12:55 ` Jani Nikula
2014-03-27 8:59 ` Vandana Kannan [this message]
2014-03-07 5:17 ` [PATCH 4/6] drm/i915: Idleness detection for DRRS Vandana Kannan
2014-03-26 13:05 ` Jani Nikula
2014-03-27 10:20 ` Vandana Kannan
2014-03-07 5:17 ` [PATCH 5/6] drm/i915/bdw: Add support for DRRS to switch RR Vandana Kannan
2014-03-26 13:06 ` Jani Nikula
2014-03-07 5:17 ` [PATCH 6/6] drm/i915: Support for RR switching on VLV Vandana Kannan
-- strict thread matches above, loose matches on Subject: below --
2014-03-28 4:44 [PATCH 0/6] v7: Enabling DRRS in the kernel Vandana Kannan
2014-03-28 4:44 ` [PATCH 3/6] drm/i915: Add support for DRRS to switch RR Vandana Kannan
2014-04-01 13:25 ` Jani Nikula
2014-04-02 5:58 ` Vandana Kannan
2014-03-05 9:43 [PATCH 0/6] v6: Enabling DRRS in the kernel Vandana Kannan
2014-03-05 9:43 ` [PATCH 3/6] drm/i915: Add support for DRRS to switch RR Vandana Kannan
2014-03-05 9:58 ` Chris Wilson
2014-03-07 8:41 ` Vandana Kannan
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=5333E882.2010906@intel.com \
--to=vandana.kannan@intel.com \
--cc=intel-gfx@lists.freedesktop.org \
--cc=jani.nikula@linux.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.