Rev 2997 | Rev 3764 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2997 | Rev 3120 | ||
---|---|---|---|
Line 32... | Line 32... | ||
32 | #include "radeon.h" |
32 | #include "radeon.h" |
33 | #include "atom.h" |
33 | #include "atom.h" |
Line 34... | Line 34... | ||
34 | 34 | ||
Line -... | Line 35... | ||
- | 35 | #define RADEON_WAIT_IDLE_TIMEOUT 200 |
|
- | 36 | ||
35 | #define RADEON_WAIT_IDLE_TIMEOUT 200 |
37 | #define DRM_IRQ_ARGS void *arg |
- | 38 | ||
- | 39 | struct drm_driver { |
|
- | 40 | irqreturn_t(*irq_handler) (DRM_IRQ_ARGS); |
|
- | 41 | void (*irq_preinstall) (struct drm_device *dev); |
|
Line 36... | Line 42... | ||
36 | 42 | int (*irq_postinstall) (struct drm_device *dev); |
|
Line 37... | Line 43... | ||
37 | struct radeon_device *main_device; |
43 | }; |
Line 46... | Line 52... | ||
46 | * |
52 | * |
47 | * This is the irq handler for the radeon KMS driver (all asics). |
53 | * This is the irq handler for the radeon KMS driver (all asics). |
48 | * radeon_irq_process is a macro that points to the per-asic |
54 | * radeon_irq_process is a macro that points to the per-asic |
49 | * irq handler callback. |
55 | * irq handler callback. |
50 | */ |
56 | */ |
51 | void irq_handler_kms() |
57 | irqreturn_t radeon_driver_irq_handler_kms(DRM_IRQ_ARGS) |
52 | { |
58 | { |
- | 59 | struct drm_device *dev = (struct drm_device *) arg; |
|
- | 60 | struct radeon_device *rdev = dev->dev_private; |
|
- | 61 | ||
53 | radeon_irq_process(main_device); |
62 | return radeon_irq_process(rdev); |
54 | } |
63 | } |
Line 55... | Line 64... | ||
55 | 64 | ||
56 | /** |
65 | /** |
57 | * radeon_driver_irq_preinstall_kms - drm irq preinstall callback |
66 | * radeon_driver_irq_preinstall_kms - drm irq preinstall callback |
58 | * |
67 | * |
59 | * @dev: drm dev pointer |
68 | * @dev: drm dev pointer |
60 | * |
69 | * |
61 | * Gets the hw ready to enable irqs (all asics). |
70 | * Gets the hw ready to enable irqs (all asics). |
62 | * This function disables all interrupt sources on the GPU. |
71 | * This function disables all interrupt sources on the GPU. |
63 | */ |
72 | */ |
64 | void radeon_irq_preinstall_kms(struct radeon_device *rdev) |
73 | void radeon_driver_irq_preinstall_kms(struct drm_device *dev) |
- | 74 | { |
|
65 | { |
75 | struct radeon_device *rdev = dev->dev_private; |
66 | unsigned long irqflags; |
76 | unsigned long irqflags; |
Line 67... | Line 77... | ||
67 | unsigned i; |
77 | unsigned i; |
68 | 78 | ||
Line 89... | Line 99... | ||
89 | * @dev: drm dev pointer |
99 | * @dev: drm dev pointer |
90 | * |
100 | * |
91 | * Handles stuff to be done after enabling irqs (all asics). |
101 | * Handles stuff to be done after enabling irqs (all asics). |
92 | * Returns 0 on success. |
102 | * Returns 0 on success. |
93 | */ |
103 | */ |
94 | - | ||
95 | int radeon_driver_irq_postinstall_kms(struct radeon_device *rdev) |
104 | int radeon_driver_irq_postinstall_kms(struct drm_device *dev) |
96 | { |
105 | { |
97 | // struct radeon_device *rdev = dev->dev_private; |
106 | dev->max_vblank_count = 0x001fffff; |
- | 107 | return 0; |
|
- | 108 | } |
|
Line -... | Line 109... | ||
- | 109 | ||
- | 110 | /** |
|
- | 111 | * radeon_driver_irq_uninstall_kms - drm irq uninstall callback |
|
- | 112 | * |
|
- | 113 | * @dev: drm dev pointer |
|
- | 114 | * |
|
- | 115 | * This function disables all interrupt sources on the GPU (all asics). |
|
- | 116 | */ |
|
- | 117 | void radeon_driver_irq_uninstall_kms(struct drm_device *dev) |
|
98 | 118 | { |
|
- | 119 | struct radeon_device *rdev = dev->dev_private; |
|
- | 120 | unsigned long irqflags; |
|
Line -... | Line 121... | ||
- | 121 | unsigned i; |
|
- | 122 | ||
- | 123 | if (rdev == NULL) { |
|
- | 124 | return; |
|
- | 125 | } |
|
- | 126 | spin_lock_irqsave(&rdev->irq.lock, irqflags); |
|
- | 127 | /* Disable *all* interrupts */ |
|
- | 128 | for (i = 0; i < RADEON_NUM_RINGS; i++) |
|
- | 129 | atomic_set(&rdev->irq.ring_int[i], 0); |
|
- | 130 | for (i = 0; i < RADEON_MAX_HPD_PINS; i++) |
|
- | 131 | rdev->irq.hpd[i] = false; |
|
- | 132 | for (i = 0; i < RADEON_MAX_CRTCS; i++) { |
|
- | 133 | rdev->irq.crtc_vblank_int[i] = false; |
|
- | 134 | atomic_set(&rdev->irq.pflip[i], 0); |
|
99 | // dev->max_vblank_count = 0x001fffff; |
135 | rdev->irq.afmt[i] = false; |
100 | 136 | } |
|
101 | radeon_irq_set(rdev); |
137 | radeon_irq_set(rdev); |
Line -... | Line 138... | ||
- | 138 | spin_unlock_irqrestore(&rdev->irq.lock, irqflags); |
|
- | 139 | } |
|
102 | return 0; |
140 | |
103 | } |
141 | |
104 | 142 | ||
105 | /** |
143 | /** |
106 | * radeon_irq_kms_init - init driver interrupt info |
144 | * radeon_irq_kms_init - init driver interrupt info |
Line 115... | Line 153... | ||
115 | int irq_line; |
153 | int irq_line; |
116 | int r = 0; |
154 | int r = 0; |
Line 117... | Line 155... | ||
117 | 155 | ||
Line 118... | Line -... | ||
118 | ENTER(); |
- | |
119 | - | ||
Line 120... | Line 156... | ||
120 | // INIT_WORK(&rdev->hotplug_work, radeon_hotplug_work_func); |
156 | ENTER(); |
121 | // INIT_WORK(&rdev->audio_work, r600_audio_update_hdmi); |
- | |
122 | - | ||
123 | spin_lock_init(&rdev->irq.lock); |
- | |
124 | // r = drm_vblank_init(rdev->ddev, rdev->num_crtc); |
- | |
125 | // if (r) { |
157 | |
126 | // return r; |
158 | |
Line 127... | Line -... | ||
127 | // } |
- | |
128 | /* enable msi */ |
- | |
129 | rdev->msi_enabled = 0; |
- | |
130 | - | ||
131 | // if (radeon_msi_ok(rdev)) { |
- | |
132 | // int ret = pci_enable_msi(rdev->pdev); |
- | |
133 | // if (!ret) { |
- | |
134 | // rdev->msi_enabled = 1; |
159 | spin_lock_init(&rdev->irq.lock); |
135 | // dev_info(rdev->dev, "radeon: using MSI.\n"); |
- | |
136 | // } |
- | |
137 | // } |
- | |
138 | rdev->irq.installed = true; |
- | |
139 | main_device = rdev; |
- | |
140 | - | ||
141 | radeon_irq_preinstall_kms(rdev); |
- | |
142 | - | ||
143 | if (irq_override) |
- | |
144 | irq_line = irq_override; |
- | |
145 | else |
- | |
146 | irq_line = rdev->pdev->irq; |
- | |
147 | - | ||
148 | dbgprintf("%s install irq %d\n", __FUNCTION__, irq_line); |
160 | /* enable msi */ |
149 | - | ||
150 | AttachIntHandler(irq_line, irq_handler_kms, 2); |
- | |
151 | 161 | rdev->msi_enabled = 0; |
|
152 | // r = drm_irq_install(rdev->ddev); |
162 | |
153 | 163 | rdev->irq.installed = true; |
|
154 | r = radeon_driver_irq_postinstall_kms(rdev); |
164 | r = drm_irq_install(rdev->ddev); |
155 | if (r) { |
165 | if (r) { |
156 | rdev->irq.installed = false; |
166 | rdev->irq.installed = false; |
157 | LEAVE(); |
167 | FAIL(); |
158 | return r; |
168 | return r; |
Line 226... | Line 236... | ||
226 | radeon_irq_set(rdev); |
236 | radeon_irq_set(rdev); |
227 | spin_unlock_irqrestore(&rdev->irq.lock, irqflags); |
237 | spin_unlock_irqrestore(&rdev->irq.lock, irqflags); |
228 | } |
238 | } |
229 | }>>> |
239 | } |
Line -... | Line 240... | ||
- | 240 | ||
- | 241 | /** |
|
- | 242 | * radeon_irq_kms_enable_hpd - enable hotplug detect interrupt |
|
- | 243 | * |
|
- | 244 | * @rdev: radeon device pointer |
|
- | 245 | * @hpd_mask: mask of hpd pins you want to enable. |
|
- | 246 | * |
|
- | 247 | * Enables the hotplug detect interrupt for a specific hpd pin (all asics). |
|
- | 248 | */ |
|
- | 249 | void radeon_irq_kms_enable_hpd(struct radeon_device *rdev, unsigned hpd_mask) |
|
- | 250 | { |
|
- | 251 | unsigned long irqflags; |
|
- | 252 | int i; |
|
- | 253 | ||
- | 254 | spin_lock_irqsave(&rdev->irq.lock, irqflags); |
|
- | 255 | for (i = 0; i < RADEON_MAX_HPD_PINS; ++i) |
|
- | 256 | rdev->irq.hpd[i] |= !!(hpd_mask & (1 << i)); |
|
- | 257 | radeon_irq_set(rdev); |
|
- | 258 | spin_unlock_irqrestore(&rdev->irq.lock, irqflags); |
|
- | 259 | } |
|
- | 260 | ||
- | 261 | /** |
|
- | 262 | * radeon_irq_kms_disable_hpd - disable hotplug detect interrupt |
|
- | 263 | * |
|
- | 264 | * @rdev: radeon device pointer |
|
- | 265 | * @hpd_mask: mask of hpd pins you want to disable. |
|
- | 266 | * |
|
- | 267 | * Disables the hotplug detect interrupt for a specific hpd pin (all asics). |
|
- | 268 | */ |
|
- | 269 | void radeon_irq_kms_disable_hpd(struct radeon_device *rdev, unsigned hpd_mask) |
|
- | 270 | { |
|
- | 271 | unsigned long irqflags; |
|
- | 272 | int i; |
|
- | 273 | ||
- | 274 | spin_lock_irqsave(&rdev->irq.lock, irqflags); |
|
- | 275 | for (i = 0; i < RADEON_MAX_HPD_PINS; ++i) |
|
- | 276 | rdev->irq.hpd[i] &= !(hpd_mask & (1 << i)); |
|
- | 277 | radeon_irq_set(rdev); |
|
- | 278 | spin_unlock_irqrestore(&rdev->irq.lock, irqflags); |
|
- | 279 | } |
|
Line -... | Line 280... | ||
- | 280 | ||
- | 281 | ||
- | 282 | static struct drm_driver drm_driver = { |
|
- | 283 | .irq_preinstall = radeon_driver_irq_preinstall_kms, |
|
- | 284 | .irq_postinstall = radeon_driver_irq_postinstall_kms, |
|
- | 285 | .irq_handler = radeon_driver_irq_handler_kms |
|
- | 286 | }; |
|
- | 287 | ||
- | 288 | static struct drm_driver *driver = &drm_driver; |
|
- | 289 | ||
- | 290 | int drm_irq_install(struct drm_device *dev) |
|
- | 291 | { |
|
- | 292 | unsigned long sh_flags = 0; |
|
- | 293 | int irq_line; |
|
- | 294 | int ret = 0; |
|
- | 295 | ||
- | 296 | char *irqname; |
|
- | 297 | ||
- | 298 | mutex_lock(&dev->struct_mutex); |
|
- | 299 | ||
- | 300 | /* Driver must have been initialized */ |
|
- | 301 | if (!dev->dev_private) { |
|
- | 302 | mutex_unlock(&dev->struct_mutex); |
|
- | 303 | return -EINVAL; |
|
- | 304 | } |
|
- | 305 | ||
- | 306 | if (dev->irq_enabled) { |
|
- | 307 | mutex_unlock(&dev->struct_mutex); |
|
- | 308 | return -EBUSY; |
|
- | 309 | } |
|
- | 310 | dev->irq_enabled = 1; |
|
- | 311 | mutex_unlock(&dev->struct_mutex); |
|
- | 312 | ||
- | 313 | irq_line = drm_dev_to_irq(dev); |
|
- | 314 | ||
- | 315 | DRM_DEBUG("irq=%d\n", drm_dev_to_irq(dev)); |
|
- | 316 | ||
- | 317 | /* Before installing handler */ |
|
- | 318 | if (driver->irq_preinstall) |
|
- | 319 | driver->irq_preinstall(dev); |
|
- | 320 | ||
- | 321 | ret = AttachIntHandler(irq_line, driver->irq_handler, (u32)dev); |
|
- | 322 | ||
- | 323 | /* After installing handler */ |
|
- | 324 | if (driver->irq_postinstall) |
|
- | 325 | ret = driver->irq_postinstall(dev); |
|
- | 326 | ||
- | 327 | if (ret < 0) { |
|
- | 328 | DRM_ERROR(__FUNCTION__); |
|
- | 329 | } |
|
- | 330 | ||
- | 331 | u16_t cmd = PciRead16(dev->pdev->busnr, dev->pdev->devfn, 4); |
|
- | 332 | cmd&= ~(1<<10); |
|
- | 333 | PciWrite16(dev->pdev->busnr, dev->pdev->devfn, 4, cmd); |
|
- | 334 |