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 * See file CREDITS for list of people who contributed to this
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License as
13 * published by the Free Software Foundation; either version 2 of
14 * the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
26 * Some codes of this file is partly ported from Linux kernel
27 * ATI video framebuffer driver.
29 * Now the driver is tested on below ATI chips:
38 #ifdef CONFIG_ATI_RADEON_FB
42 #include <asm/processor.h>
43 #include <asm/errno.h>
47 #include "videomodes.h"
51 #include "ati_radeon_fb.h"
56 #define DPRINT(x...) printf(x)
58 #define DPRINT(x...) do{}while(0)
62 #define min_t(type,x,y) \
63 ({ type __x = (x); type __y = (y); __x < __y ? __x: __y; })
66 #define MAX_MAPPED_VRAM (2048*2048*4)
67 #define MIN_MAPPED_VRAM (1024*768*1)
69 #define RADEON_BUFFER_ALIGN 0x00000fff
70 #define SURF_UPPER_BOUND(x,y,bpp) (((((x) * (((y) + 15) & ~15) * (bpp)/8) + RADEON_BUFFER_ALIGN) \
71 & ~RADEON_BUFFER_ALIGN) - 1)
72 #define RADEON_CRT_PITCH(width, bpp) ((((width) * (bpp) + ((bpp) * 8 - 1)) / ((bpp) * 8)) | \
73 ((((width) * (bpp) + ((bpp) * 8 - 1)) / ((bpp) * 8)) << 16))
75 #define CRTC_H_TOTAL_DISP_VAL(htotal, hdisp) \
76 (((((htotal) / 8) - 1) & 0x3ff) | (((((hdisp) / 8) - 1) & 0x1ff) << 16))
77 #define CRTC_HSYNC_STRT_WID_VAL(hsync_srtr, hsync_wid) \
78 (((hsync_srtr) & 0x1fff) | (((hsync_wid) & 0x3f) << 16))
79 #define CRTC_V_TOTAL_DISP_VAL(vtotal, vdisp) \
80 ((((vtotal) - 1) & 0xffff) | (((vdisp) - 1) << 16))
81 #define CRTC_VSYNC_STRT_WID_VAL(vsync_srtr, vsync_wid) \
82 ((((vsync_srtr) - 1) & 0xfff) | (((vsync_wid) & 0x1f) << 16))
84 /*#define PCI_VENDOR_ID_ATI*/
85 #define PCI_CHIP_RV280_5960 0x5960
86 #define PCI_CHIP_RV280_5961 0x5961
87 #define PCI_CHIP_RV280_5962 0x5962
88 #define PCI_CHIP_RV280_5964 0x5964
89 #define PCI_CHIP_RV370_5B60 0x5B60
90 #define PCI_CHIP_RV380_5657 0x5657
91 #define PCI_CHIP_R420_554d 0x554d
93 static struct pci_device_id ati_radeon_pci_ids[] = {
94 {PCI_VENDOR_ID_ATI, PCI_CHIP_RV280_5960},
95 {PCI_VENDOR_ID_ATI, PCI_CHIP_RV280_5961},
96 {PCI_VENDOR_ID_ATI, PCI_CHIP_RV280_5962},
97 {PCI_VENDOR_ID_ATI, PCI_CHIP_RV280_5964},
98 {PCI_VENDOR_ID_ATI, PCI_CHIP_RV370_5B60},
99 {PCI_VENDOR_ID_ATI, PCI_CHIP_RV380_5657},
100 {PCI_VENDOR_ID_ATI, PCI_CHIP_R420_554d},
104 static u16 ati_radeon_id_family_table[][2] = {
105 {PCI_CHIP_RV280_5960, CHIP_FAMILY_RV280},
106 {PCI_CHIP_RV280_5961, CHIP_FAMILY_RV280},
107 {PCI_CHIP_RV280_5962, CHIP_FAMILY_RV280},
108 {PCI_CHIP_RV280_5964, CHIP_FAMILY_RV280},
109 {PCI_CHIP_RV370_5B60, CHIP_FAMILY_RV380},
110 {PCI_CHIP_RV380_5657, CHIP_FAMILY_RV380},
111 {PCI_CHIP_R420_554d, CHIP_FAMILY_R420},
115 u16 get_radeon_id_family(u16 device)
118 for (i=0; ati_radeon_id_family_table[0][i]; i+=2)
119 if (ati_radeon_id_family_table[0][i] == device)
120 return ati_radeon_id_family_table[0][i + 1];
124 struct radeonfb_info *rinfo;
126 static void radeon_identify_vram(struct radeonfb_info *rinfo)
130 /* framebuffer size */
131 if ((rinfo->family == CHIP_FAMILY_RS100) ||
132 (rinfo->family == CHIP_FAMILY_RS200) ||
133 (rinfo->family == CHIP_FAMILY_RS300)) {
134 u32 tom = INREG(NB_TOM);
135 tmp = ((((tom >> 16) - (tom & 0xffff) + 1) << 6) * 1024);
138 OUTREG(MC_FB_LOCATION, tom);
139 OUTREG(DISPLAY_BASE_ADDR, (tom & 0xffff) << 16);
140 OUTREG(CRTC2_DISPLAY_BASE_ADDR, (tom & 0xffff) << 16);
141 OUTREG(OV0_BASE_ADDR, (tom & 0xffff) << 16);
143 /* This is supposed to fix the crtc2 noise problem. */
144 OUTREG(GRPH2_BUFFER_CNTL, INREG(GRPH2_BUFFER_CNTL) & ~0x7f0000);
146 if ((rinfo->family == CHIP_FAMILY_RS100) ||
147 (rinfo->family == CHIP_FAMILY_RS200)) {
148 /* This is to workaround the asic bug for RMX, some versions
149 of BIOS dosen't have this register initialized correctly.
151 OUTREGP(CRTC_MORE_CNTL, CRTC_H_CUTOFF_ACTIVE_EN,
152 ~CRTC_H_CUTOFF_ACTIVE_EN);
155 tmp = INREG(CONFIG_MEMSIZE);
158 /* mem size is bits [28:0], mask off the rest */
159 rinfo->video_ram = tmp & CONFIG_MEMSIZE_MASK;
162 * Hack to get around some busted production M6's
165 if (rinfo->video_ram == 0) {
166 switch (rinfo->pdev.device) {
167 case PCI_CHIP_RADEON_LY:
168 case PCI_CHIP_RADEON_LZ:
169 rinfo->video_ram = 8192 * 1024;
177 * Now try to identify VRAM type
179 if ((rinfo->family >= CHIP_FAMILY_R300) ||
180 (INREG(MEM_SDRAM_MODE_REG) & (1<<30)))
185 tmp = INREG(MEM_CNTL);
186 if (IS_R300_VARIANT(rinfo)) {
187 tmp &= R300_MEM_NUM_CHANNELS_MASK;
189 case 0: rinfo->vram_width = 64; break;
190 case 1: rinfo->vram_width = 128; break;
191 case 2: rinfo->vram_width = 256; break;
192 default: rinfo->vram_width = 128; break;
194 } else if ((rinfo->family == CHIP_FAMILY_RV100) ||
195 (rinfo->family == CHIP_FAMILY_RS100) ||
196 (rinfo->family == CHIP_FAMILY_RS200)){
197 if (tmp & RV100_MEM_HALF_MODE)
198 rinfo->vram_width = 32;
200 rinfo->vram_width = 64;
202 if (tmp & MEM_NUM_CHANNELS_MASK)
203 rinfo->vram_width = 128;
205 rinfo->vram_width = 64;
208 /* This may not be correct, as some cards can have half of channel disabled
209 * ToDo: identify these cases
212 DPRINT("radeonfb: Found %ldk of %s %d bits wide videoram\n",
213 rinfo->video_ram / 1024,
214 rinfo->vram_ddr ? "DDR" : "SDRAM",
219 static void radeon_write_pll_regs(struct radeonfb_info *rinfo, struct radeon_regs *mode)
223 radeon_fifo_wait(20);
226 /* Workaround from XFree */
227 if (rinfo->is_mobility) {
228 /* A temporal workaround for the occational blanking on certain laptop
229 * panels. This appears to related to the PLL divider registers
230 * (fail to lock?). It occurs even when all dividers are the same
231 * with their old settings. In this case we really don't need to
232 * fiddle with PLL registers. By doing this we can avoid the blanking
233 * problem with some panels.
235 if ((mode->ppll_ref_div == (INPLL(PPLL_REF_DIV) & PPLL_REF_DIV_MASK)) &&
236 (mode->ppll_div_3 == (INPLL(PPLL_DIV_3) &
237 (PPLL_POST3_DIV_MASK | PPLL_FB3_DIV_MASK)))) {
238 /* We still have to force a switch to selected PPLL div thanks to
239 * an XFree86 driver bug which will switch it away in some cases
240 * even when using UseFDev */
241 OUTREGP(CLOCK_CNTL_INDEX,
242 mode->clk_cntl_index & PPLL_DIV_SEL_MASK,
244 radeon_pll_errata_after_index(rinfo);
245 radeon_pll_errata_after_data(rinfo);
250 if(rinfo->pdev.device == PCI_CHIP_RV370_5B60) return;
252 /* Swich VCKL clock input to CPUCLK so it stays fed while PPLL updates*/
253 OUTPLLP(VCLK_ECP_CNTL, VCLK_SRC_SEL_CPUCLK, ~VCLK_SRC_SEL_MASK);
255 /* Reset PPLL & enable atomic update */
257 PPLL_RESET | PPLL_ATOMIC_UPDATE_EN | PPLL_VGA_ATOMIC_UPDATE_EN,
258 ~(PPLL_RESET | PPLL_ATOMIC_UPDATE_EN | PPLL_VGA_ATOMIC_UPDATE_EN));
260 /* Switch to selected PPLL divider */
261 OUTREGP(CLOCK_CNTL_INDEX,
262 mode->clk_cntl_index & PPLL_DIV_SEL_MASK,
265 /* Set PPLL ref. div */
266 if (rinfo->family == CHIP_FAMILY_R300 ||
267 rinfo->family == CHIP_FAMILY_RS300 ||
268 rinfo->family == CHIP_FAMILY_R350 ||
269 rinfo->family == CHIP_FAMILY_RV350) {
270 if (mode->ppll_ref_div & R300_PPLL_REF_DIV_ACC_MASK) {
271 /* When restoring console mode, use saved PPLL_REF_DIV
274 OUTPLLP(PPLL_REF_DIV, mode->ppll_ref_div, 0);
276 /* R300 uses ref_div_acc field as real ref divider */
277 OUTPLLP(PPLL_REF_DIV,
278 (mode->ppll_ref_div << R300_PPLL_REF_DIV_ACC_SHIFT),
279 ~R300_PPLL_REF_DIV_ACC_MASK);
282 OUTPLLP(PPLL_REF_DIV, mode->ppll_ref_div, ~PPLL_REF_DIV_MASK);
284 /* Set PPLL divider 3 & post divider*/
285 OUTPLLP(PPLL_DIV_3, mode->ppll_div_3, ~PPLL_FB3_DIV_MASK);
286 OUTPLLP(PPLL_DIV_3, mode->ppll_div_3, ~PPLL_POST3_DIV_MASK);
289 while (INPLL(PPLL_REF_DIV) & PPLL_ATOMIC_UPDATE_R)
291 OUTPLLP(PPLL_REF_DIV, PPLL_ATOMIC_UPDATE_W, ~PPLL_ATOMIC_UPDATE_W);
293 /* Wait read update complete */
294 /* FIXME: Certain revisions of R300 can't recover here. Not sure of
295 the cause yet, but this workaround will mask the problem for now.
296 Other chips usually will pass at the very first test, so the
297 workaround shouldn't have any effect on them. */
298 for (i = 0; (i < 10000 && INPLL(PPLL_REF_DIV) & PPLL_ATOMIC_UPDATE_R); i++)
301 OUTPLL(HTOTAL_CNTL, 0);
303 /* Clear reset & atomic update */
304 OUTPLLP(PPLL_CNTL, 0,
305 ~(PPLL_RESET | PPLL_SLEEP | PPLL_ATOMIC_UPDATE_EN | PPLL_VGA_ATOMIC_UPDATE_EN));
307 /* We may want some locking ... oh well */
310 /* Switch back VCLK source to PPLL */
311 OUTPLLP(VCLK_ECP_CNTL, VCLK_SRC_SEL_PPLLCLK, ~VCLK_SRC_SEL_MASK);
319 #if 0 /* unused ? -> scheduled for removal */
320 /* these common regs are cleared before mode setting so they do not
321 * interfere with anything
323 static reg_val common_regs[] = {
325 { OVR_WID_LEFT_RIGHT, 0 },
326 { OVR_WID_TOP_BOTTOM, 0 },
327 { OV0_SCALE_CNTL, 0 },
332 { CAP0_TRIG_CNTL, 0 },
333 { CAP1_TRIG_CNTL, 0 },
337 void radeon_setmode(void)
339 struct radeon_regs *mode = malloc(sizeof(struct radeon_regs));
341 mode->crtc_gen_cntl = 0x03000200;
342 mode->crtc_ext_cntl = 0x00008048;
343 mode->dac_cntl = 0xff002100;
344 mode->crtc_h_total_disp = 0x4f0063;
345 mode->crtc_h_sync_strt_wid = 0x8c02a2;
346 mode->crtc_v_total_disp = 0x01df020c;
347 mode->crtc_v_sync_strt_wid = 0x8201ea;
348 mode->crtc_pitch = 0x00500050;
350 OUTREG(CRTC_GEN_CNTL, mode->crtc_gen_cntl);
351 OUTREGP(CRTC_EXT_CNTL, mode->crtc_ext_cntl,
352 ~(CRTC_HSYNC_DIS | CRTC_VSYNC_DIS | CRTC_DISPLAY_DIS));
353 OUTREGP(DAC_CNTL, mode->dac_cntl, DAC_RANGE_CNTL | DAC_BLANKING);
354 OUTREG(CRTC_H_TOTAL_DISP, mode->crtc_h_total_disp);
355 OUTREG(CRTC_H_SYNC_STRT_WID, mode->crtc_h_sync_strt_wid);
356 OUTREG(CRTC_V_TOTAL_DISP, mode->crtc_v_total_disp);
357 OUTREG(CRTC_V_SYNC_STRT_WID, mode->crtc_v_sync_strt_wid);
358 OUTREG(CRTC_OFFSET, 0);
359 OUTREG(CRTC_OFFSET_CNTL, 0);
360 OUTREG(CRTC_PITCH, mode->crtc_pitch);
362 mode->clk_cntl_index = 0x300;
363 mode->ppll_ref_div = 0xc;
364 mode->ppll_div_3 = 0x00030059;
366 radeon_write_pll_regs(rinfo, mode);
369 static void set_pal(void)
373 for (idx = 0; idx < 256; idx++) {
374 OUTREG8(PALETTE_INDEX, idx);
375 OUTREG(PALETTE_DATA, val);
380 void radeon_setmode_9200(int vesa_idx, int bpp)
382 struct radeon_regs *mode = malloc(sizeof(struct radeon_regs));
384 mode->crtc_gen_cntl = CRTC_EN | CRTC_EXT_DISP_EN;
385 mode->crtc_ext_cntl = VGA_ATI_LINEAR | XCRT_CNT_EN | CRTC_CRT_ON;
386 mode->dac_cntl = DAC_MASK_ALL | DAC_VGA_ADR_EN | DAC_8BIT_EN;
387 mode->crtc_offset_cntl = CRTC_OFFSET_CNTL__CRTC_TILE_EN;
391 mode->crtc_gen_cntl |= 0x6 << 8; /* x888 */
392 #if defined(__BIG_ENDIAN)
393 mode->surface_cntl = NONSURF_AP0_SWP_32BPP | NONSURF_AP1_SWP_32BPP;
394 mode->surf_info[0] = NONSURF_AP0_SWP_32BPP | NONSURF_AP1_SWP_32BPP;
398 mode->crtc_gen_cntl |= 0x4 << 8; /* 565 */
399 #if defined(__BIG_ENDIAN)
400 mode->surface_cntl = NONSURF_AP0_SWP_16BPP | NONSURF_AP1_SWP_16BPP;
401 mode->surf_info[0] = NONSURF_AP0_SWP_16BPP | NONSURF_AP1_SWP_16BPP;
405 mode->crtc_gen_cntl |= 0x2 << 8; /* palette */
406 mode->surface_cntl = 0x00000000;
411 case RES_MODE_1280x1024:
412 mode->crtc_h_total_disp = CRTC_H_TOTAL_DISP_VAL(1688,1280);
413 mode->crtc_v_total_disp = CRTC_V_TOTAL_DISP_VAL(1066,1024);
414 mode->crtc_v_sync_strt_wid = CRTC_VSYNC_STRT_WID_VAL(1025,3);
415 #if defined(CONFIG_RADEON_VREFRESH_75HZ)
416 mode->crtc_h_sync_strt_wid = CRTC_HSYNC_STRT_WID_VAL(1288,18);
417 mode->ppll_div_3 = 0x00010078;
418 #else /* default @ 60 Hz */
419 mode->crtc_h_sync_strt_wid = CRTC_HSYNC_STRT_WID_VAL(1320,14);
420 mode->ppll_div_3 = 0x00010060;
423 * for this mode pitch expands to the same value for 32, 16 and 8 bpp,
424 * so we set it here once only.
426 mode->crtc_pitch = RADEON_CRT_PITCH(1280,32);
429 mode->surf_info[0] |= R200_SURF_TILE_COLOR_MACRO | (1280 * 4 / 16);
430 mode->surf_upper_bound[0] = SURF_UPPER_BOUND(1280,1024,32);
433 mode->surf_info[0] |= R200_SURF_TILE_COLOR_MACRO | (1280 * 2 / 16);
434 mode->surf_upper_bound[0] = SURF_UPPER_BOUND(1280,1024,16);
437 mode->surf_info[0] = R200_SURF_TILE_COLOR_MACRO | (1280 * 1 / 16);
438 mode->surf_upper_bound[0] = SURF_UPPER_BOUND(1280,1024,8);
442 case RES_MODE_1024x768:
443 #if defined(CONFIG_RADEON_VREFRESH_75HZ)
444 mode->crtc_h_total_disp = CRTC_H_TOTAL_DISP_VAL(1312,1024);
445 mode->crtc_h_sync_strt_wid = CRTC_HSYNC_STRT_WID_VAL(1032,12);
446 mode->crtc_v_total_disp = CRTC_V_TOTAL_DISP_VAL(800,768);
447 mode->crtc_v_sync_strt_wid = CRTC_VSYNC_STRT_WID_VAL(769,3);
448 mode->ppll_div_3 = 0x0002008c;
450 mode->crtc_h_total_disp = CRTC_H_TOTAL_DISP_VAL(1344,1024);
451 mode->crtc_h_sync_strt_wid = CRTC_HSYNC_STRT_WID_VAL(1040,17) | CRTC_H_SYNC_POL;
452 mode->crtc_v_total_disp = CRTC_V_TOTAL_DISP_VAL(806,768);
453 mode->crtc_v_sync_strt_wid = CRTC_VSYNC_STRT_WID_VAL(771,6) | CRTC_V_SYNC_POL;
454 mode->ppll_div_3 = 0x00020074;
456 /* also same pitch value for 32, 16 and 8 bpp */
457 mode->crtc_pitch = RADEON_CRT_PITCH(1024,32);
460 mode->surf_info[0] |= R200_SURF_TILE_COLOR_MACRO | (1024 * 4 / 16);
461 mode->surf_upper_bound[0] = SURF_UPPER_BOUND(1024,768,32);
464 mode->surf_info[0] |= R200_SURF_TILE_COLOR_MACRO | (1024 * 2 / 16);
465 mode->surf_upper_bound[0] = SURF_UPPER_BOUND(1024,768,16);
468 mode->surf_info[0] = R200_SURF_TILE_COLOR_MACRO | (1024 * 1 / 16);
469 mode->surf_upper_bound[0] = SURF_UPPER_BOUND(1024,768,8);
473 case RES_MODE_800x600:
474 mode->crtc_h_total_disp = CRTC_H_TOTAL_DISP_VAL(1056,800);
475 #if defined(CONFIG_RADEON_VREFRESH_75HZ)
476 mode->crtc_h_sync_strt_wid = CRTC_HSYNC_STRT_WID_VAL(808,10);
477 mode->crtc_v_total_disp = CRTC_V_TOTAL_DISP_VAL(625,600);
478 mode->crtc_v_sync_strt_wid = CRTC_VSYNC_STRT_WID_VAL(601,3);
479 mode->ppll_div_3 = 0x000300b0;
481 mode->crtc_h_sync_strt_wid = CRTC_HSYNC_STRT_WID_VAL(832,16);
482 mode->crtc_v_total_disp = CRTC_V_TOTAL_DISP_VAL(628,600);
483 mode->crtc_v_sync_strt_wid = CRTC_VSYNC_STRT_WID_VAL(601,4);
484 mode->ppll_div_3 = 0x0003008e;
488 mode->crtc_pitch = RADEON_CRT_PITCH(832,32);
489 mode->surf_info[0] |= R200_SURF_TILE_COLOR_MACRO | (832 * 4 / 16);
490 mode->surf_upper_bound[0] = SURF_UPPER_BOUND(832,600,32);
493 mode->crtc_pitch = RADEON_CRT_PITCH(896,16);
494 mode->surf_info[0] |= R200_SURF_TILE_COLOR_MACRO | (896 * 2 / 16);
495 mode->surf_upper_bound[0] = SURF_UPPER_BOUND(896,600,16);
498 mode->crtc_pitch = RADEON_CRT_PITCH(1024,8);
499 mode->surf_info[0] = R200_SURF_TILE_COLOR_MACRO | (1024 * 1 / 16);
500 mode->surf_upper_bound[0] = SURF_UPPER_BOUND(1024,600,8);
504 default: /* RES_MODE_640x480 */
505 #if defined(CONFIG_RADEON_VREFRESH_75HZ)
506 mode->crtc_h_total_disp = CRTC_H_TOTAL_DISP_VAL(840,640);
507 mode->crtc_h_sync_strt_wid = CRTC_HSYNC_STRT_WID_VAL(648,8) | CRTC_H_SYNC_POL;
508 mode->crtc_v_total_disp = CRTC_V_TOTAL_DISP_VAL(500,480);
509 mode->crtc_v_sync_strt_wid = CRTC_VSYNC_STRT_WID_VAL(481,3) | CRTC_V_SYNC_POL;
510 mode->ppll_div_3 = 0x00030070;
512 mode->crtc_h_total_disp = CRTC_H_TOTAL_DISP_VAL(800,640);
513 mode->crtc_h_sync_strt_wid = CRTC_HSYNC_STRT_WID_VAL(674,12) | CRTC_H_SYNC_POL;
514 mode->crtc_v_total_disp = CRTC_V_TOTAL_DISP_VAL(525,480);
515 mode->crtc_v_sync_strt_wid = CRTC_VSYNC_STRT_WID_VAL(491,2) | CRTC_V_SYNC_POL;
516 mode->ppll_div_3 = 0x00030059;
518 /* also same pitch value for 32, 16 and 8 bpp */
519 mode->crtc_pitch = RADEON_CRT_PITCH(640,32);
522 mode->surf_info[0] |= R200_SURF_TILE_COLOR_MACRO | (640 * 4 / 16);
523 mode->surf_upper_bound[0] = SURF_UPPER_BOUND(640,480,32);
526 mode->surf_info[0] |= R200_SURF_TILE_COLOR_MACRO | (640 * 2 / 16);
527 mode->surf_upper_bound[0] = SURF_UPPER_BOUND(640,480,16);
530 mode->crtc_offset_cntl = 0x00000000;
536 OUTREG(CRTC_GEN_CNTL, mode->crtc_gen_cntl | CRTC_DISP_REQ_EN_B);
537 OUTREGP(CRTC_EXT_CNTL, mode->crtc_ext_cntl,
538 (CRTC_HSYNC_DIS | CRTC_VSYNC_DIS | CRTC_DISPLAY_DIS));
539 OUTREGP(DAC_CNTL, mode->dac_cntl, DAC_RANGE_CNTL | DAC_BLANKING);
540 OUTREG(CRTC_H_TOTAL_DISP, mode->crtc_h_total_disp);
541 OUTREG(CRTC_H_SYNC_STRT_WID, mode->crtc_h_sync_strt_wid);
542 OUTREG(CRTC_V_TOTAL_DISP, mode->crtc_v_total_disp);
543 OUTREG(CRTC_V_SYNC_STRT_WID, mode->crtc_v_sync_strt_wid);
544 OUTREG(CRTC_OFFSET, 0);
545 OUTREG(CRTC_OFFSET_CNTL, mode->crtc_offset_cntl);
546 OUTREG(CRTC_PITCH, mode->crtc_pitch);
547 OUTREG(CRTC_GEN_CNTL, mode->crtc_gen_cntl);
549 mode->clk_cntl_index = 0x300;
550 mode->ppll_ref_div = 0xc;
552 radeon_write_pll_regs(rinfo, mode);
554 OUTREGP(CRTC_EXT_CNTL, mode->crtc_ext_cntl,
555 ~(CRTC_HSYNC_DIS | CRTC_VSYNC_DIS | CRTC_DISPLAY_DIS));
556 OUTREG(SURFACE0_INFO, mode->surf_info[0]);
557 OUTREG(SURFACE0_LOWER_BOUND, 0);
558 OUTREG(SURFACE0_UPPER_BOUND, mode->surf_upper_bound[0]);
559 OUTREG(SURFACE_CNTL, mode->surface_cntl);
567 #include "../bios_emulator/include/biosemu.h"
568 extern int BootVideoCardBIOS(pci_dev_t pcidev, BE_VGAInfo ** pVGAInfo, int cleanUp);
570 int radeon_probe(struct radeonfb_info *rinfo)
575 pdev = pci_find_devices(ati_radeon_pci_ids, 0);
578 pci_read_config_word(pdev, PCI_DEVICE_ID, &did);
579 printf("ATI Radeon video card (%04x, %04x) found @(%d:%d:%d)\n",
580 PCI_VENDOR_ID_ATI, did, (pdev >> 16) & 0xff,
581 (pdev >> 11) & 0x1f, (pdev >> 8) & 0x7);
583 strcpy(rinfo->name, "ATI Radeon");
584 rinfo->pdev.vendor = PCI_VENDOR_ID_ATI;
585 rinfo->pdev.device = did;
586 rinfo->family = get_radeon_id_family(rinfo->pdev.device);
587 pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0,
588 &rinfo->fb_base_phys);
589 pci_read_config_dword(pdev, PCI_BASE_ADDRESS_2,
590 &rinfo->mmio_base_phys);
591 rinfo->fb_base_phys &= 0xfffff000;
592 rinfo->mmio_base_phys &= ~0x04;
594 rinfo->mmio_base = (void *)rinfo->mmio_base_phys;
595 DPRINT("rinfo->mmio_base = 0x%x\n",rinfo->mmio_base);
596 rinfo->fb_local_base = INREG(MC_FB_LOCATION) << 16;
597 DPRINT("rinfo->fb_local_base = 0x%x\n",rinfo->fb_local_base);
598 /* PostBIOS with x86 emulater */
599 BootVideoCardBIOS(pdev, NULL, 0);
603 * (These will be added in the future for the chipfamily
604 * R300, RV200, RS200, RV100, RS100.)
607 /* Get VRAM size and type */
608 radeon_identify_vram(rinfo);
610 rinfo->mapped_vram = min_t(unsigned long, MAX_MAPPED_VRAM,
612 rinfo->fb_base = (void *)rinfo->fb_base_phys;
614 DPRINT("Radeon: framebuffer base phy address 0x%08x," \
615 "MMIO base phy address 0x%08x," \
616 "framebuffer local base 0x%08x.\n ",
617 rinfo->fb_base_phys, rinfo->mmio_base_phys,
618 rinfo->fb_local_base);
630 #define CURSOR_SIZE 0x1000 /* in KByte for HW Cursor */
631 #define PATTERN_ADR (pGD->dprBase + CURSOR_SIZE) /* pattern Memory after Cursor Memory */
632 #define PATTERN_SIZE 8*8*4 /* 4 Bytes per Pixel 8 x 8 Pixel */
633 #define ACCELMEMORY (CURSOR_SIZE + PATTERN_SIZE) /* reserved Memory for BITBlt and hw cursor */
635 void *video_hw_init(void)
637 GraphicDevice *pGD = (GraphicDevice *) & ctfb;
640 unsigned long t1, hsynch, vsynch;
641 int bits_per_pixel, i, tmp, vesa_idx = 0, videomode;
642 struct ctfb_res_modes *res_mode;
643 struct ctfb_res_modes var_mode;
645 rinfo = malloc(sizeof(struct radeonfb_info));
648 if(radeon_probe(rinfo)) {
649 printf("No radeon video card found!\n");
655 videomode = CFG_DEFAULT_VIDEO_MODE;
656 /* get video mode via environment */
657 if ((penv = getenv ("videomode")) != NULL) {
658 /* deceide if it is a string */
659 if (penv[0] <= '9') {
660 videomode = (int) simple_strtoul (penv, NULL, 16);
667 /* parameter are vesa modes */
669 for (i = 0; i < VESA_MODES_COUNT; i++) {
670 if (vesa_modes[i].vesanr == videomode)
673 if (i == VESA_MODES_COUNT) {
674 printf ("no VESA Mode found, switching to mode 0x%x ", CFG_DEFAULT_VIDEO_MODE);
677 res_mode = (struct ctfb_res_modes *) &res_mode_init[vesa_modes[i].resindex];
678 bits_per_pixel = vesa_modes[i].bits_per_pixel;
679 vesa_idx = vesa_modes[i].resindex;
681 res_mode = (struct ctfb_res_modes *) &var_mode;
682 bits_per_pixel = video_get_params (res_mode, penv);
685 /* calculate hsynch and vsynch freq (info only) */
686 t1 = (res_mode->left_margin + res_mode->xres +
687 res_mode->right_margin + res_mode->hsync_len) / 8;
689 t1 *= res_mode->pixclock;
691 hsynch = 1000000000L / t1;
692 t1 *= (res_mode->upper_margin + res_mode->yres +
693 res_mode->lower_margin + res_mode->vsync_len);
695 vsynch = 1000000000L / t1;
697 /* fill in Graphic device struct */
698 sprintf (pGD->modeIdent, "%dx%dx%d %ldkHz %ldHz", res_mode->xres,
699 res_mode->yres, bits_per_pixel, (hsynch / 1000),
701 printf ("%s\n", pGD->modeIdent);
702 pGD->winSizeX = res_mode->xres;
703 pGD->winSizeY = res_mode->yres;
704 pGD->plnSizeX = res_mode->xres;
705 pGD->plnSizeY = res_mode->yres;
707 switch (bits_per_pixel) {
710 pGD->gdfIndex = GDF_32BIT_X888RGB;
711 if (res_mode->xres == 800) {
718 pGD->gdfIndex = GDF_16BIT_565RGB;
719 if (res_mode->xres == 800) {
725 if (res_mode->xres == 800) {
726 pGD->winSizeX = 1024;
727 pGD->plnSizeX = 1024;
730 pGD->gdfIndex = GDF__8BIT_INDEX;
734 pGD->isaBase = CFG_ISA_IO_BASE_ADDRESS;
735 pGD->pciBase = rinfo->fb_base_phys;
736 pGD->frameAdrs = rinfo->fb_base_phys;
737 pGD->memSize = 64 * 1024 * 1024;
739 /* Cursor Start Address */
741 (pGD->winSizeX * pGD->winSizeY * pGD->gdfBytesPP) + rinfo->fb_base_phys;
742 if ((pGD->dprBase & 0x0fff) != 0) {
744 pGD->dprBase &= 0xfffff000;
745 pGD->dprBase += 0x00001000;
747 DPRINT ("Cursor Start %x Pattern Start %x\n", pGD->dprBase,
749 pGD->vprBase = rinfo->fb_base_phys; /* Dummy */
750 pGD->cprBase = rinfo->fb_base_phys; /* Dummy */
751 /* set up Hardware */
753 /* Clear video memory (only visible screen area) */
754 i = pGD->winSizeX * pGD->winSizeY * pGD->gdfBytesPP / 4;
755 vm = (unsigned int *) pGD->pciBase;
758 /*SetDrawingEngine (bits_per_pixel);*/
760 if (rinfo->family == CHIP_FAMILY_RV280)
761 radeon_setmode_9200(vesa_idx, bits_per_pixel);
765 return ((void *) pGD);
768 void video_set_lut (unsigned int index, /* color number */
769 unsigned char r, /* red */
770 unsigned char g, /* green */
771 unsigned char b /* blue */
774 OUTREG(PALETTE_INDEX, index);
775 OUTREG(PALETTE_DATA, (r << 16) | (g << 8) | b);