diff options
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 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 | ||
64 | static int intel_crt_mode_valid(struct drm_connector *connector, | 69 | 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 | 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 | |||
150 | static 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"); |