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