Rev 2160 | Rev 3120 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2160 | Rev 2997 | ||
---|---|---|---|
Line 23... | Line 23... | ||
23 | * |
23 | * |
24 | * Authors: Dave Airlie |
24 | * Authors: Dave Airlie |
25 | * Alex Deucher |
25 | * Alex Deucher |
26 | * Jerome Glisse |
26 | * Jerome Glisse |
27 | */ |
27 | */ |
28 | #include "drmP.h" |
28 | #include |
29 | #include "drm_crtc_helper.h" |
29 | #include |
30 | #include "radeon_drm.h" |
30 | #include |
31 | #include "radeon_reg.h" |
31 | #include "radeon_reg.h" |
32 | #include "radeon.h" |
32 | #include "radeon.h" |
33 | #include "atom.h" |
33 | #include "atom.h" |
Line -... | Line 34... | ||
- | 34 | ||
- | 35 | #define RADEON_WAIT_IDLE_TIMEOUT 200 |
|
34 | 36 | ||
Line 35... | Line 37... | ||
35 | struct radeon_device *main_device; |
37 | struct radeon_device *main_device; |
Line -... | Line 38... | ||
- | 38 | ||
- | 39 | extern int irq_override; |
|
- | 40 | ||
- | 41 | ||
- | 42 | /** |
|
- | 43 | * radeon_driver_irq_handler_kms - irq handler for KMS |
|
- | 44 | * |
|
- | 45 | * @DRM_IRQ_ARGS: args |
|
- | 46 | * |
|
- | 47 | * This is the irq handler for the radeon KMS driver (all asics). |
|
36 | 48 | * radeon_irq_process is a macro that points to the per-asic |
|
37 | extern int irq_override; |
49 | * irq handler callback. |
38 | - | ||
39 | void irq_handler_kms() |
50 | */ |
40 | { |
51 | void irq_handler_kms() |
Line -... | Line 52... | ||
- | 52 | { |
|
- | 53 | radeon_irq_process(main_device); |
|
- | 54 | } |
|
- | 55 | ||
41 | // dbgprintf("%s\n",__FUNCTION__); |
56 | /** |
- | 57 | * radeon_driver_irq_preinstall_kms - drm irq preinstall callback |
|
- | 58 | * |
|
- | 59 | * @dev: drm dev pointer |
|
42 | radeon_irq_process(main_device); |
60 | * |
43 | } |
61 | * Gets the hw ready to enable irqs (all asics). |
- | 62 | * This function disables all interrupt sources on the GPU. |
|
44 | 63 | */ |
|
Line -... | Line 64... | ||
- | 64 | void radeon_irq_preinstall_kms(struct radeon_device *rdev) |
|
45 | 65 | { |
|
46 | static void radeon_irq_preinstall(struct radeon_device *rdev) |
- | |
47 | { |
- | |
48 | unsigned i; |
66 | unsigned long irqflags; |
49 | 67 | unsigned i; |
|
50 | /* Disable *all* interrupts */ |
68 | |
51 | rdev->irq.sw_int = false; |
69 | spin_lock_irqsave(&rdev->irq.lock, irqflags); |
- | 70 | /* Disable *all* interrupts */ |
|
52 | rdev->irq.gui_idle = false; |
71 | for (i = 0; i < RADEON_NUM_RINGS; i++) |
- | 72 | atomic_set(&rdev->irq.ring_int[i], 0); |
|
- | 73 | for (i = 0; i < RADEON_MAX_HPD_PINS; i++) |
|
53 | for (i = 0; i < rdev->num_crtc; i++) |
74 | rdev->irq.hpd[i] = false; |
54 | rdev->irq.crtc_vblank_int[i] = false; |
75 | for (i = 0; i < RADEON_MAX_CRTCS; i++) { |
- | 76 | rdev->irq.crtc_vblank_int[i] = false; |
|
55 | for (i = 0; i < 6; i++) { |
77 | atomic_set(&rdev->irq.pflip[i], 0); |
56 | rdev->irq.hpd[i] = false; |
78 | rdev->irq.afmt[i] = false; |
57 | rdev->irq.pflip[i] = false; |
79 | } |
Line -... | Line 80... | ||
- | 80 | radeon_irq_set(rdev); |
|
- | 81 | spin_unlock_irqrestore(&rdev->irq.lock, irqflags); |
|
- | 82 | /* Clear bits */ |
|
- | 83 | radeon_irq_process(rdev); |
|
- | 84 | } |
|
- | 85 | ||
- | 86 | /** |
|
- | 87 | * radeon_driver_irq_postinstall_kms - drm irq preinstall callback |
|
- | 88 | * |
|
58 | } |
89 | * @dev: drm dev pointer |
59 | radeon_irq_set(rdev); |
90 | * |
60 | /* Clear bits */ |
91 | * Handles stuff to be done after enabling irqs (all asics). |
Line 61... | Line 92... | ||
61 | radeon_irq_process(rdev); |
92 | * Returns 0 on success. |
62 | } |
- | |
- | 93 | */ |
|
63 | 94 | ||
64 | int radeon_driver_irq_postinstall(struct radeon_device *rdev) |
95 | int radeon_driver_irq_postinstall_kms(struct radeon_device *rdev) |
65 | { |
96 | { |
Line -... | Line 97... | ||
- | 97 | // struct radeon_device *rdev = dev->dev_private; |
|
- | 98 | ||
- | 99 | // dev->max_vblank_count = 0x001fffff; |
|
- | 100 | ||
- | 101 | radeon_irq_set(rdev); |
|
- | 102 | return 0; |
|
- | 103 | } |
|
- | 104 | ||
66 | // struct radeon_device *rdev = dev->dev_private; |
105 | /** |
67 | 106 | * radeon_irq_kms_init - init driver interrupt info |
|
68 | // dev->max_vblank_count = 0x001fffff; |
- | |
69 | rdev->irq.sw_int = true; |
107 | * |
70 | radeon_irq_set(rdev); |
108 | * @rdev: radeon device pointer |
Line 71... | Line 109... | ||
71 | return 0; |
109 | * |
Line 72... | Line 110... | ||
72 | } |
110 | * Sets up the work irq handlers, vblank init, MSIs, etc. (all asics). |
- | 111 | * Returns 0 for success, error for failure. |
|
Line 73... | Line 112... | ||
73 | 112 | */ |
|
74 | int radeon_irq_kms_init(struct radeon_device *rdev) |
- | |
75 | { |
- | |
76 | int i; |
113 | int radeon_irq_kms_init(struct radeon_device *rdev) |
77 | int irq_line; |
114 | { |
78 | int r = 0; |
115 | int irq_line; |
79 | 116 | int r = 0; |
|
80 | ENTER(); |
- | |
- | 117 | ||
81 | 118 | ENTER(); |
|
- | 119 | ||
- | 120 | // INIT_WORK(&rdev->hotplug_work, radeon_hotplug_work_func); |
|
- | 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) { |
|
- | 126 | // return r; |
|
82 | // INIT_WORK(&rdev->hotplug_work, radeon_hotplug_work_func); |
127 | // } |
83 | 128 | /* enable msi */ |
|
Line 84... | Line 129... | ||
84 | spin_lock_init(&rdev->irq.sw_lock); |
129 | rdev->msi_enabled = 0; |
Line 85... | Line 130... | ||
85 | for (i = 0; i < rdev->num_crtc; i++) |
130 | |
86 | spin_lock_init(&rdev->irq.pflip_lock[i]); |
131 | // if (radeon_msi_ok(rdev)) { |
87 | // r = drm_vblank_init(rdev->ddev, rdev->num_crtc); |
132 | // int ret = pci_enable_msi(rdev->pdev); |
88 | // if (r) { |
133 | // if (!ret) { |
Line 104... | Line 149... | ||
104 | 149 | ||
Line 105... | Line 150... | ||
105 | AttachIntHandler(irq_line, irq_handler_kms, 2); |
150 | AttachIntHandler(irq_line, irq_handler_kms, 2); |
Line 106... | Line 151... | ||
106 | 151 | ||
107 | // r = drm_irq_install(rdev->ddev); |
152 | // r = drm_irq_install(rdev->ddev); |
108 | 153 | ||
109 | r = radeon_driver_irq_postinstall(rdev); |
154 | r = radeon_driver_irq_postinstall_kms(rdev); |
110 | if (r) { |
155 | if (r) { |
111 | rdev->irq.installed = false; |
156 | rdev->irq.installed = false; |
112 | LEAVE(); |
- | |
113 | return r; |
157 | LEAVE(); |
114 | } |
158 | return r; |
115 | 159 | } |
|
Line -... | Line 160... | ||
- | 160 | DRM_INFO("radeon: irq initialized.\n"); |
|
- | 161 | return 0; |
|
- | 162 | } |
|
- | 163 | ||
- | 164 | /** |
|
- | 165 | * radeon_irq_kms_fini - tear down driver interrrupt info |
|
- | 166 | * |
|
- | 167 | * @rdev: radeon device pointer |
|
- | 168 | * |
|
- | 169 | * Tears down the work irq handlers, vblank handlers, MSIs, etc. (all asics). |
|
- | 170 | */ |
|
- | 171 | void radeon_irq_kms_fini(struct radeon_device *rdev) |
|
- | 172 | { |
|
- | 173 | // drm_vblank_cleanup(rdev->ddev); |
|
- | 174 | if (rdev->irq.installed) { |
|
- | 175 | // drm_irq_uninstall(rdev->ddev); |
|
- | 176 | rdev->irq.installed = false; |
|
- | 177 | // if (rdev->msi_enabled) |
|
Line -... | Line 178... | ||
- | 178 | // pci_disable_msi(rdev->pdev); |
|
- | 179 | } |
|
- | 180 | // flush_work(&rdev->hotplug_work); |
|
- | 181 | } |
|
- | 182 | ||
- | 183 | /** |
|
- | 184 | * radeon_irq_kms_sw_irq_get - enable software interrupt |
|
- | 185 | * |
|
- | 186 | * @rdev: radeon device pointer |
|
- | 187 | * @ring: ring whose interrupt you want to enable |
|
116 | DRM_INFO("radeon: irq initialized.\n"); |
188 | * |
117 | return 0; |
189 | * Enables the software interrupt for a specific ring (all asics). |
118 | } |
190 | * The software interrupt is generally used to signal a fence on |
Line 119... | Line 191... | ||
119 | 191 | * a particular ring. |
|
- | 192 | */ |
|
- | 193 | void radeon_irq_kms_sw_irq_get(struct radeon_device *rdev, int ring) |
|
120 | 194 | { |
|
121 | void radeon_irq_kms_sw_irq_get(struct radeon_device *rdev) |
195 | unsigned long irqflags; |
122 | { |
196 | |
- | 197 | if (!rdev->ddev->irq_enabled) |
|
123 | unsigned long irqflags; |
198 | return; |
124 | - | ||
125 | spin_lock_irqsave(&rdev->irq.sw_lock, irqflags); |
199 | |
Line -... | Line 200... | ||
- | 200 | if (atomic_inc_return(&rdev->irq.ring_int[ring]) == 1) { |
|
- | 201 | spin_lock_irqsave(&rdev->irq.lock, irqflags); |
|
- | 202 | radeon_irq_set(rdev); |
|
- | 203 | spin_unlock_irqrestore(&rdev->irq.lock, irqflags); |
|
- | 204 | } |
|
- | 205 | } |
|
- | 206 | ||
- | 207 | /** |
|
- | 208 | * radeon_irq_kms_sw_irq_put - disable software interrupt |
|
- | 209 | * |
|
126 | if (rdev->ddev->irq_enabled && (++rdev->irq.sw_refcount == 1)) { |
210 | * @rdev: radeon device pointer |
127 | rdev->irq.sw_int = true; |
211 | * @ring: ring whose interrupt you want to disable |
128 | radeon_irq_set(rdev); |
212 | * |
Line 129... | Line 213... | ||
129 | } |
213 | * Disables the software interrupt for a specific ring (all asics). |
130 | spin_unlock_irqrestore(&rdev->irq.sw_lock, irqflags); |
214 | * The software interrupt is generally used to signal a fence on |
- | 215 | * a particular ring. |
|
131 | } |
216 | */ |
132 | 217 | void radeon_irq_kms_sw_irq_put(struct radeon_device *rdev, int ring) |
|
133 | void radeon_irq_kms_sw_irq_put(struct radeon_device *rdev) |
218 | { |
- | 219 | unsigned long irqflags; |
|
134 | { |
220 | |
135 | unsigned long irqflags; |
- | |
136 | 221 | if (!rdev->ddev->irq_enabled) |