summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_crt.c
diff options
context:
space:
mode:
authorZhenyu Wang <zhenyuw@linux.intel.com>2009-06-05 15:38:42 +0800
committerEric Anholt <eric@anholt.net>2009-06-05 11:34:51 +0000
commit2c07245fb8f7f0a282282e5a9747e46defdb2cc7 (patch)
tree101944c42c459c42c2d362efe9c3762aeece4f19 /drivers/gpu/drm/i915/intel_crt.c
parent2cce0d8740f0d1454d012401257d96c513ce358f (diff)
drm/i915: enable kernel modesetting on IGDNG
This adds kernel mode setting on IGDNG with VGA output support. Note that suspend/resume doesn't work yet. Signed-off-by: Zhenyu Wang <zhenyuw@linux.intel.com> Signed-off-by: Eric Anholt <eric@anholt.net>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_crt.c')
-rw-r--r--drivers/gpu/drm/i915/intel_crt.c76
1 files changed, 68 insertions, 8 deletions
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
index 640f5158eff..ff9bccad387 100644
--- a/drivers/gpu/drm/i915/intel_crt.c
+++ b/drivers/gpu/drm/i915/intel_crt.c
@@ -37,9 +37,14 @@ static void intel_crt_dpms(struct drm_encoder *encoder, int mode)
{
struct drm_device *dev = encoder->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- u32 temp;
+ u32 temp, reg;
- temp = I915_READ(ADPA);
+ if (IS_IGDNG(dev))
+ reg = PCH_ADPA;
+ else
+ reg = ADPA;
+
+ temp = I915_READ(reg);
temp &= ~(ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE);
temp |= ADPA_DAC_ENABLE;
@@ -58,7 +63,7 @@ static void intel_crt_dpms(struct drm_encoder *encoder, int mode)
break;
}
- I915_WRITE(ADPA, temp);
+ I915_WRITE(reg, temp);
}
static int intel_crt_mode_valid(struct drm_connector *connector,
@@ -101,17 +106,23 @@ static void intel_crt_mode_set(struct drm_encoder *encoder,
struct drm_i915_private *dev_priv = dev->dev_private;
int dpll_md_reg;
u32 adpa, dpll_md;
+ u32 adpa_reg;
if (intel_crtc->pipe == 0)
dpll_md_reg = DPLL_A_MD;
else
dpll_md_reg = DPLL_B_MD;
+ if (IS_IGDNG(dev))
+ adpa_reg = PCH_ADPA;
+ else
+ adpa_reg = ADPA;
+
/*
* Disable separate mode multiplier used when cloning SDVO to CRT
* XXX this needs to be adjusted when we really are cloning
*/
- if (IS_I965G(dev)) {
+ if (IS_I965G(dev) && !IS_IGDNG(dev)) {
dpll_md = I915_READ(dpll_md_reg);
I915_WRITE(dpll_md_reg,
dpll_md & ~DPLL_MD_UDI_MULTIPLIER_MASK);
@@ -125,13 +136,53 @@ static void intel_crt_mode_set(struct drm_encoder *encoder,
if (intel_crtc->pipe == 0) {
adpa |= ADPA_PIPE_A_SELECT;
- I915_WRITE(BCLRPAT_A, 0);
+ if (!IS_IGDNG(dev))
+ I915_WRITE(BCLRPAT_A, 0);
} else {
adpa |= ADPA_PIPE_B_SELECT;
- I915_WRITE(BCLRPAT_B, 0);
+ if (!IS_IGDNG(dev))
+ I915_WRITE(BCLRPAT_B, 0);
}
- I915_WRITE(ADPA, adpa);
+ I915_WRITE(adpa_reg, adpa);
+}
+
+static bool intel_igdng_crt_detect_hotplug(struct drm_connector *connector)
+{
+ struct drm_device *dev = connector->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ u32 adpa, temp;
+ bool ret;
+
+ temp = adpa = I915_READ(PCH_ADPA);
+
+ adpa &= ~ADPA_CRT_HOTPLUG_MASK;
+
+ adpa |= (ADPA_CRT_HOTPLUG_PERIOD_128 |
+ ADPA_CRT_HOTPLUG_WARMUP_10MS |
+ ADPA_CRT_HOTPLUG_SAMPLE_4S |
+ ADPA_CRT_HOTPLUG_VOLTAGE_50 | /* default */
+ ADPA_CRT_HOTPLUG_VOLREF_325MV |
+ ADPA_CRT_HOTPLUG_ENABLE |
+ ADPA_CRT_HOTPLUG_FORCE_TRIGGER);
+
+ DRM_DEBUG("pch crt adpa 0x%x", adpa);
+ I915_WRITE(PCH_ADPA, adpa);
+
+ /* This might not be needed as not specified in spec...*/
+ udelay(1000);
+
+ /* Check the status to see if both blue and green are on now */
+ adpa = I915_READ(PCH_ADPA);
+ if ((adpa & ADPA_CRT_HOTPLUG_MONITOR_MASK) ==
+ ADPA_CRT_HOTPLUG_MONITOR_COLOR)
+ ret = true;
+ else
+ ret = false;
+
+ /* restore origin register */
+ I915_WRITE(PCH_ADPA, temp);
+ return ret;
}
/**
@@ -148,6 +199,10 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector)
struct drm_i915_private *dev_priv = dev->dev_private;
u32 hotplug_en;
int i, tries = 0;
+
+ if (IS_IGDNG(dev))
+ return intel_igdng_crt_detect_hotplug(connector);
+
/*
* On 4 series desktop, CRT detect sequence need to be done twice
* to get a reliable result.
@@ -427,6 +482,7 @@ void intel_crt_init(struct drm_device *dev)
{
struct drm_connector *connector;
struct intel_output *intel_output;
+ u32 i2c_reg;
intel_output = kzalloc(sizeof(struct intel_output), GFP_KERNEL);
if (!intel_output)
@@ -443,7 +499,11 @@ void intel_crt_init(struct drm_device *dev)
&intel_output->enc);
/* Set up the DDC bus. */
- intel_output->ddc_bus = intel_i2c_create(dev, GPIOA, "CRTDDC_A");
+ if (IS_IGDNG(dev))
+ i2c_reg = PCH_GPIOA;
+ else
+ i2c_reg = GPIOA;
+ intel_output->ddc_bus = intel_i2c_create(dev, i2c_reg, "CRTDDC_A");
if (!intel_output->ddc_bus) {
dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration "
"failed.\n");