xref: /openbmc/u-boot/drivers/video/ati_radeon_fb.c (revision 83d290c56fab2d38cd1ab4c4cc7099559c1d5046)
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