aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorAlex Deucher <alexdeucher@gmail.com>2009-12-04 15:12:21 -0500
committerDave Airlie <airlied@redhat.com>2009-12-07 19:48:07 -0500
commite0df1ac5c2cf346f4cc335025734978a4d747aa0 (patch)
tree5728691bd5bb9a5a06c1d8517515dfcd9fd67dd0 /drivers/gpu
parentdcfdd4083509f9c46b1e92c58c062d50da50580e (diff)
drm/radeon/kms: add hpd support for r6xx/r7xx/rs780/rs880 asics
This just adds the functionality, it's not hooked up yet. Signed-off-by: Alex Deucher <alexdeucher@gmail.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/radeon/r600.c508
1 files changed, 485 insertions, 23 deletions
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index 94e7fd2f59e9..f60689602082 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -74,6 +74,281 @@ int r600_mc_wait_for_idle(struct radeon_device *rdev);
74void r600_gpu_init(struct radeon_device *rdev); 74void r600_gpu_init(struct radeon_device *rdev);
75void r600_fini(struct radeon_device *rdev); 75void r600_fini(struct radeon_device *rdev);
76 76
77/* hpd for digital panel detect/disconnect */
78bool r600_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd)
79{
80 bool connected = false;
81
82 if (ASIC_IS_DCE3(rdev)) {
83 switch (hpd) {
84 case RADEON_HPD_1:
85 if (RREG32(DC_HPD1_INT_STATUS) & DC_HPDx_SENSE)
86 connected = true;
87 break;
88 case RADEON_HPD_2:
89 if (RREG32(DC_HPD2_INT_STATUS) & DC_HPDx_SENSE)
90 connected = true;
91 break;
92 case RADEON_HPD_3:
93 if (RREG32(DC_HPD3_INT_STATUS) & DC_HPDx_SENSE)
94 connected = true;
95 break;
96 case RADEON_HPD_4:
97 if (RREG32(DC_HPD4_INT_STATUS) & DC_HPDx_SENSE)
98 connected = true;
99 break;
100 /* DCE 3.2 */
101 case RADEON_HPD_5:
102 if (RREG32(DC_HPD5_INT_STATUS) & DC_HPDx_SENSE)
103 connected = true;
104 break;
105 case RADEON_HPD_6:
106 if (RREG32(DC_HPD6_INT_STATUS) & DC_HPDx_SENSE)
107 connected = true;
108 break;
109 default:
110 break;
111 }
112 } else {
113 switch (hpd) {
114 case RADEON_HPD_1:
115 if (RREG32(DC_HOT_PLUG_DETECT1_INT_STATUS) & DC_HOT_PLUG_DETECTx_SENSE)
116 connected = true;
117 break;
118 case RADEON_HPD_2:
119 if (RREG32(DC_HOT_PLUG_DETECT2_INT_STATUS) & DC_HOT_PLUG_DETECTx_SENSE)
120 connected = true;
121 break;
122 case RADEON_HPD_3:
123 if (RREG32(DC_HOT_PLUG_DETECT3_INT_STATUS) & DC_HOT_PLUG_DETECTx_SENSE)
124 connected = true;
125 break;
126 default:
127 break;
128 }
129 }
130 return connected;
131}
132
133void r600_hpd_set_polarity(struct radeon_device *rdev,
134 enum radeon_hpd_id hpd)
135{
136 u32 tmp;
137 bool connected = r600_hpd_sense(rdev, hpd);
138
139 if (ASIC_IS_DCE3(rdev)) {
140 switch (hpd) {
141 case RADEON_HPD_1:
142 tmp = RREG32(DC_HPD1_INT_CONTROL);
143 if (connected)
144 tmp &= ~DC_HPDx_INT_POLARITY;
145 else
146 tmp |= DC_HPDx_INT_POLARITY;
147 WREG32(DC_HPD1_INT_CONTROL, tmp);
148 break;
149 case RADEON_HPD_2:
150 tmp = RREG32(DC_HPD2_INT_CONTROL);
151 if (connected)
152 tmp &= ~DC_HPDx_INT_POLARITY;
153 else
154 tmp |= DC_HPDx_INT_POLARITY;
155 WREG32(DC_HPD2_INT_CONTROL, tmp);
156 break;
157 case RADEON_HPD_3:
158 tmp = RREG32(DC_HPD3_INT_CONTROL);
159 if (connected)
160 tmp &= ~DC_HPDx_INT_POLARITY;
161 else
162 tmp |= DC_HPDx_INT_POLARITY;
163 WREG32(DC_HPD3_INT_CONTROL, tmp);
164 break;
165 case RADEON_HPD_4:
166 tmp = RREG32(DC_HPD4_INT_CONTROL);
167 if (connected)
168 tmp &= ~DC_HPDx_INT_POLARITY;
169 else
170 tmp |= DC_HPDx_INT_POLARITY;
171 WREG32(DC_HPD4_INT_CONTROL, tmp);
172 break;
173 case RADEON_HPD_5:
174 tmp = RREG32(DC_HPD5_INT_CONTROL);
175 if (connected)
176 tmp &= ~DC_HPDx_INT_POLARITY;
177 else
178 tmp |= DC_HPDx_INT_POLARITY;
179 WREG32(DC_HPD5_INT_CONTROL, tmp);
180 break;
181 /* DCE 3.2 */
182 case RADEON_HPD_6:
183 tmp = RREG32(DC_HPD6_INT_CONTROL);
184 if (connected)
185 tmp &= ~DC_HPDx_INT_POLARITY;
186 else
187 tmp |= DC_HPDx_INT_POLARITY;
188 WREG32(DC_HPD6_INT_CONTROL, tmp);
189 break;
190 default:
191 break;
192 }
193 } else {
194 switch (hpd) {
195 case RADEON_HPD_1:
196 tmp = RREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL);
197 if (connected)
198 tmp &= ~DC_HOT_PLUG_DETECTx_INT_POLARITY;
199 else
200 tmp |= DC_HOT_PLUG_DETECTx_INT_POLARITY;
201 WREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL, tmp);
202 break;
203 case RADEON_HPD_2:
204 tmp = RREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL);
205 if (connected)
206 tmp &= ~DC_HOT_PLUG_DETECTx_INT_POLARITY;
207 else
208 tmp |= DC_HOT_PLUG_DETECTx_INT_POLARITY;
209 WREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL, tmp);
210 break;
211 case RADEON_HPD_3:
212 tmp = RREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL);
213 if (connected)
214 tmp &= ~DC_HOT_PLUG_DETECTx_INT_POLARITY;
215 else
216 tmp |= DC_HOT_PLUG_DETECTx_INT_POLARITY;
217 WREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL, tmp);
218 break;
219 default:
220 break;
221 }
222 }
223}
224
225void r600_hpd_init(struct radeon_device *rdev)
226{
227 struct drm_device *dev = rdev->ddev;
228 struct drm_connector *connector;
229
230 if (ASIC_IS_DCE3(rdev)) {
231 u32 tmp = DC_HPDx_CONNECTION_TIMER(0x9c4) | DC_HPDx_RX_INT_TIMER(0xfa);
232 if (ASIC_IS_DCE32(rdev))
233 tmp |= DC_HPDx_EN;
234
235 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
236 struct radeon_connector *radeon_connector = to_radeon_connector(connector);
237 switch (radeon_connector->hpd.hpd) {
238 case RADEON_HPD_1:
239 WREG32(DC_HPD1_CONTROL, tmp);
240 rdev->irq.hpd[0] = true;
241 break;
242 case RADEON_HPD_2:
243 WREG32(DC_HPD2_CONTROL, tmp);
244 rdev->irq.hpd[1] = true;
245 break;
246 case RADEON_HPD_3:
247 WREG32(DC_HPD3_CONTROL, tmp);
248 rdev->irq.hpd[2] = true;
249 break;
250 case RADEON_HPD_4:
251 WREG32(DC_HPD4_CONTROL, tmp);
252 rdev->irq.hpd[3] = true;
253 break;
254 /* DCE 3.2 */
255 case RADEON_HPD_5:
256 WREG32(DC_HPD5_CONTROL, tmp);
257 rdev->irq.hpd[4] = true;
258 break;
259 case RADEON_HPD_6:
260 WREG32(DC_HPD6_CONTROL, tmp);
261 rdev->irq.hpd[5] = true;
262 break;
263 default:
264 break;
265 }
266 }
267 } else {
268 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
269 struct radeon_connector *radeon_connector = to_radeon_connector(connector);
270 switch (radeon_connector->hpd.hpd) {
271 case RADEON_HPD_1:
272 WREG32(DC_HOT_PLUG_DETECT1_CONTROL, DC_HOT_PLUG_DETECTx_EN);
273 rdev->irq.hpd[0] = true;
274 break;
275 case RADEON_HPD_2:
276 WREG32(DC_HOT_PLUG_DETECT2_CONTROL, DC_HOT_PLUG_DETECTx_EN);
277 rdev->irq.hpd[1] = true;
278 break;
279 case RADEON_HPD_3:
280 WREG32(DC_HOT_PLUG_DETECT3_CONTROL, DC_HOT_PLUG_DETECTx_EN);
281 rdev->irq.hpd[2] = true;
282 break;
283 default:
284 break;
285 }
286 }
287 }
288 r600_irq_set(rdev);
289}
290
291void r600_hpd_fini(struct radeon_device *rdev)
292{
293 struct drm_device *dev = rdev->ddev;
294 struct drm_connector *connector;
295
296 if (ASIC_IS_DCE3(rdev)) {
297 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
298 struct radeon_connector *radeon_connector = to_radeon_connector(connector);
299 switch (radeon_connector->hpd.hpd) {
300 case RADEON_HPD_1:
301 WREG32(DC_HPD1_CONTROL, 0);
302 rdev->irq.hpd[0] = false;
303 break;
304 case RADEON_HPD_2:
305 WREG32(DC_HPD2_CONTROL, 0);
306 rdev->irq.hpd[1] = false;
307 break;
308 case RADEON_HPD_3:
309 WREG32(DC_HPD3_CONTROL, 0);
310 rdev->irq.hpd[2] = false;
311 break;
312 case RADEON_HPD_4:
313 WREG32(DC_HPD4_CONTROL, 0);
314 rdev->irq.hpd[3] = false;
315 break;
316 /* DCE 3.2 */
317 case RADEON_HPD_5:
318 WREG32(DC_HPD5_CONTROL, 0);
319 rdev->irq.hpd[4] = false;
320 break;
321 case RADEON_HPD_6:
322 WREG32(DC_HPD6_CONTROL, 0);
323 rdev->irq.hpd[5] = false;
324 break;
325 default:
326 break;
327 }
328 }
329 } else {
330 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
331 struct radeon_connector *radeon_connector = to_radeon_connector(connector);
332 switch (radeon_connector->hpd.hpd) {
333 case RADEON_HPD_1:
334 WREG32(DC_HOT_PLUG_DETECT1_CONTROL, 0);
335 rdev->irq.hpd[0] = false;
336 break;
337 case RADEON_HPD_2:
338 WREG32(DC_HOT_PLUG_DETECT2_CONTROL, 0);
339 rdev->irq.hpd[1] = false;
340 break;
341 case RADEON_HPD_3:
342 WREG32(DC_HOT_PLUG_DETECT3_CONTROL, 0);
343 rdev->irq.hpd[2] = false;
344 break;
345 default:
346 break;
347 }
348 }
349 }
350}
351
77/* 352/*
78 * R600 PCIE GART 353 * R600 PCIE GART
79 */ 354 */
@@ -2060,6 +2335,42 @@ static void r600_disable_interrupts(struct radeon_device *rdev)
2060 rdev->ih.rptr = 0; 2335 rdev->ih.rptr = 0;
2061} 2336}
2062 2337
2338static void r600_disable_interrupt_state(struct radeon_device *rdev)
2339{
2340 u32 tmp;
2341
2342 WREG32(CP_INT_CNTL, 0);
2343 WREG32(GRBM_INT_CNTL, 0);
2344 WREG32(DxMODE_INT_MASK, 0);
2345 if (ASIC_IS_DCE3(rdev)) {
2346 WREG32(DCE3_DACA_AUTODETECT_INT_CONTROL, 0);
2347 WREG32(DCE3_DACB_AUTODETECT_INT_CONTROL, 0);
2348 tmp = RREG32(DC_HPD1_INT_CONTROL) & DC_HPDx_INT_POLARITY;
2349 WREG32(DC_HPD1_INT_CONTROL, tmp);
2350 tmp = RREG32(DC_HPD2_INT_CONTROL) & DC_HPDx_INT_POLARITY;
2351 WREG32(DC_HPD2_INT_CONTROL, tmp);
2352 tmp = RREG32(DC_HPD3_INT_CONTROL) & DC_HPDx_INT_POLARITY;
2353 WREG32(DC_HPD3_INT_CONTROL, tmp);
2354 tmp = RREG32(DC_HPD4_INT_CONTROL) & DC_HPDx_INT_POLARITY;
2355 WREG32(DC_HPD4_INT_CONTROL, tmp);
2356 if (ASIC_IS_DCE32(rdev)) {
2357 tmp = RREG32(DC_HPD5_INT_CONTROL) & DC_HPDx_INT_POLARITY;
2358 WREG32(DC_HPD5_INT_CONTROL, 0);
2359 tmp = RREG32(DC_HPD6_INT_CONTROL) & DC_HPDx_INT_POLARITY;
2360 WREG32(DC_HPD6_INT_CONTROL, 0);
2361 }
2362 } else {
2363 WREG32(DACA_AUTODETECT_INT_CONTROL, 0);
2364 WREG32(DACB_AUTODETECT_INT_CONTROL, 0);
2365 tmp = RREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL) & DC_HOT_PLUG_DETECTx_INT_POLARITY;
2366 WREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL, 0);
2367 tmp = RREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL) & DC_HOT_PLUG_DETECTx_INT_POLARITY;
2368 WREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL, 0);
2369 tmp = RREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL) & DC_HOT_PLUG_DETECTx_INT_POLARITY;
2370 WREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL, 0);
2371 }
2372}
2373
2063int r600_irq_init(struct radeon_device *rdev) 2374int r600_irq_init(struct radeon_device *rdev)
2064{ 2375{
2065 int ret = 0; 2376 int ret = 0;
@@ -2122,9 +2433,7 @@ int r600_irq_init(struct radeon_device *rdev)
2122 WREG32(IH_CNTL, ih_cntl); 2433 WREG32(IH_CNTL, ih_cntl);
2123 2434
2124 /* force the active interrupt state to all disabled */ 2435 /* force the active interrupt state to all disabled */
2125 WREG32(CP_INT_CNTL, 0); 2436 r600_disable_interrupt_state(rdev);
2126 WREG32(GRBM_INT_CNTL, 0);
2127 WREG32(DxMODE_INT_MASK, 0);
2128 2437
2129 /* enable irqs */ 2438 /* enable irqs */
2130 r600_enable_interrupts(rdev); 2439 r600_enable_interrupts(rdev);
@@ -2141,13 +2450,29 @@ void r600_irq_fini(struct radeon_device *rdev)
2141 2450
2142int r600_irq_set(struct radeon_device *rdev) 2451int r600_irq_set(struct radeon_device *rdev)
2143{ 2452{
2144 uint32_t cp_int_cntl = CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE; 2453 u32 cp_int_cntl = CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE;
2145 uint32_t mode_int = 0; 2454 u32 mode_int = 0;
2455 u32 hpd1, hpd2, hpd3, hpd4 = 0, hpd5 = 0, hpd6 = 0;
2146 2456
2147 /* don't enable anything if the ih is disabled */ 2457 /* don't enable anything if the ih is disabled */
2148 if (!rdev->ih.enabled) 2458 if (!rdev->ih.enabled)
2149 return 0; 2459 return 0;
2150 2460
2461 if (ASIC_IS_DCE3(rdev)) {
2462 hpd1 = RREG32(DC_HPD1_INT_CONTROL) & ~DC_HPDx_INT_EN;
2463 hpd2 = RREG32(DC_HPD2_INT_CONTROL) & ~DC_HPDx_INT_EN;
2464 hpd3 = RREG32(DC_HPD3_INT_CONTROL) & ~DC_HPDx_INT_EN;
2465 hpd4 = RREG32(DC_HPD4_INT_CONTROL) & ~DC_HPDx_INT_EN;
2466 if (ASIC_IS_DCE32(rdev)) {
2467 hpd5 = RREG32(DC_HPD5_INT_CONTROL) & ~DC_HPDx_INT_EN;
2468 hpd6 = RREG32(DC_HPD6_INT_CONTROL) & ~DC_HPDx_INT_EN;
2469 }
2470 } else {
2471 hpd1 = RREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL) & ~DC_HPDx_INT_EN;
2472 hpd2 = RREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL) & ~DC_HPDx_INT_EN;
2473 hpd3 = RREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL) & ~DC_HPDx_INT_EN;
2474 }
2475
2151 if (rdev->irq.sw_int) { 2476 if (rdev->irq.sw_int) {
2152 DRM_DEBUG("r600_irq_set: sw int\n"); 2477 DRM_DEBUG("r600_irq_set: sw int\n");
2153 cp_int_cntl |= RB_INT_ENABLE; 2478 cp_int_cntl |= RB_INT_ENABLE;
@@ -2160,39 +2485,137 @@ int r600_irq_set(struct radeon_device *rdev)
2160 DRM_DEBUG("r600_irq_set: vblank 1\n"); 2485 DRM_DEBUG("r600_irq_set: vblank 1\n");
2161 mode_int |= D2MODE_VBLANK_INT_MASK; 2486 mode_int |= D2MODE_VBLANK_INT_MASK;
2162 } 2487 }
2488 if (rdev->irq.hpd[0]) {
2489 DRM_DEBUG("r600_irq_set: hpd 1\n");
2490 hpd1 |= DC_HPDx_INT_EN;
2491 }
2492 if (rdev->irq.hpd[1]) {
2493 DRM_DEBUG("r600_irq_set: hpd 2\n");
2494 hpd2 |= DC_HPDx_INT_EN;
2495 }
2496 if (rdev->irq.hpd[2]) {
2497 DRM_DEBUG("r600_irq_set: hpd 3\n");
2498 hpd3 |= DC_HPDx_INT_EN;
2499 }
2500 if (rdev->irq.hpd[3]) {
2501 DRM_DEBUG("r600_irq_set: hpd 4\n");
2502 hpd4 |= DC_HPDx_INT_EN;
2503 }
2504 if (rdev->irq.hpd[4]) {
2505 DRM_DEBUG("r600_irq_set: hpd 5\n");
2506 hpd5 |= DC_HPDx_INT_EN;
2507 }
2508 if (rdev->irq.hpd[5]) {
2509 DRM_DEBUG("r600_irq_set: hpd 6\n");
2510 hpd6 |= DC_HPDx_INT_EN;
2511 }
2163 2512
2164 WREG32(CP_INT_CNTL, cp_int_cntl); 2513 WREG32(CP_INT_CNTL, cp_int_cntl);
2165 WREG32(DxMODE_INT_MASK, mode_int); 2514 WREG32(DxMODE_INT_MASK, mode_int);
2515 if (ASIC_IS_DCE3(rdev)) {
2516 WREG32(DC_HPD1_INT_CONTROL, hpd1);
2517 WREG32(DC_HPD2_INT_CONTROL, hpd2);
2518 WREG32(DC_HPD3_INT_CONTROL, hpd3);
2519 WREG32(DC_HPD4_INT_CONTROL, hpd4);
2520 if (ASIC_IS_DCE32(rdev)) {
2521 WREG32(DC_HPD5_INT_CONTROL, hpd5);
2522 WREG32(DC_HPD6_INT_CONTROL, hpd6);
2523 }
2524 } else {
2525 WREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL, hpd1);
2526 WREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL, hpd2);
2527 WREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL, hpd3);
2528 }
2166 2529
2167 return 0; 2530 return 0;
2168} 2531}
2169 2532
2170static inline void r600_irq_ack(struct radeon_device *rdev, u32 disp_int) 2533static inline void r600_irq_ack(struct radeon_device *rdev,
2534 u32 *disp_int,
2535 u32 *disp_int_cont,
2536 u32 *disp_int_cont2)
2171{ 2537{
2538 u32 tmp;
2539
2540 if (ASIC_IS_DCE3(rdev)) {
2541 *disp_int = RREG32(DCE3_DISP_INTERRUPT_STATUS);
2542 *disp_int_cont = RREG32(DCE3_DISP_INTERRUPT_STATUS_CONTINUE);
2543 *disp_int_cont2 = RREG32(DCE3_DISP_INTERRUPT_STATUS_CONTINUE2);
2544 } else {
2545 *disp_int = RREG32(DISP_INTERRUPT_STATUS);
2546 *disp_int_cont = RREG32(DISP_INTERRUPT_STATUS_CONTINUE);
2547 *disp_int_cont2 = 0;
2548 }
2172 2549
2173 if (disp_int & LB_D1_VBLANK_INTERRUPT) 2550 if (*disp_int & LB_D1_VBLANK_INTERRUPT)
2174 WREG32(D1MODE_VBLANK_STATUS, DxMODE_VBLANK_ACK); 2551 WREG32(D1MODE_VBLANK_STATUS, DxMODE_VBLANK_ACK);
2175 if (disp_int & LB_D1_VLINE_INTERRUPT) 2552 if (*disp_int & LB_D1_VLINE_INTERRUPT)
2176 WREG32(D1MODE_VLINE_STATUS, DxMODE_VLINE_ACK); 2553 WREG32(D1MODE_VLINE_STATUS, DxMODE_VLINE_ACK);
2177 if (disp_int & LB_D2_VBLANK_INTERRUPT) 2554 if (*disp_int & LB_D2_VBLANK_INTERRUPT)
2178 WREG32(D2MODE_VBLANK_STATUS, DxMODE_VBLANK_ACK); 2555 WREG32(D2MODE_VBLANK_STATUS, DxMODE_VBLANK_ACK);
2179 if (disp_int & LB_D2_VLINE_INTERRUPT) 2556 if (*disp_int & LB_D2_VLINE_INTERRUPT)
2180 WREG32(D2MODE_VLINE_STATUS, DxMODE_VLINE_ACK); 2557 WREG32(D2MODE_VLINE_STATUS, DxMODE_VLINE_ACK);
2181 2558 if (*disp_int & DC_HPD1_INTERRUPT) {
2559 if (ASIC_IS_DCE3(rdev)) {
2560 tmp = RREG32(DC_HPD1_INT_CONTROL);
2561 tmp |= DC_HPDx_INT_ACK;
2562 WREG32(DC_HPD1_INT_CONTROL, tmp);
2563 } else {
2564 tmp = RREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL);
2565 tmp |= DC_HPDx_INT_ACK;
2566 WREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL, tmp);
2567 }
2568 }
2569 if (*disp_int & DC_HPD2_INTERRUPT) {
2570 if (ASIC_IS_DCE3(rdev)) {
2571 tmp = RREG32(DC_HPD2_INT_CONTROL);
2572 tmp |= DC_HPDx_INT_ACK;
2573 WREG32(DC_HPD2_INT_CONTROL, tmp);
2574 } else {
2575 tmp = RREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL);
2576 tmp |= DC_HPDx_INT_ACK;
2577 WREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL, tmp);
2578 }
2579 }
2580 if (*disp_int_cont & DC_HPD3_INTERRUPT) {
2581 if (ASIC_IS_DCE3(rdev)) {
2582 tmp = RREG32(DC_HPD3_INT_CONTROL);
2583 tmp |= DC_HPDx_INT_ACK;
2584 WREG32(DC_HPD3_INT_CONTROL, tmp);
2585 } else {
2586 tmp = RREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL);
2587 tmp |= DC_HPDx_INT_ACK;
2588 WREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL, tmp);
2589 }
2590 }
2591 if (*disp_int_cont & DC_HPD4_INTERRUPT) {
2592 tmp = RREG32(DC_HPD4_INT_CONTROL);
2593 tmp |= DC_HPDx_INT_ACK;
2594 WREG32(DC_HPD4_INT_CONTROL, tmp);
2595 }
2596 if (ASIC_IS_DCE32(rdev)) {
2597 if (*disp_int_cont2 & DC_HPD5_INTERRUPT) {
2598 tmp = RREG32(DC_HPD5_INT_CONTROL);
2599 tmp |= DC_HPDx_INT_ACK;
2600 WREG32(DC_HPD5_INT_CONTROL, tmp);
2601 }
2602 if (*disp_int_cont2 & DC_HPD6_INTERRUPT) {
2603 tmp = RREG32(DC_HPD5_INT_CONTROL);
2604 tmp |= DC_HPDx_INT_ACK;
2605 WREG32(DC_HPD6_INT_CONTROL, tmp);
2606 }
2607 }
2182} 2608}
2183 2609
2184void r600_irq_disable(struct radeon_device *rdev) 2610void r600_irq_disable(struct radeon_device *rdev)
2185{ 2611{
2186 u32 disp_int; 2612 u32 disp_int, disp_int_cont, disp_int_cont2;
2187 2613
2188 r600_disable_interrupts(rdev); 2614 r600_disable_interrupts(rdev);
2189 /* Wait and acknowledge irq */ 2615 /* Wait and acknowledge irq */
2190 mdelay(1); 2616 mdelay(1);
2191 if (ASIC_IS_DCE3(rdev)) 2617 r600_irq_ack(rdev, &disp_int, &disp_int_cont, &disp_int_cont2);
2192 disp_int = RREG32(DCE3_DISP_INTERRUPT_STATUS); 2618 r600_disable_interrupt_state(rdev);
2193 else
2194 disp_int = RREG32(DISP_INTERRUPT_STATUS);
2195 r600_irq_ack(rdev, disp_int);
2196} 2619}
2197 2620
2198static inline u32 r600_get_ih_wptr(struct radeon_device *rdev) 2621static inline u32 r600_get_ih_wptr(struct radeon_device *rdev)
@@ -2249,7 +2672,7 @@ int r600_irq_process(struct radeon_device *rdev)
2249 u32 rptr = rdev->ih.rptr; 2672 u32 rptr = rdev->ih.rptr;
2250 u32 src_id, src_data; 2673 u32 src_id, src_data;
2251 u32 last_entry = rdev->ih.ring_size - 16; 2674 u32 last_entry = rdev->ih.ring_size - 16;
2252 u32 ring_index, disp_int; 2675 u32 ring_index, disp_int, disp_int_cont, disp_int_cont2;
2253 unsigned long flags; 2676 unsigned long flags;
2254 2677
2255 DRM_DEBUG("r600_irq_process start: rptr %d, wptr %d\n", rptr, wptr); 2678 DRM_DEBUG("r600_irq_process start: rptr %d, wptr %d\n", rptr, wptr);
@@ -2267,11 +2690,7 @@ int r600_irq_process(struct radeon_device *rdev)
2267 2690
2268restart_ih: 2691restart_ih:
2269 /* display interrupts */ 2692 /* display interrupts */
2270 if (ASIC_IS_DCE3(rdev)) 2693 r600_irq_ack(rdev, &disp_int, &disp_int_cont, &disp_int_cont2);
2271 disp_int = RREG32(DCE3_DISP_INTERRUPT_STATUS);
2272 else
2273 disp_int = RREG32(DISP_INTERRUPT_STATUS);
2274 r600_irq_ack(rdev, disp_int);
2275 2694
2276 rdev->ih.wptr = wptr; 2695 rdev->ih.wptr = wptr;
2277 while (rptr != wptr) { 2696 while (rptr != wptr) {
@@ -2321,6 +2740,49 @@ restart_ih:
2321 break; 2740 break;
2322 } 2741 }
2323 break; 2742 break;
2743 case 19: /* HPD/DAC hotplug */
2744 switch (src_data) {
2745 case 0:
2746 if (disp_int & DC_HPD1_INTERRUPT) {
2747 disp_int &= ~DC_HPD1_INTERRUPT;
2748 DRM_INFO("IH: HPD1\n");
2749 }
2750 break;
2751 case 1:
2752 if (disp_int & DC_HPD2_INTERRUPT) {
2753 disp_int &= ~DC_HPD2_INTERRUPT;
2754 DRM_INFO("IH: HPD2\n");
2755 }
2756 break;
2757 case 4:
2758 if (disp_int_cont & DC_HPD3_INTERRUPT) {
2759 disp_int_cont &= ~DC_HPD3_INTERRUPT;
2760 DRM_INFO("IH: HPD3\n");
2761 }
2762 break;
2763 case 5:
2764 if (disp_int_cont & DC_HPD4_INTERRUPT) {
2765 disp_int_cont &= ~DC_HPD4_INTERRUPT;
2766 DRM_INFO("IH: HPD4\n");
2767 }
2768 break;
2769 case 10:
2770 if (disp_int_cont2 & DC_HPD5_INTERRUPT) {
2771 disp_int_cont &= ~DC_HPD5_INTERRUPT;
2772 DRM_INFO("IH: HPD5\n");
2773 }
2774 break;
2775 case 12:
2776 if (disp_int_cont2 & DC_HPD6_INTERRUPT) {
2777 disp_int_cont &= ~DC_HPD6_INTERRUPT;
2778 DRM_INFO("IH: HPD6\n");
2779 }
2780 break;
2781 default:
2782 DRM_ERROR("Unhandled interrupt: %d %d\n", src_id, src_data);
2783 break;
2784 }
2785 break;
2324 case 176: /* CP_INT in ring buffer */ 2786 case 176: /* CP_INT in ring buffer */
2325 case 177: /* CP_INT in IB1 */ 2787 case 177: /* CP_INT in IB1 */
2326 case 178: /* CP_INT in IB2 */ 2788 case 178: /* CP_INT in IB2 */