[Intel-gfx] [PATCH] drm/i915: Enable VLV to work in BIOS-less system
Chon Ming Lee
chon.ming.lee at intel.com
Fri Sep 13 05:59:45 CEST 2013
In non PC system, such as IVI, may not use BIOS, instead it uses boot
loader with only minimal system initialization. Most of the time, boot
loader doesn't come with VBIOS, and depends on device driver to fully
initialize the display controller and GPU.
For Valleyview, without VBIOS, i915 fails to work. The patch add some
missing init code, such as doing a DPIO CMNRESET and program the GMBUS
frequency.
Signed-off-by: Chon Ming Lee <chon.ming.lee at intel.com>
---
drivers/gpu/drm/i915/i915_reg.h | 8 +++++
drivers/gpu/drm/i915/intel_display.c | 51 ++++++++++++++++++++++++++++++++++
2 files changed, 59 insertions(+), 0 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index bcee89b..8ddf58a 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -382,6 +382,8 @@
#define FB_FMAX_VMIN_FREQ_LO_MASK 0xf8000000
/* vlv2 north clock has */
+#define CCK_FUSE_REG 0x8
+#define CCK_FUSE_HPLL_FREQ_MASK 0x3
#define CCK_REG_DSI_PLL_FUSE 0x44
#define CCK_REG_DSI_PLL_CONTROL 0x48
#define DSI_PLL_VCO_EN (1 << 31)
@@ -1424,6 +1426,12 @@
#define MI_ARB_VLV (VLV_DISPLAY_BASE + 0x6504)
+#define CZCLK_CDCLK_FREQ_RATIO (dev_priv->info->display_mmio_offset + 0x6508)
+#define CDCLK_FREQ_SHIFT 4
+#define CDCLK_FREQ_MASK 0x1f
+#define CZCLK_FREQ_MASK 0xf
+#define GMBUS_FREQ (dev_priv->info->display_mmio_offset + 0x6510)
+
/*
* Palette regs
*/
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 3c0e0cf..9ef1d28 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -9497,6 +9497,31 @@ static bool has_edp_a(struct drm_device *dev)
return true;
}
+static void gmbus_set_freq(struct drm_i915_private *dev_priv, u32 hpll_freq)
+{
+ int cdclk_ratio[] = { 10, 15, 20, 25, 30, 0, 40, 45, 50, 0,
+ 60, 0, 0, 75, 80, 0, 90, 0, 100, 0,
+ 0, 0, 120, 0, 0, 0, 0, 0, 150, 0, 160 };
+ int vco_freq[] = { 800, 1600, 2000, 2400 };
+ int gmbus_freq = 0, cdclk;
+ u32 reg_val;
+
+ BUG_ON(hpll_freq > ARRAY_SIZE(vco_freq));
+
+ reg_val = I915_READ(CZCLK_CDCLK_FREQ_RATIO);
+
+ cdclk = ((reg_val >> CDCLK_FREQ_SHIFT) & CDCLK_FREQ_MASK) - 1;
+
+ if (cdclk_ratio[cdclk])
+ gmbus_freq = vco_freq[hpll_freq] / cdclk_ratio[cdclk] * 10;
+
+ WARN_ON(gmbus_freq == 0);
+
+ if (gmbus_freq != 0)
+ I915_WRITE(GMBUS_FREQ, gmbus_freq);
+
+}
+
static void intel_setup_outputs(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -9555,6 +9580,32 @@ static void intel_setup_outputs(struct drm_device *dev)
if (I915_READ(PCH_DP_D) & DP_DETECTED)
intel_dp_init(dev, PCH_DP_D, PORT_D);
} else if (IS_VALLEYVIEW(dev)) {
+ u32 reg_val;
+
+ /* Trigger DPIO CMN RESET, require especially in BIOS less
+ * system
+ */
+ reg_val = I915_READ(DPIO_CTL);
+ if (!(reg_val & 0x1)) {
+ I915_WRITE(DPIO_CTL, 0x0);
+ I915_WRITE(DPIO_CTL, 0x1);
+ POSTING_READ(DPIO_CTL);
+ }
+
+ /* In BIOS-less system, program the correct gmbus frequency
+ * before reading edid.
+ */
+
+ /* Obtain SKU information to determine the correct CDCLK */
+ mutex_lock(&dev_priv->dpio_lock);
+ reg_val = vlv_cck_read(dev_priv, CCK_FUSE_REG);
+ mutex_unlock(&dev_priv->dpio_lock);
+
+ reg_val &= CCK_FUSE_HPLL_FREQ_MASK;
+
+ /* Write CDCLK to GMBUS freq for GMBUS clk generation. */
+ gmbus_set_freq(dev_priv, reg_val);
+
/* Check for built-in panel first. Shares lanes with HDMI on SDVOC */
if (I915_READ(VLV_DISPLAY_BASE + GEN4_HDMIC) & SDVO_DETECTED) {
intel_hdmi_init(dev, VLV_DISPLAY_BASE + GEN4_HDMIC,
--
1.7.7.6
More information about the Intel-gfx
mailing list