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