2 * ATI Radeon Video card Framebuffer driver.
4 * Copyright 2007 Freescale Semiconductor, Inc.
5 * Zhang Wei <wei.zhang@freescale.com>
6 * Jason Jin <jason.jin@freescale.com>
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:
22 #include <bios_emul.h>
24 #include <asm/processor.h>
25 #include <linux/errno.h>
29 #include "videomodes.h"
33 #include "ati_radeon_fb.h"
38 #define DPRINT(x...) printf(x)
40 #define DPRINT(x...) do{}while(0)
43 #define MAX_MAPPED_VRAM (2048*2048*4)
44 #define MIN_MAPPED_VRAM (1024*768*1)
46 #define RADEON_BUFFER_ALIGN 0x00000fff
47 #define SURF_UPPER_BOUND(x,y,bpp) (((((x) * (((y) + 15) & ~15) * (bpp)/8) + RADEON_BUFFER_ALIGN) \
48 & ~RADEON_BUFFER_ALIGN) - 1)
49 #define RADEON_CRT_PITCH(width, bpp) ((((width) * (bpp) + ((bpp) * 8 - 1)) / ((bpp) * 8)) | \
50 ((((width) * (bpp) + ((bpp) * 8 - 1)) / ((bpp) * 8)) << 16))
52 #define CRTC_H_TOTAL_DISP_VAL(htotal, hdisp) \
53 (((((htotal) / 8) - 1) & 0x3ff) | (((((hdisp) / 8) - 1) & 0x1ff) << 16))
54 #define CRTC_HSYNC_STRT_WID_VAL(hsync_srtr, hsync_wid) \
55 (((hsync_srtr) & 0x1fff) | (((hsync_wid) & 0x3f) << 16))
56 #define CRTC_V_TOTAL_DISP_VAL(vtotal, vdisp) \
57 ((((vtotal) - 1) & 0xffff) | (((vdisp) - 1) << 16))
58 #define CRTC_VSYNC_STRT_WID_VAL(vsync_srtr, vsync_wid) \
59 ((((vsync_srtr) - 1) & 0xfff) | (((vsync_wid) & 0x1f) << 16))
61 /*#define PCI_VENDOR_ID_ATI*/
62 #define PCI_CHIP_RV280_5960 0x5960
63 #define PCI_CHIP_RV280_5961 0x5961
64 #define PCI_CHIP_RV280_5962 0x5962
65 #define PCI_CHIP_RV280_5964 0x5964
66 #define PCI_CHIP_RV280_5C63 0x5C63
67 #define PCI_CHIP_RV370_5B60 0x5B60
68 #define PCI_CHIP_RV380_5657 0x5657
69 #define PCI_CHIP_R420_554d 0x554d
71 static struct pci_device_id ati_radeon_pci_ids[] = {
72 {PCI_VENDOR_ID_ATI, PCI_CHIP_RV280_5960},
73 {PCI_VENDOR_ID_ATI, PCI_CHIP_RV280_5961},
74 {PCI_VENDOR_ID_ATI, PCI_CHIP_RV280_5962},
75 {PCI_VENDOR_ID_ATI, PCI_CHIP_RV280_5964},
76 {PCI_VENDOR_ID_ATI, PCI_CHIP_RV280_5C63},
77 {PCI_VENDOR_ID_ATI, PCI_CHIP_RV370_5B60},
78 {PCI_VENDOR_ID_ATI, PCI_CHIP_RV380_5657},
79 {PCI_VENDOR_ID_ATI, PCI_CHIP_R420_554d},
83 static u16 ati_radeon_id_family_table[][2] = {
84 {PCI_CHIP_RV280_5960, CHIP_FAMILY_RV280},
85 {PCI_CHIP_RV280_5961, CHIP_FAMILY_RV280},
86 {PCI_CHIP_RV280_5962, CHIP_FAMILY_RV280},
87 {PCI_CHIP_RV280_5964, CHIP_FAMILY_RV280},
88 {PCI_CHIP_RV280_5C63, CHIP_FAMILY_RV280},
89 {PCI_CHIP_RV370_5B60, CHIP_FAMILY_RV380},
90 {PCI_CHIP_RV380_5657, CHIP_FAMILY_RV380},
91 {PCI_CHIP_R420_554d, CHIP_FAMILY_R420},
95 u16 get_radeon_id_family(u16 device)
98 for (i=0; ati_radeon_id_family_table[0][i]; i+=2)
99 if (ati_radeon_id_family_table[0][i] == device)
100 return ati_radeon_id_family_table[0][i + 1];
104 struct radeonfb_info *rinfo;
106 static void radeon_identify_vram(struct radeonfb_info *rinfo)
110 /* framebuffer size */
111 if ((rinfo->family == CHIP_FAMILY_RS100) ||
112 (rinfo->family == CHIP_FAMILY_RS200) ||
113 (rinfo->family == CHIP_FAMILY_RS300)) {
114 u32 tom = INREG(NB_TOM);
115 tmp = ((((tom >> 16) - (tom & 0xffff) + 1) << 6) * 1024);
118 OUTREG(MC_FB_LOCATION, tom);
119 OUTREG(DISPLAY_BASE_ADDR, (tom & 0xffff) << 16);
120 OUTREG(CRTC2_DISPLAY_BASE_ADDR, (tom & 0xffff) << 16);
121 OUTREG(OV0_BASE_ADDR, (tom & 0xffff) << 16);
123 /* This is supposed to fix the crtc2 noise problem. */
124 OUTREG(GRPH2_BUFFER_CNTL, INREG(GRPH2_BUFFER_CNTL) & ~0x7f0000);
126 if ((rinfo->family == CHIP_FAMILY_RS100) ||
127 (rinfo->family == CHIP_FAMILY_RS200)) {
128 /* This is to workaround the asic bug for RMX, some versions
129 of BIOS dosen't have this register initialized correctly.
131 OUTREGP(CRTC_MORE_CNTL, CRTC_H_CUTOFF_ACTIVE_EN,
132 ~CRTC_H_CUTOFF_ACTIVE_EN);
135 tmp = INREG(CONFIG_MEMSIZE);
138 /* mem size is bits [28:0], mask off the rest */
139 rinfo->video_ram = tmp & CONFIG_MEMSIZE_MASK;
142 * Hack to get around some busted production M6's
145 if (rinfo->video_ram == 0) {
146 switch (rinfo->pdev.device) {
147 case PCI_CHIP_RADEON_LY:
148 case PCI_CHIP_RADEON_LZ:
149 rinfo->video_ram = 8192 * 1024;
157 * Now try to identify VRAM type
159 if ((rinfo->family >= CHIP_FAMILY_R300) ||
160 (INREG(MEM_SDRAM_MODE_REG) & (1<<30)))
165 tmp = INREG(MEM_CNTL);
166 if (IS_R300_VARIANT(rinfo)) {
167 tmp &= R300_MEM_NUM_CHANNELS_MASK;
169 case 0: rinfo->vram_width = 64; break;
170 case 1: rinfo->vram_width = 128; break;
171 case 2: rinfo->vram_width = 256; break;
172 default: rinfo->vram_width = 128; break;
174 } else if ((rinfo->family == CHIP_FAMILY_RV100) ||
175 (rinfo->family == CHIP_FAMILY_RS100) ||
176 (rinfo->family == CHIP_FAMILY_RS200)){
177 if (tmp & RV100_MEM_HALF_MODE)
178 rinfo->vram_width = 32;
180 rinfo->vram_width = 64;
182 if (tmp & MEM_NUM_CHANNELS_MASK)
183 rinfo->vram_width = 128;
185 rinfo->vram_width = 64;
188 /* This may not be correct, as some cards can have half of channel disabled
189 * ToDo: identify these cases
192 DPRINT("radeonfb: Found %dk of %s %d bits wide videoram\n",
193 rinfo->video_ram / 1024,
194 rinfo->vram_ddr ? "DDR" : "SDRAM",
199 static void radeon_write_pll_regs(struct radeonfb_info *rinfo, struct radeon_regs *mode)
203 radeon_fifo_wait(20);
206 /* Workaround from XFree */
207 if (rinfo->is_mobility) {
208 /* A temporal workaround for the occational blanking on certain laptop
209 * panels. This appears to related to the PLL divider registers
210 * (fail to lock?). It occurs even when all dividers are the same
211 * with their old settings. In this case we really don't need to
212 * fiddle with PLL registers. By doing this we can avoid the blanking
213 * problem with some panels.
215 if ((mode->ppll_ref_div == (INPLL(PPLL_REF_DIV) & PPLL_REF_DIV_MASK)) &&
216 (mode->ppll_div_3 == (INPLL(PPLL_DIV_3) &
217 (PPLL_POST3_DIV_MASK | PPLL_FB3_DIV_MASK)))) {
218 /* We still have to force a switch to selected PPLL div thanks to
219 * an XFree86 driver bug which will switch it away in some cases
220 * even when using UseFDev */
221 OUTREGP(CLOCK_CNTL_INDEX,
222 mode->clk_cntl_index & PPLL_DIV_SEL_MASK,
224 radeon_pll_errata_after_index(rinfo);
225 radeon_pll_errata_after_data(rinfo);
230 if(rinfo->pdev.device == PCI_CHIP_RV370_5B60) return;
232 /* Swich VCKL clock input to CPUCLK so it stays fed while PPLL updates*/
233 OUTPLLP(VCLK_ECP_CNTL, VCLK_SRC_SEL_CPUCLK, ~VCLK_SRC_SEL_MASK);
235 /* Reset PPLL & enable atomic update */
237 PPLL_RESET | PPLL_ATOMIC_UPDATE_EN | PPLL_VGA_ATOMIC_UPDATE_EN,
238 ~(PPLL_RESET | PPLL_ATOMIC_UPDATE_EN | PPLL_VGA_ATOMIC_UPDATE_EN));
240 /* Switch to selected PPLL divider */
241 OUTREGP(CLOCK_CNTL_INDEX,
242 mode->clk_cntl_index & PPLL_DIV_SEL_MASK,
245 /* Set PPLL ref. div */
246 if (rinfo->family == CHIP_FAMILY_R300 ||
247 rinfo->family == CHIP_FAMILY_RS300 ||
248 rinfo->family == CHIP_FAMILY_R350 ||
249 rinfo->family == CHIP_FAMILY_RV350) {
250 if (mode->ppll_ref_div & R300_PPLL_REF_DIV_ACC_MASK) {
251 /* When restoring console mode, use saved PPLL_REF_DIV
254 OUTPLLP(PPLL_REF_DIV, mode->ppll_ref_div, 0);
256 /* R300 uses ref_div_acc field as real ref divider */
257 OUTPLLP(PPLL_REF_DIV,
258 (mode->ppll_ref_div << R300_PPLL_REF_DIV_ACC_SHIFT),
259 ~R300_PPLL_REF_DIV_ACC_MASK);
262 OUTPLLP(PPLL_REF_DIV, mode->ppll_ref_div, ~PPLL_REF_DIV_MASK);
264 /* Set PPLL divider 3 & post divider*/
265 OUTPLLP(PPLL_DIV_3, mode->ppll_div_3, ~PPLL_FB3_DIV_MASK);
266 OUTPLLP(PPLL_DIV_3, mode->ppll_div_3, ~PPLL_POST3_DIV_MASK);
269 while (INPLL(PPLL_REF_DIV) & PPLL_ATOMIC_UPDATE_R)
271 OUTPLLP(PPLL_REF_DIV, PPLL_ATOMIC_UPDATE_W, ~PPLL_ATOMIC_UPDATE_W);
273 /* Wait read update complete */
274 /* FIXME: Certain revisions of R300 can't recover here. Not sure of
275 the cause yet, but this workaround will mask the problem for now.
276 Other chips usually will pass at the very first test, so the
277 workaround shouldn't have any effect on them. */
278 for (i = 0; (i < 10000 && INPLL(PPLL_REF_DIV) & PPLL_ATOMIC_UPDATE_R); i++)
281 OUTPLL(HTOTAL_CNTL, 0);
283 /* Clear reset & atomic update */
284 OUTPLLP(PPLL_CNTL, 0,
285 ~(PPLL_RESET | PPLL_SLEEP | PPLL_ATOMIC_UPDATE_EN | PPLL_VGA_ATOMIC_UPDATE_EN));
287 /* We may want some locking ... oh well */
290 /* Switch back VCLK source to PPLL */
291 OUTPLLP(VCLK_ECP_CNTL, VCLK_SRC_SEL_PPLLCLK, ~VCLK_SRC_SEL_MASK);
299 #if 0 /* unused ? -> scheduled for removal */
300 /* these common regs are cleared before mode setting so they do not
301 * interfere with anything
303 static reg_val common_regs[] = {
305 { OVR_WID_LEFT_RIGHT, 0 },
306 { OVR_WID_TOP_BOTTOM, 0 },
307 { OV0_SCALE_CNTL, 0 },
312 { CAP0_TRIG_CNTL, 0 },
313 { CAP1_TRIG_CNTL, 0 },
317 void radeon_setmode(void)
319 struct radeon_regs *mode = malloc(sizeof(struct radeon_regs));
321 mode->crtc_gen_cntl = 0x03000200;
322 mode->crtc_ext_cntl = 0x00008048;
323 mode->dac_cntl = 0xff002100;
324 mode->crtc_h_total_disp = 0x4f0063;
325 mode->crtc_h_sync_strt_wid = 0x8c02a2;
326 mode->crtc_v_total_disp = 0x01df020c;
327 mode->crtc_v_sync_strt_wid = 0x8201ea;
328 mode->crtc_pitch = 0x00500050;
330 OUTREG(CRTC_GEN_CNTL, mode->crtc_gen_cntl);
331 OUTREGP(CRTC_EXT_CNTL, mode->crtc_ext_cntl,
332 ~(CRTC_HSYNC_DIS | CRTC_VSYNC_DIS | CRTC_DISPLAY_DIS));
333 OUTREGP(DAC_CNTL, mode->dac_cntl, DAC_RANGE_CNTL | DAC_BLANKING);
334 OUTREG(CRTC_H_TOTAL_DISP, mode->crtc_h_total_disp);
335 OUTREG(CRTC_H_SYNC_STRT_WID, mode->crtc_h_sync_strt_wid);
336 OUTREG(CRTC_V_TOTAL_DISP, mode->crtc_v_total_disp);
337 OUTREG(CRTC_V_SYNC_STRT_WID, mode->crtc_v_sync_strt_wid);
338 OUTREG(CRTC_OFFSET, 0);
339 OUTREG(CRTC_OFFSET_CNTL, 0);
340 OUTREG(CRTC_PITCH, mode->crtc_pitch);
342 mode->clk_cntl_index = 0x300;
343 mode->ppll_ref_div = 0xc;
344 mode->ppll_div_3 = 0x00030059;
346 radeon_write_pll_regs(rinfo, mode);
349 static void set_pal(void)
353 for (idx = 0; idx < 256; idx++) {
354 OUTREG8(PALETTE_INDEX, idx);
355 OUTREG(PALETTE_DATA, val);
360 void radeon_setmode_9200(int vesa_idx, int bpp)
362 struct radeon_regs *mode = malloc(sizeof(struct radeon_regs));
364 mode->crtc_gen_cntl = CRTC_EN | CRTC_EXT_DISP_EN;
365 mode->crtc_ext_cntl = VGA_ATI_LINEAR | XCRT_CNT_EN | CRTC_CRT_ON;
366 mode->dac_cntl = DAC_MASK_ALL | DAC_VGA_ADR_EN | DAC_8BIT_EN;
367 mode->crtc_offset_cntl = CRTC_OFFSET_CNTL__CRTC_TILE_EN;
371 mode->crtc_gen_cntl |= 0x6 << 8; /* x888 */
372 #if defined(__BIG_ENDIAN)
373 mode->surface_cntl = NONSURF_AP0_SWP_32BPP | NONSURF_AP1_SWP_32BPP;
374 mode->surf_info[0] = NONSURF_AP0_SWP_32BPP | NONSURF_AP1_SWP_32BPP;
378 mode->crtc_gen_cntl |= 0x4 << 8; /* 565 */
379 #if defined(__BIG_ENDIAN)
380 mode->surface_cntl = NONSURF_AP0_SWP_16BPP | NONSURF_AP1_SWP_16BPP;
381 mode->surf_info[0] = NONSURF_AP0_SWP_16BPP | NONSURF_AP1_SWP_16BPP;
385 mode->crtc_gen_cntl |= 0x2 << 8; /* palette */
386 mode->surface_cntl = 0x00000000;
391 case RES_MODE_1280x1024:
392 mode->crtc_h_total_disp = CRTC_H_TOTAL_DISP_VAL(1688,1280);
393 mode->crtc_v_total_disp = CRTC_V_TOTAL_DISP_VAL(1066,1024);
394 mode->crtc_v_sync_strt_wid = CRTC_VSYNC_STRT_WID_VAL(1025,3);
395 #if defined(CONFIG_RADEON_VREFRESH_75HZ)
396 mode->crtc_h_sync_strt_wid = CRTC_HSYNC_STRT_WID_VAL(1288,18);
397 mode->ppll_div_3 = 0x00010078;
398 #else /* default @ 60 Hz */
399 mode->crtc_h_sync_strt_wid = CRTC_HSYNC_STRT_WID_VAL(1320,14);
400 mode->ppll_div_3 = 0x00010060;
403 * for this mode pitch expands to the same value for 32, 16 and 8 bpp,
404 * so we set it here once only.
406 mode->crtc_pitch = RADEON_CRT_PITCH(1280,32);
409 mode->surf_info[0] |= R200_SURF_TILE_COLOR_MACRO | (1280 * 4 / 16);
410 mode->surf_upper_bound[0] = SURF_UPPER_BOUND(1280,1024,32);
413 mode->surf_info[0] |= R200_SURF_TILE_COLOR_MACRO | (1280 * 2 / 16);
414 mode->surf_upper_bound[0] = SURF_UPPER_BOUND(1280,1024,16);
417 mode->surf_info[0] = R200_SURF_TILE_COLOR_MACRO | (1280 * 1 / 16);
418 mode->surf_upper_bound[0] = SURF_UPPER_BOUND(1280,1024,8);
422 case RES_MODE_1024x768:
423 #if defined(CONFIG_RADEON_VREFRESH_75HZ)
424 mode->crtc_h_total_disp = CRTC_H_TOTAL_DISP_VAL(1312,1024);
425 mode->crtc_h_sync_strt_wid = CRTC_HSYNC_STRT_WID_VAL(1032,12);
426 mode->crtc_v_total_disp = CRTC_V_TOTAL_DISP_VAL(800,768);
427 mode->crtc_v_sync_strt_wid = CRTC_VSYNC_STRT_WID_VAL(769,3);
428 mode->ppll_div_3 = 0x0002008c;
430 mode->crtc_h_total_disp = CRTC_H_TOTAL_DISP_VAL(1344,1024);
431 mode->crtc_h_sync_strt_wid = CRTC_HSYNC_STRT_WID_VAL(1040,17) | CRTC_H_SYNC_POL;
432 mode->crtc_v_total_disp = CRTC_V_TOTAL_DISP_VAL(806,768);
433 mode->crtc_v_sync_strt_wid = CRTC_VSYNC_STRT_WID_VAL(771,6) | CRTC_V_SYNC_POL;
434 mode->ppll_div_3 = 0x00020074;
436 /* also same pitch value for 32, 16 and 8 bpp */
437 mode->crtc_pitch = RADEON_CRT_PITCH(1024,32);
440 mode->surf_info[0] |= R200_SURF_TILE_COLOR_MACRO | (1024 * 4 / 16);
441 mode->surf_upper_bound[0] = SURF_UPPER_BOUND(1024,768,32);
444 mode->surf_info[0] |= R200_SURF_TILE_COLOR_MACRO | (1024 * 2 / 16);
445 mode->surf_upper_bound[0] = SURF_UPPER_BOUND(1024,768,16);
448 mode->surf_info[0] = R200_SURF_TILE_COLOR_MACRO | (1024 * 1 / 16);
449 mode->surf_upper_bound[0] = SURF_UPPER_BOUND(1024,768,8);
453 case RES_MODE_800x600:
454 mode->crtc_h_total_disp = CRTC_H_TOTAL_DISP_VAL(1056,800);
455 #if defined(CONFIG_RADEON_VREFRESH_75HZ)
456 mode->crtc_h_sync_strt_wid = CRTC_HSYNC_STRT_WID_VAL(808,10);
457 mode->crtc_v_total_disp = CRTC_V_TOTAL_DISP_VAL(625,600);
458 mode->crtc_v_sync_strt_wid = CRTC_VSYNC_STRT_WID_VAL(601,3);
459 mode->ppll_div_3 = 0x000300b0;
461 mode->crtc_h_sync_strt_wid = CRTC_HSYNC_STRT_WID_VAL(832,16);
462 mode->crtc_v_total_disp = CRTC_V_TOTAL_DISP_VAL(628,600);
463 mode->crtc_v_sync_strt_wid = CRTC_VSYNC_STRT_WID_VAL(601,4);
464 mode->ppll_div_3 = 0x0003008e;
468 mode->crtc_pitch = RADEON_CRT_PITCH(832,32);
469 mode->surf_info[0] |= R200_SURF_TILE_COLOR_MACRO | (832 * 4 / 16);
470 mode->surf_upper_bound[0] = SURF_UPPER_BOUND(832,600,32);
473 mode->crtc_pitch = RADEON_CRT_PITCH(896,16);
474 mode->surf_info[0] |= R200_SURF_TILE_COLOR_MACRO | (896 * 2 / 16);
475 mode->surf_upper_bound[0] = SURF_UPPER_BOUND(896,600,16);
478 mode->crtc_pitch = RADEON_CRT_PITCH(1024,8);
479 mode->surf_info[0] = R200_SURF_TILE_COLOR_MACRO | (1024 * 1 / 16);
480 mode->surf_upper_bound[0] = SURF_UPPER_BOUND(1024,600,8);
484 default: /* RES_MODE_640x480 */
485 #if defined(CONFIG_RADEON_VREFRESH_75HZ)
486 mode->crtc_h_total_disp = CRTC_H_TOTAL_DISP_VAL(840,640);
487 mode->crtc_h_sync_strt_wid = CRTC_HSYNC_STRT_WID_VAL(648,8) | CRTC_H_SYNC_POL;
488 mode->crtc_v_total_disp = CRTC_V_TOTAL_DISP_VAL(500,480);
489 mode->crtc_v_sync_strt_wid = CRTC_VSYNC_STRT_WID_VAL(481,3) | CRTC_V_SYNC_POL;
490 mode->ppll_div_3 = 0x00030070;
492 mode->crtc_h_total_disp = CRTC_H_TOTAL_DISP_VAL(800,640);
493 mode->crtc_h_sync_strt_wid = CRTC_HSYNC_STRT_WID_VAL(674,12) | CRTC_H_SYNC_POL;
494 mode->crtc_v_total_disp = CRTC_V_TOTAL_DISP_VAL(525,480);
495 mode->crtc_v_sync_strt_wid = CRTC_VSYNC_STRT_WID_VAL(491,2) | CRTC_V_SYNC_POL;
496 mode->ppll_div_3 = 0x00030059;
498 /* also same pitch value for 32, 16 and 8 bpp */
499 mode->crtc_pitch = RADEON_CRT_PITCH(640,32);
502 mode->surf_info[0] |= R200_SURF_TILE_COLOR_MACRO | (640 * 4 / 16);
503 mode->surf_upper_bound[0] = SURF_UPPER_BOUND(640,480,32);
506 mode->surf_info[0] |= R200_SURF_TILE_COLOR_MACRO | (640 * 2 / 16);
507 mode->surf_upper_bound[0] = SURF_UPPER_BOUND(640,480,16);
510 mode->crtc_offset_cntl = 0x00000000;
516 OUTREG(CRTC_GEN_CNTL, mode->crtc_gen_cntl | CRTC_DISP_REQ_EN_B);
517 OUTREGP(CRTC_EXT_CNTL, mode->crtc_ext_cntl,
518 (CRTC_HSYNC_DIS | CRTC_VSYNC_DIS | CRTC_DISPLAY_DIS));
519 OUTREGP(DAC_CNTL, mode->dac_cntl, DAC_RANGE_CNTL | DAC_BLANKING);
520 OUTREG(CRTC_H_TOTAL_DISP, mode->crtc_h_total_disp);
521 OUTREG(CRTC_H_SYNC_STRT_WID, mode->crtc_h_sync_strt_wid);
522 OUTREG(CRTC_V_TOTAL_DISP, mode->crtc_v_total_disp);
523 OUTREG(CRTC_V_SYNC_STRT_WID, mode->crtc_v_sync_strt_wid);
524 OUTREG(CRTC_OFFSET, 0);
525 OUTREG(CRTC_OFFSET_CNTL, mode->crtc_offset_cntl);
526 OUTREG(CRTC_PITCH, mode->crtc_pitch);
527 OUTREG(CRTC_GEN_CNTL, mode->crtc_gen_cntl);
529 mode->clk_cntl_index = 0x300;
530 mode->ppll_ref_div = 0xc;
532 radeon_write_pll_regs(rinfo, mode);
534 OUTREGP(CRTC_EXT_CNTL, mode->crtc_ext_cntl,
535 ~(CRTC_HSYNC_DIS | CRTC_VSYNC_DIS | CRTC_DISPLAY_DIS));
536 OUTREG(SURFACE0_INFO, mode->surf_info[0]);
537 OUTREG(SURFACE0_LOWER_BOUND, 0);
538 OUTREG(SURFACE0_UPPER_BOUND, mode->surf_upper_bound[0]);
539 OUTREG(SURFACE_CNTL, mode->surface_cntl);
547 #include "../bios_emulator/include/biosemu.h"
549 int radeon_probe(struct radeonfb_info *rinfo)
554 pdev = pci_find_devices(ati_radeon_pci_ids, 0);
557 pci_read_config_word(pdev, PCI_DEVICE_ID, &did);
558 printf("ATI Radeon video card (%04x, %04x) found @(%d:%d:%d)\n",
559 PCI_VENDOR_ID_ATI, did, (pdev >> 16) & 0xff,
560 (pdev >> 11) & 0x1f, (pdev >> 8) & 0x7);
562 strcpy(rinfo->name, "ATI Radeon");
563 rinfo->pdev.vendor = PCI_VENDOR_ID_ATI;
564 rinfo->pdev.device = did;
565 rinfo->family = get_radeon_id_family(rinfo->pdev.device);
566 pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0,
567 &rinfo->fb_base_bus);
568 pci_read_config_dword(pdev, PCI_BASE_ADDRESS_2,
569 &rinfo->mmio_base_bus);
570 rinfo->fb_base_bus &= 0xfffff000;
571 rinfo->mmio_base_bus &= ~0x04;
573 rinfo->mmio_base = pci_bus_to_virt(pdev, rinfo->mmio_base_bus,
574 PCI_REGION_MEM, 0, MAP_NOCACHE);
575 DPRINT("rinfo->mmio_base = 0x%p bus=0x%x\n",
576 rinfo->mmio_base, rinfo->mmio_base_bus);
577 rinfo->fb_local_base = INREG(MC_FB_LOCATION) << 16;
578 DPRINT("rinfo->fb_local_base = 0x%x\n",rinfo->fb_local_base);
579 /* PostBIOS with x86 emulater */
580 if (!BootVideoCardBIOS(pdev, NULL, 0))
585 * (These will be added in the future for the chipfamily
586 * R300, RV200, RS200, RV100, RS100.)
589 /* Get VRAM size and type */
590 radeon_identify_vram(rinfo);
592 rinfo->mapped_vram = min_t(unsigned long, MAX_MAPPED_VRAM,
594 rinfo->fb_base = pci_bus_to_virt(pdev, rinfo->fb_base_bus,
595 PCI_REGION_MEM, 0, MAP_NOCACHE);
596 DPRINT("Radeon: framebuffer base address 0x%08x, "
597 "bus address 0x%08x\n"
598 "MMIO base address 0x%08x, bus address 0x%08x, "
599 "framebuffer local base 0x%08x.\n ",
600 (u32)rinfo->fb_base, rinfo->fb_base_bus,
601 (u32)rinfo->mmio_base, rinfo->mmio_base_bus,
602 rinfo->fb_local_base);
613 #define CURSOR_SIZE 0x1000 /* in KByte for HW Cursor */
614 #define PATTERN_ADR (pGD->dprBase + CURSOR_SIZE) /* pattern Memory after Cursor Memory */
615 #define PATTERN_SIZE 8*8*4 /* 4 Bytes per Pixel 8 x 8 Pixel */
616 #define ACCELMEMORY (CURSOR_SIZE + PATTERN_SIZE) /* reserved Memory for BITBlt and hw cursor */
618 void *video_hw_init(void)
620 GraphicDevice *pGD = (GraphicDevice *) & ctfb;
623 unsigned long t1, hsynch, vsynch;
624 int bits_per_pixel, i, tmp, vesa_idx = 0, videomode;
625 struct ctfb_res_modes *res_mode;
626 struct ctfb_res_modes var_mode;
628 rinfo = malloc(sizeof(struct radeonfb_info));
631 if(radeon_probe(rinfo)) {
632 printf("No radeon video card found!\n");
638 videomode = CONFIG_SYS_DEFAULT_VIDEO_MODE;
639 /* get video mode via environment */
640 if ((penv = getenv ("videomode")) != NULL) {
641 /* deceide if it is a string */
642 if (penv[0] <= '9') {
643 videomode = (int) simple_strtoul (penv, NULL, 16);
650 /* parameter are vesa modes */
652 for (i = 0; i < VESA_MODES_COUNT; i++) {
653 if (vesa_modes[i].vesanr == videomode)
656 if (i == VESA_MODES_COUNT) {
657 printf ("no VESA Mode found, switching to mode 0x%x ", CONFIG_SYS_DEFAULT_VIDEO_MODE);
660 res_mode = (struct ctfb_res_modes *) &res_mode_init[vesa_modes[i].resindex];
661 bits_per_pixel = vesa_modes[i].bits_per_pixel;
662 vesa_idx = vesa_modes[i].resindex;
664 res_mode = (struct ctfb_res_modes *) &var_mode;
665 bits_per_pixel = video_get_params (res_mode, penv);
668 /* calculate hsynch and vsynch freq (info only) */
669 t1 = (res_mode->left_margin + res_mode->xres +
670 res_mode->right_margin + res_mode->hsync_len) / 8;
672 t1 *= res_mode->pixclock;
674 hsynch = 1000000000L / t1;
675 t1 *= (res_mode->upper_margin + res_mode->yres +
676 res_mode->lower_margin + res_mode->vsync_len);
678 vsynch = 1000000000L / t1;
680 /* fill in Graphic device struct */
681 sprintf (pGD->modeIdent, "%dx%dx%d %ldkHz %ldHz", res_mode->xres,
682 res_mode->yres, bits_per_pixel, (hsynch / 1000),
684 printf ("%s\n", pGD->modeIdent);
685 pGD->winSizeX = res_mode->xres;
686 pGD->winSizeY = res_mode->yres;
687 pGD->plnSizeX = res_mode->xres;
688 pGD->plnSizeY = res_mode->yres;
690 switch (bits_per_pixel) {
693 pGD->gdfIndex = GDF_32BIT_X888RGB;
694 if (res_mode->xres == 800) {
701 pGD->gdfIndex = GDF_16BIT_565RGB;
702 if (res_mode->xres == 800) {
708 if (res_mode->xres == 800) {
709 pGD->winSizeX = 1024;
710 pGD->plnSizeX = 1024;
713 pGD->gdfIndex = GDF__8BIT_INDEX;
717 pGD->isaBase = CONFIG_SYS_ISA_IO_BASE_ADDRESS;
718 pGD->pciBase = (unsigned int)rinfo->fb_base;
719 pGD->frameAdrs = (unsigned int)rinfo->fb_base;
720 pGD->memSize = 64 * 1024 * 1024;
722 /* Cursor Start Address */
723 pGD->dprBase = (pGD->winSizeX * pGD->winSizeY * pGD->gdfBytesPP) +
724 (unsigned int)rinfo->fb_base;
725 if ((pGD->dprBase & 0x0fff) != 0) {
727 pGD->dprBase &= 0xfffff000;
728 pGD->dprBase += 0x00001000;
730 DPRINT ("Cursor Start %x Pattern Start %x\n", pGD->dprBase,
732 pGD->vprBase = (unsigned int)rinfo->fb_base; /* Dummy */
733 pGD->cprBase = (unsigned int)rinfo->fb_base; /* Dummy */
734 /* set up Hardware */
736 /* Clear video memory (only visible screen area) */
737 i = pGD->winSizeX * pGD->winSizeY * pGD->gdfBytesPP / 4;
738 vm = (unsigned int *) pGD->pciBase;
741 /*SetDrawingEngine (bits_per_pixel);*/
743 if (rinfo->family == CHIP_FAMILY_RV280)
744 radeon_setmode_9200(vesa_idx, bits_per_pixel);
748 return ((void *) pGD);
751 void video_set_lut (unsigned int index, /* color number */
752 unsigned char r, /* red */
753 unsigned char g, /* green */
754 unsigned char b /* blue */
757 OUTREG(PALETTE_INDEX, index);
758 OUTREG(PALETTE_DATA, (r << 16) | (g << 8) | b);