[PATCH] i915: intel_dp_aux_backlight: Fix max backlight calculations

2019-06-17 Thread Furquan Shaikh
Max backlight value for the panel was being calculated using byte
count i.e. 0x if 2 bytes are supported for backlight brightness
and 0xff if 1 byte is supported. However, EDP_PWMGEN_BIT_COUNT
determines the number of active control bits used for the brightness
setting. Thus, even if the panel uses 2 byte setting, it might not use
all the control bits. Thus, max backlight should be set based on the
value of EDP_PWMGEN_BIT_COUNT instead of assuming 65535 or 255.

Additionally, EDP_PWMGEN_BIT_COUNT was being updated based on the VBT
frequency which results in a different max backlight value. Thus,
setting of EDP_PWMGEN_BIT_COUNT is moved to setup phase instead of
enable so that max backlight can be calculated correctly. Only the
frequency divider is set during the enable phase using the value of
EDP_PWMGEN_BIT_COUNT.

Signed-off-by: Furquan Shaikh 
Reviewed-by: Stéphane Marchesin 
---
 drivers/gpu/drm/i915/intel_dp_aux_backlight.c | 132 --
 1 file changed, 88 insertions(+), 44 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp_aux_backlight.c 
b/drivers/gpu/drm/i915/intel_dp_aux_backlight.c
index 357136f17f85..4636c8e8ae8a 100644
--- a/drivers/gpu/drm/i915/intel_dp_aux_backlight.c
+++ b/drivers/gpu/drm/i915/intel_dp_aux_backlight.c
@@ -110,61 +110,34 @@ static bool intel_dp_aux_set_pwm_freq(struct 
intel_connector *connector)
 {
struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
struct intel_dp *intel_dp = enc_to_intel_dp(&connector->encoder->base);
-   int freq, fxp, fxp_min, fxp_max, fxp_actual, f = 1;
-   u8 pn, pn_min, pn_max;
+   int freq, fxp, f, fxp_actual, fxp_min, fxp_max;
+   u8 pn;
 
-   /* Find desired value of (F x P)
-* Note that, if F x P is out of supported range, the maximum value or
-* minimum value will applied automatically. So no need to check that.
-*/
freq = dev_priv->vbt.backlight.pwm_freq_hz;
-   DRM_DEBUG_KMS("VBT defined backlight frequency %u Hz\n", freq);
if (!freq) {
DRM_DEBUG_KMS("Use panel default backlight frequency\n");
return false;
}
 
-   fxp = DIV_ROUND_CLOSEST(KHz(DP_EDP_BACKLIGHT_FREQ_BASE_KHZ), freq);
-
-   /* Use highest possible value of Pn for more granularity of brightness
-* adjustment while satifying the conditions below.
-* - Pn is in the range of Pn_min and Pn_max
-* - F is in the range of 1 and 255
-* - FxP is within 25% of desired value.
-*   Note: 25% is arbitrary value and may need some tweak.
-*/
-   if (drm_dp_dpcd_readb(&intel_dp->aux,
-  DP_EDP_PWMGEN_BIT_COUNT_CAP_MIN, &pn_min) != 1) {
-   DRM_DEBUG_KMS("Failed to read pwmgen bit count cap min\n");
+   if (drm_dp_dpcd_readb(&intel_dp->aux, DP_EDP_PWMGEN_BIT_COUNT,
+ &pn) < 0) {
+   DRM_DEBUG_KMS("Failed to read aux pwmgen bit count\n");
return false;
}
-   if (drm_dp_dpcd_readb(&intel_dp->aux,
-  DP_EDP_PWMGEN_BIT_COUNT_CAP_MAX, &pn_max) != 1) {
-   DRM_DEBUG_KMS("Failed to read pwmgen bit count cap max\n");
-   return false;
-   }
-   pn_min &= DP_EDP_PWMGEN_BIT_COUNT_MASK;
-   pn_max &= DP_EDP_PWMGEN_BIT_COUNT_MASK;
 
+   fxp = DIV_ROUND_CLOSEST(KHz(DP_EDP_BACKLIGHT_FREQ_BASE_KHZ), freq);
+   f = clamp(DIV_ROUND_CLOSEST(fxp, 1 << pn), 1, 255);
+   fxp_actual = f << pn;
+
+   /* Ensure frequency is within 25% of desired value */
fxp_min = DIV_ROUND_CLOSEST(fxp * 3, 4);
fxp_max = DIV_ROUND_CLOSEST(fxp * 5, 4);
-   if (fxp_min < (1 << pn_min) || (255 << pn_max) < fxp_max) {
-   DRM_DEBUG_KMS("VBT defined backlight frequency out of range\n");
-   return false;
-   }
 
-   for (pn = pn_max; pn >= pn_min; pn--) {
-   f = clamp(DIV_ROUND_CLOSEST(fxp, 1 << pn), 1, 255);
-   fxp_actual = f << pn;
-   if (fxp_min <= fxp_actual && fxp_actual <= fxp_max)
-   break;
-   }
-
-   if (drm_dp_dpcd_writeb(&intel_dp->aux,
-  DP_EDP_PWMGEN_BIT_COUNT, pn) < 0) {
-   DRM_DEBUG_KMS("Failed to write aux pwmgen bit count\n");
+   if (fxp_min > fxp_actual || fxp_actual > fxp_max) {
+   DRM_DEBUG_KMS("Actual frequency out of range\n");
return false;
}
+
if (drm_dp_dpcd_writeb(&intel_dp->aux,
   DP_EDP_BACKLIGHT_FREQ_SET, (u8) f) < 0) {
DRM_DEBUG_KMS("Failed to write aux backlight freq\n");
@@ -224,16 +197,87 @@ static void intel_

[PATCH v2] i915: intel_dp_aux_backlight: Fix max backlight calculations

2019-07-10 Thread Furquan Shaikh
Max backlight value for the panel was being calculated using byte
count i.e. 0x if 2 bytes are supported for backlight brightness
and 0xff if 1 byte is supported. However, EDP_PWMGEN_BIT_COUNT
determines the number of active control bits used for the brightness
setting. Thus, even if the panel uses 2 byte setting, it might not use
all the control bits. Thus, max backlight should be set based on the
value of EDP_PWMGEN_BIT_COUNT instead of assuming 65535 or 255.

Additionally, EDP_PWMGEN_BIT_COUNT was being updated based on the VBT
frequency which results in a different max backlight value. Thus,
setting of EDP_PWMGEN_BIT_COUNT is moved to setup phase instead of
enable so that max backlight can be calculated correctly. Only the
frequency divider is set during the enable phase using the value of
EDP_PWMGEN_BIT_COUNT.

Signed-off-by: Furquan Shaikh 
Reviewed-by: Stéphane Marchesin 
---
v2: In case of DPCD failure and pn being uninitialized, return max_backlight as 
0.

 drivers/gpu/drm/i915/intel_dp_aux_backlight.c | 134 --
 1 file changed, 90 insertions(+), 44 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp_aux_backlight.c 
b/drivers/gpu/drm/i915/intel_dp_aux_backlight.c
index 357136f17f85..b3678b8a5b4d 100644
--- a/drivers/gpu/drm/i915/intel_dp_aux_backlight.c
+++ b/drivers/gpu/drm/i915/intel_dp_aux_backlight.c
@@ -110,61 +110,34 @@ static bool intel_dp_aux_set_pwm_freq(struct 
intel_connector *connector)
 {
struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
struct intel_dp *intel_dp = enc_to_intel_dp(&connector->encoder->base);
-   int freq, fxp, fxp_min, fxp_max, fxp_actual, f = 1;
-   u8 pn, pn_min, pn_max;
+   int freq, fxp, f, fxp_actual, fxp_min, fxp_max;
+   u8 pn;
 
-   /* Find desired value of (F x P)
-* Note that, if F x P is out of supported range, the maximum value or
-* minimum value will applied automatically. So no need to check that.
-*/
freq = dev_priv->vbt.backlight.pwm_freq_hz;
-   DRM_DEBUG_KMS("VBT defined backlight frequency %u Hz\n", freq);
if (!freq) {
DRM_DEBUG_KMS("Use panel default backlight frequency\n");
return false;
}
 
-   fxp = DIV_ROUND_CLOSEST(KHz(DP_EDP_BACKLIGHT_FREQ_BASE_KHZ), freq);
-
-   /* Use highest possible value of Pn for more granularity of brightness
-* adjustment while satifying the conditions below.
-* - Pn is in the range of Pn_min and Pn_max
-* - F is in the range of 1 and 255
-* - FxP is within 25% of desired value.
-*   Note: 25% is arbitrary value and may need some tweak.
-*/
-   if (drm_dp_dpcd_readb(&intel_dp->aux,
-  DP_EDP_PWMGEN_BIT_COUNT_CAP_MIN, &pn_min) != 1) {
-   DRM_DEBUG_KMS("Failed to read pwmgen bit count cap min\n");
+   if (drm_dp_dpcd_readb(&intel_dp->aux, DP_EDP_PWMGEN_BIT_COUNT,
+ &pn) < 0) {
+   DRM_DEBUG_KMS("Failed to read aux pwmgen bit count\n");
return false;
}
-   if (drm_dp_dpcd_readb(&intel_dp->aux,
-  DP_EDP_PWMGEN_BIT_COUNT_CAP_MAX, &pn_max) != 1) {
-   DRM_DEBUG_KMS("Failed to read pwmgen bit count cap max\n");
-   return false;
-   }
-   pn_min &= DP_EDP_PWMGEN_BIT_COUNT_MASK;
-   pn_max &= DP_EDP_PWMGEN_BIT_COUNT_MASK;
 
+   fxp = DIV_ROUND_CLOSEST(KHz(DP_EDP_BACKLIGHT_FREQ_BASE_KHZ), freq);
+   f = clamp(DIV_ROUND_CLOSEST(fxp, 1 << pn), 1, 255);
+   fxp_actual = f << pn;
+
+   /* Ensure frequency is within 25% of desired value */
fxp_min = DIV_ROUND_CLOSEST(fxp * 3, 4);
fxp_max = DIV_ROUND_CLOSEST(fxp * 5, 4);
-   if (fxp_min < (1 << pn_min) || (255 << pn_max) < fxp_max) {
-   DRM_DEBUG_KMS("VBT defined backlight frequency out of range\n");
-   return false;
-   }
 
-   for (pn = pn_max; pn >= pn_min; pn--) {
-   f = clamp(DIV_ROUND_CLOSEST(fxp, 1 << pn), 1, 255);
-   fxp_actual = f << pn;
-   if (fxp_min <= fxp_actual && fxp_actual <= fxp_max)
-   break;
-   }
-
-   if (drm_dp_dpcd_writeb(&intel_dp->aux,
-  DP_EDP_PWMGEN_BIT_COUNT, pn) < 0) {
-   DRM_DEBUG_KMS("Failed to write aux pwmgen bit count\n");
+   if (fxp_min > fxp_actual || fxp_actual > fxp_max) {
+   DRM_DEBUG_KMS("Actual frequency out of range\n");
return false;
}
+
if (drm_dp_dpcd_writeb(&intel_dp->aux,
   DP_EDP_BACKLIGHT_FREQ_SET, (u8) f) < 0) {
DRM_DEBUG_KMS("Failed to write

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

2013-08-01 Thread Furquan Shaikh
Enables getting correct mode clock when reading pipe config

Signed-off-by: Furquan Shaikh 
---
 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 = 27;
+   }
 }
 
 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
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


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

2013-08-05 Thread Furquan Shaikh
We tested the submitted patch on several systems here and it seems to be
working fine. So, I'm not sure I understand your comment. Can you please
provide more details?

Thanks,
Furquan


On Mon, Aug 5, 2013 at 12:24 AM, Daniel Vetter  wrote:

> 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 
> > ---
> >  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 = 27;
> > + }
>
> 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
> > dri-devel@lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/dri-devel
>
> --
> Daniel Vetter
> Software Engineer, Intel Corporation
> +41 (0) 79 365 57 48 - http://blog.ffwll.ch
>
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 1/2] drm/i915: Fix bug while calculating the clock value using do_div in ironlake_crtc_clock_get

2013-08-20 Thread Furquan Shaikh
We need to round up the values since the comparison in drm_mode_equal might 
fail if division
results in fractional part

Signed-off-by: Furquan Shaikh 
---
 drivers/gpu/drm/i915/intel_display.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 0f40f8e..e0069f4 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -7190,7 +7190,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_ROUND_UP_ULL(clock, link_n);
 
pipe_config->adjusted_mode.clock = clock;
 }
-- 
1.8.3

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 2/2] drm/i915: add fast boot support for Haswell

2013-08-20 Thread Furquan Shaikh
Enables getting correct mode clock when reading pipe config
This patch has been tested successfully on top of drm-intel-nightly tree

Signed-off-by: Furquan Shaikh 
---
 drivers/gpu/drm/i915/i915_reg.h  |  6 
 drivers/gpu/drm/i915/intel_ddi.c | 70 
 drivers/gpu/drm/i915/intel_display.c |  1 +
 3 files changed, 77 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 2b96d6b..9511129 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -4970,6 +4970,7 @@
 #define  SPLL_PLL_NON_SSC  (2<<28)
 #define  SPLL_PLL_FREQ_810MHz  (0<<26)
 #define  SPLL_PLL_FREQ_1350MHz (1<<26)
+#define  SPLL_PLL_FREQ_MASK (3<<26)
 
 /* WRPLL */
 #define WRPLL_CTL1 0x46040
@@ -4983,6 +4984,10 @@
 #define  WRPLL_DIVIDER_POST(x) ((x)<<8)
 #define  WRPLL_DIVIDER_FEEDBACK(x) ((x)<<16)
 
+#define WRPLL_DIVIDER_REFERENCE_BITS(reg)(reg & 0xff)
+#define WRPLL_DIVIDER_POST_BITS(reg) ((reg >> 8) & 0x3f)
+#define WRPLL_DIVIDER_FEEDBACK_BITS(reg) ((reg >> 16) & 0xff)
+
 /* Port clock selection */
 #define PORT_CLK_SEL_A 0x46100
 #define PORT_CLK_SEL_B 0x46104
@@ -4994,6 +4999,7 @@
 #define  PORT_CLK_SEL_WRPLL1   (4<<29)
 #define  PORT_CLK_SEL_WRPLL2   (5<<29)
 #define  PORT_CLK_SEL_NONE (7<<29)
+#define  PORT_CLK_SEL_MASK  (7<<29)
 
 /* Transcoder clock selection */
 #define TRANS_CLK_SEL_A0x46140
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index b8c096b..a24a375 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -1246,6 +1246,74 @@ static void intel_ddi_hot_plug(struct intel_encoder 
*intel_encoder)
intel_dp_check_link_status(intel_dp);
 }
 
+static void intel_ddi_get_clock(struct intel_encoder *encoder,
+   struct intel_crtc_config *pipe_config)
+{
+   struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
+   int port = intel_ddi_get_encoder_port(encoder);
+   u32 temp = I915_READ(PORT_CLK_SEL(port)) & PORT_CLK_SEL_MASK;
+   u8 link_bw;
+
+   if ((temp == PORT_CLK_SEL_LCPLL_810) ||
+   (temp == PORT_CLK_SEL_LCPLL_1350) ||
+   (temp == PORT_CLK_SEL_LCPLL_2700)) {
+
+   switch (temp) {
+   case PORT_CLK_SEL_LCPLL_810:
+   link_bw = DP_LINK_BW_1_62;
+   break;
+   case PORT_CLK_SEL_LCPLL_1350:
+   link_bw = DP_LINK_BW_2_7;
+   break;
+   case PORT_CLK_SEL_LCPLL_2700:
+   link_bw = DP_LINK_BW_5_4;
+   break;
+   }
+   pipe_config->port_clock = drm_dp_bw_code_to_link_rate(link_bw);
+   } else if ((temp == PORT_CLK_SEL_WRPLL1) ||
+  (temp == PORT_CLK_SEL_WRPLL2)) {
+   uint64_t p, n2, r2;
+   u32 val, reg;
+   uint64_t freq2k;
+
+   switch (temp) {
+   case PORT_CLK_SEL_WRPLL1:
+   reg = WRPLL_CTL1;
+   break;
+   case PORT_CLK_SEL_WRPLL2:
+   reg = WRPLL_CTL2;
+   break;
+   }
+   val = I915_READ(reg);
+   r2 = WRPLL_DIVIDER_REFERENCE_BITS(val);
+   p = WRPLL_DIVIDER_POST_BITS(val);
+   n2 = WRPLL_DIVIDER_FEEDBACK_BITS(val);
+
+   freq2k = DIV_ROUND_UP_ULL(LC_FREQ * n2, r2 * p);
+   pipe_config->port_clock = freq2k / 10;
+   } else if (temp == PORT_CLK_SEL_SPLL) {
+   u32 val;
+
+   val = I915_READ(PORT_CLK_SEL_SPLL);
+
+   switch (val & SPLL_PLL_FREQ_MASK) {
+   case SPLL_PLL_FREQ_810MHz:
+   pipe_config->port_clock = 81;
+   break;
+   case SPLL_PLL_FREQ_1350MHz:
+   pipe_config->port_clock = 135;
+   break;
+   default:
+   WARN(1, "Invalid pll freq %d\n",
+val & SPLL_PLL_FREQ_MASK);
+   return;
+   }
+   } else {
+   WARN(1, "Invalid clock selection %d\n", temp);
+   return;
+   }
+}
+
 static void intel_ddi_get_config(struct intel_encoder *encoder,
 struct intel_crtc_config *pipe_config)
 {
@@ -1265,6 +1333,8 @@ static void intel_ddi_get_config(struct intel_encoder 
*encoder,
flags |= DRM_MODE_FLAG_NVSYNC;
 
pipe_config->adjusted_mode.flags |= flags;
+
+   inte

[PATCH 2/2] drm/i915: add fast boot support for Haswell

2013-08-19 Thread Furquan Shaikh
Enables getting correct mode clock when reading pipe config
This patch has been tested successfully on top of drm-intel-nightly tree

Signed-off-by: Furquan Shaikh 
---
 drivers/gpu/drm/i915/i915_reg.h  |  6 
 drivers/gpu/drm/i915/intel_ddi.c | 70 
 drivers/gpu/drm/i915/intel_display.c |  1 +
 3 files changed, 77 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 2b96d6b..9511129 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -4970,6 +4970,7 @@
 #define  SPLL_PLL_NON_SSC  (2<<28)
 #define  SPLL_PLL_FREQ_810MHz  (0<<26)
 #define  SPLL_PLL_FREQ_1350MHz (1<<26)
+#define  SPLL_PLL_FREQ_MASK (3<<26)

 /* WRPLL */
 #define WRPLL_CTL1 0x46040
@@ -4983,6 +4984,10 @@
 #define  WRPLL_DIVIDER_POST(x) ((x)<<8)
 #define  WRPLL_DIVIDER_FEEDBACK(x) ((x)<<16)

+#define WRPLL_DIVIDER_REFERENCE_BITS(reg)(reg & 0xff)
+#define WRPLL_DIVIDER_POST_BITS(reg) ((reg >> 8) & 0x3f)
+#define WRPLL_DIVIDER_FEEDBACK_BITS(reg) ((reg >> 16) & 0xff)
+
 /* Port clock selection */
 #define PORT_CLK_SEL_A 0x46100
 #define PORT_CLK_SEL_B 0x46104
@@ -4994,6 +4999,7 @@
 #define  PORT_CLK_SEL_WRPLL1   (4<<29)
 #define  PORT_CLK_SEL_WRPLL2   (5<<29)
 #define  PORT_CLK_SEL_NONE (7<<29)
+#define  PORT_CLK_SEL_MASK  (7<<29)

 /* Transcoder clock selection */
 #define TRANS_CLK_SEL_A0x46140
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index b8c096b..a24a375 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -1246,6 +1246,74 @@ static void intel_ddi_hot_plug(struct intel_encoder 
*intel_encoder)
intel_dp_check_link_status(intel_dp);
 }

+static void intel_ddi_get_clock(struct intel_encoder *encoder,
+   struct intel_crtc_config *pipe_config)
+{
+   struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
+   int port = intel_ddi_get_encoder_port(encoder);
+   u32 temp = I915_READ(PORT_CLK_SEL(port)) & PORT_CLK_SEL_MASK;
+   u8 link_bw;
+
+   if ((temp == PORT_CLK_SEL_LCPLL_810) ||
+   (temp == PORT_CLK_SEL_LCPLL_1350) ||
+   (temp == PORT_CLK_SEL_LCPLL_2700)) {
+
+   switch (temp) {
+   case PORT_CLK_SEL_LCPLL_810:
+   link_bw = DP_LINK_BW_1_62;
+   break;
+   case PORT_CLK_SEL_LCPLL_1350:
+   link_bw = DP_LINK_BW_2_7;
+   break;
+   case PORT_CLK_SEL_LCPLL_2700:
+   link_bw = DP_LINK_BW_5_4;
+   break;
+   }
+   pipe_config->port_clock = drm_dp_bw_code_to_link_rate(link_bw);
+   } else if ((temp == PORT_CLK_SEL_WRPLL1) ||
+  (temp == PORT_CLK_SEL_WRPLL2)) {
+   uint64_t p, n2, r2;
+   u32 val, reg;
+   uint64_t freq2k;
+
+   switch (temp) {
+   case PORT_CLK_SEL_WRPLL1:
+   reg = WRPLL_CTL1;
+   break;
+   case PORT_CLK_SEL_WRPLL2:
+   reg = WRPLL_CTL2;
+   break;
+   }
+   val = I915_READ(reg);
+   r2 = WRPLL_DIVIDER_REFERENCE_BITS(val);
+   p = WRPLL_DIVIDER_POST_BITS(val);
+   n2 = WRPLL_DIVIDER_FEEDBACK_BITS(val);
+
+   freq2k = DIV_ROUND_UP_ULL(LC_FREQ * n2, r2 * p);
+   pipe_config->port_clock = freq2k / 10;
+   } else if (temp == PORT_CLK_SEL_SPLL) {
+   u32 val;
+
+   val = I915_READ(PORT_CLK_SEL_SPLL);
+
+   switch (val & SPLL_PLL_FREQ_MASK) {
+   case SPLL_PLL_FREQ_810MHz:
+   pipe_config->port_clock = 81;
+   break;
+   case SPLL_PLL_FREQ_1350MHz:
+   pipe_config->port_clock = 135;
+   break;
+   default:
+   WARN(1, "Invalid pll freq %d\n",
+val & SPLL_PLL_FREQ_MASK);
+   return;
+   }
+   } else {
+   WARN(1, "Invalid clock selection %d\n", temp);
+   return;
+   }
+}
+
 static void intel_ddi_get_config(struct intel_encoder *encoder,
 struct intel_crtc_config *pipe_config)
 {
@@ -1265,6 +1333,8 @@ static void intel_ddi_get_config(struct intel_encoder 
*encoder,
flags |= DRM_MODE_FLAG_NVSYNC;

pipe_config->adjusted_mode.flags |= flags;
+
+   int

[PATCH 1/2] drm/i915: Fix bug while calculating the clock value using do_div in ironlake_crtc_clock_get

2013-08-19 Thread Furquan Shaikh
We need to round up the values since the comparison in drm_mode_equal might 
fail if division
results in fractional part

Signed-off-by: Furquan Shaikh 
---
 drivers/gpu/drm/i915/intel_display.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 0f40f8e..e0069f4 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -7190,7 +7190,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_ROUND_UP_ULL(clock, link_n);

pipe_config->adjusted_mode.clock = clock;
 }
-- 
1.8.3



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

2013-08-01 Thread Furquan Shaikh
Enables getting correct mode clock when reading pipe config

Signed-off-by: Furquan Shaikh 
---
 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 = 27;
+   }
 }

 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



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

2013-08-05 Thread Furquan Shaikh
We tested the submitted patch on several systems here and it seems to be
working fine. So, I'm not sure I understand your comment. Can you please
provide more details?

Thanks,
Furquan


On Mon, Aug 5, 2013 at 12:24 AM, Daniel Vetter  wrote:

> 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 
> > ---
> >  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 = 27;
> > + }
>
> 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
> > dri-devel at lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/dri-devel
>
> --
> Daniel Vetter
> Software Engineer, Intel Corporation
> +41 (0) 79 365 57 48 - http://blog.ffwll.ch
>
-- next part --
An HTML attachment was scrubbed...
URL: 
<http://lists.freedesktop.org/archives/dri-devel/attachments/20130805/b58b/attachment-0001.html>