2013-08-01 21:18:06

by Furquan Shaikh

[permalink] [raw]
Subject: [PATCH] drm/i915: add fast boot support for Haswell

Enables getting correct mode clock when reading pipe config

Signed-off-by: Furquan Shaikh <[email protected]>
---
drivers/gpu/drm/i915/intel_ddi.c | 8 ++++++++
drivers/gpu/drm/i915/intel_display.c | 9 ++++++++-
2 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index 931b4bb..fa0af9b 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -1269,6 +1269,7 @@ static void intel_ddi_get_config(struct intel_encoder *encoder,
struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder;
+ int port = intel_ddi_get_encoder_port(encoder);
u32 temp, flags = 0;

temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
@@ -1282,6 +1283,13 @@ static void intel_ddi_get_config(struct intel_encoder *encoder,
flags |= DRM_MODE_FLAG_NVSYNC;

pipe_config->adjusted_mode.flags |= flags;
+
+ if (port == PORT_A) {
+ if ((I915_READ(DP_A) & DP_PLL_FREQ_MASK) == DP_PLL_FREQ_160MHZ)
+ pipe_config->port_clock = 162000;
+ else
+ pipe_config->port_clock = 270000;
+ }
}

static void intel_ddi_destroy(struct drm_encoder *encoder)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 3e66f05..681c99a 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -7176,6 +7176,8 @@ static void i9xx_crtc_clock_get(struct intel_crtc *crtc,
pipe_config->pixel_multiplier;
}

+#define div_ceil(A, B) ((A)/(B) + ((A)%(B) ? 1 : 0))
+
static void ironlake_crtc_clock_get(struct intel_crtc *crtc,
struct intel_crtc_config *pipe_config)
{
@@ -7218,7 +7220,11 @@ static void ironlake_crtc_clock_get(struct intel_crtc *crtc,
return;

clock = ((u64)link_m * (u64)link_freq * (u64)repeat);
- do_div(clock, link_n);
+ /* This is required because the value comes out to be in fraction
+ (eg. 70699.54). Need to round it up since values are compared in
+ drm_mode_equal
+ */
+ clock = div_ceil(clock, link_n);

pipe_config->adjusted_mode.clock = clock;
}
@@ -9588,6 +9594,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_clock = ironlake_crtc_clock_get;
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;
--
1.8.3


2013-08-05 07:24:17

by Daniel Vetter

[permalink] [raw]
Subject: Re: [PATCH] drm/i915: add fast boot support for Haswell

On Thu, Aug 01, 2013 at 02:12:22PM -0700, Furquan Shaikh wrote:
> Enables getting correct mode clock when reading pipe config
>
> Signed-off-by: Furquan Shaikh <[email protected]>
> ---
> drivers/gpu/drm/i915/intel_ddi.c | 8 ++++++++
> drivers/gpu/drm/i915/intel_display.c | 9 ++++++++-
> 2 files changed, 16 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
> index 931b4bb..fa0af9b 100644
> --- a/drivers/gpu/drm/i915/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/intel_ddi.c
> @@ -1269,6 +1269,7 @@ static void intel_ddi_get_config(struct intel_encoder *encoder,
> struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
> struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
> enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder;
> + int port = intel_ddi_get_encoder_port(encoder);
> u32 temp, flags = 0;
>
> temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
> @@ -1282,6 +1283,13 @@ static void intel_ddi_get_config(struct intel_encoder *encoder,
> flags |= DRM_MODE_FLAG_NVSYNC;
>
> pipe_config->adjusted_mode.flags |= flags;
> +
> + if (port == PORT_A) {
> + if ((I915_READ(DP_A) & DP_PLL_FREQ_MASK) == DP_PLL_FREQ_160MHZ)
> + pipe_config->port_clock = 162000;
> + else
> + pipe_config->port_clock = 270000;
> + }

I don't think this works correctly since for DP we have new clocks on
haswell, see intel_ddi_pll_mode_set. Also I think it'd be good to go right
ahead and implement clock readout support for all hsw clock sources, not
just DP.
-Daniel

> }
>
> static void intel_ddi_destroy(struct drm_encoder *encoder)
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 3e66f05..681c99a 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -7176,6 +7176,8 @@ static void i9xx_crtc_clock_get(struct intel_crtc *crtc,
> pipe_config->pixel_multiplier;
> }
>
> +#define div_ceil(A, B) ((A)/(B) + ((A)%(B) ? 1 : 0))
> +
> static void ironlake_crtc_clock_get(struct intel_crtc *crtc,
> struct intel_crtc_config *pipe_config)
> {
> @@ -7218,7 +7220,11 @@ static void ironlake_crtc_clock_get(struct intel_crtc *crtc,
> return;
>
> clock = ((u64)link_m * (u64)link_freq * (u64)repeat);
> - do_div(clock, link_n);
> + /* This is required because the value comes out to be in fraction
> + (eg. 70699.54). Need to round it up since values are compared in
> + drm_mode_equal
> + */
> + clock = div_ceil(clock, link_n);
>
> pipe_config->adjusted_mode.clock = clock;
> }
> @@ -9588,6 +9594,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_clock = ironlake_crtc_clock_get;
> 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;
> --
> 1.8.3
>
> _______________________________________________
> dri-devel mailing list
> [email protected]
> http://lists.freedesktop.org/mailman/listinfo/dri-devel

--
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch

2013-08-05 22:42:12

by Jesse Barnes

[permalink] [raw]
Subject: Re: [PATCH] drm/i915: add fast boot support for Haswell

On Thu, 1 Aug 2013 14:12:22 -0700
Furquan Shaikh <[email protected]> wrote:

> @@ -1282,6 +1283,13 @@ static void intel_ddi_get_config(struct intel_encoder *encoder,
> flags |= DRM_MODE_FLAG_NVSYNC;
>
> pipe_config->adjusted_mode.flags |= flags;
> +
> + if (port == PORT_A) {
> + if ((I915_READ(DP_A) & DP_PLL_FREQ_MASK) == DP_PLL_FREQ_160MHZ)
> + pipe_config->port_clock = 162000;
> + else
> + pipe_config->port_clock = 270000;
> + }

Sorry Furquan, I should have checked this earlier, I knew it was too
good to be true. :)

On HSW, DP_A is actually DDI_BUF_CTL, and it has a different layout
than the old DP_A reg. Like Daniel said, doing it the old way is
invalid on HSW. It might work in your configs, but I think that's just
coincidence, since bit 16 is the port reversal bit on HSW, not the
clock freq.

To get the clock freq, you need to look at 0x45020 to find the refclk,
then look at the WRPLL_CTL for the pipe to get the dividers. That's
what Daniel meant when he asked for a full "clock_get" function. It's
only a little more complicated, but you'll need docs for it. Charlie
Huang ought to be able to get you the NDA docs that should have the
info you need.

Thanks,
--
Jesse Barnes, Intel Open Source Technology Center