* [PATCH 0/8] Rework ironlake_crtc_mode_set
@ 2012-09-12 13:06 Paulo Zanoni
2012-09-12 13:06 ` [PATCH 1/8] drm/i915: extract ironlake_set_pipeconf form ironlake_crtc_mode_set Paulo Zanoni
` (7 more replies)
0 siblings, 8 replies; 21+ messages in thread
From: Paulo Zanoni @ 2012-09-12 13:06 UTC (permalink / raw)
To: intel-gfx; +Cc: Paulo Zanoni
From: Paulo Zanoni <paulo.r.zanoni@intel.com>
Every time I have to change ironlake_crtc_mode_set I get scared by the
fact that it has 404 lines. I feel way more confident when I'm changing
small functions that do specific self-contained things.
Thus, the goal of this patch series is to extract from
ironlake_crtc_mode_set sub-functions that do specific things. The goal
of the series is to only change the coding style, not changing the
functionality.
The order that code executes was slightly changed in a few cases, but I
don't expect this to break anything. I tested this series on a SNB with
LVDS, HDMI, DP and VGA and everything worked. I don't have access to
more machines right now, but once I get to my office again I will test
more.
Also, I did a quick check on i9xx_crtc_mode_set and concluded we won't
be able to reuse any of the ironlake functions on it, although we can
try to split i9xx_crtc_mode_set in a similar way. Still, I'm not sure we
want to do that.
After these changes I'll be able to properly and sanely fix the
Haswell/LPT case (since Haswell/LPT is currently running
ironlake_crtc_mode_set):
- fork a haswell_crtc_mode_set function
- create haswell-specific versions of functions that should be
different on Haswell
- run IBX/CPT-specific code only on IBX/CPT, same for LPT
Paulo Zanoni (8):
drm/i915: extract ironlake_set_pipeconf form ironlake_crtc_mode_set
drm/i915: extract LVDS-specific code from ironlake_crtc_mode_set
drm/i915: extract set_pipe_timings from ironlake_crtc_mode_set
drm/i915: simplify setting DSPCNTR inside ironlake_crtc_mode_set
drm/i915: extract set_m_n from ironlake_crtc_mode_set
drm/i915: extract compute_clocks from ironlake_crtc_mode_set
drm/i915: extract pch_pll_set from ironlake_crtc_mode_set
drm/i915: remove unused variables from ironlake_crtc_mode_set
drivers/gpu/drm/i915/intel_display.c | 575 +++++++++++++++++++---------------
drivers/gpu/drm/i915/intel_drv.h | 3 +
drivers/gpu/drm/i915/intel_lvds.c | 43 +++
3 files changed, 374 insertions(+), 247 deletions(-)
--
1.7.10.4
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 1/8] drm/i915: extract ironlake_set_pipeconf form ironlake_crtc_mode_set
2012-09-12 13:06 [PATCH 0/8] Rework ironlake_crtc_mode_set Paulo Zanoni
@ 2012-09-12 13:06 ` Paulo Zanoni
2012-09-12 14:03 ` Daniel Vetter
2012-09-12 13:06 ` [PATCH 2/8] drm/i915: extract LVDS-specific code from ironlake_crtc_mode_set Paulo Zanoni
` (6 subsequent siblings)
7 siblings, 1 reply; 21+ messages in thread
From: Paulo Zanoni @ 2012-09-12 13:06 UTC (permalink / raw)
To: intel-gfx; +Cc: Paulo Zanoni
From: Paulo Zanoni <paulo.r.zanoni@intel.com>
Because ironlake_crtc_mode_set is a giant function that used to have
404 lines. Let's try to make it less complex/confusing.
Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
---
drivers/gpu/drm/i915/intel_display.c | 88 ++++++++++++++++++++--------------
1 file changed, 52 insertions(+), 36 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index e061acd..244bce6 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4646,6 +4646,50 @@ static int ironlake_get_refclk(struct drm_crtc *crtc)
return 120000;
}
+static void ironlake_set_pipeconf(struct drm_crtc *crtc,
+ struct drm_display_mode *adjusted_mode,
+ bool dither)
+{
+ struct drm_i915_private *dev_priv = crtc->dev->dev_private;
+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ int pipe = intel_crtc->pipe;
+ uint32_t val;
+
+ val = I915_READ(PIPECONF(pipe));
+
+ val &= ~PIPE_BPC_MASK;
+ switch (intel_crtc->bpp) {
+ case 18:
+ val |= PIPE_6BPC;
+ break;
+ case 24:
+ val |= PIPE_8BPC;
+ break;
+ case 30:
+ val |= PIPE_10BPC;
+ break;
+ case 36:
+ val |= PIPE_12BPC;
+ break;
+ default:
+ val |= PIPE_8BPC;
+ break;
+ }
+
+ val &= ~(PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_MASK);
+ if (dither)
+ val |= (PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_SP);
+
+ val &= ~PIPECONF_INTERLACE_MASK;
+ if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
+ val |= PIPECONF_INTERLACED_ILK;
+ else
+ val |= PIPECONF_PROGRESSIVE;
+
+ I915_WRITE(PIPECONF(pipe), val);
+ POSTING_READ(PIPECONF(pipe));
+}
+
static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode,
@@ -4659,7 +4703,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
int plane = intel_crtc->plane;
int refclk, num_connectors = 0;
intel_clock_t clock, reduced_clock;
- u32 dpll, fp = 0, fp2 = 0, dspcntr, pipeconf;
+ u32 dpll, fp = 0, fp2 = 0, dspcntr;
bool ok, has_reduced_clock = false, is_sdvo = false;
bool is_crt = false, is_lvds = false, is_tv = false, is_dp = false;
struct intel_encoder *encoder, *edp_encoder = NULL;
@@ -4768,32 +4812,17 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
target_clock = adjusted_mode->clock;
/* determine panel color depth */
- temp = I915_READ(PIPECONF(pipe));
- temp &= ~PIPE_BPC_MASK;
dither = intel_choose_pipe_bpp_dither(crtc, fb, &pipe_bpp, mode);
- switch (pipe_bpp) {
- case 18:
- temp |= PIPE_6BPC;
- break;
- case 24:
- temp |= PIPE_8BPC;
- break;
- case 30:
- temp |= PIPE_10BPC;
- break;
- case 36:
- temp |= PIPE_12BPC;
- break;
- default:
+ if (is_lvds && dev_priv->lvds_dither)
+ dither = true;
+
+ if (pipe_bpp != 18 && pipe_bpp != 24 && pipe_bpp != 30 &&
+ pipe_bpp != 36) {
WARN(1, "intel_choose_pipe_bpp returned invalid value %d\n",
- pipe_bpp);
- temp |= PIPE_8BPC;
+ pipe_bpp);
pipe_bpp = 24;
- break;
}
-
intel_crtc->bpp = pipe_bpp;
- I915_WRITE(PIPECONF(pipe), temp);
if (!lane) {
/*
@@ -4877,9 +4906,6 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
else
dpll |= PLL_REF_INPUT_DREFCLK;
- /* setup pipeconf */
- pipeconf = I915_READ(PIPECONF(pipe));
-
/* Set up the display plane register */
dspcntr = DISPPLANE_GAMMA_ENABLE;
@@ -4942,12 +4968,6 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
I915_WRITE(PCH_LVDS, temp);
}
- pipeconf &= ~PIPECONF_DITHER_EN;
- pipeconf &= ~PIPECONF_DITHER_TYPE_MASK;
- if ((is_lvds && dev_priv->lvds_dither) || dither) {
- pipeconf |= PIPECONF_DITHER_EN;
- pipeconf |= PIPECONF_DITHER_TYPE_SP;
- }
if (is_dp && !is_cpu_edp) {
intel_dp_set_m_n(crtc, mode, adjusted_mode);
} else {
@@ -4983,9 +5003,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
}
}
- pipeconf &= ~PIPECONF_INTERLACE_MASK;
if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
- pipeconf |= PIPECONF_INTERLACED_ILK;
/* the chip adds 2 halflines automatically */
adjusted_mode->crtc_vtotal -= 1;
adjusted_mode->crtc_vblank_end -= 1;
@@ -4993,7 +5011,6 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
adjusted_mode->crtc_hsync_start
- adjusted_mode->crtc_htotal/2);
} else {
- pipeconf |= PIPECONF_PROGRESSIVE;
I915_WRITE(VSYNCSHIFT(pipe), 0);
}
@@ -5031,8 +5048,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
if (is_cpu_edp)
ironlake_set_pll_edp(crtc, adjusted_mode->clock);
- I915_WRITE(PIPECONF(pipe), pipeconf);
- POSTING_READ(PIPECONF(pipe));
+ ironlake_set_pipeconf(crtc, adjusted_mode, dither);
intel_wait_for_vblank(dev, pipe);
--
1.7.10.4
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 2/8] drm/i915: extract LVDS-specific code from ironlake_crtc_mode_set
2012-09-12 13:06 [PATCH 0/8] Rework ironlake_crtc_mode_set Paulo Zanoni
2012-09-12 13:06 ` [PATCH 1/8] drm/i915: extract ironlake_set_pipeconf form ironlake_crtc_mode_set Paulo Zanoni
@ 2012-09-12 13:06 ` Paulo Zanoni
2012-09-12 13:56 ` Daniel Vetter
2012-09-12 13:06 ` [PATCH 3/8] drm/i915: extract set_pipe_timings " Paulo Zanoni
` (5 subsequent siblings)
7 siblings, 1 reply; 21+ messages in thread
From: Paulo Zanoni @ 2012-09-12 13:06 UTC (permalink / raw)
To: intel-gfx; +Cc: Paulo Zanoni
From: Paulo Zanoni <paulo.r.zanoni@intel.com>
A next step would be to move this code to some of the encoder-specific
callbacks. But really, moving the function away is certainly the first
step.
Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
---
drivers/gpu/drm/i915/intel_display.c | 37 ++---------------------------
drivers/gpu/drm/i915/intel_drv.h | 3 +++
drivers/gpu/drm/i915/intel_lvds.c | 43 ++++++++++++++++++++++++++++++++++
3 files changed, 48 insertions(+), 35 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 244bce6..cf1e628 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4710,7 +4710,6 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
const intel_limit_t *limit;
int ret;
struct fdi_m_n m_n = {0};
- u32 temp;
int target_clock, pixel_multiplier, lane, link_bw, factor;
unsigned int pipe_bpp;
bool dither;
@@ -4933,40 +4932,8 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
* This is an exception to the general rule that mode_set doesn't turn
* things on.
*/
- if (is_lvds) {
- temp = I915_READ(PCH_LVDS);
- temp |= LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP;
- if (HAS_PCH_CPT(dev)) {
- temp &= ~PORT_TRANS_SEL_MASK;
- temp |= PORT_TRANS_SEL_CPT(pipe);
- } else {
- if (pipe == 1)
- temp |= LVDS_PIPEB_SELECT;
- else
- temp &= ~LVDS_PIPEB_SELECT;
- }
-
- /* set the corresponsding LVDS_BORDER bit */
- temp |= dev_priv->lvds_border_bits;
- /* Set the B0-B3 data pairs corresponding to whether we're going to
- * set the DPLLs for dual-channel mode or not.
- */
- if (clock.p2 == 7)
- temp |= LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP;
- else
- temp &= ~(LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP);
-
- /* It would be nice to set 24 vs 18-bit mode (LVDS_A3_POWER_UP)
- * appropriately here, but we need to look more thoroughly into how
- * panels behave in the two modes.
- */
- temp &= ~(LVDS_HSYNC_POLARITY | LVDS_VSYNC_POLARITY);
- if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC)
- temp |= LVDS_HSYNC_POLARITY;
- if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC)
- temp |= LVDS_VSYNC_POLARITY;
- I915_WRITE(PCH_LVDS, temp);
- }
+ if (is_lvds)
+ ironlake_lvds_port_enable(intel_crtc, adjusted_mode, clock.p2);
if (is_dp && !is_cpu_edp) {
intel_dp_set_m_n(crtc, mode, adjusted_mode);
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 4f2b2d6..0b71f6c 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -412,6 +412,9 @@ extern void intel_mark_idle(struct drm_device *dev);
extern void intel_mark_fb_busy(struct drm_i915_gem_object *obj);
extern void intel_mark_fb_idle(struct drm_i915_gem_object *obj);
extern bool intel_lvds_init(struct drm_device *dev);
+extern void ironlake_lvds_port_enable(struct intel_crtc *intel_crtc,
+ struct drm_display_mode *adjusted_mode,
+ int clock_p2);
extern void intel_dp_init(struct drm_device *dev, int output_reg,
enum port port);
void
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index 5646895..e418d95 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -587,6 +587,49 @@ static int intel_lvds_set_property(struct drm_connector *connector,
return 0;
}
+void ironlake_lvds_port_enable(struct intel_crtc *intel_crtc,
+ struct drm_display_mode *adjusted_mode,
+ int clock_p2)
+{
+ struct drm_device *dev = intel_crtc->base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ enum pipe pipe = intel_crtc->pipe;
+ uint32_t temp;
+
+ temp = I915_READ(PCH_LVDS);
+ temp |= LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP;
+ if (HAS_PCH_CPT(dev)) {
+ temp &= ~PORT_TRANS_SEL_MASK;
+ temp |= PORT_TRANS_SEL_CPT(pipe);
+ } else {
+ if (pipe == 1)
+ temp |= LVDS_PIPEB_SELECT;
+ else
+ temp &= ~LVDS_PIPEB_SELECT;
+ }
+
+ /* set the corresponsding LVDS_BORDER bit */
+ temp |= dev_priv->lvds_border_bits;
+ /* Set the B0-B3 data pairs corresponding to whether we're going to
+ * set the DPLLs for dual-channel mode or not.
+ */
+ if (clock_p2 == 7)
+ temp |= LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP;
+ else
+ temp &= ~(LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP);
+
+ /* It would be nice to set 24 vs 18-bit mode (LVDS_A3_POWER_UP)
+ * appropriately here, but we need to look more thoroughly into how
+ * panels behave in the two modes.
+ */
+ temp &= ~(LVDS_HSYNC_POLARITY | LVDS_VSYNC_POLARITY);
+ if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC)
+ temp |= LVDS_HSYNC_POLARITY;
+ if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC)
+ temp |= LVDS_VSYNC_POLARITY;
+ I915_WRITE(PCH_LVDS, temp);
+}
+
static const struct drm_encoder_helper_funcs intel_lvds_helper_funcs = {
.mode_fixup = intel_lvds_mode_fixup,
.mode_set = intel_lvds_mode_set,
--
1.7.10.4
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 3/8] drm/i915: extract set_pipe_timings from ironlake_crtc_mode_set
2012-09-12 13:06 [PATCH 0/8] Rework ironlake_crtc_mode_set Paulo Zanoni
2012-09-12 13:06 ` [PATCH 1/8] drm/i915: extract ironlake_set_pipeconf form ironlake_crtc_mode_set Paulo Zanoni
2012-09-12 13:06 ` [PATCH 2/8] drm/i915: extract LVDS-specific code from ironlake_crtc_mode_set Paulo Zanoni
@ 2012-09-12 13:06 ` Paulo Zanoni
2012-09-12 14:11 ` Daniel Vetter
2012-09-12 13:06 ` [PATCH 4/8] drm/i915: simplify setting DSPCNTR inside ironlake_crtc_mode_set Paulo Zanoni
` (4 subsequent siblings)
7 siblings, 1 reply; 21+ messages in thread
From: Paulo Zanoni @ 2012-09-12 13:06 UTC (permalink / raw)
To: intel-gfx; +Cc: Paulo Zanoni
From: Paulo Zanoni <paulo.r.zanoni@intel.com>
Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
---
drivers/gpu/drm/i915/intel_display.c | 82 +++++++++++++++++++---------------
1 file changed, 46 insertions(+), 36 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index cf1e628..5a4e363 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4690,6 +4690,51 @@ static void ironlake_set_pipeconf(struct drm_crtc *crtc,
POSTING_READ(PIPECONF(pipe));
}
+static void ironlake_set_pipe_timings(struct intel_crtc *intel_crtc,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
+{
+ struct drm_i915_private *dev_priv = intel_crtc->base.dev->dev_private;
+ enum pipe pipe = intel_crtc->pipe;
+
+ if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
+ /* the chip adds 2 halflines automatically */
+ adjusted_mode->crtc_vtotal -= 1;
+ adjusted_mode->crtc_vblank_end -= 1;
+ I915_WRITE(VSYNCSHIFT(pipe),
+ adjusted_mode->crtc_hsync_start
+ - adjusted_mode->crtc_htotal/2);
+ } else {
+ I915_WRITE(VSYNCSHIFT(pipe), 0);
+ }
+
+ I915_WRITE(HTOTAL(pipe),
+ (adjusted_mode->crtc_hdisplay - 1) |
+ ((adjusted_mode->crtc_htotal - 1) << 16));
+ I915_WRITE(HBLANK(pipe),
+ (adjusted_mode->crtc_hblank_start - 1) |
+ ((adjusted_mode->crtc_hblank_end - 1) << 16));
+ I915_WRITE(HSYNC(pipe),
+ (adjusted_mode->crtc_hsync_start - 1) |
+ ((adjusted_mode->crtc_hsync_end - 1) << 16));
+
+ I915_WRITE(VTOTAL(pipe),
+ (adjusted_mode->crtc_vdisplay - 1) |
+ ((adjusted_mode->crtc_vtotal - 1) << 16));
+ I915_WRITE(VBLANK(pipe),
+ (adjusted_mode->crtc_vblank_start - 1) |
+ ((adjusted_mode->crtc_vblank_end - 1) << 16));
+ I915_WRITE(VSYNC(pipe),
+ (adjusted_mode->crtc_vsync_start - 1) |
+ ((adjusted_mode->crtc_vsync_end - 1) << 16));
+
+ /* pipesrc controls the size that is scaled from, which should
+ * always be the user's requested size.
+ */
+ I915_WRITE(PIPESRC(pipe),
+ ((mode->hdisplay - 1) << 16) | (mode->vdisplay - 1));
+}
+
static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode,
@@ -4970,42 +5015,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
}
}
- if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
- /* the chip adds 2 halflines automatically */
- adjusted_mode->crtc_vtotal -= 1;
- adjusted_mode->crtc_vblank_end -= 1;
- I915_WRITE(VSYNCSHIFT(pipe),
- adjusted_mode->crtc_hsync_start
- - adjusted_mode->crtc_htotal/2);
- } else {
- I915_WRITE(VSYNCSHIFT(pipe), 0);
- }
-
- I915_WRITE(HTOTAL(pipe),
- (adjusted_mode->crtc_hdisplay - 1) |
- ((adjusted_mode->crtc_htotal - 1) << 16));
- I915_WRITE(HBLANK(pipe),
- (adjusted_mode->crtc_hblank_start - 1) |
- ((adjusted_mode->crtc_hblank_end - 1) << 16));
- I915_WRITE(HSYNC(pipe),
- (adjusted_mode->crtc_hsync_start - 1) |
- ((adjusted_mode->crtc_hsync_end - 1) << 16));
-
- I915_WRITE(VTOTAL(pipe),
- (adjusted_mode->crtc_vdisplay - 1) |
- ((adjusted_mode->crtc_vtotal - 1) << 16));
- I915_WRITE(VBLANK(pipe),
- (adjusted_mode->crtc_vblank_start - 1) |
- ((adjusted_mode->crtc_vblank_end - 1) << 16));
- I915_WRITE(VSYNC(pipe),
- (adjusted_mode->crtc_vsync_start - 1) |
- ((adjusted_mode->crtc_vsync_end - 1) << 16));
-
- /* pipesrc controls the size that is scaled from, which should
- * always be the user's requested size.
- */
- I915_WRITE(PIPESRC(pipe),
- ((mode->hdisplay - 1) << 16) | (mode->vdisplay - 1));
+ ironlake_set_pipe_timings(intel_crtc, mode, adjusted_mode);
I915_WRITE(PIPE_DATA_M1(pipe), TU_SIZE(m_n.tu) | m_n.gmch_m);
I915_WRITE(PIPE_DATA_N1(pipe), m_n.gmch_n);
--
1.7.10.4
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 4/8] drm/i915: simplify setting DSPCNTR inside ironlake_crtc_mode_set
2012-09-12 13:06 [PATCH 0/8] Rework ironlake_crtc_mode_set Paulo Zanoni
` (2 preceding siblings ...)
2012-09-12 13:06 ` [PATCH 3/8] drm/i915: extract set_pipe_timings " Paulo Zanoni
@ 2012-09-12 13:06 ` Paulo Zanoni
2012-09-12 14:12 ` Daniel Vetter
2012-09-12 13:06 ` [PATCH 5/8] drm/i915: extract set_m_n from ironlake_crtc_mode_set Paulo Zanoni
` (3 subsequent siblings)
7 siblings, 1 reply; 21+ messages in thread
From: Paulo Zanoni @ 2012-09-12 13:06 UTC (permalink / raw)
To: intel-gfx; +Cc: Paulo Zanoni
From: Paulo Zanoni <paulo.r.zanoni@intel.com>
Because declaring a variable in the beginning of the function, then
initializing it 100 lines later, then using it 100 lines later does
not make our code look good IMHO.
Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
---
drivers/gpu/drm/i915/intel_display.c | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 5a4e363..b657416 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4748,7 +4748,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
int plane = intel_crtc->plane;
int refclk, num_connectors = 0;
intel_clock_t clock, reduced_clock;
- u32 dpll, fp = 0, fp2 = 0, dspcntr;
+ u32 dpll, fp = 0, fp2 = 0;
bool ok, has_reduced_clock = false, is_sdvo = false;
bool is_crt = false, is_lvds = false, is_tv = false, is_dp = false;
struct intel_encoder *encoder, *edp_encoder = NULL;
@@ -4950,9 +4950,6 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
else
dpll |= PLL_REF_INPUT_DREFCLK;
- /* Set up the display plane register */
- dspcntr = DISPPLANE_GAMMA_ENABLE;
-
DRM_DEBUG_KMS("Mode for pipe %d:\n", pipe);
drm_mode_debug_printmodeline(mode);
@@ -5029,7 +5026,8 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
intel_wait_for_vblank(dev, pipe);
- I915_WRITE(DSPCNTR(plane), dspcntr);
+ /* Set up the display plane register */
+ I915_WRITE(DSPCNTR(plane), DISPPLANE_GAMMA_ENABLE);
POSTING_READ(DSPCNTR(plane));
ret = intel_pipe_set_base(crtc, x, y, fb);
--
1.7.10.4
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 5/8] drm/i915: extract set_m_n from ironlake_crtc_mode_set
2012-09-12 13:06 [PATCH 0/8] Rework ironlake_crtc_mode_set Paulo Zanoni
` (3 preceding siblings ...)
2012-09-12 13:06 ` [PATCH 4/8] drm/i915: simplify setting DSPCNTR inside ironlake_crtc_mode_set Paulo Zanoni
@ 2012-09-12 13:06 ` Paulo Zanoni
2012-09-12 14:20 ` Daniel Vetter
2012-09-12 13:06 ` [PATCH 6/8] drm/i915: extract compute_clocks " Paulo Zanoni
` (2 subsequent siblings)
7 siblings, 1 reply; 21+ messages in thread
From: Paulo Zanoni @ 2012-09-12 13:06 UTC (permalink / raw)
To: intel-gfx; +Cc: Paulo Zanoni
From: Paulo Zanoni <paulo.r.zanoni@intel.com>
The set_m_n code was spread all over the mode_set function.
Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
---
drivers/gpu/drm/i915/intel_display.c | 152 ++++++++++++++++++++--------------
1 file changed, 89 insertions(+), 63 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index b657416..8d3b9d6 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4735,6 +4735,92 @@ static void ironlake_set_pipe_timings(struct intel_crtc *intel_crtc,
((mode->hdisplay - 1) << 16) | (mode->vdisplay - 1));
}
+static void ironlake_set_m_n(struct drm_crtc *crtc,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
+{
+ struct drm_device *dev = crtc->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ enum pipe pipe = intel_crtc->pipe;
+ struct intel_encoder *intel_encoder, *edp_encoder = NULL;
+ struct fdi_m_n m_n = {0};
+ int target_clock, pixel_multiplier, lane, link_bw;
+ bool is_dp = false, is_cpu_edp = false;
+
+ for_each_encoder_on_crtc(dev, crtc, intel_encoder) {
+ switch (intel_encoder->type) {
+ case INTEL_OUTPUT_DISPLAYPORT:
+ is_dp = true;
+ break;
+ case INTEL_OUTPUT_EDP:
+ is_dp = true;
+ if (!intel_encoder_is_pch_edp(&intel_encoder->base))
+ is_cpu_edp = true;
+ edp_encoder = intel_encoder;
+ break;
+ }
+ }
+
+ /* FDI link */
+ pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode);
+ lane = 0;
+ /* CPU eDP doesn't require FDI link, so just set DP M/N
+ according to current link config */
+ if (is_cpu_edp) {
+ intel_edp_link_config(edp_encoder, &lane, &link_bw);
+ } else {
+ /* FDI is a binary signal running at ~2.7GHz, encoding
+ * each output octet as 10 bits. The actual frequency
+ * is stored as a divider into a 100MHz clock, and the
+ * mode pixel clock is stored in units of 1KHz.
+ * Hence the bw of each lane in terms of the mode signal
+ * is:
+ */
+ link_bw = intel_fdi_link_freq(dev) * MHz(100)/KHz(1)/10;
+ }
+
+ /* [e]DP over FDI requires target mode clock instead of link clock. */
+ if (edp_encoder)
+ target_clock = intel_edp_target_clock(edp_encoder, mode);
+ else if (is_dp)
+ target_clock = mode->clock;
+ else
+ target_clock = adjusted_mode->clock;
+
+ if (!lane) {
+ /*
+ * Account for spread spectrum to avoid
+ * oversubscribing the link. Max center spread
+ * is 2.5%; use 5% for safety's sake.
+ */
+ u32 bps = target_clock * intel_crtc->bpp * 21 / 20;
+ lane = bps / (link_bw * 8) + 1;
+ }
+
+ intel_crtc->fdi_lanes = lane;
+
+ if (pixel_multiplier > 1)
+ link_bw *= pixel_multiplier;
+
+ ironlake_compute_m_n(intel_crtc->bpp, lane, target_clock, link_bw,
+ &m_n);
+
+ if (is_dp && !is_cpu_edp) {
+ intel_dp_set_m_n(crtc, mode, adjusted_mode);
+ } else {
+ /* For non-DP output, clear any trans DP clock recovery setting.*/
+ I915_WRITE(TRANSDATA_M1(pipe), 0);
+ I915_WRITE(TRANSDATA_N1(pipe), 0);
+ I915_WRITE(TRANSDPLINK_M1(pipe), 0);
+ I915_WRITE(TRANSDPLINK_N1(pipe), 0);
+ }
+ I915_WRITE(PIPE_DATA_M1(pipe), TU_SIZE(m_n.tu) | m_n.gmch_m);
+ I915_WRITE(PIPE_DATA_N1(pipe), m_n.gmch_n);
+ I915_WRITE(PIPE_LINK_M1(pipe), m_n.link_m);
+ I915_WRITE(PIPE_LINK_N1(pipe), m_n.link_n);
+}
+
static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode,
@@ -4751,11 +4837,9 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
u32 dpll, fp = 0, fp2 = 0;
bool ok, has_reduced_clock = false, is_sdvo = false;
bool is_crt = false, is_lvds = false, is_tv = false, is_dp = false;
- struct intel_encoder *encoder, *edp_encoder = NULL;
+ struct intel_encoder *encoder;
const intel_limit_t *limit;
- int ret;
- struct fdi_m_n m_n = {0};
- int target_clock, pixel_multiplier, lane, link_bw, factor;
+ int ret, factor;
unsigned int pipe_bpp;
bool dither;
bool is_cpu_edp = false, is_pch_edp = false;
@@ -4786,7 +4870,6 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
is_pch_edp = true;
else
is_cpu_edp = true;
- edp_encoder = encoder;
break;
}
@@ -4828,33 +4911,6 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
if (is_sdvo && is_tv)
i9xx_adjust_sdvo_tv_clock(adjusted_mode, &clock);
-
- /* FDI link */
- pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode);
- lane = 0;
- /* CPU eDP doesn't require FDI link, so just set DP M/N
- according to current link config */
- if (is_cpu_edp) {
- intel_edp_link_config(edp_encoder, &lane, &link_bw);
- } else {
- /* FDI is a binary signal running at ~2.7GHz, encoding
- * each output octet as 10 bits. The actual frequency
- * is stored as a divider into a 100MHz clock, and the
- * mode pixel clock is stored in units of 1KHz.
- * Hence the bw of each lane in terms of the mode signal
- * is:
- */
- link_bw = intel_fdi_link_freq(dev) * MHz(100)/KHz(1)/10;
- }
-
- /* [e]DP over FDI requires target mode clock instead of link clock. */
- if (edp_encoder)
- target_clock = intel_edp_target_clock(edp_encoder, mode);
- else if (is_dp)
- target_clock = mode->clock;
- else
- target_clock = adjusted_mode->clock;
-
/* determine panel color depth */
dither = intel_choose_pipe_bpp_dither(crtc, fb, &pipe_bpp, mode);
if (is_lvds && dev_priv->lvds_dither)
@@ -4868,23 +4924,6 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
}
intel_crtc->bpp = pipe_bpp;
- if (!lane) {
- /*
- * Account for spread spectrum to avoid
- * oversubscribing the link. Max center spread
- * is 2.5%; use 5% for safety's sake.
- */
- u32 bps = target_clock * intel_crtc->bpp * 21 / 20;
- lane = bps / (link_bw * 8) + 1;
- }
-
- intel_crtc->fdi_lanes = lane;
-
- if (pixel_multiplier > 1)
- link_bw *= pixel_multiplier;
- ironlake_compute_m_n(intel_crtc->bpp, lane, target_clock, link_bw,
- &m_n);
-
fp = clock.n << 16 | clock.m1 << 8 | clock.m2;
if (has_reduced_clock)
fp2 = reduced_clock.n << 16 | reduced_clock.m1 << 8 |
@@ -4977,15 +5016,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
if (is_lvds)
ironlake_lvds_port_enable(intel_crtc, adjusted_mode, clock.p2);
- if (is_dp && !is_cpu_edp) {
- intel_dp_set_m_n(crtc, mode, adjusted_mode);
- } else {
- /* For non-DP output, clear any trans DP clock recovery setting.*/
- I915_WRITE(TRANSDATA_M1(pipe), 0);
- I915_WRITE(TRANSDATA_N1(pipe), 0);
- I915_WRITE(TRANSDPLINK_M1(pipe), 0);
- I915_WRITE(TRANSDPLINK_N1(pipe), 0);
- }
+ ironlake_set_m_n(crtc, mode, adjusted_mode);
if (intel_crtc->pch_pll) {
I915_WRITE(intel_crtc->pch_pll->pll_reg, dpll);
@@ -5014,11 +5045,6 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
ironlake_set_pipe_timings(intel_crtc, mode, adjusted_mode);
- I915_WRITE(PIPE_DATA_M1(pipe), TU_SIZE(m_n.tu) | m_n.gmch_m);
- I915_WRITE(PIPE_DATA_N1(pipe), m_n.gmch_n);
- I915_WRITE(PIPE_LINK_M1(pipe), m_n.link_m);
- I915_WRITE(PIPE_LINK_N1(pipe), m_n.link_n);
-
if (is_cpu_edp)
ironlake_set_pll_edp(crtc, adjusted_mode->clock);
--
1.7.10.4
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 6/8] drm/i915: extract compute_clocks from ironlake_crtc_mode_set
2012-09-12 13:06 [PATCH 0/8] Rework ironlake_crtc_mode_set Paulo Zanoni
` (4 preceding siblings ...)
2012-09-12 13:06 ` [PATCH 5/8] drm/i915: extract set_m_n from ironlake_crtc_mode_set Paulo Zanoni
@ 2012-09-12 13:06 ` Paulo Zanoni
2012-09-12 14:31 ` Daniel Vetter
2012-09-12 13:06 ` [PATCH 7/8] drm/i915: extract pch_pll_set " Paulo Zanoni
2012-09-12 13:06 ` [PATCH 8/8] drm/i915: remove unused variables " Paulo Zanoni
7 siblings, 1 reply; 21+ messages in thread
From: Paulo Zanoni @ 2012-09-12 13:06 UTC (permalink / raw)
To: intel-gfx; +Cc: Paulo Zanoni
From: Paulo Zanoni <paulo.r.zanoni@intel.com>
Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
---
drivers/gpu/drm/i915/intel_display.c | 95 +++++++++++++++++++++++-----------
1 file changed, 66 insertions(+), 29 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 8d3b9d6..dc4132a 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4821,6 +4821,69 @@ static void ironlake_set_m_n(struct drm_crtc *crtc,
I915_WRITE(PIPE_LINK_N1(pipe), m_n.link_n);
}
+static bool ironlake_compute_clocks(struct drm_crtc *crtc,
+ struct drm_display_mode *adjusted_mode,
+ intel_clock_t *clock,
+ bool *has_reduced_clock,
+ intel_clock_t *reduced_clock)
+{
+ struct drm_device *dev = crtc->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_encoder *intel_encoder;
+ int refclk;
+ const intel_limit_t *limit;
+ bool ret, is_sdvo = false, is_tv = false, is_lvds = false;
+
+ for_each_encoder_on_crtc(dev, crtc, intel_encoder) {
+ switch (intel_encoder->type) {
+ case INTEL_OUTPUT_LVDS:
+ is_lvds = true;
+ break;
+ case INTEL_OUTPUT_SDVO:
+ case INTEL_OUTPUT_HDMI:
+ is_sdvo = true;
+ if (intel_encoder->needs_tv_clock)
+ is_tv = true;
+ break;
+ case INTEL_OUTPUT_TVOUT:
+ is_tv = true;
+ break;
+ }
+ }
+
+ refclk = ironlake_get_refclk(crtc);
+
+ /*
+ * Returns a set of divisors for the desired target clock with the given
+ * refclk, or FALSE. The returned values represent the clock equation:
+ * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2.
+ */
+ limit = intel_limit(crtc, refclk);
+ ret = limit->find_pll(limit, crtc, adjusted_mode->clock, refclk, NULL,
+ clock);
+ if (!ret)
+ return false;
+
+ if (is_lvds && dev_priv->lvds_downclock_avail) {
+ /*
+ * Ensure we match the reduced clock's P to the target clock.
+ * If the clocks don't match, we can't switch the display clock
+ * by using the FP0/FP1. In such case we will disable the LVDS
+ * downclock feature.
+ */
+ *has_reduced_clock = limit->find_pll(limit, crtc,
+ dev_priv->lvds_downclock,
+ refclk,
+ clock,
+ reduced_clock);
+ }
+
+ if (is_sdvo && is_tv)
+ i9xx_adjust_sdvo_tv_clock(adjusted_mode, clock);
+
+ return true;
+}
+
static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode,
@@ -4832,13 +4895,12 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
int pipe = intel_crtc->pipe;
int plane = intel_crtc->plane;
- int refclk, num_connectors = 0;
+ int num_connectors = 0;
intel_clock_t clock, reduced_clock;
u32 dpll, fp = 0, fp2 = 0;
bool ok, has_reduced_clock = false, is_sdvo = false;
bool is_crt = false, is_lvds = false, is_tv = false, is_dp = false;
struct intel_encoder *encoder;
- const intel_limit_t *limit;
int ret, factor;
unsigned int pipe_bpp;
bool dither;
@@ -4876,16 +4938,8 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
num_connectors++;
}
- refclk = ironlake_get_refclk(crtc);
-
- /*
- * Returns a set of divisors for the desired target clock with the given
- * refclk, or FALSE. The returned values represent the clock equation:
- * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2.
- */
- limit = intel_limit(crtc, refclk);
- ok = limit->find_pll(limit, crtc, adjusted_mode->clock, refclk, NULL,
- &clock);
+ ok = ironlake_compute_clocks(crtc, adjusted_mode, &clock,
+ &has_reduced_clock, &reduced_clock);
if (!ok) {
DRM_ERROR("Couldn't find PLL settings for mode!\n");
return -EINVAL;
@@ -4894,23 +4948,6 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
/* Ensure that the cursor is valid for the new mode before changing... */
intel_crtc_update_cursor(crtc, true);
- if (is_lvds && dev_priv->lvds_downclock_avail) {
- /*
- * Ensure we match the reduced clock's P to the target clock.
- * If the clocks don't match, we can't switch the display clock
- * by using the FP0/FP1. In such case we will disable the LVDS
- * downclock feature.
- */
- has_reduced_clock = limit->find_pll(limit, crtc,
- dev_priv->lvds_downclock,
- refclk,
- &clock,
- &reduced_clock);
- }
-
- if (is_sdvo && is_tv)
- i9xx_adjust_sdvo_tv_clock(adjusted_mode, &clock);
-
/* determine panel color depth */
dither = intel_choose_pipe_bpp_dither(crtc, fb, &pipe_bpp, mode);
if (is_lvds && dev_priv->lvds_dither)
--
1.7.10.4
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 7/8] drm/i915: extract pch_pll_set from ironlake_crtc_mode_set
2012-09-12 13:06 [PATCH 0/8] Rework ironlake_crtc_mode_set Paulo Zanoni
` (5 preceding siblings ...)
2012-09-12 13:06 ` [PATCH 6/8] drm/i915: extract compute_clocks " Paulo Zanoni
@ 2012-09-12 13:06 ` Paulo Zanoni
2012-09-12 14:40 ` Daniel Vetter
2012-09-12 13:06 ` [PATCH 8/8] drm/i915: remove unused variables " Paulo Zanoni
7 siblings, 1 reply; 21+ messages in thread
From: Paulo Zanoni @ 2012-09-12 13:06 UTC (permalink / raw)
To: intel-gfx; +Cc: Paulo Zanoni
From: Paulo Zanoni <paulo.r.zanoni@intel.com>
This is all the code responsible for setting the PCH PLLs.
Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
---
drivers/gpu/drm/i915/intel_display.c | 260 ++++++++++++++++++++--------------
1 file changed, 153 insertions(+), 107 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index dc4132a..7ffbcfd 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4884,6 +4884,143 @@ static bool ironlake_compute_clocks(struct drm_crtc *crtc,
return true;
}
+static bool ironlake_pch_pll_set(struct drm_crtc *crtc,
+ struct drm_display_mode *adjusted_mode,
+ intel_clock_t *clock,
+ bool has_reduced_clock,
+ intel_clock_t *reduced_clock)
+{
+ struct drm_device *dev = crtc->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ struct intel_encoder *intel_encoder;
+ int num_connectors = 0;
+ u32 dpll, fp = 0, fp2 = 0;
+ int factor, pixel_multiplier;
+ struct intel_pch_pll *pll;
+ bool is_lvds = false, is_sdvo = false, is_tv = false;
+ bool is_dp = false, is_cpu_edp = false;
+
+ for_each_encoder_on_crtc(dev, crtc, intel_encoder) {
+ switch (intel_encoder->type) {
+ case INTEL_OUTPUT_LVDS:
+ is_lvds = true;
+ break;
+ case INTEL_OUTPUT_SDVO:
+ case INTEL_OUTPUT_HDMI:
+ is_sdvo = true;
+ if (intel_encoder->needs_tv_clock)
+ is_tv = true;
+ break;
+ case INTEL_OUTPUT_TVOUT:
+ is_tv = true;
+ break;
+ case INTEL_OUTPUT_DISPLAYPORT:
+ is_dp = true;
+ break;
+ case INTEL_OUTPUT_EDP:
+ is_dp = true;
+ if (!intel_encoder_is_pch_edp(&intel_encoder->base))
+ is_cpu_edp = true;
+ break;
+ }
+
+ num_connectors++;
+ }
+
+ fp = clock->n << 16 | clock->m1 << 8 | clock->m2;
+ if (has_reduced_clock)
+ fp2 = reduced_clock->n << 16 | reduced_clock->m1 << 8 |
+ reduced_clock->m2;
+
+ /* Enable autotuning of the PLL clock (if permissible) */
+ factor = 21;
+ if (is_lvds) {
+ if ((intel_panel_use_ssc(dev_priv) &&
+ dev_priv->lvds_ssc_freq == 100) ||
+ (I915_READ(PCH_LVDS) & LVDS_CLKB_POWER_MASK) == LVDS_CLKB_POWER_UP)
+ factor = 25;
+ } else if (is_sdvo && is_tv)
+ factor = 20;
+
+ if (clock->m < factor * clock->n)
+ fp |= FP_CB_TUNE;
+
+ dpll = 0;
+
+ if (is_lvds)
+ dpll |= DPLLB_MODE_LVDS;
+ else
+ dpll |= DPLLB_MODE_DAC_SERIAL;
+ if (is_sdvo) {
+ pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode);
+ if (pixel_multiplier > 1) {
+ dpll |= (pixel_multiplier - 1) << PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT;
+ }
+ dpll |= DPLL_DVO_HIGH_SPEED;
+ }
+ if (is_dp && !is_cpu_edp)
+ dpll |= DPLL_DVO_HIGH_SPEED;
+
+ /* compute bitmask from p1 value */
+ dpll |= (1 << (clock->p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT;
+ /* also FPA1 */
+ dpll |= (1 << (clock->p1 - 1)) << DPLL_FPA1_P1_POST_DIV_SHIFT;
+
+ switch (clock->p2) {
+ case 5:
+ dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_5;
+ break;
+ case 7:
+ dpll |= DPLLB_LVDS_P2_CLOCK_DIV_7;
+ break;
+ case 10:
+ dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_10;
+ break;
+ case 14:
+ dpll |= DPLLB_LVDS_P2_CLOCK_DIV_14;
+ break;
+ }
+
+ if (is_sdvo && is_tv)
+ dpll |= PLL_REF_INPUT_TVCLKINBC;
+ else if (is_tv)
+ /* XXX: just matching BIOS for now */
+ /* dpll |= PLL_REF_INPUT_TVCLKINBC; */
+ dpll |= 3;
+ else if (is_lvds && intel_panel_use_ssc(dev_priv) && num_connectors < 2)
+ dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN;
+ else
+ dpll |= PLL_REF_INPUT_DREFCLK;
+
+ pll = intel_get_pch_pll(intel_crtc, dpll, fp);
+ if (!pll)
+ return false;
+
+ I915_WRITE(intel_crtc->pch_pll->pll_reg, dpll);
+
+ /* Wait for the clocks to stabilize. */
+ POSTING_READ(intel_crtc->pch_pll->pll_reg);
+ udelay(150);
+
+ /* The pixel multiplier can only be updated once the
+ * DPLL is enabled and the clocks are stable.
+ *
+ * So write it again.
+ */
+ I915_WRITE(intel_crtc->pch_pll->pll_reg, dpll);
+
+ intel_crtc->lowfreq_avail = false;
+ if (is_lvds && has_reduced_clock && i915_powersave) {
+ I915_WRITE(intel_crtc->pch_pll->fp1_reg, fp2);
+ intel_crtc->lowfreq_avail = true;
+ } else {
+ I915_WRITE(intel_crtc->pch_pll->fp1_reg, fp);
+ }
+
+ return true;
+}
+
static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode,
@@ -4897,11 +5034,10 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
int plane = intel_crtc->plane;
int num_connectors = 0;
intel_clock_t clock, reduced_clock;
- u32 dpll, fp = 0, fp2 = 0;
bool ok, has_reduced_clock = false, is_sdvo = false;
bool is_crt = false, is_lvds = false, is_tv = false, is_dp = false;
struct intel_encoder *encoder;
- int ret, factor;
+ int ret;
unsigned int pipe_bpp;
bool dither;
bool is_cpu_edp = false, is_pch_edp = false;
@@ -4961,90 +5097,25 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
}
intel_crtc->bpp = pipe_bpp;
- fp = clock.n << 16 | clock.m1 << 8 | clock.m2;
- if (has_reduced_clock)
- fp2 = reduced_clock.n << 16 | reduced_clock.m1 << 8 |
- reduced_clock.m2;
-
- /* Enable autotuning of the PLL clock (if permissible) */
- factor = 21;
- if (is_lvds) {
- if ((intel_panel_use_ssc(dev_priv) &&
- dev_priv->lvds_ssc_freq == 100) ||
- (I915_READ(PCH_LVDS) & LVDS_CLKB_POWER_MASK) == LVDS_CLKB_POWER_UP)
- factor = 25;
- } else if (is_sdvo && is_tv)
- factor = 20;
-
- if (clock.m < factor * clock.n)
- fp |= FP_CB_TUNE;
-
- dpll = 0;
-
- if (is_lvds)
- dpll |= DPLLB_MODE_LVDS;
- else
- dpll |= DPLLB_MODE_DAC_SERIAL;
- if (is_sdvo) {
- int pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode);
- if (pixel_multiplier > 1) {
- dpll |= (pixel_multiplier - 1) << PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT;
- }
- dpll |= DPLL_DVO_HIGH_SPEED;
- }
- if (is_dp && !is_cpu_edp)
- dpll |= DPLL_DVO_HIGH_SPEED;
-
- /* compute bitmask from p1 value */
- dpll |= (1 << (clock.p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT;
- /* also FPA1 */
- dpll |= (1 << (clock.p1 - 1)) << DPLL_FPA1_P1_POST_DIV_SHIFT;
-
- switch (clock.p2) {
- case 5:
- dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_5;
- break;
- case 7:
- dpll |= DPLLB_LVDS_P2_CLOCK_DIV_7;
- break;
- case 10:
- dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_10;
- break;
- case 14:
- dpll |= DPLLB_LVDS_P2_CLOCK_DIV_14;
- break;
- }
-
- if (is_sdvo && is_tv)
- dpll |= PLL_REF_INPUT_TVCLKINBC;
- else if (is_tv)
- /* XXX: just matching BIOS for now */
- /* dpll |= PLL_REF_INPUT_TVCLKINBC; */
- dpll |= 3;
- else if (is_lvds && intel_panel_use_ssc(dev_priv) && num_connectors < 2)
- dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN;
- else
- dpll |= PLL_REF_INPUT_DREFCLK;
-
DRM_DEBUG_KMS("Mode for pipe %d:\n", pipe);
drm_mode_debug_printmodeline(mode);
- /* CPU eDP is the only output that doesn't need a PCH PLL of its own on
- * pre-Haswell/LPT generation */
- if (HAS_PCH_LPT(dev)) {
- DRM_DEBUG_KMS("LPT detected: no PLL for pipe %d necessary\n",
- pipe);
- } else if (!is_cpu_edp) {
- struct intel_pch_pll *pll;
-
- pll = intel_get_pch_pll(intel_crtc, dpll, fp);
- if (pll == NULL) {
- DRM_DEBUG_DRIVER("failed to find PLL for pipe %d\n",
- pipe);
- return -EINVAL;
+ if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)) {
+ /* CPU eDP is the only output that doesn't need a PCH PLL of its
+ * own */
+ if (is_cpu_edp) {
+ intel_put_pch_pll(intel_crtc);
+ } else {
+ ok = ironlake_pch_pll_set(crtc, adjusted_mode, &clock,
+ has_reduced_clock,
+ &reduced_clock);
+ if (!ok) {
+ DRM_ERROR("Failed to find PLL for pipe %d\n",
+ pipe);
+ return -EINVAL;
+ }
}
- } else
- intel_put_pch_pll(intel_crtc);
+ }
/* The LVDS pin pair needs to be on before the DPLLs are enabled.
* This is an exception to the general rule that mode_set doesn't turn
@@ -5055,31 +5126,6 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
ironlake_set_m_n(crtc, mode, adjusted_mode);
- if (intel_crtc->pch_pll) {
- I915_WRITE(intel_crtc->pch_pll->pll_reg, dpll);
-
- /* Wait for the clocks to stabilize. */
- POSTING_READ(intel_crtc->pch_pll->pll_reg);
- udelay(150);
-
- /* The pixel multiplier can only be updated once the
- * DPLL is enabled and the clocks are stable.
- *
- * So write it again.
- */
- I915_WRITE(intel_crtc->pch_pll->pll_reg, dpll);
- }
-
- intel_crtc->lowfreq_avail = false;
- if (intel_crtc->pch_pll) {
- if (is_lvds && has_reduced_clock && i915_powersave) {
- I915_WRITE(intel_crtc->pch_pll->fp1_reg, fp2);
- intel_crtc->lowfreq_avail = true;
- } else {
- I915_WRITE(intel_crtc->pch_pll->fp1_reg, fp);
- }
- }
-
ironlake_set_pipe_timings(intel_crtc, mode, adjusted_mode);
if (is_cpu_edp)
--
1.7.10.4
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 8/8] drm/i915: remove unused variables from ironlake_crtc_mode_set
2012-09-12 13:06 [PATCH 0/8] Rework ironlake_crtc_mode_set Paulo Zanoni
` (6 preceding siblings ...)
2012-09-12 13:06 ` [PATCH 7/8] drm/i915: extract pch_pll_set " Paulo Zanoni
@ 2012-09-12 13:06 ` Paulo Zanoni
7 siblings, 0 replies; 21+ messages in thread
From: Paulo Zanoni @ 2012-09-12 13:06 UTC (permalink / raw)
To: intel-gfx; +Cc: Paulo Zanoni
From: Paulo Zanoni <paulo.r.zanoni@intel.com>
They are actually set but not used [-Wunused-but-set-variable].
Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
---
drivers/gpu/drm/i915/intel_display.c | 25 +++----------------------
1 file changed, 3 insertions(+), 22 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 7ffbcfd..05339ef 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -5034,39 +5034,20 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
int plane = intel_crtc->plane;
int num_connectors = 0;
intel_clock_t clock, reduced_clock;
- bool ok, has_reduced_clock = false, is_sdvo = false;
- bool is_crt = false, is_lvds = false, is_tv = false, is_dp = false;
+ bool ok, has_reduced_clock = false;
+ bool is_lvds = false, is_cpu_edp = false;
struct intel_encoder *encoder;
int ret;
unsigned int pipe_bpp;
bool dither;
- bool is_cpu_edp = false, is_pch_edp = false;
for_each_encoder_on_crtc(dev, crtc, encoder) {
switch (encoder->type) {
case INTEL_OUTPUT_LVDS:
is_lvds = true;
break;
- case INTEL_OUTPUT_SDVO:
- case INTEL_OUTPUT_HDMI:
- is_sdvo = true;
- if (encoder->needs_tv_clock)
- is_tv = true;
- break;
- case INTEL_OUTPUT_TVOUT:
- is_tv = true;
- break;
- case INTEL_OUTPUT_ANALOG:
- is_crt = true;
- break;
- case INTEL_OUTPUT_DISPLAYPORT:
- is_dp = true;
- break;
case INTEL_OUTPUT_EDP:
- is_dp = true;
- if (intel_encoder_is_pch_edp(&encoder->base))
- is_pch_edp = true;
- else
+ if (!intel_encoder_is_pch_edp(&encoder->base))
is_cpu_edp = true;
break;
}
--
1.7.10.4
^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [PATCH 2/8] drm/i915: extract LVDS-specific code from ironlake_crtc_mode_set
2012-09-12 13:06 ` [PATCH 2/8] drm/i915: extract LVDS-specific code from ironlake_crtc_mode_set Paulo Zanoni
@ 2012-09-12 13:56 ` Daniel Vetter
0 siblings, 0 replies; 21+ messages in thread
From: Daniel Vetter @ 2012-09-12 13:56 UTC (permalink / raw)
To: Paulo Zanoni; +Cc: intel-gfx, Paulo Zanoni
On Wed, Sep 12, 2012 at 10:06:30AM -0300, Paulo Zanoni wrote:
> From: Paulo Zanoni <paulo.r.zanoni@intel.com>
>
> A next step would be to move this code to some of the encoder-specific
> callbacks. But really, moving the function away is certainly the first
> step.
>
> Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
I have a slightly more ambitious version of this in my modeset-rework
branch - it also consolidates the lvds port enabling with the pre-pch code
and encapsulates it within a new encoder->pre_pll_enable callback. Since
this is part of a larger rework of how we handle clock settings that I'm
toying around with, I'd like to keep things as-is for now.
-Daniel
> ---
> drivers/gpu/drm/i915/intel_display.c | 37 ++---------------------------
> drivers/gpu/drm/i915/intel_drv.h | 3 +++
> drivers/gpu/drm/i915/intel_lvds.c | 43 ++++++++++++++++++++++++++++++++++
> 3 files changed, 48 insertions(+), 35 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 244bce6..cf1e628 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -4710,7 +4710,6 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
> const intel_limit_t *limit;
> int ret;
> struct fdi_m_n m_n = {0};
> - u32 temp;
> int target_clock, pixel_multiplier, lane, link_bw, factor;
> unsigned int pipe_bpp;
> bool dither;
> @@ -4933,40 +4932,8 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
> * This is an exception to the general rule that mode_set doesn't turn
> * things on.
> */
> - if (is_lvds) {
> - temp = I915_READ(PCH_LVDS);
> - temp |= LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP;
> - if (HAS_PCH_CPT(dev)) {
> - temp &= ~PORT_TRANS_SEL_MASK;
> - temp |= PORT_TRANS_SEL_CPT(pipe);
> - } else {
> - if (pipe == 1)
> - temp |= LVDS_PIPEB_SELECT;
> - else
> - temp &= ~LVDS_PIPEB_SELECT;
> - }
> -
> - /* set the corresponsding LVDS_BORDER bit */
> - temp |= dev_priv->lvds_border_bits;
> - /* Set the B0-B3 data pairs corresponding to whether we're going to
> - * set the DPLLs for dual-channel mode or not.
> - */
> - if (clock.p2 == 7)
> - temp |= LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP;
> - else
> - temp &= ~(LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP);
> -
> - /* It would be nice to set 24 vs 18-bit mode (LVDS_A3_POWER_UP)
> - * appropriately here, but we need to look more thoroughly into how
> - * panels behave in the two modes.
> - */
> - temp &= ~(LVDS_HSYNC_POLARITY | LVDS_VSYNC_POLARITY);
> - if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC)
> - temp |= LVDS_HSYNC_POLARITY;
> - if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC)
> - temp |= LVDS_VSYNC_POLARITY;
> - I915_WRITE(PCH_LVDS, temp);
> - }
> + if (is_lvds)
> + ironlake_lvds_port_enable(intel_crtc, adjusted_mode, clock.p2);
>
> if (is_dp && !is_cpu_edp) {
> intel_dp_set_m_n(crtc, mode, adjusted_mode);
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 4f2b2d6..0b71f6c 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -412,6 +412,9 @@ extern void intel_mark_idle(struct drm_device *dev);
> extern void intel_mark_fb_busy(struct drm_i915_gem_object *obj);
> extern void intel_mark_fb_idle(struct drm_i915_gem_object *obj);
> extern bool intel_lvds_init(struct drm_device *dev);
> +extern void ironlake_lvds_port_enable(struct intel_crtc *intel_crtc,
> + struct drm_display_mode *adjusted_mode,
> + int clock_p2);
> extern void intel_dp_init(struct drm_device *dev, int output_reg,
> enum port port);
> void
> diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
> index 5646895..e418d95 100644
> --- a/drivers/gpu/drm/i915/intel_lvds.c
> +++ b/drivers/gpu/drm/i915/intel_lvds.c
> @@ -587,6 +587,49 @@ static int intel_lvds_set_property(struct drm_connector *connector,
> return 0;
> }
>
> +void ironlake_lvds_port_enable(struct intel_crtc *intel_crtc,
> + struct drm_display_mode *adjusted_mode,
> + int clock_p2)
> +{
> + struct drm_device *dev = intel_crtc->base.dev;
> + struct drm_i915_private *dev_priv = dev->dev_private;
> + enum pipe pipe = intel_crtc->pipe;
> + uint32_t temp;
> +
> + temp = I915_READ(PCH_LVDS);
> + temp |= LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP;
> + if (HAS_PCH_CPT(dev)) {
> + temp &= ~PORT_TRANS_SEL_MASK;
> + temp |= PORT_TRANS_SEL_CPT(pipe);
> + } else {
> + if (pipe == 1)
> + temp |= LVDS_PIPEB_SELECT;
> + else
> + temp &= ~LVDS_PIPEB_SELECT;
> + }
> +
> + /* set the corresponsding LVDS_BORDER bit */
> + temp |= dev_priv->lvds_border_bits;
> + /* Set the B0-B3 data pairs corresponding to whether we're going to
> + * set the DPLLs for dual-channel mode or not.
> + */
> + if (clock_p2 == 7)
> + temp |= LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP;
> + else
> + temp &= ~(LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP);
> +
> + /* It would be nice to set 24 vs 18-bit mode (LVDS_A3_POWER_UP)
> + * appropriately here, but we need to look more thoroughly into how
> + * panels behave in the two modes.
> + */
> + temp &= ~(LVDS_HSYNC_POLARITY | LVDS_VSYNC_POLARITY);
> + if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC)
> + temp |= LVDS_HSYNC_POLARITY;
> + if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC)
> + temp |= LVDS_VSYNC_POLARITY;
> + I915_WRITE(PCH_LVDS, temp);
> +}
> +
> static const struct drm_encoder_helper_funcs intel_lvds_helper_funcs = {
> .mode_fixup = intel_lvds_mode_fixup,
> .mode_set = intel_lvds_mode_set,
> --
> 1.7.10.4
>
> _______________________________________________
> 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
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 1/8] drm/i915: extract ironlake_set_pipeconf form ironlake_crtc_mode_set
2012-09-12 13:06 ` [PATCH 1/8] drm/i915: extract ironlake_set_pipeconf form ironlake_crtc_mode_set Paulo Zanoni
@ 2012-09-12 14:03 ` Daniel Vetter
0 siblings, 0 replies; 21+ messages in thread
From: Daniel Vetter @ 2012-09-12 14:03 UTC (permalink / raw)
To: Paulo Zanoni; +Cc: intel-gfx, Paulo Zanoni
On Wed, Sep 12, 2012 at 10:06:29AM -0300, Paulo Zanoni wrote:
> From: Paulo Zanoni <paulo.r.zanoni@intel.com>
>
> Because ironlake_crtc_mode_set is a giant function that used to have
> 404 lines. Let's try to make it less complex/confusing.
>
> Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
> ---
> drivers/gpu/drm/i915/intel_display.c | 88 ++++++++++++++++++++--------------
> 1 file changed, 52 insertions(+), 36 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index e061acd..244bce6 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -4646,6 +4646,50 @@ static int ironlake_get_refclk(struct drm_crtc *crtc)
> return 120000;
> }
>
> +static void ironlake_set_pipeconf(struct drm_crtc *crtc,
> + struct drm_display_mode *adjusted_mode,
> + bool dither)
> +{
> + struct drm_i915_private *dev_priv = crtc->dev->dev_private;
> + struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> + int pipe = intel_crtc->pipe;
> + uint32_t val;
> +
> + val = I915_READ(PIPECONF(pipe));
> +
> + val &= ~PIPE_BPC_MASK;
> + switch (intel_crtc->bpp) {
> + case 18:
> + val |= PIPE_6BPC;
> + break;
> + case 24:
> + val |= PIPE_8BPC;
> + break;
> + case 30:
> + val |= PIPE_10BPC;
> + break;
> + case 36:
> + val |= PIPE_12BPC;
> + break;
> + default:
> + val |= PIPE_8BPC;
> + break;
> + }
> +
> + val &= ~(PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_MASK);
> + if (dither)
> + val |= (PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_SP);
> +
> + val &= ~PIPECONF_INTERLACE_MASK;
> + if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
> + val |= PIPECONF_INTERLACED_ILK;
> + else
> + val |= PIPECONF_PROGRESSIVE;
> +
> + I915_WRITE(PIPECONF(pipe), val);
> + POSTING_READ(PIPECONF(pipe));
> +}
> +
> static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
> struct drm_display_mode *mode,
> struct drm_display_mode *adjusted_mode,
> @@ -4659,7 +4703,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
> int plane = intel_crtc->plane;
> int refclk, num_connectors = 0;
> intel_clock_t clock, reduced_clock;
> - u32 dpll, fp = 0, fp2 = 0, dspcntr, pipeconf;
> + u32 dpll, fp = 0, fp2 = 0, dspcntr;
> bool ok, has_reduced_clock = false, is_sdvo = false;
> bool is_crt = false, is_lvds = false, is_tv = false, is_dp = false;
> struct intel_encoder *encoder, *edp_encoder = NULL;
> @@ -4768,32 +4812,17 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
> target_clock = adjusted_mode->clock;
>
> /* determine panel color depth */
> - temp = I915_READ(PIPECONF(pipe));
> - temp &= ~PIPE_BPC_MASK;
> dither = intel_choose_pipe_bpp_dither(crtc, fb, &pipe_bpp, mode);
> - switch (pipe_bpp) {
> - case 18:
> - temp |= PIPE_6BPC;
> - break;
> - case 24:
> - temp |= PIPE_8BPC;
> - break;
> - case 30:
> - temp |= PIPE_10BPC;
> - break;
> - case 36:
> - temp |= PIPE_12BPC;
> - break;
> - default:
> + if (is_lvds && dev_priv->lvds_dither)
> + dither = true;
> +
> + if (pipe_bpp != 18 && pipe_bpp != 24 && pipe_bpp != 30 &&
> + pipe_bpp != 36) {
> WARN(1, "intel_choose_pipe_bpp returned invalid value %d\n",
> - pipe_bpp);
> - temp |= PIPE_8BPC;
> + pipe_bpp);
> pipe_bpp = 24;
> - break;
choose_pipe_bpp_dither already has this fallback code and we duplicate
things here, again. Can you follow up with a 2nd patch to rip this out and
add a BUG(); to the new ilk_set_pipeconf function for the default: bpp
case and directly store the bpp in intel_crtc->bpp?
Patch looks good, applied.
-Daniel
> }
> -
> intel_crtc->bpp = pipe_bpp;
> - I915_WRITE(PIPECONF(pipe), temp);
>
> if (!lane) {
> /*
> @@ -4877,9 +4906,6 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
> else
> dpll |= PLL_REF_INPUT_DREFCLK;
>
> - /* setup pipeconf */
> - pipeconf = I915_READ(PIPECONF(pipe));
> -
> /* Set up the display plane register */
> dspcntr = DISPPLANE_GAMMA_ENABLE;
>
> @@ -4942,12 +4968,6 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
> I915_WRITE(PCH_LVDS, temp);
> }
>
> - pipeconf &= ~PIPECONF_DITHER_EN;
> - pipeconf &= ~PIPECONF_DITHER_TYPE_MASK;
> - if ((is_lvds && dev_priv->lvds_dither) || dither) {
> - pipeconf |= PIPECONF_DITHER_EN;
> - pipeconf |= PIPECONF_DITHER_TYPE_SP;
> - }
> if (is_dp && !is_cpu_edp) {
> intel_dp_set_m_n(crtc, mode, adjusted_mode);
> } else {
> @@ -4983,9 +5003,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
> }
> }
>
> - pipeconf &= ~PIPECONF_INTERLACE_MASK;
> if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
> - pipeconf |= PIPECONF_INTERLACED_ILK;
> /* the chip adds 2 halflines automatically */
> adjusted_mode->crtc_vtotal -= 1;
> adjusted_mode->crtc_vblank_end -= 1;
> @@ -4993,7 +5011,6 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
> adjusted_mode->crtc_hsync_start
> - adjusted_mode->crtc_htotal/2);
> } else {
> - pipeconf |= PIPECONF_PROGRESSIVE;
> I915_WRITE(VSYNCSHIFT(pipe), 0);
> }
>
> @@ -5031,8 +5048,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
> if (is_cpu_edp)
> ironlake_set_pll_edp(crtc, adjusted_mode->clock);
>
> - I915_WRITE(PIPECONF(pipe), pipeconf);
> - POSTING_READ(PIPECONF(pipe));
> + ironlake_set_pipeconf(crtc, adjusted_mode, dither);
>
> intel_wait_for_vblank(dev, pipe);
>
> --
> 1.7.10.4
>
> _______________________________________________
> 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
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 3/8] drm/i915: extract set_pipe_timings from ironlake_crtc_mode_set
2012-09-12 13:06 ` [PATCH 3/8] drm/i915: extract set_pipe_timings " Paulo Zanoni
@ 2012-09-12 14:11 ` Daniel Vetter
2012-09-19 18:11 ` Paulo Zanoni
0 siblings, 1 reply; 21+ messages in thread
From: Daniel Vetter @ 2012-09-12 14:11 UTC (permalink / raw)
To: Paulo Zanoni; +Cc: intel-gfx, Paulo Zanoni
On Wed, Sep 12, 2012 at 10:06:31AM -0300, Paulo Zanoni wrote:
> From: Paulo Zanoni <paulo.r.zanoni@intel.com>
>
> Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
Hm, I think we should extract the same code from i9xx_crtc_set_mode, too
and share it in a common intel_set_pipe_timings. Their almost identical
safe for:
- vsyncshift is only gen4+
- source position handling is a bit different, but I think it'd be
semantically clearer if we leave that out of set_pipe_timings. Imo that
belongs to the panel fitter settings, which are currently splattered all
over. Meh.
Comments?
-Daniel
> ---
> drivers/gpu/drm/i915/intel_display.c | 82 +++++++++++++++++++---------------
> 1 file changed, 46 insertions(+), 36 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index cf1e628..5a4e363 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -4690,6 +4690,51 @@ static void ironlake_set_pipeconf(struct drm_crtc *crtc,
> POSTING_READ(PIPECONF(pipe));
> }
>
> +static void ironlake_set_pipe_timings(struct intel_crtc *intel_crtc,
> + struct drm_display_mode *mode,
> + struct drm_display_mode *adjusted_mode)
> +{
> + struct drm_i915_private *dev_priv = intel_crtc->base.dev->dev_private;
> + enum pipe pipe = intel_crtc->pipe;
> +
> + if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
> + /* the chip adds 2 halflines automatically */
> + adjusted_mode->crtc_vtotal -= 1;
> + adjusted_mode->crtc_vblank_end -= 1;
> + I915_WRITE(VSYNCSHIFT(pipe),
> + adjusted_mode->crtc_hsync_start
> + - adjusted_mode->crtc_htotal/2);
> + } else {
> + I915_WRITE(VSYNCSHIFT(pipe), 0);
> + }
> +
> + I915_WRITE(HTOTAL(pipe),
> + (adjusted_mode->crtc_hdisplay - 1) |
> + ((adjusted_mode->crtc_htotal - 1) << 16));
> + I915_WRITE(HBLANK(pipe),
> + (adjusted_mode->crtc_hblank_start - 1) |
> + ((adjusted_mode->crtc_hblank_end - 1) << 16));
> + I915_WRITE(HSYNC(pipe),
> + (adjusted_mode->crtc_hsync_start - 1) |
> + ((adjusted_mode->crtc_hsync_end - 1) << 16));
> +
> + I915_WRITE(VTOTAL(pipe),
> + (adjusted_mode->crtc_vdisplay - 1) |
> + ((adjusted_mode->crtc_vtotal - 1) << 16));
> + I915_WRITE(VBLANK(pipe),
> + (adjusted_mode->crtc_vblank_start - 1) |
> + ((adjusted_mode->crtc_vblank_end - 1) << 16));
> + I915_WRITE(VSYNC(pipe),
> + (adjusted_mode->crtc_vsync_start - 1) |
> + ((adjusted_mode->crtc_vsync_end - 1) << 16));
> +
> + /* pipesrc controls the size that is scaled from, which should
> + * always be the user's requested size.
> + */
> + I915_WRITE(PIPESRC(pipe),
> + ((mode->hdisplay - 1) << 16) | (mode->vdisplay - 1));
> +}
> +
> static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
> struct drm_display_mode *mode,
> struct drm_display_mode *adjusted_mode,
> @@ -4970,42 +5015,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
> }
> }
>
> - if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
> - /* the chip adds 2 halflines automatically */
> - adjusted_mode->crtc_vtotal -= 1;
> - adjusted_mode->crtc_vblank_end -= 1;
> - I915_WRITE(VSYNCSHIFT(pipe),
> - adjusted_mode->crtc_hsync_start
> - - adjusted_mode->crtc_htotal/2);
> - } else {
> - I915_WRITE(VSYNCSHIFT(pipe), 0);
> - }
> -
> - I915_WRITE(HTOTAL(pipe),
> - (adjusted_mode->crtc_hdisplay - 1) |
> - ((adjusted_mode->crtc_htotal - 1) << 16));
> - I915_WRITE(HBLANK(pipe),
> - (adjusted_mode->crtc_hblank_start - 1) |
> - ((adjusted_mode->crtc_hblank_end - 1) << 16));
> - I915_WRITE(HSYNC(pipe),
> - (adjusted_mode->crtc_hsync_start - 1) |
> - ((adjusted_mode->crtc_hsync_end - 1) << 16));
> -
> - I915_WRITE(VTOTAL(pipe),
> - (adjusted_mode->crtc_vdisplay - 1) |
> - ((adjusted_mode->crtc_vtotal - 1) << 16));
> - I915_WRITE(VBLANK(pipe),
> - (adjusted_mode->crtc_vblank_start - 1) |
> - ((adjusted_mode->crtc_vblank_end - 1) << 16));
> - I915_WRITE(VSYNC(pipe),
> - (adjusted_mode->crtc_vsync_start - 1) |
> - ((adjusted_mode->crtc_vsync_end - 1) << 16));
> -
> - /* pipesrc controls the size that is scaled from, which should
> - * always be the user's requested size.
> - */
> - I915_WRITE(PIPESRC(pipe),
> - ((mode->hdisplay - 1) << 16) | (mode->vdisplay - 1));
> + ironlake_set_pipe_timings(intel_crtc, mode, adjusted_mode);
>
> I915_WRITE(PIPE_DATA_M1(pipe), TU_SIZE(m_n.tu) | m_n.gmch_m);
> I915_WRITE(PIPE_DATA_N1(pipe), m_n.gmch_n);
> --
> 1.7.10.4
>
> _______________________________________________
> 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
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 4/8] drm/i915: simplify setting DSPCNTR inside ironlake_crtc_mode_set
2012-09-12 13:06 ` [PATCH 4/8] drm/i915: simplify setting DSPCNTR inside ironlake_crtc_mode_set Paulo Zanoni
@ 2012-09-12 14:12 ` Daniel Vetter
0 siblings, 0 replies; 21+ messages in thread
From: Daniel Vetter @ 2012-09-12 14:12 UTC (permalink / raw)
To: Paulo Zanoni; +Cc: intel-gfx, Paulo Zanoni
On Wed, Sep 12, 2012 at 10:06:32AM -0300, Paulo Zanoni wrote:
> From: Paulo Zanoni <paulo.r.zanoni@intel.com>
>
> Because declaring a variable in the beginning of the function, then
> initializing it 100 lines later, then using it 100 lines later does
> not make our code look good IMHO.
>
> Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
Queued for -next, thanks for the patch. I've checked the gmch code and
there we have a few more bits (specifically pipe selection on gen2/3).
-Daniel
> ---
> drivers/gpu/drm/i915/intel_display.c | 8 +++-----
> 1 file changed, 3 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 5a4e363..b657416 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -4748,7 +4748,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
> int plane = intel_crtc->plane;
> int refclk, num_connectors = 0;
> intel_clock_t clock, reduced_clock;
> - u32 dpll, fp = 0, fp2 = 0, dspcntr;
> + u32 dpll, fp = 0, fp2 = 0;
> bool ok, has_reduced_clock = false, is_sdvo = false;
> bool is_crt = false, is_lvds = false, is_tv = false, is_dp = false;
> struct intel_encoder *encoder, *edp_encoder = NULL;
> @@ -4950,9 +4950,6 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
> else
> dpll |= PLL_REF_INPUT_DREFCLK;
>
> - /* Set up the display plane register */
> - dspcntr = DISPPLANE_GAMMA_ENABLE;
> -
> DRM_DEBUG_KMS("Mode for pipe %d:\n", pipe);
> drm_mode_debug_printmodeline(mode);
>
> @@ -5029,7 +5026,8 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
>
> intel_wait_for_vblank(dev, pipe);
>
> - I915_WRITE(DSPCNTR(plane), dspcntr);
> + /* Set up the display plane register */
> + I915_WRITE(DSPCNTR(plane), DISPPLANE_GAMMA_ENABLE);
> POSTING_READ(DSPCNTR(plane));
>
> ret = intel_pipe_set_base(crtc, x, y, fb);
> --
> 1.7.10.4
>
> _______________________________________________
> 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
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 5/8] drm/i915: extract set_m_n from ironlake_crtc_mode_set
2012-09-12 13:06 ` [PATCH 5/8] drm/i915: extract set_m_n from ironlake_crtc_mode_set Paulo Zanoni
@ 2012-09-12 14:20 ` Daniel Vetter
0 siblings, 0 replies; 21+ messages in thread
From: Daniel Vetter @ 2012-09-12 14:20 UTC (permalink / raw)
To: Paulo Zanoni; +Cc: intel-gfx, Paulo Zanoni
On Wed, Sep 12, 2012 at 10:06:33AM -0300, Paulo Zanoni wrote:
> From: Paulo Zanoni <paulo.r.zanoni@intel.com>
>
> The set_m_n code was spread all over the mode_set function.
>
> Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
> ---
> drivers/gpu/drm/i915/intel_display.c | 152 ++++++++++++++++++++--------------
> 1 file changed, 89 insertions(+), 63 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index b657416..8d3b9d6 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -4735,6 +4735,92 @@ static void ironlake_set_pipe_timings(struct intel_crtc *intel_crtc,
> ((mode->hdisplay - 1) << 16) | (mode->vdisplay - 1));
> }
>
> +static void ironlake_set_m_n(struct drm_crtc *crtc,
> + struct drm_display_mode *mode,
> + struct drm_display_mode *adjusted_mode)
> +{
> + struct drm_device *dev = crtc->dev;
> + struct drm_i915_private *dev_priv = dev->dev_private;
> + struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> + enum pipe pipe = intel_crtc->pipe;
> + struct intel_encoder *intel_encoder, *edp_encoder = NULL;
> + struct fdi_m_n m_n = {0};
> + int target_clock, pixel_multiplier, lane, link_bw;
> + bool is_dp = false, is_cpu_edp = false;
> +
> + for_each_encoder_on_crtc(dev, crtc, intel_encoder) {
> + switch (intel_encoder->type) {
> + case INTEL_OUTPUT_DISPLAYPORT:
> + is_dp = true;
> + break;
> + case INTEL_OUTPUT_EDP:
> + is_dp = true;
> + if (!intel_encoder_is_pch_edp(&intel_encoder->base))
> + is_cpu_edp = true;
> + edp_encoder = intel_encoder;
> + break;
> + }
> + }
> +
> + /* FDI link */
> + pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode);
> + lane = 0;
> + /* CPU eDP doesn't require FDI link, so just set DP M/N
> + according to current link config */
> + if (is_cpu_edp) {
> + intel_edp_link_config(edp_encoder, &lane, &link_bw);
> + } else {
> + /* FDI is a binary signal running at ~2.7GHz, encoding
> + * each output octet as 10 bits. The actual frequency
> + * is stored as a divider into a 100MHz clock, and the
> + * mode pixel clock is stored in units of 1KHz.
> + * Hence the bw of each lane in terms of the mode signal
> + * is:
> + */
> + link_bw = intel_fdi_link_freq(dev) * MHz(100)/KHz(1)/10;
> + }
> +
> + /* [e]DP over FDI requires target mode clock instead of link clock. */
> + if (edp_encoder)
> + target_clock = intel_edp_target_clock(edp_encoder, mode);
> + else if (is_dp)
> + target_clock = mode->clock;
> + else
> + target_clock = adjusted_mode->clock;
> +
> + if (!lane) {
> + /*
> + * Account for spread spectrum to avoid
> + * oversubscribing the link. Max center spread
> + * is 2.5%; use 5% for safety's sake.
> + */
> + u32 bps = target_clock * intel_crtc->bpp * 21 / 20;
> + lane = bps / (link_bw * 8) + 1;
> + }
> +
> + intel_crtc->fdi_lanes = lane;
> +
> + if (pixel_multiplier > 1)
> + link_bw *= pixel_multiplier;
> +
> + ironlake_compute_m_n(intel_crtc->bpp, lane, target_clock, link_bw,
> + &m_n);
> +
> + if (is_dp && !is_cpu_edp) {
> + intel_dp_set_m_n(crtc, mode, adjusted_mode);
> + } else {
> + /* For non-DP output, clear any trans DP clock recovery setting.*/
> + I915_WRITE(TRANSDATA_M1(pipe), 0);
> + I915_WRITE(TRANSDATA_N1(pipe), 0);
> + I915_WRITE(TRANSDPLINK_M1(pipe), 0);
> + I915_WRITE(TRANSDPLINK_N1(pipe), 0);
> + }
The pch DP transcoder m/n values are imo encoder-specific state - I'm
toying around with ideas to shovel this into encoder callbacks, similarly
to the lvds port enabling. Hence ...
[pls scroll down.]
> + I915_WRITE(PIPE_DATA_M1(pipe), TU_SIZE(m_n.tu) | m_n.gmch_m);
> + I915_WRITE(PIPE_DATA_N1(pipe), m_n.gmch_n);
> + I915_WRITE(PIPE_LINK_M1(pipe), m_n.link_m);
> + I915_WRITE(PIPE_LINK_N1(pipe), m_n.link_n);
> +}
> +
> static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
> struct drm_display_mode *mode,
> struct drm_display_mode *adjusted_mode,
> @@ -4751,11 +4837,9 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
> u32 dpll, fp = 0, fp2 = 0;
> bool ok, has_reduced_clock = false, is_sdvo = false;
> bool is_crt = false, is_lvds = false, is_tv = false, is_dp = false;
> - struct intel_encoder *encoder, *edp_encoder = NULL;
> + struct intel_encoder *encoder;
> const intel_limit_t *limit;
> - int ret;
> - struct fdi_m_n m_n = {0};
> - int target_clock, pixel_multiplier, lane, link_bw, factor;
> + int ret, factor;
> unsigned int pipe_bpp;
> bool dither;
> bool is_cpu_edp = false, is_pch_edp = false;
> @@ -4786,7 +4870,6 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
> is_pch_edp = true;
> else
> is_cpu_edp = true;
> - edp_encoder = encoder;
> break;
> }
>
> @@ -4828,33 +4911,6 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
> if (is_sdvo && is_tv)
> i9xx_adjust_sdvo_tv_clock(adjusted_mode, &clock);
>
> -
> - /* FDI link */
> - pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode);
> - lane = 0;
> - /* CPU eDP doesn't require FDI link, so just set DP M/N
> - according to current link config */
> - if (is_cpu_edp) {
> - intel_edp_link_config(edp_encoder, &lane, &link_bw);
> - } else {
> - /* FDI is a binary signal running at ~2.7GHz, encoding
> - * each output octet as 10 bits. The actual frequency
> - * is stored as a divider into a 100MHz clock, and the
> - * mode pixel clock is stored in units of 1KHz.
> - * Hence the bw of each lane in terms of the mode signal
> - * is:
> - */
> - link_bw = intel_fdi_link_freq(dev) * MHz(100)/KHz(1)/10;
> - }
> -
> - /* [e]DP over FDI requires target mode clock instead of link clock. */
> - if (edp_encoder)
> - target_clock = intel_edp_target_clock(edp_encoder, mode);
> - else if (is_dp)
> - target_clock = mode->clock;
> - else
> - target_clock = adjusted_mode->clock;
> -
> /* determine panel color depth */
> dither = intel_choose_pipe_bpp_dither(crtc, fb, &pipe_bpp, mode);
> if (is_lvds && dev_priv->lvds_dither)
> @@ -4868,23 +4924,6 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
> }
> intel_crtc->bpp = pipe_bpp;
>
> - if (!lane) {
> - /*
> - * Account for spread spectrum to avoid
> - * oversubscribing the link. Max center spread
> - * is 2.5%; use 5% for safety's sake.
> - */
> - u32 bps = target_clock * intel_crtc->bpp * 21 / 20;
> - lane = bps / (link_bw * 8) + 1;
> - }
> -
> - intel_crtc->fdi_lanes = lane;
> -
> - if (pixel_multiplier > 1)
> - link_bw *= pixel_multiplier;
> - ironlake_compute_m_n(intel_crtc->bpp, lane, target_clock, link_bw,
> - &m_n);
> -
> fp = clock.n << 16 | clock.m1 << 8 | clock.m2;
> if (has_reduced_clock)
> fp2 = reduced_clock.n << 16 | reduced_clock.m1 << 8 |
> @@ -4977,15 +5016,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
> if (is_lvds)
> ironlake_lvds_port_enable(intel_crtc, adjusted_mode, clock.p2);
>
> - if (is_dp && !is_cpu_edp) {
> - intel_dp_set_m_n(crtc, mode, adjusted_mode);
> - } else {
> - /* For non-DP output, clear any trans DP clock recovery setting.*/
> - I915_WRITE(TRANSDATA_M1(pipe), 0);
> - I915_WRITE(TRANSDATA_N1(pipe), 0);
> - I915_WRITE(TRANSDPLINK_M1(pipe), 0);
> - I915_WRITE(TRANSDPLINK_N1(pipe), 0);
> - }
> + ironlake_set_m_n(crtc, mode, adjusted_mode);
... I think we should leave this here for now ...
>
> if (intel_crtc->pch_pll) {
> I915_WRITE(intel_crtc->pch_pll->pll_reg, dpll);
> @@ -5014,11 +5045,6 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
>
> ironlake_set_pipe_timings(intel_crtc, mode, adjusted_mode);
>
> - I915_WRITE(PIPE_DATA_M1(pipe), TU_SIZE(m_n.tu) | m_n.gmch_m);
> - I915_WRITE(PIPE_DATA_N1(pipe), m_n.gmch_n);
> - I915_WRITE(PIPE_LINK_M1(pipe), m_n.link_m);
> - I915_WRITE(PIPE_LINK_N1(pipe), m_n.link_n);
... and instead move the new ironlake_set_m_n call to this place - that
way we don't change anything in the register write sequence, too. And
somehow changing the register write sequence bites us every time we try :(
Also, I'm hunting a strange dp dpms issue on ilk/gm45 currently and I
suspect (without any evidence). So I prefer we're extra careful around dp
state for now.
Otherwise this looks nice.
-Daniel
> -
> if (is_cpu_edp)
> ironlake_set_pll_edp(crtc, adjusted_mode->clock);
>
> --
> 1.7.10.4
>
> _______________________________________________
> 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
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 6/8] drm/i915: extract compute_clocks from ironlake_crtc_mode_set
2012-09-12 13:06 ` [PATCH 6/8] drm/i915: extract compute_clocks " Paulo Zanoni
@ 2012-09-12 14:31 ` Daniel Vetter
2012-09-12 14:34 ` Daniel Vetter
0 siblings, 1 reply; 21+ messages in thread
From: Daniel Vetter @ 2012-09-12 14:31 UTC (permalink / raw)
To: Paulo Zanoni; +Cc: intel-gfx, Paulo Zanoni
On Wed, Sep 12, 2012 at 10:06:34AM -0300, Paulo Zanoni wrote:
> From: Paulo Zanoni <paulo.r.zanoni@intel.com>
>
> Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
Queued for -next, thanks for the patch. I've needed to resolve some
conflicts since I didn't pick up all previous patches, but nothing to
onerous.
-Daniel
--
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 6/8] drm/i915: extract compute_clocks from ironlake_crtc_mode_set
2012-09-12 14:31 ` Daniel Vetter
@ 2012-09-12 14:34 ` Daniel Vetter
0 siblings, 0 replies; 21+ messages in thread
From: Daniel Vetter @ 2012-09-12 14:34 UTC (permalink / raw)
To: Paulo Zanoni; +Cc: intel-gfx, Paulo Zanoni
On Wed, Sep 12, 2012 at 04:31:50PM +0200, Daniel Vetter wrote:
> On Wed, Sep 12, 2012 at 10:06:34AM -0300, Paulo Zanoni wrote:
> > From: Paulo Zanoni <paulo.r.zanoni@intel.com>
> >
> > Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
> Queued for -next, thanks for the patch. I've needed to resolve some
> conflicts since I didn't pick up all previous patches, but nothing to
> onerous.
Wanted to add: I think the clock computation is one of the things most
responsible for tons of encoder type checks in the crtc mode_set code. My
idea is to move the clock computation out into an enhanced adjust_mode
stage, and deal with the encoder special-cases in the encoder->adjust_mode
callback.
That way we can also do (eventually) pll allocation and bandwidth
calculations/link allocations _before_ we start with the actual modeset
sequence. Which is obviously required for decent global modeset support.
But for now this is a good start to group the clock cruft together and
hide it someplace cuddly.
-Daniel
--
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 7/8] drm/i915: extract pch_pll_set from ironlake_crtc_mode_set
2012-09-12 13:06 ` [PATCH 7/8] drm/i915: extract pch_pll_set " Paulo Zanoni
@ 2012-09-12 14:40 ` Daniel Vetter
2012-09-18 20:18 ` Paulo Zanoni
0 siblings, 1 reply; 21+ messages in thread
From: Daniel Vetter @ 2012-09-12 14:40 UTC (permalink / raw)
To: Paulo Zanoni; +Cc: intel-gfx, Paulo Zanoni
On Wed, Sep 12, 2012 at 10:06:35AM -0300, Paulo Zanoni wrote:
> From: Paulo Zanoni <paulo.r.zanoni@intel.com>
>
> This is all the code responsible for setting the PCH PLLs.
>
> Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
> ---
> drivers/gpu/drm/i915/intel_display.c | 260 ++++++++++++++++++++--------------
> 1 file changed, 153 insertions(+), 107 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index dc4132a..7ffbcfd 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -4884,6 +4884,143 @@ static bool ironlake_compute_clocks(struct drm_crtc *crtc,
> return true;
> }
>
> +static bool ironlake_pch_pll_set(struct drm_crtc *crtc,
> + struct drm_display_mode *adjusted_mode,
> + intel_clock_t *clock,
> + bool has_reduced_clock,
> + intel_clock_t *reduced_clock)
> +{
> + struct drm_device *dev = crtc->dev;
> + struct drm_i915_private *dev_priv = dev->dev_private;
> + struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> + struct intel_encoder *intel_encoder;
> + int num_connectors = 0;
> + u32 dpll, fp = 0, fp2 = 0;
> + int factor, pixel_multiplier;
> + struct intel_pch_pll *pll;
> + bool is_lvds = false, is_sdvo = false, is_tv = false;
> + bool is_dp = false, is_cpu_edp = false;
> +
> + for_each_encoder_on_crtc(dev, crtc, intel_encoder) {
> + switch (intel_encoder->type) {
> + case INTEL_OUTPUT_LVDS:
> + is_lvds = true;
> + break;
> + case INTEL_OUTPUT_SDVO:
> + case INTEL_OUTPUT_HDMI:
> + is_sdvo = true;
> + if (intel_encoder->needs_tv_clock)
> + is_tv = true;
> + break;
> + case INTEL_OUTPUT_TVOUT:
> + is_tv = true;
> + break;
> + case INTEL_OUTPUT_DISPLAYPORT:
> + is_dp = true;
> + break;
> + case INTEL_OUTPUT_EDP:
> + is_dp = true;
> + if (!intel_encoder_is_pch_edp(&intel_encoder->base))
> + is_cpu_edp = true;
> + break;
> + }
> +
> + num_connectors++;
> + }
> +
> + fp = clock->n << 16 | clock->m1 << 8 | clock->m2;
> + if (has_reduced_clock)
> + fp2 = reduced_clock->n << 16 | reduced_clock->m1 << 8 |
> + reduced_clock->m2;
> +
> + /* Enable autotuning of the PLL clock (if permissible) */
> + factor = 21;
> + if (is_lvds) {
> + if ((intel_panel_use_ssc(dev_priv) &&
> + dev_priv->lvds_ssc_freq == 100) ||
> + (I915_READ(PCH_LVDS) & LVDS_CLKB_POWER_MASK) == LVDS_CLKB_POWER_UP)
> + factor = 25;
> + } else if (is_sdvo && is_tv)
> + factor = 20;
> +
> + if (clock->m < factor * clock->n)
> + fp |= FP_CB_TUNE;
> +
> + dpll = 0;
> +
> + if (is_lvds)
> + dpll |= DPLLB_MODE_LVDS;
> + else
> + dpll |= DPLLB_MODE_DAC_SERIAL;
> + if (is_sdvo) {
> + pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode);
> + if (pixel_multiplier > 1) {
> + dpll |= (pixel_multiplier - 1) << PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT;
> + }
> + dpll |= DPLL_DVO_HIGH_SPEED;
> + }
> + if (is_dp && !is_cpu_edp)
> + dpll |= DPLL_DVO_HIGH_SPEED;
> +
> + /* compute bitmask from p1 value */
> + dpll |= (1 << (clock->p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT;
> + /* also FPA1 */
> + dpll |= (1 << (clock->p1 - 1)) << DPLL_FPA1_P1_POST_DIV_SHIFT;
> +
> + switch (clock->p2) {
> + case 5:
> + dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_5;
> + break;
> + case 7:
> + dpll |= DPLLB_LVDS_P2_CLOCK_DIV_7;
> + break;
> + case 10:
> + dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_10;
> + break;
> + case 14:
> + dpll |= DPLLB_LVDS_P2_CLOCK_DIV_14;
> + break;
> + }
> +
> + if (is_sdvo && is_tv)
> + dpll |= PLL_REF_INPUT_TVCLKINBC;
> + else if (is_tv)
> + /* XXX: just matching BIOS for now */
> + /* dpll |= PLL_REF_INPUT_TVCLKINBC; */
> + dpll |= 3;
> + else if (is_lvds && intel_panel_use_ssc(dev_priv) && num_connectors < 2)
> + dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN;
> + else
> + dpll |= PLL_REF_INPUT_DREFCLK;
> +
> + pll = intel_get_pch_pll(intel_crtc, dpll, fp);
> + if (!pll)
> + return false;
> +
> + I915_WRITE(intel_crtc->pch_pll->pll_reg, dpll);
> +
> + /* Wait for the clocks to stabilize. */
> + POSTING_READ(intel_crtc->pch_pll->pll_reg);
> + udelay(150);
> +
> + /* The pixel multiplier can only be updated once the
> + * DPLL is enabled and the clocks are stable.
> + *
> + * So write it again.
> + */
> + I915_WRITE(intel_crtc->pch_pll->pll_reg, dpll);
> +
> + intel_crtc->lowfreq_avail = false;
> + if (is_lvds && has_reduced_clock && i915_powersave) {
> + I915_WRITE(intel_crtc->pch_pll->fp1_reg, fp2);
> + intel_crtc->lowfreq_avail = true;
> + } else {
> + I915_WRITE(intel_crtc->pch_pll->fp1_reg, fp);
> + }
> +
> + return true;
> +}
> +
> static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
> struct drm_display_mode *mode,
> struct drm_display_mode *adjusted_mode,
> @@ -4897,11 +5034,10 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
> int plane = intel_crtc->plane;
> int num_connectors = 0;
> intel_clock_t clock, reduced_clock;
> - u32 dpll, fp = 0, fp2 = 0;
> bool ok, has_reduced_clock = false, is_sdvo = false;
> bool is_crt = false, is_lvds = false, is_tv = false, is_dp = false;
> struct intel_encoder *encoder;
> - int ret, factor;
> + int ret;
> unsigned int pipe_bpp;
> bool dither;
> bool is_cpu_edp = false, is_pch_edp = false;
> @@ -4961,90 +5097,25 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
> }
> intel_crtc->bpp = pipe_bpp;
>
> - fp = clock.n << 16 | clock.m1 << 8 | clock.m2;
> - if (has_reduced_clock)
> - fp2 = reduced_clock.n << 16 | reduced_clock.m1 << 8 |
> - reduced_clock.m2;
> -
> - /* Enable autotuning of the PLL clock (if permissible) */
> - factor = 21;
> - if (is_lvds) {
> - if ((intel_panel_use_ssc(dev_priv) &&
> - dev_priv->lvds_ssc_freq == 100) ||
> - (I915_READ(PCH_LVDS) & LVDS_CLKB_POWER_MASK) == LVDS_CLKB_POWER_UP)
> - factor = 25;
> - } else if (is_sdvo && is_tv)
> - factor = 20;
> -
> - if (clock.m < factor * clock.n)
> - fp |= FP_CB_TUNE;
> -
> - dpll = 0;
> -
> - if (is_lvds)
> - dpll |= DPLLB_MODE_LVDS;
> - else
> - dpll |= DPLLB_MODE_DAC_SERIAL;
> - if (is_sdvo) {
> - int pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode);
> - if (pixel_multiplier > 1) {
> - dpll |= (pixel_multiplier - 1) << PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT;
> - }
> - dpll |= DPLL_DVO_HIGH_SPEED;
> - }
> - if (is_dp && !is_cpu_edp)
> - dpll |= DPLL_DVO_HIGH_SPEED;
> -
> - /* compute bitmask from p1 value */
> - dpll |= (1 << (clock.p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT;
> - /* also FPA1 */
> - dpll |= (1 << (clock.p1 - 1)) << DPLL_FPA1_P1_POST_DIV_SHIFT;
> -
> - switch (clock.p2) {
> - case 5:
> - dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_5;
> - break;
> - case 7:
> - dpll |= DPLLB_LVDS_P2_CLOCK_DIV_7;
> - break;
> - case 10:
> - dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_10;
> - break;
> - case 14:
> - dpll |= DPLLB_LVDS_P2_CLOCK_DIV_14;
> - break;
> - }
> -
> - if (is_sdvo && is_tv)
> - dpll |= PLL_REF_INPUT_TVCLKINBC;
> - else if (is_tv)
> - /* XXX: just matching BIOS for now */
> - /* dpll |= PLL_REF_INPUT_TVCLKINBC; */
> - dpll |= 3;
> - else if (is_lvds && intel_panel_use_ssc(dev_priv) && num_connectors < 2)
> - dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN;
> - else
> - dpll |= PLL_REF_INPUT_DREFCLK;
> -
> DRM_DEBUG_KMS("Mode for pipe %d:\n", pipe);
> drm_mode_debug_printmodeline(mode);
>
> - /* CPU eDP is the only output that doesn't need a PCH PLL of its own on
> - * pre-Haswell/LPT generation */
> - if (HAS_PCH_LPT(dev)) {
> - DRM_DEBUG_KMS("LPT detected: no PLL for pipe %d necessary\n",
> - pipe);
> - } else if (!is_cpu_edp) {
> - struct intel_pch_pll *pll;
> -
> - pll = intel_get_pch_pll(intel_crtc, dpll, fp);
> - if (pll == NULL) {
> - DRM_DEBUG_DRIVER("failed to find PLL for pipe %d\n",
> - pipe);
> - return -EINVAL;
> + if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)) {
Since the plan is to move all the hsw_crtc_stuff out into it's own
function I'd prefer a !HAS_PCH_LPT check here.
> + /* CPU eDP is the only output that doesn't need a PCH PLL of its
> + * own */
> + if (is_cpu_edp) {
> + intel_put_pch_pll(intel_crtc);
> + } else {
> + ok = ironlake_pch_pll_set(crtc, adjusted_mode, &clock,
> + has_reduced_clock,
> + &reduced_clock);
> + if (!ok) {
> + DRM_ERROR("Failed to find PLL for pipe %d\n",
> + pipe);
> + return -EINVAL;
> + }
> }
> - } else
> - intel_put_pch_pll(intel_crtc);
> + }
>
> /* The LVDS pin pair needs to be on before the DPLLs are enabled.
> * This is an exception to the general rule that mode_set doesn't turn
> @@ -5055,31 +5126,6 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
>
> ironlake_set_m_n(crtc, mode, adjusted_mode);
>
> - if (intel_crtc->pch_pll) {
> - I915_WRITE(intel_crtc->pch_pll->pll_reg, dpll);
> -
> - /* Wait for the clocks to stabilize. */
> - POSTING_READ(intel_crtc->pch_pll->pll_reg);
> - udelay(150);
> -
> - /* The pixel multiplier can only be updated once the
> - * DPLL is enabled and the clocks are stable.
> - *
> - * So write it again.
> - */
> - I915_WRITE(intel_crtc->pch_pll->pll_reg, dpll);
> - }
> -
> - intel_crtc->lowfreq_avail = false;
> - if (intel_crtc->pch_pll) {
> - if (is_lvds && has_reduced_clock && i915_powersave) {
> - I915_WRITE(intel_crtc->pch_pll->fp1_reg, fp2);
> - intel_crtc->lowfreq_avail = true;
> - } else {
> - I915_WRITE(intel_crtc->pch_pll->fp1_reg, fp);
> - }
> - }
> -
Again, you're moving registers around - see the comment about that the
lvds pin pairs need to be enabled _before_ we fire up the pll. Yeah, this
is a mess and I think we should move the actual pll enabling to the
crtc_enable stage (and the also move the lvds pin pair/port enabling in
there). So
- the actuall pll enabling needs to stay here.
- maybe call the function update_pch_pll instead of set_pch_pll. This is
more in line with Jesse's similar refactoring of i9xx_crtc_mode_set,
where he called the split-out pll functions update_pll, too.
Cheers, Daniel
> ironlake_set_pipe_timings(intel_crtc, mode, adjusted_mode);
>
> if (is_cpu_edp)
> --
> 1.7.10.4
>
> _______________________________________________
> 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
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 7/8] drm/i915: extract pch_pll_set from ironlake_crtc_mode_set
2012-09-12 14:40 ` Daniel Vetter
@ 2012-09-18 20:18 ` Paulo Zanoni
2012-09-19 9:17 ` Daniel Vetter
0 siblings, 1 reply; 21+ messages in thread
From: Paulo Zanoni @ 2012-09-18 20:18 UTC (permalink / raw)
To: Daniel Vetter; +Cc: intel-gfx, Paulo Zanoni
Hi
2012/9/12 Daniel Vetter <daniel@ffwll.ch>:
> On Wed, Sep 12, 2012 at 10:06:35AM -0300, Paulo Zanoni wrote:
>> From: Paulo Zanoni <paulo.r.zanoni@intel.com>
[ ... ]
>> + if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)) {
>
> Since the plan is to move all the hsw_crtc_stuff out into it's own
> function I'd prefer a !HAS_PCH_LPT check here.
I don't agree with the LPT check. Let me give some more details about
my plan so you can understand why I did this.
My plan was to add even more (HAS_PCH_IBX || HAS_PCH_CPT) checks to
other places of this function and copy them all to the
haswell_crtc_mode_set version since I'm still not sure we'll never
ever have HSW with something older than LPT. After forking the Haswell
version, the plan was to add a WARN(!(HAS_PCH_IBX || HAS_PCH_CPT)) to
ironlake_crtc_mode_set and then remove the checks form it (leaving the
checks on haswell_crtc_mode_set untouched and prepared for the 42 new
PCHs they plan to ship after LPT). This code under the check was made
specifically for IBX/CPT (and PPT) and only tested on it, so I guess
the correct check is check for IBX/CPT.
So, may I keep the IBX/CPT check? Should I change the plan instead?
>> - intel_crtc->lowfreq_avail = false;
>> - if (intel_crtc->pch_pll) {
>> - if (is_lvds && has_reduced_clock && i915_powersave) {
>> - I915_WRITE(intel_crtc->pch_pll->fp1_reg, fp2);
>> - intel_crtc->lowfreq_avail = true;
>> - } else {
>> - I915_WRITE(intel_crtc->pch_pll->fp1_reg, fp);
>> - }
>> - }
>> -
>
> Again, you're moving registers around - see the comment about that the
> lvds pin pairs need to be enabled _before_ we fire up the pll.
Oh, thanks! Let's hope that after the rework it's harder to make such
mistakes :)
> Yeah, this
> is a mess and I think we should move the actual pll enabling to the
> crtc_enable stage (and the also move the lvds pin pair/port enabling in
> there). So
> - the actuall pll enabling needs to stay here.
> - maybe call the function update_pch_pll instead of set_pch_pll. This is
> more in line with Jesse's similar refactoring of i9xx_crtc_mode_set,
> where he called the split-out pll functions update_pll, too.
Ok, will do.
--
Paulo Zanoni
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 7/8] drm/i915: extract pch_pll_set from ironlake_crtc_mode_set
2012-09-18 20:18 ` Paulo Zanoni
@ 2012-09-19 9:17 ` Daniel Vetter
0 siblings, 0 replies; 21+ messages in thread
From: Daniel Vetter @ 2012-09-19 9:17 UTC (permalink / raw)
To: Paulo Zanoni; +Cc: intel-gfx, Paulo Zanoni
On Tue, Sep 18, 2012 at 10:18 PM, Paulo Zanoni <przanoni@gmail.com> wrote:
> 2012/9/12 Daniel Vetter <daniel@ffwll.ch>:
>> On Wed, Sep 12, 2012 at 10:06:35AM -0300, Paulo Zanoni wrote:
>>> From: Paulo Zanoni <paulo.r.zanoni@intel.com>
> [ ... ]
>>> + if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)) {
>>
>> Since the plan is to move all the hsw_crtc_stuff out into it's own
>> function I'd prefer a !HAS_PCH_LPT check here.
>
> I don't agree with the LPT check. Let me give some more details about
> my plan so you can understand why I did this.
>
> My plan was to add even more (HAS_PCH_IBX || HAS_PCH_CPT) checks to
> other places of this function and copy them all to the
> haswell_crtc_mode_set version since I'm still not sure we'll never
> ever have HSW with something older than LPT. After forking the Haswell
> version, the plan was to add a WARN(!(HAS_PCH_IBX || HAS_PCH_CPT)) to
> ironlake_crtc_mode_set and then remove the checks form it (leaving the
> checks on haswell_crtc_mode_set untouched and prepared for the 42 new
> PCHs they plan to ship after LPT). This code under the check was made
> specifically for IBX/CPT (and PPT) and only tested on it, so I guess
> the correct check is check for IBX/CPT.
>
> So, may I keep the IBX/CPT check? Should I change the plan instead?
Makes sense, so I'm ok with keeping these checks and code-blocks in
the haswell code. We can rip them out once haswell ships and we know
whether the hw guys want to ship 42 different pch models or not.
-Daniel
--
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 3/8] drm/i915: extract set_pipe_timings from ironlake_crtc_mode_set
2012-09-12 14:11 ` Daniel Vetter
@ 2012-09-19 18:11 ` Paulo Zanoni
2012-09-20 7:32 ` Daniel Vetter
0 siblings, 1 reply; 21+ messages in thread
From: Paulo Zanoni @ 2012-09-19 18:11 UTC (permalink / raw)
To: Daniel Vetter; +Cc: intel-gfx, Paulo Zanoni
Hi
2012/9/12 Daniel Vetter <daniel@ffwll.ch>:
> On Wed, Sep 12, 2012 at 10:06:31AM -0300, Paulo Zanoni wrote:
>> From: Paulo Zanoni <paulo.r.zanoni@intel.com>
>>
>> Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
>
> Hm, I think we should extract the same code from i9xx_crtc_set_mode, too
> and share it in a common intel_set_pipe_timings. Their almost identical
> safe for:
> - vsyncshift is only gen4+
This is easy to solve.
> - source position handling is a bit different, but I think it'd be
> semantically clearer if we leave that out of set_pipe_timings. Imo that
> belongs to the panel fitter settings, which are currently splattered all
> over. Meh.
Well, the PIPESRC register is described inside the "pipe timings"
documentation section, so I think it should be inside the
set_pipe_timings function.
I actually implemented your suggestion locally and the only real
problem is that on i9xx_crtc_mode_set we currently write to DSPSIZE
and DSPPOS before writing to PIPESRC, so to make the code look good we
have 2 options:
1 - Write to DSPPOS and DSPSIZE before writing all the timing registers
2 - Write to DSPPOS and DSPSIZE after writing all the timing registers
In both cases we are changing the writing order. I looked at the
documentation and it seems we should be writing to the plane registers
only after setting the pipe registers, so maybe solution 2 is the
correct. The problem is that yes, we are changing the behavior and I
don't even have such machines to test.
So, how do we proceed here? Want the version, keep the old one, or do
something entirely different?
>
> Comments?
> -Daniel
>> ---
>> drivers/gpu/drm/i915/intel_display.c | 82 +++++++++++++++++++---------------
>> 1 file changed, 46 insertions(+), 36 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
>> index cf1e628..5a4e363 100644
>> --- a/drivers/gpu/drm/i915/intel_display.c
>> +++ b/drivers/gpu/drm/i915/intel_display.c
>> @@ -4690,6 +4690,51 @@ static void ironlake_set_pipeconf(struct drm_crtc *crtc,
>> POSTING_READ(PIPECONF(pipe));
>> }
>>
>> +static void ironlake_set_pipe_timings(struct intel_crtc *intel_crtc,
>> + struct drm_display_mode *mode,
>> + struct drm_display_mode *adjusted_mode)
>> +{
>> + struct drm_i915_private *dev_priv = intel_crtc->base.dev->dev_private;
>> + enum pipe pipe = intel_crtc->pipe;
>> +
>> + if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
>> + /* the chip adds 2 halflines automatically */
>> + adjusted_mode->crtc_vtotal -= 1;
>> + adjusted_mode->crtc_vblank_end -= 1;
>> + I915_WRITE(VSYNCSHIFT(pipe),
>> + adjusted_mode->crtc_hsync_start
>> + - adjusted_mode->crtc_htotal/2);
>> + } else {
>> + I915_WRITE(VSYNCSHIFT(pipe), 0);
>> + }
>> +
>> + I915_WRITE(HTOTAL(pipe),
>> + (adjusted_mode->crtc_hdisplay - 1) |
>> + ((adjusted_mode->crtc_htotal - 1) << 16));
>> + I915_WRITE(HBLANK(pipe),
>> + (adjusted_mode->crtc_hblank_start - 1) |
>> + ((adjusted_mode->crtc_hblank_end - 1) << 16));
>> + I915_WRITE(HSYNC(pipe),
>> + (adjusted_mode->crtc_hsync_start - 1) |
>> + ((adjusted_mode->crtc_hsync_end - 1) << 16));
>> +
>> + I915_WRITE(VTOTAL(pipe),
>> + (adjusted_mode->crtc_vdisplay - 1) |
>> + ((adjusted_mode->crtc_vtotal - 1) << 16));
>> + I915_WRITE(VBLANK(pipe),
>> + (adjusted_mode->crtc_vblank_start - 1) |
>> + ((adjusted_mode->crtc_vblank_end - 1) << 16));
>> + I915_WRITE(VSYNC(pipe),
>> + (adjusted_mode->crtc_vsync_start - 1) |
>> + ((adjusted_mode->crtc_vsync_end - 1) << 16));
>> +
>> + /* pipesrc controls the size that is scaled from, which should
>> + * always be the user's requested size.
>> + */
>> + I915_WRITE(PIPESRC(pipe),
>> + ((mode->hdisplay - 1) << 16) | (mode->vdisplay - 1));
>> +}
>> +
>> static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
>> struct drm_display_mode *mode,
>> struct drm_display_mode *adjusted_mode,
>> @@ -4970,42 +5015,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
>> }
>> }
>>
>> - if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
>> - /* the chip adds 2 halflines automatically */
>> - adjusted_mode->crtc_vtotal -= 1;
>> - adjusted_mode->crtc_vblank_end -= 1;
>> - I915_WRITE(VSYNCSHIFT(pipe),
>> - adjusted_mode->crtc_hsync_start
>> - - adjusted_mode->crtc_htotal/2);
>> - } else {
>> - I915_WRITE(VSYNCSHIFT(pipe), 0);
>> - }
>> -
>> - I915_WRITE(HTOTAL(pipe),
>> - (adjusted_mode->crtc_hdisplay - 1) |
>> - ((adjusted_mode->crtc_htotal - 1) << 16));
>> - I915_WRITE(HBLANK(pipe),
>> - (adjusted_mode->crtc_hblank_start - 1) |
>> - ((adjusted_mode->crtc_hblank_end - 1) << 16));
>> - I915_WRITE(HSYNC(pipe),
>> - (adjusted_mode->crtc_hsync_start - 1) |
>> - ((adjusted_mode->crtc_hsync_end - 1) << 16));
>> -
>> - I915_WRITE(VTOTAL(pipe),
>> - (adjusted_mode->crtc_vdisplay - 1) |
>> - ((adjusted_mode->crtc_vtotal - 1) << 16));
>> - I915_WRITE(VBLANK(pipe),
>> - (adjusted_mode->crtc_vblank_start - 1) |
>> - ((adjusted_mode->crtc_vblank_end - 1) << 16));
>> - I915_WRITE(VSYNC(pipe),
>> - (adjusted_mode->crtc_vsync_start - 1) |
>> - ((adjusted_mode->crtc_vsync_end - 1) << 16));
>> -
>> - /* pipesrc controls the size that is scaled from, which should
>> - * always be the user's requested size.
>> - */
>> - I915_WRITE(PIPESRC(pipe),
>> - ((mode->hdisplay - 1) << 16) | (mode->vdisplay - 1));
>> + ironlake_set_pipe_timings(intel_crtc, mode, adjusted_mode);
>>
>> I915_WRITE(PIPE_DATA_M1(pipe), TU_SIZE(m_n.tu) | m_n.gmch_m);
>> I915_WRITE(PIPE_DATA_N1(pipe), m_n.gmch_n);
>> --
>> 1.7.10.4
>>
>> _______________________________________________
>> 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
--
Paulo Zanoni
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 3/8] drm/i915: extract set_pipe_timings from ironlake_crtc_mode_set
2012-09-19 18:11 ` Paulo Zanoni
@ 2012-09-20 7:32 ` Daniel Vetter
0 siblings, 0 replies; 21+ messages in thread
From: Daniel Vetter @ 2012-09-20 7:32 UTC (permalink / raw)
To: Paulo Zanoni; +Cc: intel-gfx, Paulo Zanoni
On Wed, Sep 19, 2012 at 03:11:33PM -0300, Paulo Zanoni wrote:
> Hi
>
> 2012/9/12 Daniel Vetter <daniel@ffwll.ch>:
> > On Wed, Sep 12, 2012 at 10:06:31AM -0300, Paulo Zanoni wrote:
> >> From: Paulo Zanoni <paulo.r.zanoni@intel.com>
> >>
> >> Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
> >
> > Hm, I think we should extract the same code from i9xx_crtc_set_mode, too
> > and share it in a common intel_set_pipe_timings. Their almost identical
> > safe for:
> > - vsyncshift is only gen4+
>
> This is easy to solve.
>
> > - source position handling is a bit different, but I think it'd be
> > semantically clearer if we leave that out of set_pipe_timings. Imo that
> > belongs to the panel fitter settings, which are currently splattered all
> > over. Meh.
>
> Well, the PIPESRC register is described inside the "pipe timings"
> documentation section, so I think it should be inside the
> set_pipe_timings function.
>
> I actually implemented your suggestion locally and the only real
> problem is that on i9xx_crtc_mode_set we currently write to DSPSIZE
> and DSPPOS before writing to PIPESRC, so to make the code look good we
> have 2 options:
> 1 - Write to DSPPOS and DSPSIZE before writing all the timing registers
> 2 - Write to DSPPOS and DSPSIZE after writing all the timing registers
>
> In both cases we are changing the writing order. I looked at the
> documentation and it seems we should be writing to the plane registers
> only after setting the pipe registers, so maybe solution 2 is the
> correct. The problem is that yes, we are changing the behavior and I
> don't even have such machines to test.
>
> So, how do we proceed here? Want the version, keep the old one, or do
> something entirely different?
I guess a quick patch to move around the DSP* regs down and run it on a
few gen2/3 machines. Then move things around if it doesn't blow up. Since
I'm travelling I think you need to volunteer Chris for the testing ;-)
-Daniel
--
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
^ permalink raw reply [flat|nested] 21+ messages in thread
end of thread, other threads:[~2012-09-20 7:32 UTC | newest]
Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-09-12 13:06 [PATCH 0/8] Rework ironlake_crtc_mode_set Paulo Zanoni
2012-09-12 13:06 ` [PATCH 1/8] drm/i915: extract ironlake_set_pipeconf form ironlake_crtc_mode_set Paulo Zanoni
2012-09-12 14:03 ` Daniel Vetter
2012-09-12 13:06 ` [PATCH 2/8] drm/i915: extract LVDS-specific code from ironlake_crtc_mode_set Paulo Zanoni
2012-09-12 13:56 ` Daniel Vetter
2012-09-12 13:06 ` [PATCH 3/8] drm/i915: extract set_pipe_timings " Paulo Zanoni
2012-09-12 14:11 ` Daniel Vetter
2012-09-19 18:11 ` Paulo Zanoni
2012-09-20 7:32 ` Daniel Vetter
2012-09-12 13:06 ` [PATCH 4/8] drm/i915: simplify setting DSPCNTR inside ironlake_crtc_mode_set Paulo Zanoni
2012-09-12 14:12 ` Daniel Vetter
2012-09-12 13:06 ` [PATCH 5/8] drm/i915: extract set_m_n from ironlake_crtc_mode_set Paulo Zanoni
2012-09-12 14:20 ` Daniel Vetter
2012-09-12 13:06 ` [PATCH 6/8] drm/i915: extract compute_clocks " Paulo Zanoni
2012-09-12 14:31 ` Daniel Vetter
2012-09-12 14:34 ` Daniel Vetter
2012-09-12 13:06 ` [PATCH 7/8] drm/i915: extract pch_pll_set " Paulo Zanoni
2012-09-12 14:40 ` Daniel Vetter
2012-09-18 20:18 ` Paulo Zanoni
2012-09-19 9:17 ` Daniel Vetter
2012-09-12 13:06 ` [PATCH 8/8] drm/i915: remove unused variables " Paulo Zanoni
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.