1*352d2591SJean-Christophe PLAGNIOL-VILLARD /*
2*352d2591SJean-Christophe PLAGNIOL-VILLARD  * ATI Radeon Video card Framebuffer driver.
3*352d2591SJean-Christophe PLAGNIOL-VILLARD  *
4*352d2591SJean-Christophe PLAGNIOL-VILLARD  * Copyright 2007 Freescale Semiconductor, Inc.
5*352d2591SJean-Christophe PLAGNIOL-VILLARD  * Zhang Wei <wei.zhang@freescale.com>
6*352d2591SJean-Christophe PLAGNIOL-VILLARD  * Jason Jin <jason.jin@freescale.com>
7*352d2591SJean-Christophe PLAGNIOL-VILLARD  *
8*352d2591SJean-Christophe PLAGNIOL-VILLARD  * See file CREDITS for list of people who contributed to this
9*352d2591SJean-Christophe PLAGNIOL-VILLARD  * project.
10*352d2591SJean-Christophe PLAGNIOL-VILLARD  *
11*352d2591SJean-Christophe PLAGNIOL-VILLARD  * This program is free software; you can redistribute it and/or
12*352d2591SJean-Christophe PLAGNIOL-VILLARD  * modify it under the terms of the GNU General Public License as
13*352d2591SJean-Christophe PLAGNIOL-VILLARD  * published by the Free Software Foundation; either version 2 of
14*352d2591SJean-Christophe PLAGNIOL-VILLARD  * the License, or (at your option) any later version.
15*352d2591SJean-Christophe PLAGNIOL-VILLARD  *
16*352d2591SJean-Christophe PLAGNIOL-VILLARD  * This program is distributed in the hope that it will be useful,
17*352d2591SJean-Christophe PLAGNIOL-VILLARD  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18*352d2591SJean-Christophe PLAGNIOL-VILLARD  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19*352d2591SJean-Christophe PLAGNIOL-VILLARD  * GNU General Public License for more details.
20*352d2591SJean-Christophe PLAGNIOL-VILLARD  *
21*352d2591SJean-Christophe PLAGNIOL-VILLARD  * You should have received a copy of the GNU General Public License
22*352d2591SJean-Christophe PLAGNIOL-VILLARD  * along with this program; if not, write to the Free Software
23*352d2591SJean-Christophe PLAGNIOL-VILLARD  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
24*352d2591SJean-Christophe PLAGNIOL-VILLARD  * MA 02111-1307 USA
25*352d2591SJean-Christophe PLAGNIOL-VILLARD  *
26*352d2591SJean-Christophe PLAGNIOL-VILLARD  * Some codes of this file is partly ported from Linux kernel
27*352d2591SJean-Christophe PLAGNIOL-VILLARD  * ATI video framebuffer driver.
28*352d2591SJean-Christophe PLAGNIOL-VILLARD  *
29*352d2591SJean-Christophe PLAGNIOL-VILLARD  * Now the driver is tested on below ATI chips:
30*352d2591SJean-Christophe PLAGNIOL-VILLARD  *   9200
31*352d2591SJean-Christophe PLAGNIOL-VILLARD  *   X300
32*352d2591SJean-Christophe PLAGNIOL-VILLARD  *   X700
33*352d2591SJean-Christophe PLAGNIOL-VILLARD  *
34*352d2591SJean-Christophe PLAGNIOL-VILLARD  */
35*352d2591SJean-Christophe PLAGNIOL-VILLARD 
36*352d2591SJean-Christophe PLAGNIOL-VILLARD #include <common.h>
37*352d2591SJean-Christophe PLAGNIOL-VILLARD 
38*352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_ATI_RADEON_FB
39*352d2591SJean-Christophe PLAGNIOL-VILLARD 
40*352d2591SJean-Christophe PLAGNIOL-VILLARD #include <command.h>
41*352d2591SJean-Christophe PLAGNIOL-VILLARD #include <pci.h>
42*352d2591SJean-Christophe PLAGNIOL-VILLARD #include <asm/processor.h>
43*352d2591SJean-Christophe PLAGNIOL-VILLARD #include <asm/errno.h>
44*352d2591SJean-Christophe PLAGNIOL-VILLARD #include <asm/io.h>
45*352d2591SJean-Christophe PLAGNIOL-VILLARD #include <malloc.h>
46*352d2591SJean-Christophe PLAGNIOL-VILLARD #include <video_fb.h>
47*352d2591SJean-Christophe PLAGNIOL-VILLARD 
48*352d2591SJean-Christophe PLAGNIOL-VILLARD #include <radeon.h>
49*352d2591SJean-Christophe PLAGNIOL-VILLARD #include "ati_ids.h"
50*352d2591SJean-Christophe PLAGNIOL-VILLARD #include "ati_radeon_fb.h"
51*352d2591SJean-Christophe PLAGNIOL-VILLARD 
52*352d2591SJean-Christophe PLAGNIOL-VILLARD #undef DEBUG
53*352d2591SJean-Christophe PLAGNIOL-VILLARD 
54*352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef DEBUG
55*352d2591SJean-Christophe PLAGNIOL-VILLARD #define DPRINT(x...) printf(x)
56*352d2591SJean-Christophe PLAGNIOL-VILLARD #else
57*352d2591SJean-Christophe PLAGNIOL-VILLARD #define DPRINT(x...) do{}while(0)
58*352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
59*352d2591SJean-Christophe PLAGNIOL-VILLARD 
60*352d2591SJean-Christophe PLAGNIOL-VILLARD #ifndef min_t
61*352d2591SJean-Christophe PLAGNIOL-VILLARD #define min_t(type,x,y) \
62*352d2591SJean-Christophe PLAGNIOL-VILLARD 	({ type __x = (x); type __y = (y); __x < __y ? __x: __y; })
63*352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
64*352d2591SJean-Christophe PLAGNIOL-VILLARD 
65*352d2591SJean-Christophe PLAGNIOL-VILLARD #define MAX_MAPPED_VRAM	(2048*2048*4)
66*352d2591SJean-Christophe PLAGNIOL-VILLARD #define MIN_MAPPED_VRAM	(1024*768*1)
67*352d2591SJean-Christophe PLAGNIOL-VILLARD 
68*352d2591SJean-Christophe PLAGNIOL-VILLARD /*#define PCI_VENDOR_ID_ATI*/
69*352d2591SJean-Christophe PLAGNIOL-VILLARD #define PCI_CHIP_RV280_5960		0x5960
70*352d2591SJean-Christophe PLAGNIOL-VILLARD #define PCI_CHIP_RV280_5961		0x5961
71*352d2591SJean-Christophe PLAGNIOL-VILLARD #define PCI_CHIP_RV280_5962		0x5962
72*352d2591SJean-Christophe PLAGNIOL-VILLARD #define PCI_CHIP_RV280_5964		0x5964
73*352d2591SJean-Christophe PLAGNIOL-VILLARD #define PCI_CHIP_RV370_5B60		0x5B60
74*352d2591SJean-Christophe PLAGNIOL-VILLARD #define PCI_CHIP_RV380_5657		0x5657
75*352d2591SJean-Christophe PLAGNIOL-VILLARD #define PCI_CHIP_R420_554d		0x554d
76*352d2591SJean-Christophe PLAGNIOL-VILLARD 
77*352d2591SJean-Christophe PLAGNIOL-VILLARD static struct pci_device_id ati_radeon_pci_ids[] = {
78*352d2591SJean-Christophe PLAGNIOL-VILLARD 	{PCI_VENDOR_ID_ATI, PCI_CHIP_RV280_5960},
79*352d2591SJean-Christophe PLAGNIOL-VILLARD 	{PCI_VENDOR_ID_ATI, PCI_CHIP_RV280_5961},
80*352d2591SJean-Christophe PLAGNIOL-VILLARD 	{PCI_VENDOR_ID_ATI, PCI_CHIP_RV280_5962},
81*352d2591SJean-Christophe PLAGNIOL-VILLARD 	{PCI_VENDOR_ID_ATI, PCI_CHIP_RV280_5964},
82*352d2591SJean-Christophe PLAGNIOL-VILLARD 	{PCI_VENDOR_ID_ATI, PCI_CHIP_RV370_5B60},
83*352d2591SJean-Christophe PLAGNIOL-VILLARD 	{PCI_VENDOR_ID_ATI, PCI_CHIP_RV380_5657},
84*352d2591SJean-Christophe PLAGNIOL-VILLARD 	{PCI_VENDOR_ID_ATI, PCI_CHIP_R420_554d},
85*352d2591SJean-Christophe PLAGNIOL-VILLARD 	{0, 0}
86*352d2591SJean-Christophe PLAGNIOL-VILLARD };
87*352d2591SJean-Christophe PLAGNIOL-VILLARD 
88*352d2591SJean-Christophe PLAGNIOL-VILLARD static u16 ati_radeon_id_family_table[][2] = {
89*352d2591SJean-Christophe PLAGNIOL-VILLARD 	{PCI_CHIP_RV280_5960, CHIP_FAMILY_RV280},
90*352d2591SJean-Christophe PLAGNIOL-VILLARD 	{PCI_CHIP_RV280_5961, CHIP_FAMILY_RV280},
91*352d2591SJean-Christophe PLAGNIOL-VILLARD 	{PCI_CHIP_RV280_5962, CHIP_FAMILY_RV280},
92*352d2591SJean-Christophe PLAGNIOL-VILLARD 	{PCI_CHIP_RV280_5964, CHIP_FAMILY_RV280},
93*352d2591SJean-Christophe PLAGNIOL-VILLARD 	{PCI_CHIP_RV370_5B60, CHIP_FAMILY_RV380},
94*352d2591SJean-Christophe PLAGNIOL-VILLARD 	{PCI_CHIP_RV380_5657, CHIP_FAMILY_RV380},
95*352d2591SJean-Christophe PLAGNIOL-VILLARD 	{PCI_CHIP_R420_554d,  CHIP_FAMILY_R420},
96*352d2591SJean-Christophe PLAGNIOL-VILLARD 	{0, 0}
97*352d2591SJean-Christophe PLAGNIOL-VILLARD };
98*352d2591SJean-Christophe PLAGNIOL-VILLARD 
99*352d2591SJean-Christophe PLAGNIOL-VILLARD u16 get_radeon_id_family(u16 device)
100*352d2591SJean-Christophe PLAGNIOL-VILLARD {
101*352d2591SJean-Christophe PLAGNIOL-VILLARD 	int i;
102*352d2591SJean-Christophe PLAGNIOL-VILLARD 	for (i=0; ati_radeon_id_family_table[0][i]; i+=2)
103*352d2591SJean-Christophe PLAGNIOL-VILLARD 		if (ati_radeon_id_family_table[0][i] == device)
104*352d2591SJean-Christophe PLAGNIOL-VILLARD 			return ati_radeon_id_family_table[0][i + 1];
105*352d2591SJean-Christophe PLAGNIOL-VILLARD 	return 0;
106*352d2591SJean-Christophe PLAGNIOL-VILLARD }
107*352d2591SJean-Christophe PLAGNIOL-VILLARD 
108*352d2591SJean-Christophe PLAGNIOL-VILLARD struct radeonfb_info *rinfo;
109*352d2591SJean-Christophe PLAGNIOL-VILLARD 
110*352d2591SJean-Christophe PLAGNIOL-VILLARD static void radeon_identify_vram(struct radeonfb_info *rinfo)
111*352d2591SJean-Christophe PLAGNIOL-VILLARD {
112*352d2591SJean-Christophe PLAGNIOL-VILLARD 	u32 tmp;
113*352d2591SJean-Christophe PLAGNIOL-VILLARD 
114*352d2591SJean-Christophe PLAGNIOL-VILLARD 	/* framebuffer size */
115*352d2591SJean-Christophe PLAGNIOL-VILLARD 	if ((rinfo->family == CHIP_FAMILY_RS100) ||
116*352d2591SJean-Christophe PLAGNIOL-VILLARD 		(rinfo->family == CHIP_FAMILY_RS200) ||
117*352d2591SJean-Christophe PLAGNIOL-VILLARD 		(rinfo->family == CHIP_FAMILY_RS300)) {
118*352d2591SJean-Christophe PLAGNIOL-VILLARD 		u32 tom = INREG(NB_TOM);
119*352d2591SJean-Christophe PLAGNIOL-VILLARD 		tmp = ((((tom >> 16) - (tom & 0xffff) + 1) << 6) * 1024);
120*352d2591SJean-Christophe PLAGNIOL-VILLARD 
121*352d2591SJean-Christophe PLAGNIOL-VILLARD 		radeon_fifo_wait(6);
122*352d2591SJean-Christophe PLAGNIOL-VILLARD 		OUTREG(MC_FB_LOCATION, tom);
123*352d2591SJean-Christophe PLAGNIOL-VILLARD 		OUTREG(DISPLAY_BASE_ADDR, (tom & 0xffff) << 16);
124*352d2591SJean-Christophe PLAGNIOL-VILLARD 		OUTREG(CRTC2_DISPLAY_BASE_ADDR, (tom & 0xffff) << 16);
125*352d2591SJean-Christophe PLAGNIOL-VILLARD 		OUTREG(OV0_BASE_ADDR, (tom & 0xffff) << 16);
126*352d2591SJean-Christophe PLAGNIOL-VILLARD 
127*352d2591SJean-Christophe PLAGNIOL-VILLARD 		/* This is supposed to fix the crtc2 noise problem. */
128*352d2591SJean-Christophe PLAGNIOL-VILLARD 		OUTREG(GRPH2_BUFFER_CNTL, INREG(GRPH2_BUFFER_CNTL) & ~0x7f0000);
129*352d2591SJean-Christophe PLAGNIOL-VILLARD 
130*352d2591SJean-Christophe PLAGNIOL-VILLARD 		if ((rinfo->family == CHIP_FAMILY_RS100) ||
131*352d2591SJean-Christophe PLAGNIOL-VILLARD 			(rinfo->family == CHIP_FAMILY_RS200)) {
132*352d2591SJean-Christophe PLAGNIOL-VILLARD 		/* This is to workaround the asic bug for RMX, some versions
133*352d2591SJean-Christophe PLAGNIOL-VILLARD 		   of BIOS dosen't have this register initialized correctly.
134*352d2591SJean-Christophe PLAGNIOL-VILLARD 		*/
135*352d2591SJean-Christophe PLAGNIOL-VILLARD 			OUTREGP(CRTC_MORE_CNTL, CRTC_H_CUTOFF_ACTIVE_EN,
136*352d2591SJean-Christophe PLAGNIOL-VILLARD 				~CRTC_H_CUTOFF_ACTIVE_EN);
137*352d2591SJean-Christophe PLAGNIOL-VILLARD 		}
138*352d2591SJean-Christophe PLAGNIOL-VILLARD 	} else {
139*352d2591SJean-Christophe PLAGNIOL-VILLARD 		tmp = INREG(CONFIG_MEMSIZE);
140*352d2591SJean-Christophe PLAGNIOL-VILLARD 	}
141*352d2591SJean-Christophe PLAGNIOL-VILLARD 
142*352d2591SJean-Christophe PLAGNIOL-VILLARD 	/* mem size is bits [28:0], mask off the rest */
143*352d2591SJean-Christophe PLAGNIOL-VILLARD 	rinfo->video_ram = tmp & CONFIG_MEMSIZE_MASK;
144*352d2591SJean-Christophe PLAGNIOL-VILLARD 
145*352d2591SJean-Christophe PLAGNIOL-VILLARD 	/*
146*352d2591SJean-Christophe PLAGNIOL-VILLARD 	 * Hack to get around some busted production M6's
147*352d2591SJean-Christophe PLAGNIOL-VILLARD 	 * reporting no ram
148*352d2591SJean-Christophe PLAGNIOL-VILLARD 	 */
149*352d2591SJean-Christophe PLAGNIOL-VILLARD 	if (rinfo->video_ram == 0) {
150*352d2591SJean-Christophe PLAGNIOL-VILLARD 		switch (rinfo->pdev.device) {
151*352d2591SJean-Christophe PLAGNIOL-VILLARD 		case PCI_CHIP_RADEON_LY:
152*352d2591SJean-Christophe PLAGNIOL-VILLARD 		case PCI_CHIP_RADEON_LZ:
153*352d2591SJean-Christophe PLAGNIOL-VILLARD 			rinfo->video_ram = 8192 * 1024;
154*352d2591SJean-Christophe PLAGNIOL-VILLARD 			break;
155*352d2591SJean-Christophe PLAGNIOL-VILLARD 		default:
156*352d2591SJean-Christophe PLAGNIOL-VILLARD 			break;
157*352d2591SJean-Christophe PLAGNIOL-VILLARD 		}
158*352d2591SJean-Christophe PLAGNIOL-VILLARD 	}
159*352d2591SJean-Christophe PLAGNIOL-VILLARD 
160*352d2591SJean-Christophe PLAGNIOL-VILLARD 	/*
161*352d2591SJean-Christophe PLAGNIOL-VILLARD 	 * Now try to identify VRAM type
162*352d2591SJean-Christophe PLAGNIOL-VILLARD 	 */
163*352d2591SJean-Christophe PLAGNIOL-VILLARD 	if ((rinfo->family >= CHIP_FAMILY_R300) ||
164*352d2591SJean-Christophe PLAGNIOL-VILLARD 	    (INREG(MEM_SDRAM_MODE_REG) & (1<<30)))
165*352d2591SJean-Christophe PLAGNIOL-VILLARD 		rinfo->vram_ddr = 1;
166*352d2591SJean-Christophe PLAGNIOL-VILLARD 	else
167*352d2591SJean-Christophe PLAGNIOL-VILLARD 		rinfo->vram_ddr = 0;
168*352d2591SJean-Christophe PLAGNIOL-VILLARD 
169*352d2591SJean-Christophe PLAGNIOL-VILLARD 	tmp = INREG(MEM_CNTL);
170*352d2591SJean-Christophe PLAGNIOL-VILLARD 	if (IS_R300_VARIANT(rinfo)) {
171*352d2591SJean-Christophe PLAGNIOL-VILLARD 		tmp &=  R300_MEM_NUM_CHANNELS_MASK;
172*352d2591SJean-Christophe PLAGNIOL-VILLARD 		switch (tmp) {
173*352d2591SJean-Christophe PLAGNIOL-VILLARD 		case 0:  rinfo->vram_width = 64; break;
174*352d2591SJean-Christophe PLAGNIOL-VILLARD 		case 1:  rinfo->vram_width = 128; break;
175*352d2591SJean-Christophe PLAGNIOL-VILLARD 		case 2:  rinfo->vram_width = 256; break;
176*352d2591SJean-Christophe PLAGNIOL-VILLARD 		default: rinfo->vram_width = 128; break;
177*352d2591SJean-Christophe PLAGNIOL-VILLARD 		}
178*352d2591SJean-Christophe PLAGNIOL-VILLARD 	} else if ((rinfo->family == CHIP_FAMILY_RV100) ||
179*352d2591SJean-Christophe PLAGNIOL-VILLARD 		   (rinfo->family == CHIP_FAMILY_RS100) ||
180*352d2591SJean-Christophe PLAGNIOL-VILLARD 		   (rinfo->family == CHIP_FAMILY_RS200)){
181*352d2591SJean-Christophe PLAGNIOL-VILLARD 		if (tmp & RV100_MEM_HALF_MODE)
182*352d2591SJean-Christophe PLAGNIOL-VILLARD 			rinfo->vram_width = 32;
183*352d2591SJean-Christophe PLAGNIOL-VILLARD 		else
184*352d2591SJean-Christophe PLAGNIOL-VILLARD 			rinfo->vram_width = 64;
185*352d2591SJean-Christophe PLAGNIOL-VILLARD 	} else {
186*352d2591SJean-Christophe PLAGNIOL-VILLARD 		if (tmp & MEM_NUM_CHANNELS_MASK)
187*352d2591SJean-Christophe PLAGNIOL-VILLARD 			rinfo->vram_width = 128;
188*352d2591SJean-Christophe PLAGNIOL-VILLARD 		else
189*352d2591SJean-Christophe PLAGNIOL-VILLARD 			rinfo->vram_width = 64;
190*352d2591SJean-Christophe PLAGNIOL-VILLARD 	}
191*352d2591SJean-Christophe PLAGNIOL-VILLARD 
192*352d2591SJean-Christophe PLAGNIOL-VILLARD 	/* This may not be correct, as some cards can have half of channel disabled
193*352d2591SJean-Christophe PLAGNIOL-VILLARD 	 * ToDo: identify these cases
194*352d2591SJean-Christophe PLAGNIOL-VILLARD 	 */
195*352d2591SJean-Christophe PLAGNIOL-VILLARD 
196*352d2591SJean-Christophe PLAGNIOL-VILLARD 	DPRINT("radeonfb: Found %ldk of %s %d bits wide videoram\n",
197*352d2591SJean-Christophe PLAGNIOL-VILLARD 	       rinfo->video_ram / 1024,
198*352d2591SJean-Christophe PLAGNIOL-VILLARD 	       rinfo->vram_ddr ? "DDR" : "SDRAM",
199*352d2591SJean-Christophe PLAGNIOL-VILLARD 	       rinfo->vram_width);
200*352d2591SJean-Christophe PLAGNIOL-VILLARD 
201*352d2591SJean-Christophe PLAGNIOL-VILLARD }
202*352d2591SJean-Christophe PLAGNIOL-VILLARD 
203*352d2591SJean-Christophe PLAGNIOL-VILLARD static void radeon_write_pll_regs(struct radeonfb_info *rinfo, struct radeon_regs *mode)
204*352d2591SJean-Christophe PLAGNIOL-VILLARD {
205*352d2591SJean-Christophe PLAGNIOL-VILLARD 	int i;
206*352d2591SJean-Christophe PLAGNIOL-VILLARD 
207*352d2591SJean-Christophe PLAGNIOL-VILLARD 	radeon_fifo_wait(20);
208*352d2591SJean-Christophe PLAGNIOL-VILLARD 
209*352d2591SJean-Christophe PLAGNIOL-VILLARD #if 0
210*352d2591SJean-Christophe PLAGNIOL-VILLARD 	/* Workaround from XFree */
211*352d2591SJean-Christophe PLAGNIOL-VILLARD 	if (rinfo->is_mobility) {
212*352d2591SJean-Christophe PLAGNIOL-VILLARD 		/* A temporal workaround for the occational blanking on certain laptop
213*352d2591SJean-Christophe PLAGNIOL-VILLARD 		 * panels. This appears to related to the PLL divider registers
214*352d2591SJean-Christophe PLAGNIOL-VILLARD 		 * (fail to lock?). It occurs even when all dividers are the same
215*352d2591SJean-Christophe PLAGNIOL-VILLARD 		 * with their old settings. In this case we really don't need to
216*352d2591SJean-Christophe PLAGNIOL-VILLARD 		 * fiddle with PLL registers. By doing this we can avoid the blanking
217*352d2591SJean-Christophe PLAGNIOL-VILLARD 		 * problem with some panels.
218*352d2591SJean-Christophe PLAGNIOL-VILLARD 		 */
219*352d2591SJean-Christophe PLAGNIOL-VILLARD 		if ((mode->ppll_ref_div == (INPLL(PPLL_REF_DIV) & PPLL_REF_DIV_MASK)) &&
220*352d2591SJean-Christophe PLAGNIOL-VILLARD 		    (mode->ppll_div_3 == (INPLL(PPLL_DIV_3) &
221*352d2591SJean-Christophe PLAGNIOL-VILLARD 					  (PPLL_POST3_DIV_MASK | PPLL_FB3_DIV_MASK)))) {
222*352d2591SJean-Christophe PLAGNIOL-VILLARD 			/* We still have to force a switch to selected PPLL div thanks to
223*352d2591SJean-Christophe PLAGNIOL-VILLARD 			 * an XFree86 driver bug which will switch it away in some cases
224*352d2591SJean-Christophe PLAGNIOL-VILLARD 			 * even when using UseFDev */
225*352d2591SJean-Christophe PLAGNIOL-VILLARD 			OUTREGP(CLOCK_CNTL_INDEX,
226*352d2591SJean-Christophe PLAGNIOL-VILLARD 				mode->clk_cntl_index & PPLL_DIV_SEL_MASK,
227*352d2591SJean-Christophe PLAGNIOL-VILLARD 				~PPLL_DIV_SEL_MASK);
228*352d2591SJean-Christophe PLAGNIOL-VILLARD 			radeon_pll_errata_after_index(rinfo);
229*352d2591SJean-Christophe PLAGNIOL-VILLARD 			radeon_pll_errata_after_data(rinfo);
230*352d2591SJean-Christophe PLAGNIOL-VILLARD 			return;
231*352d2591SJean-Christophe PLAGNIOL-VILLARD 		}
232*352d2591SJean-Christophe PLAGNIOL-VILLARD 	}
233*352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
234*352d2591SJean-Christophe PLAGNIOL-VILLARD 	if(rinfo->pdev.device == PCI_CHIP_RV370_5B60) return;
235*352d2591SJean-Christophe PLAGNIOL-VILLARD 
236*352d2591SJean-Christophe PLAGNIOL-VILLARD 	/* Swich VCKL clock input to CPUCLK so it stays fed while PPLL updates*/
237*352d2591SJean-Christophe PLAGNIOL-VILLARD 	OUTPLLP(VCLK_ECP_CNTL, VCLK_SRC_SEL_CPUCLK, ~VCLK_SRC_SEL_MASK);
238*352d2591SJean-Christophe PLAGNIOL-VILLARD 
239*352d2591SJean-Christophe PLAGNIOL-VILLARD 	/* Reset PPLL & enable atomic update */
240*352d2591SJean-Christophe PLAGNIOL-VILLARD 	OUTPLLP(PPLL_CNTL,
241*352d2591SJean-Christophe PLAGNIOL-VILLARD 		PPLL_RESET | PPLL_ATOMIC_UPDATE_EN | PPLL_VGA_ATOMIC_UPDATE_EN,
242*352d2591SJean-Christophe PLAGNIOL-VILLARD 		~(PPLL_RESET | PPLL_ATOMIC_UPDATE_EN | PPLL_VGA_ATOMIC_UPDATE_EN));
243*352d2591SJean-Christophe PLAGNIOL-VILLARD 
244*352d2591SJean-Christophe PLAGNIOL-VILLARD 	/* Switch to selected PPLL divider */
245*352d2591SJean-Christophe PLAGNIOL-VILLARD 	OUTREGP(CLOCK_CNTL_INDEX,
246*352d2591SJean-Christophe PLAGNIOL-VILLARD 		mode->clk_cntl_index & PPLL_DIV_SEL_MASK,
247*352d2591SJean-Christophe PLAGNIOL-VILLARD 		~PPLL_DIV_SEL_MASK);
248*352d2591SJean-Christophe PLAGNIOL-VILLARD 
249*352d2591SJean-Christophe PLAGNIOL-VILLARD 	/* Set PPLL ref. div */
250*352d2591SJean-Christophe PLAGNIOL-VILLARD 	if (rinfo->family == CHIP_FAMILY_R300 ||
251*352d2591SJean-Christophe PLAGNIOL-VILLARD 	    rinfo->family == CHIP_FAMILY_RS300 ||
252*352d2591SJean-Christophe PLAGNIOL-VILLARD 	    rinfo->family == CHIP_FAMILY_R350 ||
253*352d2591SJean-Christophe PLAGNIOL-VILLARD 	    rinfo->family == CHIP_FAMILY_RV350) {
254*352d2591SJean-Christophe PLAGNIOL-VILLARD 		if (mode->ppll_ref_div & R300_PPLL_REF_DIV_ACC_MASK) {
255*352d2591SJean-Christophe PLAGNIOL-VILLARD 			/* When restoring console mode, use saved PPLL_REF_DIV
256*352d2591SJean-Christophe PLAGNIOL-VILLARD 			 * setting.
257*352d2591SJean-Christophe PLAGNIOL-VILLARD 			 */
258*352d2591SJean-Christophe PLAGNIOL-VILLARD 			OUTPLLP(PPLL_REF_DIV, mode->ppll_ref_div, 0);
259*352d2591SJean-Christophe PLAGNIOL-VILLARD 		} else {
260*352d2591SJean-Christophe PLAGNIOL-VILLARD 			/* R300 uses ref_div_acc field as real ref divider */
261*352d2591SJean-Christophe PLAGNIOL-VILLARD 			OUTPLLP(PPLL_REF_DIV,
262*352d2591SJean-Christophe PLAGNIOL-VILLARD 				(mode->ppll_ref_div << R300_PPLL_REF_DIV_ACC_SHIFT),
263*352d2591SJean-Christophe PLAGNIOL-VILLARD 				~R300_PPLL_REF_DIV_ACC_MASK);
264*352d2591SJean-Christophe PLAGNIOL-VILLARD 		}
265*352d2591SJean-Christophe PLAGNIOL-VILLARD 	} else
266*352d2591SJean-Christophe PLAGNIOL-VILLARD 		OUTPLLP(PPLL_REF_DIV, mode->ppll_ref_div, ~PPLL_REF_DIV_MASK);
267*352d2591SJean-Christophe PLAGNIOL-VILLARD 
268*352d2591SJean-Christophe PLAGNIOL-VILLARD 	/* Set PPLL divider 3 & post divider*/
269*352d2591SJean-Christophe PLAGNIOL-VILLARD 	OUTPLLP(PPLL_DIV_3, mode->ppll_div_3, ~PPLL_FB3_DIV_MASK);
270*352d2591SJean-Christophe PLAGNIOL-VILLARD 	OUTPLLP(PPLL_DIV_3, mode->ppll_div_3, ~PPLL_POST3_DIV_MASK);
271*352d2591SJean-Christophe PLAGNIOL-VILLARD 
272*352d2591SJean-Christophe PLAGNIOL-VILLARD 	/* Write update */
273*352d2591SJean-Christophe PLAGNIOL-VILLARD 	while (INPLL(PPLL_REF_DIV) & PPLL_ATOMIC_UPDATE_R)
274*352d2591SJean-Christophe PLAGNIOL-VILLARD 		;
275*352d2591SJean-Christophe PLAGNIOL-VILLARD 	OUTPLLP(PPLL_REF_DIV, PPLL_ATOMIC_UPDATE_W, ~PPLL_ATOMIC_UPDATE_W);
276*352d2591SJean-Christophe PLAGNIOL-VILLARD 
277*352d2591SJean-Christophe PLAGNIOL-VILLARD 	/* Wait read update complete */
278*352d2591SJean-Christophe PLAGNIOL-VILLARD 	/* FIXME: Certain revisions of R300 can't recover here.  Not sure of
279*352d2591SJean-Christophe PLAGNIOL-VILLARD 	   the cause yet, but this workaround will mask the problem for now.
280*352d2591SJean-Christophe PLAGNIOL-VILLARD 	   Other chips usually will pass at the very first test, so the
281*352d2591SJean-Christophe PLAGNIOL-VILLARD 	   workaround shouldn't have any effect on them. */
282*352d2591SJean-Christophe PLAGNIOL-VILLARD 	for (i = 0; (i < 10000 && INPLL(PPLL_REF_DIV) & PPLL_ATOMIC_UPDATE_R); i++)
283*352d2591SJean-Christophe PLAGNIOL-VILLARD 		;
284*352d2591SJean-Christophe PLAGNIOL-VILLARD 
285*352d2591SJean-Christophe PLAGNIOL-VILLARD 	OUTPLL(HTOTAL_CNTL, 0);
286*352d2591SJean-Christophe PLAGNIOL-VILLARD 
287*352d2591SJean-Christophe PLAGNIOL-VILLARD 	/* Clear reset & atomic update */
288*352d2591SJean-Christophe PLAGNIOL-VILLARD 	OUTPLLP(PPLL_CNTL, 0,
289*352d2591SJean-Christophe PLAGNIOL-VILLARD 		~(PPLL_RESET | PPLL_SLEEP | PPLL_ATOMIC_UPDATE_EN | PPLL_VGA_ATOMIC_UPDATE_EN));
290*352d2591SJean-Christophe PLAGNIOL-VILLARD 
291*352d2591SJean-Christophe PLAGNIOL-VILLARD 	/* We may want some locking ... oh well */
292*352d2591SJean-Christophe PLAGNIOL-VILLARD 	udelay(5000);
293*352d2591SJean-Christophe PLAGNIOL-VILLARD 
294*352d2591SJean-Christophe PLAGNIOL-VILLARD 	/* Switch back VCLK source to PPLL */
295*352d2591SJean-Christophe PLAGNIOL-VILLARD 	OUTPLLP(VCLK_ECP_CNTL, VCLK_SRC_SEL_PPLLCLK, ~VCLK_SRC_SEL_MASK);
296*352d2591SJean-Christophe PLAGNIOL-VILLARD }
297*352d2591SJean-Christophe PLAGNIOL-VILLARD 
298*352d2591SJean-Christophe PLAGNIOL-VILLARD typedef struct {
299*352d2591SJean-Christophe PLAGNIOL-VILLARD 	u16 reg;
300*352d2591SJean-Christophe PLAGNIOL-VILLARD 	u32 val;
301*352d2591SJean-Christophe PLAGNIOL-VILLARD } reg_val;
302*352d2591SJean-Christophe PLAGNIOL-VILLARD 
303*352d2591SJean-Christophe PLAGNIOL-VILLARD #if 0	/* unused ? -> scheduled for removal */
304*352d2591SJean-Christophe PLAGNIOL-VILLARD /* these common regs are cleared before mode setting so they do not
305*352d2591SJean-Christophe PLAGNIOL-VILLARD  * interfere with anything
306*352d2591SJean-Christophe PLAGNIOL-VILLARD  */
307*352d2591SJean-Christophe PLAGNIOL-VILLARD static reg_val common_regs[] = {
308*352d2591SJean-Christophe PLAGNIOL-VILLARD 	{ OVR_CLR, 0 },
309*352d2591SJean-Christophe PLAGNIOL-VILLARD 	{ OVR_WID_LEFT_RIGHT, 0 },
310*352d2591SJean-Christophe PLAGNIOL-VILLARD 	{ OVR_WID_TOP_BOTTOM, 0 },
311*352d2591SJean-Christophe PLAGNIOL-VILLARD 	{ OV0_SCALE_CNTL, 0 },
312*352d2591SJean-Christophe PLAGNIOL-VILLARD 	{ SUBPIC_CNTL, 0 },
313*352d2591SJean-Christophe PLAGNIOL-VILLARD 	{ VIPH_CONTROL, 0 },
314*352d2591SJean-Christophe PLAGNIOL-VILLARD 	{ I2C_CNTL_1, 0 },
315*352d2591SJean-Christophe PLAGNIOL-VILLARD 	{ GEN_INT_CNTL, 0 },
316*352d2591SJean-Christophe PLAGNIOL-VILLARD 	{ CAP0_TRIG_CNTL, 0 },
317*352d2591SJean-Christophe PLAGNIOL-VILLARD 	{ CAP1_TRIG_CNTL, 0 },
318*352d2591SJean-Christophe PLAGNIOL-VILLARD };
319*352d2591SJean-Christophe PLAGNIOL-VILLARD #endif /* 0 */
320*352d2591SJean-Christophe PLAGNIOL-VILLARD 
321*352d2591SJean-Christophe PLAGNIOL-VILLARD void radeon_setmode(void)
322*352d2591SJean-Christophe PLAGNIOL-VILLARD {
323*352d2591SJean-Christophe PLAGNIOL-VILLARD 	struct radeon_regs *mode = malloc(sizeof(struct radeon_regs));
324*352d2591SJean-Christophe PLAGNIOL-VILLARD 
325*352d2591SJean-Christophe PLAGNIOL-VILLARD 	mode->crtc_gen_cntl = 0x03000200;
326*352d2591SJean-Christophe PLAGNIOL-VILLARD 	mode->crtc_ext_cntl = 0x00008048;
327*352d2591SJean-Christophe PLAGNIOL-VILLARD 	mode->dac_cntl = 0xff002100;
328*352d2591SJean-Christophe PLAGNIOL-VILLARD 	mode->crtc_h_total_disp = 0x4f0063;
329*352d2591SJean-Christophe PLAGNIOL-VILLARD 	mode->crtc_h_sync_strt_wid = 0x8c02a2;
330*352d2591SJean-Christophe PLAGNIOL-VILLARD 	mode->crtc_v_total_disp = 0x01df020c;
331*352d2591SJean-Christophe PLAGNIOL-VILLARD 	mode->crtc_v_sync_strt_wid = 0x8201ea;
332*352d2591SJean-Christophe PLAGNIOL-VILLARD 	mode->crtc_pitch = 0x00500050;
333*352d2591SJean-Christophe PLAGNIOL-VILLARD 
334*352d2591SJean-Christophe PLAGNIOL-VILLARD 	OUTREG(CRTC_GEN_CNTL, mode->crtc_gen_cntl);
335*352d2591SJean-Christophe PLAGNIOL-VILLARD 	OUTREGP(CRTC_EXT_CNTL, mode->crtc_ext_cntl,
336*352d2591SJean-Christophe PLAGNIOL-VILLARD 		~(CRTC_HSYNC_DIS | CRTC_VSYNC_DIS | CRTC_DISPLAY_DIS));
337*352d2591SJean-Christophe PLAGNIOL-VILLARD 	OUTREGP(DAC_CNTL, mode->dac_cntl, DAC_RANGE_CNTL | DAC_BLANKING);
338*352d2591SJean-Christophe PLAGNIOL-VILLARD 	OUTREG(CRTC_H_TOTAL_DISP, mode->crtc_h_total_disp);
339*352d2591SJean-Christophe PLAGNIOL-VILLARD 	OUTREG(CRTC_H_SYNC_STRT_WID, mode->crtc_h_sync_strt_wid);
340*352d2591SJean-Christophe PLAGNIOL-VILLARD 	OUTREG(CRTC_V_TOTAL_DISP, mode->crtc_v_total_disp);
341*352d2591SJean-Christophe PLAGNIOL-VILLARD 	OUTREG(CRTC_V_SYNC_STRT_WID, mode->crtc_v_sync_strt_wid);
342*352d2591SJean-Christophe PLAGNIOL-VILLARD 	OUTREG(CRTC_OFFSET, 0);
343*352d2591SJean-Christophe PLAGNIOL-VILLARD 	OUTREG(CRTC_OFFSET_CNTL, 0);
344*352d2591SJean-Christophe PLAGNIOL-VILLARD 	OUTREG(CRTC_PITCH, mode->crtc_pitch);
345*352d2591SJean-Christophe PLAGNIOL-VILLARD 
346*352d2591SJean-Christophe PLAGNIOL-VILLARD 	mode->clk_cntl_index = 0x300;
347*352d2591SJean-Christophe PLAGNIOL-VILLARD 	mode->ppll_ref_div = 0xc;
348*352d2591SJean-Christophe PLAGNIOL-VILLARD 	mode->ppll_div_3 = 0x00030059;
349*352d2591SJean-Christophe PLAGNIOL-VILLARD 
350*352d2591SJean-Christophe PLAGNIOL-VILLARD 	radeon_write_pll_regs(rinfo, mode);
351*352d2591SJean-Christophe PLAGNIOL-VILLARD }
352*352d2591SJean-Christophe PLAGNIOL-VILLARD 
353*352d2591SJean-Christophe PLAGNIOL-VILLARD #include "../bios_emulator/include/biosemu.h"
354*352d2591SJean-Christophe PLAGNIOL-VILLARD extern int BootVideoCardBIOS(pci_dev_t pcidev, BE_VGAInfo ** pVGAInfo, int cleanUp);
355*352d2591SJean-Christophe PLAGNIOL-VILLARD 
356*352d2591SJean-Christophe PLAGNIOL-VILLARD int radeon_probe(struct radeonfb_info *rinfo)
357*352d2591SJean-Christophe PLAGNIOL-VILLARD {
358*352d2591SJean-Christophe PLAGNIOL-VILLARD 	pci_dev_t pdev;
359*352d2591SJean-Christophe PLAGNIOL-VILLARD 	u16 did;
360*352d2591SJean-Christophe PLAGNIOL-VILLARD 
361*352d2591SJean-Christophe PLAGNIOL-VILLARD 	pdev = pci_find_devices(ati_radeon_pci_ids, 0);
362*352d2591SJean-Christophe PLAGNIOL-VILLARD 
363*352d2591SJean-Christophe PLAGNIOL-VILLARD 	if (pdev != -1) {
364*352d2591SJean-Christophe PLAGNIOL-VILLARD 		pci_read_config_word(pdev, PCI_DEVICE_ID, &did);
365*352d2591SJean-Christophe PLAGNIOL-VILLARD 		printf("ATI Radeon video card (%04x, %04x) found @(%d:%d:%d)\n",
366*352d2591SJean-Christophe PLAGNIOL-VILLARD 				PCI_VENDOR_ID_ATI, did, (pdev >> 16) & 0xff,
367*352d2591SJean-Christophe PLAGNIOL-VILLARD 				(pdev >> 11) & 0x1f, (pdev >> 8) & 0x7);
368*352d2591SJean-Christophe PLAGNIOL-VILLARD 
369*352d2591SJean-Christophe PLAGNIOL-VILLARD 		strcpy(rinfo->name, "ATI Radeon");
370*352d2591SJean-Christophe PLAGNIOL-VILLARD 		rinfo->pdev.vendor = PCI_VENDOR_ID_ATI;
371*352d2591SJean-Christophe PLAGNIOL-VILLARD 		rinfo->pdev.device = did;
372*352d2591SJean-Christophe PLAGNIOL-VILLARD 		rinfo->family = get_radeon_id_family(rinfo->pdev.device);
373*352d2591SJean-Christophe PLAGNIOL-VILLARD 		pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0,
374*352d2591SJean-Christophe PLAGNIOL-VILLARD 				&rinfo->fb_base_phys);
375*352d2591SJean-Christophe PLAGNIOL-VILLARD 		pci_read_config_dword(pdev, PCI_BASE_ADDRESS_2,
376*352d2591SJean-Christophe PLAGNIOL-VILLARD 				&rinfo->mmio_base_phys);
377*352d2591SJean-Christophe PLAGNIOL-VILLARD 		rinfo->fb_base_phys &= 0xfffff000;
378*352d2591SJean-Christophe PLAGNIOL-VILLARD 		rinfo->mmio_base_phys &= ~0x04;
379*352d2591SJean-Christophe PLAGNIOL-VILLARD 
380*352d2591SJean-Christophe PLAGNIOL-VILLARD 		rinfo->mmio_base = (void *)rinfo->mmio_base_phys;
381*352d2591SJean-Christophe PLAGNIOL-VILLARD 		DPRINT("rinfo->mmio_base = 0x%x\n",rinfo->mmio_base);
382*352d2591SJean-Christophe PLAGNIOL-VILLARD 		rinfo->fb_local_base = INREG(MC_FB_LOCATION) << 16;
383*352d2591SJean-Christophe PLAGNIOL-VILLARD 		DPRINT("rinfo->fb_local_base = 0x%x\n",rinfo->fb_local_base);
384*352d2591SJean-Christophe PLAGNIOL-VILLARD 		/* PostBIOS with x86 emulater */
385*352d2591SJean-Christophe PLAGNIOL-VILLARD 		BootVideoCardBIOS(pdev, NULL, 0);
386*352d2591SJean-Christophe PLAGNIOL-VILLARD 
387*352d2591SJean-Christophe PLAGNIOL-VILLARD 		/*
388*352d2591SJean-Christophe PLAGNIOL-VILLARD 		 * Check for errata
389*352d2591SJean-Christophe PLAGNIOL-VILLARD 		 * (These will be added in the future for the chipfamily
390*352d2591SJean-Christophe PLAGNIOL-VILLARD 		 * R300, RV200, RS200, RV100, RS100.)
391*352d2591SJean-Christophe PLAGNIOL-VILLARD 		 */
392*352d2591SJean-Christophe PLAGNIOL-VILLARD 
393*352d2591SJean-Christophe PLAGNIOL-VILLARD 		/* Get VRAM size and type */
394*352d2591SJean-Christophe PLAGNIOL-VILLARD 		radeon_identify_vram(rinfo);
395*352d2591SJean-Christophe PLAGNIOL-VILLARD 
396*352d2591SJean-Christophe PLAGNIOL-VILLARD 		rinfo->mapped_vram = min_t(unsigned long, MAX_MAPPED_VRAM,
397*352d2591SJean-Christophe PLAGNIOL-VILLARD 				rinfo->video_ram);
398*352d2591SJean-Christophe PLAGNIOL-VILLARD 		rinfo->fb_base = (void *)rinfo->fb_base_phys;
399*352d2591SJean-Christophe PLAGNIOL-VILLARD 
400*352d2591SJean-Christophe PLAGNIOL-VILLARD 		DPRINT("Radeon: framebuffer base phy address 0x%08x," \
401*352d2591SJean-Christophe PLAGNIOL-VILLARD 		      "MMIO base phy address 0x%08x," \
402*352d2591SJean-Christophe PLAGNIOL-VILLARD 		      "framebuffer local base 0x%08x.\n ",
403*352d2591SJean-Christophe PLAGNIOL-VILLARD 		      rinfo->fb_base_phys, rinfo->mmio_base_phys,
404*352d2591SJean-Christophe PLAGNIOL-VILLARD 		      rinfo->fb_local_base);
405*352d2591SJean-Christophe PLAGNIOL-VILLARD 
406*352d2591SJean-Christophe PLAGNIOL-VILLARD 		return 0;
407*352d2591SJean-Christophe PLAGNIOL-VILLARD 	}
408*352d2591SJean-Christophe PLAGNIOL-VILLARD 	return -1;
409*352d2591SJean-Christophe PLAGNIOL-VILLARD }
410*352d2591SJean-Christophe PLAGNIOL-VILLARD 
411*352d2591SJean-Christophe PLAGNIOL-VILLARD /*
412*352d2591SJean-Christophe PLAGNIOL-VILLARD  * The Graphic Device
413*352d2591SJean-Christophe PLAGNIOL-VILLARD  */
414*352d2591SJean-Christophe PLAGNIOL-VILLARD GraphicDevice ctfb;
415*352d2591SJean-Christophe PLAGNIOL-VILLARD 
416*352d2591SJean-Christophe PLAGNIOL-VILLARD #define CURSOR_SIZE	0x1000	/* in KByte for HW Cursor */
417*352d2591SJean-Christophe PLAGNIOL-VILLARD #define PATTERN_ADR	(pGD->dprBase + CURSOR_SIZE)	/* pattern Memory after Cursor Memory */
418*352d2591SJean-Christophe PLAGNIOL-VILLARD #define PATTERN_SIZE	8*8*4	/* 4 Bytes per Pixel 8 x 8 Pixel */
419*352d2591SJean-Christophe PLAGNIOL-VILLARD #define ACCELMEMORY	(CURSOR_SIZE + PATTERN_SIZE)	/* reserved Memory for BITBlt and hw cursor */
420*352d2591SJean-Christophe PLAGNIOL-VILLARD 
421*352d2591SJean-Christophe PLAGNIOL-VILLARD void *video_hw_init(void)
422*352d2591SJean-Christophe PLAGNIOL-VILLARD {
423*352d2591SJean-Christophe PLAGNIOL-VILLARD 	GraphicDevice *pGD = (GraphicDevice *) & ctfb;
424*352d2591SJean-Christophe PLAGNIOL-VILLARD 	int i;
425*352d2591SJean-Christophe PLAGNIOL-VILLARD 	u32 *vm;
426*352d2591SJean-Christophe PLAGNIOL-VILLARD 
427*352d2591SJean-Christophe PLAGNIOL-VILLARD 	rinfo = malloc(sizeof(struct radeonfb_info));
428*352d2591SJean-Christophe PLAGNIOL-VILLARD 
429*352d2591SJean-Christophe PLAGNIOL-VILLARD 	if(radeon_probe(rinfo)) {
430*352d2591SJean-Christophe PLAGNIOL-VILLARD 		printf("No radeon video card found!\n");
431*352d2591SJean-Christophe PLAGNIOL-VILLARD 		return NULL;
432*352d2591SJean-Christophe PLAGNIOL-VILLARD 	}
433*352d2591SJean-Christophe PLAGNIOL-VILLARD 
434*352d2591SJean-Christophe PLAGNIOL-VILLARD 	/* fill in Graphic device struct */
435*352d2591SJean-Christophe PLAGNIOL-VILLARD 	sprintf (pGD->modeIdent, "%dx%dx%d %ldkHz %ldHz", 640,
436*352d2591SJean-Christophe PLAGNIOL-VILLARD 		 480, 16, (1000 / 1000),
437*352d2591SJean-Christophe PLAGNIOL-VILLARD 		 (2000 / 1000));
438*352d2591SJean-Christophe PLAGNIOL-VILLARD 	printf ("%s\n", pGD->modeIdent);
439*352d2591SJean-Christophe PLAGNIOL-VILLARD 
440*352d2591SJean-Christophe PLAGNIOL-VILLARD 	pGD->winSizeX = 640;
441*352d2591SJean-Christophe PLAGNIOL-VILLARD 	pGD->winSizeY = 480;
442*352d2591SJean-Christophe PLAGNIOL-VILLARD 	pGD->plnSizeX = 640;
443*352d2591SJean-Christophe PLAGNIOL-VILLARD 	pGD->plnSizeY = 480;
444*352d2591SJean-Christophe PLAGNIOL-VILLARD 
445*352d2591SJean-Christophe PLAGNIOL-VILLARD 	pGD->gdfBytesPP = 1;
446*352d2591SJean-Christophe PLAGNIOL-VILLARD 	pGD->gdfIndex = GDF__8BIT_INDEX;
447*352d2591SJean-Christophe PLAGNIOL-VILLARD 
448*352d2591SJean-Christophe PLAGNIOL-VILLARD 	pGD->isaBase = CFG_ISA_IO_BASE_ADDRESS;
449*352d2591SJean-Christophe PLAGNIOL-VILLARD 	pGD->pciBase = rinfo->fb_base_phys;
450*352d2591SJean-Christophe PLAGNIOL-VILLARD 	pGD->frameAdrs = rinfo->fb_base_phys;
451*352d2591SJean-Christophe PLAGNIOL-VILLARD 	pGD->memSize = 64 * 1024 * 1024;
452*352d2591SJean-Christophe PLAGNIOL-VILLARD 
453*352d2591SJean-Christophe PLAGNIOL-VILLARD 	/* Cursor Start Address */
454*352d2591SJean-Christophe PLAGNIOL-VILLARD 	pGD->dprBase =
455*352d2591SJean-Christophe PLAGNIOL-VILLARD 	    (pGD->winSizeX * pGD->winSizeY * pGD->gdfBytesPP) + rinfo->fb_base_phys;
456*352d2591SJean-Christophe PLAGNIOL-VILLARD 	if ((pGD->dprBase & 0x0fff) != 0) {
457*352d2591SJean-Christophe PLAGNIOL-VILLARD 		/* allign it */
458*352d2591SJean-Christophe PLAGNIOL-VILLARD 		pGD->dprBase &= 0xfffff000;
459*352d2591SJean-Christophe PLAGNIOL-VILLARD 		pGD->dprBase += 0x00001000;
460*352d2591SJean-Christophe PLAGNIOL-VILLARD 	}
461*352d2591SJean-Christophe PLAGNIOL-VILLARD 	DPRINT ("Cursor Start %x Pattern Start %x\n", pGD->dprBase,
462*352d2591SJean-Christophe PLAGNIOL-VILLARD 		PATTERN_ADR);
463*352d2591SJean-Christophe PLAGNIOL-VILLARD 	pGD->vprBase = rinfo->fb_base_phys;	/* Dummy */
464*352d2591SJean-Christophe PLAGNIOL-VILLARD 	pGD->cprBase = rinfo->fb_base_phys;	/* Dummy */
465*352d2591SJean-Christophe PLAGNIOL-VILLARD 	/* set up Hardware */
466*352d2591SJean-Christophe PLAGNIOL-VILLARD 
467*352d2591SJean-Christophe PLAGNIOL-VILLARD 	/* Clear video memory */
468*352d2591SJean-Christophe PLAGNIOL-VILLARD 	i = pGD->memSize / 4;
469*352d2591SJean-Christophe PLAGNIOL-VILLARD 	vm = (unsigned int *) pGD->pciBase;
470*352d2591SJean-Christophe PLAGNIOL-VILLARD 	while (i--)
471*352d2591SJean-Christophe PLAGNIOL-VILLARD 		*vm++ = 0;
472*352d2591SJean-Christophe PLAGNIOL-VILLARD 	/*SetDrawingEngine (bits_per_pixel);*/
473*352d2591SJean-Christophe PLAGNIOL-VILLARD 
474*352d2591SJean-Christophe PLAGNIOL-VILLARD 	radeon_setmode();
475*352d2591SJean-Christophe PLAGNIOL-VILLARD 
476*352d2591SJean-Christophe PLAGNIOL-VILLARD 	return ((void *) pGD);
477*352d2591SJean-Christophe PLAGNIOL-VILLARD }
478*352d2591SJean-Christophe PLAGNIOL-VILLARD 
479*352d2591SJean-Christophe PLAGNIOL-VILLARD void video_set_lut (unsigned int index,	/* color number */
480*352d2591SJean-Christophe PLAGNIOL-VILLARD 	       unsigned char r,	/* red */
481*352d2591SJean-Christophe PLAGNIOL-VILLARD 	       unsigned char g,	/* green */
482*352d2591SJean-Christophe PLAGNIOL-VILLARD 	       unsigned char b	/* blue */
483*352d2591SJean-Christophe PLAGNIOL-VILLARD 	       )
484*352d2591SJean-Christophe PLAGNIOL-VILLARD {
485*352d2591SJean-Christophe PLAGNIOL-VILLARD 	OUTREG(PALETTE_INDEX, index);
486*352d2591SJean-Christophe PLAGNIOL-VILLARD 	OUTREG(PALETTE_DATA, (r << 16) | (g << 8) | b);
487*352d2591SJean-Christophe PLAGNIOL-VILLARD }
488*352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
489