diff options
author | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
---|---|---|
committer | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
commit | ada47b5fe13d89735805b566185f4885f5a3f750 (patch) | |
tree | 644b88f8a71896307d71438e9b3af49126ffb22b /drivers/gpu/drm/radeon/rs600.c | |
parent | 43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff) | |
parent | 3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff) |
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'drivers/gpu/drm/radeon/rs600.c')
-rw-r--r-- | drivers/gpu/drm/radeon/rs600.c | 285 |
1 files changed, 234 insertions, 51 deletions
diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index 5f117cd8736a..a81bc7a21e14 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c | |||
@@ -37,6 +37,7 @@ | |||
37 | */ | 37 | */ |
38 | #include "drmP.h" | 38 | #include "drmP.h" |
39 | #include "radeon.h" | 39 | #include "radeon.h" |
40 | #include "radeon_asic.h" | ||
40 | #include "atom.h" | 41 | #include "atom.h" |
41 | #include "rs600d.h" | 42 | #include "rs600d.h" |
42 | 43 | ||
@@ -45,6 +46,107 @@ | |||
45 | void rs600_gpu_init(struct radeon_device *rdev); | 46 | void rs600_gpu_init(struct radeon_device *rdev); |
46 | int rs600_mc_wait_for_idle(struct radeon_device *rdev); | 47 | int rs600_mc_wait_for_idle(struct radeon_device *rdev); |
47 | 48 | ||
49 | /* hpd for digital panel detect/disconnect */ | ||
50 | bool rs600_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd) | ||
51 | { | ||
52 | u32 tmp; | ||
53 | bool connected = false; | ||
54 | |||
55 | switch (hpd) { | ||
56 | case RADEON_HPD_1: | ||
57 | tmp = RREG32(R_007D04_DC_HOT_PLUG_DETECT1_INT_STATUS); | ||
58 | if (G_007D04_DC_HOT_PLUG_DETECT1_SENSE(tmp)) | ||
59 | connected = true; | ||
60 | break; | ||
61 | case RADEON_HPD_2: | ||
62 | tmp = RREG32(R_007D14_DC_HOT_PLUG_DETECT2_INT_STATUS); | ||
63 | if (G_007D14_DC_HOT_PLUG_DETECT2_SENSE(tmp)) | ||
64 | connected = true; | ||
65 | break; | ||
66 | default: | ||
67 | break; | ||
68 | } | ||
69 | return connected; | ||
70 | } | ||
71 | |||
72 | void rs600_hpd_set_polarity(struct radeon_device *rdev, | ||
73 | enum radeon_hpd_id hpd) | ||
74 | { | ||
75 | u32 tmp; | ||
76 | bool connected = rs600_hpd_sense(rdev, hpd); | ||
77 | |||
78 | switch (hpd) { | ||
79 | case RADEON_HPD_1: | ||
80 | tmp = RREG32(R_007D08_DC_HOT_PLUG_DETECT1_INT_CONTROL); | ||
81 | if (connected) | ||
82 | tmp &= ~S_007D08_DC_HOT_PLUG_DETECT1_INT_POLARITY(1); | ||
83 | else | ||
84 | tmp |= S_007D08_DC_HOT_PLUG_DETECT1_INT_POLARITY(1); | ||
85 | WREG32(R_007D08_DC_HOT_PLUG_DETECT1_INT_CONTROL, tmp); | ||
86 | break; | ||
87 | case RADEON_HPD_2: | ||
88 | tmp = RREG32(R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL); | ||
89 | if (connected) | ||
90 | tmp &= ~S_007D18_DC_HOT_PLUG_DETECT2_INT_POLARITY(1); | ||
91 | else | ||
92 | tmp |= S_007D18_DC_HOT_PLUG_DETECT2_INT_POLARITY(1); | ||
93 | WREG32(R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL, tmp); | ||
94 | break; | ||
95 | default: | ||
96 | break; | ||
97 | } | ||
98 | } | ||
99 | |||
100 | void rs600_hpd_init(struct radeon_device *rdev) | ||
101 | { | ||
102 | struct drm_device *dev = rdev->ddev; | ||
103 | struct drm_connector *connector; | ||
104 | |||
105 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | ||
106 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
107 | switch (radeon_connector->hpd.hpd) { | ||
108 | case RADEON_HPD_1: | ||
109 | WREG32(R_007D00_DC_HOT_PLUG_DETECT1_CONTROL, | ||
110 | S_007D00_DC_HOT_PLUG_DETECT1_EN(1)); | ||
111 | rdev->irq.hpd[0] = true; | ||
112 | break; | ||
113 | case RADEON_HPD_2: | ||
114 | WREG32(R_007D10_DC_HOT_PLUG_DETECT2_CONTROL, | ||
115 | S_007D10_DC_HOT_PLUG_DETECT2_EN(1)); | ||
116 | rdev->irq.hpd[1] = true; | ||
117 | break; | ||
118 | default: | ||
119 | break; | ||
120 | } | ||
121 | } | ||
122 | if (rdev->irq.installed) | ||
123 | rs600_irq_set(rdev); | ||
124 | } | ||
125 | |||
126 | void rs600_hpd_fini(struct radeon_device *rdev) | ||
127 | { | ||
128 | struct drm_device *dev = rdev->ddev; | ||
129 | struct drm_connector *connector; | ||
130 | |||
131 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | ||
132 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
133 | switch (radeon_connector->hpd.hpd) { | ||
134 | case RADEON_HPD_1: | ||
135 | WREG32(R_007D00_DC_HOT_PLUG_DETECT1_CONTROL, | ||
136 | S_007D00_DC_HOT_PLUG_DETECT1_EN(0)); | ||
137 | rdev->irq.hpd[0] = false; | ||
138 | break; | ||
139 | case RADEON_HPD_2: | ||
140 | WREG32(R_007D10_DC_HOT_PLUG_DETECT2_CONTROL, | ||
141 | S_007D10_DC_HOT_PLUG_DETECT2_EN(0)); | ||
142 | rdev->irq.hpd[1] = false; | ||
143 | break; | ||
144 | default: | ||
145 | break; | ||
146 | } | ||
147 | } | ||
148 | } | ||
149 | |||
48 | /* | 150 | /* |
49 | * GART. | 151 | * GART. |
50 | */ | 152 | */ |
@@ -57,7 +159,7 @@ void rs600_gart_tlb_flush(struct radeon_device *rdev) | |||
57 | WREG32_MC(R_000100_MC_PT0_CNTL, tmp); | 159 | WREG32_MC(R_000100_MC_PT0_CNTL, tmp); |
58 | 160 | ||
59 | tmp = RREG32_MC(R_000100_MC_PT0_CNTL); | 161 | tmp = RREG32_MC(R_000100_MC_PT0_CNTL); |
60 | tmp |= S_000100_INVALIDATE_ALL_L1_TLBS(1) & S_000100_INVALIDATE_L2_CACHE(1); | 162 | tmp |= S_000100_INVALIDATE_ALL_L1_TLBS(1) | S_000100_INVALIDATE_L2_CACHE(1); |
61 | WREG32_MC(R_000100_MC_PT0_CNTL, tmp); | 163 | WREG32_MC(R_000100_MC_PT0_CNTL, tmp); |
62 | 164 | ||
63 | tmp = RREG32_MC(R_000100_MC_PT0_CNTL); | 165 | tmp = RREG32_MC(R_000100_MC_PT0_CNTL); |
@@ -95,45 +197,46 @@ int rs600_gart_enable(struct radeon_device *rdev) | |||
95 | r = radeon_gart_table_vram_pin(rdev); | 197 | r = radeon_gart_table_vram_pin(rdev); |
96 | if (r) | 198 | if (r) |
97 | return r; | 199 | return r; |
200 | radeon_gart_restore(rdev); | ||
98 | /* Enable bus master */ | 201 | /* Enable bus master */ |
99 | tmp = RREG32(R_00004C_BUS_CNTL) & C_00004C_BUS_MASTER_DIS; | 202 | tmp = RREG32(R_00004C_BUS_CNTL) & C_00004C_BUS_MASTER_DIS; |
100 | WREG32(R_00004C_BUS_CNTL, tmp); | 203 | WREG32(R_00004C_BUS_CNTL, tmp); |
101 | /* FIXME: setup default page */ | 204 | /* FIXME: setup default page */ |
102 | WREG32_MC(R_000100_MC_PT0_CNTL, | 205 | WREG32_MC(R_000100_MC_PT0_CNTL, |
103 | (S_000100_EFFECTIVE_L2_CACHE_SIZE(6) | | 206 | (S_000100_EFFECTIVE_L2_CACHE_SIZE(6) | |
104 | S_000100_EFFECTIVE_L2_QUEUE_SIZE(6))); | 207 | S_000100_EFFECTIVE_L2_QUEUE_SIZE(6))); |
208 | |||
105 | for (i = 0; i < 19; i++) { | 209 | for (i = 0; i < 19; i++) { |
106 | WREG32_MC(R_00016C_MC_PT0_CLIENT0_CNTL + i, | 210 | WREG32_MC(R_00016C_MC_PT0_CLIENT0_CNTL + i, |
107 | S_00016C_ENABLE_TRANSLATION_MODE_OVERRIDE(1) | | 211 | S_00016C_ENABLE_TRANSLATION_MODE_OVERRIDE(1) | |
108 | S_00016C_SYSTEM_ACCESS_MODE_MASK( | 212 | S_00016C_SYSTEM_ACCESS_MODE_MASK( |
109 | V_00016C_SYSTEM_ACCESS_MODE_IN_SYS) | | 213 | V_00016C_SYSTEM_ACCESS_MODE_NOT_IN_SYS) | |
110 | S_00016C_SYSTEM_APERTURE_UNMAPPED_ACCESS( | 214 | S_00016C_SYSTEM_APERTURE_UNMAPPED_ACCESS( |
111 | V_00016C_SYSTEM_APERTURE_UNMAPPED_DEFAULT_PAGE) | | 215 | V_00016C_SYSTEM_APERTURE_UNMAPPED_PASSTHROUGH) | |
112 | S_00016C_EFFECTIVE_L1_CACHE_SIZE(1) | | 216 | S_00016C_EFFECTIVE_L1_CACHE_SIZE(3) | |
113 | S_00016C_ENABLE_FRAGMENT_PROCESSING(1) | | 217 | S_00016C_ENABLE_FRAGMENT_PROCESSING(1) | |
114 | S_00016C_EFFECTIVE_L1_QUEUE_SIZE(1)); | 218 | S_00016C_EFFECTIVE_L1_QUEUE_SIZE(3)); |
115 | } | 219 | } |
116 | |||
117 | /* System context map to GART space */ | ||
118 | WREG32_MC(R_000112_MC_PT0_SYSTEM_APERTURE_LOW_ADDR, rdev->mc.gtt_start); | ||
119 | WREG32_MC(R_000114_MC_PT0_SYSTEM_APERTURE_HIGH_ADDR, rdev->mc.gtt_end); | ||
120 | |||
121 | /* enable first context */ | 220 | /* enable first context */ |
122 | WREG32_MC(R_00013C_MC_PT0_CONTEXT0_FLAT_START_ADDR, rdev->mc.gtt_start); | ||
123 | WREG32_MC(R_00014C_MC_PT0_CONTEXT0_FLAT_END_ADDR, rdev->mc.gtt_end); | ||
124 | WREG32_MC(R_000102_MC_PT0_CONTEXT0_CNTL, | 221 | WREG32_MC(R_000102_MC_PT0_CONTEXT0_CNTL, |
125 | S_000102_ENABLE_PAGE_TABLE(1) | | 222 | S_000102_ENABLE_PAGE_TABLE(1) | |
126 | S_000102_PAGE_TABLE_DEPTH(V_000102_PAGE_TABLE_FLAT)); | 223 | S_000102_PAGE_TABLE_DEPTH(V_000102_PAGE_TABLE_FLAT)); |
224 | |||
127 | /* disable all other contexts */ | 225 | /* disable all other contexts */ |
128 | for (i = 1; i < 8; i++) { | 226 | for (i = 1; i < 8; i++) |
129 | WREG32_MC(R_000102_MC_PT0_CONTEXT0_CNTL + i, 0); | 227 | WREG32_MC(R_000102_MC_PT0_CONTEXT0_CNTL + i, 0); |
130 | } | ||
131 | 228 | ||
132 | /* setup the page table */ | 229 | /* setup the page table */ |
133 | WREG32_MC(R_00012C_MC_PT0_CONTEXT0_FLAT_BASE_ADDR, | 230 | WREG32_MC(R_00012C_MC_PT0_CONTEXT0_FLAT_BASE_ADDR, |
134 | rdev->gart.table_addr); | 231 | rdev->gart.table_addr); |
232 | WREG32_MC(R_00013C_MC_PT0_CONTEXT0_FLAT_START_ADDR, rdev->mc.gtt_start); | ||
233 | WREG32_MC(R_00014C_MC_PT0_CONTEXT0_FLAT_END_ADDR, rdev->mc.gtt_end); | ||
135 | WREG32_MC(R_00011C_MC_PT0_CONTEXT0_DEFAULT_READ_ADDR, 0); | 234 | WREG32_MC(R_00011C_MC_PT0_CONTEXT0_DEFAULT_READ_ADDR, 0); |
136 | 235 | ||
236 | /* System context maps to VRAM space */ | ||
237 | WREG32_MC(R_000112_MC_PT0_SYSTEM_APERTURE_LOW_ADDR, rdev->mc.vram_start); | ||
238 | WREG32_MC(R_000114_MC_PT0_SYSTEM_APERTURE_HIGH_ADDR, rdev->mc.vram_end); | ||
239 | |||
137 | /* enable page tables */ | 240 | /* enable page tables */ |
138 | tmp = RREG32_MC(R_000100_MC_PT0_CNTL); | 241 | tmp = RREG32_MC(R_000100_MC_PT0_CNTL); |
139 | WREG32_MC(R_000100_MC_PT0_CNTL, (tmp | S_000100_ENABLE_PT(1))); | 242 | WREG32_MC(R_000100_MC_PT0_CNTL, (tmp | S_000100_ENABLE_PT(1))); |
@@ -146,23 +249,28 @@ int rs600_gart_enable(struct radeon_device *rdev) | |||
146 | 249 | ||
147 | void rs600_gart_disable(struct radeon_device *rdev) | 250 | void rs600_gart_disable(struct radeon_device *rdev) |
148 | { | 251 | { |
149 | uint32_t tmp; | 252 | u32 tmp; |
253 | int r; | ||
150 | 254 | ||
151 | /* FIXME: disable out of gart access */ | 255 | /* FIXME: disable out of gart access */ |
152 | WREG32_MC(R_000100_MC_PT0_CNTL, 0); | 256 | WREG32_MC(R_000100_MC_PT0_CNTL, 0); |
153 | tmp = RREG32_MC(R_000009_MC_CNTL1); | 257 | tmp = RREG32_MC(R_000009_MC_CNTL1); |
154 | WREG32_MC(R_000009_MC_CNTL1, tmp & C_000009_ENABLE_PAGE_TABLES); | 258 | WREG32_MC(R_000009_MC_CNTL1, tmp & C_000009_ENABLE_PAGE_TABLES); |
155 | if (rdev->gart.table.vram.robj) { | 259 | if (rdev->gart.table.vram.robj) { |
156 | radeon_object_kunmap(rdev->gart.table.vram.robj); | 260 | r = radeon_bo_reserve(rdev->gart.table.vram.robj, false); |
157 | radeon_object_unpin(rdev->gart.table.vram.robj); | 261 | if (r == 0) { |
262 | radeon_bo_kunmap(rdev->gart.table.vram.robj); | ||
263 | radeon_bo_unpin(rdev->gart.table.vram.robj); | ||
264 | radeon_bo_unreserve(rdev->gart.table.vram.robj); | ||
265 | } | ||
158 | } | 266 | } |
159 | } | 267 | } |
160 | 268 | ||
161 | void rs600_gart_fini(struct radeon_device *rdev) | 269 | void rs600_gart_fini(struct radeon_device *rdev) |
162 | { | 270 | { |
271 | radeon_gart_fini(rdev); | ||
163 | rs600_gart_disable(rdev); | 272 | rs600_gart_disable(rdev); |
164 | radeon_gart_table_vram_free(rdev); | 273 | radeon_gart_table_vram_free(rdev); |
165 | radeon_gart_fini(rdev); | ||
166 | } | 274 | } |
167 | 275 | ||
168 | #define R600_PTE_VALID (1 << 0) | 276 | #define R600_PTE_VALID (1 << 0) |
@@ -189,7 +297,16 @@ int rs600_irq_set(struct radeon_device *rdev) | |||
189 | { | 297 | { |
190 | uint32_t tmp = 0; | 298 | uint32_t tmp = 0; |
191 | uint32_t mode_int = 0; | 299 | uint32_t mode_int = 0; |
192 | 300 | u32 hpd1 = RREG32(R_007D08_DC_HOT_PLUG_DETECT1_INT_CONTROL) & | |
301 | ~S_007D08_DC_HOT_PLUG_DETECT1_INT_EN(1); | ||
302 | u32 hpd2 = RREG32(R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL) & | ||
303 | ~S_007D18_DC_HOT_PLUG_DETECT2_INT_EN(1); | ||
304 | |||
305 | if (!rdev->irq.installed) { | ||
306 | WARN(1, "Can't enable IRQ/MSI because no handler is installed.\n"); | ||
307 | WREG32(R_000040_GEN_INT_CNTL, 0); | ||
308 | return -EINVAL; | ||
309 | } | ||
193 | if (rdev->irq.sw_int) { | 310 | if (rdev->irq.sw_int) { |
194 | tmp |= S_000040_SW_INT_EN(1); | 311 | tmp |= S_000040_SW_INT_EN(1); |
195 | } | 312 | } |
@@ -199,8 +316,16 @@ int rs600_irq_set(struct radeon_device *rdev) | |||
199 | if (rdev->irq.crtc_vblank_int[1]) { | 316 | if (rdev->irq.crtc_vblank_int[1]) { |
200 | mode_int |= S_006540_D2MODE_VBLANK_INT_MASK(1); | 317 | mode_int |= S_006540_D2MODE_VBLANK_INT_MASK(1); |
201 | } | 318 | } |
319 | if (rdev->irq.hpd[0]) { | ||
320 | hpd1 |= S_007D08_DC_HOT_PLUG_DETECT1_INT_EN(1); | ||
321 | } | ||
322 | if (rdev->irq.hpd[1]) { | ||
323 | hpd2 |= S_007D18_DC_HOT_PLUG_DETECT2_INT_EN(1); | ||
324 | } | ||
202 | WREG32(R_000040_GEN_INT_CNTL, tmp); | 325 | WREG32(R_000040_GEN_INT_CNTL, tmp); |
203 | WREG32(R_006540_DxMODE_INT_MASK, mode_int); | 326 | WREG32(R_006540_DxMODE_INT_MASK, mode_int); |
327 | WREG32(R_007D08_DC_HOT_PLUG_DETECT1_INT_CONTROL, hpd1); | ||
328 | WREG32(R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL, hpd2); | ||
204 | return 0; | 329 | return 0; |
205 | } | 330 | } |
206 | 331 | ||
@@ -208,6 +333,7 @@ static inline uint32_t rs600_irq_ack(struct radeon_device *rdev, u32 *r500_disp_ | |||
208 | { | 333 | { |
209 | uint32_t irqs = RREG32(R_000044_GEN_INT_STATUS); | 334 | uint32_t irqs = RREG32(R_000044_GEN_INT_STATUS); |
210 | uint32_t irq_mask = ~C_000044_SW_INT; | 335 | uint32_t irq_mask = ~C_000044_SW_INT; |
336 | u32 tmp; | ||
211 | 337 | ||
212 | if (G_000044_DISPLAY_INT_STAT(irqs)) { | 338 | if (G_000044_DISPLAY_INT_STAT(irqs)) { |
213 | *r500_disp_int = RREG32(R_007EDC_DISP_INTERRUPT_STATUS); | 339 | *r500_disp_int = RREG32(R_007EDC_DISP_INTERRUPT_STATUS); |
@@ -219,6 +345,16 @@ static inline uint32_t rs600_irq_ack(struct radeon_device *rdev, u32 *r500_disp_ | |||
219 | WREG32(R_006D34_D2MODE_VBLANK_STATUS, | 345 | WREG32(R_006D34_D2MODE_VBLANK_STATUS, |
220 | S_006D34_D2MODE_VBLANK_ACK(1)); | 346 | S_006D34_D2MODE_VBLANK_ACK(1)); |
221 | } | 347 | } |
348 | if (G_007EDC_DC_HOT_PLUG_DETECT1_INTERRUPT(*r500_disp_int)) { | ||
349 | tmp = RREG32(R_007D08_DC_HOT_PLUG_DETECT1_INT_CONTROL); | ||
350 | tmp |= S_007D08_DC_HOT_PLUG_DETECT1_INT_ACK(1); | ||
351 | WREG32(R_007D08_DC_HOT_PLUG_DETECT1_INT_CONTROL, tmp); | ||
352 | } | ||
353 | if (G_007EDC_DC_HOT_PLUG_DETECT2_INTERRUPT(*r500_disp_int)) { | ||
354 | tmp = RREG32(R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL); | ||
355 | tmp |= S_007D18_DC_HOT_PLUG_DETECT2_INT_ACK(1); | ||
356 | WREG32(R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL, tmp); | ||
357 | } | ||
222 | } else { | 358 | } else { |
223 | *r500_disp_int = 0; | 359 | *r500_disp_int = 0; |
224 | } | 360 | } |
@@ -244,6 +380,7 @@ int rs600_irq_process(struct radeon_device *rdev) | |||
244 | { | 380 | { |
245 | uint32_t status, msi_rearm; | 381 | uint32_t status, msi_rearm; |
246 | uint32_t r500_disp_int; | 382 | uint32_t r500_disp_int; |
383 | bool queue_hotplug = false; | ||
247 | 384 | ||
248 | status = rs600_irq_ack(rdev, &r500_disp_int); | 385 | status = rs600_irq_ack(rdev, &r500_disp_int); |
249 | if (!status && !r500_disp_int) { | 386 | if (!status && !r500_disp_int) { |
@@ -251,15 +388,31 @@ int rs600_irq_process(struct radeon_device *rdev) | |||
251 | } | 388 | } |
252 | while (status || r500_disp_int) { | 389 | while (status || r500_disp_int) { |
253 | /* SW interrupt */ | 390 | /* SW interrupt */ |
254 | if (G_000040_SW_INT_EN(status)) | 391 | if (G_000044_SW_INT(status)) |
255 | radeon_fence_process(rdev); | 392 | radeon_fence_process(rdev); |
256 | /* Vertical blank interrupts */ | 393 | /* Vertical blank interrupts */ |
257 | if (G_007EDC_LB_D1_VBLANK_INTERRUPT(r500_disp_int)) | 394 | if (G_007EDC_LB_D1_VBLANK_INTERRUPT(r500_disp_int)) { |
258 | drm_handle_vblank(rdev->ddev, 0); | 395 | drm_handle_vblank(rdev->ddev, 0); |
259 | if (G_007EDC_LB_D2_VBLANK_INTERRUPT(r500_disp_int)) | 396 | rdev->pm.vblank_sync = true; |
397 | wake_up(&rdev->irq.vblank_queue); | ||
398 | } | ||
399 | if (G_007EDC_LB_D2_VBLANK_INTERRUPT(r500_disp_int)) { | ||
260 | drm_handle_vblank(rdev->ddev, 1); | 400 | drm_handle_vblank(rdev->ddev, 1); |
401 | rdev->pm.vblank_sync = true; | ||
402 | wake_up(&rdev->irq.vblank_queue); | ||
403 | } | ||
404 | if (G_007EDC_DC_HOT_PLUG_DETECT1_INTERRUPT(r500_disp_int)) { | ||
405 | queue_hotplug = true; | ||
406 | DRM_DEBUG("HPD1\n"); | ||
407 | } | ||
408 | if (G_007EDC_DC_HOT_PLUG_DETECT2_INTERRUPT(r500_disp_int)) { | ||
409 | queue_hotplug = true; | ||
410 | DRM_DEBUG("HPD2\n"); | ||
411 | } | ||
261 | status = rs600_irq_ack(rdev, &r500_disp_int); | 412 | status = rs600_irq_ack(rdev, &r500_disp_int); |
262 | } | 413 | } |
414 | if (queue_hotplug) | ||
415 | queue_work(rdev->wq, &rdev->hotplug_work); | ||
263 | if (rdev->msi_enabled) { | 416 | if (rdev->msi_enabled) { |
264 | switch (rdev->family) { | 417 | switch (rdev->family) { |
265 | case CHIP_RS600: | 418 | case CHIP_RS600: |
@@ -301,25 +454,59 @@ int rs600_mc_wait_for_idle(struct radeon_device *rdev) | |||
301 | 454 | ||
302 | void rs600_gpu_init(struct radeon_device *rdev) | 455 | void rs600_gpu_init(struct radeon_device *rdev) |
303 | { | 456 | { |
304 | /* FIXME: HDP same place on rs600 ? */ | ||
305 | r100_hdp_reset(rdev); | 457 | r100_hdp_reset(rdev); |
306 | /* FIXME: is this correct ? */ | ||
307 | r420_pipes_init(rdev); | 458 | r420_pipes_init(rdev); |
308 | /* Wait for mc idle */ | 459 | /* Wait for mc idle */ |
309 | if (rs600_mc_wait_for_idle(rdev)) | 460 | if (rs600_mc_wait_for_idle(rdev)) |
310 | dev_warn(rdev->dev, "Wait MC idle timeout before updating MC.\n"); | 461 | dev_warn(rdev->dev, "Wait MC idle timeout before updating MC.\n"); |
311 | } | 462 | } |
312 | 463 | ||
313 | void rs600_vram_info(struct radeon_device *rdev) | 464 | void rs600_mc_init(struct radeon_device *rdev) |
314 | { | 465 | { |
315 | /* FIXME: to do or is these values sane ? */ | 466 | u64 base; |
467 | |||
468 | rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0); | ||
469 | rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0); | ||
316 | rdev->mc.vram_is_ddr = true; | 470 | rdev->mc.vram_is_ddr = true; |
317 | rdev->mc.vram_width = 128; | 471 | rdev->mc.vram_width = 128; |
472 | rdev->mc.real_vram_size = RREG32(RADEON_CONFIG_MEMSIZE); | ||
473 | rdev->mc.mc_vram_size = rdev->mc.real_vram_size; | ||
474 | rdev->mc.visible_vram_size = rdev->mc.aper_size; | ||
475 | rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev); | ||
476 | base = RREG32_MC(R_000004_MC_FB_LOCATION); | ||
477 | base = G_000004_MC_FB_START(base) << 16; | ||
478 | rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev); | ||
479 | radeon_vram_location(rdev, &rdev->mc, base); | ||
480 | radeon_gtt_location(rdev, &rdev->mc); | ||
481 | radeon_update_bandwidth_info(rdev); | ||
318 | } | 482 | } |
319 | 483 | ||
320 | void rs600_bandwidth_update(struct radeon_device *rdev) | 484 | void rs600_bandwidth_update(struct radeon_device *rdev) |
321 | { | 485 | { |
322 | /* FIXME: implement, should this be like rs690 ? */ | 486 | struct drm_display_mode *mode0 = NULL; |
487 | struct drm_display_mode *mode1 = NULL; | ||
488 | u32 d1mode_priority_a_cnt, d2mode_priority_a_cnt; | ||
489 | /* FIXME: implement full support */ | ||
490 | |||
491 | radeon_update_display_priority(rdev); | ||
492 | |||
493 | if (rdev->mode_info.crtcs[0]->base.enabled) | ||
494 | mode0 = &rdev->mode_info.crtcs[0]->base.mode; | ||
495 | if (rdev->mode_info.crtcs[1]->base.enabled) | ||
496 | mode1 = &rdev->mode_info.crtcs[1]->base.mode; | ||
497 | |||
498 | rs690_line_buffer_adjust(rdev, mode0, mode1); | ||
499 | |||
500 | if (rdev->disp_priority == 2) { | ||
501 | d1mode_priority_a_cnt = RREG32(R_006548_D1MODE_PRIORITY_A_CNT); | ||
502 | d2mode_priority_a_cnt = RREG32(R_006D48_D2MODE_PRIORITY_A_CNT); | ||
503 | d1mode_priority_a_cnt |= S_006548_D1MODE_PRIORITY_A_ALWAYS_ON(1); | ||
504 | d2mode_priority_a_cnt |= S_006D48_D2MODE_PRIORITY_A_ALWAYS_ON(1); | ||
505 | WREG32(R_006548_D1MODE_PRIORITY_A_CNT, d1mode_priority_a_cnt); | ||
506 | WREG32(R_00654C_D1MODE_PRIORITY_B_CNT, d1mode_priority_a_cnt); | ||
507 | WREG32(R_006D48_D2MODE_PRIORITY_A_CNT, d2mode_priority_a_cnt); | ||
508 | WREG32(R_006D4C_D2MODE_PRIORITY_B_CNT, d2mode_priority_a_cnt); | ||
509 | } | ||
323 | } | 510 | } |
324 | 511 | ||
325 | uint32_t rs600_mc_rreg(struct radeon_device *rdev, uint32_t reg) | 512 | uint32_t rs600_mc_rreg(struct radeon_device *rdev, uint32_t reg) |
@@ -388,8 +575,8 @@ static int rs600_startup(struct radeon_device *rdev) | |||
388 | if (r) | 575 | if (r) |
389 | return r; | 576 | return r; |
390 | /* Enable IRQ */ | 577 | /* Enable IRQ */ |
391 | rdev->irq.sw_int = true; | ||
392 | rs600_irq_set(rdev); | 578 | rs600_irq_set(rdev); |
579 | rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL); | ||
393 | /* 1M ring buffer */ | 580 | /* 1M ring buffer */ |
394 | r = r100_cp_init(rdev, 1024 * 1024); | 581 | r = r100_cp_init(rdev, 1024 * 1024); |
395 | if (r) { | 582 | if (r) { |
@@ -423,6 +610,8 @@ int rs600_resume(struct radeon_device *rdev) | |||
423 | atom_asic_init(rdev->mode_info.atom_context); | 610 | atom_asic_init(rdev->mode_info.atom_context); |
424 | /* Resume clock after posting */ | 611 | /* Resume clock after posting */ |
425 | rv515_clock_startup(rdev); | 612 | rv515_clock_startup(rdev); |
613 | /* Initialize surface registers */ | ||
614 | radeon_surface_init(rdev); | ||
426 | return rs600_startup(rdev); | 615 | return rs600_startup(rdev); |
427 | } | 616 | } |
428 | 617 | ||
@@ -437,7 +626,7 @@ int rs600_suspend(struct radeon_device *rdev) | |||
437 | 626 | ||
438 | void rs600_fini(struct radeon_device *rdev) | 627 | void rs600_fini(struct radeon_device *rdev) |
439 | { | 628 | { |
440 | rs600_suspend(rdev); | 629 | radeon_pm_fini(rdev); |
441 | r100_cp_fini(rdev); | 630 | r100_cp_fini(rdev); |
442 | r100_wb_fini(rdev); | 631 | r100_wb_fini(rdev); |
443 | r100_ib_fini(rdev); | 632 | r100_ib_fini(rdev); |
@@ -445,7 +634,7 @@ void rs600_fini(struct radeon_device *rdev) | |||
445 | rs600_gart_fini(rdev); | 634 | rs600_gart_fini(rdev); |
446 | radeon_irq_kms_fini(rdev); | 635 | radeon_irq_kms_fini(rdev); |
447 | radeon_fence_driver_fini(rdev); | 636 | radeon_fence_driver_fini(rdev); |
448 | radeon_object_fini(rdev); | 637 | radeon_bo_fini(rdev); |
449 | radeon_atombios_fini(rdev); | 638 | radeon_atombios_fini(rdev); |
450 | kfree(rdev->bios); | 639 | kfree(rdev->bios); |
451 | rdev->bios = NULL; | 640 | rdev->bios = NULL; |
@@ -482,20 +671,15 @@ int rs600_init(struct radeon_device *rdev) | |||
482 | RREG32(R_0007C0_CP_STAT)); | 671 | RREG32(R_0007C0_CP_STAT)); |
483 | } | 672 | } |
484 | /* check if cards are posted or not */ | 673 | /* check if cards are posted or not */ |
485 | if (!radeon_card_posted(rdev) && rdev->bios) { | 674 | if (radeon_boot_test_post_card(rdev) == false) |
486 | DRM_INFO("GPU not posted. posting now...\n"); | 675 | return -EINVAL; |
487 | atom_asic_init(rdev->mode_info.atom_context); | 676 | |
488 | } | ||
489 | /* Initialize clocks */ | 677 | /* Initialize clocks */ |
490 | radeon_get_clock_info(rdev->ddev); | 678 | radeon_get_clock_info(rdev->ddev); |
491 | /* Initialize power management */ | 679 | /* Initialize power management */ |
492 | radeon_pm_init(rdev); | 680 | radeon_pm_init(rdev); |
493 | /* Get vram informations */ | 681 | /* initialize memory controller */ |
494 | rs600_vram_info(rdev); | 682 | rs600_mc_init(rdev); |
495 | /* Initialize memory controller (also test AGP) */ | ||
496 | r = r420_mc_init(rdev); | ||
497 | if (r) | ||
498 | return r; | ||
499 | rs600_debugfs(rdev); | 683 | rs600_debugfs(rdev); |
500 | /* Fence driver */ | 684 | /* Fence driver */ |
501 | r = radeon_fence_driver_init(rdev); | 685 | r = radeon_fence_driver_init(rdev); |
@@ -505,7 +689,7 @@ int rs600_init(struct radeon_device *rdev) | |||
505 | if (r) | 689 | if (r) |
506 | return r; | 690 | return r; |
507 | /* Memory manager */ | 691 | /* Memory manager */ |
508 | r = radeon_object_init(rdev); | 692 | r = radeon_bo_init(rdev); |
509 | if (r) | 693 | if (r) |
510 | return r; | 694 | return r; |
511 | r = rs600_gart_init(rdev); | 695 | r = rs600_gart_init(rdev); |
@@ -517,7 +701,6 @@ int rs600_init(struct radeon_device *rdev) | |||
517 | if (r) { | 701 | if (r) { |
518 | /* Somethings want wront with the accel init stop accel */ | 702 | /* Somethings want wront with the accel init stop accel */ |
519 | dev_err(rdev->dev, "Disabling GPU acceleration\n"); | 703 | dev_err(rdev->dev, "Disabling GPU acceleration\n"); |
520 | rs600_suspend(rdev); | ||
521 | r100_cp_fini(rdev); | 704 | r100_cp_fini(rdev); |
522 | r100_wb_fini(rdev); | 705 | r100_wb_fini(rdev); |
523 | r100_ib_fini(rdev); | 706 | r100_ib_fini(rdev); |