Commit 2c07245f authored by Zhenyu Wang's avatar Zhenyu Wang Committed by Eric Anholt

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: default avatarZhenyu Wang <zhenyuw@linux.intel.com>
Signed-off-by: default avatarEric Anholt <eric@anholt.net>
parent 2cce0d87
...@@ -922,7 +922,7 @@ static int i915_probe_agp(struct drm_device *dev, unsigned long *aperture_size, ...@@ -922,7 +922,7 @@ static int i915_probe_agp(struct drm_device *dev, unsigned long *aperture_size,
* Some of the preallocated space is taken by the GTT * Some of the preallocated space is taken by the GTT
* and popup. GTT is 1K per MB of aperture size, and popup is 4K. * and popup. GTT is 1K per MB of aperture size, and popup is 4K.
*/ */
if (IS_G4X(dev) || IS_IGD(dev)) if (IS_G4X(dev) || IS_IGD(dev) || IS_IGDNG(dev))
overhead = 4096; overhead = 4096;
else else
overhead = (*aperture_size / 1024) + 4096; overhead = (*aperture_size / 1024) + 4096;
......
...@@ -37,9 +37,14 @@ static void intel_crt_dpms(struct drm_encoder *encoder, int mode) ...@@ -37,9 +37,14 @@ static void intel_crt_dpms(struct drm_encoder *encoder, int mode)
{ {
struct drm_device *dev = encoder->dev; struct drm_device *dev = encoder->dev;
struct drm_i915_private *dev_priv = dev->dev_private; 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_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE);
temp |= ADPA_DAC_ENABLE; temp |= ADPA_DAC_ENABLE;
...@@ -58,7 +63,7 @@ static void intel_crt_dpms(struct drm_encoder *encoder, int mode) ...@@ -58,7 +63,7 @@ static void intel_crt_dpms(struct drm_encoder *encoder, int mode)
break; break;
} }
I915_WRITE(ADPA, temp); I915_WRITE(reg, temp);
} }
static int intel_crt_mode_valid(struct drm_connector *connector, static int intel_crt_mode_valid(struct drm_connector *connector,
...@@ -101,17 +106,23 @@ static void intel_crt_mode_set(struct drm_encoder *encoder, ...@@ -101,17 +106,23 @@ static void intel_crt_mode_set(struct drm_encoder *encoder,
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
int dpll_md_reg; int dpll_md_reg;
u32 adpa, dpll_md; u32 adpa, dpll_md;
u32 adpa_reg;
if (intel_crtc->pipe == 0) if (intel_crtc->pipe == 0)
dpll_md_reg = DPLL_A_MD; dpll_md_reg = DPLL_A_MD;
else else
dpll_md_reg = DPLL_B_MD; 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 * Disable separate mode multiplier used when cloning SDVO to CRT
* XXX this needs to be adjusted when we really are cloning * 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); dpll_md = I915_READ(dpll_md_reg);
I915_WRITE(dpll_md_reg, I915_WRITE(dpll_md_reg,
dpll_md & ~DPLL_MD_UDI_MULTIPLIER_MASK); dpll_md & ~DPLL_MD_UDI_MULTIPLIER_MASK);
...@@ -125,13 +136,53 @@ static void intel_crt_mode_set(struct drm_encoder *encoder, ...@@ -125,13 +136,53 @@ static void intel_crt_mode_set(struct drm_encoder *encoder,
if (intel_crtc->pipe == 0) { if (intel_crtc->pipe == 0) {
adpa |= ADPA_PIPE_A_SELECT; adpa |= ADPA_PIPE_A_SELECT;
I915_WRITE(BCLRPAT_A, 0); if (!IS_IGDNG(dev))
I915_WRITE(BCLRPAT_A, 0);
} else { } else {
adpa |= ADPA_PIPE_B_SELECT; 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) ...@@ -148,6 +199,10 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector)
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
u32 hotplug_en; u32 hotplug_en;
int i, tries = 0; 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 * On 4 series desktop, CRT detect sequence need to be done twice
* to get a reliable result. * to get a reliable result.
...@@ -427,6 +482,7 @@ void intel_crt_init(struct drm_device *dev) ...@@ -427,6 +482,7 @@ void intel_crt_init(struct drm_device *dev)
{ {
struct drm_connector *connector; struct drm_connector *connector;
struct intel_output *intel_output; struct intel_output *intel_output;
u32 i2c_reg;
intel_output = kzalloc(sizeof(struct intel_output), GFP_KERNEL); intel_output = kzalloc(sizeof(struct intel_output), GFP_KERNEL);
if (!intel_output) if (!intel_output)
...@@ -443,7 +499,11 @@ void intel_crt_init(struct drm_device *dev) ...@@ -443,7 +499,11 @@ void intel_crt_init(struct drm_device *dev)
&intel_output->enc); &intel_output->enc);
/* Set up the DDC bus. */ /* 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) { if (!intel_output->ddc_bus) {
dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration " dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration "
"failed.\n"); "failed.\n");
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment