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