Rev 881 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
808 | serge | 1 | |
2 | |||
881 | serge | 3 | rhdPtr->MMIOMapSize = 1 << rhdPtr->memsize[RHD_MMIO_BAR]; |
808 | serge | 4 | rhdPtr->MMIOBase = MapIoMem((void*)rhdPtr->memBase[RHD_MMIO_BAR], |
881 | serge | 5 | rhdPtr->MMIOMapSize,PG_SW+PG_NOCACHE); |
6 | if( rhdPtr->MMIOBase==0) |
||
7 | return 0; |
||
8 | |||
9 | DBG(dbgprintf("Mapped IO at %x (size %x)\n", rhdPtr->MMIOBase, rhdPtr->MMIOMapSize)); |
||
808 | serge | 10 | |
881 | serge | 11 | } |
12 | |||
808 | serge | 13 | /* Read MC register */ |
14 | |||
881 | serge | 15 | { |
16 | u32_t data; |
||
17 | |||
18 | if ((info->ChipFamily == CHIP_FAMILY_RS690) || |
||
19 | |||
20 | OUTREG(RS690_MC_INDEX, (addr & RS690_MC_INDEX_MASK)); |
||
21 | data = INREG(RS690_MC_DATA); |
||
22 | } else if (info->ChipFamily == CHIP_FAMILY_RS600) { |
||
23 | OUTREG(RS600_MC_INDEX, (addr & RS600_MC_INDEX_MASK)); |
||
24 | data = INREG(RS600_MC_DATA); |
||
25 | } else if (IS_AVIVO_VARIANT) { |
||
26 | OUTREG(AVIVO_MC_INDEX, (addr & 0xff) | 0x7f0000); |
||
27 | (void)INREG(AVIVO_MC_INDEX); |
||
28 | data = INREG(AVIVO_MC_DATA); |
||
29 | |||
30 | OUTREG(AVIVO_MC_INDEX, 0); |
||
31 | |||
32 | } else { |
||
33 | OUTREG(R300_MC_IND_INDEX, addr & 0x3f); |
||
34 | (void)INREG(R300_MC_IND_INDEX); |
||
35 | data = INREG(R300_MC_IND_DATA); |
||
36 | |||
37 | OUTREG(R300_MC_IND_INDEX, 0); |
||
38 | |||
39 | } |
||
40 | |||
41 | return data; |
||
42 | |||
43 | |||
44 | /* Write MC information */ |
||
45 | |||
883 | serge | 46 | { |
47 | if ((info->ChipFamily == CHIP_FAMILY_RS690) || |
||
48 | (info->ChipFamily == CHIP_FAMILY_RS740)) { |
||
49 | OUTREG(RS690_MC_INDEX, ((addr & RS690_MC_INDEX_MASK) | RS690_MC_INDEX_WR_EN)); |
||
50 | OUTREG(RS690_MC_DATA, data); |
||
51 | OUTREG(RS690_MC_INDEX, RS690_MC_INDEX_WR_ACK); |
||
52 | } |
||
53 | else if (info->ChipFamily == CHIP_FAMILY_RS600) { |
||
54 | OUTREG(RS600_MC_INDEX, ((addr & RS600_MC_INDEX_MASK) | RS600_MC_INDEX_WR_EN)); |
||
55 | OUTREG(RS600_MC_DATA, data); |
||
56 | OUTREG(RS600_MC_INDEX, RS600_MC_INDEX_WR_ACK); |
||
57 | } |
||
58 | else if (IS_AVIVO_VARIANT) { |
||
59 | OUTREG(AVIVO_MC_INDEX, (addr & 0xff) | 0xff0000); |
||
60 | (void)INREG(AVIVO_MC_INDEX); |
||
61 | OUTREG(AVIVO_MC_DATA, data); |
||
62 | OUTREG(AVIVO_MC_INDEX, 0); |
||
63 | (void)INREG(AVIVO_MC_INDEX); |
||
64 | } |
||
65 | else { |
||
66 | OUTREG(R300_MC_IND_INDEX, (((addr) & 0x3f) | R300_MC_IND_WR_EN)); |
||
67 | (void)INREG(R300_MC_IND_INDEX); |
||
68 | OUTREG(R300_MC_IND_DATA, data); |
||
69 | OUTREG(R300_MC_IND_INDEX, 0); |
||
70 | (void)INREG(R300_MC_IND_INDEX); |
||
71 | } |
||
72 | } |
||
73 | |||
74 | static Bool avivo_get_mc_idle(RHDPtr info) |
||
881 | serge | 75 | |
883 | serge | 76 | |
77 | if (info->ChipFamily >= CHIP_FAMILY_R600) { |
||
78 | |||
79 | return TRUE; |
||
80 | } |
||
81 | else if (info->ChipFamily == CHIP_FAMILY_RV515) { |
||
82 | if (INMC(info, RV515_MC_STATUS) & RV515_MC_STATUS_IDLE) |
||
83 | return TRUE; |
||
84 | else |
||
85 | return FALSE; |
||
86 | } |
||
87 | else if (info->ChipFamily == CHIP_FAMILY_RS600) |
||
88 | { |
||
89 | if (INMC(info, RS600_MC_STATUS) & RS600_MC_STATUS_IDLE) |
||
90 | return TRUE; |
||
91 | else |
||
92 | return FALSE; |
||
93 | } |
||
94 | else if ((info->ChipFamily == CHIP_FAMILY_RS690) || |
||
95 | (info->ChipFamily == CHIP_FAMILY_RS740)) { |
||
96 | if (INMC(info, RS690_MC_STATUS) & RS690_MC_STATUS_IDLE) |
||
97 | return TRUE; |
||
98 | else |
||
99 | return FALSE; |
||
100 | } |
||
101 | else { |
||
102 | if (INMC(info, R520_MC_STATUS) & R520_MC_STATUS_IDLE) |
||
103 | return TRUE; |
||
104 | else |
||
105 | return FALSE; |
||
106 | } |
||
107 | } |
||
108 | |||
109 | #define LOC_FB 0x1 |
||
110 | |||
881 | serge | 111 | |
112 | static void radeon_read_mc_fb_agp_location(RHDPtr info, int mask, |
||
113 | |||
114 | { |
||
115 | |||
116 | if (info->ChipFamily >= CHIP_FAMILY_RV770) { |
||
117 | |||
118 | *fb_loc = INREG(R700_MC_VM_FB_LOCATION); |
||
119 | if (mask & LOC_AGP) { |
||
120 | *agp_loc = INREG(R600_MC_VM_AGP_BOT); |
||
121 | *agp_loc_hi = INREG(R600_MC_VM_AGP_TOP); |
||
122 | } |
||
123 | } else if (info->ChipFamily >= CHIP_FAMILY_R600) { |
||
124 | if (mask & LOC_FB) |
||
125 | *fb_loc = INREG(R600_MC_VM_FB_LOCATION); |
||
126 | if (mask & LOC_AGP) { |
||
127 | *agp_loc = INREG(R600_MC_VM_AGP_BOT); |
||
128 | *agp_loc_hi = INREG(R600_MC_VM_AGP_TOP); |
||
129 | } |
||
130 | } else if (info->ChipFamily == CHIP_FAMILY_RV515) { |
||
131 | if (mask & LOC_FB) |
||
132 | *fb_loc = INMC(info, RV515_MC_FB_LOCATION); |
||
133 | if (mask & LOC_AGP) { |
||
134 | *agp_loc = INMC(info, RV515_MC_AGP_LOCATION); |
||
135 | *agp_loc_hi = 0; |
||
136 | } |
||
137 | } else if (info->ChipFamily == CHIP_FAMILY_RS600) { |
||
138 | if (mask & LOC_FB) |
||
139 | *fb_loc = INMC(info, RS600_MC_FB_LOCATION); |
||
140 | if (mask & LOC_AGP) { |
||
141 | *agp_loc = 0;//INMC(pScrn, RS600_MC_AGP_LOCATION); |
||
142 | *agp_loc_hi = 0; |
||
143 | } |
||
144 | } else if ((info->ChipFamily == CHIP_FAMILY_RS690) || |
||
145 | (info->ChipFamily == CHIP_FAMILY_RS740)) { |
||
146 | if (mask & LOC_FB) |
||
147 | *fb_loc = INMC(info, RS690_MC_FB_LOCATION); |
||
148 | if (mask & LOC_AGP) { |
||
149 | *agp_loc = INMC(info, RS690_MC_AGP_LOCATION); |
||
150 | *agp_loc_hi = 0; |
||
151 | } |
||
152 | } else if (info->ChipFamily >= CHIP_FAMILY_R520) { |
||
153 | if (mask & LOC_FB) |
||
154 | *fb_loc = INMC(info, R520_MC_FB_LOCATION); |
||
155 | if (mask & LOC_AGP) { |
||
156 | *agp_loc = INMC(info, R520_MC_AGP_LOCATION); |
||
157 | *agp_loc_hi = 0; |
||
158 | } |
||
159 | } else { |
||
160 | if (mask & LOC_FB) |
||
161 | *fb_loc = INREG(RADEON_MC_FB_LOCATION); |
||
162 | if (mask & LOC_AGP) |
||
163 | *agp_loc = INREG(RADEON_MC_AGP_LOCATION); |
||
164 | } |
||
165 | } |
||
166 | |||
167 | static void radeon_write_mc_fb_agp_location(RHDPtr info, int mask, u32_t fb_loc, |
||
168 | |||
883 | serge | 169 | { |
170 | |||
171 | if (info->ChipFamily >= CHIP_FAMILY_RV770) { |
||
172 | |||
173 | OUTREG(R700_MC_VM_FB_LOCATION, fb_loc); |
||
174 | if (mask & LOC_AGP) { |
||
175 | OUTREG(R600_MC_VM_AGP_BOT, agp_loc); |
||
176 | OUTREG(R600_MC_VM_AGP_TOP, agp_loc_hi); |
||
177 | } |
||
178 | } |
||
179 | else if (info->ChipFamily >= CHIP_FAMILY_R600) |
||
180 | { |
||
181 | if (mask & LOC_FB) |
||
182 | OUTREG(R600_MC_VM_FB_LOCATION, fb_loc); |
||
183 | if (mask & LOC_AGP) { |
||
184 | OUTREG(R600_MC_VM_AGP_BOT, agp_loc); |
||
185 | OUTREG(R600_MC_VM_AGP_TOP, agp_loc_hi); |
||
186 | } |
||
187 | } |
||
188 | else if (info->ChipFamily == CHIP_FAMILY_RV515) |
||
189 | { |
||
190 | if (mask & LOC_FB) |
||
191 | OUTMC(info, RV515_MC_FB_LOCATION, fb_loc); |
||
192 | if (mask & LOC_AGP) |
||
193 | OUTMC(info, RV515_MC_AGP_LOCATION, agp_loc); |
||
194 | (void)INMC(info, RV515_MC_AGP_LOCATION); |
||
195 | } |
||
196 | else if (info->ChipFamily == CHIP_FAMILY_RS600) |
||
197 | { |
||
198 | if (mask & LOC_FB) |
||
199 | OUTMC(info, RS600_MC_FB_LOCATION, fb_loc); |
||
200 | /* if (mask & LOC_AGP) |
||
201 | OUTMC(pScrn, RS600_MC_AGP_LOCATION, agp_loc);*/ |
||
202 | } |
||
203 | else if ((info->ChipFamily == CHIP_FAMILY_RS690) || |
||
204 | (info->ChipFamily == CHIP_FAMILY_RS740)) |
||
205 | { |
||
206 | if (mask & LOC_FB) |
||
207 | OUTMC(info, RS690_MC_FB_LOCATION, fb_loc); |
||
208 | if (mask & LOC_AGP) |
||
209 | OUTMC(info, RS690_MC_AGP_LOCATION, agp_loc); |
||
210 | } |
||
211 | else if (info->ChipFamily >= CHIP_FAMILY_R520) |
||
212 | { |
||
213 | if (mask & LOC_FB) |
||
214 | OUTMC(info, R520_MC_FB_LOCATION, fb_loc); |
||
215 | if (mask & LOC_AGP) |
||
216 | OUTMC(info, R520_MC_AGP_LOCATION, agp_loc); |
||
217 | (void)INMC(info, R520_MC_FB_LOCATION); |
||
218 | } |
||
219 | else { |
||
220 | if (mask & LOC_FB) |
||
221 | OUTREG(RADEON_MC_FB_LOCATION, fb_loc); |
||
222 | if (mask & LOC_AGP) |
||
223 | OUTREG(RADEON_MC_AGP_LOCATION, agp_loc); |
||
224 | } |
||
225 | } |
||
226 | |||
227 | |||
228 | |||
229 | |||
230 | u32_t timeout; |
||
231 | |||
232 | u32_t mc_fb_loc, mc_agp_loc, mc_agp_loc_hi; |
||
233 | |||
234 | radeon_read_mc_fb_agp_location(info, LOC_FB | LOC_AGP, &mc_fb_loc, |
||
235 | |||
236 | |||
237 | if (IS_AVIVO_VARIANT) |
||
238 | |||
239 | |||
240 | if (mc_fb_loc != info->mc_fb_location || |
||
241 | |||
242 | { |
||
243 | u32_t d1crtc, d2crtc; |
||
244 | u32_t tmp; |
||
245 | // RADEONWaitForIdleMMIO(pScrn); |
||
246 | |||
247 | OUTREG(AVIVO_D1VGA_CONTROL, INREG(AVIVO_D1VGA_CONTROL) & ~AVIVO_DVGA_CONTROL_MODE_ENABLE); |
||
248 | |||
249 | |||
250 | /* Stop display & memory access */ |
||
251 | |||
252 | OUTREG(AVIVO_D1CRTC_CONTROL, d1crtc & ~AVIVO_CRTC_EN); |
||
253 | |||
254 | d2crtc = INREG(AVIVO_D2CRTC_CONTROL); |
||
255 | |||
256 | |||
257 | tmp = INREG(AVIVO_D2CRTC_CONTROL); |
||
258 | |||
259 | usleep(10000); |
||
260 | |||
261 | while (!(avivo_get_mc_idle(info))) |
||
262 | { |
||
263 | if (++timeout > 1000000) |
||
264 | { |
||
265 | dbgprintf("Timeout trying to update memory controller settings !\n"); |
||
266 | dbgprintf("You will probably crash now ... \n"); |
||
267 | /* Nothing we can do except maybe try to kill the server, |
||
268 | * let's wait 2 seconds to leave the above message a chance |
||
269 | * to maybe hit the disk and continue trying to setup despite |
||
270 | * the MC being non-idle |
||
271 | */ |
||
272 | usleep(2000000); |
||
273 | } |
||
274 | usleep(10); |
||
275 | } |
||
276 | |||
277 | radeon_write_mc_fb_agp_location(info, LOC_FB | LOC_AGP, |
||
278 | |||
279 | info->mc_agp_location, |
||
280 | info->mc_agp_location_hi); |
||
281 | |||
282 | if (info->ChipFamily < CHIP_FAMILY_R600) { |
||
283 | |||
284 | } |
||
285 | else { |
||
286 | OUTREG(R600_HDP_NONSURFACE_BASE, (info->mc_fb_location << 16) & 0xff0000); |
||
287 | } |
||
288 | |||
289 | OUTREG(AVIVO_D1CRTC_CONTROL, d1crtc ); |
||
290 | |||
291 | OUTREG(AVIVO_D2CRTC_CONTROL, d2crtc ); |
||
292 | |||
293 | tmp = INREG(AVIVO_D2CRTC_CONTROL); |
||
294 | |||
295 | /* Reset the engine and HDP */ |
||
296 | |||
297 | } |
||
298 | } |
||
299 | else |
||
300 | { |
||
301 | |||
302 | /* Write memory mapping registers only if their value change |
||
303 | |||
304 | * reprogrammed |
||
305 | */ |
||
306 | if ( mc_fb_loc != info->mc_fb_location || |
||
307 | mc_agp_loc != info->mc_agp_location) |
||
308 | { |
||
309 | u32_t crtc_ext_cntl, crtc_gen_cntl, crtc2_gen_cntl=0, ov0_scale_cntl; |
||
310 | u32_t old_mc_status, status_idle; |
||
311 | |||
312 | dbgprintf(" Map Changed ! Applying ...\n"); |
||
313 | |||
314 | /* Make sure engine is idle. We assume the CCE is stopped |
||
315 | |||
316 | */ |
||
317 | // RADEONWaitForIdleMMIO(info); |
||
318 | |||
319 | if (info->IsIGP) |
||
320 | |||
321 | |||
322 | /* Capture MC_STATUS in case things go wrong ... */ |
||
323 | |||
324 | |||
325 | /* Stop display & memory access */ |
||
326 | |||
327 | OUTREG(RADEON_OV0_SCALE_CNTL, ov0_scale_cntl & ~RADEON_SCALER_ENABLE); |
||
328 | crtc_ext_cntl = INREG(RADEON_CRTC_EXT_CNTL); |
||
329 | OUTREG(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl | RADEON_CRTC_DISPLAY_DIS); |
||
330 | crtc_gen_cntl = INREG(RADEON_CRTC_GEN_CNTL); |
||
331 | // RADEONWaitForVerticalSync(pScrn); |
||
332 | OUTREG(RADEON_CRTC_GEN_CNTL, |
||
333 | (crtc_gen_cntl & ~(RADEON_CRTC_CUR_EN | RADEON_CRTC_ICON_EN)) |
||
334 | | RADEON_CRTC_DISP_REQ_EN_B | RADEON_CRTC_EXT_DISP_EN); |
||
335 | |||
336 | if (info->HasCRTC2) |
||
337 | |||
338 | crtc2_gen_cntl = INREG(RADEON_CRTC2_GEN_CNTL); |
||
339 | // RADEONWaitForVerticalSync2(pScrn); |
||
340 | OUTREG(RADEON_CRTC2_GEN_CNTL, (crtc2_gen_cntl |
||
341 | & ~(RADEON_CRTC2_CUR_EN | RADEON_CRTC2_ICON_EN)) |
||
342 | | RADEON_CRTC2_DISP_REQ_EN_B); |
||
343 | } |
||
344 | |||
345 | /* Make sure the chip settles down (paranoid !) */ |
||
346 | |||
347 | |||
348 | /* Wait for MC idle */ |
||
349 | |||
350 | status_idle = R300_MC_IDLE; |
||
351 | else |
||
352 | status_idle = RADEON_MC_IDLE; |
||
353 | |||
354 | timeout = 0; |
||
355 | |||
356 | { |
||
357 | if (++timeout > 1000000) |
||
358 | { |
||
359 | dbgprintf("Timeout trying to update memory controller settings !\n"); |
||
360 | dbgprintf("MC_STATUS = 0x%08x (on entry = 0x%08x)\n", |
||
361 | INREG(RADEON_MC_STATUS), old_mc_status); |
||
362 | dbgprintf("You will probably crash now ... \n"); |
||
363 | /* Nothing we can do except maybe try to kill the server, |
||
364 | * let's wait 2 seconds to leave the above message a chance |
||
365 | * to maybe hit the disk and continue trying to setup despite |
||
366 | * the MC being non-idle |
||
367 | */ |
||
368 | usleep(20000); |
||
369 | } |
||
370 | usleep(10); |
||
371 | } |
||
372 | |||
373 | /* Update maps, first clearing out AGP to make sure we don't get |
||
374 | |||
375 | */ |
||
376 | OUTREG(RADEON_MC_AGP_LOCATION, 0xfffffffc); |
||
377 | OUTREG(RADEON_MC_FB_LOCATION, info->mc_fb_location); |
||
378 | radeon_write_mc_fb_agp_location(info, LOC_FB | LOC_AGP, info->mc_fb_location, |
||
379 | 0xfffffffc, 0); |
||
380 | |||
381 | OUTREG(RADEON_CRTC_GEN_CNTL,crtc_gen_cntl ); |
||
382 | |||
383 | OUTREG(RADEON_OV0_SCALE_CNTL, ov0_scale_cntl ); |
||
384 | |||
385 | |||
386 | |||
387 | |||
388 | info->mc_agp_location, 0); |
||
389 | /* Make sure map fully reached the chip */ |
||
390 | (void)INREG(RADEON_MC_FB_LOCATION); |
||
391 | |||
392 | dbgprintf(" Map applied, resetting engine ...\n"); |
||
393 | |||
394 | /* Reset the engine and HDP */ |
||
395 | |||
396 | |||
397 | /* Make sure we have sane offsets before re-enabling the CRTCs, disable |
||
398 | |||
399 | */ |
||
400 | |||
401 | OUTREG(RADEON_CRTC_OFFSET_CNTL, RADEON_CRTC_OFFSET_FLIP_CNTL); |
||
402 | |||
403 | OUTREG(RADEON_CUR_OFFSET, 0); |
||
404 | timeout = 0; |
||
405 | while(INREG(RADEON_CRTC_OFFSET) & RADEON_CRTC_OFFSET__GUI_TRIG_OFFSET) |
||
406 | { |
||
407 | if (timeout++ > 1000000) { |
||
408 | dbgprintf("Timeout waiting for CRTC offset to update !\n"); |
||
409 | break; |
||
410 | } |
||
411 | usleep(1000); |
||
412 | } |
||
413 | if (info->HasCRTC2) |
||
414 | { |
||
415 | OUTREG(RADEON_CRTC2_OFFSET_CNTL, RADEON_CRTC2_OFFSET_FLIP_CNTL); |
||
416 | OUTREG(RADEON_CRTC2_OFFSET, 0); |
||
417 | OUTREG(RADEON_CUR2_OFFSET, 0); |
||
418 | timeout = 0; |
||
419 | while(INREG(RADEON_CRTC2_OFFSET) & RADEON_CRTC2_OFFSET__GUI_TRIG_OFFSET) |
||
420 | { |
||
421 | if (timeout++ > 1000000) { |
||
422 | dbgprintf("Timeout waiting for CRTC2 offset to update !\n"); |
||
423 | break; |
||
424 | } |
||
425 | usleep(1000); |
||
426 | } |
||
427 | } |
||
428 | } |
||
429 | |||
430 | dbgprintf("Updating display base addresses...\n"); |
||
431 | |||
432 | OUTREG(RADEON_DISPLAY_BASE_ADDR, info->fbLocation); |
||
433 | |||
434 | OUTREG(RADEON_DISPLAY2_BASE_ADDR, info->fbLocation); |
||
435 | OUTREG(RADEON_OV0_BASE_ADDR, info->fbLocation); |
||
436 | (void)INREG(RADEON_OV0_BASE_ADDR); |
||
437 | |||
438 | /* More paranoia delays, wait 100ms */ |
||
439 | |||
440 | |||
441 | dbgprintf("Memory map updated.\n"); |
||
442 | |||
443 | }; |
||
444 | |||
445 | |||
446 | |||
447 | |||
881 | serge | 448 | u32_t mem_size; |
449 | u32_t aper_size; |
||
450 | |||
451 | radeon_read_mc_fb_agp_location(info, LOC_FB | LOC_AGP, &info->mc_fb_location, |
||
452 | |||
453 | |||
454 | dbgprintf(" MC_FB_LOCATION : 0x%08x\n", (unsigned)info->mc_fb_location); |
||
455 | |||
883 | serge | 456 | |
457 | |||
458 | |||
459 | |||
881 | serge | 460 | */ |
461 | if (info->ChipFamily >= CHIP_FAMILY_R600){ |
||
462 | mem_size = INREG(R600_CONFIG_MEMSIZE); |
||
463 | aper_size = INREG(R600_CONFIG_APER_SIZE); |
||
464 | } |
||
465 | else { |
||
466 | mem_size = INREG(RADEON_CONFIG_MEMSIZE); |
||
467 | aper_size = INREG(RADEON_CONFIG_APER_SIZE); |
||
468 | } |
||
469 | |||
470 | if (mem_size == 0) |
||
471 | |||
472 | |||
473 | /* Fix for RN50, M6, M7 with 8/16/32(??) MBs of VRAM - |
||
474 | |||
475 | if (aper_size > mem_size) |
||
476 | mem_size = aper_size; |
||
477 | |||
478 | |||
479 | |||
480 | |||
481 | (info->ChipFamily != CHIP_FAMILY_RS740)) { |
||
482 | if (info->IsIGP) |
||
483 | info->mc_fb_location = INREG(RADEON_NB_TOM); |
||
484 | else |
||
485 | { |
||
486 | u32_t aper0_base; |
||
487 | |||
488 | if (info->ChipFamily >= CHIP_FAMILY_R600) { |
||
489 | |||
490 | } |
||
491 | else { |
||
492 | aper0_base = INREG(RADEON_CONFIG_APER_0_BASE); |
||
493 | } |
||
494 | dbgprintf("aper0 base %x\n", aper0_base ); |
||
495 | |||
883 | serge | 496 | /* Recent chips have an "issue" with the memory controller, the |
881 | serge | 497 | |
498 | * too bad if we walk over the top of system memory, we don't |
||
499 | * use DMA without a remapped anyway. |
||
500 | * Affected chips are rv280, all r3xx, and all r4xx, but not IGP |
||
501 | */ |
||
502 | if ( info->ChipFamily == CHIP_FAMILY_RV280 || |
||
503 | info->ChipFamily == CHIP_FAMILY_R300 || |
||
504 | info->ChipFamily == CHIP_FAMILY_R350 || |
||
505 | info->ChipFamily == CHIP_FAMILY_RV350 || |
||
506 | info->ChipFamily == CHIP_FAMILY_RV380 || |
||
507 | info->ChipFamily == CHIP_FAMILY_R420 || |
||
508 | info->ChipFamily == CHIP_FAMILY_RV410) |
||
509 | aper0_base &= ~(mem_size - 1); |
||
510 | |||
511 | if ( info->ChipFamily >= CHIP_FAMILY_R600) { |
||
512 | |||
513 | (((aper0_base + mem_size - 1) & 0xff000000U) >> 8); |
||
514 | dbgprintf("mc fb loc is %08x\n", (unsigned int)info->mc_fb_location); |
||
515 | } |
||
516 | else { |
||
517 | info->mc_fb_location = (aper0_base >> 16) | |
||
518 | ((aper0_base + mem_size - 1) & 0xffff0000U); |
||
519 | dbgprintf("mc fb loc is %08x\n", (unsigned int)info->mc_fb_location); |
||
520 | } |
||
883 | serge | 521 | } |
881 | serge | 522 | } |
523 | if (info->ChipFamily >= CHIP_FAMILY_R600) { |
||
524 | info->fbLocation = (info->mc_fb_location & 0xffff) << 24; |
||
525 | } |
||
526 | else { |
||
527 | info->fbLocation = (info->mc_fb_location & 0xffff) << 16; |
||
528 | } |
||
529 | /* Just disable the damn AGP apertures for now, it may be |
||
530 | * re-enabled later by the DRM |
||
531 | */ |
||
532 | |||
533 | // if (IS_AVIVO_VARIANT) { |
||
534 | |||
883 | serge | 535 | // OUTREG(R600_HDP_NONSURFACE_BASE, (info->mc_fb_location << 16) & 0xff0000); |
536 | // } |
||
537 | // else { |
||
538 | // OUTREG(AVIVO_HDP_FB_LOCATION, info->mc_fb_location); |
||
539 | // } |
||
540 | // info->mc_agp_location = 0x003f0000; |
||
541 | // } |
||
542 | // else |
||
543 | // info->mc_agp_location = 0xffffffc0; |
||
544 | |||
545 | dbgprintf("RADEONInitMemoryMap() : \n"); |
||
881 | serge | 546 | |
547 | dbgprintf(" MC_FB_LOCATION : 0x%08x\n", (unsigned)info->mc_fb_location); |
||
883 | serge | 548 | dbgprintf(" MC_AGP_LOCATION : 0x%08x\n", (unsigned)info->mc_agp_location); |
881 | serge | 549 | dbgprintf(" FB_LOCATION : 0x%08x\n", (unsigned)info->fbLocation); |
550 | |||
883 | serge | 551 | RADEONUpdateMemMapRegisters(info); |
552 | |||
553 | |||
881 | serge | 554 | static void RADEONGetVRamType(RHDPtr info) |
555 | |||
556 | u32_t tmp; |
||
557 | |||
558 | if (info->IsIGP || (info->ChipFamily >= CHIP_FAMILY_R300)) |
||
559 | |||
560 | else if (INREG(RADEON_MEM_SDRAM_MODE_REG) & RADEON_MEM_CFG_TYPE_DDR) |
||
561 | info->IsDDR = TRUE; |
||
562 | else |
||
563 | info->IsDDR = FALSE; |
||
564 | |||
565 | if ( (info->ChipFamily >= CHIP_FAMILY_R600) && |
||
566 | |||
567 | { |
||
568 | int chansize; |
||
569 | /* r6xx */ |
||
570 | tmp = INREG(R600_RAMCFG); |
||
571 | if (tmp & R600_CHANSIZE_OVERRIDE) |
||
572 | chansize = 16; |
||
573 | else if (tmp & R600_CHANSIZE) |
||
574 | chansize = 64; |
||
575 | else |
||
576 | chansize = 32; |
||
577 | if (info->ChipFamily == CHIP_FAMILY_R600) |
||
578 | info->RamWidth = 8 * chansize; |
||
579 | else if (info->ChipFamily == CHIP_FAMILY_RV670) |
||
580 | info->RamWidth = 4 * chansize; |
||
581 | else if ((info->ChipFamily == CHIP_FAMILY_RV610) || |
||
582 | (info->ChipFamily == CHIP_FAMILY_RV620)) |
||
583 | info->RamWidth = chansize; |
||
584 | else if ((info->ChipFamily == CHIP_FAMILY_RV630) || |
||
585 | (info->ChipFamily == CHIP_FAMILY_RV635)) |
||
586 | info->RamWidth = 2 * chansize; |
||
587 | } |
||
588 | else if (info->ChipFamily == CHIP_FAMILY_RV515) { |
||
589 | /* rv515/rv550 */ |
||
590 | tmp = INMC(info, RV515_MC_CNTL); |
||
591 | tmp &= RV515_MEM_NUM_CHANNELS_MASK; |
||
592 | switch (tmp) { |
||
593 | case 0: info->RamWidth = 64; break; |
||
594 | case 1: info->RamWidth = 128; break; |
||
595 | default: info->RamWidth = 128; break; |
||
596 | } |
||
597 | } |
||
598 | else if ((info->ChipFamily >= CHIP_FAMILY_R520) && |
||
599 | (info->ChipFamily <= CHIP_FAMILY_RV570)){ |
||
600 | /* r520/rv530/rv560/rv570/r580 */ |
||
601 | tmp = INMC(info, R520_MC_CNTL0); |
||
602 | switch ((tmp & R520_MEM_NUM_CHANNELS_MASK) >> R520_MEM_NUM_CHANNELS_SHIFT) { |
||
603 | case 0: info->RamWidth = 32; break; |
||
604 | case 1: info->RamWidth = 64; break; |
||
605 | case 2: info->RamWidth = 128; break; |
||
606 | case 3: info->RamWidth = 256; break; |
||
607 | default: info->RamWidth = 64; break; |
||
608 | } |
||
609 | if (tmp & R520_MC_CHANNEL_SIZE) { |
||
610 | info->RamWidth *= 2; |
||
611 | } |
||
612 | } |
||
613 | else if ((info->ChipFamily >= CHIP_FAMILY_R300) && |
||
614 | (info->ChipFamily <= CHIP_FAMILY_RV410)) { |
||
615 | /* r3xx, r4xx */ |
||
616 | tmp = INREG(RADEON_MEM_CNTL); |
||
617 | tmp &= R300_MEM_NUM_CHANNELS_MASK; |
||
618 | switch (tmp) { |
||
619 | case 0: info->RamWidth = 64; break; |
||
620 | case 1: info->RamWidth = 128; break; |
||
621 | case 2: info->RamWidth = 256; break; |
||
622 | default: info->RamWidth = 128; break; |
||
623 | } |
||
624 | } |
||
625 | else if ((info->ChipFamily == CHIP_FAMILY_RV100) || |
||
626 | (info->ChipFamily == CHIP_FAMILY_RS100) || |
||
627 | (info->ChipFamily == CHIP_FAMILY_RS200)){ |
||
628 | tmp = INREG(RADEON_MEM_CNTL); |
||
629 | if (tmp & RV100_HALF_MODE) |
||
630 | info->RamWidth = 32; |
||
631 | else |
||
632 | info->RamWidth = 64; |
||
633 | |||
634 | if (!info->HasCRTC2) { |
||
635 | |||
883 | serge | 636 | info->IsDDR = TRUE; |
637 | } |
||
638 | } |
||
881 | serge | 639 | else if (info->ChipFamily <= CHIP_FAMILY_RV280) { |
883 | serge | 640 | tmp = INREG(RADEON_MEM_CNTL); |
881 | serge | 641 | if (tmp & RADEON_MEM_NUM_CHANNELS_MASK) |
642 | info->RamWidth = 128; |
||
643 | else |
||
644 | info->RamWidth = 64; |
||
645 | } else { |
||
646 | /* newer IGPs */ |
||
647 | info->RamWidth = 128; |
||
648 | } |
||
649 | |||
650 | /* This may not be correct, as some cards can have half of channel disabled |
||
651 | |||
652 | */ |
||
653 | } |
||
654 | |||
655 | /* |
||
656 | |||
657 | * accessible to the CPU can vary. This function is our best shot at figuring |
||
658 | * it out. Returns a value in KB. |
||
659 | */ |
||
660 | static u32_t RADEONGetAccessibleVRAM(RHDPtr info) |
||
661 | { |
||
662 | u32_t aper_size; |
||
663 | unsigned char byte; |
||
664 | |||
665 | if (info->ChipFamily >= CHIP_FAMILY_R600) |
||
666 | |||
667 | else |
||
668 | aper_size = INREG(RADEON_CONFIG_APER_SIZE) / 1024; |
||
669 | |||
670 | |||
671 | |||
672 | |||
673 | */ |
||
674 | if (info->ChipFamily == CHIP_FAMILY_RV280 || |
||
675 | info->ChipFamily == CHIP_FAMILY_RV350 || |
||
676 | info->ChipFamily == CHIP_FAMILY_RV380 || |
||
677 | info->ChipFamily == CHIP_FAMILY_R420 || |
||
678 | info->ChipFamily == CHIP_FAMILY_RV410 || |
||
679 | IS_AVIVO_VARIANT) { |
||
680 | MASKREG (RADEON_HOST_PATH_CNTL, RADEON_HDP_APER_CNTL, |
||
681 | ~RADEON_HDP_APER_CNTL); |
||
682 | dbgprintf("Generation 2 PCI interface, using max accessible memory\n"); |
||
683 | return aper_size * 2; |
||
684 | } |
||
685 | |||
686 | /* Older cards have all sorts of funny issues to deal with. First |
||
687 | |||
688 | * header type... Limit those to one aperture size |
||
689 | */ |
||
690 | byte = pciReadByte(info->PciTag, 0xe); |
||
691 | if (byte & 0x80) { |
||
883 | serge | 692 | dbgprintf("Generation 1 PCI interface in multifunction mode, " |
693 | "accessible memory limited to one aperture\n"); |
||
694 | return aper_size; |
||
695 | } |
||
696 | |||
697 | /* Single function older card. We read HDP_APER_CNTL to see how the BIOS |
||
881 | serge | 698 | |
699 | * we expect the BIOS to have done the right thing (might be too optimistic...) |
||
700 | */ |
||
701 | if (INREG(RADEON_HOST_PATH_CNTL) & RADEON_HDP_APER_CNTL) |
||
702 | return aper_size * 2; |
||
883 | serge | 703 | |
704 | return aper_size; |
||
881 | serge | 705 | |
706 | |||
707 | int RADEONDRIGetPciAperTableSize(RHDPtr info) |
||
708 | |||
883 | serge | 709 | int ret_size; |
710 | int num_pages; |
||
711 | |||
712 | num_pages = (info->pciAperSize * 1024 * 1024) / 4096; |
||
881 | serge | 713 | |
883 | serge | 714 | ret_size = num_pages * sizeof(unsigned int); |
715 | |||
716 | return ret_size; |
||
717 | |||
718 | |||
719 | static Bool RADEONPreInitVRAM(RHDPtr info) |
||
720 | |||
881 | serge | 721 | u32_t accessible, bar_size; |
722 | |||
723 | if ((!IS_AVIVO_VARIANT) && info->IsIGP) |
||
724 | |||
725 | u32_t tom = INREG(RADEON_NB_TOM); |
||
726 | |||
727 | info->videoRam = (((tom >> 16) - |
||
728 | |||
729 | |||
730 | OUTREG(RADEON_CONFIG_MEMSIZE, info->videoRam * 1024); |
||
731 | |||
732 | else |
||
733 | { |
||
734 | if (info->ChipFamily >= CHIP_FAMILY_R600) |
||
735 | info->videoRam = INREG(R600_CONFIG_MEMSIZE) / 1024; |
||
736 | else |
||
737 | { |
||
738 | /* Read VRAM size from card */ |
||
739 | info->videoRam = INREG(RADEON_CONFIG_MEMSIZE) / 1024; |
||
740 | |||
741 | /* Some production boards of m6 will return 0 if it's 8 MB */ |
||
742 | |||
743 | { |
||
744 | info->videoRam = 8192; |
||
745 | OUTREG(RADEON_CONFIG_MEMSIZE, 0x800000); |
||
746 | } |
||
747 | } |
||
748 | } |
||
749 | |||
750 | RADEONGetVRamType(info); |
||
751 | |||
752 | /* Get accessible memory */ |
||
753 | |||
754 | |||
755 | /* Crop it to the size of the PCI BAR */ |
||
756 | |||
757 | |||
758 | bar_size = 1 << (info->memsize[RHD_FB_BAR] - 10); |
||
759 | |||
760 | if (bar_size == 0) |
||
761 | |||
762 | if (accessible > bar_size) |
||
763 | accessible = bar_size; |
||
764 | |||
765 | dbgprintf("Detected total video RAM=%dK width=%dbit," |
||
766 | |||
767 | info->videoRam, info->RamWidth, |
||
768 | (unsigned)accessible, (unsigned)bar_size); |
||
769 | |||
770 | if (info->videoRam > accessible) |
||
771 | |||
772 | |||
773 | if (!IS_AVIVO_VARIANT) |
||
774 | |||
775 | info->BusCntl = INREG(RADEON_BUS_CNTL); |
||
776 | |||
777 | info->videoRam &= ~1023; |
||
778 | |||
779 | |||
780 | info->gartSize = RADEON_DEFAULT_GART_SIZE; |
||
781 | |||
883 | serge | 782 | info->bufSize = RADEON_DEFAULT_BUFFER_SIZE; |
783 | |||
784 | info->gartTexSize = info->gartSize - (info->ringSize + info->bufSize); |
||
881 | serge | 785 | |
883 | serge | 786 | info->pciAperSize = RADEON_DEFAULT_PCI_APER_SIZE; |
881 | serge | 787 | |
883 | serge | 788 | |
789 | |||
881 | serge | 790 | |
791 | |||
808 | serge | 792 | |
883 | serge | 793 | // if (info->cardType == CARD_PCIE ) |
808 | serge | 794 | |
883 | serge | 795 | // info->FbSecureSize = RADEONDRIGetPciAperTableSize(info); |
796 | // else |
||
797 | // info->FbSecureSize = 0; |
||
798 | |||
799 | return TRUE; |
||
808 | serge | 800 | |
883 | serge | 801 | |
808 | serge | 802 | |
803 | |||
804 | |||
881 | serge | 805 | u32_t cmd_stat; |
806 | |||
807 | rhdPtr->ChipErrata = 0; |
||
808 | |||
809 | if ( (rhdPtr->ChipFamily == CHIP_FAMILY_R300) && |
||
810 | |||
811 | == RADEON_CFG_ATI_REV_A11)) |
||
812 | rhdPtr->ChipErrata |= CHIP_ERRATA_R300_CG; |
||
813 | |||
814 | if ( (rhdPtr->ChipFamily == CHIP_FAMILY_RV200) || |
||
815 | |||
816 | rhdPtr->ChipErrata |= CHIP_ERRATA_PLL_DUMMYREADS; |
||
817 | |||
818 | if ( (rhdPtr->ChipFamily == CHIP_FAMILY_RV100) || |
||
819 | |||
820 | (rhdPtr->ChipFamily == CHIP_FAMILY_RS200) ) |
||
821 | rhdPtr->ChipErrata |= CHIP_ERRATA_PLL_DELAY; |
||
822 | |||
823 | rhdPtr->cardType = CARD_PCI; |
||
824 | |||
825 | |||
826 | |||
827 | |||
828 | if (cmd_stat & RADEON_CAP_LIST) |
||
829 | |||
830 | u32_t cap_ptr, cap_id; |
||
831 | |||
832 | cap_ptr = pciReadLong(rhdPtr->PciTag, RADEON_CAPABILITIES_PTR_PCI_CONFIG); |
||
833 | |||
834 | |||
835 | while(cap_ptr != RADEON_CAP_ID_NULL) |
||
836 | |||
837 | cap_id = pciReadLong(rhdPtr->PciTag, cap_ptr); |
||
838 | if ((cap_id & 0xff)== RADEON_CAP_ID_AGP) { |
||
839 | rhdPtr->cardType = CARD_AGP; |
||
840 | break; |
||
841 | } |
||
842 | if ((cap_id & 0xff)== RADEON_CAP_ID_EXP) { |
||
843 | rhdPtr->cardType = CARD_PCIE; |
||
844 | break; |
||
845 | } |
||
846 | cap_ptr = (cap_id >> 8) & RADEON_CAP_PTR_MASK; |
||
847 | } |
||
848 | } |
||
849 | |||
850 | dbgprintf("%s card detected\n",(rhdPtr->cardType==CARD_PCI) ? "PCI" : |
||
851 | |||
852 | |||
853 | /* treat PCIE IGP cards as PCI */ |
||
854 | |||
855 | rhdPtr->cardType = CARD_PCI; |
||
856 | |||
857 | if ( (rhdPtr->ChipFamily == CHIP_FAMILY_RS100) || |
||
858 | |||
859 | (rhdPtr->ChipFamily == CHIP_FAMILY_RS300) || |
||
860 | (rhdPtr->ChipFamily == CHIP_FAMILY_RS400) || |
||
861 | (rhdPtr->ChipFamily == CHIP_FAMILY_RS480) || |
||
862 | (rhdPtr->ChipFamily == CHIP_FAMILY_RS600) || |
||
863 | (rhdPtr->ChipFamily == CHIP_FAMILY_RS690) || |
||
864 | (rhdPtr->ChipFamily == CHIP_FAMILY_RS740)) |
||
865 | rhdPtr->has_tcl = FALSE; |
||
866 | else { |
||
867 | rhdPtr->has_tcl = TRUE; |
||
868 | } |
||
869 | |||
870 | rhdPtr->LinearAddr = rhdPtr->memBase[RHD_FB_BAR]; |
||
871 | |||
872 | return TRUE; |
||
873 | |||
874 | |||
875 | #if 0 |
||
876 | |||
883 | serge | 877 | { |
878 | unsigned char *RADEONMMIO = info->MMIO; |
||
879 | // unsigned long mode = drmAgpGetMode(info->dri->drmFD); /* Default mode */ |
||
880 | // unsigned int vendor = drmAgpVendorId(info->dri->drmFD); |
||
881 | // unsigned int device = drmAgpDeviceId(info->dri->drmFD); |
||
882 | /* ignore agp 3.0 mode bit from the chip as it's buggy on some cards with |
||
883 | pcie-agp rialto bridge chip - use the one from bridge which must match */ |
||
884 | uint32_t agp_status = (INREG(RADEON_AGP_STATUS) ); // & RADEON_AGP_MODE_MASK; |
||
885 | Bool is_v3 = (agp_status & RADEON_AGPv3_MODE); |
||
886 | unsigned int defaultMode; |
||
887 | |||
888 | if (is_v3) { |
||
889 | |||
890 | } else { |
||
891 | if (agp_status & RADEON_AGP_4X_MODE) defaultMode = 4; |
||
892 | else if (agp_status & RADEON_AGP_2X_MODE) defaultMode = 2; |
||
893 | else defaultMode = 1; |
||
894 | } |
||
895 | |||
896 | // agpMode = defaultMode; |
||
897 | |||
898 | dbgprintf(pScreen->myNum, from, "Using AGP %dx\n", dbgprintf); |
||
899 | |||
900 | mode &= ~RADEON_AGP_MODE_MASK; |
||
901 | |||
902 | /* only set one mode bit for AGPv3 */ |
||
903 | switch (defaultMode) { |
||
904 | case 8: mode |= RADEON_AGPv3_8X_MODE; break; |
||
905 | case 4: default: mode |= RADEON_AGPv3_4X_MODE; |
||
906 | } |
||
907 | /*TODO: need to take care of other bits valid for v3 mode |
||
908 | * currently these bits are not used in all tested cards. |
||
909 | */ |
||
910 | } else { |
||
911 | switch (defaultMode) { |
||
912 | case 4: mode |= RADEON_AGP_4X_MODE; |
||
913 | case 2: mode |= RADEON_AGP_2X_MODE; |
||
914 | case 1: default: mode |= RADEON_AGP_1X_MODE; |
||
915 | } |
||
916 | } |
||
917 | |||
918 | /* AGP Fast Writes. |
||
919 | |||
920 | * writes at all */ |
||
921 | mode &= ~RADEON_AGP_FW_MODE; /* Disable per default */ |
||
922 | |||
923 | dbgprintf("AGP Mode 0x%08lx\n", mode); |
||
924 | |||
925 | if (drmAgpEnable(info->dri->drmFD, mode) < 0) { |
||
926 | |||
927 | drmAgpRelease(info->dri->drmFD); |
||
928 | return FALSE; |
||
929 | } |
||
930 | |||
931 | /* Workaround for some hardware bugs */ |
||
932 | |||
933 | OUTREG(RADEON_AGP_CNTL, INREG(RADEON_AGP_CNTL) | 0x000e0000); |
||
934 | |||
935 | /* Modify the mode if the default mode |
||
936 | |||
937 | * particular combination of graphics |
||
938 | * card and AGP chipset. |
||
939 | */ |
||
940 | |||
941 | return TRUE; |
||
942 | |||
943 | #endif |
||
944 | |||
945 | Bool RHDPreInit() |
||
946 | |||
808 | serge | 947 | RHDPtr info; |
948 | |||
883 | serge | 949 | /* We need access to IO space already */ |
950 | |||
808 | serge | 951 | dbgprintf("Failed to map MMIO.\n"); |
881 | serge | 952 | return FALSE; |
953 | }; |
||
954 | |||
955 | |||
808 | serge | 956 | |
957 | |||
881 | serge | 958 | |
959 | if (!RADEONPreInitVRAM(&rhd)) |
||
808 | serge | 960 | |
881 | serge | 961 | |
962 | RADEONInitMemoryMap(&rhd); |
||
808 | serge | 963 | |
881 | serge | 964 | if (!rhd.videoRam) |
965 | |||
966 | dbgprintf("No Video RAM detected.\n"); |
||
967 | goto error1; |
||
968 | } |
||
969 | dbgprintf("VideoRAM: %d kByte\n",rhd.videoRam); |
||
970 | |||
971 | // rhd.FbFreeStart = 0; |
||
972 | |||
883 | serge | 973 | |
881 | serge | 974 | // if( !rhdMapFB(&rhd)) |
975 | |||
976 | |||
977 | // rhd.FbScanoutStart = 0; |
||
978 | |||
979 | |||
980 | rhd.FbFreeStart = 10*1024*1024; |
||
981 | |||
817 | serge | 982 | |
883 | serge | 983 | rhdInitHeap(&rhd); |
808 | serge | 984 | |
985 | info = &rhd; |
||
986 | |||
883 | serge | 987 | |
988 | |||
989 | |||
990 | error1: |
||
991 | |||
808 | serge | 992 | };><>>>><>><>=>=>=>=>><>><>><>><>>><> |
993 |