diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-12 18:09:18 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-12 18:09:18 -0700 |
commit | 6b702462cbe5b6f372966a53f4465d745d86b65c (patch) | |
tree | 19a8d090b284bb804e8a2ffa38fa51b58118db6a /drivers/gpu/drm/i915/intel_crt.c | |
parent | 947ec0b0c1e7e80eef4fe64f7763a06d0cf04d2e (diff) | |
parent | 3c24475c1e4e8d10e50df161d8c4f1d382997a7c (diff) | |
download | op-kernel-dev-6b702462cbe5b6f372966a53f4465d745d86b65c.zip op-kernel-dev-6b702462cbe5b6f372966a53f4465d745d86b65c.tar.gz |
Merge branch 'drm-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6
* 'drm-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6: (50 commits)
drm: include kernel list header file in hashtab header
drm: Export hash table functionality.
drm: Split out the mm declarations in a separate header. Add atomic operations.
drm/radeon: add support for RV790.
drm/radeon: add rv740 drm support.
drm_calloc_large: check right size, check integer overflow, use GFP_ZERO
drm: Eliminate magic I2C frobbing when reading EDID
drm/i915: duplicate desired mode for use by fbcon.
drm/via: vfree() no need checking before calling it
drm: Replace DRM_DEBUG with DRM_DEBUG_DRIVER in i915 driver
drm: Replace DRM_DEBUG with DRM_DEBUG_MODE in drm_mode
drm/i915: Replace DRM_DEBUG with DRM_DEBUG_KMS in intel_sdvo
drm/i915: replace DRM_DEBUG with DRM_DEBUG_KMS in intel_lvds
drm: add separate drm debugging levels
radeon: remove _DRM_DRIVER from the preadded sarea map
drm: don't associate _DRM_DRIVER maps with a master
drm: simplify kcalloc() call to kzalloc().
intelfb: fix spelling of "CLOCK"
drm: fix LOCK_TEST_WITH_RETURN macro
drm/i915: Hook connector to encoder during load detection (fixes tv/vga detect)
...
Diffstat (limited to 'drivers/gpu/drm/i915/intel_crt.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_crt.c | 76 |
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 79acc4f..6de97fc 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. @@ -423,6 +478,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) @@ -439,7 +495,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"); |