aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_crt.c
diff options
context:
space:
mode:
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 79acc4f4c1f8..6de97fc66029 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)
37{ 37{
38 struct drm_device *dev = encoder->dev; 38 struct drm_device *dev = encoder->dev;
39 struct drm_i915_private *dev_priv = dev->dev_private; 39 struct drm_i915_private *dev_priv = dev->dev_private;
40 u32 temp; 40 u32 temp, reg;
41 41
42 temp = I915_READ(ADPA); 42 if (IS_IGDNG(dev))
43 reg = PCH_ADPA;
44 else
45 reg = ADPA;
46
47 temp = I915_READ(reg);
43 temp &= ~(ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE); 48 temp &= ~(ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE);
44 temp |= ADPA_DAC_ENABLE; 49 temp |= ADPA_DAC_ENABLE;
45 50
@@ -58,7 +63,7 @@ static void intel_crt_dpms(struct drm_encoder *encoder, int mode)
58 break; 63 break;
59 } 64 }
60 65
61 I915_WRITE(ADPA, temp); 66 I915_WRITE(reg, temp);
62} 67}
63 68
64static int intel_crt_mode_valid(struct drm_connector *connector, 69static int intel_crt_mode_valid(struct drm_connector *connector,
@@ -101,17 +106,23 @@ static void intel_crt_mode_set(struct drm_encoder *encoder,
101 struct drm_i915_private *dev_priv = dev->dev_private; 106 struct drm_i915_private *dev_priv = dev->dev_private;
102 int dpll_md_reg; 107 int dpll_md_reg;
103 u32 adpa, dpll_md; 108 u32 adpa, dpll_md;
109 u32 adpa_reg;
104 110
105 if (intel_crtc->pipe == 0) 111 if (intel_crtc->pipe == 0)
106 dpll_md_reg = DPLL_A_MD; 112 dpll_md_reg = DPLL_A_MD;
107 else 113 else
108 dpll_md_reg = DPLL_B_MD; 114 dpll_md_reg = DPLL_B_MD;
109 115
116 if (IS_IGDNG(dev))
117 adpa_reg = PCH_ADPA;
118 else
119 adpa_reg = ADPA;
120
110 /* 121 /*
111 * Disable separate mode multiplier used when cloning SDVO to CRT 122 * Disable separate mode multiplier used when cloning SDVO to CRT
112 * XXX this needs to be adjusted when we really are cloning 123 * XXX this needs to be adjusted when we really are cloning
113 */ 124 */
114 if (IS_I965G(dev)) { 125 if (IS_I965G(dev) && !IS_IGDNG(dev)) {
115 dpll_md = I915_READ(dpll_md_reg); 126 dpll_md = I915_READ(dpll_md_reg);
116 I915_WRITE(dpll_md_reg, 127 I915_WRITE(dpll_md_reg,
117 dpll_md & ~DPLL_MD_UDI_MULTIPLIER_MASK); 128 dpll_md & ~DPLL_MD_UDI_MULTIPLIER_MASK);
@@ -125,13 +136,53 @@ static void intel_crt_mode_set(struct drm_encoder *encoder,
125 136
126 if (intel_crtc->pipe == 0) { 137 if (intel_crtc->pipe == 0) {
127 adpa |= ADPA_PIPE_A_SELECT; 138 adpa |= ADPA_PIPE_A_SELECT;
128 I915_WRITE(BCLRPAT_A, 0); 139 if (!IS_IGDNG(dev))
140 I915_WRITE(BCLRPAT_A, 0);
129 } else { 141 } else {
130 adpa |= ADPA_PIPE_B_SELECT; 142 adpa |= ADPA_PIPE_B_SELECT;
131 I915_WRITE(BCLRPAT_B, 0); 143 if (!IS_IGDNG(dev))
144 I915_WRITE(BCLRPAT_B, 0);
132 } 145 }
133 146
134 I915_WRITE(ADPA, adpa); 147 I915_WRITE(adpa_reg, adpa);
148}
149
150static bool intel_igdng_crt_detect_hotplug(struct drm_connector *connector)
151{
152 struct drm_device *dev = connector->dev;
153 struct drm_i915_private *dev_priv = dev->dev_private;
154 u32 adpa, temp;
155 bool ret;
156
157 temp = adpa = I915_READ(PCH_ADPA);
158
159 adpa &= ~ADPA_CRT_HOTPLUG_MASK;
160
161 adpa |= (ADPA_CRT_HOTPLUG_PERIOD_128 |
162 ADPA_CRT_HOTPLUG_WARMUP_10MS |
163 ADPA_CRT_HOTPLUG_SAMPLE_4S |
164 ADPA_CRT_HOTPLUG_VOLTAGE_50 | /* default */
165 ADPA_CRT_HOTPLUG_VOLREF_325MV |
166 ADPA_CRT_HOTPLUG_ENABLE |
167 ADPA_CRT_HOTPLUG_FORCE_TRIGGER);
168
169 DRM_DEBUG("pch crt adpa 0x%x", adpa);
170 I915_WRITE(PCH_ADPA, adpa);
171
172 /* This might not be needed as not specified in spec...*/
173 udelay(1000);
174
175 /* Check the status to see if both blue and green are on now */
176 adpa = I915_READ(PCH_ADPA);
177 if ((adpa & ADPA_CRT_HOTPLUG_MONITOR_MASK) ==
178 ADPA_CRT_HOTPLUG_MONITOR_COLOR)
179 ret = true;
180 else
181 ret = false;
182
183 /* restore origin register */
184 I915_WRITE(PCH_ADPA, temp);
185 return ret;
135} 186}
136 187
137/** 188/**
@@ -148,6 +199,10 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector)
148 struct drm_i915_private *dev_priv = dev->dev_private; 199 struct drm_i915_private *dev_priv = dev->dev_private;
149 u32 hotplug_en; 200 u32 hotplug_en;
150 int i, tries = 0; 201 int i, tries = 0;
202
203 if (IS_IGDNG(dev))
204 return intel_igdng_crt_detect_hotplug(connector);
205
151 /* 206 /*
152 * On 4 series desktop, CRT detect sequence need to be done twice 207 * On 4 series desktop, CRT detect sequence need to be done twice
153 * to get a reliable result. 208 * to get a reliable result.
@@ -423,6 +478,7 @@ void intel_crt_init(struct drm_device *dev)
423{ 478{
424 struct drm_connector *connector; 479 struct drm_connector *connector;
425 struct intel_output *intel_output; 480 struct intel_output *intel_output;
481 u32 i2c_reg;
426 482
427 intel_output = kzalloc(sizeof(struct intel_output), GFP_KERNEL); 483 intel_output = kzalloc(sizeof(struct intel_output), GFP_KERNEL);
428 if (!intel_output) 484 if (!intel_output)
@@ -439,7 +495,11 @@ void intel_crt_init(struct drm_device *dev)
439 &intel_output->enc); 495 &intel_output->enc);
440 496
441 /* Set up the DDC bus. */ 497 /* Set up the DDC bus. */
442 intel_output->ddc_bus = intel_i2c_create(dev, GPIOA, "CRTDDC_A"); 498 if (IS_IGDNG(dev))
499 i2c_reg = PCH_GPIOA;
500 else
501 i2c_reg = GPIOA;
502 intel_output->ddc_bus = intel_i2c_create(dev, i2c_reg, "CRTDDC_A");
443 if (!intel_output->ddc_bus) { 503 if (!intel_output->ddc_bus) {
444 dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration " 504 dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration "
445 "failed.\n"); 505 "failed.\n");