1 // SPDX-License-Identifier: GPL-2.0+
3 * ATI Radeon Video card Framebuffer driver.
5 * Copyright 2007 Freescale Semiconductor, Inc.
9 * Some codes of this file is partly ported from Linux kernel
10 * ATI video framebuffer driver.
12 * Now the driver is tested on below ATI chips:
19 #include <linux/delay.h>
22 #include <bios_emul.h>
25 #include <asm/processor.h>
26 #include <linux/errno.h>
30 #include "videomodes.h"
34 #include "ati_radeon_fb.h"
39 #define DPRINT(x...) printf(x)
41 #define DPRINT(x...) do{}while(0)
44 #define MAX_MAPPED_VRAM (2048*2048*4)
45 #define MIN_MAPPED_VRAM (1024*768*1)
47 #define RADEON_BUFFER_ALIGN 0x00000fff
48 #define SURF_UPPER_BOUND(x,y,bpp) (((((x) * (((y) + 15) & ~15) * (bpp)/8) + RADEON_BUFFER_ALIGN) \
49 & ~RADEON_BUFFER_ALIGN) - 1)
50 #define RADEON_CRT_PITCH(width, bpp) ((((width) * (bpp) + ((bpp) * 8 - 1)) / ((bpp) * 8)) | \
51 ((((width) * (bpp) + ((bpp) * 8 - 1)) / ((bpp) * 8)) << 16))
53 #define CRTC_H_TOTAL_DISP_VAL(htotal, hdisp) \
54 (((((htotal) / 8) - 1) & 0x3ff) | (((((hdisp) / 8) - 1) & 0x1ff) << 16))
55 #define CRTC_HSYNC_STRT_WID_VAL(hsync_srtr, hsync_wid) \
56 (((hsync_srtr) & 0x1fff) | (((hsync_wid) & 0x3f) << 16))
57 #define CRTC_V_TOTAL_DISP_VAL(vtotal, vdisp) \
58 ((((vtotal) - 1) & 0xffff) | (((vdisp) - 1) << 16))
59 #define CRTC_VSYNC_STRT_WID_VAL(vsync_srtr, vsync_wid) \
60 ((((vsync_srtr) - 1) & 0xfff) | (((vsync_wid) & 0x1f) << 16))
62 /*#define PCI_VENDOR_ID_ATI*/
63 #define PCI_CHIP_RV280_5960 0x5960
64 #define PCI_CHIP_RV280_5961 0x5961
65 #define PCI_CHIP_RV280_5962 0x5962
66 #define PCI_CHIP_RV280_5964 0x5964
67 #define PCI_CHIP_RV280_5C63 0x5C63
68 #define PCI_CHIP_RV370_5B60 0x5B60
69 #define PCI_CHIP_RV380_5657 0x5657
70 #define PCI_CHIP_R420_554d 0x554d
72 static struct pci_device_id ati_radeon_pci_ids[] = {
73 {PCI_VENDOR_ID_ATI, PCI_CHIP_RV280_5960},
74 {PCI_VENDOR_ID_ATI, PCI_CHIP_RV280_5961},
75 {PCI_VENDOR_ID_ATI, PCI_CHIP_RV280_5962},
76 {PCI_VENDOR_ID_ATI, PCI_CHIP_RV280_5964},
77 {PCI_VENDOR_ID_ATI, PCI_CHIP_RV280_5C63},
78 {PCI_VENDOR_ID_ATI, PCI_CHIP_RV370_5B60},
79 {PCI_VENDOR_ID_ATI, PCI_CHIP_RV380_5657},
80 {PCI_VENDOR_ID_ATI, PCI_CHIP_R420_554d},
84 static u16 ati_radeon_id_family_table[][2] = {
85 {PCI_CHIP_RV280_5960, CHIP_FAMILY_RV280},
86 {PCI_CHIP_RV280_5961, CHIP_FAMILY_RV280},
87 {PCI_CHIP_RV280_5962, CHIP_FAMILY_RV280},
88 {PCI_CHIP_RV280_5964, CHIP_FAMILY_RV280},
89 {PCI_CHIP_RV280_5C63, CHIP_FAMILY_RV280},
90 {PCI_CHIP_RV370_5B60, CHIP_FAMILY_RV380},
91 {PCI_CHIP_RV380_5657, CHIP_FAMILY_RV380},
92 {PCI_CHIP_R420_554d, CHIP_FAMILY_R420},
96 u16 get_radeon_id_family(u16 device)
99 for (i=0; ati_radeon_id_family_table[0][i]; i+=2)
100 if (ati_radeon_id_family_table[0][i] == device)
101 return ati_radeon_id_family_table[0][i + 1];
105 struct radeonfb_info *rinfo;
107 static void radeon_identify_vram(struct radeonfb_info *rinfo)
111 /* framebuffer size */
112 if ((rinfo->family == CHIP_FAMILY_RS100) ||
113 (rinfo->family == CHIP_FAMILY_RS200) ||
114 (rinfo->family == CHIP_FAMILY_RS300)) {
115 u32 tom = INREG(NB_TOM);
116 tmp = ((((tom >> 16) - (tom & 0xffff) + 1) << 6) * 1024);
119 OUTREG(MC_FB_LOCATION, tom);
120 OUTREG(DISPLAY_BASE_ADDR, (tom & 0xffff) << 16);
121 OUTREG(CRTC2_DISPLAY_BASE_ADDR, (tom & 0xffff) << 16);
122 OUTREG(OV0_BASE_ADDR, (tom & 0xffff) << 16);
124 /* This is supposed to fix the crtc2 noise problem. */
125 OUTREG(GRPH2_BUFFER_CNTL, INREG(GRPH2_BUFFER_CNTL) & ~0x7f0000);
127 if ((rinfo->family == CHIP_FAMILY_RS100) ||
128 (rinfo->family == CHIP_FAMILY_RS200)) {
129 /* This is to workaround the asic bug for RMX, some versions
130 of BIOS dosen't have this register initialized correctly.
132 OUTREGP(CRTC_MORE_CNTL, CRTC_H_CUTOFF_ACTIVE_EN,
133 ~CRTC_H_CUTOFF_ACTIVE_EN);
136 tmp = INREG(CONFIG_MEMSIZE);
139 /* mem size is bits [28:0], mask off the rest */
140 rinfo->video_ram = tmp & CONFIG_MEMSIZE_MASK;
143 * Hack to get around some busted production M6's
146 if (rinfo->video_ram == 0) {
147 switch (rinfo->pdev.device) {
148 case PCI_CHIP_RADEON_LY:
149 case PCI_CHIP_RADEON_LZ:
150 rinfo->video_ram = 8192 * 1024;
158 * Now try to identify VRAM type
160 if ((rinfo->family >= CHIP_FAMILY_R300) ||
161 (INREG(MEM_SDRAM_MODE_REG) & (1<<30)))
166 tmp = INREG(MEM_CNTL);
167 if (IS_R300_VARIANT(rinfo)) {
168 tmp &= R300_MEM_NUM_CHANNELS_MASK;
170 case 0: rinfo->vram_width = 64; break;
171 case 1: rinfo->vram_width = 128; break;
172 case 2: rinfo->vram_width = 256; break;
173 default: rinfo->vram_width = 128; break;
175 } else if ((rinfo->family == CHIP_FAMILY_RV100) ||
176 (rinfo->family == CHIP_FAMILY_RS100) ||
177 (rinfo->family == CHIP_FAMILY_RS200)){
178 if (tmp & RV100_MEM_HALF_MODE)
179 rinfo->vram_width = 32;
181 rinfo->vram_width = 64;
183 if (tmp & MEM_NUM_CHANNELS_MASK)
184 rinfo->vram_width = 128;
186 rinfo->vram_width = 64;
189 /* This may not be correct, as some cards can have half of channel disabled
190 * ToDo: identify these cases
193 DPRINT("radeonfb: Found %dk of %s %d bits wide videoram\n",
194 rinfo->video_ram / 1024,
195 rinfo->vram_ddr ? "DDR" : "SDRAM",
200 static void radeon_write_pll_regs(struct radeonfb_info *rinfo, struct radeon_regs *mode)
204 radeon_fifo_wait(20);
207 /* Workaround from XFree */
208 if (rinfo->is_mobility) {
209 /* A temporal workaround for the occational blanking on certain laptop
210 * panels. This appears to related to the PLL divider registers
211 * (fail to lock?). It occurs even when all dividers are the same
212 * with their old settings. In this case we really don't need to
213 * fiddle with PLL registers. By doing this we can avoid the blanking
214 * problem with some panels.
216 if ((mode->ppll_ref_div == (INPLL(PPLL_REF_DIV) & PPLL_REF_DIV_MASK)) &&
217 (mode->ppll_div_3 == (INPLL(PPLL_DIV_3) &
218 (PPLL_POST3_DIV_MASK | PPLL_FB3_DIV_MASK)))) {
219 /* We still have to force a switch to selected PPLL div thanks to
220 * an XFree86 driver bug which will switch it away in some cases
221 * even when using UseFDev */
222 OUTREGP(CLOCK_CNTL_INDEX,
223 mode->clk_cntl_index & PPLL_DIV_SEL_MASK,
225 radeon_pll_errata_after_index(rinfo);
226 radeon_pll_errata_after_data(rinfo);
231 if(rinfo->pdev.device == PCI_CHIP_RV370_5B60) return;
233 /* Swich VCKL clock input to CPUCLK so it stays fed while PPLL updates*/
234 OUTPLLP(VCLK_ECP_CNTL, VCLK_SRC_SEL_CPUCLK, ~VCLK_SRC_SEL_MASK);
236 /* Reset PPLL & enable atomic update */
238 PPLL_RESET | PPLL_ATOMIC_UPDATE_EN | PPLL_VGA_ATOMIC_UPDATE_EN,
239 ~(PPLL_RESET | PPLL_ATOMIC_UPDATE_EN | PPLL_VGA_ATOMIC_UPDATE_EN));
241 /* Switch to selected PPLL divider */
242 OUTREGP(CLOCK_CNTL_INDEX,
243 mode->clk_cntl_index & PPLL_DIV_SEL_MASK,
246 /* Set PPLL ref. div */
247 if (rinfo->family == CHIP_FAMILY_R300 ||
248 rinfo->family == CHIP_FAMILY_RS300 ||
249 rinfo->family == CHIP_FAMILY_R350 ||
250 rinfo->family == CHIP_FAMILY_RV350) {
251 if (mode->ppll_ref_div & R300_PPLL_REF_DIV_ACC_MASK) {
252 /* When restoring console mode, use saved PPLL_REF_DIV
255 OUTPLLP(PPLL_REF_DIV, mode->ppll_ref_div, 0);
257 /* R300 uses ref_div_acc field as real ref divider */
258 OUTPLLP(PPLL_REF_DIV,
259 (mode->ppll_ref_div << R300_PPLL_REF_DIV_ACC_SHIFT),
260 ~R300_PPLL_REF_DIV_ACC_MASK);
263 OUTPLLP(PPLL_REF_DIV, mode->ppll_ref_div, ~PPLL_REF_DIV_MASK);
265 /* Set PPLL divider 3 & post divider*/
266 OUTPLLP(PPLL_DIV_3, mode->ppll_div_3, ~PPLL_FB3_DIV_MASK);
267 OUTPLLP(PPLL_DIV_3, mode->ppll_div_3, ~PPLL_POST3_DIV_MASK);
270 while (INPLL(PPLL_REF_DIV) & PPLL_ATOMIC_UPDATE_R)
272 OUTPLLP(PPLL_REF_DIV, PPLL_ATOMIC_UPDATE_W, ~PPLL_ATOMIC_UPDATE_W);
274 /* Wait read update complete */
275 /* FIXME: Certain revisions of R300 can't recover here. Not sure of
276 the cause yet, but this workaround will mask the problem for now.
277 Other chips usually will pass at the very first test, so the
278 workaround shouldn't have any effect on them. */
279 for (i = 0; (i < 10000 && INPLL(PPLL_REF_DIV) & PPLL_ATOMIC_UPDATE_R); i++)
282 OUTPLL(HTOTAL_CNTL, 0);
284 /* Clear reset & atomic update */
285 OUTPLLP(PPLL_CNTL, 0,
286 ~(PPLL_RESET | PPLL_SLEEP | PPLL_ATOMIC_UPDATE_EN | PPLL_VGA_ATOMIC_UPDATE_EN));
288 /* We may want some locking ... oh well */
291 /* Switch back VCLK source to PPLL */
292 OUTPLLP(VCLK_ECP_CNTL, VCLK_SRC_SEL_PPLLCLK, ~VCLK_SRC_SEL_MASK);
300 #if 0 /* unused ? -> scheduled for removal */
301 /* these common regs are cleared before mode setting so they do not
302 * interfere with anything
304 static reg_val common_regs[] = {
306 { OVR_WID_LEFT_RIGHT, 0 },
307 { OVR_WID_TOP_BOTTOM, 0 },
308 { OV0_SCALE_CNTL, 0 },
313 { CAP0_TRIG_CNTL, 0 },
314 { CAP1_TRIG_CNTL, 0 },
318 void radeon_setmode(void)
320 struct radeon_regs *mode = malloc(sizeof(struct radeon_regs));
322 mode->crtc_gen_cntl = 0x03000200;
323 mode->crtc_ext_cntl = 0x00008048;
324 mode->dac_cntl = 0xff002100;
325 mode->crtc_h_total_disp = 0x4f0063;
326 mode->crtc_h_sync_strt_wid = 0x8c02a2;
327 mode->crtc_v_total_disp = 0x01df020c;
328 mode->crtc_v_sync_strt_wid = 0x8201ea;
329 mode->crtc_pitch = 0x00500050;
331 OUTREG(CRTC_GEN_CNTL, mode->crtc_gen_cntl);
332 OUTREGP(CRTC_EXT_CNTL, mode->crtc_ext_cntl,
333 ~(CRTC_HSYNC_DIS | CRTC_VSYNC_DIS | CRTC_DISPLAY_DIS));
334 OUTREGP(DAC_CNTL, mode->dac_cntl, DAC_RANGE_CNTL | DAC_BLANKING);
335 OUTREG(CRTC_H_TOTAL_DISP, mode->crtc_h_total_disp);
336 OUTREG(CRTC_H_SYNC_STRT_WID, mode->crtc_h_sync_strt_wid);
337 OUTREG(CRTC_V_TOTAL_DISP, mode->crtc_v_total_disp);
338 OUTREG(CRTC_V_SYNC_STRT_WID, mode->crtc_v_sync_strt_wid);
339 OUTREG(CRTC_OFFSET, 0);
340 OUTREG(CRTC_OFFSET_CNTL, 0);
341 OUTREG(CRTC_PITCH, mode->crtc_pitch);
343 mode->clk_cntl_index = 0x300;
344 mode->ppll_ref_div = 0xc;
345 mode->ppll_div_3 = 0x00030059;
347 radeon_write_pll_regs(rinfo, mode);
350 static void set_pal(void)
354 for (idx = 0; idx < 256; idx++) {
355 OUTREG8(PALETTE_INDEX, idx);
356 OUTREG(PALETTE_DATA, val);
361 void radeon_setmode_9200(int vesa_idx, int bpp)
363 struct radeon_regs *mode = malloc(sizeof(struct radeon_regs));
365 mode->crtc_gen_cntl = CRTC_EN | CRTC_EXT_DISP_EN;
366 mode->crtc_ext_cntl = VGA_ATI_LINEAR | XCRT_CNT_EN | CRTC_CRT_ON;
367 mode->dac_cntl = DAC_MASK_ALL | DAC_VGA_ADR_EN | DAC_8BIT_EN;
368 mode->crtc_offset_cntl = CRTC_OFFSET_CNTL__CRTC_TILE_EN;
372 mode->crtc_gen_cntl |= 0x6 << 8; /* x888 */
373 #if defined(__BIG_ENDIAN)
374 mode->surface_cntl = NONSURF_AP0_SWP_32BPP | NONSURF_AP1_SWP_32BPP;
375 mode->surf_info[0] = NONSURF_AP0_SWP_32BPP | NONSURF_AP1_SWP_32BPP;
379 mode->crtc_gen_cntl |= 0x4 << 8; /* 565 */
380 #if defined(__BIG_ENDIAN)
381 mode->surface_cntl = NONSURF_AP0_SWP_16BPP | NONSURF_AP1_SWP_16BPP;
382 mode->surf_info[0] = NONSURF_AP0_SWP_16BPP | NONSURF_AP1_SWP_16BPP;
386 mode->crtc_gen_cntl |= 0x2 << 8; /* palette */
387 mode->surface_cntl = 0x00000000;
392 case RES_MODE_1280x1024:
393 mode->crtc_h_total_disp = CRTC_H_TOTAL_DISP_VAL(1688,1280);
394 mode->crtc_v_total_disp = CRTC_V_TOTAL_DISP_VAL(1066,1024);
395 mode->crtc_v_sync_strt_wid = CRTC_VSYNC_STRT_WID_VAL(1025,3);
396 #if defined(CONFIG_RADEON_VREFRESH_75HZ)
397 mode->crtc_h_sync_strt_wid = CRTC_HSYNC_STRT_WID_VAL(1288,18);
398 mode->ppll_div_3 = 0x00010078;
399 #else /* default @ 60 Hz */
400 mode->crtc_h_sync_strt_wid = CRTC_HSYNC_STRT_WID_VAL(1320,14);
401 mode->ppll_div_3 = 0x00010060;
404 * for this mode pitch expands to the same value for 32, 16 and 8 bpp,
405 * so we set it here once only.
407 mode->crtc_pitch = RADEON_CRT_PITCH(1280,32);
410 mode->surf_info[0] |= R200_SURF_TILE_COLOR_MACRO | (1280 * 4 / 16);
411 mode->surf_upper_bound[0] = SURF_UPPER_BOUND(1280,1024,32);
414 mode->surf_info[0] |= R200_SURF_TILE_COLOR_MACRO | (1280 * 2 / 16);
415 mode->surf_upper_bound[0] = SURF_UPPER_BOUND(1280,1024,16);
418 mode->surf_info[0] = R200_SURF_TILE_COLOR_MACRO | (1280 * 1 / 16);
419 mode->surf_upper_bound[0] = SURF_UPPER_BOUND(1280,1024,8);
423 case RES_MODE_1024x768:
424 #if defined(CONFIG_RADEON_VREFRESH_75HZ)
425 mode->crtc_h_total_disp = CRTC_H_TOTAL_DISP_VAL(1312,1024);
426 mode->crtc_h_sync_strt_wid = CRTC_HSYNC_STRT_WID_VAL(1032,12);
427 mode->crtc_v_total_disp = CRTC_V_TOTAL_DISP_VAL(800,768);
428 mode->crtc_v_sync_strt_wid = CRTC_VSYNC_STRT_WID_VAL(769,3);
429 mode->ppll_div_3 = 0x0002008c;
431 mode->crtc_h_total_disp = CRTC_H_TOTAL_DISP_VAL(1344,1024);
432 mode->crtc_h_sync_strt_wid = CRTC_HSYNC_STRT_WID_VAL(1040,17) | CRTC_H_SYNC_POL;
433 mode->crtc_v_total_disp = CRTC_V_TOTAL_DISP_VAL(806,768);
434 mode->crtc_v_sync_strt_wid = CRTC_VSYNC_STRT_WID_VAL(771,6) | CRTC_V_SYNC_POL;
435 mode->ppll_div_3 = 0x00020074;
437 /* also same pitch value for 32, 16 and 8 bpp */
438 mode->crtc_pitch = RADEON_CRT_PITCH(1024,32);
441 mode->surf_info[0] |= R200_SURF_TILE_COLOR_MACRO | (1024 * 4 / 16);
442 mode->surf_upper_bound[0] = SURF_UPPER_BOUND(1024,768,32);
445 mode->surf_info[0] |= R200_SURF_TILE_COLOR_MACRO | (1024 * 2 / 16);
446 mode->surf_upper_bound[0] = SURF_UPPER_BOUND(1024,768,16);
449 mode->surf_info[0] = R200_SURF_TILE_COLOR_MACRO | (1024 * 1 / 16);
450 mode->surf_upper_bound[0] = SURF_UPPER_BOUND(1024,768,8);
454 case RES_MODE_800x600:
455 mode->crtc_h_total_disp = CRTC_H_TOTAL_DISP_VAL(1056,800);
456 #if defined(CONFIG_RADEON_VREFRESH_75HZ)
457 mode->crtc_h_sync_strt_wid = CRTC_HSYNC_STRT_WID_VAL(808,10);
458 mode->crtc_v_total_disp = CRTC_V_TOTAL_DISP_VAL(625,600);
459 mode->crtc_v_sync_strt_wid = CRTC_VSYNC_STRT_WID_VAL(601,3);
460 mode->ppll_div_3 = 0x000300b0;
462 mode->crtc_h_sync_strt_wid = CRTC_HSYNC_STRT_WID_VAL(832,16);
463 mode->crtc_v_total_disp = CRTC_V_TOTAL_DISP_VAL(628,600);
464 mode->crtc_v_sync_strt_wid = CRTC_VSYNC_STRT_WID_VAL(601,4);
465 mode->ppll_div_3 = 0x0003008e;
469 mode->crtc_pitch = RADEON_CRT_PITCH(832,32);
470 mode->surf_info[0] |= R200_SURF_TILE_COLOR_MACRO | (832 * 4 / 16);
471 mode->surf_upper_bound[0] = SURF_UPPER_BOUND(832,600,32);
474 mode->crtc_pitch = RADEON_CRT_PITCH(896,16);
475 mode->surf_info[0] |= R200_SURF_TILE_COLOR_MACRO | (896 * 2 / 16);
476 mode->surf_upper_bound[0] = SURF_UPPER_BOUND(896,600,16);
479 mode->crtc_pitch = RADEON_CRT_PITCH(1024,8);
480 mode->surf_info[0] = R200_SURF_TILE_COLOR_MACRO | (1024 * 1 / 16);
481 mode->surf_upper_bound[0] = SURF_UPPER_BOUND(1024,600,8);
485 default: /* RES_MODE_640x480 */
486 #if defined(CONFIG_RADEON_VREFRESH_75HZ)
487 mode->crtc_h_total_disp = CRTC_H_TOTAL_DISP_VAL(840,640);
488 mode->crtc_h_sync_strt_wid = CRTC_HSYNC_STRT_WID_VAL(648,8) | CRTC_H_SYNC_POL;
489 mode->crtc_v_total_disp = CRTC_V_TOTAL_DISP_VAL(500,480);
490 mode->crtc_v_sync_strt_wid = CRTC_VSYNC_STRT_WID_VAL(481,3) | CRTC_V_SYNC_POL;
491 mode->ppll_div_3 = 0x00030070;
493 mode->crtc_h_total_disp = CRTC_H_TOTAL_DISP_VAL(800,640);
494 mode->crtc_h_sync_strt_wid = CRTC_HSYNC_STRT_WID_VAL(674,12) | CRTC_H_SYNC_POL;
495 mode->crtc_v_total_disp = CRTC_V_TOTAL_DISP_VAL(525,480);
496 mode->crtc_v_sync_strt_wid = CRTC_VSYNC_STRT_WID_VAL(491,2) | CRTC_V_SYNC_POL;
497 mode->ppll_div_3 = 0x00030059;
499 /* also same pitch value for 32, 16 and 8 bpp */
500 mode->crtc_pitch = RADEON_CRT_PITCH(640,32);
503 mode->surf_info[0] |= R200_SURF_TILE_COLOR_MACRO | (640 * 4 / 16);
504 mode->surf_upper_bound[0] = SURF_UPPER_BOUND(640,480,32);
507 mode->surf_info[0] |= R200_SURF_TILE_COLOR_MACRO | (640 * 2 / 16);
508 mode->surf_upper_bound[0] = SURF_UPPER_BOUND(640,480,16);
511 mode->crtc_offset_cntl = 0x00000000;
517 OUTREG(CRTC_GEN_CNTL, mode->crtc_gen_cntl | CRTC_DISP_REQ_EN_B);
518 OUTREGP(CRTC_EXT_CNTL, mode->crtc_ext_cntl,
519 (CRTC_HSYNC_DIS | CRTC_VSYNC_DIS | CRTC_DISPLAY_DIS));
520 OUTREGP(DAC_CNTL, mode->dac_cntl, DAC_RANGE_CNTL | DAC_BLANKING);
521 OUTREG(CRTC_H_TOTAL_DISP, mode->crtc_h_total_disp);
522 OUTREG(CRTC_H_SYNC_STRT_WID, mode->crtc_h_sync_strt_wid);
523 OUTREG(CRTC_V_TOTAL_DISP, mode->crtc_v_total_disp);
524 OUTREG(CRTC_V_SYNC_STRT_WID, mode->crtc_v_sync_strt_wid);
525 OUTREG(CRTC_OFFSET, 0);
526 OUTREG(CRTC_OFFSET_CNTL, mode->crtc_offset_cntl);
527 OUTREG(CRTC_PITCH, mode->crtc_pitch);
528 OUTREG(CRTC_GEN_CNTL, mode->crtc_gen_cntl);
530 mode->clk_cntl_index = 0x300;
531 mode->ppll_ref_div = 0xc;
533 radeon_write_pll_regs(rinfo, mode);
535 OUTREGP(CRTC_EXT_CNTL, mode->crtc_ext_cntl,
536 ~(CRTC_HSYNC_DIS | CRTC_VSYNC_DIS | CRTC_DISPLAY_DIS));
537 OUTREG(SURFACE0_INFO, mode->surf_info[0]);
538 OUTREG(SURFACE0_LOWER_BOUND, 0);
539 OUTREG(SURFACE0_UPPER_BOUND, mode->surf_upper_bound[0]);
540 OUTREG(SURFACE_CNTL, mode->surface_cntl);
548 #include "../bios_emulator/include/biosemu.h"
550 int radeon_probe(struct radeonfb_info *rinfo)
555 pdev = pci_find_devices(ati_radeon_pci_ids, 0);
558 pci_read_config_word(pdev, PCI_DEVICE_ID, &did);
559 printf("ATI Radeon video card (%04x, %04x) found @(%d:%d:%d)\n",
560 PCI_VENDOR_ID_ATI, did, (pdev >> 16) & 0xff,
561 (pdev >> 11) & 0x1f, (pdev >> 8) & 0x7);
563 strcpy(rinfo->name, "ATI Radeon");
564 rinfo->pdev.vendor = PCI_VENDOR_ID_ATI;
565 rinfo->pdev.device = did;
566 rinfo->family = get_radeon_id_family(rinfo->pdev.device);
567 pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0,
568 &rinfo->fb_base_bus);
569 pci_read_config_dword(pdev, PCI_BASE_ADDRESS_2,
570 &rinfo->mmio_base_bus);
571 rinfo->fb_base_bus &= 0xfffff000;
572 rinfo->mmio_base_bus &= ~0x04;
574 rinfo->mmio_base = pci_bus_to_virt(pdev, rinfo->mmio_base_bus,
575 PCI_REGION_MEM, 0, MAP_NOCACHE);
576 DPRINT("rinfo->mmio_base = 0x%p bus=0x%x\n",
577 rinfo->mmio_base, rinfo->mmio_base_bus);
578 rinfo->fb_local_base = INREG(MC_FB_LOCATION) << 16;
579 DPRINT("rinfo->fb_local_base = 0x%x\n",rinfo->fb_local_base);
580 /* PostBIOS with x86 emulater */
581 if (!BootVideoCardBIOS(pdev, NULL, 0))
586 * (These will be added in the future for the chipfamily
587 * R300, RV200, RS200, RV100, RS100.)
590 /* Get VRAM size and type */
591 radeon_identify_vram(rinfo);
593 rinfo->mapped_vram = min_t(unsigned long, MAX_MAPPED_VRAM,
595 rinfo->fb_base = pci_bus_to_virt(pdev, rinfo->fb_base_bus,
596 PCI_REGION_MEM, 0, MAP_NOCACHE);
597 DPRINT("Radeon: framebuffer base address 0x%08x, "
598 "bus address 0x%08x\n"
599 "MMIO base address 0x%08x, bus address 0x%08x, "
600 "framebuffer local base 0x%08x.\n ",
601 (u32)rinfo->fb_base, rinfo->fb_base_bus,
602 (u32)rinfo->mmio_base, rinfo->mmio_base_bus,
603 rinfo->fb_local_base);
614 #define CURSOR_SIZE 0x1000 /* in KByte for HW Cursor */
615 #define PATTERN_ADR (pGD->dprBase + CURSOR_SIZE) /* pattern Memory after Cursor Memory */
616 #define PATTERN_SIZE 8*8*4 /* 4 Bytes per Pixel 8 x 8 Pixel */
617 #define ACCELMEMORY (CURSOR_SIZE + PATTERN_SIZE) /* reserved Memory for BITBlt and hw cursor */
619 void *video_hw_init(void)
621 GraphicDevice *pGD = (GraphicDevice *) & ctfb;
624 unsigned long t1, hsynch, vsynch;
625 int bits_per_pixel, i, tmp, vesa_idx = 0, videomode;
626 struct ctfb_res_modes *res_mode;
627 struct ctfb_res_modes var_mode;
629 rinfo = malloc(sizeof(struct radeonfb_info));
632 if(radeon_probe(rinfo)) {
633 printf("No radeon video card found!\n");
639 videomode = CONFIG_SYS_DEFAULT_VIDEO_MODE;
640 /* get video mode via environment */
641 penv = env_get("videomode");
643 /* deceide if it is a string */
644 if (penv[0] <= '9') {
645 videomode = (int) simple_strtoul (penv, NULL, 16);
652 /* parameter are vesa modes */
654 for (i = 0; i < VESA_MODES_COUNT; i++) {
655 if (vesa_modes[i].vesanr == videomode)
658 if (i == VESA_MODES_COUNT) {
659 printf ("no VESA Mode found, switching to mode 0x%x ", CONFIG_SYS_DEFAULT_VIDEO_MODE);
662 res_mode = (struct ctfb_res_modes *) &res_mode_init[vesa_modes[i].resindex];
663 bits_per_pixel = vesa_modes[i].bits_per_pixel;
664 vesa_idx = vesa_modes[i].resindex;
666 res_mode = (struct ctfb_res_modes *) &var_mode;
667 bits_per_pixel = video_get_params (res_mode, penv);
670 /* calculate hsynch and vsynch freq (info only) */
671 t1 = (res_mode->left_margin + res_mode->xres +
672 res_mode->right_margin + res_mode->hsync_len) / 8;
674 t1 *= res_mode->pixclock;
676 hsynch = 1000000000L / t1;
677 t1 *= (res_mode->upper_margin + res_mode->yres +
678 res_mode->lower_margin + res_mode->vsync_len);
680 vsynch = 1000000000L / t1;
682 /* fill in Graphic device struct */
683 sprintf (pGD->modeIdent, "%dx%dx%d %ldkHz %ldHz", res_mode->xres,
684 res_mode->yres, bits_per_pixel, (hsynch / 1000),
686 printf ("%s\n", pGD->modeIdent);
687 pGD->winSizeX = res_mode->xres;
688 pGD->winSizeY = res_mode->yres;
689 pGD->plnSizeX = res_mode->xres;
690 pGD->plnSizeY = res_mode->yres;
692 switch (bits_per_pixel) {
695 pGD->gdfIndex = GDF_32BIT_X888RGB;
696 if (res_mode->xres == 800) {
703 pGD->gdfIndex = GDF_16BIT_565RGB;
704 if (res_mode->xres == 800) {
710 if (res_mode->xres == 800) {
711 pGD->winSizeX = 1024;
712 pGD->plnSizeX = 1024;
715 pGD->gdfIndex = GDF__8BIT_INDEX;
719 pGD->isaBase = CONFIG_SYS_ISA_IO_BASE_ADDRESS;
720 pGD->pciBase = (unsigned int)rinfo->fb_base;
721 pGD->frameAdrs = (unsigned int)rinfo->fb_base;
722 pGD->memSize = 64 * 1024 * 1024;
724 /* Cursor Start Address */
725 pGD->dprBase = (pGD->winSizeX * pGD->winSizeY * pGD->gdfBytesPP) +
726 (unsigned int)rinfo->fb_base;
727 if ((pGD->dprBase & 0x0fff) != 0) {
729 pGD->dprBase &= 0xfffff000;
730 pGD->dprBase += 0x00001000;
732 DPRINT ("Cursor Start %x Pattern Start %x\n", pGD->dprBase,
734 pGD->vprBase = (unsigned int)rinfo->fb_base; /* Dummy */
735 pGD->cprBase = (unsigned int)rinfo->fb_base; /* Dummy */
736 /* set up Hardware */
738 /* Clear video memory (only visible screen area) */
739 i = pGD->winSizeX * pGD->winSizeY * pGD->gdfBytesPP / 4;
740 vm = (unsigned int *) pGD->pciBase;
743 /*SetDrawingEngine (bits_per_pixel);*/
745 if (rinfo->family == CHIP_FAMILY_RV280)
746 radeon_setmode_9200(vesa_idx, bits_per_pixel);
750 return ((void *) pGD);
753 void video_set_lut (unsigned int index, /* color number */
754 unsigned char r, /* red */
755 unsigned char g, /* green */
756 unsigned char b /* blue */
759 OUTREG(PALETTE_INDEX, index);
760 OUTREG(PALETTE_DATA, (r << 16) | (g << 8) | b);