All of lore.kernel.org
 help / color / mirror / Atom feed
From: Vandana Kannan <vandana.kannan@intel.com>
To: Daniel Vetter <daniel@ffwll.ch>,
	Jani Nikula <jani.nikula@linux.intel.com>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>,
	"intel-gfx@lists.freedesktop.org"
	<intel-gfx@lists.freedesktop.org>
Subject: Re: [PATCH v5 2/2] drm/i915: State readout and cross-checking for dp_m2_n2
Date: Wed, 18 Jun 2014 10:11:20 +0530	[thread overview]
Message-ID: <53A11870.9030805@intel.com> (raw)
In-Reply-To: <20140617164240.GP5821@phenom.ffwll.local>

On Jun-17-2014 10:12 PM, Daniel Vetter wrote:
> On Tue, Jun 17, 2014 at 05:52:24PM +0300, Jani Nikula wrote:
>> On Mon, 16 Jun 2014, Vandana Kannan <vandana.kannan@intel.com> wrote:
>>> On Jun-13-2014 7:42 PM, Jani Nikula wrote:
>>>> On Thu, 22 May 2014, Vandana Kannan <vandana.kannan@intel.com> wrote:
>>>>> Adding relevant read out comparison code, in check_crtc_state, for the new
>>>>> member of crtc_config, dp_m2_n2, which was introduced to store link_m_n
>>>>> values for a DP downclock mode (if available). Suggested by Daniel.
>>>>>
>>>>> v2: Changed patch title.
>>>>> Daniel's review comments incorporated.
>>>>> Added relevant state readout code for M2_N2. dp_m2_n2 comparison to be done
>>>>> only when high RR is not in use (This is because alternate m_n register
>>>>> programming will be done only when low RR is being used).
>>>>>
>>>>> v3: Modified call to get_m2_n2 which had dp_m_n as param by mistake.
>>>>> Compare dp_m_n and dp_m2_n2 for gen 7 and below. compare the structures
>>>>> based on DRRS state for gen 8 and above.
>>>>> Save and restore M2 N2 registers for gen 7 and below
>>>>>
>>>>> v4: For Gen>=8, check M_N registers against dp_m_n and dp_m2_n2 as there is
>>>>> only one set of M_N registers
>>>>>
>>>>> v5: Removed the chunk which saves and restores M2_N2 registers. Modified
>>>>> get_m_n() to get M2_N2 registers as well. Modified the macro which compares
>>>>> hw.dp_m_n against sw.dp_m2_n2/sw.dp_m_n for gen > 8.
>>>>>
>>>>> Signed-off-by: Vandana Kannan <vandana.kannan@intel.com>
>>>>> Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
>>>>> ---
>>>>>  drivers/gpu/drm/i915/intel_display.c | 68 +++++++++++++++++++++++++++++++-----
>>>>>  1 file changed, 60 insertions(+), 8 deletions(-)
>>>>>
>>>>> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
>>>>> index cf3ad87..d593897 100644
>>>>> --- a/drivers/gpu/drm/i915/intel_display.c
>>>>> +++ b/drivers/gpu/drm/i915/intel_display.c
>>>>> @@ -6945,7 +6945,8 @@ static void intel_pch_transcoder_get_m_n(struct intel_crtc *crtc,
>>>>>  
>>>>>  static void intel_cpu_transcoder_get_m_n(struct intel_crtc *crtc,
>>>>>  					 enum transcoder transcoder,
>>>>> -					 struct intel_link_m_n *m_n)
>>>>> +					 struct intel_link_m_n *m_n,
>>>>> +					 struct intel_link_m_n *m2_n2)
>>>>>  {
>>>>>  	struct drm_device *dev = crtc->base.dev;
>>>>>  	struct drm_i915_private *dev_priv = dev->dev_private;
>>>>> @@ -6959,6 +6960,15 @@ static void intel_cpu_transcoder_get_m_n(struct intel_crtc *crtc,
>>>>>  		m_n->gmch_n = I915_READ(PIPE_DATA_N1(transcoder));
>>>>>  		m_n->tu = ((I915_READ(PIPE_DATA_M1(transcoder))
>>>>>  			    & TU_SIZE_MASK) >> TU_SIZE_SHIFT) + 1;
>>>>> +		if (m2_n2 && INTEL_INFO(dev)->gen < 8) {
>>>>> +			m2_n2->link_m = I915_READ(PIPE_LINK_M2(transcoder));
>>>>> +			m2_n2->link_n =	I915_READ(PIPE_LINK_N2(transcoder));
>>>>> +			m2_n2->gmch_m =	I915_READ(PIPE_DATA_M2(transcoder))
>>>>> +					& ~TU_SIZE_MASK;
>>>>> +			m2_n2->gmch_n =	I915_READ(PIPE_DATA_N2(transcoder));
>>>>> +			m2_n2->tu = ((I915_READ(PIPE_DATA_M2(transcoder))
>>>>> +					& TU_SIZE_MASK) >> TU_SIZE_SHIFT) + 1;
>>>>> +		}
>>>>>  	} else {
>>>>>  		m_n->link_m = I915_READ(PIPE_LINK_M_G4X(pipe));
>>>>>  		m_n->link_n = I915_READ(PIPE_LINK_N_G4X(pipe));
>>>>> @@ -6977,14 +6987,15 @@ void intel_dp_get_m_n(struct intel_crtc *crtc,
>>>>>  		intel_pch_transcoder_get_m_n(crtc, &pipe_config->dp_m_n);
>>>>>  	else
>>>>>  		intel_cpu_transcoder_get_m_n(crtc, pipe_config->cpu_transcoder,
>>>>> -					     &pipe_config->dp_m_n);
>>>>> +					     &pipe_config->dp_m_n,
>>>>> +					     &pipe_config->dp_m2_n2);
>>>>>  }
>>>>>  
>>>>>  static void ironlake_get_fdi_m_n_config(struct intel_crtc *crtc,
>>>>>  					struct intel_crtc_config *pipe_config)
>>>>>  {
>>>>>  	intel_cpu_transcoder_get_m_n(crtc, pipe_config->cpu_transcoder,
>>>>> -				     &pipe_config->fdi_m_n);
>>>>> +				     &pipe_config->fdi_m_n, NULL);
>>>>>  }
>>>>>  
>>>>>  static void ironlake_get_pfit_config(struct intel_crtc *crtc,
>>>>> @@ -9485,6 +9496,15 @@ static void intel_dump_pipe_config(struct intel_crtc *crtc,
>>>>>  		      pipe_config->dp_m_n.gmch_m, pipe_config->dp_m_n.gmch_n,
>>>>>  		      pipe_config->dp_m_n.link_m, pipe_config->dp_m_n.link_n,
>>>>>  		      pipe_config->dp_m_n.tu);
>>>>> +
>>>>> +	DRM_DEBUG_KMS("dp: %i, gmch_m2: %u, gmch_n2: %u, link_m2: %u, link_n2: %u, tu2: %u\n",
>>>>> +		      pipe_config->has_dp_encoder,
>>>>> +		      pipe_config->dp_m2_n2.gmch_m,
>>>>> +		      pipe_config->dp_m2_n2.gmch_n,
>>>>> +		      pipe_config->dp_m2_n2.link_m,
>>>>> +		      pipe_config->dp_m2_n2.link_n,
>>>>> +		      pipe_config->dp_m2_n2.tu);
>>>>> +
>>>>>  	DRM_DEBUG_KMS("requested mode:\n");
>>>>>  	drm_mode_debug_printmodeline(&pipe_config->requested_mode);
>>>>>  	DRM_DEBUG_KMS("adjusted mode:\n");
>>>>> @@ -9867,6 +9887,22 @@ intel_pipe_config_compare(struct drm_device *dev,
>>>>>  		return false; \
>>>>>  	}
>>>>>  
>>>>> +/* This is required for BDW+ where there is only one set of registers for
>>>>> + * switching between high and low RR.
>>>>> + * This macro can be used whenever a comparison has to be made between one
>>>>> + * hw state and multiple sw state variables.
>>>>> + */
>>>>> +#define PIPE_CONF_CHECK_I_ALT(name, alt_name) \
>>>>> +	if ((current_config->name != pipe_config->name) && \
>>>>> +		(current_config->alt_name != pipe_config->name)) { \
>>>>> +			DRM_ERROR("mismatch in " #name " " \
>>>>> +				  "(expected %i or %i, found %i)\n", \
>>>>> +				  current_config->name, \
>>>>> +				  current_config->alt_name, \
>>>>> +				  pipe_config->name); \
>>>>> +			return false; \
>>>>> +	}
>>>>> +
>>>>>  #define PIPE_CONF_CHECK_FLAGS(name, mask)	\
>>>>>  	if ((current_config->name ^ pipe_config->name) & (mask)) { \
>>>>>  		DRM_ERROR("mismatch in " #name "(" #mask ") "	   \
>>>>> @@ -9899,11 +9935,26 @@ intel_pipe_config_compare(struct drm_device *dev,
>>>>>  	PIPE_CONF_CHECK_I(fdi_m_n.tu);
>>>>>  
>>>>>  	PIPE_CONF_CHECK_I(has_dp_encoder);
>>>>> -	PIPE_CONF_CHECK_I(dp_m_n.gmch_m);
>>>>> -	PIPE_CONF_CHECK_I(dp_m_n.gmch_n);
>>>>> -	PIPE_CONF_CHECK_I(dp_m_n.link_m);
>>>>> -	PIPE_CONF_CHECK_I(dp_m_n.link_n);
>>>>> -	PIPE_CONF_CHECK_I(dp_m_n.tu);
>>>>> +
>>>>> +	if (INTEL_INFO(dev)->gen < 8) {
>>>>> +		PIPE_CONF_CHECK_I(dp_m_n.gmch_m);
>>>>> +		PIPE_CONF_CHECK_I(dp_m_n.gmch_n);
>>>>> +		PIPE_CONF_CHECK_I(dp_m_n.link_m);
>>>>> +		PIPE_CONF_CHECK_I(dp_m_n.link_n);
>>>>> +		PIPE_CONF_CHECK_I(dp_m_n.tu);
>>>>> +
>>>>> +		PIPE_CONF_CHECK_I(dp_m2_n2.gmch_m);
>>>>> +		PIPE_CONF_CHECK_I(dp_m2_n2.gmch_n);
>>>>> +		PIPE_CONF_CHECK_I(dp_m2_n2.link_m);
>>>>> +		PIPE_CONF_CHECK_I(dp_m2_n2.link_n);
>>>>> +		PIPE_CONF_CHECK_I(dp_m2_n2.tu);
>>>>> +	} else {
>>>>> +		PIPE_CONF_CHECK_I_ALT(dp_m_n.gmch_m, dp_m2_n2.gmch_m);
>>>>> +		PIPE_CONF_CHECK_I_ALT(dp_m_n.gmch_n, dp_m2_n2.gmch_n);
>>>>> +		PIPE_CONF_CHECK_I_ALT(dp_m_n.link_m, dp_m2_n2.link_m);
>>>>> +		PIPE_CONF_CHECK_I_ALT(dp_m_n.link_n, dp_m2_n2.link_n);
>>>>> +		PIPE_CONF_CHECK_I_ALT(dp_m_n.tu, dp_m2_n2.tu);
>>>>
>>>> If there's no downclock mode (e.g. because it's not eDP), this now
>>>> accepts register value 0 as okay for each state check. That's not cool.
>>>>
>>>> Perhaps drrs state should be part of pipe config.
>>>>
>>>> BR,
>>>> Jani.
>>>>
>>> Ok, shall I go ahead with the following approach?
>>>
>>> pipe_config{
>>> 	drrs_state;
>>> }
>>>
>>> in pipe_config_compare() {
>>> if gen < 8 {
>>> compare dp_m1_n1
>>> if drrs_state == seamless
>>> 	compare hw.dp_m2_n2 and sw.dp_m2_n2
>>> /* this drrs_state would be set only in edp_init_connector and only when
>>> a downclock_mode is found */
>>> }
>>> else
>>> 	compare hw.dp_m_n and sw.dp_m_n or sw.dp_m2_n2
>>> }
>>>
>>> drrs_state is stored in vbt struct and intel_dp as of now. some changes
>>> would be required around this to avoid saving this state at a third
>>> place (pipe_config).
>>> option 1. move drrs_state from intel_dp to dev_priv.
>>> option 2. move drrs_state from intel_dp to pipe_config.
>>>
>>> with the above changes, the patches accessing intel_dp->drrs_state would
>>> require changes.
>>>
>>> Please let me know your inputs on this.
>>
>> Daniel, any further thoughts on this? What fits best with future work?
>> Or go ahead with the patch as-is, even though it has the corner case?
> 
> I think we should have a flag that says whether the 2nd set of regs is
> valid, then only use those if that's set. So amounts to adding a static
> copy to pipe_config, e.g. config.has_drrs -> 2nd set of values is valid.
> 
I had introduced HAS_DRRS(dev) in patch#1 of this 2-patch series. I
could use that along with intel_crtc->config.has_dp_encoder check to
proceed with dp_m2_n2 comparison.
What are you thoughts on this?

-Vandana
> Or we just compare against 0 and don't use them if they're all 0 since
> that's just not a valid m/n setting.
> 
> Future plans for drrs are more about tracking and will require moving
> things around in general all over the place. Imo no concern for this patch
> here.
> -Daniel
> 

  reply	other threads:[~2014-06-18  4:41 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-05-22  6:48 [PATCH v5 2/2] drm/i915: State readout and cross-checking for dp_m2_n2 Vandana Kannan
2014-05-30  4:48 ` Vandana Kannan
2014-06-13 14:12 ` Jani Nikula
2014-06-16  9:45   ` Vandana Kannan
2014-06-17 14:52     ` Jani Nikula
2014-06-17 16:42       ` Daniel Vetter
2014-06-18  4:41         ` Vandana Kannan [this message]
2014-06-18 10:46           ` Daniel Vetter
2014-06-18 14:06             ` Vandana Kannan
2014-06-18 14:57               ` [PATCH v6 " Vandana Kannan
2014-06-23 10:57                 ` [PATCH v7 " 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=53A11870.9030805@intel.com \
    --to=vandana.kannan@intel.com \
    --cc=daniel.vetter@ffwll.ch \
    --cc=daniel@ffwll.ch \
    --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.