1 /* 2 * ATI Radeon Video card Framebuffer driver. 3 * 4 * Copyright 2007 Freescale Semiconductor, Inc. 5 * Zhang Wei <wei.zhang@freescale.com> 6 * Jason Jin <jason.jin@freescale.com> 7 * 8 * SPDX-License-Identifier: GPL-2.0+ 9 * 10 * Some codes of this file is partly ported from Linux kernel 11 * ATI video framebuffer driver. 12 * 13 * Now the driver is tested on below ATI chips: 14 * 9200 15 * X300 16 * X700 17 */ 18 19 #include <common.h> 20 21 #include <command.h> 22 #include <pci.h> 23 #include <asm/processor.h> 24 #include <asm/errno.h> 25 #include <asm/io.h> 26 #include <malloc.h> 27 #include <video_fb.h> 28 #include "videomodes.h" 29 30 #include <radeon.h> 31 #include "ati_ids.h" 32 #include "ati_radeon_fb.h" 33 34 #undef DEBUG 35 36 #ifdef DEBUG 37 #define DPRINT(x...) printf(x) 38 #else 39 #define DPRINT(x...) do{}while(0) 40 #endif 41 42 #ifndef min_t 43 #define min_t(type,x,y) \ 44 ({ type __x = (x); type __y = (y); __x < __y ? __x: __y; }) 45 #endif 46 47 #define MAX_MAPPED_VRAM (2048*2048*4) 48 #define MIN_MAPPED_VRAM (1024*768*1) 49 50 #define RADEON_BUFFER_ALIGN 0x00000fff 51 #define SURF_UPPER_BOUND(x,y,bpp) (((((x) * (((y) + 15) & ~15) * (bpp)/8) + RADEON_BUFFER_ALIGN) \ 52 & ~RADEON_BUFFER_ALIGN) - 1) 53 #define RADEON_CRT_PITCH(width, bpp) ((((width) * (bpp) + ((bpp) * 8 - 1)) / ((bpp) * 8)) | \ 54 ((((width) * (bpp) + ((bpp) * 8 - 1)) / ((bpp) * 8)) << 16)) 55 56 #define CRTC_H_TOTAL_DISP_VAL(htotal, hdisp) \ 57 (((((htotal) / 8) - 1) & 0x3ff) | (((((hdisp) / 8) - 1) & 0x1ff) << 16)) 58 #define CRTC_HSYNC_STRT_WID_VAL(hsync_srtr, hsync_wid) \ 59 (((hsync_srtr) & 0x1fff) | (((hsync_wid) & 0x3f) << 16)) 60 #define CRTC_V_TOTAL_DISP_VAL(vtotal, vdisp) \ 61 ((((vtotal) - 1) & 0xffff) | (((vdisp) - 1) << 16)) 62 #define CRTC_VSYNC_STRT_WID_VAL(vsync_srtr, vsync_wid) \ 63 ((((vsync_srtr) - 1) & 0xfff) | (((vsync_wid) & 0x1f) << 16)) 64 65 /*#define PCI_VENDOR_ID_ATI*/ 66 #define PCI_CHIP_RV280_5960 0x5960 67 #define PCI_CHIP_RV280_5961 0x5961 68 #define PCI_CHIP_RV280_5962 0x5962 69 #define PCI_CHIP_RV280_5964 0x5964 70 #define PCI_CHIP_RV280_5C63 0x5C63 71 #define PCI_CHIP_RV370_5B60 0x5B60 72 #define PCI_CHIP_RV380_5657 0x5657 73 #define PCI_CHIP_R420_554d 0x554d 74 75 static struct pci_device_id ati_radeon_pci_ids[] = { 76 {PCI_VENDOR_ID_ATI, PCI_CHIP_RV280_5960}, 77 {PCI_VENDOR_ID_ATI, PCI_CHIP_RV280_5961}, 78 {PCI_VENDOR_ID_ATI, PCI_CHIP_RV280_5962}, 79 {PCI_VENDOR_ID_ATI, PCI_CHIP_RV280_5964}, 80 {PCI_VENDOR_ID_ATI, PCI_CHIP_RV280_5C63}, 81 {PCI_VENDOR_ID_ATI, PCI_CHIP_RV370_5B60}, 82 {PCI_VENDOR_ID_ATI, PCI_CHIP_RV380_5657}, 83 {PCI_VENDOR_ID_ATI, PCI_CHIP_R420_554d}, 84 {0, 0} 85 }; 86 87 static u16 ati_radeon_id_family_table[][2] = { 88 {PCI_CHIP_RV280_5960, CHIP_FAMILY_RV280}, 89 {PCI_CHIP_RV280_5961, CHIP_FAMILY_RV280}, 90 {PCI_CHIP_RV280_5962, CHIP_FAMILY_RV280}, 91 {PCI_CHIP_RV280_5964, CHIP_FAMILY_RV280}, 92 {PCI_CHIP_RV280_5C63, CHIP_FAMILY_RV280}, 93 {PCI_CHIP_RV370_5B60, CHIP_FAMILY_RV380}, 94 {PCI_CHIP_RV380_5657, CHIP_FAMILY_RV380}, 95 {PCI_CHIP_R420_554d, CHIP_FAMILY_R420}, 96 {0, 0} 97 }; 98 99 u16 get_radeon_id_family(u16 device) 100 { 101 int i; 102 for (i=0; ati_radeon_id_family_table[0][i]; i+=2) 103 if (ati_radeon_id_family_table[0][i] == device) 104 return ati_radeon_id_family_table[0][i + 1]; 105 return 0; 106 } 107 108 struct radeonfb_info *rinfo; 109 110 static void radeon_identify_vram(struct radeonfb_info *rinfo) 111 { 112 u32 tmp; 113 114 /* framebuffer size */ 115 if ((rinfo->family == CHIP_FAMILY_RS100) || 116 (rinfo->family == CHIP_FAMILY_RS200) || 117 (rinfo->family == CHIP_FAMILY_RS300)) { 118 u32 tom = INREG(NB_TOM); 119 tmp = ((((tom >> 16) - (tom & 0xffff) + 1) << 6) * 1024); 120 121 radeon_fifo_wait(6); 122 OUTREG(MC_FB_LOCATION, tom); 123 OUTREG(DISPLAY_BASE_ADDR, (tom & 0xffff) << 16); 124 OUTREG(CRTC2_DISPLAY_BASE_ADDR, (tom & 0xffff) << 16); 125 OUTREG(OV0_BASE_ADDR, (tom & 0xffff) << 16); 126 127 /* This is supposed to fix the crtc2 noise problem. */ 128 OUTREG(GRPH2_BUFFER_CNTL, INREG(GRPH2_BUFFER_CNTL) & ~0x7f0000); 129 130 if ((rinfo->family == CHIP_FAMILY_RS100) || 131 (rinfo->family == CHIP_FAMILY_RS200)) { 132 /* This is to workaround the asic bug for RMX, some versions 133 of BIOS dosen't have this register initialized correctly. 134 */ 135 OUTREGP(CRTC_MORE_CNTL, CRTC_H_CUTOFF_ACTIVE_EN, 136 ~CRTC_H_CUTOFF_ACTIVE_EN); 137 } 138 } else { 139 tmp = INREG(CONFIG_MEMSIZE); 140 } 141 142 /* mem size is bits [28:0], mask off the rest */ 143 rinfo->video_ram = tmp & CONFIG_MEMSIZE_MASK; 144 145 /* 146 * Hack to get around some busted production M6's 147 * reporting no ram 148 */ 149 if (rinfo->video_ram == 0) { 150 switch (rinfo->pdev.device) { 151 case PCI_CHIP_RADEON_LY: 152 case PCI_CHIP_RADEON_LZ: 153 rinfo->video_ram = 8192 * 1024; 154 break; 155 default: 156 break; 157 } 158 } 159 160 /* 161 * Now try to identify VRAM type 162 */ 163 if ((rinfo->family >= CHIP_FAMILY_R300) || 164 (INREG(MEM_SDRAM_MODE_REG) & (1<<30))) 165 rinfo->vram_ddr = 1; 166 else 167 rinfo->vram_ddr = 0; 168 169 tmp = INREG(MEM_CNTL); 170 if (IS_R300_VARIANT(rinfo)) { 171 tmp &= R300_MEM_NUM_CHANNELS_MASK; 172 switch (tmp) { 173 case 0: rinfo->vram_width = 64; break; 174 case 1: rinfo->vram_width = 128; break; 175 case 2: rinfo->vram_width = 256; break; 176 default: rinfo->vram_width = 128; break; 177 } 178 } else if ((rinfo->family == CHIP_FAMILY_RV100) || 179 (rinfo->family == CHIP_FAMILY_RS100) || 180 (rinfo->family == CHIP_FAMILY_RS200)){ 181 if (tmp & RV100_MEM_HALF_MODE) 182 rinfo->vram_width = 32; 183 else 184 rinfo->vram_width = 64; 185 } else { 186 if (tmp & MEM_NUM_CHANNELS_MASK) 187 rinfo->vram_width = 128; 188 else 189 rinfo->vram_width = 64; 190 } 191 192 /* This may not be correct, as some cards can have half of channel disabled 193 * ToDo: identify these cases 194 */ 195 196 DPRINT("radeonfb: Found %dk of %s %d bits wide videoram\n", 197 rinfo->video_ram / 1024, 198 rinfo->vram_ddr ? "DDR" : "SDRAM", 199 rinfo->vram_width); 200 201 } 202 203 static void radeon_write_pll_regs(struct radeonfb_info *rinfo, struct radeon_regs *mode) 204 { 205 int i; 206 207 radeon_fifo_wait(20); 208 209 #if 0 210 /* Workaround from XFree */ 211 if (rinfo->is_mobility) { 212 /* A temporal workaround for the occational blanking on certain laptop 213 * panels. This appears to related to the PLL divider registers 214 * (fail to lock?). It occurs even when all dividers are the same 215 * with their old settings. In this case we really don't need to 216 * fiddle with PLL registers. By doing this we can avoid the blanking 217 * problem with some panels. 218 */ 219 if ((mode->ppll_ref_div == (INPLL(PPLL_REF_DIV) & PPLL_REF_DIV_MASK)) && 220 (mode->ppll_div_3 == (INPLL(PPLL_DIV_3) & 221 (PPLL_POST3_DIV_MASK | PPLL_FB3_DIV_MASK)))) { 222 /* We still have to force a switch to selected PPLL div thanks to 223 * an XFree86 driver bug which will switch it away in some cases 224 * even when using UseFDev */ 225 OUTREGP(CLOCK_CNTL_INDEX, 226 mode->clk_cntl_index & PPLL_DIV_SEL_MASK, 227 ~PPLL_DIV_SEL_MASK); 228 radeon_pll_errata_after_index(rinfo); 229 radeon_pll_errata_after_data(rinfo); 230 return; 231 } 232 } 233 #endif 234 if(rinfo->pdev.device == PCI_CHIP_RV370_5B60) return; 235 236 /* Swich VCKL clock input to CPUCLK so it stays fed while PPLL updates*/ 237 OUTPLLP(VCLK_ECP_CNTL, VCLK_SRC_SEL_CPUCLK, ~VCLK_SRC_SEL_MASK); 238 239 /* Reset PPLL & enable atomic update */ 240 OUTPLLP(PPLL_CNTL, 241 PPLL_RESET | PPLL_ATOMIC_UPDATE_EN | PPLL_VGA_ATOMIC_UPDATE_EN, 242 ~(PPLL_RESET | PPLL_ATOMIC_UPDATE_EN | PPLL_VGA_ATOMIC_UPDATE_EN)); 243 244 /* Switch to selected PPLL divider */ 245 OUTREGP(CLOCK_CNTL_INDEX, 246 mode->clk_cntl_index & PPLL_DIV_SEL_MASK, 247 ~PPLL_DIV_SEL_MASK); 248 249 /* Set PPLL ref. div */ 250 if (rinfo->family == CHIP_FAMILY_R300 || 251 rinfo->family == CHIP_FAMILY_RS300 || 252 rinfo->family == CHIP_FAMILY_R350 || 253 rinfo->family == CHIP_FAMILY_RV350) { 254 if (mode->ppll_ref_div & R300_PPLL_REF_DIV_ACC_MASK) { 255 /* When restoring console mode, use saved PPLL_REF_DIV 256 * setting. 257 */ 258 OUTPLLP(PPLL_REF_DIV, mode->ppll_ref_div, 0); 259 } else { 260 /* R300 uses ref_div_acc field as real ref divider */ 261 OUTPLLP(PPLL_REF_DIV, 262 (mode->ppll_ref_div << R300_PPLL_REF_DIV_ACC_SHIFT), 263 ~R300_PPLL_REF_DIV_ACC_MASK); 264 } 265 } else 266 OUTPLLP(PPLL_REF_DIV, mode->ppll_ref_div, ~PPLL_REF_DIV_MASK); 267 268 /* Set PPLL divider 3 & post divider*/ 269 OUTPLLP(PPLL_DIV_3, mode->ppll_div_3, ~PPLL_FB3_DIV_MASK); 270 OUTPLLP(PPLL_DIV_3, mode->ppll_div_3, ~PPLL_POST3_DIV_MASK); 271 272 /* Write update */ 273 while (INPLL(PPLL_REF_DIV) & PPLL_ATOMIC_UPDATE_R) 274 ; 275 OUTPLLP(PPLL_REF_DIV, PPLL_ATOMIC_UPDATE_W, ~PPLL_ATOMIC_UPDATE_W); 276 277 /* Wait read update complete */ 278 /* FIXME: Certain revisions of R300 can't recover here. Not sure of 279 the cause yet, but this workaround will mask the problem for now. 280 Other chips usually will pass at the very first test, so the 281 workaround shouldn't have any effect on them. */ 282 for (i = 0; (i < 10000 && INPLL(PPLL_REF_DIV) & PPLL_ATOMIC_UPDATE_R); i++) 283 ; 284 285 OUTPLL(HTOTAL_CNTL, 0); 286 287 /* Clear reset & atomic update */ 288 OUTPLLP(PPLL_CNTL, 0, 289 ~(PPLL_RESET | PPLL_SLEEP | PPLL_ATOMIC_UPDATE_EN | PPLL_VGA_ATOMIC_UPDATE_EN)); 290 291 /* We may want some locking ... oh well */ 292 udelay(5000); 293 294 /* Switch back VCLK source to PPLL */ 295 OUTPLLP(VCLK_ECP_CNTL, VCLK_SRC_SEL_PPLLCLK, ~VCLK_SRC_SEL_MASK); 296 } 297 298 typedef struct { 299 u16 reg; 300 u32 val; 301 } reg_val; 302 303 #if 0 /* unused ? -> scheduled for removal */ 304 /* these common regs are cleared before mode setting so they do not 305 * interfere with anything 306 */ 307 static reg_val common_regs[] = { 308 { OVR_CLR, 0 }, 309 { OVR_WID_LEFT_RIGHT, 0 }, 310 { OVR_WID_TOP_BOTTOM, 0 }, 311 { OV0_SCALE_CNTL, 0 }, 312 { SUBPIC_CNTL, 0 }, 313 { VIPH_CONTROL, 0 }, 314 { I2C_CNTL_1, 0 }, 315 { GEN_INT_CNTL, 0 }, 316 { CAP0_TRIG_CNTL, 0 }, 317 { CAP1_TRIG_CNTL, 0 }, 318 }; 319 #endif /* 0 */ 320 321 void radeon_setmode(void) 322 { 323 struct radeon_regs *mode = malloc(sizeof(struct radeon_regs)); 324 325 mode->crtc_gen_cntl = 0x03000200; 326 mode->crtc_ext_cntl = 0x00008048; 327 mode->dac_cntl = 0xff002100; 328 mode->crtc_h_total_disp = 0x4f0063; 329 mode->crtc_h_sync_strt_wid = 0x8c02a2; 330 mode->crtc_v_total_disp = 0x01df020c; 331 mode->crtc_v_sync_strt_wid = 0x8201ea; 332 mode->crtc_pitch = 0x00500050; 333 334 OUTREG(CRTC_GEN_CNTL, mode->crtc_gen_cntl); 335 OUTREGP(CRTC_EXT_CNTL, mode->crtc_ext_cntl, 336 ~(CRTC_HSYNC_DIS | CRTC_VSYNC_DIS | CRTC_DISPLAY_DIS)); 337 OUTREGP(DAC_CNTL, mode->dac_cntl, DAC_RANGE_CNTL | DAC_BLANKING); 338 OUTREG(CRTC_H_TOTAL_DISP, mode->crtc_h_total_disp); 339 OUTREG(CRTC_H_SYNC_STRT_WID, mode->crtc_h_sync_strt_wid); 340 OUTREG(CRTC_V_TOTAL_DISP, mode->crtc_v_total_disp); 341 OUTREG(CRTC_V_SYNC_STRT_WID, mode->crtc_v_sync_strt_wid); 342 OUTREG(CRTC_OFFSET, 0); 343 OUTREG(CRTC_OFFSET_CNTL, 0); 344 OUTREG(CRTC_PITCH, mode->crtc_pitch); 345 346 mode->clk_cntl_index = 0x300; 347 mode->ppll_ref_div = 0xc; 348 mode->ppll_div_3 = 0x00030059; 349 350 radeon_write_pll_regs(rinfo, mode); 351 } 352 353 static void set_pal(void) 354 { 355 int idx, val = 0; 356 357 for (idx = 0; idx < 256; idx++) { 358 OUTREG8(PALETTE_INDEX, idx); 359 OUTREG(PALETTE_DATA, val); 360 val += 0x00010101; 361 } 362 } 363 364 void radeon_setmode_9200(int vesa_idx, int bpp) 365 { 366 struct radeon_regs *mode = malloc(sizeof(struct radeon_regs)); 367 368 mode->crtc_gen_cntl = CRTC_EN | CRTC_EXT_DISP_EN; 369 mode->crtc_ext_cntl = VGA_ATI_LINEAR | XCRT_CNT_EN | CRTC_CRT_ON; 370 mode->dac_cntl = DAC_MASK_ALL | DAC_VGA_ADR_EN | DAC_8BIT_EN; 371 mode->crtc_offset_cntl = CRTC_OFFSET_CNTL__CRTC_TILE_EN; 372 373 switch (bpp) { 374 case 24: 375 mode->crtc_gen_cntl |= 0x6 << 8; /* x888 */ 376 #if defined(__BIG_ENDIAN) 377 mode->surface_cntl = NONSURF_AP0_SWP_32BPP | NONSURF_AP1_SWP_32BPP; 378 mode->surf_info[0] = NONSURF_AP0_SWP_32BPP | NONSURF_AP1_SWP_32BPP; 379 #endif 380 break; 381 case 16: 382 mode->crtc_gen_cntl |= 0x4 << 8; /* 565 */ 383 #if defined(__BIG_ENDIAN) 384 mode->surface_cntl = NONSURF_AP0_SWP_16BPP | NONSURF_AP1_SWP_16BPP; 385 mode->surf_info[0] = NONSURF_AP0_SWP_16BPP | NONSURF_AP1_SWP_16BPP; 386 #endif 387 break; 388 default: 389 mode->crtc_gen_cntl |= 0x2 << 8; /* palette */ 390 mode->surface_cntl = 0x00000000; 391 break; 392 } 393 394 switch (vesa_idx) { 395 case RES_MODE_1280x1024: 396 mode->crtc_h_total_disp = CRTC_H_TOTAL_DISP_VAL(1688,1280); 397 mode->crtc_v_total_disp = CRTC_V_TOTAL_DISP_VAL(1066,1024); 398 mode->crtc_v_sync_strt_wid = CRTC_VSYNC_STRT_WID_VAL(1025,3); 399 #if defined(CONFIG_RADEON_VREFRESH_75HZ) 400 mode->crtc_h_sync_strt_wid = CRTC_HSYNC_STRT_WID_VAL(1288,18); 401 mode->ppll_div_3 = 0x00010078; 402 #else /* default @ 60 Hz */ 403 mode->crtc_h_sync_strt_wid = CRTC_HSYNC_STRT_WID_VAL(1320,14); 404 mode->ppll_div_3 = 0x00010060; 405 #endif 406 /* 407 * for this mode pitch expands to the same value for 32, 16 and 8 bpp, 408 * so we set it here once only. 409 */ 410 mode->crtc_pitch = RADEON_CRT_PITCH(1280,32); 411 switch (bpp) { 412 case 24: 413 mode->surf_info[0] |= R200_SURF_TILE_COLOR_MACRO | (1280 * 4 / 16); 414 mode->surf_upper_bound[0] = SURF_UPPER_BOUND(1280,1024,32); 415 break; 416 case 16: 417 mode->surf_info[0] |= R200_SURF_TILE_COLOR_MACRO | (1280 * 2 / 16); 418 mode->surf_upper_bound[0] = SURF_UPPER_BOUND(1280,1024,16); 419 break; 420 default: /* 8 bpp */ 421 mode->surf_info[0] = R200_SURF_TILE_COLOR_MACRO | (1280 * 1 / 16); 422 mode->surf_upper_bound[0] = SURF_UPPER_BOUND(1280,1024,8); 423 break; 424 } 425 break; 426 case RES_MODE_1024x768: 427 #if defined(CONFIG_RADEON_VREFRESH_75HZ) 428 mode->crtc_h_total_disp = CRTC_H_TOTAL_DISP_VAL(1312,1024); 429 mode->crtc_h_sync_strt_wid = CRTC_HSYNC_STRT_WID_VAL(1032,12); 430 mode->crtc_v_total_disp = CRTC_V_TOTAL_DISP_VAL(800,768); 431 mode->crtc_v_sync_strt_wid = CRTC_VSYNC_STRT_WID_VAL(769,3); 432 mode->ppll_div_3 = 0x0002008c; 433 #else /* @ 60 Hz */ 434 mode->crtc_h_total_disp = CRTC_H_TOTAL_DISP_VAL(1344,1024); 435 mode->crtc_h_sync_strt_wid = CRTC_HSYNC_STRT_WID_VAL(1040,17) | CRTC_H_SYNC_POL; 436 mode->crtc_v_total_disp = CRTC_V_TOTAL_DISP_VAL(806,768); 437 mode->crtc_v_sync_strt_wid = CRTC_VSYNC_STRT_WID_VAL(771,6) | CRTC_V_SYNC_POL; 438 mode->ppll_div_3 = 0x00020074; 439 #endif 440 /* also same pitch value for 32, 16 and 8 bpp */ 441 mode->crtc_pitch = RADEON_CRT_PITCH(1024,32); 442 switch (bpp) { 443 case 24: 444 mode->surf_info[0] |= R200_SURF_TILE_COLOR_MACRO | (1024 * 4 / 16); 445 mode->surf_upper_bound[0] = SURF_UPPER_BOUND(1024,768,32); 446 break; 447 case 16: 448 mode->surf_info[0] |= R200_SURF_TILE_COLOR_MACRO | (1024 * 2 / 16); 449 mode->surf_upper_bound[0] = SURF_UPPER_BOUND(1024,768,16); 450 break; 451 default: /* 8 bpp */ 452 mode->surf_info[0] = R200_SURF_TILE_COLOR_MACRO | (1024 * 1 / 16); 453 mode->surf_upper_bound[0] = SURF_UPPER_BOUND(1024,768,8); 454 break; 455 } 456 break; 457 case RES_MODE_800x600: 458 mode->crtc_h_total_disp = CRTC_H_TOTAL_DISP_VAL(1056,800); 459 #if defined(CONFIG_RADEON_VREFRESH_75HZ) 460 mode->crtc_h_sync_strt_wid = CRTC_HSYNC_STRT_WID_VAL(808,10); 461 mode->crtc_v_total_disp = CRTC_V_TOTAL_DISP_VAL(625,600); 462 mode->crtc_v_sync_strt_wid = CRTC_VSYNC_STRT_WID_VAL(601,3); 463 mode->ppll_div_3 = 0x000300b0; 464 #else /* @ 60 Hz */ 465 mode->crtc_h_sync_strt_wid = CRTC_HSYNC_STRT_WID_VAL(832,16); 466 mode->crtc_v_total_disp = CRTC_V_TOTAL_DISP_VAL(628,600); 467 mode->crtc_v_sync_strt_wid = CRTC_VSYNC_STRT_WID_VAL(601,4); 468 mode->ppll_div_3 = 0x0003008e; 469 #endif 470 switch (bpp) { 471 case 24: 472 mode->crtc_pitch = RADEON_CRT_PITCH(832,32); 473 mode->surf_info[0] |= R200_SURF_TILE_COLOR_MACRO | (832 * 4 / 16); 474 mode->surf_upper_bound[0] = SURF_UPPER_BOUND(832,600,32); 475 break; 476 case 16: 477 mode->crtc_pitch = RADEON_CRT_PITCH(896,16); 478 mode->surf_info[0] |= R200_SURF_TILE_COLOR_MACRO | (896 * 2 / 16); 479 mode->surf_upper_bound[0] = SURF_UPPER_BOUND(896,600,16); 480 break; 481 default: /* 8 bpp */ 482 mode->crtc_pitch = RADEON_CRT_PITCH(1024,8); 483 mode->surf_info[0] = R200_SURF_TILE_COLOR_MACRO | (1024 * 1 / 16); 484 mode->surf_upper_bound[0] = SURF_UPPER_BOUND(1024,600,8); 485 break; 486 } 487 break; 488 default: /* RES_MODE_640x480 */ 489 #if defined(CONFIG_RADEON_VREFRESH_75HZ) 490 mode->crtc_h_total_disp = CRTC_H_TOTAL_DISP_VAL(840,640); 491 mode->crtc_h_sync_strt_wid = CRTC_HSYNC_STRT_WID_VAL(648,8) | CRTC_H_SYNC_POL; 492 mode->crtc_v_total_disp = CRTC_V_TOTAL_DISP_VAL(500,480); 493 mode->crtc_v_sync_strt_wid = CRTC_VSYNC_STRT_WID_VAL(481,3) | CRTC_V_SYNC_POL; 494 mode->ppll_div_3 = 0x00030070; 495 #else /* @ 60 Hz */ 496 mode->crtc_h_total_disp = CRTC_H_TOTAL_DISP_VAL(800,640); 497 mode->crtc_h_sync_strt_wid = CRTC_HSYNC_STRT_WID_VAL(674,12) | CRTC_H_SYNC_POL; 498 mode->crtc_v_total_disp = CRTC_V_TOTAL_DISP_VAL(525,480); 499 mode->crtc_v_sync_strt_wid = CRTC_VSYNC_STRT_WID_VAL(491,2) | CRTC_V_SYNC_POL; 500 mode->ppll_div_3 = 0x00030059; 501 #endif 502 /* also same pitch value for 32, 16 and 8 bpp */ 503 mode->crtc_pitch = RADEON_CRT_PITCH(640,32); 504 switch (bpp) { 505 case 24: 506 mode->surf_info[0] |= R200_SURF_TILE_COLOR_MACRO | (640 * 4 / 16); 507 mode->surf_upper_bound[0] = SURF_UPPER_BOUND(640,480,32); 508 break; 509 case 16: 510 mode->surf_info[0] |= R200_SURF_TILE_COLOR_MACRO | (640 * 2 / 16); 511 mode->surf_upper_bound[0] = SURF_UPPER_BOUND(640,480,16); 512 break; 513 default: /* 8 bpp */ 514 mode->crtc_offset_cntl = 0x00000000; 515 break; 516 } 517 break; 518 } 519 520 OUTREG(CRTC_GEN_CNTL, mode->crtc_gen_cntl | CRTC_DISP_REQ_EN_B); 521 OUTREGP(CRTC_EXT_CNTL, mode->crtc_ext_cntl, 522 (CRTC_HSYNC_DIS | CRTC_VSYNC_DIS | CRTC_DISPLAY_DIS)); 523 OUTREGP(DAC_CNTL, mode->dac_cntl, DAC_RANGE_CNTL | DAC_BLANKING); 524 OUTREG(CRTC_H_TOTAL_DISP, mode->crtc_h_total_disp); 525 OUTREG(CRTC_H_SYNC_STRT_WID, mode->crtc_h_sync_strt_wid); 526 OUTREG(CRTC_V_TOTAL_DISP, mode->crtc_v_total_disp); 527 OUTREG(CRTC_V_SYNC_STRT_WID, mode->crtc_v_sync_strt_wid); 528 OUTREG(CRTC_OFFSET, 0); 529 OUTREG(CRTC_OFFSET_CNTL, mode->crtc_offset_cntl); 530 OUTREG(CRTC_PITCH, mode->crtc_pitch); 531 OUTREG(CRTC_GEN_CNTL, mode->crtc_gen_cntl); 532 533 mode->clk_cntl_index = 0x300; 534 mode->ppll_ref_div = 0xc; 535 536 radeon_write_pll_regs(rinfo, mode); 537 538 OUTREGP(CRTC_EXT_CNTL, mode->crtc_ext_cntl, 539 ~(CRTC_HSYNC_DIS | CRTC_VSYNC_DIS | CRTC_DISPLAY_DIS)); 540 OUTREG(SURFACE0_INFO, mode->surf_info[0]); 541 OUTREG(SURFACE0_LOWER_BOUND, 0); 542 OUTREG(SURFACE0_UPPER_BOUND, mode->surf_upper_bound[0]); 543 OUTREG(SURFACE_CNTL, mode->surface_cntl); 544 545 if (bpp > 8) 546 set_pal(); 547 548 free(mode); 549 } 550 551 #include "../bios_emulator/include/biosemu.h" 552 extern int BootVideoCardBIOS(pci_dev_t pcidev, BE_VGAInfo ** pVGAInfo, int cleanUp); 553 554 int radeon_probe(struct radeonfb_info *rinfo) 555 { 556 pci_dev_t pdev; 557 u16 did; 558 559 pdev = pci_find_devices(ati_radeon_pci_ids, 0); 560 561 if (pdev != -1) { 562 pci_read_config_word(pdev, PCI_DEVICE_ID, &did); 563 printf("ATI Radeon video card (%04x, %04x) found @(%d:%d:%d)\n", 564 PCI_VENDOR_ID_ATI, did, (pdev >> 16) & 0xff, 565 (pdev >> 11) & 0x1f, (pdev >> 8) & 0x7); 566 567 strcpy(rinfo->name, "ATI Radeon"); 568 rinfo->pdev.vendor = PCI_VENDOR_ID_ATI; 569 rinfo->pdev.device = did; 570 rinfo->family = get_radeon_id_family(rinfo->pdev.device); 571 pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0, 572 &rinfo->fb_base_bus); 573 pci_read_config_dword(pdev, PCI_BASE_ADDRESS_2, 574 &rinfo->mmio_base_bus); 575 rinfo->fb_base_bus &= 0xfffff000; 576 rinfo->mmio_base_bus &= ~0x04; 577 578 rinfo->mmio_base = pci_bus_to_virt(pdev, rinfo->mmio_base_bus, 579 PCI_REGION_MEM, 0, MAP_NOCACHE); 580 DPRINT("rinfo->mmio_base = 0x%p bus=0x%x\n", 581 rinfo->mmio_base, rinfo->mmio_base_bus); 582 rinfo->fb_local_base = INREG(MC_FB_LOCATION) << 16; 583 DPRINT("rinfo->fb_local_base = 0x%x\n",rinfo->fb_local_base); 584 /* PostBIOS with x86 emulater */ 585 if (!BootVideoCardBIOS(pdev, NULL, 0)) 586 return -1; 587 588 /* 589 * Check for errata 590 * (These will be added in the future for the chipfamily 591 * R300, RV200, RS200, RV100, RS100.) 592 */ 593 594 /* Get VRAM size and type */ 595 radeon_identify_vram(rinfo); 596 597 rinfo->mapped_vram = min_t(unsigned long, MAX_MAPPED_VRAM, 598 rinfo->video_ram); 599 rinfo->fb_base = pci_bus_to_virt(pdev, rinfo->fb_base_bus, 600 PCI_REGION_MEM, 0, MAP_NOCACHE); 601 DPRINT("Radeon: framebuffer base address 0x%08x, " 602 "bus address 0x%08x\n" 603 "MMIO base address 0x%08x, bus address 0x%08x, " 604 "framebuffer local base 0x%08x.\n ", 605 (u32)rinfo->fb_base, rinfo->fb_base_bus, 606 (u32)rinfo->mmio_base, rinfo->mmio_base_bus, 607 rinfo->fb_local_base); 608 return 0; 609 } 610 return -1; 611 } 612 613 /* 614 * The Graphic Device 615 */ 616 GraphicDevice ctfb; 617 618 #define CURSOR_SIZE 0x1000 /* in KByte for HW Cursor */ 619 #define PATTERN_ADR (pGD->dprBase + CURSOR_SIZE) /* pattern Memory after Cursor Memory */ 620 #define PATTERN_SIZE 8*8*4 /* 4 Bytes per Pixel 8 x 8 Pixel */ 621 #define ACCELMEMORY (CURSOR_SIZE + PATTERN_SIZE) /* reserved Memory for BITBlt and hw cursor */ 622 623 void *video_hw_init(void) 624 { 625 GraphicDevice *pGD = (GraphicDevice *) & ctfb; 626 u32 *vm; 627 char *penv; 628 unsigned long t1, hsynch, vsynch; 629 int bits_per_pixel, i, tmp, vesa_idx = 0, videomode; 630 struct ctfb_res_modes *res_mode; 631 struct ctfb_res_modes var_mode; 632 633 rinfo = malloc(sizeof(struct radeonfb_info)); 634 635 printf("Video: "); 636 if(radeon_probe(rinfo)) { 637 printf("No radeon video card found!\n"); 638 return NULL; 639 } 640 641 tmp = 0; 642 643 videomode = CONFIG_SYS_DEFAULT_VIDEO_MODE; 644 /* get video mode via environment */ 645 if ((penv = getenv ("videomode")) != NULL) { 646 /* deceide if it is a string */ 647 if (penv[0] <= '9') { 648 videomode = (int) simple_strtoul (penv, NULL, 16); 649 tmp = 1; 650 } 651 } else { 652 tmp = 1; 653 } 654 if (tmp) { 655 /* parameter are vesa modes */ 656 /* search params */ 657 for (i = 0; i < VESA_MODES_COUNT; i++) { 658 if (vesa_modes[i].vesanr == videomode) 659 break; 660 } 661 if (i == VESA_MODES_COUNT) { 662 printf ("no VESA Mode found, switching to mode 0x%x ", CONFIG_SYS_DEFAULT_VIDEO_MODE); 663 i = 0; 664 } 665 res_mode = (struct ctfb_res_modes *) &res_mode_init[vesa_modes[i].resindex]; 666 bits_per_pixel = vesa_modes[i].bits_per_pixel; 667 vesa_idx = vesa_modes[i].resindex; 668 } else { 669 res_mode = (struct ctfb_res_modes *) &var_mode; 670 bits_per_pixel = video_get_params (res_mode, penv); 671 } 672 673 /* calculate hsynch and vsynch freq (info only) */ 674 t1 = (res_mode->left_margin + res_mode->xres + 675 res_mode->right_margin + res_mode->hsync_len) / 8; 676 t1 *= 8; 677 t1 *= res_mode->pixclock; 678 t1 /= 1000; 679 hsynch = 1000000000L / t1; 680 t1 *= (res_mode->upper_margin + res_mode->yres + 681 res_mode->lower_margin + res_mode->vsync_len); 682 t1 /= 1000; 683 vsynch = 1000000000L / t1; 684 685 /* fill in Graphic device struct */ 686 sprintf (pGD->modeIdent, "%dx%dx%d %ldkHz %ldHz", res_mode->xres, 687 res_mode->yres, bits_per_pixel, (hsynch / 1000), 688 (vsynch / 1000)); 689 printf ("%s\n", pGD->modeIdent); 690 pGD->winSizeX = res_mode->xres; 691 pGD->winSizeY = res_mode->yres; 692 pGD->plnSizeX = res_mode->xres; 693 pGD->plnSizeY = res_mode->yres; 694 695 switch (bits_per_pixel) { 696 case 24: 697 pGD->gdfBytesPP = 4; 698 pGD->gdfIndex = GDF_32BIT_X888RGB; 699 if (res_mode->xres == 800) { 700 pGD->winSizeX = 832; 701 pGD->plnSizeX = 832; 702 } 703 break; 704 case 16: 705 pGD->gdfBytesPP = 2; 706 pGD->gdfIndex = GDF_16BIT_565RGB; 707 if (res_mode->xres == 800) { 708 pGD->winSizeX = 896; 709 pGD->plnSizeX = 896; 710 } 711 break; 712 default: 713 if (res_mode->xres == 800) { 714 pGD->winSizeX = 1024; 715 pGD->plnSizeX = 1024; 716 } 717 pGD->gdfBytesPP = 1; 718 pGD->gdfIndex = GDF__8BIT_INDEX; 719 break; 720 } 721 722 pGD->isaBase = CONFIG_SYS_ISA_IO_BASE_ADDRESS; 723 pGD->pciBase = (unsigned int)rinfo->fb_base; 724 pGD->frameAdrs = (unsigned int)rinfo->fb_base; 725 pGD->memSize = 64 * 1024 * 1024; 726 727 /* Cursor Start Address */ 728 pGD->dprBase = (pGD->winSizeX * pGD->winSizeY * pGD->gdfBytesPP) + 729 (unsigned int)rinfo->fb_base; 730 if ((pGD->dprBase & 0x0fff) != 0) { 731 /* allign it */ 732 pGD->dprBase &= 0xfffff000; 733 pGD->dprBase += 0x00001000; 734 } 735 DPRINT ("Cursor Start %x Pattern Start %x\n", pGD->dprBase, 736 PATTERN_ADR); 737 pGD->vprBase = (unsigned int)rinfo->fb_base; /* Dummy */ 738 pGD->cprBase = (unsigned int)rinfo->fb_base; /* Dummy */ 739 /* set up Hardware */ 740 741 /* Clear video memory (only visible screen area) */ 742 i = pGD->winSizeX * pGD->winSizeY * pGD->gdfBytesPP / 4; 743 vm = (unsigned int *) pGD->pciBase; 744 while (i--) 745 *vm++ = 0; 746 /*SetDrawingEngine (bits_per_pixel);*/ 747 748 if (rinfo->family == CHIP_FAMILY_RV280) 749 radeon_setmode_9200(vesa_idx, bits_per_pixel); 750 else 751 radeon_setmode(); 752 753 return ((void *) pGD); 754 } 755 756 void video_set_lut (unsigned int index, /* color number */ 757 unsigned char r, /* red */ 758 unsigned char g, /* green */ 759 unsigned char b /* blue */ 760 ) 761 { 762 OUTREG(PALETTE_INDEX, index); 763 OUTREG(PALETTE_DATA, (r << 16) | (g << 8) | b); 764 } 765