diff options
| -rw-r--r-- | drivers/gpu/drm/radeon/r600.c | 508 |
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); | |||
| 74 | void r600_gpu_init(struct radeon_device *rdev); | 74 | void r600_gpu_init(struct radeon_device *rdev); |
| 75 | void r600_fini(struct radeon_device *rdev); | 75 | void r600_fini(struct radeon_device *rdev); |
| 76 | 76 | ||
| 77 | /* hpd for digital panel detect/disconnect */ | ||
| 78 | bool 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 | |||
| 133 | void 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 | |||
| 225 | void 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 | |||
| 291 | void 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 | ||
| 2338 | static 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 | |||
| 2063 | int r600_irq_init(struct radeon_device *rdev) | 2374 | int 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 | ||
| 2142 | int r600_irq_set(struct radeon_device *rdev) | 2451 | int 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 | ||
| 2170 | static inline void r600_irq_ack(struct radeon_device *rdev, u32 disp_int) | 2533 | static 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 | ||
| 2184 | void r600_irq_disable(struct radeon_device *rdev) | 2610 | void 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 | ||
| 2198 | static inline u32 r600_get_ih_wptr(struct radeon_device *rdev) | 2621 | static 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 | ||
| 2268 | restart_ih: | 2691 | restart_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 */ |
