2 * ATI Radeon Video card Framebuffer driver.
4 * Copyright 2007 Freescale Semiconductor, Inc.
8 * SPDX-License-Identifier: GPL-2.0+
10 * Some codes of this file is partly ported from Linux kernel
11 * ATI video framebuffer driver.
13 * Now the driver is tested on below ATI chips:
23 #include <asm/processor.h>
24 #include <asm/errno.h>
28 #include "videomodes.h"
32 #include "ati_radeon_fb.h"
37 #define DPRINT(x...) printf(x)
39 #define DPRINT(x...) do{}while(0)
43 #define min_t(type,x,y) \
44 ({ type __x = (x); type __y = (y); __x < __y ? __x: __y; })
47 #define MAX_MAPPED_VRAM (2048*2048*4)
48 #define MIN_MAPPED_VRAM (1024*768*1)
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))
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))
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
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},
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},
99 u16 get_radeon_id_family(u16 device)
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];
108 struct radeonfb_info *rinfo;
110 static void radeon_identify_vram(struct radeonfb_info *rinfo)
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);
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);
127 /* This is supposed to fix the crtc2 noise problem. */
128 OUTREG(GRPH2_BUFFER_CNTL, INREG(GRPH2_BUFFER_CNTL) & ~0x7f0000);
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.
135 OUTREGP(CRTC_MORE_CNTL, CRTC_H_CUTOFF_ACTIVE_EN,
136 ~CRTC_H_CUTOFF_ACTIVE_EN);
139 tmp = INREG(CONFIG_MEMSIZE);
142 /* mem size is bits [28:0], mask off the rest */
143 rinfo->video_ram = tmp & CONFIG_MEMSIZE_MASK;
146 * Hack to get around some busted production M6's
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;
161 * Now try to identify VRAM type
163 if ((rinfo->family >= CHIP_FAMILY_R300) ||
164 (INREG(MEM_SDRAM_MODE_REG) & (1<<30)))
169 tmp = INREG(MEM_CNTL);
170 if (IS_R300_VARIANT(rinfo)) {
171 tmp &= R300_MEM_NUM_CHANNELS_MASK;
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;
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;
184 rinfo->vram_width = 64;
186 if (tmp & MEM_NUM_CHANNELS_MASK)
187 rinfo->vram_width = 128;
189 rinfo->vram_width = 64;
192 /* This may not be correct, as some cards can have half of channel disabled
193 * ToDo: identify these cases
196 DPRINT("radeonfb: Found %dk of %s %d bits wide videoram\n",
197 rinfo->video_ram / 1024,
198 rinfo->vram_ddr ? "DDR" : "SDRAM",
203 static void radeon_write_pll_regs(struct radeonfb_info *rinfo, struct radeon_regs *mode)
207 radeon_fifo_wait(20);
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.
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,
228 radeon_pll_errata_after_index(rinfo);
229 radeon_pll_errata_after_data(rinfo);
234 if(rinfo->pdev.device == PCI_CHIP_RV370_5B60) return;
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);
239 /* Reset PPLL & enable atomic update */
241 PPLL_RESET | PPLL_ATOMIC_UPDATE_EN | PPLL_VGA_ATOMIC_UPDATE_EN,
242 ~(PPLL_RESET | PPLL_ATOMIC_UPDATE_EN | PPLL_VGA_ATOMIC_UPDATE_EN));
244 /* Switch to selected PPLL divider */
245 OUTREGP(CLOCK_CNTL_INDEX,
246 mode->clk_cntl_index & PPLL_DIV_SEL_MASK,
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
258 OUTPLLP(PPLL_REF_DIV, mode->ppll_ref_div, 0);
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);
266 OUTPLLP(PPLL_REF_DIV, mode->ppll_ref_div, ~PPLL_REF_DIV_MASK);
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);
273 while (INPLL(PPLL_REF_DIV) & PPLL_ATOMIC_UPDATE_R)
275 OUTPLLP(PPLL_REF_DIV, PPLL_ATOMIC_UPDATE_W, ~PPLL_ATOMIC_UPDATE_W);
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++)
285 OUTPLL(HTOTAL_CNTL, 0);
287 /* Clear reset & atomic update */
288 OUTPLLP(PPLL_CNTL, 0,
289 ~(PPLL_RESET | PPLL_SLEEP | PPLL_ATOMIC_UPDATE_EN | PPLL_VGA_ATOMIC_UPDATE_EN));
291 /* We may want some locking ... oh well */
294 /* Switch back VCLK source to PPLL */
295 OUTPLLP(VCLK_ECP_CNTL, VCLK_SRC_SEL_PPLLCLK, ~VCLK_SRC_SEL_MASK);
303 #if 0 /* unused ? -> scheduled for removal */
304 /* these common regs are cleared before mode setting so they do not
305 * interfere with anything
307 static reg_val common_regs[] = {
309 { OVR_WID_LEFT_RIGHT, 0 },
310 { OVR_WID_TOP_BOTTOM, 0 },
311 { OV0_SCALE_CNTL, 0 },
316 { CAP0_TRIG_CNTL, 0 },
317 { CAP1_TRIG_CNTL, 0 },
321 void radeon_setmode(void)
323 struct radeon_regs *mode = malloc(sizeof(struct radeon_regs));
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;
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);
346 mode->clk_cntl_index = 0x300;
347 mode->ppll_ref_div = 0xc;
348 mode->ppll_div_3 = 0x00030059;
350 radeon_write_pll_regs(rinfo, mode);
353 static void set_pal(void)
357 for (idx = 0; idx < 256; idx++) {
358 OUTREG8(PALETTE_INDEX, idx);
359 OUTREG(PALETTE_DATA, val);
364 void radeon_setmode_9200(int vesa_idx, int bpp)
366 struct radeon_regs *mode = malloc(sizeof(struct radeon_regs));
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;
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;
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;
389 mode->crtc_gen_cntl |= 0x2 << 8; /* palette */
390 mode->surface_cntl = 0x00000000;
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;
407 * for this mode pitch expands to the same value for 32, 16 and 8 bpp,
408 * so we set it here once only.
410 mode->crtc_pitch = RADEON_CRT_PITCH(1280,32);
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);
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);
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);
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;
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;
440 /* also same pitch value for 32, 16 and 8 bpp */
441 mode->crtc_pitch = RADEON_CRT_PITCH(1024,32);
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);
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);
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);
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;
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;
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);
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);
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);
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;
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;
502 /* also same pitch value for 32, 16 and 8 bpp */
503 mode->crtc_pitch = RADEON_CRT_PITCH(640,32);
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);
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);
514 mode->crtc_offset_cntl = 0x00000000;
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);
533 mode->clk_cntl_index = 0x300;
534 mode->ppll_ref_div = 0xc;
536 radeon_write_pll_regs(rinfo, mode);
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);
551 #include "../bios_emulator/include/biosemu.h"
552 extern int BootVideoCardBIOS(pci_dev_t pcidev, BE_VGAInfo ** pVGAInfo, int cleanUp);
554 int radeon_probe(struct radeonfb_info *rinfo)
559 pdev = pci_find_devices(ati_radeon_pci_ids, 0);
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);
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;
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))
590 * (These will be added in the future for the chipfamily
591 * R300, RV200, RS200, RV100, RS100.)
594 /* Get VRAM size and type */
595 radeon_identify_vram(rinfo);
597 rinfo->mapped_vram = min_t(unsigned long, MAX_MAPPED_VRAM,
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);
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 */
623 void *video_hw_init(void)
625 GraphicDevice *pGD = (GraphicDevice *) & ctfb;
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;
633 rinfo = malloc(sizeof(struct radeonfb_info));
636 if(radeon_probe(rinfo)) {
637 printf("No radeon video card found!\n");
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);
655 /* parameter are vesa modes */
657 for (i = 0; i < VESA_MODES_COUNT; i++) {
658 if (vesa_modes[i].vesanr == videomode)
661 if (i == VESA_MODES_COUNT) {
662 printf ("no VESA Mode found, switching to mode 0x%x ", CONFIG_SYS_DEFAULT_VIDEO_MODE);
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;
669 res_mode = (struct ctfb_res_modes *) &var_mode;
670 bits_per_pixel = video_get_params (res_mode, penv);
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;
677 t1 *= res_mode->pixclock;
679 hsynch = 1000000000L / t1;
680 t1 *= (res_mode->upper_margin + res_mode->yres +
681 res_mode->lower_margin + res_mode->vsync_len);
683 vsynch = 1000000000L / t1;
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),
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;
695 switch (bits_per_pixel) {
698 pGD->gdfIndex = GDF_32BIT_X888RGB;
699 if (res_mode->xres == 800) {
706 pGD->gdfIndex = GDF_16BIT_565RGB;
707 if (res_mode->xres == 800) {
713 if (res_mode->xres == 800) {
714 pGD->winSizeX = 1024;
715 pGD->plnSizeX = 1024;
718 pGD->gdfIndex = GDF__8BIT_INDEX;
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;
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) {
732 pGD->dprBase &= 0xfffff000;
733 pGD->dprBase += 0x00001000;
735 DPRINT ("Cursor Start %x Pattern Start %x\n", pGD->dprBase,
737 pGD->vprBase = (unsigned int)rinfo->fb_base; /* Dummy */
738 pGD->cprBase = (unsigned int)rinfo->fb_base; /* Dummy */
739 /* set up Hardware */
741 /* Clear video memory (only visible screen area) */
742 i = pGD->winSizeX * pGD->winSizeY * pGD->gdfBytesPP / 4;
743 vm = (unsigned int *) pGD->pciBase;
746 /*SetDrawingEngine (bits_per_pixel);*/
748 if (rinfo->family == CHIP_FAMILY_RV280)
749 radeon_setmode_9200(vesa_idx, bits_per_pixel);
753 return ((void *) pGD);
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 */
762 OUTREG(PALETTE_INDEX, index);
763 OUTREG(PALETTE_DATA, (r << 16) | (g << 8) | b);