* [PATCH 1/8] drm/i915: clear up the fdi/dp set_m_n confusion
2013-02-22 0:04 [PATCH 00/10] bpc handling fixes Daniel Vetter
@ 2013-02-22 0:04 ` Daniel Vetter
2013-02-22 0:04 ` [PATCH 01/10] drm/i915: use pipe_config for lvds dithering Daniel Vetter
` (16 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Daniel Vetter @ 2013-02-22 0:04 UTC (permalink / raw)
To: Intel Graphics Development; +Cc: Daniel Vetter
There's a rather decent confusion going on around transcoder m_n
values. So let's clarify:
- All dp encoders need this, either on the pch transcoder if it's a
pch port, or on the cpu transcoder/pipe if it's a cpu port.
- fdi links need to have the right m_n values for the fdi link set in
the cpu transcoder.
To handle the pch vs transcoder stuff a bit better, extract transcoder
set_m_n helpers. To make them simpler, set intel_crtc->cpu_transcoder
als in ironlake_crtc_mode_set, so that gen5+ (where the cpu m_n
registers are all at the same offset) can use it.
Haswell modeset is decently confused about dp vs. edp vs. fdi. dp vs.
edp works exactly the same as dp (since there's no pch dp any more),
so use that as a check. And only set up the fdi m_n values if we
really have a pch encoder present (which means we have a VGA encoder).
On ilk+ we've called ironlake_set_m_n both for cpu_edp and for pch
encoders. Now that dp_set_m_n handles all dp links (thanks to the
pch encoder check), we can ditch the cpu_edp stuff from the
fdi_set_m_n function.
Since the dp_m_n values are not readily available, we need to
carefully coax the edp values out of the encoder. Hence we can't (yet)
kill this superflous complexity.
v2: Rebase on top of the ivb fdi B/C check patch - we need to properly
clear intel_crtc->fdi_lane, otherwise those checks will misfire.
v3: Rebased on top of a s/IS_HASWELL/HAS_DDI/ patch from Paulo Zanoni.
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
drivers/gpu/drm/i915/intel_display.c | 86 +++++++++++++++++++++++-------------
drivers/gpu/drm/i915/intel_dp.c | 30 ++-----------
drivers/gpu/drm/i915/intel_drv.h | 8 ++++
3 files changed, 67 insertions(+), 57 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index f1d47dd..8335fd5 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -5255,15 +5255,47 @@ int ironlake_get_lanes_required(int target_clock, int link_bw, int bpp)
return bps / (link_bw * 8) + 1;
}
-static void ironlake_set_m_n(struct drm_crtc *crtc)
+void intel_pch_transcoder_set_m_n(struct intel_crtc *crtc,
+ struct intel_link_m_n *m_n)
{
- struct drm_device *dev = crtc->dev;
+ struct drm_device *dev = crtc->base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ int pipe = crtc->pipe;
+
+ I915_WRITE(TRANSDATA_M1(pipe), TU_SIZE(m_n->tu) | m_n->gmch_m);
+ I915_WRITE(TRANSDATA_N1(pipe), m_n->gmch_n);
+ I915_WRITE(TRANSDPLINK_M1(pipe), m_n->link_m);
+ I915_WRITE(TRANSDPLINK_N1(pipe), m_n->link_n);
+}
+
+void intel_cpu_transcoder_set_m_n(struct intel_crtc *crtc,
+ struct intel_link_m_n *m_n)
+{
+ struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
+ int pipe = crtc->pipe;
+ enum transcoder transcoder = crtc->cpu_transcoder;
+
+ if (INTEL_INFO(dev)->gen >= 5) {
+ I915_WRITE(PIPE_DATA_M1(transcoder), TU_SIZE(m_n->tu) | m_n->gmch_m);
+ I915_WRITE(PIPE_DATA_N1(transcoder), m_n->gmch_n);
+ I915_WRITE(PIPE_LINK_M1(transcoder), m_n->link_m);
+ I915_WRITE(PIPE_LINK_N1(transcoder), m_n->link_n);
+ } else {
+ I915_WRITE(PIPE_GMCH_DATA_M(pipe), TU_SIZE(m_n->tu) | m_n->gmch_m);
+ I915_WRITE(PIPE_GMCH_DATA_N(pipe), m_n->gmch_n);
+ I915_WRITE(PIPE_DP_LINK_M(pipe), m_n->link_m);
+ I915_WRITE(PIPE_DP_LINK_N(pipe), m_n->link_n);
+ }
+}
+
+static void ironlake_fdi_set_m_n(struct drm_crtc *crtc)
+{
+ struct drm_device *dev = crtc->dev;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct drm_display_mode *adjusted_mode =
&intel_crtc->config.adjusted_mode;
struct drm_display_mode *mode = &intel_crtc->config.requested_mode;
- enum transcoder cpu_transcoder = intel_crtc->cpu_transcoder;
struct intel_encoder *intel_encoder, *edp_encoder = NULL;
struct intel_link_m_n m_n = {0};
int target_clock, lane, link_bw;
@@ -5283,22 +5315,14 @@ static void ironlake_set_m_n(struct drm_crtc *crtc)
}
}
- /* FDI link */
- 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;
- }
+ /* 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)
@@ -5308,9 +5332,8 @@ static void ironlake_set_m_n(struct drm_crtc *crtc)
else
target_clock = adjusted_mode->clock;
- if (!lane)
- lane = ironlake_get_lanes_required(target_clock, link_bw,
- intel_crtc->config.pipe_bpp);
+ lane = ironlake_get_lanes_required(target_clock, link_bw,
+ intel_crtc->config.pipe_bpp);
intel_crtc->fdi_lanes = lane;
@@ -5319,10 +5342,7 @@ static void ironlake_set_m_n(struct drm_crtc *crtc)
intel_link_compute_m_n(intel_crtc->config.pipe_bpp, lane, target_clock,
link_bw, &m_n);
- I915_WRITE(PIPE_DATA_M1(cpu_transcoder), TU_SIZE(m_n.tu) | m_n.gmch_m);
- I915_WRITE(PIPE_DATA_N1(cpu_transcoder), m_n.gmch_n);
- I915_WRITE(PIPE_LINK_M1(cpu_transcoder), m_n.link_m);
- I915_WRITE(PIPE_LINK_N1(cpu_transcoder), m_n.link_n);
+ intel_cpu_transcoder_set_m_n(intel_crtc, &m_n);
}
static uint32_t ironlake_compute_dpll(struct intel_crtc *intel_crtc,
@@ -5469,6 +5489,8 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
WARN(!(HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)),
"Unexpected PCH type %d\n", INTEL_PCH_TYPE(dev));
+ intel_crtc->cpu_transcoder = pipe;
+
ok = ironlake_compute_clocks(crtc, adjusted_mode, &clock,
&has_reduced_clock, &reduced_clock);
if (!ok) {
@@ -5507,7 +5529,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
} else
intel_put_pch_pll(intel_crtc);
- if (is_dp && !is_cpu_edp)
+ if (is_dp)
intel_dp_set_m_n(crtc, mode, adjusted_mode);
for_each_encoder_on_crtc(dev, crtc, encoder)
@@ -5543,7 +5565,9 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
/* Note, this also computes intel_crtc->fdi_lanes which is used below in
* ironlake_check_fdi_lanes. */
- ironlake_set_m_n(crtc);
+ intel_crtc->fdi_lanes = 0;
+ if (intel_crtc->config.has_pch_encoder)
+ ironlake_fdi_set_m_n(crtc);
fdi_config_ok = ironlake_check_fdi_lanes(intel_crtc);
@@ -5650,15 +5674,15 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc,
DRM_DEBUG_KMS("Mode for pipe %d:\n", pipe);
drm_mode_debug_printmodeline(mode);
- if (is_dp && !is_cpu_edp)
+ if (is_dp)
intel_dp_set_m_n(crtc, mode, adjusted_mode);
intel_crtc->lowfreq_avail = false;
intel_set_pipe_timings(intel_crtc, mode, adjusted_mode);
- if (!is_dp || is_cpu_edp)
- ironlake_set_m_n(crtc);
+ if (intel_crtc->config.has_pch_encoder)
+ ironlake_fdi_set_m_n(crtc);
haswell_set_pipeconf(crtc, adjusted_mode, dither);
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index a4c9858..a4caf1e 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -766,12 +766,9 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
struct drm_device *dev = crtc->dev;
struct intel_encoder *intel_encoder;
struct intel_dp *intel_dp;
- struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
int lane_count = 4;
struct intel_link_m_n m_n;
- int pipe = intel_crtc->pipe;
- enum transcoder cpu_transcoder = intel_crtc->cpu_transcoder;
/*
* Find the lane count in the intel_encoder private
@@ -795,29 +792,10 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
intel_link_compute_m_n(intel_crtc->config.pipe_bpp, lane_count,
mode->clock, adjusted_mode->clock, &m_n);
- if (HAS_DDI(dev)) {
- I915_WRITE(PIPE_DATA_M1(cpu_transcoder),
- TU_SIZE(m_n.tu) | m_n.gmch_m);
- I915_WRITE(PIPE_DATA_N1(cpu_transcoder), m_n.gmch_n);
- I915_WRITE(PIPE_LINK_M1(cpu_transcoder), m_n.link_m);
- I915_WRITE(PIPE_LINK_N1(cpu_transcoder), m_n.link_n);
- } else if (HAS_PCH_SPLIT(dev)) {
- I915_WRITE(TRANSDATA_M1(pipe), TU_SIZE(m_n.tu) | m_n.gmch_m);
- I915_WRITE(TRANSDATA_N1(pipe), m_n.gmch_n);
- I915_WRITE(TRANSDPLINK_M1(pipe), m_n.link_m);
- I915_WRITE(TRANSDPLINK_N1(pipe), m_n.link_n);
- } else if (IS_VALLEYVIEW(dev)) {
- 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);
- } else {
- I915_WRITE(PIPE_GMCH_DATA_M(pipe),
- TU_SIZE(m_n.tu) | m_n.gmch_m);
- I915_WRITE(PIPE_GMCH_DATA_N(pipe), m_n.gmch_n);
- I915_WRITE(PIPE_DP_LINK_M(pipe), m_n.link_m);
- I915_WRITE(PIPE_DP_LINK_N(pipe), m_n.link_n);
- }
+ if (intel_crtc->config.has_pch_encoder)
+ intel_pch_transcoder_set_m_n(intel_crtc, &m_n);
+ else
+ intel_cpu_transcoder_set_m_n(intel_crtc, &m_n);
}
void intel_dp_init_link_config(struct intel_dp *intel_dp)
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index e43155a..aa4dee4 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -191,8 +191,12 @@ struct intel_crtc_config {
*/
bool limited_color_range;
+ /* DP has a bunch of special case unfortunately, so mark the pipe
+ * accordingly. */
+ bool has_dp_encoder;
bool dither;
int pipe_bpp;
+ struct intel_link_m_n dp_m_n;
/* Used by SDVO (and if we ever fix it, HDMI). */
unsigned pixel_multiplier;
@@ -635,6 +639,10 @@ extern void intel_init_clock_gating(struct drm_device *dev);
extern void intel_write_eld(struct drm_encoder *encoder,
struct drm_display_mode *mode);
extern void intel_cpt_verify_modeset(struct drm_device *dev, int pipe);
+extern void intel_cpu_transcoder_set_m_n(struct intel_crtc *crtc,
+ struct intel_link_m_n *m_n);
+extern void intel_pch_transcoder_set_m_n(struct intel_crtc *crtc,
+ struct intel_link_m_n *m_n);
extern void intel_prepare_ddi(struct drm_device *dev);
extern void hsw_fdi_link_train(struct drm_crtc *crtc);
extern void intel_ddi_init(struct drm_device *dev, enum port port);
--
1.7.11.4
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH 01/10] drm/i915: use pipe_config for lvds dithering
2013-02-22 0:04 [PATCH 00/10] bpc handling fixes Daniel Vetter
2013-02-22 0:04 ` [PATCH 1/8] drm/i915: clear up the fdi/dp set_m_n confusion Daniel Vetter
@ 2013-02-22 0:04 ` Daniel Vetter
2013-02-22 0:04 ` [PATCH 02/10] drm/i915: consolidate pch pll computations a bit Daniel Vetter
` (15 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Daniel Vetter @ 2013-02-22 0:04 UTC (permalink / raw)
To: Intel Graphics Development; +Cc: Daniel Vetter
Up to now we've relied on the bios to get this right for us. Let's try
out whether our code has improved a bit, since we should dither
always when the output bpp doesn't match the plane bpp.
- gen5+ should be fine, since we only use the bios hint as an upgrade.
- gen4 changes, since here dithering is still controlled in the lvds
register.
- gen2/3 has implicit dithering depeding upon whether you use 2 or 3
lvds pairs (which makes sense, since it only supports 8bpc pipe
outpu configurations).
- hsw doesn't support lvds.
v2: Remove redudant dither setting.
v3: Completly drop reliance on dev_priv->lvds_dither.
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
drivers/gpu/drm/i915/intel_display.c | 25 +++++++------------------
drivers/gpu/drm/i915/intel_drv.h | 5 +++++
drivers/gpu/drm/i915/intel_lvds.c | 12 +++++++-----
3 files changed, 19 insertions(+), 23 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 45a52f3..1c26109 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4875,8 +4875,7 @@ static int ironlake_get_refclk(struct drm_crtc *crtc)
}
static void ironlake_set_pipeconf(struct drm_crtc *crtc,
- struct drm_display_mode *adjusted_mode,
- bool dither)
+ struct drm_display_mode *adjusted_mode)
{
struct drm_i915_private *dev_priv = crtc->dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
@@ -4905,7 +4904,7 @@ static void ironlake_set_pipeconf(struct drm_crtc *crtc,
}
val &= ~(PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_MASK);
- if (dither)
+ if (intel_crtc->config.dither)
val |= (PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_SP);
val &= ~PIPECONF_INTERLACE_MASK;
@@ -4988,8 +4987,7 @@ static void intel_set_pipe_csc(struct drm_crtc *crtc)
}
static void haswell_set_pipeconf(struct drm_crtc *crtc,
- struct drm_display_mode *adjusted_mode,
- bool dither)
+ struct drm_display_mode *adjusted_mode)
{
struct drm_i915_private *dev_priv = crtc->dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
@@ -4999,7 +4997,7 @@ static void haswell_set_pipeconf(struct drm_crtc *crtc,
val = I915_READ(PIPECONF(cpu_transcoder));
val &= ~(PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_MASK);
- if (dither)
+ if (intel_crtc->config.dither)
val |= (PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_SP);
val &= ~PIPECONF_INTERLACE_MASK_HSW;
@@ -5351,7 +5349,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
bool is_lvds = false;
struct intel_encoder *encoder;
int ret;
- bool dither, fdi_config_ok;
+ bool fdi_config_ok;
for_each_encoder_on_crtc(dev, crtc, encoder) {
switch (encoder->type) {
@@ -5386,11 +5384,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);
- /* determine panel color depth */
- dither = intel_crtc->config.dither;
- if (is_lvds && dev_priv->lvds_dither)
- dither = true;
-
fp = clock.n << 16 | clock.m1 << 8 | clock.m2;
if (has_reduced_clock)
fp2 = reduced_clock.n << 16 | reduced_clock.m1 << 8 |
@@ -5456,7 +5449,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
fdi_config_ok = ironlake_check_fdi_lanes(intel_crtc);
- ironlake_set_pipeconf(crtc, adjusted_mode, dither);
+ ironlake_set_pipeconf(crtc, adjusted_mode);
intel_wait_for_vblank(dev, pipe);
@@ -5535,7 +5528,6 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc,
bool is_cpu_edp = false;
struct intel_encoder *encoder;
int ret;
- bool dither;
for_each_encoder_on_crtc(dev, crtc, encoder) {
switch (encoder->type) {
@@ -5566,9 +5558,6 @@ static int haswell_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);
- /* determine panel color depth */
- dither = intel_crtc->config.dither;
-
DRM_DEBUG_KMS("Mode for pipe %d:\n", pipe);
drm_mode_debug_printmodeline(mode);
@@ -5582,7 +5571,7 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc,
if (intel_crtc->config.has_pch_encoder)
ironlake_fdi_set_m_n(crtc);
- haswell_set_pipeconf(crtc, adjusted_mode, dither);
+ haswell_set_pipeconf(crtc, adjusted_mode);
intel_set_pipe_csc(crtc);
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index ddc8ff4..fdda144 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -194,6 +194,11 @@ struct intel_crtc_config {
/* DP has a bunch of special case unfortunately, so mark the pipe
* accordingly. */
bool has_dp_encoder;
+
+ /*
+ * Enable dithering, used when the selected pipe bpp doesn't match the
+ * plane bpp.
+ */
bool dither;
/* Controls for the clock computation, to override various stages. */
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index 4eb57de..ff4f523 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -136,7 +136,7 @@ static void intel_pre_pll_enable_lvds(struct intel_encoder *encoder)
* special lvds dither control bit on pch-split platforms, dithering is
* only controlled through the PIPECONF reg. */
if (INTEL_INFO(dev)->gen == 4) {
- if (dev_priv->lvds_dither)
+ if (intel_crtc->config.dither)
temp |= LVDS_ENABLE_DITHER;
else
temp &= ~LVDS_ENABLE_DITHER;
@@ -332,7 +332,13 @@ static bool intel_lvds_compute_config(struct intel_encoder *intel_encoder,
DRM_DEBUG_KMS("forcing display bpp (was %d) to LVDS (%d)\n",
pipe_config->pipe_bpp, lvds_bpp);
pipe_config->pipe_bpp = lvds_bpp;
+
+ /* Make sure pre-965 set dither correctly */
+ if (INTEL_INFO(dev)->gen < 4)
+ pfit_control |= PANEL_8TO6_DITHER_ENABLE;
+
}
+
/*
* We have timings from the BIOS for the panel, put them in
* to the adjusted mode. The CRTC will be set up for this mode,
@@ -467,10 +473,6 @@ out:
pfit_pgm_ratios = 0;
}
- /* Make sure pre-965 set dither correctly */
- if (INTEL_INFO(dev)->gen < 4 && dev_priv->lvds_dither)
- pfit_control |= PANEL_8TO6_DITHER_ENABLE;
-
if (pfit_control != lvds_encoder->pfit_control ||
pfit_pgm_ratios != lvds_encoder->pfit_pgm_ratios) {
lvds_encoder->pfit_control = pfit_control;
--
1.7.11.4
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH 02/10] drm/i915: consolidate pch pll computations a bit
2013-02-22 0:04 [PATCH 00/10] bpc handling fixes Daniel Vetter
2013-02-22 0:04 ` [PATCH 1/8] drm/i915: clear up the fdi/dp set_m_n confusion Daniel Vetter
2013-02-22 0:04 ` [PATCH 01/10] drm/i915: use pipe_config for lvds dithering Daniel Vetter
@ 2013-02-22 0:04 ` Daniel Vetter
2013-02-22 0:04 ` [PATCH 2/8] drm/i915: move dp_m_n computation to dp_encoder->compute_config Daniel Vetter
` (14 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Daniel Vetter @ 2013-02-22 0:04 UTC (permalink / raw)
To: Intel Graphics Development; +Cc: Daniel Vetter
We need the dpll/fp/fp2 values only when we need a pch pll. So move
them together with the code to acquire such a pll.
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
drivers/gpu/drm/i915/intel_display.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 1c26109..c7f6dcb 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -5344,7 +5344,7 @@ 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;
+ u32 dpll = 0, fp = 0, fp2 = 0;
bool ok, has_reduced_clock = false;
bool is_lvds = false;
struct intel_encoder *encoder;
@@ -5384,13 +5384,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);
- 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;
-
- dpll = ironlake_compute_dpll(intel_crtc, &clock, fp);
-
DRM_DEBUG_KMS("Mode for pipe %d:\n", pipe);
drm_mode_debug_printmodeline(mode);
@@ -5398,6 +5391,13 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
if (intel_crtc->config.has_pch_encoder) {
struct intel_pch_pll *pll;
+ 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;
+
+ dpll = ironlake_compute_dpll(intel_crtc, &clock, fp);
+
pll = intel_get_pch_pll(intel_crtc, dpll, fp);
if (pll == NULL) {
DRM_DEBUG_DRIVER("failed to find PLL for pipe %d\n",
--
1.7.11.4
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH 2/8] drm/i915: move dp_m_n computation to dp_encoder->compute_config
2013-02-22 0:04 [PATCH 00/10] bpc handling fixes Daniel Vetter
` (2 preceding siblings ...)
2013-02-22 0:04 ` [PATCH 02/10] drm/i915: consolidate pch pll computations a bit Daniel Vetter
@ 2013-02-22 0:04 ` Daniel Vetter
2013-02-22 0:05 ` [PATCH 03/10] drm/i915: fixup 12bpc hdmi dotclock handling Daniel Vetter
` (13 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Daniel Vetter @ 2013-02-22 0:04 UTC (permalink / raw)
To: Intel Graphics Development; +Cc: Daniel Vetter
We need a flag to designate dp encoders and the dp link m_n parameters
in the pipe config for that. And now that the pipe bpp computations
have been moved up and stored in the pipe config, too, we can do this
without losing our sanity.
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
drivers/gpu/drm/i915/intel_display.c | 30 +++++++++++-----------
drivers/gpu/drm/i915/intel_dp.c | 49 +++++++-----------------------------
drivers/gpu/drm/i915/intel_drv.h | 3 ---
3 files changed, 25 insertions(+), 57 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 8335fd5..ab4e52c 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4125,6 +4125,14 @@ static void i9xx_update_pll_dividers(struct drm_crtc *crtc,
}
}
+static void intel_dp_set_m_n(struct intel_crtc *crtc)
+{
+ if (crtc->config.has_pch_encoder)
+ intel_pch_transcoder_set_m_n(crtc, &crtc->config.dp_m_n);
+ else
+ intel_cpu_transcoder_set_m_n(crtc, &crtc->config.dp_m_n);
+}
+
static void vlv_update_pll(struct drm_crtc *crtc,
intel_clock_t *clock, intel_clock_t *reduced_clock,
int num_connectors)
@@ -4132,9 +4140,6 @@ static void vlv_update_pll(struct drm_crtc *crtc,
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 drm_display_mode *adjusted_mode =
- &intel_crtc->config.adjusted_mode;
- struct drm_display_mode *mode = &intel_crtc->config.requested_mode;
int pipe = intel_crtc->pipe;
u32 dpll, mdiv, pdiv;
u32 bestn, bestm1, bestm2, bestp1, bestp2;
@@ -4190,8 +4195,8 @@ static void vlv_update_pll(struct drm_crtc *crtc,
intel_dpio_write(dev_priv, DPIO_FASTCLK_DISABLE, 0x620);
- if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT))
- intel_dp_set_m_n(crtc, mode, adjusted_mode);
+ if (intel_crtc->config.has_dp_encoder)
+ intel_dp_set_m_n(intel_crtc);
I915_WRITE(DPLL(pipe), dpll);
@@ -4237,9 +4242,6 @@ static void i9xx_update_pll(struct drm_crtc *crtc,
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 drm_display_mode *adjusted_mode =
- &intel_crtc->config.adjusted_mode;
- struct drm_display_mode *mode = &intel_crtc->config.requested_mode;
struct intel_encoder *encoder;
int pipe = intel_crtc->pipe;
u32 dpll;
@@ -4314,8 +4316,8 @@ static void i9xx_update_pll(struct drm_crtc *crtc,
if (encoder->pre_pll_enable)
encoder->pre_pll_enable(encoder);
- if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT))
- intel_dp_set_m_n(crtc, mode, adjusted_mode);
+ if (intel_crtc->config.has_dp_encoder)
+ intel_dp_set_m_n(intel_crtc);
I915_WRITE(DPLL(pipe), dpll);
@@ -5529,8 +5531,8 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
} else
intel_put_pch_pll(intel_crtc);
- if (is_dp)
- intel_dp_set_m_n(crtc, mode, adjusted_mode);
+ if (intel_crtc->config.has_dp_encoder)
+ intel_dp_set_m_n(intel_crtc);
for_each_encoder_on_crtc(dev, crtc, encoder)
if (encoder->pre_pll_enable)
@@ -5674,8 +5676,8 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc,
DRM_DEBUG_KMS("Mode for pipe %d:\n", pipe);
drm_mode_debug_printmodeline(mode);
- if (is_dp)
- intel_dp_set_m_n(crtc, mode, adjusted_mode);
+ if (intel_crtc->config.has_dp_encoder)
+ intel_dp_set_m_n(intel_crtc);
intel_crtc->lowfreq_avail = false;
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index a4caf1e..1920fae 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -193,6 +193,8 @@ intel_dp_mode_valid(struct drm_connector *connector,
if (mode->vdisplay > fixed_mode->vdisplay)
return MODE_PANEL;
+
+ target_clock = fixed_mode->clock;
}
max_link_clock = drm_dp_bw_code_to_link_rate(intel_dp_max_link_bw(intel_dp));
@@ -688,6 +690,8 @@ intel_dp_compute_config(struct intel_encoder *encoder,
if (HAS_PCH_SPLIT(dev) && !IS_HASWELL(dev) && !is_cpu_edp(intel_dp))
pipe_config->has_pch_encoder = true;
+ pipe_config->has_dp_encoder = true;
+
if (is_edp(intel_dp) && intel_connector->panel.fixed_mode) {
intel_fixed_panel_mode(intel_connector->panel.fixed_mode,
adjusted_mode);
@@ -707,7 +711,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
/* Walk through all bpp values. Luckily they're all nicely spaced with 2
* bpc in between. */
- bpp = 8*3;
+ bpp = min_t(int, 8*3, pipe_config->pipe_bpp);
if (is_edp(intel_dp) && dev_priv->edp.bpp)
bpp = min_t(int, bpp, dev_priv->edp.bpp);
@@ -756,46 +760,11 @@ found:
DRM_DEBUG_KMS("DP link bw required %i available %i\n",
mode_rate, link_avail);
- return true;
-}
-
-void
-intel_dp_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 intel_encoder *intel_encoder;
- struct intel_dp *intel_dp;
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- int lane_count = 4;
- struct intel_link_m_n m_n;
+ intel_link_compute_m_n(bpp, lane_count,
+ target_clock, adjusted_mode->clock,
+ &pipe_config->dp_m_n);
- /*
- * Find the lane count in the intel_encoder private
- */
- for_each_encoder_on_crtc(dev, crtc, intel_encoder) {
- intel_dp = enc_to_intel_dp(&intel_encoder->base);
-
- if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT ||
- intel_encoder->type == INTEL_OUTPUT_EDP)
- {
- lane_count = intel_dp->lane_count;
- break;
- }
- }
-
- /*
- * Compute the GMCH and Link ratios. The '3' here is
- * the number of bytes_per_pixel post-LUT, which we always
- * set up for 8-bits of R/G/B, or 3 bytes total.
- */
- intel_link_compute_m_n(intel_crtc->config.pipe_bpp, lane_count,
- mode->clock, adjusted_mode->clock, &m_n);
-
- if (intel_crtc->config.has_pch_encoder)
- intel_pch_transcoder_set_m_n(intel_crtc, &m_n);
- else
- intel_cpu_transcoder_set_m_n(intel_crtc, &m_n);
+ return true;
}
void intel_dp_init_link_config(struct intel_dp *intel_dp)
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index aa4dee4..76c5273 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -468,9 +468,6 @@ extern void intel_dp_init(struct drm_device *dev, int output_reg,
enum port port);
extern void intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
struct intel_connector *intel_connector);
-void
-intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode);
extern void intel_dp_init_link_config(struct intel_dp *intel_dp);
extern void intel_dp_start_link_train(struct intel_dp *intel_dp);
extern void intel_dp_complete_link_train(struct intel_dp *intel_dp);
--
1.7.11.4
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH 03/10] drm/i915: fixup 12bpc hdmi dotclock handling
2013-02-22 0:04 [PATCH 00/10] bpc handling fixes Daniel Vetter
` (3 preceding siblings ...)
2013-02-22 0:04 ` [PATCH 2/8] drm/i915: move dp_m_n computation to dp_encoder->compute_config Daniel Vetter
@ 2013-02-22 0:05 ` Daniel Vetter
2013-02-22 0:05 ` [PATCH 3/8] drm/i915: track dp target_clock in pipe_config Daniel Vetter
` (12 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Daniel Vetter @ 2013-02-22 0:05 UTC (permalink / raw)
To: Intel Graphics Development; +Cc: Daniel Vetter
We need to multiply the hdmi port dotclock by 1.5x since it's not
really a dotclock, but the 10/8 encoding bitclock divided by 10.
Also add correct limit checks for the dotclock and reject modes which
don't fit. HDMI 1.4 would allow more, but our hw doesn't support that
unfortunately :(
Somehow I suspect 12bpc hdmi output never really worked - we really
need an i-g-t testcase to check all the different pixel modes and
outputs.
v2: Fixup the adjusted port clock handling - we need to make sure that
the fdi link code still gets the real pixelclock.
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
drivers/gpu/drm/i915/intel_hdmi.c | 23 ++++++++++++++++++-----
1 file changed, 18 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index 0e51b2b..27542c9 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -779,6 +779,7 @@ bool intel_hdmi_compute_config(struct intel_encoder *encoder,
struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
struct drm_device *dev = encoder->base.dev;
struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
+ int clock_12bpc = pipe_config->requested_mode.clock * 3 / 2;
if (intel_hdmi->color_range_auto) {
/* See CEA-861-E - 5.1 Default Encoding Parameters */
@@ -796,19 +797,31 @@ bool intel_hdmi_compute_config(struct intel_encoder *encoder,
pipe_config->has_pch_encoder = true;
/*
- * HDMI is either 12 or 8, so if the display lets 10bpc sneak
- * through, clamp it down. Note that only pch_split platforms have 12bpc
- * pipes, g4x and vlv only has a 10bpc pipe, all earlier platforms have
- * only 8bpc.
+ * HDMI is either 12 or 8, so if the display lets 10bpc sneak through,
+ * clamp it down. Note that only pch_split platforms have 12bpc pipes,
+ * g4x and vlv only has a 10bpc pipe, all earlier platforms have only
+ * 8bpc. We also need to check that the higher clock still fits within
+ * limits. On g4x/vlv we still set the pipe bpp to 12bpc, the crtc fixup
+ * code will then clamp that to 10bpc.
*/
- if (pipe_config->pipe_bpp > 8*3) {
+ if (pipe_config->pipe_bpp > 8*3 && clock_12bpc < 225000) {
DRM_DEBUG_KMS("forcing bpc to 12 for HDMI\n");
pipe_config->pipe_bpp = 12*3;
+
+ /* Need to adjust the port link by 1.5x for 12bpc. */
+ adjusted_mode->clock = clock_12bpc;
+ pipe_config->pixel_target_clock =
+ pipe_config->requested_mode.clock;
} else {
DRM_DEBUG_KMS("forcing bpc to 8 for HDMI\n");
pipe_config->pipe_bpp = 8*3;
}
+ if (adjusted_mode->clock > 225000) {
+ DRM_DEBUG_KMS("too high HDMI clock, rejecting mode\n");
+ return false;
+ }
+
return true;
}
--
1.7.11.4
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH 3/8] drm/i915: track dp target_clock in pipe_config
2013-02-22 0:04 [PATCH 00/10] bpc handling fixes Daniel Vetter
` (4 preceding siblings ...)
2013-02-22 0:05 ` [PATCH 03/10] drm/i915: fixup 12bpc hdmi dotclock handling Daniel Vetter
@ 2013-02-22 0:05 ` Daniel Vetter
2013-02-22 0:05 ` [PATCH 04/10] drm/i915: Disable high-bpc on pre-1.4 EDID screens Daniel Vetter
` (11 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Daniel Vetter @ 2013-02-22 0:05 UTC (permalink / raw)
To: Intel Graphics Development; +Cc: Daniel Vetter
We need it in the fdi m_n computation, which nicely kills almost
all ugly special cases in there.
It looks like we also need this to handle 12bpc hdmi correctly.
Eventually it might be better to switch things around and put the
target clock into adjusted_mode->clock and create a new pipe_config
parameter for the port link clock.
v2: Add a massive comment in the code to explain this mess.
v3: s/dp_target_clock/pixel_target_clock in anticipation of the hdmi
use-case.
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
drivers/gpu/drm/i915/intel_display.c | 25 +++----------------------
drivers/gpu/drm/i915/intel_dp.c | 1 +
drivers/gpu/drm/i915/intel_drv.h | 7 ++++++-
3 files changed, 10 insertions(+), 23 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index ab4e52c..09dda9d 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -5297,25 +5297,9 @@ static void ironlake_fdi_set_m_n(struct drm_crtc *crtc)
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct drm_display_mode *adjusted_mode =
&intel_crtc->config.adjusted_mode;
- struct drm_display_mode *mode = &intel_crtc->config.requested_mode;
- struct intel_encoder *intel_encoder, *edp_encoder = NULL;
struct intel_link_m_n m_n = {0};
int target_clock, 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;
- }
- }
+ uint32_t bps;
/* FDI is a binary signal running at ~2.7GHz, encoding
* each output octet as 10 bits. The actual frequency
@@ -5326,11 +5310,8 @@ static void ironlake_fdi_set_m_n(struct drm_crtc *crtc)
*/
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;
+ if (intel_crtc->config.pixel_target_clock)
+ target_clock = intel_crtc->config.pixel_target_clock;
else
target_clock = adjusted_mode->clock;
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 1920fae..3261242 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -753,6 +753,7 @@ found:
intel_dp->lane_count = lane_count;
adjusted_mode->clock = drm_dp_bw_code_to_link_rate(intel_dp->link_bw);
pipe_config->pipe_bpp = bpp;
+ pipe_config->pixel_target_clock = target_clock;
DRM_DEBUG_KMS("DP link bw %02x lane count %d clock %d bpp %d\n",
intel_dp->link_bw, intel_dp->lane_count,
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 76c5273..eab5559 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -197,7 +197,12 @@ struct intel_crtc_config {
bool dither;
int pipe_bpp;
struct intel_link_m_n dp_m_n;
-
+ /**
+ * This is currently used by DP and HDMI encoders since those can have a
+ * target pixel clock != the port link clock (which is currently stored
+ * in adjusted_mode->clock).
+ */
+ int pixel_target_clock;
/* Used by SDVO (and if we ever fix it, HDMI). */
unsigned pixel_multiplier;
};
--
1.7.11.4
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH 04/10] drm/i915: Disable high-bpc on pre-1.4 EDID screens
2013-02-22 0:04 [PATCH 00/10] bpc handling fixes Daniel Vetter
` (5 preceding siblings ...)
2013-02-22 0:05 ` [PATCH 3/8] drm/i915: track dp target_clock in pipe_config Daniel Vetter
@ 2013-02-22 0:05 ` Daniel Vetter
2013-02-22 0:05 ` [PATCH 4/8] drm/i915: rip out superflous is_dp&is_cpu_edp tracking Daniel Vetter
` (10 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Daniel Vetter @ 2013-02-22 0:05 UTC (permalink / raw)
To: Intel Graphics Development; +Cc: Daniel Vetter
Prevents black screens when using 30bpp framebuffers on my
HDMI screens here. The DP input on the same screen though reports a
1.4 EDID with the correct 8bpc limit set.
v2: Actually check for the right thing!
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
drivers/gpu/drm/i915/intel_display.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index c7f6dcb..ff35876 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -7317,6 +7317,13 @@ pipe_config_set_bpp(struct drm_crtc *crtc,
bpp, connector->display_info.bpc*3);
pipe_config->pipe_bpp = connector->display_info.bpc*3;
}
+
+ /* Clamp bpp to 8 on screens without EDID 1.4 */
+ if (connector->display_info.bpc == 0 && bpp > 24) {
+ DRM_DEBUG_KMS("clamping display bpp (was %d) to default limit of 24\n",
+ bpp);
+ pipe_config->pipe_bpp = 24;
+ }
}
return bpp;
--
1.7.11.4
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH 4/8] drm/i915: rip out superflous is_dp&is_cpu_edp tracking
2013-02-22 0:04 [PATCH 00/10] bpc handling fixes Daniel Vetter
` (6 preceding siblings ...)
2013-02-22 0:05 ` [PATCH 04/10] drm/i915: Disable high-bpc on pre-1.4 EDID screens Daniel Vetter
@ 2013-02-22 0:05 ` Daniel Vetter
2013-02-22 0:05 ` [PATCH 5/8] drm/i915: add hw state readout/checking for pipe_config Daniel Vetter
` (9 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Daniel Vetter @ 2013-02-22 0:05 UTC (permalink / raw)
To: Intel Graphics Development; +Cc: Daniel Vetter
The only exception left is is_cpu_edp in the haswell modeset code.
We need that to assign the cpu transcoder, but we might want to
move that eventually into the encoder, too.
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
drivers/gpu/drm/i915/intel_display.c | 37 +++++++-----------------------------
1 file changed, 7 insertions(+), 30 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 09dda9d..d4efe97 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4475,7 +4475,7 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc,
intel_clock_t clock, reduced_clock;
u32 dspcntr, pipeconf;
bool ok, has_reduced_clock = false, is_sdvo = false;
- bool is_lvds = false, is_tv = false, is_dp = false;
+ bool is_lvds = false, is_tv = false;
struct intel_encoder *encoder;
const intel_limit_t *limit;
int ret;
@@ -4494,9 +4494,6 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc,
case INTEL_OUTPUT_TVOUT:
is_tv = true;
break;
- case INTEL_OUTPUT_DISPLAYPORT:
- is_dp = true;
- break;
}
num_connectors++;
@@ -4577,7 +4574,7 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc,
/* default to 8bpc */
pipeconf &= ~(PIPECONF_BPC_MASK | PIPECONF_DITHER_EN);
- if (is_dp) {
+ if (intel_crtc->config.has_dp_encoder) {
if (intel_crtc->config.dither) {
pipeconf |= PIPECONF_6BPC |
PIPECONF_DITHER_EN |
@@ -5338,7 +5335,6 @@ static uint32_t ironlake_compute_dpll(struct intel_crtc *intel_crtc,
uint32_t dpll;
int factor, num_connectors = 0;
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) {
@@ -5354,14 +5350,6 @@ static uint32_t ironlake_compute_dpll(struct intel_crtc *intel_crtc,
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++;
@@ -5393,7 +5381,8 @@ static uint32_t ironlake_compute_dpll(struct intel_crtc *intel_crtc,
}
dpll |= DPLL_DVO_HIGH_SPEED;
}
- if (is_dp && !is_cpu_edp)
+ if (intel_crtc->config.has_dp_encoder &&
+ intel_crtc->config.has_pch_encoder)
dpll |= DPLL_DVO_HIGH_SPEED;
/* compute bitmask from p1 value */
@@ -5446,7 +5435,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
intel_clock_t clock, reduced_clock;
u32 dpll, fp = 0, fp2 = 0;
bool ok, has_reduced_clock = false;
- bool is_lvds = false, is_dp = false, is_cpu_edp = false;
+ bool is_lvds = false;
struct intel_encoder *encoder;
int ret;
bool dither, fdi_config_ok;
@@ -5456,14 +5445,6 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
case INTEL_OUTPUT_LVDS:
is_lvds = 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_cpu_edp = true;
- break;
}
num_connectors++;
@@ -5500,7 +5481,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
drm_mode_debug_printmodeline(mode);
/* CPU eDP is the only output that doesn't need a PCH PLL of its own. */
- if (!is_cpu_edp) {
+ if (intel_crtc->config.has_pch_encoder) {
struct intel_pch_pll *pll;
pll = intel_get_pch_pll(intel_crtc, dpll, fp);
@@ -5613,18 +5594,14 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc,
int pipe = intel_crtc->pipe;
int plane = intel_crtc->plane;
int num_connectors = 0;
- bool is_dp = false, is_cpu_edp = false;
+ bool is_cpu_edp = false;
struct intel_encoder *encoder;
int ret;
bool dither;
for_each_encoder_on_crtc(dev, crtc, encoder) {
switch (encoder->type) {
- case INTEL_OUTPUT_DISPLAYPORT:
- is_dp = true;
- break;
case INTEL_OUTPUT_EDP:
- is_dp = true;
if (!intel_encoder_is_pch_edp(&encoder->base))
is_cpu_edp = true;
break;
--
1.7.11.4
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH 5/8] drm/i915: add hw state readout/checking for pipe_config
2013-02-22 0:04 [PATCH 00/10] bpc handling fixes Daniel Vetter
` (7 preceding siblings ...)
2013-02-22 0:05 ` [PATCH 4/8] drm/i915: rip out superflous is_dp&is_cpu_edp tracking Daniel Vetter
@ 2013-02-22 0:05 ` Daniel Vetter
2013-02-22 0:05 ` [PATCH 05/10] drm/i915: force bpp for eDP panels Daniel Vetter
` (8 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Daniel Vetter @ 2013-02-22 0:05 UTC (permalink / raw)
To: Intel Graphics Development; +Cc: Daniel Vetter
We need to be able to read out the hw state code for a bunch
of reasons:
- Correctly disabling boot-up/resume state.
- Pure paranoia.
Since not all of the pipe configuration is e.g. relevant for
fastboot (or at least we can allow some wiggle room in some
parameters, like the clocks), we need to add a strict_checking
parameter to intel_pipe_config_compare for fastboot.
For now intel_pipe_config_compare should be fully paranoid and
check everything that the hw state readout code supports. Which
for this infrastructure code is nothing.
I've gone a bit overboard with adding 3 get_pipe_config functions:
The ilk version will differ with the next patch, so it's not too
onerous.
v2: Don't check the hw config if the pipe is off, since an enabled,
but dpms off crtc will obviously have tons of difference with the hw
state.
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
drivers/gpu/drm/i915/i915_drv.h | 5 +++
drivers/gpu/drm/i915/intel_display.c | 77 +++++++++++++++++++++++++++++++-----
2 files changed, 72 insertions(+), 10 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 8fb14fb..7484ea8 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -272,6 +272,7 @@ struct drm_i915_error_state {
};
struct intel_crtc_config;
+struct intel_crtc;
struct drm_i915_display_funcs {
bool (*fbc_enabled)(struct drm_device *dev);
@@ -285,6 +286,10 @@ struct drm_i915_display_funcs {
void (*update_linetime_wm)(struct drm_device *dev, int pipe,
struct drm_display_mode *mode);
void (*modeset_global_resources)(struct drm_device *dev);
+ /* Returns the active state of the crtc, and if the crtc is active,
+ * fills out the pipe-config with the hw state. */
+ bool (*get_pipe_config)(struct intel_crtc *,
+ struct intel_crtc_config *);
int (*crtc_mode_set)(struct drm_crtc *crtc,
int x, int y,
struct drm_framebuffer *old_fb);
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index d4efe97..ba9adf7 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4636,6 +4636,20 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc,
return ret;
}
+static bool i9xx_get_pipe_config(struct intel_crtc *crtc,
+ struct intel_crtc_config *pipe_config)
+{
+ struct drm_device *dev = crtc->base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ uint32_t tmp;
+
+ tmp = I915_READ(PIPECONF(crtc->pipe));
+ if (!(tmp & PIPECONF_ENABLE))
+ return false;
+
+ return true;
+}
+
static void ironlake_init_pch_refclk(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -5296,7 +5310,6 @@ static void ironlake_fdi_set_m_n(struct drm_crtc *crtc)
&intel_crtc->config.adjusted_mode;
struct intel_link_m_n m_n = {0};
int target_clock, lane, link_bw;
- uint32_t bps;
/* FDI is a binary signal running at ~2.7GHz, encoding
* each output octet as 10 bits. The actual frequency
@@ -5552,6 +5565,20 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
return fdi_config_ok ? ret : -EINVAL;
}
+static bool ironlake_get_pipe_config(struct intel_crtc *crtc,
+ struct intel_crtc_config *pipe_config)
+{
+ struct drm_device *dev = crtc->base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ uint32_t tmp;
+
+ tmp = I915_READ(PIPECONF(crtc->pipe));
+ if (!(tmp & PIPECONF_ENABLE))
+ return false;
+
+ return true;
+}
+
static void haswell_modeset_global_resources(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -5661,6 +5688,20 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc,
return ret;
}
+static bool haswell_get_pipe_config(struct intel_crtc *crtc,
+ struct intel_crtc_config *pipe_config)
+{
+ struct drm_device *dev = crtc->base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ uint32_t tmp;
+
+ tmp = I915_READ(PIPECONF(crtc->cpu_transcoder));
+ if (!(tmp & PIPECONF_ENABLE))
+ return false;
+
+ return true;
+}
+
static int intel_crtc_mode_set(struct drm_crtc *crtc,
int x, int y,
struct drm_framebuffer *fb)
@@ -7596,12 +7637,21 @@ intel_modeset_update_state(struct drm_device *dev, unsigned prepare_pipes)
base.head) \
if (mask & (1 <<(intel_crtc)->pipe)) \
+static bool
+intel_pipe_config_compare(struct intel_crtc_config *current_config,
+ struct intel_crtc_config *pipe_config)
+{
+ return true;
+}
+
void
intel_modeset_check_state(struct drm_device *dev)
{
+ drm_i915_private_t *dev_priv = dev->dev_private;
struct intel_crtc *crtc;
struct intel_encoder *encoder;
struct intel_connector *connector;
+ struct intel_crtc_config pipe_config;
list_for_each_entry(connector, &dev->mode_config.connector_list,
base.head) {
@@ -7690,7 +7740,15 @@ intel_modeset_check_state(struct drm_device *dev)
"crtc's computed enabled state doesn't match tracked enabled state "
"(expected %i, found %i)\n", enabled, crtc->base.enabled);
- assert_pipe(dev->dev_private, crtc->pipe, crtc->active);
+ active = dev_priv->display.get_pipe_config(crtc,
+ &pipe_config);
+ WARN(crtc->active != active,
+ "crtc active state doesn't match with hw state "
+ "(expected %i, found %i)\n", crtc->active, active);
+
+ WARN(active &&
+ !intel_pipe_config_compare(&crtc->config, &pipe_config),
+ "pipe state doesn't match!\n");
}
}
@@ -8502,18 +8560,21 @@ static void intel_init_display(struct drm_device *dev)
/* We always want a DPMS function */
if (HAS_DDI(dev)) {
+ dev_priv->display.get_pipe_config = haswell_get_pipe_config;
dev_priv->display.crtc_mode_set = haswell_crtc_mode_set;
dev_priv->display.crtc_enable = haswell_crtc_enable;
dev_priv->display.crtc_disable = haswell_crtc_disable;
dev_priv->display.off = haswell_crtc_off;
dev_priv->display.update_plane = ironlake_update_plane;
} else if (HAS_PCH_SPLIT(dev)) {
+ dev_priv->display.get_pipe_config = ironlake_get_pipe_config;
dev_priv->display.crtc_mode_set = ironlake_crtc_mode_set;
dev_priv->display.crtc_enable = ironlake_crtc_enable;
dev_priv->display.crtc_disable = ironlake_crtc_disable;
dev_priv->display.off = ironlake_crtc_off;
dev_priv->display.update_plane = ironlake_update_plane;
} else {
+ dev_priv->display.get_pipe_config = i9xx_get_pipe_config;
dev_priv->display.crtc_mode_set = i9xx_crtc_mode_set;
dev_priv->display.crtc_enable = i9xx_crtc_enable;
dev_priv->display.crtc_disable = i9xx_crtc_disable;
@@ -9034,14 +9095,10 @@ void intel_modeset_setup_hw_state(struct drm_device *dev,
}
}
- for_each_pipe(pipe) {
- crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]);
-
- tmp = I915_READ(PIPECONF(crtc->cpu_transcoder));
- if (tmp & PIPECONF_ENABLE)
- crtc->active = true;
- else
- crtc->active = false;
+ list_for_each_entry(crtc, &dev->mode_config.crtc_list,
+ base.head) {
+ crtc->active = dev_priv->display.get_pipe_config(crtc,
+ &crtc->config);
crtc->base.enabled = crtc->active;
--
1.7.11.4
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH 05/10] drm/i915: force bpp for eDP panels
2013-02-22 0:04 [PATCH 00/10] bpc handling fixes Daniel Vetter
` (8 preceding siblings ...)
2013-02-22 0:05 ` [PATCH 5/8] drm/i915: add hw state readout/checking for pipe_config Daniel Vetter
@ 2013-02-22 0:05 ` Daniel Vetter
2013-02-22 6:50 ` Jani Nikula
2013-02-22 0:05 ` [PATCH 06/10] drm/i915: extract i9xx_set_pipeconf Daniel Vetter
` (7 subsequent siblings)
17 siblings, 1 reply; 21+ messages in thread
From: Daniel Vetter @ 2013-02-22 0:05 UTC (permalink / raw)
To: Intel Graphics Development; +Cc: Jani Nikula, Daniel Vetter
We'ev had our fair share of woes already which showed that we can't
rely on the bpc limits in the EDID for eDP panels without risking
black screens. So now we limit the depth by what the BIOS recommends
in the VBT:
commit 2f4f649a69a9eb51f6e98130e19dd90a260a4145
Author: Jani Nikula <jani.nikula@intel.com>
Date: Mon Nov 12 14:33:44 2012 +0200
drm/i915: do not ignore eDP bpc settings from vbt
But that's not enough, since at least the panel on my ASUS Zenbook
Prime here is also unhappy if the bpc is too low. Hence just take the
firmware value and dither to get what flimsy panels want.
Like before we ensure that we don't change the bpp if the firmware
doesn't proved a value, see
commit 2f4f649a69a9eb51f6e98130e19dd90a260a4145
Author: Jani Nikula <jani.nikula@intel.com>
Date: Mon Nov 12 14:33:44 2012 +0200
drm/i915: do not ignore eDP bpc settings from vbt
Cc: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
drivers/gpu/drm/i915/intel_dp.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 83e3791..81693fc 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -755,8 +755,15 @@ intel_dp_compute_config(struct intel_encoder *encoder,
/* Walk through all bpp values. Luckily they're all nicely spaced with 2
* bpc in between. */
bpp = min_t(int, 8*3, pipe_config->pipe_bpp);
- if (is_edp(intel_dp) && dev_priv->edp.bpp)
- bpp = min_t(int, bpp, dev_priv->edp.bpp);
+
+ /* eDP panels are really fickle, try to enfore the bpp the firmware
+ * recomments. This means we'll up-dither 16bpp framebuffers on
+ * high-depth panels. */
+ if (is_edp(intel_dp) && dev_priv->edp.bpp) {
+ DRM_DEBUG_KMS("forcing bpp for eDP panel to BIOS-provided %i\n",
+ dev_priv->edp.bpp);
+ bpp = dev_priv->edp.bpp;
+ }
for (; bpp >= 6*3; bpp -= 2*3) {
mode_rate = intel_dp_link_required(target_clock, bpp);
--
1.7.11.4
^ permalink raw reply related [flat|nested] 21+ messages in thread* Re: [PATCH 05/10] drm/i915: force bpp for eDP panels
2013-02-22 0:05 ` [PATCH 05/10] drm/i915: force bpp for eDP panels Daniel Vetter
@ 2013-02-22 6:50 ` Jani Nikula
2013-02-22 11:10 ` [PATCH] " Daniel Vetter
0 siblings, 1 reply; 21+ messages in thread
From: Jani Nikula @ 2013-02-22 6:50 UTC (permalink / raw)
To: Intel Graphics Development; +Cc: Daniel Vetter
On Fri, 22 Feb 2013, Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
> We'ev had our fair share of woes already which showed that we can't
^^
> rely on the bpc limits in the EDID for eDP panels without risking
> black screens. So now we limit the depth by what the BIOS recommends
> in the VBT:
>
> commit 2f4f649a69a9eb51f6e98130e19dd90a260a4145
> Author: Jani Nikula <jani.nikula@intel.com>
> Date: Mon Nov 12 14:33:44 2012 +0200
>
> drm/i915: do not ignore eDP bpc settings from vbt
>
> But that's not enough, since at least the panel on my ASUS Zenbook
> Prime here is also unhappy if the bpc is too low. Hence just take the
> firmware value and dither to get what flimsy panels want.
>
> Like before we ensure that we don't change the bpp if the firmware
> doesn't proved a value, see
s/proved/provide/
> commit 2f4f649a69a9eb51f6e98130e19dd90a260a4145
> Author: Jani Nikula <jani.nikula@intel.com>
> Date: Mon Nov 12 14:33:44 2012 +0200
>
> drm/i915: do not ignore eDP bpc settings from vbt
That's the same reference as above. Perhaps you mean:
commit 9a30a61f3516871c5c638fd7c025fbaa11ddf7fe
Author: Jani Nikula <jani.nikula@intel.com>
Date: Mon Nov 12 14:33:45 2012 +0200
drm/i915: do not default to 18 bpp for eDP if missing from VBT
With that and a few typos here and there sorted out,
Reviewed-by: Jani Nikula <jani.nikula@intel.com>
> Cc: Jani Nikula <jani.nikula@intel.com>
> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> ---
> drivers/gpu/drm/i915/intel_dp.c | 11 +++++++++--
> 1 file changed, 9 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index 83e3791..81693fc 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -755,8 +755,15 @@ intel_dp_compute_config(struct intel_encoder *encoder,
> /* Walk through all bpp values. Luckily they're all nicely spaced with 2
> * bpc in between. */
> bpp = min_t(int, 8*3, pipe_config->pipe_bpp);
> - if (is_edp(intel_dp) && dev_priv->edp.bpp)
> - bpp = min_t(int, bpp, dev_priv->edp.bpp);
> +
> + /* eDP panels are really fickle, try to enfore the bpp the firmware
^
> + * recomments. This means we'll up-dither 16bpp framebuffers on
^
> + * high-depth panels. */
> + if (is_edp(intel_dp) && dev_priv->edp.bpp) {
> + DRM_DEBUG_KMS("forcing bpp for eDP panel to BIOS-provided %i\n",
> + dev_priv->edp.bpp);
> + bpp = dev_priv->edp.bpp;
> + }
>
> for (; bpp >= 6*3; bpp -= 2*3) {
> mode_rate = intel_dp_link_required(target_clock, bpp);
> --
> 1.7.11.4
^ permalink raw reply [flat|nested] 21+ messages in thread* [PATCH] drm/i915: force bpp for eDP panels
2013-02-22 6:50 ` Jani Nikula
@ 2013-02-22 11:10 ` Daniel Vetter
0 siblings, 0 replies; 21+ messages in thread
From: Daniel Vetter @ 2013-02-22 11:10 UTC (permalink / raw)
To: Intel Graphics Development; +Cc: Jani Nikula, Daniel Vetter
We've had our fair share of woes already which showed that we can't
rely on the bpc limits in the EDID for eDP panels without risking
black screens. So now we limit the depth by what the BIOS recommends
in the VBT:
commit 2f4f649a69a9eb51f6e98130e19dd90a260a4145
Author: Jani Nikula <jani.nikula@intel.com>
Date: Mon Nov 12 14:33:44 2012 +0200
drm/i915: do not ignore eDP bpc settings from vbt
But that's not enough, since at least the panel on my ASUS Zenbook
Prime here is also unhappy if the bpc is too low. Hence just take the
firmware value and dither to get what flimsy panels want.
Like before we ensure that we don't change the bpp if the firmware
doesn't provide a value, see
commit 9a30a61f3516871c5c638fd7c025fbaa11ddf7fe
Author: Jani Nikula <jani.nikula@intel.com>
Date: Mon Nov 12 14:33:45 2012 +0200
drm/i915: do not default to 18 bpp for eDP if missing from VBT
Cc: Jani Nikula <jani.nikula@intel.com>
Reviewed-by: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
drivers/gpu/drm/i915/intel_dp.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 83e3791..81693fc 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -755,8 +755,15 @@ intel_dp_compute_config(struct intel_encoder *encoder,
/* Walk through all bpp values. Luckily they're all nicely spaced with 2
* bpc in between. */
bpp = min_t(int, 8*3, pipe_config->pipe_bpp);
- if (is_edp(intel_dp) && dev_priv->edp.bpp)
- bpp = min_t(int, bpp, dev_priv->edp.bpp);
+
+ /* eDP panels are really fickle, try to enfore the bpp the firmware
+ * recomments. This means we'll up-dither 16bpp framebuffers on
+ * high-depth panels. */
+ if (is_edp(intel_dp) && dev_priv->edp.bpp) {
+ DRM_DEBUG_KMS("forcing bpp for eDP panel to BIOS-provided %i\n",
+ dev_priv->edp.bpp);
+ bpp = dev_priv->edp.bpp;
+ }
for (; bpp >= 6*3; bpp -= 2*3) {
mode_rate = intel_dp_link_required(target_clock, bpp);
--
1.7.11.4
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 06/10] drm/i915: extract i9xx_set_pipeconf
2013-02-22 0:04 [PATCH 00/10] bpc handling fixes Daniel Vetter
` (9 preceding siblings ...)
2013-02-22 0:05 ` [PATCH 05/10] drm/i915: force bpp for eDP panels Daniel Vetter
@ 2013-02-22 0:05 ` Daniel Vetter
2013-02-22 0:05 ` [PATCH 6/8] drm/i915: hw readout support for ->has_pch_encoders Daniel Vetter
` (6 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Daniel Vetter @ 2013-02-22 0:05 UTC (permalink / raw)
To: Intel Graphics Development; +Cc: Daniel Vetter
Prep-patch to improve the bpc handling in a next patch.
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
drivers/gpu/drm/i915/intel_display.c | 120 +++++++++++++++++++----------------
1 file changed, 65 insertions(+), 55 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index ff35876..27ecc35 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4353,6 +4353,68 @@ static void intel_set_pipe_timings(struct intel_crtc *intel_crtc,
((mode->hdisplay - 1) << 16) | (mode->vdisplay - 1));
}
+static void i9xx_set_pipeconf(struct intel_crtc *intel_crtc)
+{
+ struct drm_device *dev = intel_crtc->base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ uint32_t pipeconf;
+
+ pipeconf = I915_READ(PIPECONF(intel_crtc->pipe));
+
+ if (intel_crtc->pipe == 0 && INTEL_INFO(dev)->gen < 4) {
+ /* Enable pixel doubling when the dot clock is > 90% of the (display)
+ * core speed.
+ *
+ * XXX: No double-wide on 915GM pipe B. Is that the only reason for the
+ * pipe == 0 check?
+ */
+ if (intel_crtc->config.requested_mode.clock >
+ dev_priv->display.get_display_clock_speed(dev) * 9 / 10)
+ pipeconf |= PIPECONF_DOUBLE_WIDE;
+ else
+ pipeconf &= ~PIPECONF_DOUBLE_WIDE;
+ }
+
+ /* default to 8bpc */
+ pipeconf &= ~(PIPECONF_BPC_MASK | PIPECONF_DITHER_EN);
+ if (intel_crtc->config.has_dp_encoder) {
+ if (intel_crtc->config.dither) {
+ pipeconf |= PIPECONF_6BPC |
+ PIPECONF_DITHER_EN |
+ PIPECONF_DITHER_TYPE_SP;
+ }
+ }
+
+ if (IS_VALLEYVIEW(dev) && intel_pipe_has_type(&intel_crtc->base,
+ INTEL_OUTPUT_EDP)) {
+ if (intel_crtc->config.dither) {
+ pipeconf |= PIPECONF_6BPC |
+ PIPECONF_ENABLE |
+ I965_PIPECONF_ACTIVE;
+ }
+ }
+
+ if (HAS_PIPE_CXSR(dev)) {
+ if (intel_crtc->lowfreq_avail) {
+ DRM_DEBUG_KMS("enabling CxSR downclocking\n");
+ pipeconf |= PIPECONF_CXSR_DOWNCLOCK;
+ } else {
+ DRM_DEBUG_KMS("disabling CxSR downclocking\n");
+ pipeconf &= ~PIPECONF_CXSR_DOWNCLOCK;
+ }
+ }
+
+ pipeconf &= ~PIPECONF_INTERLACE_MASK;
+ if (!IS_GEN2(dev) &&
+ intel_crtc->config.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
+ pipeconf |= PIPECONF_INTERLACE_W_FIELD_INDICATION;
+ else
+ pipeconf |= PIPECONF_PROGRESSIVE;
+
+ I915_WRITE(PIPECONF(intel_crtc->pipe), pipeconf);
+ POSTING_READ(PIPECONF(intel_crtc->pipe));
+}
+
static int i9xx_crtc_mode_set(struct drm_crtc *crtc,
int x, int y,
struct drm_framebuffer *fb)
@@ -4367,7 +4429,7 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc,
int plane = intel_crtc->plane;
int refclk, num_connectors = 0;
intel_clock_t clock, reduced_clock;
- u32 dspcntr, pipeconf;
+ u32 dspcntr;
bool ok, has_reduced_clock = false, is_sdvo = false;
bool is_lvds = false, is_tv = false;
struct intel_encoder *encoder;
@@ -4447,9 +4509,6 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc,
has_reduced_clock ? &reduced_clock : NULL,
num_connectors);
- /* setup pipeconf */
- pipeconf = I915_READ(PIPECONF(pipe));
-
/* Set up the display plane register */
dspcntr = DISPPLANE_GAMMA_ENABLE;
@@ -4458,58 +4517,9 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc,
else
dspcntr |= DISPPLANE_SEL_PIPE_B;
- if (pipe == 0 && INTEL_INFO(dev)->gen < 4) {
- /* Enable pixel doubling when the dot clock is > 90% of the (display)
- * core speed.
- *
- * XXX: No double-wide on 915GM pipe B. Is that the only reason for the
- * pipe == 0 check?
- */
- if (mode->clock >
- dev_priv->display.get_display_clock_speed(dev) * 9 / 10)
- pipeconf |= PIPECONF_DOUBLE_WIDE;
- else
- pipeconf &= ~PIPECONF_DOUBLE_WIDE;
- }
-
- /* default to 8bpc */
- pipeconf &= ~(PIPECONF_BPC_MASK | PIPECONF_DITHER_EN);
- if (intel_crtc->config.has_dp_encoder) {
- if (intel_crtc->config.dither) {
- pipeconf |= PIPECONF_6BPC |
- PIPECONF_DITHER_EN |
- PIPECONF_DITHER_TYPE_SP;
- }
- }
-
- if (IS_VALLEYVIEW(dev) && intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP)) {
- if (intel_crtc->config.dither) {
- pipeconf |= PIPECONF_6BPC |
- PIPECONF_ENABLE |
- I965_PIPECONF_ACTIVE;
- }
- }
-
DRM_DEBUG_KMS("Mode for pipe %c:\n", pipe == 0 ? 'A' : 'B');
drm_mode_debug_printmodeline(mode);
- if (HAS_PIPE_CXSR(dev)) {
- if (intel_crtc->lowfreq_avail) {
- DRM_DEBUG_KMS("enabling CxSR downclocking\n");
- pipeconf |= PIPECONF_CXSR_DOWNCLOCK;
- } else {
- DRM_DEBUG_KMS("disabling CxSR downclocking\n");
- pipeconf &= ~PIPECONF_CXSR_DOWNCLOCK;
- }
- }
-
- pipeconf &= ~PIPECONF_INTERLACE_MASK;
- if (!IS_GEN2(dev) &&
- adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
- pipeconf |= PIPECONF_INTERLACE_W_FIELD_INDICATION;
- else
- pipeconf |= PIPECONF_PROGRESSIVE;
-
intel_set_pipe_timings(intel_crtc, mode, adjusted_mode);
/* pipesrc and dspsize control the size that is scaled from,
@@ -4520,8 +4530,8 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc,
(mode->hdisplay - 1));
I915_WRITE(DSPPOS(plane), 0);
- I915_WRITE(PIPECONF(pipe), pipeconf);
- POSTING_READ(PIPECONF(pipe));
+ i9xx_set_pipeconf(intel_crtc);
+
intel_enable_pipe(dev_priv, pipe, false);
intel_wait_for_vblank(dev, pipe);
--
1.7.11.4
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH 6/8] drm/i915: hw readout support for ->has_pch_encoders
2013-02-22 0:04 [PATCH 00/10] bpc handling fixes Daniel Vetter
` (10 preceding siblings ...)
2013-02-22 0:05 ` [PATCH 06/10] drm/i915: extract i9xx_set_pipeconf Daniel Vetter
@ 2013-02-22 0:05 ` Daniel Vetter
2013-02-22 0:05 ` [PATCH 7/8] drm/i915: create pipe_config->dpll for clock state Daniel Vetter
` (5 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Daniel Vetter @ 2013-02-22 0:05 UTC (permalink / raw)
To: Intel Graphics Development; +Cc: Daniel Vetter
Now we can ditch the checks in the Haswell disable code.
v2: add support for Haswell
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
drivers/gpu/drm/i915/intel_display.c | 34 +++++++++++++++++++++++++---------
1 file changed, 25 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index ba9adf7..25eb201 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2945,11 +2945,6 @@ static void intel_crtc_wait_for_pending_flips(struct drm_crtc *crtc)
mutex_unlock(&dev->struct_mutex);
}
-static bool haswell_crtc_driving_pch(struct drm_crtc *crtc)
-{
- return intel_pipe_has_type(crtc, INTEL_OUTPUT_ANALOG);
-}
-
/* Program iCLKIP clock to the desired frequency */
static void lpt_program_iclkip(struct drm_crtc *crtc)
{
@@ -3532,13 +3527,10 @@ static void haswell_crtc_disable(struct drm_crtc *crtc)
int pipe = intel_crtc->pipe;
int plane = intel_crtc->plane;
enum transcoder cpu_transcoder = intel_crtc->cpu_transcoder;
- bool is_pch_port;
if (!intel_crtc->active)
return;
- is_pch_port = haswell_crtc_driving_pch(crtc);
-
for_each_encoder_on_crtc(dev, crtc, encoder)
encoder->disable(encoder);
@@ -3565,7 +3557,7 @@ static void haswell_crtc_disable(struct drm_crtc *crtc)
if (encoder->post_disable)
encoder->post_disable(encoder);
- if (is_pch_port) {
+ if (intel_crtc->config.has_pch_encoder) {
lpt_disable_pch_transcoder(dev_priv);
intel_ddi_fdi_disable(crtc);
}
@@ -5576,6 +5568,9 @@ static bool ironlake_get_pipe_config(struct intel_crtc *crtc,
if (!(tmp & PIPECONF_ENABLE))
return false;
+ if (I915_READ(TRANSCONF(crtc->pipe)) & TRANS_ENABLE)
+ pipe_config->has_pch_encoder = true;
+
return true;
}
@@ -5699,6 +5694,17 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc,
if (!(tmp & PIPECONF_ENABLE))
return false;
+ /*
+ * aswell has only FDI/PCH transcoder A. It is which is connected to
+ * DDI E. So just check whether this pipe is wired to DDI E and whether
+ * the PCH transcoder is on.
+ */
+ tmp = I915_READ(TRANS_DDI_FUNC_CTL(crtc->pipe));
+ if ((tmp & TRANS_DDI_PORT_MASK) == TRANS_DDI_SELECT_PORT(PORT_E) &&
+ I915_READ(TRANSCONF(PIPE_A)) & TRANS_ENABLE)
+ pipe_config->has_pch_encoder = true;
+
+
return true;
}
@@ -7641,6 +7647,14 @@ static bool
intel_pipe_config_compare(struct intel_crtc_config *current_config,
struct intel_crtc_config *pipe_config)
{
+ if (current_config->has_pch_encoder != pipe_config->has_pch_encoder) {
+ DRM_ERROR("mismatch in has_pch_encoder "
+ "(expected %i, found %i)\n",
+ current_config->has_pch_encoder,
+ pipe_config->has_pch_encoder);
+ return false;
+ }
+
return true;
}
@@ -7740,6 +7754,7 @@ intel_modeset_check_state(struct drm_device *dev)
"crtc's computed enabled state doesn't match tracked enabled state "
"(expected %i, found %i)\n", enabled, crtc->base.enabled);
+ memset(&pipe_config, 0, sizeof(pipe_config));
active = dev_priv->display.get_pipe_config(crtc,
&pipe_config);
WARN(crtc->active != active,
@@ -9097,6 +9112,7 @@ void intel_modeset_setup_hw_state(struct drm_device *dev,
list_for_each_entry(crtc, &dev->mode_config.crtc_list,
base.head) {
+ memset(&crtc->config, 0, sizeof(crtc->config));
crtc->active = dev_priv->display.get_pipe_config(crtc,
&crtc->config);
--
1.7.11.4
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH 7/8] drm/i915: create pipe_config->dpll for clock state
2013-02-22 0:04 [PATCH 00/10] bpc handling fixes Daniel Vetter
` (11 preceding siblings ...)
2013-02-22 0:05 ` [PATCH 6/8] drm/i915: hw readout support for ->has_pch_encoders Daniel Vetter
@ 2013-02-22 0:05 ` Daniel Vetter
2013-02-22 0:05 ` [PATCH 07/10] drm/i915: drop adjusted_mode from *_set_pipeconf functions Daniel Vetter
` (4 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Daniel Vetter @ 2013-02-22 0:05 UTC (permalink / raw)
To: Intel Graphics Development; +Cc: Daniel Vetter
Clock computations and handling are highly encoder specific, both in
the optimal clock selection and also in which clocks to use and when
sharing of clocks is possible.
So the best place to do this is somewhere in the encoders, with a
generic fallback for those encoders without special needs. To facility
this, add a pipe_config->clocks_set boolean.
This patch here is only prep work, it simply sets the computed clock
values in pipe_config->dpll, and uses that data in the hw clock
setting functions.
Haswell code isn't touched, simply because Haswell clocks work much
different and need their own infrastructure (with probably a
Haswell-specific config->ddi_clock substruct).
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
drivers/gpu/drm/i915/intel_display.c | 155 +++++++++++++++++++----------------
drivers/gpu/drm/i915/intel_drv.h | 12 +++
2 files changed, 95 insertions(+), 72 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 25eb201..2f9b3ce 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4061,37 +4061,38 @@ static int i9xx_get_refclk(struct drm_crtc *crtc, int num_connectors)
return refclk;
}
-static void i9xx_adjust_sdvo_tv_clock(struct drm_display_mode *adjusted_mode,
- intel_clock_t *clock)
+static void i9xx_adjust_sdvo_tv_clock(struct intel_crtc *crtc)
{
+ unsigned dotclock = crtc->config.adjusted_mode.clock;
+ struct dpll *clock = &crtc->config.dpll;
+
/* SDVO TV has fixed PLL values depend on its clock range,
this mirrors vbios setting. */
- if (adjusted_mode->clock >= 100000
- && adjusted_mode->clock < 140500) {
+ if (dotclock >= 100000 && dotclock < 140500) {
clock->p1 = 2;
clock->p2 = 10;
clock->n = 3;
clock->m1 = 16;
clock->m2 = 8;
- } else if (adjusted_mode->clock >= 140500
- && adjusted_mode->clock <= 200000) {
+ } else if (dotclock >= 140500 && dotclock <= 200000) {
clock->p1 = 1;
clock->p2 = 10;
clock->n = 6;
clock->m1 = 12;
clock->m2 = 8;
}
+
+ crtc->config.clock_set = true;
}
-static void i9xx_update_pll_dividers(struct drm_crtc *crtc,
- intel_clock_t *clock,
+static void i9xx_update_pll_dividers(struct intel_crtc *crtc,
intel_clock_t *reduced_clock)
{
- struct drm_device *dev = crtc->dev;
+ struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- int pipe = intel_crtc->pipe;
+ int pipe = crtc->pipe;
u32 fp, fp2 = 0;
+ struct dpll *clock = &crtc->config.dpll;
if (IS_PINEVIEW(dev)) {
fp = (1 << clock->n) << 16 | clock->m1 << 8 | clock->m2;
@@ -4107,11 +4108,11 @@ static void i9xx_update_pll_dividers(struct drm_crtc *crtc,
I915_WRITE(FP0(pipe), fp);
- intel_crtc->lowfreq_avail = false;
- if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) &&
+ crtc->lowfreq_avail = false;
+ if (intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_LVDS) &&
reduced_clock && i915_powersave) {
I915_WRITE(FP1(pipe), fp2);
- intel_crtc->lowfreq_avail = true;
+ crtc->lowfreq_avail = true;
} else {
I915_WRITE(FP1(pipe), fp);
}
@@ -4125,14 +4126,11 @@ static void intel_dp_set_m_n(struct intel_crtc *crtc)
intel_cpu_transcoder_set_m_n(crtc, &crtc->config.dp_m_n);
}
-static void vlv_update_pll(struct drm_crtc *crtc,
- intel_clock_t *clock, intel_clock_t *reduced_clock,
- int num_connectors)
+static void vlv_update_pll(struct intel_crtc *crtc)
{
- struct drm_device *dev = crtc->dev;
+ struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- int pipe = intel_crtc->pipe;
+ int pipe = crtc->pipe;
u32 dpll, mdiv, pdiv;
u32 bestn, bestm1, bestm2, bestp1, bestp2;
bool is_sdvo;
@@ -4140,8 +4138,8 @@ static void vlv_update_pll(struct drm_crtc *crtc,
mutex_lock(&dev_priv->dpio_lock);
- is_sdvo = intel_pipe_has_type(crtc, INTEL_OUTPUT_SDVO) ||
- intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI);
+ is_sdvo = intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_SDVO) ||
+ intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_HDMI);
dpll = DPLL_VGA_MODE_DIS;
dpll |= DPLL_EXT_BUFFER_ENABLE_VLV;
@@ -4151,11 +4149,11 @@ static void vlv_update_pll(struct drm_crtc *crtc,
I915_WRITE(DPLL(pipe), dpll);
POSTING_READ(DPLL(pipe));
- bestn = clock->n;
- bestm1 = clock->m1;
- bestm2 = clock->m2;
- bestp1 = clock->p1;
- bestp2 = clock->p2;
+ bestn = crtc->config.dpll.n;
+ bestm1 = crtc->config.dpll.m1;
+ bestm2 = crtc->config.dpll.m2;
+ bestp1 = crtc->config.dpll.p1;
+ bestp2 = crtc->config.dpll.p2;
/*
* In Valleyview PLL and program lane counter registers are exposed
@@ -4187,8 +4185,8 @@ static void vlv_update_pll(struct drm_crtc *crtc,
intel_dpio_write(dev_priv, DPIO_FASTCLK_DISABLE, 0x620);
- if (intel_crtc->config.has_dp_encoder)
- intel_dp_set_m_n(intel_crtc);
+ if (crtc->config.has_dp_encoder)
+ intel_dp_set_m_n(crtc);
I915_WRITE(DPLL(pipe), dpll);
@@ -4199,8 +4197,8 @@ static void vlv_update_pll(struct drm_crtc *crtc,
temp = 0;
if (is_sdvo) {
temp = 0;
- if (intel_crtc->config.pixel_multiplier > 1) {
- temp = (intel_crtc->config.pixel_multiplier - 1)
+ if (crtc->config.pixel_multiplier > 1) {
+ temp = (crtc->config.pixel_multiplier - 1)
<< DPLL_MD_UDI_MULTIPLIER_SHIFT;
}
}
@@ -4208,16 +4206,15 @@ static void vlv_update_pll(struct drm_crtc *crtc,
POSTING_READ(DPLL_MD(pipe));
/* Now program lane control registers */
- if(intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)
- || intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI))
- {
+ if(intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_DISPLAYPORT)
+ || intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_HDMI)) {
temp = 0x1000C4;
if(pipe == 1)
temp |= (1 << 21);
intel_dpio_write(dev_priv, DPIO_DATA_CHANNEL1, temp);
}
- if(intel_pipe_has_type(crtc,INTEL_OUTPUT_EDP))
- {
+
+ if(intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_EDP)) {
temp = 0x1000C4;
if(pipe == 1)
temp |= (1 << 21);
@@ -4227,39 +4224,39 @@ static void vlv_update_pll(struct drm_crtc *crtc,
mutex_unlock(&dev_priv->dpio_lock);
}
-static void i9xx_update_pll(struct drm_crtc *crtc,
- intel_clock_t *clock, intel_clock_t *reduced_clock,
+static void i9xx_update_pll(struct intel_crtc *crtc,
+ intel_clock_t *reduced_clock,
int num_connectors)
{
- struct drm_device *dev = crtc->dev;
+ struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct intel_encoder *encoder;
- int pipe = intel_crtc->pipe;
+ int pipe = crtc->pipe;
u32 dpll;
bool is_sdvo;
+ struct dpll *clock = &crtc->config.dpll;
- i9xx_update_pll_dividers(crtc, clock, reduced_clock);
+ i9xx_update_pll_dividers(crtc, reduced_clock);
- is_sdvo = intel_pipe_has_type(crtc, INTEL_OUTPUT_SDVO) ||
- intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI);
+ is_sdvo = intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_SDVO) ||
+ intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_HDMI);
dpll = DPLL_VGA_MODE_DIS;
- if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS))
+ if (intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_LVDS))
dpll |= DPLLB_MODE_LVDS;
else
dpll |= DPLLB_MODE_DAC_SERIAL;
if (is_sdvo) {
- if ((intel_crtc->config.pixel_multiplier > 1) &&
+ if ((crtc->config.pixel_multiplier > 1) &&
(IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev))) {
- dpll |= (intel_crtc->config.pixel_multiplier - 1)
+ dpll |= (crtc->config.pixel_multiplier - 1)
<< SDVO_MULTIPLIER_SHIFT_HIRES;
}
dpll |= DPLL_DVO_HIGH_SPEED;
}
- if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT))
+ if (intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_DISPLAYPORT))
dpll |= DPLL_DVO_HIGH_SPEED;
/* compute bitmask from p1 value */
@@ -4287,13 +4284,13 @@ static void i9xx_update_pll(struct drm_crtc *crtc,
if (INTEL_INFO(dev)->gen >= 4)
dpll |= (6 << PLL_LOAD_PULSE_PHASE_SHIFT);
- if (is_sdvo && intel_pipe_has_type(crtc, INTEL_OUTPUT_TVOUT))
+ if (is_sdvo && intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_TVOUT))
dpll |= PLL_REF_INPUT_TVCLKINBC;
- else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_TVOUT))
+ else if (intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_TVOUT))
/* XXX: just matching BIOS for now */
/* dpll |= PLL_REF_INPUT_TVCLKINBC; */
dpll |= 3;
- else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) &&
+ else if (intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_LVDS) &&
intel_panel_use_ssc(dev_priv) && num_connectors < 2)
dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN;
else
@@ -4304,12 +4301,12 @@ static void i9xx_update_pll(struct drm_crtc *crtc,
POSTING_READ(DPLL(pipe));
udelay(150);
- for_each_encoder_on_crtc(dev, crtc, encoder)
+ for_each_encoder_on_crtc(dev, &crtc->base, encoder)
if (encoder->pre_pll_enable)
encoder->pre_pll_enable(encoder);
- if (intel_crtc->config.has_dp_encoder)
- intel_dp_set_m_n(intel_crtc);
+ if (crtc->config.has_dp_encoder)
+ intel_dp_set_m_n(crtc);
I915_WRITE(DPLL(pipe), dpll);
@@ -4321,8 +4318,8 @@ static void i9xx_update_pll(struct drm_crtc *crtc,
u32 temp = 0;
if (is_sdvo) {
temp = 0;
- if (intel_crtc->config.pixel_multiplier > 1) {
- temp = (intel_crtc->config.pixel_multiplier - 1)
+ if (crtc->config.pixel_multiplier > 1) {
+ temp = (crtc->config.pixel_multiplier - 1)
<< DPLL_MD_UDI_MULTIPLIER_SHIFT;
}
}
@@ -4337,23 +4334,23 @@ static void i9xx_update_pll(struct drm_crtc *crtc,
}
}
-static void i8xx_update_pll(struct drm_crtc *crtc,
+static void i8xx_update_pll(struct intel_crtc *crtc,
struct drm_display_mode *adjusted_mode,
- intel_clock_t *clock, intel_clock_t *reduced_clock,
+ intel_clock_t *reduced_clock,
int num_connectors)
{
- struct drm_device *dev = crtc->dev;
+ struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct intel_encoder *encoder;
- int pipe = intel_crtc->pipe;
+ int pipe = crtc->pipe;
u32 dpll;
+ struct dpll *clock = &crtc->config.dpll;
- i9xx_update_pll_dividers(crtc, clock, reduced_clock);
+ i9xx_update_pll_dividers(crtc, reduced_clock);
dpll = DPLL_VGA_MODE_DIS;
- if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {
+ if (intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_LVDS)) {
dpll |= (1 << (clock->p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT;
} else {
if (clock->p1 == 2)
@@ -4364,7 +4361,7 @@ static void i8xx_update_pll(struct drm_crtc *crtc,
dpll |= PLL_P2_DIVIDE_BY_4;
}
- if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) &&
+ if (intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_LVDS) &&
intel_panel_use_ssc(dev_priv) && num_connectors < 2)
dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN;
else
@@ -4375,7 +4372,7 @@ static void i8xx_update_pll(struct drm_crtc *crtc,
POSTING_READ(DPLL(pipe));
udelay(150);
- for_each_encoder_on_crtc(dev, crtc, encoder)
+ for_each_encoder_on_crtc(dev, &crtc->base, encoder)
if (encoder->pre_pll_enable)
encoder->pre_pll_enable(encoder);
@@ -4522,20 +4519,26 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc,
&clock,
&reduced_clock);
}
+ /* Compat-code for transition, will disappear. */
+ if (!intel_crtc->config.clock_set) {
+ intel_crtc->config.dpll.n = clock.n;
+ intel_crtc->config.dpll.m1 = clock.m1;
+ intel_crtc->config.dpll.m2 = clock.m2;
+ intel_crtc->config.dpll.p1 = clock.p1;
+ intel_crtc->config.dpll.p2 = clock.p2;
+ }
if (is_sdvo && is_tv)
- i9xx_adjust_sdvo_tv_clock(adjusted_mode, &clock);
+ i9xx_adjust_sdvo_tv_clock(intel_crtc);
if (IS_GEN2(dev))
- i8xx_update_pll(crtc, adjusted_mode, &clock,
+ i8xx_update_pll(intel_crtc, adjusted_mode,
has_reduced_clock ? &reduced_clock : NULL,
num_connectors);
else if (IS_VALLEYVIEW(dev))
- vlv_update_pll(crtc, &clock,
- has_reduced_clock ? &reduced_clock : NULL,
- num_connectors);
+ vlv_update_pll(intel_crtc);
else
- i9xx_update_pll(crtc, &clock,
+ i9xx_update_pll(intel_crtc,
has_reduced_clock ? &reduced_clock : NULL,
num_connectors);
@@ -5162,7 +5165,7 @@ static bool ironlake_compute_clocks(struct drm_crtc *crtc,
}
if (is_sdvo && is_tv)
- i9xx_adjust_sdvo_tv_clock(adjusted_mode, clock);
+ i9xx_adjust_sdvo_tv_clock(to_intel_crtc(crtc));
return true;
}
@@ -5466,6 +5469,14 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
DRM_ERROR("Couldn't find PLL settings for mode!\n");
return -EINVAL;
}
+ /* Compat-code for transition, will disappear. */
+ if (!intel_crtc->config.clock_set) {
+ intel_crtc->config.dpll.n = clock.n;
+ intel_crtc->config.dpll.m1 = clock.m1;
+ intel_crtc->config.dpll.m2 = clock.m2;
+ intel_crtc->config.dpll.p1 = clock.p1;
+ intel_crtc->config.dpll.p2 = clock.p2;
+ }
/* Ensure that the cursor is valid for the new mode before changing... */
intel_crtc_update_cursor(crtc, true);
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index eab5559..ddc8ff4 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -195,6 +195,18 @@ struct intel_crtc_config {
* accordingly. */
bool has_dp_encoder;
bool dither;
+
+ /* Controls for the clock computation, to override various stages. */
+ bool clock_set;
+
+ /* Settings for the intel dpll used on pretty much everything but
+ * haswell. */
+ struct dpll {
+ unsigned n;
+ unsigned m1, m2;
+ unsigned p1, p2;
+ } dpll;
+
int pipe_bpp;
struct intel_link_m_n dp_m_n;
/**
--
1.7.11.4
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH 07/10] drm/i915: drop adjusted_mode from *_set_pipeconf functions
2013-02-22 0:04 [PATCH 00/10] bpc handling fixes Daniel Vetter
` (12 preceding siblings ...)
2013-02-22 0:05 ` [PATCH 7/8] drm/i915: create pipe_config->dpll for clock state Daniel Vetter
@ 2013-02-22 0:05 ` Daniel Vetter
2013-02-22 0:05 ` [PATCH 08/10] drm/i915: implement high-bpc + pipeconf-dither support for g4x/vlv Daniel Vetter
` (3 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Daniel Vetter @ 2013-02-22 0:05 UTC (permalink / raw)
To: Intel Graphics Development; +Cc: Daniel Vetter
They can get at the adjusted mode through intel_crtc->config.
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
drivers/gpu/drm/i915/intel_display.c | 14 ++++++--------
1 file changed, 6 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 27ecc35..a0d80d7 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4884,8 +4884,7 @@ 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)
+static void ironlake_set_pipeconf(struct drm_crtc *crtc)
{
struct drm_i915_private *dev_priv = crtc->dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
@@ -4918,7 +4917,7 @@ static void ironlake_set_pipeconf(struct drm_crtc *crtc,
val |= (PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_SP);
val &= ~PIPECONF_INTERLACE_MASK;
- if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
+ if (intel_crtc->config.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
val |= PIPECONF_INTERLACED_ILK;
else
val |= PIPECONF_PROGRESSIVE;
@@ -4996,8 +4995,7 @@ static void intel_set_pipe_csc(struct drm_crtc *crtc)
}
}
-static void haswell_set_pipeconf(struct drm_crtc *crtc,
- struct drm_display_mode *adjusted_mode)
+static void haswell_set_pipeconf(struct drm_crtc *crtc)
{
struct drm_i915_private *dev_priv = crtc->dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
@@ -5011,7 +5009,7 @@ static void haswell_set_pipeconf(struct drm_crtc *crtc,
val |= (PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_SP);
val &= ~PIPECONF_INTERLACE_MASK_HSW;
- if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
+ if (intel_crtc->config.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
val |= PIPECONF_INTERLACED_ILK;
else
val |= PIPECONF_PROGRESSIVE;
@@ -5459,7 +5457,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
fdi_config_ok = ironlake_check_fdi_lanes(intel_crtc);
- ironlake_set_pipeconf(crtc, adjusted_mode);
+ ironlake_set_pipeconf(crtc);
intel_wait_for_vblank(dev, pipe);
@@ -5581,7 +5579,7 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc,
if (intel_crtc->config.has_pch_encoder)
ironlake_fdi_set_m_n(crtc);
- haswell_set_pipeconf(crtc, adjusted_mode);
+ haswell_set_pipeconf(crtc);
intel_set_pipe_csc(crtc);
--
1.7.11.4
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH 08/10] drm/i915: implement high-bpc + pipeconf-dither support for g4x/vlv
2013-02-22 0:04 [PATCH 00/10] bpc handling fixes Daniel Vetter
` (13 preceding siblings ...)
2013-02-22 0:05 ` [PATCH 07/10] drm/i915: drop adjusted_mode from *_set_pipeconf functions Daniel Vetter
@ 2013-02-22 0:05 ` Daniel Vetter
2013-02-22 0:05 ` [PATCH 8/8] drm/i915: move dp clock computations to encoder->compute_config Daniel Vetter
` (2 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Daniel Vetter @ 2013-02-22 0:05 UTC (permalink / raw)
To: Intel Graphics Development; +Cc: Daniel Vetter
The current code is rather ... ugly. The only thing it managed to pull
off is getting 6bpc on DP working on g4x. Then someone added another
custom hack for 6bpc eDP on vlv. Fix up this entire mess by properly
implementing the PIPECONF-based dither/bpc controls on g4x/vlv.
Note that compared to pch based platforms g4x/vlv don't support 12bpc
modes. g4x is already caught, extend the check for vlv.
The other fixup is to restrict the lvds-specific dithering to early
gen4 devices - g4x should use the pipeconf dither controls. Note that
on gen2/3 the dither control is in the panel fitter even.
v2: Don't enable dithering when the pipe is in 10 bpc mode. Quoting
from Bspec "PIPEACONF - Pipe A Configuration Register, bit 4":
"Programming note: Dithering should only be enabled for 8 bpc or 6
bpc."
v3: Actually drop the old ugly dither code.
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
drivers/gpu/drm/i915/intel_display.c | 33 +++++++++++++++++++--------------
drivers/gpu/drm/i915/intel_lvds.c | 2 +-
2 files changed, 20 insertions(+), 15 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index a0d80d7..5c7cfc9 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4375,22 +4375,27 @@ static void i9xx_set_pipeconf(struct intel_crtc *intel_crtc)
pipeconf &= ~PIPECONF_DOUBLE_WIDE;
}
- /* default to 8bpc */
- pipeconf &= ~(PIPECONF_BPC_MASK | PIPECONF_DITHER_EN);
- if (intel_crtc->config.has_dp_encoder) {
- if (intel_crtc->config.dither) {
- pipeconf |= PIPECONF_6BPC |
- PIPECONF_DITHER_EN |
+ /* only g4x and later have fancy bpc/dither controls */
+ if (IS_G4X(dev) || IS_VALLEYVIEW(dev)) {
+ pipeconf &= ~(PIPECONF_BPC_MASK | PIPECONF_DITHER_EN);
+ if (intel_crtc->config.dither && intel_crtc->config.pipe_bpp != 30)
+ pipeconf |= PIPECONF_DITHER_EN |
PIPECONF_DITHER_TYPE_SP;
- }
- }
- if (IS_VALLEYVIEW(dev) && intel_pipe_has_type(&intel_crtc->base,
- INTEL_OUTPUT_EDP)) {
- if (intel_crtc->config.dither) {
- pipeconf |= PIPECONF_6BPC |
- PIPECONF_ENABLE |
- I965_PIPECONF_ACTIVE;
+ pipeconf &= ~PIPECONF_BPC_MASK;
+ switch (intel_crtc->config.pipe_bpp) {
+ case 18:
+ pipeconf |= PIPECONF_6BPC;
+ break;
+ case 24:
+ pipeconf |= PIPECONF_8BPC;
+ break;
+ case 30:
+ pipeconf |= PIPECONF_10BPC;
+ break;
+ default:
+ /* Case prevented by intel_choose_pipe_bpp_dither. */
+ BUG();
}
}
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index ff4f523..5060e44 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -135,7 +135,7 @@ static void intel_pre_pll_enable_lvds(struct intel_encoder *encoder)
/* Set the dithering flag on LVDS as needed, note that there is no
* special lvds dither control bit on pch-split platforms, dithering is
* only controlled through the PIPECONF reg. */
- if (INTEL_INFO(dev)->gen == 4) {
+ if (INTEL_INFO(dev)->gen == 4 && !IS_G4X(dev)) {
if (intel_crtc->config.dither)
temp |= LVDS_ENABLE_DITHER;
else
--
1.7.11.4
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH 8/8] drm/i915: move dp clock computations to encoder->compute_config
2013-02-22 0:04 [PATCH 00/10] bpc handling fixes Daniel Vetter
` (14 preceding siblings ...)
2013-02-22 0:05 ` [PATCH 08/10] drm/i915: implement high-bpc + pipeconf-dither support for g4x/vlv Daniel Vetter
@ 2013-02-22 0:05 ` Daniel Vetter
2013-02-22 0:05 ` [PATCH 09/10] drm/i915: allow high-bpc modes on DP Daniel Vetter
2013-02-22 0:05 ` [PATCH 10/10] drm/i915: Fixup non-24bpp support for VGA screens on Haswell Daniel Vetter
17 siblings, 0 replies; 21+ messages in thread
From: Daniel Vetter @ 2013-02-22 0:05 UTC (permalink / raw)
To: Intel Graphics Development; +Cc: Daniel Vetter
With the exception of hsw, which has dedicated DP clocks which run at
the fixed frequency already, and vlv, which doesn't have optmized
pre-defined dp clock parameters (yet).
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
drivers/gpu/drm/i915/intel_display.c | 97 +-----------------------------------
drivers/gpu/drm/i915/intel_dp.c | 45 +++++++++++++++++
2 files changed, 46 insertions(+), 96 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 2f9b3ce..45a52f3 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -98,15 +98,6 @@ intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
intel_clock_t *best_clock);
static bool
-intel_find_pll_g4x_dp(const intel_limit_t *, struct drm_crtc *crtc,
- int target, int refclk, intel_clock_t *match_clock,
- intel_clock_t *best_clock);
-static bool
-intel_find_pll_ironlake_dp(const intel_limit_t *, struct drm_crtc *crtc,
- int target, int refclk, intel_clock_t *match_clock,
- intel_clock_t *best_clock);
-
-static bool
intel_vlv_find_best_pll(const intel_limit_t *limit, struct drm_crtc *crtc,
int target, int refclk, intel_clock_t *match_clock,
intel_clock_t *best_clock);
@@ -238,20 +229,6 @@ static const intel_limit_t intel_limits_g4x_dual_channel_lvds = {
.find_pll = intel_g4x_find_best_PLL,
};
-static const intel_limit_t intel_limits_g4x_display_port = {
- .dot = { .min = 161670, .max = 227000 },
- .vco = { .min = 1750000, .max = 3500000},
- .n = { .min = 1, .max = 2 },
- .m = { .min = 97, .max = 108 },
- .m1 = { .min = 0x10, .max = 0x12 },
- .m2 = { .min = 0x05, .max = 0x06 },
- .p = { .min = 10, .max = 20 },
- .p1 = { .min = 1, .max = 2},
- .p2 = { .dot_limit = 0,
- .p2_slow = 10, .p2_fast = 10 },
- .find_pll = intel_find_pll_g4x_dp,
-};
-
static const intel_limit_t intel_limits_pineview_sdvo = {
.dot = { .min = 20000, .max = 400000},
.vco = { .min = 1700000, .max = 3500000 },
@@ -358,20 +335,6 @@ static const intel_limit_t intel_limits_ironlake_dual_lvds_100m = {
.find_pll = intel_g4x_find_best_PLL,
};
-static const intel_limit_t intel_limits_ironlake_display_port = {
- .dot = { .min = 25000, .max = 350000 },
- .vco = { .min = 1760000, .max = 3510000},
- .n = { .min = 1, .max = 2 },
- .m = { .min = 81, .max = 90 },
- .m1 = { .min = 12, .max = 22 },
- .m2 = { .min = 5, .max = 9 },
- .p = { .min = 10, .max = 20 },
- .p1 = { .min = 1, .max = 2},
- .p2 = { .dot_limit = 0,
- .p2_slow = 10, .p2_fast = 10 },
- .find_pll = intel_find_pll_ironlake_dp,
-};
-
static const intel_limit_t intel_limits_vlv_dac = {
.dot = { .min = 25000, .max = 270000 },
.vco = { .min = 4000000, .max = 6000000 },
@@ -482,10 +445,7 @@ static const intel_limit_t *intel_ironlake_limit(struct drm_crtc *crtc,
else
limit = &intel_limits_ironlake_single_lvds;
}
- } else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT) ||
- intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP))
- limit = &intel_limits_ironlake_display_port;
- else
+ } else
limit = &intel_limits_ironlake_dac;
return limit;
@@ -508,8 +468,6 @@ static const intel_limit_t *intel_g4x_limit(struct drm_crtc *crtc)
limit = &intel_limits_g4x_hdmi;
} else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_SDVO)) {
limit = &intel_limits_g4x_sdvo;
- } else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) {
- limit = &intel_limits_g4x_display_port;
} else /* The option is for other outputs */
limit = &intel_limits_i9xx_sdvo;
@@ -752,59 +710,6 @@ intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
}
static bool
-intel_find_pll_ironlake_dp(const intel_limit_t *limit, struct drm_crtc *crtc,
- int target, int refclk, intel_clock_t *match_clock,
- intel_clock_t *best_clock)
-{
- struct drm_device *dev = crtc->dev;
- intel_clock_t clock;
-
- if (target < 200000) {
- clock.n = 1;
- clock.p1 = 2;
- clock.p2 = 10;
- clock.m1 = 12;
- clock.m2 = 9;
- } else {
- clock.n = 2;
- clock.p1 = 1;
- clock.p2 = 10;
- clock.m1 = 14;
- clock.m2 = 8;
- }
- intel_clock(dev, refclk, &clock);
- memcpy(best_clock, &clock, sizeof(intel_clock_t));
- return true;
-}
-
-/* DisplayPort has only two frequencies, 162MHz and 270MHz */
-static bool
-intel_find_pll_g4x_dp(const intel_limit_t *limit, struct drm_crtc *crtc,
- int target, int refclk, intel_clock_t *match_clock,
- intel_clock_t *best_clock)
-{
- intel_clock_t clock;
- if (target < 200000) {
- clock.p1 = 2;
- clock.p2 = 10;
- clock.n = 2;
- clock.m1 = 23;
- clock.m2 = 8;
- } else {
- clock.p1 = 1;
- clock.p2 = 10;
- clock.n = 1;
- clock.m1 = 14;
- clock.m2 = 2;
- }
- clock.m = 5 * (clock.m1 + 2) + (clock.m2 + 2);
- clock.p = (clock.p1 * clock.p2);
- clock.dot = 96000 * clock.m / (clock.n + 2) / clock.p;
- clock.vco = 0;
- memcpy(best_clock, &clock, sizeof(intel_clock_t));
- return true;
-}
-static bool
intel_vlv_find_best_pll(const intel_limit_t *limit, struct drm_crtc *crtc,
int target, int refclk, intel_clock_t *match_clock,
intel_clock_t *best_clock)
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 3261242..83e3791 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -670,6 +670,49 @@ intel_dp_i2c_init(struct intel_dp *intel_dp,
return ret;
}
+static void
+intel_dp_set_clock(struct intel_encoder *encoder,
+ struct intel_crtc_config *pipe_config, int link_bw)
+{
+ struct drm_device *dev = encoder->base.dev;
+
+ if (IS_G4X(dev)) {
+ if (link_bw == DP_LINK_BW_1_62) {
+ pipe_config->dpll.p1 = 2;
+ pipe_config->dpll.p2 = 10;
+ pipe_config->dpll.n = 2;
+ pipe_config->dpll.m1 = 23;
+ pipe_config->dpll.m2 = 8;
+ } else {
+ pipe_config->dpll.p1 = 1;
+ pipe_config->dpll.p2 = 10;
+ pipe_config->dpll.n = 1;
+ pipe_config->dpll.m1 = 14;
+ pipe_config->dpll.m2 = 2;
+ }
+ pipe_config->clock_set = true;
+ } else if (IS_HASWELL(dev)) {
+ /* Haswell has special-purpose DP DDI clocks. */
+ } else if (HAS_PCH_SPLIT(dev)) {
+ if (link_bw == DP_LINK_BW_1_62) {
+ pipe_config->dpll.n = 1;
+ pipe_config->dpll.p1 = 2;
+ pipe_config->dpll.p2 = 10;
+ pipe_config->dpll.m1 = 12;
+ pipe_config->dpll.m2 = 9;
+ } else {
+ pipe_config->dpll.n = 2;
+ pipe_config->dpll.p1 = 1;
+ pipe_config->dpll.p2 = 10;
+ pipe_config->dpll.m1 = 14;
+ pipe_config->dpll.m2 = 8;
+ }
+ pipe_config->clock_set = true;
+ } else if (IS_VALLEYVIEW(dev)) {
+ /* FIXME: Need to figure out optimized DP clocks for vlv. */
+ }
+}
+
bool
intel_dp_compute_config(struct intel_encoder *encoder,
struct intel_crtc_config *pipe_config)
@@ -765,6 +808,8 @@ found:
target_clock, adjusted_mode->clock,
&pipe_config->dp_m_n);
+ intel_dp_set_clock(encoder, pipe_config, intel_dp->link_bw);
+
return true;
}
--
1.7.11.4
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH 09/10] drm/i915: allow high-bpc modes on DP
2013-02-22 0:04 [PATCH 00/10] bpc handling fixes Daniel Vetter
` (15 preceding siblings ...)
2013-02-22 0:05 ` [PATCH 8/8] drm/i915: move dp clock computations to encoder->compute_config Daniel Vetter
@ 2013-02-22 0:05 ` Daniel Vetter
2013-02-22 0:05 ` [PATCH 10/10] drm/i915: Fixup non-24bpp support for VGA screens on Haswell Daniel Vetter
17 siblings, 0 replies; 21+ messages in thread
From: Daniel Vetter @ 2013-02-22 0:05 UTC (permalink / raw)
To: Intel Graphics Development; +Cc: Daniel Vetter
Totally untested due to lack of screens supporting more than 8bpc. But
now we should have closed all holes in our bpp handling, so this
should be safe. The last missing piece was 10bpc support for g4x/vlv,
since we directly use the pipe bpp to feed the display link (and
anyway, only the cpt has any means to have a pipe bpp != the display
link bpp).
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
drivers/gpu/drm/i915/intel_dp.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 81693fc..3c8a708 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -754,7 +754,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
/* Walk through all bpp values. Luckily they're all nicely spaced with 2
* bpc in between. */
- bpp = min_t(int, 8*3, pipe_config->pipe_bpp);
+ bpp = pipe_config->pipe_bpp;
/* eDP panels are really fickle, try to enfore the bpp the firmware
* recomments. This means we'll up-dither 16bpp framebuffers on
--
1.7.11.4
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH 10/10] drm/i915: Fixup non-24bpp support for VGA screens on Haswell
2013-02-22 0:04 [PATCH 00/10] bpc handling fixes Daniel Vetter
` (16 preceding siblings ...)
2013-02-22 0:05 ` [PATCH 09/10] drm/i915: allow high-bpc modes on DP Daniel Vetter
@ 2013-02-22 0:05 ` Daniel Vetter
17 siblings, 0 replies; 21+ messages in thread
From: Daniel Vetter @ 2013-02-22 0:05 UTC (permalink / raw)
To: Intel Graphics Development; +Cc: Daniel Vetter
The LPT PCH only supports 8bpc, so we need to force the pipe bpp
to the right value.
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
drivers/gpu/drm/i915/intel_crt.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
index 1bd09a7..27c2b85 100644
--- a/drivers/gpu/drm/i915/intel_crt.c
+++ b/drivers/gpu/drm/i915/intel_crt.c
@@ -214,6 +214,10 @@ static bool intel_crt_compute_config(struct intel_encoder *encoder,
if (HAS_PCH_SPLIT(dev))
pipe_config->has_pch_encoder = true;
+ /* LPT FDI RX only supports 8bpc. */
+ if (HAS_PCH_LPT(dev))
+ pipe_config->pipe_bpp = 24;
+
return true;
}
--
1.7.11.4
^ permalink raw reply related [flat|nested] 21+ messages in thread