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