1 /*
2  *	drivers/video/radeonfb.c
3  *	framebuffer driver for ATI Radeon chipset video boards
4  *
5  *	Copyright 2000	Ani Joshi <ajoshi@kernel.crashing.org>
6  *
7  *
8  *	ChangeLog:
9  *	2000-08-03	initial version 0.0.1
10  *	2000-09-10	more bug fixes, public release 0.0.5
11  *	2001-02-19	mode bug fixes, 0.0.7
12  *	2001-07-05	fixed scrolling issues, engine initialization,
13  *			and minor mode tweaking, 0.0.9
14  *	2001-09-07	Radeon VE support, Nick Kurshev
15  *			blanking, pan_display, and cmap fixes, 0.1.0
16  *	2001-10-10	Radeon 7500 and 8500 support, and experimental
17  *			flat panel support, 0.1.1
18  *	2001-11-17	Radeon M6 (ppc) support, Daniel Berlin, 0.1.2
19  *	2001-11-18	DFP fixes, Kevin Hendricks, 0.1.3
20  *	2001-11-29	more cmap, backlight fixes, Benjamin Herrenschmidt
21  *	2002-01-18	DFP panel detection via BIOS, Michael Clark, 0.1.4
22  *	2002-06-02	console switching, mode set fixes, accel fixes
23  *	2002-06-03	MTRR support, Peter Horton, 0.1.5
24  *	2002-09-21	rv250, r300, m9 initial support,
25  *			added mirror option, 0.1.6
26  *	2003-04-10	accel engine fixes, 0.1.7
27  *	2003-04-12	Mac PowerBook sleep fixes, Benjamin Herrenschmidt,
28  *			0.1.8
29  *
30  * Other change (--BenH)
31  *
32  * 	2003-01-01	- Tweaks for PLL on some iBooks
33  * 			- Fix SURFACE_CNTL usage on r9000
34  *      2003-03-23	- Added new Power Management code from ATI
35  *      		- Added default PLL values for r300 from lkml
36  *      		- Fix mirror ioctl result code (that ioctl still need some
37  *      		  rework to actually use the second head)
38  *      2003-03-26	- Never set TMDS_PLL_EN, it seem to break more than
39  *                        just old r300's
40  *      2003-04-02	- Got final word from ATI, TMDS_PLL_EN has to be flipped
41  *      		  depending if we are dealing with an "RV" card or not
42  *      		- Comsetic changes to sleep code, make it a bit more robust
43  *      		  hopefully
44  *      		- Fix 800x600-8 mode accel (Daniel Mantione)
45  *      		- Fix scaling on LCDs (not yet preserving aspect ratio though)
46  *      		- Properly set scroll mode to SCROLL_YREDRAW when accel
47  *      		  is disabled from fbset
48  *      		- Add some more radeon PCI IDs & default PLL values
49  *      2003-04-05	- Update the code that retreive the panel infos from the
50  *                        BIOS to match what XFree is doing
51  *                      - Avoid a divide by 0 when failing to retreive those infos
52  *      2003-04-07	- Fix the M6 video RAM workaround
53  *      		- Some bits in the PM code were flipped, fix that.
54  *      		- RB2D_DSTCACHE_MODE shouldn't be cleared on r300 (and
55  *      		  maybe not on others according to a comment in XFree, but
56  *      		  we keep working code for now).
57  *      		- Use ROP3_S for rectangle fill
58  *      2003-04-10      - Re-change the pitch workaround. We now align the pitch
59  *      		  when accel is enabled for a given mode, and we don't when
60  *      		  accel is disabled. That should properly deal with all cases
61  *      		  and allows us to remove the "special case" accel code
62  *      		- Bring in XFree workaround to not write the same value to
63  *      		  the PLL (can cause blanking of some panels)
64  *      		- Bring in some of Peter Horton fixes (accel reset, cleanups)
65  *      		  still some more to get in though...
66  *      		- Back to use of ROP3_P for rectangle fill (hrm...)
67  *      2003-04-11	- Properly reset accel engine on each console switch so
68  *      		  we work around switching from XFree leaving it in a weird
69  *      		  state. Also extend the comparison of values causing us to
70  *      		  reload the mode on console switch.
71  *      2003-04-30	- For BIOS returned LCD infos, assume high sync polarity
72  *      2003-07-08	- Fix an oops during boot related to disp not beeing initialized
73  *      		  when modedb called us back for set_var. Remove bogus refs to
74  *      		  RADEON_PM chip, this is really a mach64 chip, not a Radeon.
75  *      		  Add some DFP blanking support
76  *      2003-07-11	- Merged with Ani's 0.1.8 version
77  *
78  *	Special thanks to ATI DevRel team for their hardware donations,
79  *	and for spending the time to fix the power management code !
80  *
81  *	Note: This driver in in bad need of beeing completely re-organized.
82  *	      My long term plans, if I ever get enough time for that, is
83  *	      to split the actual mode setting code so it can properly
84  *	      work on any head, the probe code, which will be stuffed with
85  *	      OF parsing on PPC and i2c fallback (look at what XFree does)
86  *	      and the PM code ought to be in a separate file. --BenH.
87  *
88  *
89  *      Known Bugs:
90  *
91  *       - Incompatible with ATI FireGL drivers. They are playing with things
92  *         like MC_FB_LOCATION behind our back. Not much we can do. This is
93  *         becoming a real problem as DRI is also playing with those and the
94  *         GATOS CVS as well in a different way.
95  *         We should really define _once for all_ the way we want those setup
96  *         and do it the same way everywhere or we won't be able to keep
97  *         compatibility with radeonfb.
98  *         IMHO, the proper setup is what radeon_fixup_apertures() does on
99  *         PPC when SET_MC_FB_FROM_APERTURE is defined (not the case currently
100  *         because of compatiblity problems with DRI). This is, I think, also
101  *         what GATOS does. We shall ask ATI what they do in the FireGL drivers
102  *       - We don't preserve aspect ratio on scaled modes on LCDs yet
103  *       - The way we retreive the BIOS informations probably doesn't work with
104  *         anything but the primary card since we need a "live" BIOS image in
105  *         memory to find the tables configured by the BIOS during POST stage.
106  */
107 
108 
109 #define RADEON_VERSION	"0.1.8-ben"
110 
111 
112 #include <linux/config.h>
113 #include <linux/module.h>
114 #include <linux/kernel.h>
115 #include <linux/errno.h>
116 #include <linux/string.h>
117 #include <linux/mm.h>
118 #include <linux/tty.h>
119 #include <linux/slab.h>
120 #include <linux/delay.h>
121 #include <linux/fb.h>
122 #include <linux/console.h>
123 #include <linux/vt_kern.h>
124 #include <linux/selection.h>
125 #include <linux/ioport.h>
126 #include <linux/init.h>
127 #include <linux/pci.h>
128 #include <linux/vmalloc.h>
129 
130 #include <asm/io.h>
131 #include <asm/uaccess.h>
132 #ifdef CONFIG_ALL_PPC
133 #include <asm/prom.h>
134 #include <asm/pci-bridge.h>
135 #include <video/macmodes.h>
136 
137 #ifdef CONFIG_NVRAM
138 #include <linux/nvram.h>
139 #endif
140 
141 #ifdef CONFIG_PMAC_BACKLIGHT
142 #include <asm/backlight.h>
143 #endif
144 
145 #ifdef CONFIG_BOOTX_TEXT
146 #include <asm/btext.h>
147 #endif
148 
149 #ifdef CONFIG_ADB_PMU
150 #include <linux/adb.h>
151 #include <linux/pmu.h>
152 #endif
153 
154 #endif /* CONFIG_ALL_PPC */
155 
156 #ifdef CONFIG_MTRR
157 #include <asm/mtrr.h>
158 #endif
159 
160 #include <video/fbcon.h>
161 #include <video/fbcon-cfb8.h>
162 #include <video/fbcon-cfb16.h>
163 #include <video/fbcon-cfb24.h>
164 #include <video/fbcon-cfb32.h>
165 
166 #include "radeon.h"
167 
168 #include <linux/radeonfb.h>
169 
170 
171 #define DEBUG	0
172 
173 #if DEBUG
174 #define RTRACE		printk
175 #else
176 #define RTRACE		if(0) printk
177 #endif
178 
179 #define MAX_MAPPED_VRAM (2048*2048*4)
180 #define MIN_MAPPED_VRAM (1024*768*1)
181 
182 enum radeon_chips {
183 	RADEON_QD,
184 	RADEON_QE,
185 	RADEON_QF,
186 	RADEON_QG,
187 	RADEON_QY,
188 	RADEON_QZ,
189 	RADEON_LW,
190 	RADEON_LX,
191 	RADEON_LY,
192 	RADEON_LZ,
193 	RADEON_QL,
194 	RADEON_QN,
195 	RADEON_QO,
196 	RADEON_Ql,
197 	RADEON_BB,
198 	RADEON_QM,
199 	RADEON_QW,
200 	RADEON_QX,
201 	RADEON_Id,
202 	RADEON_Ie,
203 	RADEON_If,
204 	RADEON_Ig,
205 	RADEON_Y_,
206 	RADEON_Ya,
207 	RADEON_Yd,
208 	RADEON_Ld,
209 	RADEON_Le,
210 	RADEON_Lf,
211 	RADEON_Lg,
212 	RADEON_ND,
213 	RADEON_NE,
214 	RADEON_NF,
215 	RADEON_NG,
216 	RADEON_AE,
217 	RADEON_AF,
218 	RADEON_AD,
219 	RADEON_NH,
220 	RADEON_NI,
221 	RADEON_AP,
222 	RADEON_AQ,
223 	RADEON_AR,
224 };
225 
226 enum radeon_arch {
227 	RADEON_R100,
228 	RADEON_M6,
229 	RADEON_RV100,
230 	RADEON_R200,
231 	RADEON_M7,
232 	RADEON_RV200,
233 	RADEON_M9,
234 	RADEON_RV250,
235 	RADEON_RV280,
236 	RADEON_R300,
237 	RADEON_R350,
238 	RADEON_RV350,
239 };
240 
241 static struct radeon_chip_info {
242 	const char *name;
243 	unsigned char arch;
244 } radeon_chip_info[] __devinitdata = {
245 	{ "QD", RADEON_R100 },
246 	{ "QE", RADEON_R100 },
247 	{ "QF", RADEON_R100 },
248 	{ "QG", RADEON_R100 },
249 	{ "VE QY", RADEON_RV100 },
250 	{ "VE QZ", RADEON_RV100 },
251 	{ "M7 LW", RADEON_M7 },
252 	{ "M7 LX", RADEON_M7 },
253 	{ "M6 LY", RADEON_M6 },
254 	{ "M6 LZ", RADEON_M6 },
255 	{ "8500 QL", RADEON_R200 },
256 	{ "8500 QN", RADEON_R200 },
257 	{ "8500 QO", RADEON_R200 },
258 	{ "8500 Ql", RADEON_R200 },
259 	{ "8500 BB", RADEON_R200 },
260 	{ "9100 QM", RADEON_R200 },
261 	{ "7500 QW", RADEON_RV200 },
262 	{ "7500 QX", RADEON_RV200 },
263 	{ "9000 Id", RADEON_RV250 },
264 	{ "9000 Ie", RADEON_RV250 },
265 	{ "9000 If", RADEON_RV250 },
266 	{ "9000 Ig", RADEON_RV250 },
267 	{ "9200 Y", RADEON_RV280 },
268 	{ "9200 Ya", RADEON_RV280 },
269 	{ "9200 Yd", RADEON_RV280 },
270 	{ "M9 Ld", RADEON_M9 },
271 	{ "M9 Le", RADEON_M9 },
272 	{ "M9 Lf", RADEON_M9 },
273 	{ "M9 Lg", RADEON_M9 },
274 	{ "9700 ND", RADEON_R300 },
275 	{ "9700 NE", RADEON_R300 },
276 	{ "9700 NF", RADEON_R350 },
277 	{ "9700 NG", RADEON_R350 },
278 	{ "9700 AE", RADEON_R300 },
279 	{ "9700 AF", RADEON_R300 },
280 	{ "9500 AD", RADEON_R300 },
281 	{ "9800 NH", RADEON_R350 },
282 	{ "9800 NI", RADEON_R350 },
283 	{ "9600 AP", RADEON_RV350 },
284 	{ "9600 AQ", RADEON_RV350 },
285 	{ "9600 AR", RADEON_RV350 },
286 };
287 
288 
289 enum radeon_montype
290 {
291 	MT_NONE,
292 	MT_CRT,		/* CRT */
293 	MT_LCD,		/* LCD */
294 	MT_DFP,		/* DVI */
295 	MT_CTV,		/* composite TV */
296 	MT_STV		/* S-Video out */
297 };
298 
299 
300 static struct pci_device_id radeonfb_pci_table[] __devinitdata = {
301 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QD, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QD},
302 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QE},
303 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QF},
304 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QG, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QG},
305 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QY, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QY},
306 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QZ, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QZ},
307 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_LW, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_LW},
308 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_LX, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_LX},
309 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_LY, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_LY},
310 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_LZ, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_LZ},
311 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QL, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QL},
312 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QN, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QN},
313 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QO, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QO},
314 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Ql, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Ql},
315 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_BB, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_BB},
316 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QM, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QM},
317 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QW, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QW},
318 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QX, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QX},
319 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Id, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Id},
320 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Ie, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Ie},
321 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_If, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_If},
322 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Ig, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Ig},
323 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Ld, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Ld},
324 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Le, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Le},
325 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Lf, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Lf},
326 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Lg, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Lg},
327 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_ND, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_ND},
328 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_NE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_NE},
329 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_NF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_NF},
330 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_NG, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_NG},
331 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_AE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_AE},
332 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_AF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_AF},
333 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_NH, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_NH},
334 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_NI, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_NI},
335 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Y_, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Y_},
336 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Ya, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Ya},
337 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Yd, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Yd},
338 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_AD, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_AD},
339 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_AP, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_AP},
340 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_AQ, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_AQ},
341 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_AR, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_AR},
342 	{ 0, }
343 };
344 MODULE_DEVICE_TABLE(pci, radeonfb_pci_table);
345 
346 
347 typedef struct {
348 	u16 reg;
349 	u32 val;
350 } reg_val;
351 
352 
353 /* these common regs are cleared before mode setting so they do not
354  * interfere with anything
355  */
356 reg_val common_regs[] = {
357 	{ OVR_CLR, 0 },
358 	{ OVR_WID_LEFT_RIGHT, 0 },
359 	{ OVR_WID_TOP_BOTTOM, 0 },
360 	{ OV0_SCALE_CNTL, 0 },
361 	{ SUBPIC_CNTL, 0 },
362 	{ VIPH_CONTROL, 0 },
363 	{ I2C_CNTL_1, 0 },
364 	{ GEN_INT_CNTL, 0 },
365 	{ CAP0_TRIG_CNTL, 0 },
366 };
367 
368 reg_val common_regs_m6[] = {
369 	{ OVR_CLR, 0 },
370 	{ OVR_WID_LEFT_RIGHT, 0 },
371 	{ OVR_WID_TOP_BOTTOM, 0 },
372 	{ OV0_SCALE_CNTL, 0 },
373 	{ SUBPIC_CNTL, 0 },
374 	{ GEN_INT_CNTL, 0 },
375 	{ CAP0_TRIG_CNTL, 0 }
376 };
377 
378 
379 #define COMMON_REGS_SIZE = (sizeof(common_regs)/sizeof(common_regs[0]))
380 #define COMMON_REGS_M6_SIZE = (sizeof(common_regs)/sizeof(common_regs_m6[0]))
381 
382 typedef struct {
383         u8 clock_chip_type;
384         u8 struct_size;
385         u8 accelerator_entry;
386         u8 VGA_entry;
387         u16 VGA_table_offset;
388         u16 POST_table_offset;
389         u16 XCLK;
390         u16 MCLK;
391         u8 num_PLL_blocks;
392         u8 size_PLL_blocks;
393         u16 PCLK_ref_freq;
394         u16 PCLK_ref_divider;
395         u32 PCLK_min_freq;
396         u32 PCLK_max_freq;
397         u16 MCLK_ref_freq;
398         u16 MCLK_ref_divider;
399         u32 MCLK_min_freq;
400         u32 MCLK_max_freq;
401         u16 XCLK_ref_freq;
402         u16 XCLK_ref_divider;
403         u32 XCLK_min_freq;
404         u32 XCLK_max_freq;
405 } __attribute__ ((packed)) PLL_BLOCK;
406 
407 
408 struct pll_info {
409 	int ppll_max;
410 	int ppll_min;
411 	int xclk;
412 	int ref_div;
413 	int ref_clk;
414 };
415 
416 
417 struct ram_info {
418 	int ml;
419 	int mb;
420 	int trcd;
421 	int trp;
422 	int twr;
423 	int cl;
424 	int tr2w;
425 	int loop_latency;
426 	int rloop;
427 };
428 
429 
430 struct radeon_regs {
431 	/* CRTC regs */
432 	u32 crtc_h_total_disp;
433 	u32 crtc_h_sync_strt_wid;
434 	u32 crtc_v_total_disp;
435 	u32 crtc_v_sync_strt_wid;
436 	u32 crtc_pitch;
437 	u32 crtc_gen_cntl;
438 	u32 crtc_ext_cntl;
439 	u32 crtc_more_cntl;
440 	u32 dac_cntl;
441 
442 	u32 flags;
443 	u32 pix_clock;
444 	int xres, yres;
445 
446 	/* DDA regs */
447 	u32 dda_config;
448 	u32 dda_on_off;
449 
450 	/* PLL regs */
451 	u32 ppll_div_3;
452 	u32 ppll_ref_div;
453 
454 	/* Flat panel regs */
455 	u32 fp_crtc_h_total_disp;
456 	u32 fp_crtc_v_total_disp;
457 	u32 fp_gen_cntl;
458 	u32 fp_h_sync_strt_wid;
459 	u32 fp_horz_stretch;
460 	u32 fp_panel_cntl;
461 	u32 fp_v_sync_strt_wid;
462 	u32 fp_vert_stretch;
463 	u32 lvds_gen_cntl;
464 	u32 lvds_pll_cntl;
465 	u32 tmds_crc;
466 	u32 tmds_transmitter_cntl;
467 
468 	/* Dynamic clock control */
469 	u32 vclk_ecp_cntl;
470 
471 	/* Endian control */
472 	u32 surface_cntl;
473 };
474 
475 
476 struct radeonfb_info {
477 	struct fb_info info;
478 
479 	struct radeon_regs state;
480 	struct radeon_regs init_state;
481 
482 	char name[16];
483 	char ram_type[12];
484 
485 	unsigned long mmio_base_phys;
486 	unsigned long fb_base_phys;
487 
488 	unsigned long mmio_base;
489 	unsigned long fb_base;
490 
491 	unsigned long fb_local_base;
492 
493 	struct pci_dev *pdev;
494 
495 	unsigned char *EDID;
496 	unsigned char *bios_seg;
497 
498 	struct display disp;
499 	int currcon;
500 	struct display *currcon_display;
501 
502 	struct { u8 red, green, blue, pad; } palette[256];
503 
504 	short chipset;
505 	unsigned char arch;
506 	unsigned int video_ram;
507 	u8 rev;
508 	int pitch, bpp, depth;
509 	int xres, yres, pixclock;
510 	int xres_virtual, yres_virtual;
511 
512 	int use_default_var;
513 	int got_dfpinfo;
514 
515 	int hasCRTC2;
516 	int crtDisp_type;
517 	int dviDisp_type;
518 
519 	int panel_xres, panel_yres;
520 	int clock;
521 	int hOver_plus, hSync_width, hblank;
522 	int vOver_plus, vSync_width, vblank;
523 	int hAct_high, vAct_high, interlaced;
524 	int synct, misc;
525 
526 	u32 dp_gui_master_cntl;
527 
528 	struct pll_info pll;
529 	int pll_output_freq, post_div, fb_div;
530 
531 	struct ram_info ram;
532 
533 	int mtrr_hdl;
534 
535 #if defined(FBCON_HAS_CFB16) || defined(FBCON_HAS_CFB32)
536         union {
537 #if defined(FBCON_HAS_CFB16)
538                 u_int16_t cfb16[16];
539 #endif
540 #if defined(FBCON_HAS_CFB24)
541                 u_int32_t cfb24[16];
542 #endif
543 #if defined(FBCON_HAS_CFB32)
544                 u_int32_t cfb32[16];
545 #endif
546         } con_cmap;
547 #endif
548 
549 #ifdef CONFIG_PMAC_PBOOK
550 	int pm_reg;
551 	u32 save_regs[64];
552 	u32 mdll, mdll2;
553 #endif
554 
555 	int asleep;
556 
557 	struct radeonfb_info *next;
558 };
559 
560 
561 static struct fb_var_screeninfo radeonfb_default_var = {
562         640, 480, 640, 480, 0, 0, 8, 0,
563         {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0},
564         0, 0, -1, -1, 0, 39721, 40, 24, 32, 11, 96, 2,
565         0, FB_VMODE_NONINTERLACED
566 };
567 
568 
569 /*
570  * IO macros
571  */
572 
573 #define INREG8(addr)		readb((rinfo->mmio_base)+addr)
574 #define OUTREG8(addr,val)	writeb(val, (rinfo->mmio_base)+addr)
575 #define INREG(addr)		readl((rinfo->mmio_base)+addr)
576 #define OUTREG(addr,val)	writel(val, (rinfo->mmio_base)+addr)
577 
578 #define OUTPLL(addr,val)						\
579 	do {								\
580 		OUTREG8(CLOCK_CNTL_INDEX, (addr & 0x0000003f) | 0x00000080); \
581 		OUTREG(CLOCK_CNTL_DATA, val);				\
582 	} while (0)							\
583 
584 #define OUTPLLP(addr,val,mask)  					\
585 	do {								\
586 		unsigned int _tmp = INPLL(addr);			\
587 		_tmp &= (mask);						\
588 		_tmp |= (val);						\
589 		OUTPLL(addr, _tmp);					\
590 	} while (0)
591 
592 #define OUTREGP(addr,val,mask)  					\
593 	do {								\
594 		unsigned int _tmp = INREG(addr);			\
595 		_tmp &= (mask);						\
596 		_tmp |= (val);						\
597 		OUTREG(addr, _tmp);					\
598 	} while (0)
599 
600 
_INPLL(struct radeonfb_info * rinfo,u32 addr)601 static __inline__ u32 _INPLL(struct radeonfb_info *rinfo, u32 addr)
602 {
603 	OUTREG8(CLOCK_CNTL_INDEX, addr & 0x0000003f);
604 	return (INREG(CLOCK_CNTL_DATA));
605 }
606 
607 #define INPLL(addr)		_INPLL(rinfo, addr)
608 
609 #define PRIMARY_MONITOR(rinfo)	((rinfo->dviDisp_type != MT_NONE) &&	\
610 				 (rinfo->dviDisp_type != MT_STV) &&	\
611 				 (rinfo->dviDisp_type != MT_CTV) ?	\
612 				 rinfo->dviDisp_type : rinfo->crtDisp_type)
613 
GET_MON_NAME(int type)614 static char *GET_MON_NAME(int type)
615 {
616 	char *pret = NULL;
617 
618 	switch (type) {
619 		case MT_NONE:
620 			pret = "no";
621 			break;
622 		case MT_CRT:
623 			pret = "CRT";
624 			break;
625 		case MT_DFP:
626 			pret = "DFP";
627 			break;
628 		case MT_LCD:
629 			pret = "LCD";
630 			break;
631 		case MT_CTV:
632 			pret = "CTV";
633 			break;
634 		case MT_STV:
635 			pret = "STV";
636 			break;
637 	}
638 
639 	return pret;
640 }
641 
642 
643 /*
644  * 2D engine routines
645  */
646 
radeon_engine_flush(struct radeonfb_info * rinfo)647 static __inline__ void radeon_engine_flush (struct radeonfb_info *rinfo)
648 {
649 	int i;
650 
651 	/* initiate flush */
652 	OUTREGP(RB2D_DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL,
653 	        ~RB2D_DC_FLUSH_ALL);
654 
655 	for (i=0; i < 2000000; i++) {
656 		if (!(INREG(RB2D_DSTCACHE_CTLSTAT) & RB2D_DC_BUSY))
657 			break;
658 	}
659 }
660 
661 
_radeon_fifo_wait(struct radeonfb_info * rinfo,int entries)662 static __inline__ void _radeon_fifo_wait (struct radeonfb_info *rinfo, int entries)
663 {
664 	int i;
665 
666 	for (i=0; i<2000000; i++)
667 		if ((INREG(RBBM_STATUS) & 0x7f) >= entries)
668 			return;
669 }
670 
671 
_radeon_engine_idle(struct radeonfb_info * rinfo)672 static __inline__ void _radeon_engine_idle (struct radeonfb_info *rinfo)
673 {
674 	int i;
675 
676 	/* ensure FIFO is empty before waiting for idle */
677 	_radeon_fifo_wait (rinfo, 64);
678 
679 	for (i=0; i<2000000; i++) {
680 		if (((INREG(RBBM_STATUS) & GUI_ACTIVE)) == 0) {
681 			radeon_engine_flush (rinfo);
682 			return;
683 		}
684 	}
685 }
686 
687 
688 #define radeon_engine_idle()		_radeon_engine_idle(rinfo)
689 #define radeon_fifo_wait(entries)	_radeon_fifo_wait(rinfo,entries)
690 
691 
692 
693 /*
694  * helper routines
695  */
696 
radeon_get_dstbpp(u16 depth)697 static __inline__ u32 radeon_get_dstbpp(u16 depth)
698 {
699 	switch (depth) {
700 		case 8:
701 			return DST_8BPP;
702 		case 15:
703 			return DST_15BPP;
704 		case 16:
705 			return DST_16BPP;
706 		case 32:
707 			return DST_32BPP;
708 		default:
709 			return 0;
710 	}
711 }
712 
713 
var_to_depth(const struct fb_var_screeninfo * var)714 static inline int var_to_depth(const struct fb_var_screeninfo *var)
715 {
716 	if (var->bits_per_pixel != 16)
717 		return var->bits_per_pixel;
718 	return (var->green.length == 6) ? 16 : 15;
719 }
720 
721 
_radeon_engine_reset(struct radeonfb_info * rinfo)722 static void _radeon_engine_reset(struct radeonfb_info *rinfo)
723 {
724 	u32 clock_cntl_index, mclk_cntl, rbbm_soft_reset;
725 	u32 host_path_cntl;
726 
727 	radeon_engine_flush (rinfo);
728 
729     	/* Some ASICs have bugs with dynamic-on feature, which are
730      	 * ASIC-version dependent, so we force all blocks on for now
731      	 * -- from XFree86
732      	 * We don't do that on macs, things just work here with dynamic
733      	 * clocking... --BenH
734 	 */
735 #ifdef CONFIG_ALL_PPC
736 	if (_machine != _MACH_Pmac && rinfo->hasCRTC2)
737 #else
738 	if (rinfo->hasCRTC2)
739 #endif
740 	{
741 		u32 tmp;
742 
743 		tmp = INPLL(SCLK_CNTL);
744 		OUTPLL(SCLK_CNTL, ((tmp & ~DYN_STOP_LAT_MASK) |
745 				   CP_MAX_DYN_STOP_LAT |
746 				   SCLK_FORCEON_MASK));
747 
748 		if (rinfo->arch == RADEON_RV200)
749 		{
750 			tmp = INPLL(SCLK_MORE_CNTL);
751 			OUTPLL(SCLK_MORE_CNTL, tmp | SCLK_MORE_FORCEON);
752 		}
753 	}
754 
755 	clock_cntl_index = INREG(CLOCK_CNTL_INDEX);
756 	mclk_cntl = INPLL(MCLK_CNTL);
757 
758 	OUTPLL(MCLK_CNTL, (mclk_cntl |
759 			   FORCEON_MCLKA |
760 			   FORCEON_MCLKB |
761 			   FORCEON_YCLKA |
762 			   FORCEON_YCLKB |
763 			   FORCEON_MC |
764 			   FORCEON_AIC));
765 
766 	host_path_cntl = INREG(HOST_PATH_CNTL);
767 	rbbm_soft_reset = INREG(RBBM_SOFT_RESET);
768 
769 	if (rinfo->arch == RADEON_R300) {
770 		u32 tmp;
771 
772 		OUTREG(RBBM_SOFT_RESET, (rbbm_soft_reset |
773 					 SOFT_RESET_CP |
774 					 SOFT_RESET_HI |
775 					 SOFT_RESET_E2));
776 		INREG(RBBM_SOFT_RESET);
777 		OUTREG(RBBM_SOFT_RESET, 0);
778 		tmp = INREG(RB2D_DSTCACHE_MODE);
779 		OUTREG(RB2D_DSTCACHE_MODE, tmp | (1 << 17)); /* FIXME */
780 	} else {
781 		OUTREG(RBBM_SOFT_RESET, rbbm_soft_reset |
782 					SOFT_RESET_CP |
783 					SOFT_RESET_HI |
784 					SOFT_RESET_SE |
785 					SOFT_RESET_RE |
786 					SOFT_RESET_PP |
787 					SOFT_RESET_E2 |
788 					SOFT_RESET_RB);
789 		INREG(RBBM_SOFT_RESET);
790 		OUTREG(RBBM_SOFT_RESET, rbbm_soft_reset & (u32)
791 					~(SOFT_RESET_CP |
792 					  SOFT_RESET_HI |
793 					  SOFT_RESET_SE |
794 					  SOFT_RESET_RE |
795 					  SOFT_RESET_PP |
796 					  SOFT_RESET_E2 |
797 					  SOFT_RESET_RB));
798 		INREG(RBBM_SOFT_RESET);
799 	}
800 
801 	OUTREG(HOST_PATH_CNTL, host_path_cntl | HDP_SOFT_RESET);
802 	INREG(HOST_PATH_CNTL);
803 	OUTREG(HOST_PATH_CNTL, host_path_cntl);
804 
805 	if (rinfo->arch != RADEON_R300)
806 		OUTREG(RBBM_SOFT_RESET, rbbm_soft_reset);
807 
808 	OUTREG(CLOCK_CNTL_INDEX, clock_cntl_index);
809 	OUTPLL(MCLK_CNTL, mclk_cntl);
810 
811 	return;
812 }
813 
814 #define radeon_engine_reset()		_radeon_engine_reset(rinfo)
815 
816 
round_div(int num,int den)817 static __inline__ int round_div(int num, int den)
818 {
819         return (num + (den / 2)) / den;
820 }
821 
min_bits_req(int val)822 static __inline__ int min_bits_req(int val)
823 {
824         int bits_req = 0;
825 
826         if (val == 0)
827                 bits_req = 1;
828 
829         while (val) {
830                 val >>= 1;
831                 bits_req++;
832         }
833 
834         return (bits_req);
835 }
836 
_max(int val1,int val2)837 static __inline__ int _max(int val1, int val2)
838 {
839         if (val1 >= val2)
840                 return val1;
841         else
842                 return val2;
843 }
844 
845 
846 
847 /*
848  * globals
849  */
850 
851 static char fontname[40] __initdata;
852 static char *mode_option __initdata;
853 static char noaccel = 0;
854 static char mirror = 0;
855 static int panel_yres __initdata = 0;
856 static char force_dfp __initdata = 0;
857 static char force_crt __initdata = 0;
858 static char force_nolcd __initdata = 0;
859 static struct radeonfb_info *board_list = NULL;
860 static char nomtrr __initdata = 0;
861 
862 #ifdef FBCON_HAS_CFB8
863 static struct display_switch fbcon_radeon8;
864 #endif
865 
866 #ifdef FBCON_HAS_CFB16
867 static struct display_switch fbcon_radeon16;
868 #endif
869 
870 #ifdef FBCON_HAS_CFB32
871 static struct display_switch fbcon_radeon32;
872 #endif
873 
874 
875 /*
876  * prototypes
877  */
878 
879 static int radeonfb_get_fix (struct fb_fix_screeninfo *fix, int con,
880                              struct fb_info *info);
881 static int radeonfb_get_var (struct fb_var_screeninfo *var, int con,
882                              struct fb_info *info);
883 static int radeonfb_set_var (struct fb_var_screeninfo *var, int con,
884                              struct fb_info *info);
885 static int radeonfb_get_cmap (struct fb_cmap *cmap, int kspc, int con,
886                               struct fb_info *info);
887 static int radeonfb_set_cmap (struct fb_cmap *cmap, int kspc, int con,
888                               struct fb_info *info);
889 static int radeonfb_pan_display (struct fb_var_screeninfo *var, int con,
890                                  struct fb_info *info);
891 static int radeonfb_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
892                            unsigned long arg, int con, struct fb_info *info);
893 static int radeonfb_switch (int con, struct fb_info *info);
894 static int radeonfb_updatevar (int con, struct fb_info *info);
895 static void radeonfb_blank (int blank, struct fb_info *info);
896 static int radeon_get_cmap_len (const struct fb_var_screeninfo *var);
897 static int radeon_getcolreg (unsigned regno, unsigned *red, unsigned *green,
898                              unsigned *blue, unsigned *transp,
899                              struct fb_info *info);
900 static int radeon_setcolreg (unsigned regno, unsigned red, unsigned green,
901                              unsigned blue, unsigned transp, struct fb_info *info);
902 static void radeon_set_dispsw (struct radeonfb_info *rinfo, struct display *disp);
903 static void radeon_save_state (struct radeonfb_info *rinfo,
904                                struct radeon_regs *save);
905 static int radeon_engine_init (struct radeonfb_info *rinfo);
906 static void radeon_load_video_mode (struct radeonfb_info *rinfo,
907                                     struct fb_var_screeninfo *mode);
908 static void radeon_write_mode (struct radeonfb_info *rinfo,
909                                struct radeon_regs *mode);
910 static int __devinit radeon_set_fbinfo (struct radeonfb_info *rinfo);
911 static int __devinit radeon_init_disp (struct radeonfb_info *rinfo);
912 static int radeonfb_pci_register (struct pci_dev *pdev,
913                                  const struct pci_device_id *ent);
914 static void __devexit radeonfb_pci_unregister (struct pci_dev *pdev);
915 static int radeon_do_set_var (struct fb_var_screeninfo *var, int con,
916                              int real, struct fb_info *info);
917 
918 #ifdef CONFIG_PMAC_PBOOK
919 static int radeon_sleep_notify(struct pmu_sleep_notifier *self, int when);
920 static struct pmu_sleep_notifier radeon_sleep_notifier = {
921 	radeon_sleep_notify, SLEEP_LEVEL_VIDEO,
922 };
923 #endif /* CONFIG_PMAC_PBOOK */
924 #ifdef CONFIG_PMAC_BACKLIGHT
925 static int radeon_set_backlight_enable(int on, int level, void *data);
926 static int radeon_set_backlight_level(int level, void *data);
927 static struct backlight_controller radeon_backlight_controller = {
928 	radeon_set_backlight_enable,
929 	radeon_set_backlight_level
930 };
931 static void OUTMC( struct radeonfb_info *rinfo, u8 indx, u32 value);
932 static u32 INMC(struct radeonfb_info *rinfo, u8 indx);
933 static void radeon_pm_disable_dynamic_mode(struct radeonfb_info *rinfo);
934 static void radeon_pm_enable_dynamic_mode(struct radeonfb_info *rinfo);
935 static void radeon_pm_yclk_mclk_sync(struct radeonfb_info *rinfo);
936 static void radeon_pm_program_mode_reg(struct radeonfb_info *rinfo, u16 value, u8 delay_required);
937 static void radeon_pm_enable_dll(struct radeonfb_info *rinfo);
938 static void radeon_pm_full_reset_sdram(struct radeonfb_info *rinfo);
939 #endif /* CONFIG_PMAC_BACKLIGHT */
940 
941 static struct fb_ops radeon_fb_ops = {
942 	owner:			THIS_MODULE,
943 	fb_get_fix:		radeonfb_get_fix,
944 	fb_get_var:		radeonfb_get_var,
945 	fb_set_var:		radeonfb_set_var,
946 	fb_get_cmap:		radeonfb_get_cmap,
947 	fb_set_cmap:		radeonfb_set_cmap,
948 	fb_pan_display:		radeonfb_pan_display,
949 	fb_ioctl:		radeonfb_ioctl,
950 };
951 
952 
953 static struct pci_driver radeonfb_driver = {
954 	name:		"radeonfb",
955 	id_table:	radeonfb_pci_table,
956 	probe:		radeonfb_pci_register,
957 	remove:		__devexit_p(radeonfb_pci_unregister),
958 };
959 
960 
radeonfb_init(void)961 int __init radeonfb_init (void)
962 {
963 	return pci_module_init (&radeonfb_driver);
964 }
965 
966 
radeonfb_exit(void)967 void __exit radeonfb_exit (void)
968 {
969 	pci_unregister_driver (&radeonfb_driver);
970 }
971 
972 
radeonfb_setup(char * options)973 int __init radeonfb_setup (char *options)
974 {
975         char *this_opt;
976 
977         if (!options || !*options)
978                 return 0;
979 
980 	while ((this_opt = strsep (&options, ",")) != NULL) {
981 		if (!*this_opt)
982 			continue;
983                 if (!strncmp (this_opt, "font:", 5)) {
984                         char *p;
985                         int i;
986 
987                         p = this_opt + 5;
988                         for (i=0; i<sizeof (fontname) - 1; i++)
989                                 if (!*p || *p == ' ' || *p == ',')
990                                         break;
991                         memcpy(fontname, this_opt + 5, i);
992                 } else if (!strncmp(this_opt, "noaccel", 7)) {
993 			noaccel = 1;
994                 } else if (!strncmp(this_opt, "mirror", 6)) {
995 			mirror = 1;
996 		} else if (!strncmp(this_opt, "dfp", 3)) {
997 			force_dfp = 1;
998 			force_nolcd = 1;
999 		} else if (!strncmp(this_opt, "crt", 3)) {
1000 			force_crt = 1;
1001 			force_nolcd = 1;
1002 		} else if (!strncmp(this_opt, "nolcd", 5)) {
1003 			force_nolcd = 1;
1004 		} else if (!strncmp(this_opt, "panel_yres:", 11)) {
1005 			panel_yres = simple_strtoul((this_opt+11), NULL, 0);
1006 		} else if (!strncmp(this_opt, "nomtrr", 6)) {
1007 			nomtrr = 1;
1008                 } else
1009 			mode_option = this_opt;
1010         }
1011 
1012 	return 0;
1013 }
1014 
1015 #ifdef MODULE
1016 module_init(radeonfb_init);
1017 module_exit(radeonfb_exit);
1018 #endif
1019 
1020 
1021 MODULE_AUTHOR("Ani Joshi");
1022 MODULE_DESCRIPTION("framebuffer driver for ATI Radeon chipset");
1023 MODULE_LICENSE("GPL");
1024 
1025 MODULE_PARM(noaccel, "i");
1026 MODULE_PARM_DESC(noaccel, "Disable (1) or enable (0) the usage of the 2d accel engine");
1027 MODULE_PARM(force_dfp, "i");
1028 MODULE_PARM_DESC(force_dfp,"Force (1) the usage of a digital flat panel");
1029 MODULE_PARM(force_crt, "i");
1030 MODULE_PARM_DESC(force_crt,"Force (1) the usage of a CRT monitor");
1031 MODULE_PARM(force_nolcd, "i");
1032 MODULE_PARM_DESC(force_nolcd,"Avoid (1) the usage of a digital flat panel");
1033 
radeon_find_rom(struct radeonfb_info * rinfo)1034 static unsigned char *radeon_find_rom(struct radeonfb_info *rinfo)
1035 {
1036 #if defined(__i386__)
1037 	/* I simplified this code as we used to miss the signatures in
1038 	 * a lot of case. It's now closer to XFree, we just don't check
1039 	 * for signatures at all... Something better will have to be done
1040 	 * later obviously
1041 	 */
1042         u32  segstart;
1043         unsigned char *rom_base;
1044 
1045         for(segstart=0x000c0000; segstart<0x000f0000; segstart+=0x00001000) {
1046                 rom_base = (char *)ioremap(segstart, 0x1000);
1047                 if ((*rom_base == 0x55) && (((*(rom_base + 1)) & 0xff) == 0xaa))
1048 	                return rom_base;
1049                 iounmap(rom_base);
1050         }
1051 #endif
1052         return NULL;
1053 }
1054 
1055 #ifdef CONFIG_ALL_PPC
radeon_read_OF(struct radeonfb_info * rinfo)1056 static int radeon_read_OF (struct radeonfb_info *rinfo)
1057 {
1058 	struct device_node *dp;
1059 	unsigned int *xtal;
1060 
1061 	dp = pci_device_to_OF_node(rinfo->pdev);
1062 	if (dp == NULL)
1063 		return 0;
1064 
1065 	xtal = (unsigned int *) get_property(dp, "ATY,RefCLK", 0);
1066 	if ((xtal == NULL) || (*xtal == 0))
1067 		return 0;
1068 
1069 	rinfo->pll.ref_clk = *xtal / 10;
1070 
1071 	return 1;
1072 }
1073 #endif
1074 
radeon_get_pllinfo(struct radeonfb_info * rinfo,char * bios_seg)1075 static void radeon_get_pllinfo(struct radeonfb_info *rinfo, char *bios_seg)
1076 {
1077         void *bios_header;
1078         void *header_ptr;
1079         u16 bios_header_offset, pll_info_offset;
1080         PLL_BLOCK pll;
1081 
1082 	if (bios_seg) {
1083 	        bios_header = bios_seg + 0x48L;
1084        		header_ptr  = bios_header;
1085 
1086         	bios_header_offset = readw(header_ptr);
1087 	        bios_header = bios_seg + bios_header_offset;
1088         	bios_header += 0x30;
1089 
1090         	header_ptr = bios_header;
1091         	pll_info_offset = readw(header_ptr);
1092         	header_ptr = bios_seg + pll_info_offset;
1093 
1094         	memcpy_fromio(&pll, header_ptr, 50);
1095 
1096         	/* Consider ref clock to be sane between 1000 and 5000,
1097         	 * just in case we tapped the wrong BIOS...
1098         	 */
1099 		if (pll.PCLK_ref_freq < 1000 || pll.PCLK_ref_freq > 5000)
1100 			goto use_defaults;
1101 
1102         	rinfo->pll.xclk = (u32)pll.XCLK;
1103         	rinfo->pll.ref_clk = (u32)pll.PCLK_ref_freq;
1104         	rinfo->pll.ref_div = (u32)pll.PCLK_ref_divider;
1105         	rinfo->pll.ppll_min = pll.PCLK_min_freq;
1106         	rinfo->pll.ppll_max = pll.PCLK_max_freq;
1107 
1108 		printk("radeonfb: ref_clk=%d, ref_div=%d, xclk=%d from BIOS\n",
1109 			rinfo->pll.ref_clk, rinfo->pll.ref_div, rinfo->pll.xclk);
1110 	} else {
1111 #ifdef CONFIG_ALL_PPC
1112 		if (radeon_read_OF(rinfo)) {
1113 			unsigned int tmp, Nx, M, ref_div, xclk;
1114 
1115 			tmp = INPLL(M_SPLL_REF_FB_DIV);
1116 			ref_div = INPLL(PPLL_REF_DIV) & 0x3ff;
1117 
1118 			Nx = (tmp & 0xff00) >> 8;
1119 			M = (tmp & 0xff);
1120 			xclk = ((((2 * Nx * rinfo->pll.ref_clk) + (M)) /
1121 				(2 * M)));
1122 
1123 			rinfo->pll.xclk = xclk;
1124 			rinfo->pll.ref_div = ref_div;
1125 			rinfo->pll.ppll_min = 12000;
1126 			rinfo->pll.ppll_max = 35000;
1127 
1128 			printk("radeonfb: ref_clk=%d, ref_div=%d, xclk=%d from OF\n",
1129 				rinfo->pll.ref_clk, rinfo->pll.ref_div, rinfo->pll.xclk);
1130 
1131 			return;
1132 		}
1133 #endif
1134 use_defaults:
1135 		/* No BIOS or BIOS not found, use defaults
1136 		 *
1137 		 * NOTE: Those defaults settings are rather "randomly" picked from
1138 		 * informations we found so far, but we would really need some
1139 		 * better mecanism to get them. Recent XFree can +/- probe for
1140 		 * the proper clocks.
1141 		 */
1142 		switch (rinfo->arch) {
1143 			case RADEON_RV200:
1144 				rinfo->pll.ppll_max = 35000;
1145 				rinfo->pll.ppll_min = 12000;
1146 				rinfo->pll.xclk = 23000;
1147 				rinfo->pll.ref_div = 12;
1148 				rinfo->pll.ref_clk = 2700;
1149 				break;
1150 			case RADEON_R200:
1151 				rinfo->pll.ppll_max = 35000;
1152 				rinfo->pll.ppll_min = 12000;
1153 				rinfo->pll.xclk = 27500;
1154 				rinfo->pll.ref_div = 12;
1155 				rinfo->pll.ref_clk = 2700;
1156 				break;
1157 			case RADEON_RV250:
1158 				rinfo->pll.ppll_max = 35000;
1159 				rinfo->pll.ppll_min = 12000;
1160 				rinfo->pll.xclk = 25000;
1161 				rinfo->pll.ref_div = 12;
1162 				rinfo->pll.ref_clk = 2700;
1163 				break;
1164 			case RADEON_R300:
1165 				rinfo->pll.ppll_max = 40000;
1166 				rinfo->pll.ppll_min = 20000;
1167 				rinfo->pll.xclk = 27000;
1168 				rinfo->pll.ref_div = 12;
1169 				rinfo->pll.ref_clk = 2700;
1170 				break;
1171 			case RADEON_R100:
1172 			default:
1173 				rinfo->pll.ppll_max = 35000;
1174 				rinfo->pll.ppll_min = 12000;
1175 				rinfo->pll.xclk = 16600;
1176 				rinfo->pll.ref_div = 67;
1177 				rinfo->pll.ref_clk = 2700;
1178 				break;
1179 		}
1180 
1181 		printk("radeonfb: ref_clk=%d, ref_div=%d, xclk=%d defaults\n",
1182 			rinfo->pll.ref_clk, rinfo->pll.ref_div, rinfo->pll.xclk);
1183 	}
1184 }
1185 
1186 
radeon_get_moninfo(struct radeonfb_info * rinfo)1187 static void radeon_get_moninfo (struct radeonfb_info *rinfo)
1188 {
1189 	u32 tmp = INREG(RADEON_BIOS_4_SCRATCH);
1190 
1191 	if (force_dfp) {
1192 		printk("radeonfb: forcing DFP\n");
1193 		rinfo->dviDisp_type = MT_DFP;
1194 		return;
1195 	} else if (force_crt) {
1196 		printk("radeonfb: forcing CRT\n");
1197 		rinfo->dviDisp_type = MT_NONE;
1198 		rinfo->crtDisp_type = MT_CRT;
1199 		return;
1200 	}
1201 
1202 
1203 	if (rinfo->hasCRTC2 && tmp) {
1204 		/* primary DVI port */
1205 		if (tmp & 0x08)
1206 			rinfo->dviDisp_type = MT_DFP;
1207 		else if (tmp & 0x4)
1208 			rinfo->dviDisp_type = MT_LCD;
1209 		else if (tmp & 0x200)
1210 			rinfo->dviDisp_type = MT_CRT;
1211 		else if (tmp & 0x10)
1212 			rinfo->dviDisp_type = MT_CTV;
1213 		else if (tmp & 0x20)
1214 			rinfo->dviDisp_type = MT_STV;
1215 
1216 		/* secondary CRT port */
1217 		if (tmp & 0x2)
1218 			rinfo->crtDisp_type = MT_CRT;
1219 		else if (tmp & 0x800)
1220 			rinfo->crtDisp_type = MT_DFP;
1221 		else if (tmp & 0x400)
1222 			rinfo->crtDisp_type = MT_LCD;
1223 		else if (tmp & 0x1000)
1224 			rinfo->crtDisp_type = MT_CTV;
1225 		else if (tmp & 0x2000)
1226 			rinfo->crtDisp_type = MT_STV;
1227 	} else {
1228 		rinfo->dviDisp_type = MT_NONE;
1229 
1230 		tmp = INREG(FP_GEN_CNTL);
1231 
1232 		if (tmp & FP_EN_TMDS)
1233 			rinfo->crtDisp_type = MT_DFP;
1234 		else
1235 			rinfo->crtDisp_type = MT_CRT;
1236 	}
1237 }
1238 
1239 #ifdef CONFIG_ALL_PPC
radeon_get_EDID_OF(struct radeonfb_info * rinfo)1240 static int radeon_get_EDID_OF(struct radeonfb_info *rinfo)
1241 {
1242         struct device_node *dp;
1243         unsigned char *pedid = NULL;
1244         static char *propnames[] = { "DFP,EDID", "LCD,EDID", "EDID", "EDID1", NULL };
1245         int i;
1246 
1247         dp = pci_device_to_OF_node(rinfo->pdev);
1248         while (dp != NULL) {
1249                 for (i = 0; propnames[i] != NULL; ++i) {
1250                         pedid = (unsigned char *)
1251                                 get_property(dp, propnames[i], NULL);
1252                         if (pedid != NULL) {
1253                                 rinfo->EDID = pedid;
1254                                 return 1;
1255                         }
1256                 }
1257                 dp = dp->child;
1258         }
1259         return 0;
1260 }
1261 #endif /* CONFIG_ALL_PPC */
1262 
radeon_get_EDID(struct radeonfb_info * rinfo)1263 static void radeon_get_EDID(struct radeonfb_info *rinfo)
1264 {
1265 #ifdef CONFIG_ALL_PPC
1266 	if (!radeon_get_EDID_OF(rinfo))
1267 		RTRACE("radeonfb: could not retrieve EDID from OF\n");
1268 #else
1269 	/* XXX use other methods later */
1270 #endif
1271 }
1272 
1273 #ifdef CONFIG_ALL_PPC
1274 #undef SET_MC_FB_FROM_APERTURE
1275 static void
radeon_fixup_apertures(struct radeonfb_info * rinfo)1276 radeon_fixup_apertures(struct radeonfb_info *rinfo)
1277 {
1278 	u32 save_crtc_gen_cntl, save_crtc2_gen_cntl;
1279 	u32 save_crtc_ext_cntl;
1280 	u32 aper_base, aper_size;
1281 	u32 agp_base;
1282 
1283 	/* First, we disable display to avoid interfering */
1284 	if (rinfo->hasCRTC2) {
1285 		save_crtc2_gen_cntl = INREG(CRTC2_GEN_CNTL);
1286 		OUTREG(CRTC2_GEN_CNTL, save_crtc2_gen_cntl | CRTC2_DISP_REQ_EN_B);
1287 	}
1288 	save_crtc_gen_cntl = INREG(CRTC_GEN_CNTL);
1289 	save_crtc_ext_cntl = INREG(CRTC_EXT_CNTL);
1290 
1291 	OUTREG(CRTC_EXT_CNTL, save_crtc_ext_cntl | CRTC_DISPLAY_DIS);
1292 	OUTREG(CRTC_GEN_CNTL, save_crtc_gen_cntl | CRTC_DISP_REQ_EN_B);
1293 	mdelay(100);
1294 
1295 	aper_base = INREG(CONFIG_APER_0_BASE);
1296 	aper_size = INREG(CONFIG_APER_SIZE);
1297 
1298 #ifdef SET_MC_FB_FROM_APERTURE
1299 	/* Set framebuffer to be at the same address as set in PCI BAR */
1300 	OUTREG(MC_FB_LOCATION,
1301 		((aper_base + aper_size - 1) & 0xffff0000) | (aper_base >> 16));
1302 	rinfo->fb_local_base = aper_base;
1303 #else
1304 	OUTREG(MC_FB_LOCATION, 0x7fff0000);
1305 	rinfo->fb_local_base = 0;
1306 #endif
1307 	agp_base = aper_base + aper_size;
1308 	if (agp_base & 0xf0000000)
1309 		agp_base = (aper_base | 0x0fffffff) + 1;
1310 
1311 	/* Set AGP to be just after the framebuffer on a 256Mb boundary. This
1312 	 * assumes the FB isn't mapped to 0xf0000000 or above, but this is
1313 	 * always the case on PPCs afaik.
1314 	 */
1315 #ifdef SET_MC_FB_FROM_APERTURE
1316 	OUTREG(MC_AGP_LOCATION, 0xffff0000 | (agp_base >> 16));
1317 #else
1318 	OUTREG(MC_AGP_LOCATION, 0xffffe000);
1319 #endif
1320 
1321 	/* Fixup the display base addresses & engine offsets while we
1322 	 * are at it as well
1323 	 */
1324 #ifdef SET_MC_FB_FROM_APERTURE
1325 	OUTREG(DISPLAY_BASE_ADDR, aper_base);
1326 	if (rinfo->hasCRTC2)
1327 		OUTREG(CRTC2_DISPLAY_BASE_ADDR, aper_base);
1328 #else
1329 	OUTREG(DISPLAY_BASE_ADDR, 0);
1330 	if (rinfo->hasCRTC2)
1331 		OUTREG(CRTC2_DISPLAY_BASE_ADDR, 0);
1332 #endif
1333 	mdelay(100);
1334 
1335 	/* Restore display settings */
1336 	OUTREG(CRTC_GEN_CNTL, save_crtc_gen_cntl);
1337 	OUTREG(CRTC_EXT_CNTL, save_crtc_ext_cntl);
1338 	if (rinfo->hasCRTC2)
1339 		OUTREG(CRTC2_GEN_CNTL, save_crtc2_gen_cntl);
1340 
1341 #if 0
1342 	printk("aper_base: %08x MC_FB_LOC to: %08x, MC_AGP_LOC to: %08x\n",
1343 		aper_base,
1344 		((aper_base + aper_size - 1) & 0xffff0000) | (aper_base >> 16),
1345 		0xffff0000 | (agp_base >> 16));
1346 #endif
1347 }
1348 #endif /* CONFIG_ALL_PPC */
1349 
radeon_dfp_parse_EDID(struct radeonfb_info * rinfo)1350 static int radeon_dfp_parse_EDID(struct radeonfb_info *rinfo)
1351 {
1352 	unsigned char *block = rinfo->EDID;
1353 
1354 	if (!block)
1355 		return 0;
1356 
1357 	/* jump to the detailed timing block section */
1358 	block += 54;
1359 
1360 	rinfo->clock = (block[0] + (block[1] << 8));
1361 	rinfo->panel_xres = (block[2] + ((block[4] & 0xf0) << 4));
1362 	rinfo->hblank = (block[3] + ((block[4] & 0x0f) << 8));
1363 	rinfo->panel_yres = (block[5] + ((block[7] & 0xf0) << 4));
1364 	rinfo->vblank = (block[6] + ((block[7] & 0x0f) << 8));
1365 	rinfo->hOver_plus = (block[8] + ((block[11] & 0xc0) << 2));
1366 	rinfo->hSync_width = (block[9] + ((block[11] & 0x30) << 4));
1367 	rinfo->vOver_plus = ((block[10] >> 4) + ((block[11] & 0x0c) << 2));
1368 	rinfo->vSync_width = ((block[10] & 0x0f) + ((block[11] & 0x03) << 4));
1369 	rinfo->interlaced = ((block[17] & 0x80) >> 7);
1370 	rinfo->synct = ((block[17] & 0x18) >> 3);
1371 	rinfo->misc = ((block[17] & 0x06) >> 1);
1372 	rinfo->hAct_high = rinfo->vAct_high = 0;
1373 	if (rinfo->synct == 3) {
1374 		if (rinfo->misc & 2)
1375 			rinfo->hAct_high = 1;
1376 		if (rinfo->misc & 1)
1377 			rinfo->vAct_high = 1;
1378 	}
1379 
1380 	RTRACE("hOver_plus = %d\t hSync_width = %d\n", rinfo->hOver_plus,
1381 		rinfo->hSync_width);
1382 	RTRACE("vOver_plus = %d\t vSync_width = %d\n", rinfo->vOver_plus,
1383 		rinfo->vSync_width);
1384 	RTRACE("hblank = %d\t vblank = %d\n", rinfo->hblank,
1385 		rinfo->vblank);
1386 	RTRACE("sync = %d\n", rinfo->synct);
1387 	RTRACE("misc = %d\n", rinfo->misc);
1388 	RTRACE("clock = %d\n", rinfo->clock);
1389 	printk("radeonfb: detected DFP panel size from EDID: %dx%d\n",
1390 		rinfo->panel_xres, rinfo->panel_yres);
1391 
1392 	rinfo->got_dfpinfo = 1;
1393 
1394 	return 1;
1395 }
1396 
radeon_update_default_var(struct radeonfb_info * rinfo)1397 static void radeon_update_default_var(struct radeonfb_info *rinfo)
1398 {
1399 	struct fb_var_screeninfo *var = &radeonfb_default_var;
1400 
1401         /*
1402          * Update default var to match the lcd monitor's native resolution
1403          */
1404 	var->xres = rinfo->panel_xres;
1405 	var->yres = rinfo->panel_yres;
1406 	var->xres_virtual = rinfo->panel_xres;
1407 	var->yres_virtual = rinfo->panel_yres;
1408 	var->xoffset = var->yoffset = 0;
1409 	var->bits_per_pixel = 8;
1410 	var->pixclock = 100000000 / rinfo->clock;
1411 	var->left_margin = (rinfo->hblank - rinfo->hOver_plus - rinfo->hSync_width);
1412 	var->right_margin = rinfo->hOver_plus;
1413 	var->upper_margin = (rinfo->vblank - rinfo->vOver_plus - rinfo->vSync_width);
1414 	var->lower_margin = rinfo->vOver_plus;
1415 	var->hsync_len = rinfo->hSync_width;
1416 	var->vsync_len = rinfo->vSync_width;
1417 	var->sync = 0;
1418 	if (rinfo->hAct_high)
1419 		var->sync |= FB_SYNC_HOR_HIGH_ACT;
1420 	if (rinfo->vAct_high)
1421 		var->sync |= FB_SYNC_VERT_HIGH_ACT;
1422 
1423 	var->vmode = 0;
1424 	if (rinfo->interlaced)
1425 		var->vmode |= FB_VMODE_INTERLACED;
1426 
1427 	rinfo->use_default_var = 1;
1428 }
1429 
1430 /* Copied from XFree86 4.3 --BenH */
1431 static int
radeon_get_dfpinfo_BIOS(struct radeonfb_info * rinfo,unsigned char * fpbiosstart)1432 radeon_get_dfpinfo_BIOS(struct radeonfb_info *rinfo, unsigned char *fpbiosstart)
1433 {
1434 	unsigned char *tmp;
1435 	unsigned short offset;
1436 
1437 	offset = readw(fpbiosstart + 0x34);
1438 	if (offset != 0)
1439 		offset = readw(rinfo->bios_seg + offset + 2);
1440 	if (offset == 0) {
1441 		printk("radeonfb: Failed to detect DFP panel info using BIOS\n");
1442 		return 0;
1443 	}
1444 	tmp = rinfo->bios_seg + offset;
1445 
1446 	/* This is an EDID block */
1447 	rinfo->clock = readw(tmp);
1448 	rinfo->panel_xres = (readb(tmp + 2) + ((readb(tmp + 4) & 0xf0) << 4));
1449 	rinfo->hblank = (readb(tmp + 3) + ((readb(tmp + 4) & 0x0f) << 8));
1450 	rinfo->panel_yres = (readb(tmp + 5) + ((readb(tmp + 7) & 0xf0) << 4));
1451 	rinfo->vblank = (readb(tmp + 6) + ((readb(tmp + 7) & 0x0f) << 8));
1452 	rinfo->hOver_plus = (readb(tmp + 8) + ((readb(tmp + 11) & 0xc0) << 2));
1453 	rinfo->hSync_width = (readb(tmp + 9) + ((readb(tmp + 11) & 0x30) << 4));
1454 	rinfo->vOver_plus = ((readb(tmp + 10) >> 4) + ((readb(tmp + 11) & 0x0c) << 2));
1455 	rinfo->vSync_width = ((readb(tmp + 10) & 0x0f) + ((readb(tmp + 11) & 0x03) << 4));
1456 	rinfo->interlaced = ((readb(tmp + 17) & 0x80) >> 7);
1457 	rinfo->synct = ((readb(tmp + 17) & 0x18) >> 3);
1458 	rinfo->misc = ((readb(tmp + 17) & 0x06) >> 1);
1459 	rinfo->hAct_high = rinfo->vAct_high = 0;
1460 	if (rinfo->synct == 3) {
1461 		if (rinfo->misc & 2)
1462 			rinfo->hAct_high = 1;
1463 		if (rinfo->misc & 1)
1464 			rinfo->vAct_high = 1;
1465 	}
1466 
1467 	printk("radeonfb: detected DFP panel size from BIOS: %dx%d\n",
1468 		rinfo->panel_xres, rinfo->panel_yres);
1469 
1470 	rinfo->got_dfpinfo = 1;
1471 	return 1;
1472 }
1473 
1474 
1475 static int
radeon_get_lcdinfo_BIOS(struct radeonfb_info * rinfo,unsigned char * fpbiosstart)1476 radeon_get_lcdinfo_BIOS(struct radeonfb_info *rinfo, unsigned char *fpbiosstart)
1477 {
1478 	unsigned char *tmp, *tmp0;
1479 	unsigned char stmp[30];
1480 	unsigned short offset;
1481 	int i;
1482 
1483 	offset = readw(fpbiosstart + 0x40);
1484 	if (offset == 0) {
1485 		printk("radeonfb: Failed to detect LCD panel info using BIOS\n");
1486 		return 0;
1487 	}
1488 	tmp = rinfo->bios_seg + offset;
1489 
1490 	for(i=0; i<24; i++)
1491 		stmp[i] = readb(tmp+i+1);
1492 	stmp[24] = 0;
1493 	printk("radeonfb: panel ID string: %s\n", stmp);
1494 	rinfo->panel_xres = readw(tmp + 25);
1495 	rinfo->panel_yres = readw(tmp + 27);
1496 	printk("radeonfb: detected LCD panel size from BIOS: %dx%d\n",
1497 		rinfo->panel_xres, rinfo->panel_yres);
1498 
1499 	for(i=0; i<20; i++) {
1500 		tmp0 = rinfo->bios_seg + readw(tmp+64+i*2);
1501 		if (tmp0 == 0)
1502 			break;
1503 		if ((readw(tmp0) == rinfo->panel_xres) &&
1504 		    (readw(tmp0+2) == rinfo->panel_yres)) {
1505 			rinfo->hblank = (readw(tmp0+17) - readw(tmp0+19)) * 8;
1506 			rinfo->hOver_plus = ((readw(tmp0+21) - readw(tmp0+19) -1) * 8) & 0x7fff;
1507 			rinfo->hSync_width = readb(tmp0+23) * 8;
1508 			rinfo->vblank = readw(tmp0+24) - readw(tmp0+26);
1509 			rinfo->vOver_plus = (readw(tmp0+28) & 0x7ff) - readw(tmp0+26);
1510 			rinfo->vSync_width = (readw(tmp0+28) & 0xf800) >> 11;
1511 			rinfo->clock = readw(tmp0+9);
1512                         /* We don't know that the H/V sync active level should be
1513                            make the same assumptions as XFree does - High Active */
1514                         rinfo->vAct_high=1;
1515                         rinfo->hAct_high=1;
1516 			rinfo->got_dfpinfo = 1;
1517 			return 1;
1518 		}
1519 	}
1520 	return 0;
1521 }
1522 
radeon_get_panelinfo_BIOS(struct radeonfb_info * rinfo)1523 static int radeon_get_panelinfo_BIOS(struct radeonfb_info *rinfo)
1524 {
1525 	unsigned char *fpbiosstart;
1526 
1527 	if (!rinfo->bios_seg)
1528 		return 0;
1529 
1530 	if (!(fpbiosstart = rinfo->bios_seg + readw(rinfo->bios_seg + 0x48))) {
1531 		printk("radeonfb: Failed to detect DFP panel info using BIOS\n");
1532 		return 0;
1533 	}
1534 
1535 	if (rinfo->dviDisp_type == MT_LCD)
1536 		return radeon_get_lcdinfo_BIOS(rinfo, fpbiosstart);
1537 	else if (rinfo->dviDisp_type == MT_DFP)
1538 		return radeon_get_dfpinfo_BIOS(rinfo, fpbiosstart);
1539 
1540 	return 0;
1541 }
1542 
1543 
1544 
radeon_get_dfpinfo(struct radeonfb_info * rinfo)1545 static int radeon_get_dfpinfo (struct radeonfb_info *rinfo)
1546 {
1547 	unsigned int tmp;
1548 	unsigned short a, b;
1549 
1550 	if (radeon_get_panelinfo_BIOS(rinfo))
1551 		radeon_update_default_var(rinfo);
1552 
1553 	if (radeon_dfp_parse_EDID(rinfo))
1554 		radeon_update_default_var(rinfo);
1555 
1556 	if (!rinfo->got_dfpinfo) {
1557 		/*
1558 		 * it seems all else has failed now and we
1559 		 * resort to probing registers for our DFP info
1560 	         */
1561 		if (panel_yres) {
1562 			rinfo->panel_yres = panel_yres;
1563 		} else {
1564 			tmp = INREG(FP_VERT_STRETCH);
1565 			tmp &= 0x00fff000;
1566 			rinfo->panel_yres = (unsigned short)(tmp >> 0x0c) + 1;
1567 		}
1568 
1569 		switch (rinfo->panel_yres) {
1570 			case 480:
1571 				rinfo->panel_xres = 640;
1572 				break;
1573 			case 600:
1574 				rinfo->panel_xres = 800;
1575 				break;
1576 			case 768:
1577 				rinfo->panel_xres = 1024;
1578 				break;
1579 			case 1024:
1580 				rinfo->panel_xres = 1280;
1581 				break;
1582 			case 1050:
1583 				rinfo->panel_xres = 1400;
1584 				break;
1585 			case 1200:
1586 				rinfo->panel_xres = 1600;
1587 				break;
1588 			default:
1589 				printk("radeonfb: Failed to detect DFP panel size\n");
1590 				return 0;
1591 		}
1592 
1593 		printk("radeonfb: detected DFP panel size from registers: %dx%d\n",
1594 			rinfo->panel_xres, rinfo->panel_yres);
1595 
1596 		tmp = INREG(FP_CRTC_H_TOTAL_DISP);
1597 		a = (tmp & FP_CRTC_H_TOTAL_MASK) + 4;
1598 		b = (tmp & 0x01ff0000) >> FP_CRTC_H_DISP_SHIFT;
1599 		rinfo->hblank = (a - b + 1) * 8;
1600 
1601 		tmp = INREG(FP_H_SYNC_STRT_WID);
1602 		rinfo->hOver_plus = (unsigned short) ((tmp & FP_H_SYNC_STRT_CHAR_MASK) >>
1603 					FP_H_SYNC_STRT_CHAR_SHIFT) - b - 1;
1604 		rinfo->hOver_plus *= 8;
1605 		rinfo->hSync_width = (unsigned short) ((tmp & FP_H_SYNC_WID_MASK) >>
1606 					FP_H_SYNC_WID_SHIFT);
1607 		rinfo->hSync_width *= 8;
1608 		tmp = INREG(FP_CRTC_V_TOTAL_DISP);
1609 		a = (tmp & FP_CRTC_V_TOTAL_MASK) + 1;
1610 		b = (tmp & FP_CRTC_V_DISP_MASK) >> FP_CRTC_V_DISP_SHIFT;
1611 		rinfo->vblank = a - b /* + 24 */ ;
1612 
1613 		tmp = INREG(FP_V_SYNC_STRT_WID);
1614 		rinfo->vOver_plus = (unsigned short) (tmp & FP_V_SYNC_STRT_MASK)
1615 					- b + 1;
1616 		rinfo->vSync_width = (unsigned short) ((tmp & FP_V_SYNC_WID_MASK) >>
1617 					FP_V_SYNC_WID_SHIFT);
1618 
1619 		/* XXX */
1620 		/* We should calculate the pixclock as well here... --BenH.
1621 		 */
1622 
1623 		return 1;
1624 	}
1625 
1626 	return 1;
1627 }
1628 
radeonfb_pci_register(struct pci_dev * pdev,const struct pci_device_id * ent)1629 static int radeonfb_pci_register (struct pci_dev *pdev,
1630 				  const struct pci_device_id *ent)
1631 {
1632 	struct radeonfb_info *rinfo;
1633 	struct fb_info *fb_info;
1634 	struct radeon_chip_info *rci = &radeon_chip_info[ent->driver_data];
1635 	u32 tmp;
1636 	int i, j;
1637 
1638 	RTRACE("radeonfb_pci_register BEGIN\n");
1639 
1640 	rinfo = kmalloc (sizeof (struct radeonfb_info), GFP_KERNEL);
1641 	if (!rinfo) {
1642 		printk ("radeonfb: could not allocate memory\n");
1643 		return -ENODEV;
1644 	}
1645 
1646 	memset (rinfo, 0, sizeof (struct radeonfb_info));
1647 
1648 	fb_info = (struct fb_info *)rinfo;
1649 	rinfo->pdev = pdev;
1650 	strncpy(rinfo->name, rci->name, 16);
1651 	rinfo->arch = rci->arch;
1652 
1653 	/* enable device */
1654 	{
1655 		int err;
1656 
1657 		if ((err = pci_enable_device(pdev))) {
1658 			printk("radeonfb: cannot enable device\n");
1659 			kfree (rinfo);
1660 			return -ENODEV;
1661 		}
1662 	}
1663 
1664 	/* set base addrs */
1665 	rinfo->fb_base_phys = pci_resource_start (pdev, 0);
1666 	rinfo->mmio_base_phys = pci_resource_start (pdev, 2);
1667 
1668 	/* request the mem regions */
1669 	if (!request_mem_region (rinfo->fb_base_phys,
1670 				 pci_resource_len(pdev, 0), "radeonfb")) {
1671 		printk ("radeonfb: cannot reserve FB region\n");
1672 		kfree (rinfo);
1673 		return -ENODEV;
1674 	}
1675 
1676 	if (!request_mem_region (rinfo->mmio_base_phys,
1677 				 pci_resource_len(pdev, 2), "radeonfb")) {
1678 		printk ("radeonfb: cannot reserve MMIO region\n");
1679 		release_mem_region (rinfo->fb_base_phys,
1680 				    pci_resource_len(pdev, 0));
1681 		kfree (rinfo);
1682 		return -ENODEV;
1683 	}
1684 
1685 	/* map the regions */
1686 	rinfo->mmio_base = (unsigned long) ioremap (rinfo->mmio_base_phys,
1687 				    		    RADEON_REGSIZE);
1688 	if (!rinfo->mmio_base) {
1689 		printk ("radeonfb: cannot map MMIO\n");
1690 		release_mem_region (rinfo->mmio_base_phys,
1691 				    pci_resource_len(pdev, 2));
1692 		release_mem_region (rinfo->fb_base_phys,
1693 				    pci_resource_len(pdev, 0));
1694 		kfree (rinfo);
1695 		return -ENODEV;
1696 	}
1697 
1698 	rinfo->chipset = pdev->device;
1699 
1700 	switch (rinfo->arch) {
1701 		case RADEON_R100:
1702 			rinfo->hasCRTC2 = 0;
1703 			break;
1704 		default:
1705 			/* all the rest have it */
1706 			rinfo->hasCRTC2 = 1;
1707 			break;
1708 	}
1709 
1710 	if (mirror)
1711 		printk("radeonfb: mirroring display to CRT\n");
1712 
1713 	/* framebuffer size */
1714 	tmp = INREG(CONFIG_MEMSIZE);
1715 
1716 	/* mem size is bits [28:0], mask off the rest */
1717 	rinfo->video_ram = tmp & CONFIG_MEMSIZE_MASK;
1718 
1719 	/* ram type */
1720 	tmp = INREG(MEM_SDRAM_MODE_REG);
1721 	switch ((MEM_CFG_TYPE & tmp) >> 30) {
1722 		case 0:
1723 			/* SDR SGRAM (2:1) */
1724 			strcpy(rinfo->ram_type, "SDR SGRAM");
1725 			rinfo->ram.ml = 4;
1726 			rinfo->ram.mb = 4;
1727 			rinfo->ram.trcd = 1;
1728 			rinfo->ram.trp = 2;
1729 			rinfo->ram.twr = 1;
1730 			rinfo->ram.cl = 2;
1731 			rinfo->ram.loop_latency = 16;
1732 			rinfo->ram.rloop = 16;
1733 
1734 			break;
1735 		case 1:
1736 			/* DDR SGRAM */
1737 			strcpy(rinfo->ram_type, "DDR SGRAM");
1738 			rinfo->ram.ml = 4;
1739 			rinfo->ram.mb = 4;
1740 			rinfo->ram.trcd = 3;
1741 			rinfo->ram.trp = 3;
1742 			rinfo->ram.twr = 2;
1743 			rinfo->ram.cl = 3;
1744 			rinfo->ram.tr2w = 1;
1745 			rinfo->ram.loop_latency = 16;
1746 			rinfo->ram.rloop = 16;
1747 
1748 			break;
1749 		default:
1750 			/* 64-bit SDR SGRAM */
1751 			strcpy(rinfo->ram_type, "SDR SGRAM 64");
1752 			rinfo->ram.ml = 4;
1753 			rinfo->ram.mb = 8;
1754 			rinfo->ram.trcd = 3;
1755 			rinfo->ram.trp = 3;
1756 			rinfo->ram.twr = 1;
1757 			rinfo->ram.cl = 3;
1758 			rinfo->ram.tr2w = 1;
1759 			rinfo->ram.loop_latency = 17;
1760 			rinfo->ram.rloop = 17;
1761 
1762 			break;
1763 	}
1764 
1765 	rinfo->bios_seg = radeon_find_rom(rinfo);
1766 	radeon_get_pllinfo(rinfo, rinfo->bios_seg);
1767 
1768 	/*
1769 	 * Hack to get around some busted production M6's
1770 	 * reporting no ram
1771 	 */
1772 	if (rinfo->video_ram == 0) {
1773 		switch (pdev->device) {
1774 			case PCI_DEVICE_ID_ATI_RADEON_LY:
1775 			case PCI_DEVICE_ID_ATI_RADEON_LZ:
1776 				rinfo->video_ram = 8192 * 1024;
1777 				break;
1778 			default:
1779 				break;
1780 		}
1781 	}
1782 
1783 
1784 	RTRACE("radeonfb: probed %s %dk videoram\n", (rinfo->ram_type), (rinfo->video_ram/1024));
1785 
1786 	RTRACE("BIOS 4 scratch = %x\n", INREG(RADEON_BIOS_4_SCRATCH));
1787 	RTRACE("FP_GEN_CNTL: %x, FP2_GEN_CNTL: %x\n",
1788 		INREG(FP_GEN_CNTL), INREG(FP2_GEN_CNTL));
1789 	RTRACE("TMDS_TRANSMITTER_CNTL: %x, TMDS_CNTL: %x, LVDS_GEN_CNTL: %x\n",
1790 		INREG(TMDS_TRANSMITTER_CNTL), INREG(TMDS_CNTL), INREG(LVDS_GEN_CNTL));
1791 	RTRACE("DAC_CNTL: %x, DAC_CNTL2: %x, CRTC_GEN_CNTL: %x\n",
1792 		INREG(DAC_CNTL), INREG(DAC_CNTL2), INREG(CRTC_GEN_CNTL));
1793 
1794 
1795 #if !defined(__powerpc__)
1796 	radeon_get_moninfo(rinfo);
1797 #else
1798 	switch (rinfo->arch) {
1799 		case RADEON_M6:
1800 		case RADEON_M7:
1801 		case RADEON_M9:
1802 			/* If forced to no-LCD, we shut down the backlight */
1803 			if (force_nolcd) {
1804 #ifdef CONFIG_PMAC_BACKLIGHT
1805 				radeon_set_backlight_enable(0, BACKLIGHT_OFF, rinfo);
1806 #endif
1807 			} else {
1808 				rinfo->dviDisp_type = MT_LCD;
1809 				break;
1810 			}
1811 			/* Fall through */
1812 		default:
1813 			radeon_get_moninfo(rinfo);
1814 			break;
1815 	}
1816 #endif
1817 
1818 	radeon_get_EDID(rinfo);
1819 
1820 	if ((rinfo->dviDisp_type == MT_DFP) || (rinfo->dviDisp_type == MT_LCD) ||
1821 	    (rinfo->crtDisp_type == MT_DFP)) {
1822 		if (!radeon_get_dfpinfo(rinfo)) {
1823 			iounmap ((void*)rinfo->mmio_base);
1824 			release_mem_region (rinfo->mmio_base_phys,
1825 					    pci_resource_len(pdev, 2));
1826 			release_mem_region (rinfo->fb_base_phys,
1827 					    pci_resource_len(pdev, 0));
1828 			kfree (rinfo);
1829 			return -ENODEV;
1830 		}
1831 	}
1832 
1833 	fb_info->mapped_vram = min_t(unsigned int, MAX_MAPPED_VRAM, rinfo->video_ram);
1834 	do {
1835 		rinfo->fb_base = (unsigned long) ioremap (rinfo->fb_base_phys,
1836 				  		  fb_info->mapped_vram);
1837 		if (rinfo->fb_base)
1838 			break;
1839 
1840 		fb_info->mapped_vram /= 2;
1841 	} while(fb_info->mapped_vram > MIN_MAPPED_VRAM);
1842 
1843 	if (!rinfo->fb_base) {
1844 		printk ("radeonfb: cannot map FB\n");
1845 		iounmap ((void*)rinfo->mmio_base);
1846 		release_mem_region (rinfo->mmio_base_phys,
1847 				    pci_resource_len(pdev, 2));
1848 		release_mem_region (rinfo->fb_base_phys,
1849 				    pci_resource_len(pdev, 0));
1850 		kfree (rinfo);
1851 		return -ENODEV;
1852 	}
1853 	RTRACE(KERN_INFO "radeonfb: mapped %dk videoram\n", fb_info->mapped_vram/1024);
1854 
1855 	/* currcon not yet configured, will be set by first switch */
1856 	rinfo->currcon = -1;
1857 
1858 	/* On PPC, the firmware sets up a memory mapping that tends
1859 	 * to cause lockups when enabling the engine. We reconfigure
1860 	 * the card internal memory mappings properly
1861 	 */
1862 #ifdef CONFIG_ALL_PPC
1863 	radeon_fixup_apertures(rinfo);
1864 #else
1865 	rinfo->fb_local_base = INREG(MC_FB_LOCATION) << 16;
1866 #endif /* CONFIG_ALL_PPC */
1867 
1868 	/* save current mode regs before we switch into the new one
1869 	 * so we can restore this upon __exit
1870 	 */
1871 	radeon_save_state (rinfo, &rinfo->init_state);
1872 
1873 	/* init palette */
1874 	for (i=0; i<16; i++) {
1875 		j = color_table[i];
1876 		rinfo->palette[i].red = default_red[j];
1877 		rinfo->palette[i].green = default_grn[j];
1878 		rinfo->palette[i].blue = default_blu[j];
1879 	}
1880 
1881 	pci_set_drvdata(pdev, rinfo);
1882 	rinfo->next = board_list;
1883 	board_list = rinfo;
1884 
1885 	/* set all the vital stuff */
1886 	radeon_set_fbinfo (rinfo);
1887 
1888 	if (register_framebuffer ((struct fb_info *) rinfo) < 0) {
1889 		printk ("radeonfb: could not register framebuffer\n");
1890 		iounmap ((void*)rinfo->fb_base);
1891 		iounmap ((void*)rinfo->mmio_base);
1892 		release_mem_region (rinfo->mmio_base_phys,
1893 				    pci_resource_len(pdev, 2));
1894 		release_mem_region (rinfo->fb_base_phys,
1895 				    pci_resource_len(pdev, 0));
1896 		kfree (rinfo);
1897 		return -ENODEV;
1898 	}
1899 
1900 #ifdef CONFIG_MTRR
1901 	rinfo->mtrr_hdl = nomtrr ? -1 : mtrr_add(rinfo->fb_base_phys,
1902 						 rinfo->video_ram,
1903 						 MTRR_TYPE_WRCOMB, 1);
1904 #endif
1905 
1906 
1907 #ifdef CONFIG_PMAC_BACKLIGHT
1908 	if (rinfo->dviDisp_type == MT_LCD)
1909 		register_backlight_controller(&radeon_backlight_controller,
1910 					      rinfo, "ati");
1911 #endif
1912 
1913 	printk ("radeonfb: ATI Radeon %s %s %d MB\n", rinfo->name, rinfo->ram_type,
1914 		(rinfo->video_ram/(1024*1024)));
1915 
1916 	if (rinfo->hasCRTC2) {
1917 		printk("radeonfb: DVI port %s monitor connected\n",
1918 			GET_MON_NAME(rinfo->dviDisp_type));
1919 		printk("radeonfb: CRT port %s monitor connected\n",
1920 			GET_MON_NAME(rinfo->crtDisp_type));
1921 	} else {
1922 		printk("radeonfb: CRT port %s monitor connected\n",
1923 			GET_MON_NAME(rinfo->crtDisp_type));
1924 	}
1925 
1926 #ifdef CONFIG_PMAC_PBOOK
1927 	if (rinfo->arch == RADEON_M6 ||
1928 	    rinfo->arch == RADEON_M7 ||
1929 	    rinfo->arch == RADEON_M9) {
1930                /* Find PM registers in config space */
1931                rinfo->pm_reg = pci_find_capability(pdev, PCI_CAP_ID_PM);
1932 
1933                /* Enable dynamic PM of chip clocks */
1934                radeon_pm_enable_dynamic_mode(rinfo);
1935 
1936                /* Register sleep callbacks */
1937                pmu_register_sleep_notifier(&radeon_sleep_notifier);
1938                printk("radeonfb: Power Management enabled for Mobility chipsets\n");
1939        }
1940 #endif
1941 
1942 	RTRACE("radeonfb_pci_register END\n");
1943 
1944 	return 0;
1945 }
1946 
1947 
1948 
radeonfb_pci_unregister(struct pci_dev * pdev)1949 static void __devexit radeonfb_pci_unregister (struct pci_dev *pdev)
1950 {
1951         struct radeonfb_info *rinfo = pci_get_drvdata(pdev);
1952 
1953         if (!rinfo)
1954                 return;
1955 
1956 	/* restore original state */
1957         radeon_write_mode (rinfo, &rinfo->init_state);
1958 
1959 #ifdef CONFIG_MTRR
1960 	if (rinfo->mtrr_hdl >= 0)
1961 		mtrr_del(rinfo->mtrr_hdl, 0, 0);
1962 #endif
1963 
1964         unregister_framebuffer ((struct fb_info *) rinfo);
1965 
1966         iounmap ((void*)rinfo->mmio_base);
1967         iounmap ((void*)rinfo->fb_base);
1968 
1969 	release_mem_region (rinfo->mmio_base_phys,
1970 			    pci_resource_len(pdev, 2));
1971 	release_mem_region (rinfo->fb_base_phys,
1972 			    pci_resource_len(pdev, 0));
1973 
1974         kfree (rinfo);
1975 }
1976 
1977 
radeon_engine_init(struct radeonfb_info * rinfo)1978 static int radeon_engine_init (struct radeonfb_info *rinfo)
1979 {
1980 	unsigned long temp;
1981 
1982 	/* disable 3D engine */
1983 	OUTREG(RB3D_CNTL, 0);
1984 
1985 	radeon_engine_reset ();
1986 
1987 	radeon_fifo_wait (1);
1988 	if (rinfo->arch != RADEON_R300)
1989 		OUTREG(RB2D_DSTCACHE_MODE, 0);
1990 
1991 	radeon_fifo_wait (3);
1992 	/* We re-read MC_FB_LOCATION from card as it can have been
1993 	 * modified by XFree drivers (ouch !)
1994 	 */
1995 	rinfo->fb_local_base = INREG(MC_FB_LOCATION) << 16;
1996 
1997 	OUTREG(DEFAULT_PITCH_OFFSET, (rinfo->pitch << 0x16) |
1998 				     (rinfo->fb_local_base >> 10));
1999 	OUTREG(DST_PITCH_OFFSET, (rinfo->pitch << 0x16) | (rinfo->fb_local_base >> 10));
2000 	OUTREG(SRC_PITCH_OFFSET, (rinfo->pitch << 0x16) | (rinfo->fb_local_base >> 10));
2001 
2002 	radeon_fifo_wait (1);
2003 #if defined(__BIG_ENDIAN)
2004 	OUTREGP(DP_DATATYPE, HOST_BIG_ENDIAN_EN, ~HOST_BIG_ENDIAN_EN);
2005 #else
2006 	OUTREGP(DP_DATATYPE, 0, ~HOST_BIG_ENDIAN_EN);
2007 #endif
2008 	radeon_fifo_wait (1);
2009 	OUTREG(DEFAULT_SC_BOTTOM_RIGHT, (DEFAULT_SC_RIGHT_MAX |
2010 					 DEFAULT_SC_BOTTOM_MAX));
2011 
2012 	temp = radeon_get_dstbpp(rinfo->depth);
2013 	rinfo->dp_gui_master_cntl = ((temp << 8) | GMC_CLR_CMP_CNTL_DIS);
2014 
2015 	radeon_fifo_wait (1);
2016 	OUTREG(DP_GUI_MASTER_CNTL, (rinfo->dp_gui_master_cntl |
2017 				    GMC_BRUSH_SOLID_COLOR |
2018 				    GMC_SRC_DATATYPE_COLOR));
2019 
2020 	radeon_fifo_wait (7);
2021 
2022 	/* clear line drawing regs */
2023 	OUTREG(DST_LINE_START, 0);
2024 	OUTREG(DST_LINE_END, 0);
2025 
2026 	/* set brush color regs */
2027 	OUTREG(DP_BRUSH_FRGD_CLR, 0xffffffff);
2028 	OUTREG(DP_BRUSH_BKGD_CLR, 0x00000000);
2029 
2030 	/* set source color regs */
2031 	OUTREG(DP_SRC_FRGD_CLR, 0xffffffff);
2032 	OUTREG(DP_SRC_BKGD_CLR, 0x00000000);
2033 
2034 	/* default write mask */
2035 	OUTREG(DP_WRITE_MSK, 0xffffffff);
2036 
2037 	radeon_engine_idle ();
2038 
2039 	return 0;
2040 }
2041 
2042 
2043 
radeon_set_fbinfo(struct radeonfb_info * rinfo)2044 static int __devinit radeon_set_fbinfo (struct radeonfb_info *rinfo)
2045 {
2046 	struct fb_info *info;
2047 
2048 	info = &rinfo->info;
2049 
2050 	strcpy (info->modename, rinfo->name);
2051         info->node = -1;
2052         info->flags = FBINFO_FLAG_DEFAULT;
2053         info->fbops = &radeon_fb_ops;
2054         info->display_fg = NULL;
2055         strncpy (info->fontname, fontname, sizeof (info->fontname));
2056         info->fontname[sizeof (info->fontname) - 1] = 0;
2057         info->changevar = NULL;
2058         info->switch_con = radeonfb_switch;
2059         info->updatevar = radeonfb_updatevar;
2060         info->blank = radeonfb_blank;
2061 
2062         if (radeon_init_disp (rinfo) < 0)
2063                 return -1;
2064 
2065         return 0;
2066 }
2067 
2068 
2069 
radeon_init_disp(struct radeonfb_info * rinfo)2070 static int __devinit radeon_init_disp (struct radeonfb_info *rinfo)
2071 {
2072         struct fb_info *info;
2073         struct display *disp;
2074 
2075         info = &rinfo->info;
2076         disp = &rinfo->disp;
2077 
2078         disp->var = radeonfb_default_var;
2079 
2080 	/* We must initialize disp before calling fb_find_mode, as the later
2081 	 * will cause an implicit call to radeonfb_set_var that could crash
2082 	 * if disp is NULL
2083 	 */
2084         info->disp = disp;
2085         rinfo->currcon_display = disp;
2086 
2087 #ifndef MODULE
2088         if (mode_option)
2089                 fb_find_mode (&disp->var, &rinfo->info, mode_option,
2090                               NULL, 0, NULL, 8);
2091         else
2092 #endif
2093 	if (!rinfo->use_default_var)
2094                 fb_find_mode (&disp->var, &rinfo->info, "640x480-8@60",
2095                               NULL, 0, NULL, 0);
2096 
2097 	disp->var.accel_flags |= FB_ACCELF_TEXT;
2098 
2099 	/* Do we need that below ? ... */
2100 	rinfo->depth = var_to_depth(&disp->var);
2101 	rinfo->bpp = disp->var.bits_per_pixel;
2102 
2103 	/* Apply that dawn mode ! */
2104 	radeon_do_set_var(&disp->var, -1, 0, info);
2105 
2106 	return 0;
2107 }
2108 
2109 
radeon_set_dispsw(struct radeonfb_info * rinfo,struct display * disp)2110 static void radeon_set_dispsw (struct radeonfb_info *rinfo, struct display *disp)
2111 
2112 {
2113         int accel;
2114 
2115         accel = disp->var.accel_flags & FB_ACCELF_TEXT;
2116 
2117         disp->dispsw_data = NULL;
2118 
2119         disp->screen_base = (char*)rinfo->fb_base;
2120         disp->type = FB_TYPE_PACKED_PIXELS;
2121         disp->type_aux = 0;
2122         disp->ypanstep = 1;
2123         disp->ywrapstep = 0;
2124         disp->can_soft_blank = 1;
2125         disp->inverse = 0;
2126 
2127         switch (disp->var.bits_per_pixel) {
2128 #ifdef FBCON_HAS_CFB8
2129                 case 8:
2130                         disp->visual = FB_VISUAL_PSEUDOCOLOR;
2131                         disp->dispsw = accel ? &fbcon_radeon8 : &fbcon_cfb8;
2132                         if (accel)
2133                         	disp->line_length = (disp->var.xres_virtual + 0x3f) & ~0x3f;
2134                         else
2135                         	disp->line_length = disp->var.xres_virtual;
2136                         break;
2137 #endif /* FBCON_HAS_CFB8 */
2138 
2139 #ifdef FBCON_HAS_CFB16
2140                 case 16:
2141                         disp->dispsw = accel ? &fbcon_radeon16 : &fbcon_cfb16;
2142                         disp->dispsw_data = &rinfo->con_cmap.cfb16;
2143                         disp->visual = FB_VISUAL_DIRECTCOLOR;
2144                         if (accel)
2145 				disp->line_length = (disp->var.xres_virtual * 2 + 0x3f) & ~0x3f;
2146 			else
2147 				disp->line_length = disp->var.xres_virtual * 2;
2148                         break;
2149 #endif  /* FBCON_HAS_CFB16 */
2150 
2151 #ifdef FBCON_HAS_CFB24
2152                 case 24:
2153                         disp->dispsw = &fbcon_cfb24;
2154                         disp->dispsw_data = &rinfo->con_cmap.cfb24;
2155                         disp->visual = FB_VISUAL_DIRECTCOLOR;
2156                         if (accel)
2157 				disp->line_length = (disp->var.xres_virtual * 3 + 0x3f) & ~0x3f;
2158 			else
2159 				disp->line_length = disp->var.xres_virtual * 3;
2160                         break;
2161 #endif /* FBCON_HAS_CFB24 */
2162 
2163 #ifdef FBCON_HAS_CFB32
2164                 case 32:
2165                         disp->dispsw = accel ? &fbcon_radeon32 : &fbcon_cfb32;
2166                         disp->dispsw_data = &rinfo->con_cmap.cfb32;
2167                         disp->visual = FB_VISUAL_DIRECTCOLOR;
2168                         if (accel)
2169 				disp->line_length = (disp->var.xres_virtual * 4 + 0x3f) & ~0x3f;
2170 			else
2171 				disp->line_length = disp->var.xres_virtual * 4;
2172                         break;
2173 #endif /* FBCON_HAS_CFB32 */
2174 
2175                 default:
2176                         printk ("radeonfb: setting fbcon_dummy renderer\n");
2177                         disp->dispsw = &fbcon_dummy;
2178         }
2179 
2180         return;
2181 }
2182 
2183 
do_install_cmap(int con,struct fb_info * info)2184 static void do_install_cmap(int con, struct fb_info *info)
2185 {
2186         struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
2187 
2188         if (con != rinfo->currcon)
2189                 return;
2190 
2191         if (fb_display[con].cmap.len)
2192                 fb_set_cmap(&fb_display[con].cmap, 1, radeon_setcolreg, info);
2193         else {
2194 		int size = radeon_get_cmap_len(&fb_display[con].var);
2195                 fb_set_cmap(fb_default_cmap(size), 1, radeon_setcolreg, info);
2196         }
2197 }
2198 
2199 
2200 
radeonfb_do_maximize(struct radeonfb_info * rinfo,struct fb_var_screeninfo * var,struct fb_var_screeninfo * v,int nom,int den)2201 static int radeonfb_do_maximize(struct radeonfb_info *rinfo,
2202                                 struct fb_var_screeninfo *var,
2203                                 struct fb_var_screeninfo *v,
2204                                 int nom, int den)
2205 {
2206         static struct {
2207                 int xres, yres;
2208         } modes[] = {
2209                 {1600, 1280},
2210                 {1280, 1024},
2211                 {1024, 768},
2212                 {800, 600},
2213                 {640, 480},
2214                 {-1, -1}
2215         };
2216         int i;
2217 	struct fb_info *fb_info = (struct fb_info *)rinfo;
2218 
2219         /* use highest possible virtual resolution */
2220         if (v->xres_virtual == -1 && v->yres_virtual == -1) {
2221                 printk("radeonfb: using max available virtual resolution\n");
2222                 for (i=0; modes[i].xres != -1; i++) {
2223                         if (modes[i].xres * nom / den * modes[i].yres <
2224                             fb_info->mapped_vram / 2)
2225                                 break;
2226                 }
2227                 if (modes[i].xres == -1) {
2228                         printk("radeonfb: could not find virtual resolution that fits into video memory!\n");
2229                         return -EINVAL;
2230                 }
2231                 v->xres_virtual = modes[i].xres;
2232                 v->yres_virtual = modes[i].yres;
2233 
2234                 printk("radeonfb: virtual resolution set to max of %dx%d\n",
2235                         v->xres_virtual, v->yres_virtual);
2236         } else if (v->xres_virtual == -1) {
2237                 v->xres_virtual = (fb_info->mapped_vram * den /
2238                                 (nom * v->yres_virtual * 2)) & ~15;
2239         } else if (v->yres_virtual == -1) {
2240                 v->xres_virtual = (v->xres_virtual + 15) & ~15;
2241                 v->yres_virtual = fb_info->mapped_vram * den /
2242                         (nom * v->xres_virtual *2);
2243         } else {
2244                 if (v->xres_virtual * nom / den * v->yres_virtual >
2245                         fb_info->mapped_vram) {
2246                         return -EINVAL;
2247                 }
2248         }
2249 
2250         if (v->xres_virtual * nom / den >= 8192) {
2251                 v->xres_virtual = 8192 * den / nom - 16;
2252         }
2253 
2254         if (v->xres_virtual < v->xres)
2255                 return -EINVAL;
2256 
2257         if (v->yres_virtual < v->yres)
2258                 return -EINVAL;
2259 
2260         return 0;
2261 }
2262 
2263 
2264 
2265 /*
2266  * fb ops
2267  */
2268 
radeonfb_get_fix(struct fb_fix_screeninfo * fix,int con,struct fb_info * info)2269 static int radeonfb_get_fix (struct fb_fix_screeninfo *fix, int con,
2270                              struct fb_info *info)
2271 {
2272         struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
2273         struct display *disp;
2274 
2275         disp = (con < 0) ? rinfo->info.disp : &fb_display[con];
2276 
2277         memset (fix, 0, sizeof (struct fb_fix_screeninfo));
2278 	sprintf (fix->id, "ATI Radeon %s", rinfo->name);
2279 
2280         fix->smem_start = rinfo->fb_base_phys;
2281         fix->smem_len = rinfo->video_ram;
2282 
2283         fix->type = disp->type;
2284         fix->type_aux = disp->type_aux;
2285         fix->visual = disp->visual;
2286 
2287         fix->xpanstep = 8;
2288         fix->ypanstep = 1;
2289         fix->ywrapstep = 0;
2290 
2291         fix->line_length = disp->line_length;
2292 
2293         fix->mmio_start = rinfo->mmio_base_phys;
2294         fix->mmio_len = RADEON_REGSIZE;
2295 	if (noaccel)
2296 	        fix->accel = FB_ACCEL_NONE;
2297 	else
2298 		fix->accel = FB_ACCEL_ATI_RADEON;
2299 
2300         return 0;
2301 }
2302 
2303 
2304 
radeonfb_get_var(struct fb_var_screeninfo * var,int con,struct fb_info * info)2305 static int radeonfb_get_var (struct fb_var_screeninfo *var, int con,
2306                              struct fb_info *info)
2307 {
2308         struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
2309 
2310         *var = (con < 0) ? rinfo->disp.var : fb_display[con].var;
2311 
2312         return 0;
2313 }
2314 
2315 
radeon_do_set_var(struct fb_var_screeninfo * var,int con,int real,struct fb_info * info)2316 static int radeon_do_set_var (struct fb_var_screeninfo *var, int con,
2317                              int real, struct fb_info *info)
2318 {
2319         struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
2320         struct display *disp;
2321         struct fb_var_screeninfo v;
2322         int nom, den, accel;
2323         unsigned chgvar = 1;
2324 
2325         disp = (con < 0) ? rinfo->info.disp : &fb_display[con];
2326 
2327         accel = (noaccel == 0) && ((var->accel_flags & FB_ACCELF_TEXT) != 0);
2328 
2329         if (con >= 0) {
2330                 chgvar = ((disp->var.xres != var->xres) ||
2331                           (disp->var.yres != var->yres) ||
2332                           (disp->var.xres_virtual != var->xres_virtual) ||
2333                           (disp->var.yres_virtual != var->yres_virtual) ||
2334                           (disp->var.bits_per_pixel != var->bits_per_pixel) ||
2335                           memcmp (&disp->var.red, &var->red, sizeof (var->red)) ||
2336                           memcmp (&disp->var.green, &var->green, sizeof (var->green)) ||
2337                           memcmp (&disp->var.blue, &var->blue, sizeof (var->blue)) ||
2338                           var->accel_flags != disp->var.accel_flags);
2339         }
2340 
2341 try_again:
2342 
2343         memcpy (&v, var, sizeof (v));
2344 
2345         switch (v.bits_per_pixel) {
2346 		case 0 ... 8:
2347 			v.bits_per_pixel = 8;
2348 			break;
2349 		case 9 ... 16:
2350 			v.bits_per_pixel = 16;
2351 			break;
2352 		case 17 ... 24:
2353 			v.bits_per_pixel = 24;
2354 			break;
2355 		case 25 ... 32:
2356 			v.bits_per_pixel = 32;
2357 			break;
2358 		default:
2359 			return -EINVAL;
2360 	}
2361 
2362 	switch (var_to_depth(&v)) {
2363 #ifdef FBCON_HAS_CFB8
2364                 case 8:
2365                         nom = den = 1;
2366                         if (accel)
2367                         	disp->line_length = (v.xres_virtual + 0x3f) & ~0x3f;
2368                         else
2369                         	disp->line_length = v.xres_virtual;
2370                         disp->visual = FB_VISUAL_PSEUDOCOLOR;
2371                         v.red.offset = v.green.offset = v.blue.offset = 0;
2372                         v.red.length = v.green.length = v.blue.length = 8;
2373                         v.transp.offset = v.transp.length = 0;
2374                         break;
2375 #endif
2376 
2377 #ifdef FBCON_HAS_CFB16
2378 		case 15:
2379 			nom = 2;
2380 			den = 1;
2381 			if (accel)
2382                         	disp->line_length = (v.xres_virtual * 2 + 0x3f) & ~0x3f;
2383 			else
2384                         	disp->line_length = v.xres_virtual * 2;
2385 			disp->visual = FB_VISUAL_DIRECTCOLOR;
2386 			v.red.offset = 10;
2387 			v.green.offset = 5;
2388 			v.blue.offset = 0;
2389 			v.red.length = v.green.length = v.blue.length = 5;
2390 			v.transp.offset = v.transp.length = 0;
2391 			break;
2392                 case 16:
2393                         nom = 2;
2394                         den = 1;
2395 			if (accel)
2396                         	disp->line_length = (v.xres_virtual * 2 + 0x3f) & ~0x3f;
2397 			else
2398                         	disp->line_length = v.xres_virtual * 2;
2399                         disp->visual = FB_VISUAL_DIRECTCOLOR;
2400                         v.red.offset = 11;
2401                         v.green.offset = 5;
2402                         v.blue.offset = 0;
2403                         v.red.length = 5;
2404                         v.green.length = 6;
2405                         v.blue.length = 5;
2406                         v.transp.offset = v.transp.length = 0;
2407                         break;
2408 #endif
2409 
2410 #ifdef FBCON_HAS_CFB24
2411                 case 24:
2412                         nom = 4;
2413                         den = 1;
2414 			if (accel)
2415                         	disp->line_length = (v.xres_virtual * 3 + 0x3f) & ~0x3f;
2416 			else
2417                         	disp->line_length = v.xres_virtual * 3;
2418                         disp->visual = FB_VISUAL_DIRECTCOLOR;
2419                         v.red.offset = 16;
2420                         v.green.offset = 8;
2421                         v.blue.offset = 0;
2422                         v.red.length = v.blue.length = v.green.length = 8;
2423                         v.transp.offset = v.transp.length = 0;
2424                         break;
2425 #endif
2426 #ifdef FBCON_HAS_CFB32
2427                 case 32:
2428                         nom = 4;
2429                         den = 1;
2430 			if (accel)
2431                         	disp->line_length = (v.xres_virtual * 4 + 0x3f) & ~0x3f;
2432 			else
2433                         	disp->line_length = v.xres_virtual * 4;
2434                         disp->visual = FB_VISUAL_DIRECTCOLOR;
2435                         v.red.offset = 16;
2436                         v.green.offset = 8;
2437                         v.blue.offset = 0;
2438                         v.red.length = v.blue.length = v.green.length = 8;
2439                         v.transp.offset = 24;
2440                         v.transp.length = 8;
2441                         break;
2442 #endif
2443                 default:
2444                         printk ("radeonfb: mode %dx%dx%d rejected, color depth invalid\n",
2445                                 var->xres, var->yres, var->bits_per_pixel);
2446                         return -EINVAL;
2447         }
2448 
2449 	if (((v.xres_virtual * v.yres_virtual * nom) / den) > info->mapped_vram)
2450 		return -EINVAL;
2451 
2452         if (radeonfb_do_maximize(rinfo, var, &v, nom, den) < 0)
2453                 return -EINVAL;
2454 
2455         if (v.xoffset < 0)
2456                 v.xoffset = 0;
2457         if (v.yoffset < 0)
2458                 v.yoffset = 0;
2459 
2460         if (v.xoffset > v.xres_virtual - v.xres)
2461                 v.xoffset = v.xres_virtual - v.xres - 1;
2462 
2463         if (v.yoffset > v.yres_virtual - v.yres)
2464                 v.yoffset = v.yres_virtual - v.yres - 1;
2465 
2466         v.red.msb_right = v.green.msb_right = v.blue.msb_right =
2467                           v.transp.offset = v.transp.length =
2468                           v.transp.msb_right = 0;
2469 
2470         switch (v.activate & FB_ACTIVATE_MASK) {
2471                 case FB_ACTIVATE_TEST:
2472                         return 0;
2473                 case FB_ACTIVATE_NXTOPEN:
2474                 case FB_ACTIVATE_NOW:
2475                         break;
2476                 default:
2477                         return -EINVAL;
2478         }
2479 
2480         /* Set real accel */
2481         if (accel)
2482 	        v.accel_flags |= FB_ACCELF_TEXT;
2483         else
2484 	        v.accel_flags &= ~FB_ACCELF_TEXT;
2485 
2486         memcpy (&disp->var, &v, sizeof (v));
2487 
2488         if (real)
2489         	radeon_load_video_mode (rinfo, &v);
2490 	if (accel && real) {
2491 		if (radeon_engine_init(rinfo) < 0) {
2492                         var->accel_flags &= ~FB_ACCELF_TEXT;
2493 			goto try_again;
2494 		}
2495 	}
2496 
2497         if (chgvar) {
2498 	        radeon_set_dispsw(rinfo, disp);
2499 
2500                 if (!accel)
2501                         disp->scrollmode = SCROLL_YREDRAW;
2502                 else
2503                         disp->scrollmode = 0;
2504 
2505                 if (info && info->changevar && con >= 0)
2506                         info->changevar(con);
2507         }
2508 
2509         if (real)
2510         	do_install_cmap(con, info);
2511 
2512         return 0;
2513 }
2514 
radeonfb_set_var(struct fb_var_screeninfo * var,int con,struct fb_info * info)2515 static int radeonfb_set_var (struct fb_var_screeninfo *var, int con,
2516                              struct fb_info *info)
2517 {
2518 	return radeon_do_set_var(var, con, 1, info);
2519 }
2520 
2521 
radeonfb_get_cmap(struct fb_cmap * cmap,int kspc,int con,struct fb_info * info)2522 static int radeonfb_get_cmap (struct fb_cmap *cmap, int kspc, int con,
2523                               struct fb_info *info)
2524 {
2525         struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
2526         struct display *disp;
2527 
2528         disp = (con < 0) ? rinfo->info.disp : &fb_display[con];
2529 
2530         if (con == rinfo->currcon) {
2531                 int rc = fb_get_cmap (cmap, kspc, radeon_getcolreg, info);
2532                 return rc;
2533         } else if (disp->cmap.len)
2534                 fb_copy_cmap (&disp->cmap, cmap, kspc ? 0 : 2);
2535         else
2536                 fb_copy_cmap (fb_default_cmap (radeon_get_cmap_len (&disp->var)),
2537                               cmap, kspc ? 0 : 2);
2538 
2539         return 0;
2540 }
2541 
2542 
2543 
radeonfb_set_cmap(struct fb_cmap * cmap,int kspc,int con,struct fb_info * info)2544 static int radeonfb_set_cmap (struct fb_cmap *cmap, int kspc, int con,
2545                               struct fb_info *info)
2546 {
2547         struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
2548         struct display *disp;
2549         unsigned int cmap_len;
2550 
2551         disp = (con < 0) ? rinfo->info.disp : &fb_display[con];
2552 
2553         cmap_len = radeon_get_cmap_len (&disp->var);
2554         if (disp->cmap.len != cmap_len) {
2555                 int err = fb_alloc_cmap (&disp->cmap, cmap_len, 0);
2556                 if (err)
2557                         return err;
2558         }
2559 
2560         if (con == rinfo->currcon) {
2561                 int rc = fb_set_cmap (cmap, kspc, radeon_setcolreg, info);
2562                 return rc;
2563         } else
2564                 fb_copy_cmap (cmap, &disp->cmap, kspc ? 0 : 1);
2565 
2566         return 0;
2567 }
2568 
2569 
2570 
radeonfb_pan_display(struct fb_var_screeninfo * var,int con,struct fb_info * info)2571 static int radeonfb_pan_display (struct fb_var_screeninfo *var, int con,
2572                                  struct fb_info *info)
2573 {
2574         struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
2575 
2576         if (((var->xoffset + var->xres) > var->xres_virtual)
2577             || ((var->yoffset + var->yres) > var->yres_virtual))
2578                return -EINVAL;
2579 
2580         if (rinfo->asleep)
2581                 return 0;
2582 
2583         OUTREG(CRTC_OFFSET, ((var->yoffset * var->xres_virtual + var->xoffset)
2584                              * var->bits_per_pixel / 8) & ~7);
2585 
2586         return 0;
2587 }
2588 
2589 
radeonfb_ioctl(struct inode * inode,struct file * file,unsigned int cmd,unsigned long arg,int con,struct fb_info * info)2590 static int radeonfb_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
2591                            unsigned long arg, int con, struct fb_info *info)
2592 {
2593         struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
2594 	unsigned int tmp;
2595 	u32 value = 0;
2596 	int rc;
2597 
2598 	switch (cmd) {
2599 		/*
2600 		 * TODO:  set mirror accordingly for non-Mobility chipsets with 2 CRTC's
2601 		 */
2602 		case FBIO_RADEON_SET_MIRROR:
2603 			switch (rinfo->arch) {
2604 				case RADEON_M6:
2605 				case RADEON_M7:
2606 				case RADEON_M9:
2607 					break;
2608 				default:
2609 					return -EINVAL;
2610 			}
2611 
2612 			rc = get_user(value, (__u32*)arg);
2613 
2614 			if (rc)
2615 				return rc;
2616 
2617 			if (value & 0x01) {
2618 				tmp = INREG(LVDS_GEN_CNTL);
2619 
2620 				tmp |= (LVDS_ON | LVDS_BLON);
2621 			} else {
2622 				tmp = INREG(LVDS_GEN_CNTL);
2623 
2624 				tmp &= ~(LVDS_ON | LVDS_BLON);
2625 			}
2626 
2627 			OUTREG(LVDS_GEN_CNTL, tmp);
2628 
2629 			if (value & 0x02) {
2630 				tmp = INREG(CRTC_EXT_CNTL);
2631 				tmp |= CRTC_CRT_ON;
2632 
2633 				mirror = 1;
2634 			} else {
2635 				tmp = INREG(CRTC_EXT_CNTL);
2636 				tmp &= ~CRTC_CRT_ON;
2637 
2638 				mirror = 0;
2639 			}
2640 
2641 			OUTREG(CRTC_EXT_CNTL, tmp);
2642 
2643 			return 0;
2644 
2645 		case FBIO_RADEON_GET_MIRROR:
2646 			switch (rinfo->arch) {
2647 				case RADEON_M6:
2648 				case RADEON_M7:
2649 				case RADEON_M9:
2650 					break;
2651 				default:
2652 					return -EINVAL;
2653 			}
2654 
2655 			tmp = INREG(LVDS_GEN_CNTL);
2656 			if ((LVDS_ON | LVDS_BLON) & tmp)
2657 				value |= 0x01;
2658 
2659 			tmp = INREG(CRTC_EXT_CNTL);
2660 			if (CRTC_CRT_ON & tmp)
2661 				value |= 0x02;
2662 
2663 			return put_user(value, (__u32*)arg);
2664 	}
2665 
2666 	return -EINVAL;
2667 }
2668 
2669 
radeonfb_switch(int con,struct fb_info * info)2670 static int radeonfb_switch (int con, struct fb_info *info)
2671 {
2672         struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
2673         struct display *disp, *old_disp;
2674         struct fb_cmap *cmap;
2675         int switchmode = 0;
2676 
2677         disp = (con < 0) ? rinfo->info.disp : &fb_display[con];
2678         old_disp = rinfo->currcon_display;
2679 
2680         if (rinfo->currcon >= 0) {
2681                 cmap = &(rinfo->currcon_display->cmap);
2682                 if (cmap->len)
2683                         fb_get_cmap (cmap, 1, radeon_getcolreg, info);
2684         }
2685 
2686         if ((old_disp == NULL) || ((disp->var.xres != old_disp->var.xres) ||
2687             (disp->var.yres != old_disp->var.yres) ||
2688             (disp->var.xres_virtual != old_disp->var.xres_virtual) ||
2689             (disp->var.yres_virtual != old_disp->var.yres_virtual) ||
2690             (disp->var.bits_per_pixel != old_disp->var.bits_per_pixel) ||
2691             memcmp (&disp->var.red, &old_disp->var.red, sizeof (old_disp->var.red)) ||
2692             memcmp (&disp->var.green, &old_disp->var.green, sizeof (old_disp->var.green)) ||
2693             memcmp (&disp->var.blue, &old_disp->var.blue, sizeof (old_disp->var.blue)) ||
2694             old_disp->var.accel_flags != disp->var.accel_flags))
2695         	switchmode = 1;
2696 
2697 	if (rinfo->currcon == -1)
2698 		switchmode = 1;
2699 
2700 try_again:
2701 	rinfo->currcon = con;
2702 	rinfo->currcon_display = disp;
2703 	disp->var.activate = FB_ACTIVATE_NOW;
2704 
2705         if (switchmode) {
2706                 radeonfb_set_var (&disp->var, con, info);
2707                 do_install_cmap(con, info);
2708         } else {
2709 		if (radeon_engine_init(rinfo) < 0) {
2710                         disp->var.accel_flags &= ~FB_ACCELF_TEXT;
2711                         switchmode = 1;
2712 			goto try_again;
2713 		}
2714         }
2715 
2716         radeon_set_dispsw (rinfo, disp);
2717 
2718         return 0;
2719 }
2720 
2721 
radeonfb_updatevar(int con,struct fb_info * info)2722 static int radeonfb_updatevar (int con, struct fb_info *info)
2723 {
2724         int rc;
2725 
2726         rc = (con < 0) ? -EINVAL : radeonfb_pan_display (&fb_display[con].var,
2727                                                          con, info);
2728 
2729         return rc;
2730 }
2731 
radeonfb_blank(int blank,struct fb_info * info)2732 static void radeonfb_blank (int blank, struct fb_info *info)
2733 {
2734         struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
2735         u32 val = INREG(CRTC_EXT_CNTL);
2736 	u32 val_lvds = INREG(LVDS_GEN_CNTL);
2737 	u32 val_dfp = INREG(FP_GEN_CNTL);
2738 
2739 	if (rinfo->asleep)
2740 		return;
2741 
2742 #ifdef CONFIG_PMAC_BACKLIGHT
2743 	if (rinfo->dviDisp_type == MT_LCD && _machine == _MACH_Pmac) {
2744 		set_backlight_enable(!blank);
2745 		return;
2746 	}
2747 #endif
2748 
2749         /* reset it */
2750         val &= ~(CRTC_DISPLAY_DIS | CRTC_HSYNC_DIS |
2751                  CRTC_VSYNC_DIS);
2752 	val_lvds &= ~(LVDS_DISPLAY_DIS);
2753 	val_dfp |= FP_FPON | FP_TMDS_EN;
2754 
2755         switch (blank) {
2756                 case VESA_NO_BLANKING:
2757                         break;
2758                 case VESA_VSYNC_SUSPEND:
2759                         val |= (CRTC_DISPLAY_DIS | CRTC_VSYNC_DIS);
2760                         break;
2761                 case VESA_HSYNC_SUSPEND:
2762                         val |= (CRTC_DISPLAY_DIS | CRTC_HSYNC_DIS);
2763                         break;
2764                 case VESA_POWERDOWN:
2765                         val |= (CRTC_DISPLAY_DIS | CRTC_VSYNC_DIS |
2766                                 CRTC_HSYNC_DIS);
2767 			val_lvds |= (LVDS_DISPLAY_DIS);
2768 			val_dfp &= ~(FP_FPON | FP_TMDS_EN);
2769                         break;
2770         }
2771 
2772 	switch (rinfo->dviDisp_type) {
2773 		case MT_LCD:
2774 			OUTREG(LVDS_GEN_CNTL, val_lvds);
2775 			break;
2776 		case MT_DFP:
2777 			OUTREG(FP_GEN_CNTL, val_dfp);
2778 			break;
2779 		case MT_CRT:
2780 		default:
2781 		        OUTREG(CRTC_EXT_CNTL, val);
2782 			break;
2783 	}
2784 }
2785 
2786 
radeon_get_cmap_len(const struct fb_var_screeninfo * var)2787 static int radeon_get_cmap_len (const struct fb_var_screeninfo *var)
2788 {
2789         int rc = 256;            /* reasonable default */
2790 
2791         switch (var_to_depth(var)) {
2792                 case 15:
2793                         rc = 32;
2794                         break;
2795 		case 16:
2796 			rc = 64;
2797 			break;
2798         }
2799 
2800         return rc;
2801 }
2802 
2803 
radeon_getcolreg(unsigned regno,unsigned * red,unsigned * green,unsigned * blue,unsigned * transp,struct fb_info * info)2804 static int radeon_getcolreg (unsigned regno, unsigned *red, unsigned *green,
2805                              unsigned *blue, unsigned *transp,
2806                              struct fb_info *info)
2807 {
2808         struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
2809 
2810 	if (regno > 255)
2811 		return 1;
2812 
2813  	*red = (rinfo->palette[regno].red<<8) | rinfo->palette[regno].red;
2814     	*green = (rinfo->palette[regno].green<<8) | rinfo->palette[regno].green;
2815     	*blue = (rinfo->palette[regno].blue<<8) | rinfo->palette[regno].blue;
2816     	*transp = 0;
2817 
2818 	return 0;
2819 }
2820 
2821 
2822 
radeon_setcolreg(unsigned regno,unsigned red,unsigned green,unsigned blue,unsigned transp,struct fb_info * info)2823 static int radeon_setcolreg (unsigned regno, unsigned red, unsigned green,
2824                              unsigned blue, unsigned transp, struct fb_info *info)
2825 {
2826         struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
2827 	u32 pindex;
2828 
2829 	if (regno > 255)
2830 		return 1;
2831 
2832 	red >>= 8;
2833 	green >>= 8;
2834 	blue >>= 8;
2835 	rinfo->palette[regno].red = red;
2836 	rinfo->palette[regno].green = green;
2837 	rinfo->palette[regno].blue = blue;
2838 
2839         /* default */
2840         pindex = regno;
2841 
2842         if (!rinfo->asleep) {
2843         	u32 dac_cntl2, vclk_cntl;
2844 
2845 		vclk_cntl = INPLL(VCLK_ECP_CNTL);
2846 		OUTPLL(VCLK_ECP_CNTL, vclk_cntl & ~PIXCLK_DAC_ALWAYS_ONb);
2847 
2848 		/* Make sure we are on first palette */
2849 		if (rinfo->hasCRTC2) {
2850 			dac_cntl2 = INREG(DAC_CNTL2);
2851 			dac_cntl2 &= ~DAC2_PALETTE_ACCESS_CNTL;
2852 			OUTREG(DAC_CNTL2, dac_cntl2);
2853 		}
2854 
2855 		if (rinfo->bpp == 16) {
2856 			pindex = regno * 8;
2857 
2858 			if (rinfo->depth == 16 && regno > 63)
2859 				return 1;
2860 			if (rinfo->depth == 15 && regno > 31)
2861 				return 1;
2862 
2863 			/* For 565, the green component is mixed one order below */
2864 			if (rinfo->depth == 16) {
2865 		                OUTREG8(PALETTE_INDEX, pindex>>1);
2866 	       	         	OUTREG(PALETTE_DATA, (rinfo->palette[regno>>1].red << 16) |
2867 	                        	(green << 8) | (rinfo->palette[regno>>1].blue));
2868 	                	green = rinfo->palette[regno<<1].green;
2869 	        	}
2870 		}
2871 
2872 		if (rinfo->depth != 16 || regno < 32) {
2873 			OUTREG8(PALETTE_INDEX, pindex);
2874 			OUTREG(PALETTE_DATA, (red << 16) | (green << 8) | blue);
2875 		}
2876 
2877 		OUTPLL(VCLK_ECP_CNTL, vclk_cntl);
2878 	}
2879  	if (regno < 16) {
2880         	switch (rinfo->depth) {
2881 #ifdef FBCON_HAS_CFB16
2882 		        case 15:
2883         			rinfo->con_cmap.cfb16[regno] = (regno << 10) | (regno << 5) |
2884 				                       	 	  regno;
2885 			        break;
2886 		        case 16:
2887         			rinfo->con_cmap.cfb16[regno] = (regno << 11) | (regno << 5) |
2888 				                       	 	  regno;
2889 			        break;
2890 #endif
2891 #ifdef FBCON_HAS_CFB24
2892                         case 24:
2893                                 rinfo->con_cmap.cfb24[regno] = (regno << 16) | (regno << 8) | regno;
2894                                 break;
2895 #endif
2896 #ifdef FBCON_HAS_CFB32
2897 	        	case 32: {
2898             			u32 i;
2899 
2900   		       		i = (regno << 8) | regno;
2901             			rinfo->con_cmap.cfb32[regno] = (i << 16) | i;
2902 		        	break;
2903         		}
2904 #endif
2905                 }
2906         }
2907         return 0;
2908 
2909 }
2910 
2911 
radeon_save_state(struct radeonfb_info * rinfo,struct radeon_regs * save)2912 static void radeon_save_state (struct radeonfb_info *rinfo,
2913                                struct radeon_regs *save)
2914 {
2915 	/* CRTC regs */
2916 	save->crtc_gen_cntl = INREG(CRTC_GEN_CNTL);
2917 	save->crtc_ext_cntl = INREG(CRTC_EXT_CNTL);
2918 	save->crtc_more_cntl = INREG(CRTC_MORE_CNTL);
2919 	save->dac_cntl = INREG(DAC_CNTL);
2920         save->crtc_h_total_disp = INREG(CRTC_H_TOTAL_DISP);
2921         save->crtc_h_sync_strt_wid = INREG(CRTC_H_SYNC_STRT_WID);
2922         save->crtc_v_total_disp = INREG(CRTC_V_TOTAL_DISP);
2923         save->crtc_v_sync_strt_wid = INREG(CRTC_V_SYNC_STRT_WID);
2924 	save->crtc_pitch = INREG(CRTC_PITCH);
2925 #if defined(__BIG_ENDIAN)
2926 	save->surface_cntl = INREG(SURFACE_CNTL);
2927 #endif
2928 
2929 	/* FP regs */
2930 	save->fp_crtc_h_total_disp = INREG(FP_CRTC_H_TOTAL_DISP);
2931 	save->fp_crtc_v_total_disp = INREG(FP_CRTC_V_TOTAL_DISP);
2932 	save->fp_gen_cntl = INREG(FP_GEN_CNTL);
2933 	save->fp_h_sync_strt_wid = INREG(FP_H_SYNC_STRT_WID);
2934 	save->fp_horz_stretch = INREG(FP_HORZ_STRETCH);
2935 	save->fp_v_sync_strt_wid = INREG(FP_V_SYNC_STRT_WID);
2936 	save->fp_vert_stretch = INREG(FP_VERT_STRETCH);
2937 	save->lvds_gen_cntl = INREG(LVDS_GEN_CNTL);
2938 	save->lvds_pll_cntl = INREG(LVDS_PLL_CNTL);
2939 	save->tmds_crc = INREG(TMDS_CRC);
2940 	save->tmds_transmitter_cntl = INREG(TMDS_TRANSMITTER_CNTL);
2941 	save->vclk_ecp_cntl = INPLL(VCLK_ECP_CNTL);
2942 }
2943 
2944 
radeon_calc_pll_regs(struct radeonfb_info * rinfo,struct radeon_regs * regs,unsigned long freq)2945 static void radeon_calc_pll_regs(struct radeonfb_info *rinfo, struct radeon_regs *regs, unsigned long freq)
2946 {
2947 	const struct {
2948 		int divider;
2949 		int bitvalue;
2950 	} *post_div,
2951 	  post_divs[] = {
2952 		{ 1,  0 },
2953 		{ 2,  1 },
2954 		{ 4,  2 },
2955 		{ 8,  3 },
2956 		{ 3,  4 },
2957 		{ 16, 5 },
2958 		{ 6,  6 },
2959 		{ 12, 7 },
2960 		{ 0,  0 },
2961 	};
2962 
2963 	if (freq > rinfo->pll.ppll_max)
2964 		freq = rinfo->pll.ppll_max;
2965 	if (freq*12 < rinfo->pll.ppll_min)
2966 		freq = rinfo->pll.ppll_min / 12;
2967 
2968 
2969 	for (post_div = &post_divs[0]; post_div->divider; ++post_div) {
2970 		rinfo->pll_output_freq = post_div->divider * freq;
2971 		if (rinfo->pll_output_freq >= rinfo->pll.ppll_min  &&
2972 		    rinfo->pll_output_freq <= rinfo->pll.ppll_max)
2973 			break;
2974 	}
2975 
2976 	/* Why do we have those in rinfo at this point ? --BenH */
2977 	rinfo->post_div = post_div->divider;
2978 	rinfo->fb_div = round_div(rinfo->pll.ref_div*rinfo->pll_output_freq,
2979 				  rinfo->pll.ref_clk);
2980 	regs->ppll_ref_div = rinfo->pll.ref_div;
2981 	regs->ppll_div_3 = rinfo->fb_div | (post_div->bitvalue << 16);
2982 
2983 #ifdef CONFIG_ALL_PPC
2984 	/* Gross hack for iBook with M7 until I find out a proper fix */
2985 	if (machine_is_compatible("PowerBook4,3") && rinfo->arch == RADEON_M7)
2986 		regs->ppll_div_3 = 0x000600ad;
2987 #endif /* CONFIG_ALL_PPC */
2988 
2989 	RTRACE("post div = 0x%x\n", rinfo->post_div);
2990 	RTRACE("fb_div = 0x%x\n", rinfo->fb_div);
2991 	RTRACE("ppll_div_3 = 0x%x\n", regs->ppll_div_3);
2992 }
2993 
radeon_load_video_mode(struct radeonfb_info * rinfo,struct fb_var_screeninfo * mode)2994 static void radeon_load_video_mode (struct radeonfb_info *rinfo,
2995                                     struct fb_var_screeninfo *mode)
2996 {
2997 	struct radeon_regs newmode;
2998 	int hTotal, vTotal, hSyncStart, hSyncEnd,
2999 	    hSyncPol, vSyncStart, vSyncEnd, vSyncPol, cSync;
3000 	u8 hsync_adj_tab[] = {0, 0x12, 9, 9, 6, 5};
3001 	u8 hsync_fudge_fp[] = {2, 2, 0, 0, 5, 5};
3002 	u32 sync, h_sync_pol, v_sync_pol, dotClock, pixClock;
3003 	unsigned int freq;
3004 #if 0
3005         unsigned int xclk_freq, vclk_freq;
3006         int xclk_per_trans, xclk_per_trans_precise;
3007         int useable_precision, roff, ron;
3008         int min_bits;
3009 #endif
3010 	int format = 0;
3011 	int hsync_start, hsync_fudge, bytpp, hsync_wid, vsync_wid;
3012 	int primary_mon = PRIMARY_MONITOR(rinfo);
3013 	int depth = var_to_depth(mode);
3014         int accel = mode->accel_flags & FB_ACCELF_TEXT;
3015 
3016 	rinfo->xres = mode->xres;
3017 	rinfo->yres = mode->yres;
3018 	rinfo->xres_virtual = mode->xres_virtual;
3019 	rinfo->yres_virtual = mode->yres_virtual;
3020 	rinfo->pixclock = mode->pixclock;
3021 
3022 	hSyncStart = mode->xres + mode->right_margin;
3023 	hSyncEnd = hSyncStart + mode->hsync_len;
3024 	hTotal = hSyncEnd + mode->left_margin;
3025 
3026 	vSyncStart = mode->yres + mode->lower_margin;
3027 	vSyncEnd = vSyncStart + mode->vsync_len;
3028 	vTotal = vSyncEnd + mode->upper_margin;
3029 	pixClock = mode->pixclock;
3030 
3031 	if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) {
3032                 /* Force the native video mode of the LCD monitor.
3033                  * This is complicated, because when the hardware
3034                  * stretcher is used, the extra pixels are not counted
3035                  * in the horizontal timing parameters. So:
3036                  *   - For the visible part of the display, we use the
3037                  *     requested paramters.
3038                  *   - For the invisible part of the display, we use the
3039                  *     parameters of the native video mode.
3040                  */
3041 		if (rinfo->panel_xres < mode->xres)
3042 			rinfo->xres = mode->xres = rinfo->panel_xres;
3043 		if (rinfo->panel_yres < mode->yres)
3044 			rinfo->yres = mode->yres = rinfo->panel_yres;
3045 
3046 		hTotal = mode->xres + rinfo->hblank;
3047 		hSyncStart = mode->xres + rinfo->hOver_plus;
3048 		hSyncEnd = hSyncStart + rinfo->hSync_width;
3049 
3050 		vTotal = mode->yres + rinfo->vblank;
3051 		vSyncStart = mode->yres + rinfo->vOver_plus;
3052 		vSyncEnd = vSyncStart + rinfo->vSync_width;
3053 
3054 		/* If we know the LCD clock, we shall use it, unfortunately,
3055 		 * we may not know it until we have proper EDID probing
3056 		 */
3057 		if (rinfo->clock)
3058 			pixClock = 100000000 / rinfo->clock;
3059 	}
3060 	dotClock = 1000000000 / pixClock;
3061 	freq = dotClock / 10; /* x100 */
3062 
3063 	sync = mode->sync;
3064 	h_sync_pol = sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1;
3065 	v_sync_pol = sync & FB_SYNC_VERT_HIGH_ACT ? 0 : 1;
3066 
3067 	RTRACE("hStart = %d, hEnd = %d, hTotal = %d\n",
3068 		hSyncStart, hSyncEnd, hTotal);
3069 	RTRACE("vStart = %d, vEnd = %d, vTotal = %d\n",
3070 		vSyncStart, vSyncEnd, vTotal);
3071 
3072 	hsync_wid = (hSyncEnd - hSyncStart) / 8;
3073 	vsync_wid = vSyncEnd - vSyncStart;
3074 	if (hsync_wid == 0)
3075 		hsync_wid = 1;
3076 	else if (hsync_wid > 0x3f)	/* max */
3077 		hsync_wid = 0x3f;
3078 
3079 	if (vsync_wid == 0)
3080 		vsync_wid = 1;
3081 	else if (vsync_wid > 0x1f)	/* max */
3082 		vsync_wid = 0x1f;
3083 
3084 	hSyncPol = mode->sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1;
3085 	vSyncPol = mode->sync & FB_SYNC_VERT_HIGH_ACT ? 0 : 1;
3086 
3087 	cSync = mode->sync & FB_SYNC_COMP_HIGH_ACT ? (1 << 4) : 0;
3088 
3089 	format = radeon_get_dstbpp(depth);
3090 	bytpp = mode->bits_per_pixel >> 3;
3091 
3092 	if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD))
3093 		hsync_fudge = hsync_fudge_fp[format-1];
3094 	else
3095 		hsync_fudge = hsync_adj_tab[format-1];
3096 
3097 	hsync_start = hSyncStart - 8 + hsync_fudge;
3098 
3099 	newmode.crtc_gen_cntl = CRTC_EXT_DISP_EN | CRTC_EN |
3100 				(format << 8);
3101 
3102 	/* Clear auto-center etc... Maybe we can actually use these
3103 	 * later, when I implement a scaling mode that keep
3104 	 * aspect ratio
3105 	 */
3106 	newmode.crtc_more_cntl = rinfo->init_state.crtc_more_cntl;
3107 	newmode.crtc_more_cntl &= 0xfffffff0;
3108 
3109 	if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) {
3110 		newmode.crtc_ext_cntl = VGA_ATI_LINEAR | XCRT_CNT_EN;
3111 		if (mirror)
3112 			newmode.crtc_ext_cntl |= CRTC_CRT_ON;
3113 
3114 		newmode.crtc_gen_cntl &= ~(CRTC_DBL_SCAN_EN |
3115 					   CRTC_INTERLACE_EN);
3116 	} else {
3117 		newmode.crtc_ext_cntl = VGA_ATI_LINEAR | XCRT_CNT_EN |
3118 					CRTC_CRT_ON;
3119 	}
3120 
3121 	newmode.dac_cntl = /* INREG(DAC_CNTL) | */ DAC_MASK_ALL | DAC_VGA_ADR_EN |
3122 			   DAC_8BIT_EN;
3123 
3124 	newmode.crtc_h_total_disp = ((((hTotal / 8) - 1) & 0x3ff) |
3125 				     (((mode->xres / 8) - 1) << 16));
3126 
3127 	newmode.crtc_h_sync_strt_wid = ((hsync_start & 0x1fff) |
3128 					(hsync_wid << 16) | (h_sync_pol << 23));
3129 
3130 	newmode.crtc_v_total_disp = ((vTotal - 1) & 0xffff) |
3131 				    ((mode->yres - 1) << 16);
3132 
3133 	newmode.crtc_v_sync_strt_wid = (((vSyncStart - 1) & 0xfff) |
3134 					 (vsync_wid << 16) | (v_sync_pol  << 23));
3135 
3136 	/* We first calculate the engine pitch (we always calculate it as this value may
3137 	 * be used elsewhere, like when setting us the btext engine
3138 	 */
3139 	rinfo->pitch = ((mode->xres_virtual * ((mode->bits_per_pixel + 1) / 8) + 0x3f)
3140  				& ~(0x3f)) >> 6;
3141 	if (accel)
3142 		/* Then, re-multiply it to get the CRTC pitch */
3143 		newmode.crtc_pitch = (rinfo->pitch << 3) / ((mode->bits_per_pixel + 1) / 8);
3144 	else
3145 		newmode.crtc_pitch = (mode->xres_virtual >> 3);
3146 
3147 	newmode.crtc_pitch |= (newmode.crtc_pitch << 16);
3148 
3149 	/*
3150 	 * It looks like recent chips have a problem with SURFACE_CNTL,
3151 	 * setting SURF_TRANSLATION_DIS completely disables the
3152 	 * swapper as well, so we leave it unset now.
3153 	 */
3154 	newmode.surface_cntl = 0;
3155 
3156 #if defined(__BIG_ENDIAN)
3157 	/* Setup swapping on both apertures, though we currently
3158 	 * only use aperture 0, enabling swapper on aperture 1
3159 	 * won't harm
3160 	 */
3161 	switch (mode->bits_per_pixel) {
3162 		case 16:
3163 			newmode.surface_cntl |= NONSURF_AP0_SWP_16BPP;
3164 			newmode.surface_cntl |= NONSURF_AP1_SWP_16BPP;
3165 			break;
3166 		case 24:
3167 		case 32:
3168 			newmode.surface_cntl |= NONSURF_AP0_SWP_32BPP;
3169 			newmode.surface_cntl |= NONSURF_AP1_SWP_32BPP;
3170 			break;
3171 	}
3172 #endif
3173 
3174 	RTRACE("h_total_disp = 0x%x\t   hsync_strt_wid = 0x%x\n",
3175 		newmode.crtc_h_total_disp, newmode.crtc_h_sync_strt_wid);
3176 	RTRACE("v_total_disp = 0x%x\t   vsync_strt_wid = 0x%x\n",
3177 		newmode.crtc_v_total_disp, newmode.crtc_v_sync_strt_wid);
3178 
3179 	newmode.xres = mode->xres;
3180 	newmode.yres = mode->yres;
3181 
3182 	rinfo->bpp = mode->bits_per_pixel;
3183 	rinfo->depth = depth;
3184 
3185 	RTRACE("pixclock = %lu\n", (unsigned long)pixClock);
3186 	RTRACE("freq = %lu\n", (unsigned long)freq);
3187 	radeon_calc_pll_regs(rinfo, &newmode, freq);
3188 
3189 	newmode.vclk_ecp_cntl = rinfo->init_state.vclk_ecp_cntl;
3190 
3191 #if 0
3192 	/* DDA */
3193 	/* XXX: Figure out if there is really a DDA on radeons ! I think there
3194 	 * isn't actually...
3195 	 */
3196 	vclk_freq = round_div(rinfo->pll.ref_clk * rinfo->fb_div,
3197 			      rinfo->pll.ref_div * rinfo->post_div);
3198 	xclk_freq = rinfo->pll.xclk;
3199 
3200 	xclk_per_trans = round_div(xclk_freq * 128, vclk_freq * mode->bits_per_pixel);
3201 
3202 	min_bits = min_bits_req(xclk_per_trans);
3203 	useable_precision = min_bits + 1;
3204 
3205 	xclk_per_trans_precise = round_div((xclk_freq * 128) << (11 - useable_precision),
3206 					   vclk_freq * mode->bits_per_pixel);
3207 
3208 	ron = (4 * rinfo->ram.mb + 3 * _max(rinfo->ram.trcd - 2, 0) +
3209 	       2 * rinfo->ram.trp + rinfo->ram.twr + rinfo->ram.cl + rinfo->ram.tr2w +
3210 	       xclk_per_trans) << (11 - useable_precision);
3211 	roff = xclk_per_trans_precise * (32 - 4);
3212 
3213 	RTRACE("ron = %d, roff = %d\n", ron, roff);
3214 	RTRACE("vclk_freq = %d, per = %d\n", vclk_freq, xclk_per_trans_precise);
3215 
3216 	if ((ron + rinfo->ram.rloop) >= roff) {
3217 		printk("radeonfb: error ron out of range\n");
3218 		return;
3219 	}
3220 
3221 	newmode.dda_config = (xclk_per_trans_precise |
3222 			      (useable_precision << 16) |
3223 			      (rinfo->ram.rloop << 20));
3224 	newmode.dda_on_off = (ron << 16) | roff;
3225 #endif
3226 
3227 	if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) {
3228 		unsigned int hRatio, vRatio;
3229 
3230 		if (mode->xres > rinfo->panel_xres)
3231 			mode->xres = rinfo->panel_xres;
3232 		if (mode->yres > rinfo->panel_yres)
3233 			mode->yres = rinfo->panel_yres;
3234 
3235 		newmode.fp_horz_stretch = (((rinfo->panel_xres / 8) - 1)
3236 					   << HORZ_PANEL_SHIFT);
3237 		newmode.fp_vert_stretch = ((rinfo->panel_yres - 1)
3238 					   << VERT_PANEL_SHIFT);
3239 
3240 		if (mode->xres != rinfo->panel_xres) {
3241 			hRatio = round_div(mode->xres * HORZ_STRETCH_RATIO_MAX,
3242 					   rinfo->panel_xres);
3243 			newmode.fp_horz_stretch = (((((unsigned long)hRatio) & HORZ_STRETCH_RATIO_MASK)) |
3244 						   (newmode.fp_horz_stretch &
3245 						    (HORZ_PANEL_SIZE | HORZ_FP_LOOP_STRETCH |
3246 						     HORZ_AUTO_RATIO_INC)));
3247 			newmode.fp_horz_stretch |= (HORZ_STRETCH_BLEND |
3248 						    HORZ_STRETCH_ENABLE);
3249 		}
3250 		newmode.fp_horz_stretch &= ~HORZ_AUTO_RATIO;
3251 
3252 		if (mode->yres != rinfo->panel_yres) {
3253 			vRatio = round_div(mode->yres * VERT_STRETCH_RATIO_MAX,
3254 					   rinfo->panel_yres);
3255 			newmode.fp_vert_stretch = (((((unsigned long)vRatio) & VERT_STRETCH_RATIO_MASK)) |
3256 						   (newmode.fp_vert_stretch &
3257 						   (VERT_PANEL_SIZE | VERT_STRETCH_RESERVED)));
3258 			newmode.fp_vert_stretch |= (VERT_STRETCH_BLEND |
3259 						    VERT_STRETCH_ENABLE);
3260 		}
3261 		newmode.fp_vert_stretch &= ~VERT_AUTO_RATIO_EN;
3262 
3263 		newmode.fp_gen_cntl = (rinfo->init_state.fp_gen_cntl & (u32)
3264 				       ~(FP_SEL_CRTC2 |
3265 					 FP_RMX_HVSYNC_CONTROL_EN |
3266 					 FP_DFP_SYNC_SEL |
3267 					 FP_CRT_SYNC_SEL |
3268 					 FP_CRTC_LOCK_8DOT |
3269 					 FP_USE_SHADOW_EN |
3270 					 FP_CRTC_USE_SHADOW_VEND |
3271 					 FP_CRT_SYNC_ALT));
3272 
3273 		newmode.fp_gen_cntl |= (FP_CRTC_DONT_SHADOW_VPAR |
3274 					FP_CRTC_DONT_SHADOW_HEND);
3275 
3276 		newmode.lvds_gen_cntl = rinfo->init_state.lvds_gen_cntl;
3277 		newmode.lvds_pll_cntl = rinfo->init_state.lvds_pll_cntl;
3278 		newmode.tmds_crc = rinfo->init_state.tmds_crc;
3279 		newmode.tmds_transmitter_cntl = rinfo->init_state.tmds_transmitter_cntl;
3280 
3281 		if (primary_mon == MT_LCD) {
3282 			newmode.lvds_gen_cntl |= (LVDS_ON | LVDS_BLON);
3283 			newmode.fp_gen_cntl &= ~(FP_FPON | FP_TMDS_EN);
3284 		} else {
3285 			/* DFP */
3286 			newmode.fp_gen_cntl |= (FP_FPON | FP_TMDS_EN);
3287 			newmode.tmds_transmitter_cntl = (TMDS_RAN_PAT_RST | TMDS_ICHCSEL) &
3288 							 ~(TMDS_PLLRST);
3289 			/* TMDS_PLL_EN bit is reversed on RV (and mobility) chips */
3290 			if (rinfo->arch == RADEON_R100 ||
3291 			    rinfo->arch == RADEON_R200 ||
3292 			    rinfo->arch == RADEON_R300 ||
3293 			    rinfo->arch == RADEON_R350)
3294 				newmode.tmds_transmitter_cntl &= ~TMDS_PLL_EN;
3295 			else
3296 				newmode.tmds_transmitter_cntl |= TMDS_PLL_EN;
3297 
3298 			newmode.crtc_ext_cntl &= ~CRTC_CRT_ON;
3299 		}
3300 
3301 		newmode.fp_crtc_h_total_disp = (((rinfo->hblank / 8) & 0x3ff) |
3302 				(((mode->xres / 8) - 1) << 16));
3303 		newmode.fp_crtc_v_total_disp = (rinfo->vblank & 0xffff) |
3304 				((mode->yres - 1) << 16);
3305 		newmode.fp_h_sync_strt_wid = ((rinfo->hOver_plus & 0x1fff) |
3306 				(hsync_wid << 16) | (h_sync_pol << 23));
3307 		newmode.fp_v_sync_strt_wid = ((rinfo->vOver_plus & 0xfff) |
3308 				(vsync_wid << 16) | (v_sync_pol  << 23));
3309 	}
3310 
3311 	/* do it! */
3312 	if (!rinfo->asleep)
3313 		radeon_write_mode (rinfo, &newmode);
3314 
3315 #if defined(CONFIG_BOOTX_TEXT)
3316 	btext_update_display(rinfo->fb_base_phys, mode->xres, mode->yres,
3317 			     rinfo->depth, rinfo->pitch*64);
3318 #endif
3319 
3320 	return;
3321 }
3322 
3323 
radeon_write_pll_regs(struct radeonfb_info * rinfo,struct radeon_regs * mode)3324 static void radeon_write_pll_regs(struct radeonfb_info *rinfo, struct radeon_regs *mode)
3325 {
3326 	/* Workaround from XFree */
3327 	if (rinfo->arch < RADEON_R300) {
3328 	        /* A temporal workaround for the occational blanking on certain laptop panels.
3329 	           This appears to related to the PLL divider registers (fail to lock?).
3330 		   It occurs even when all dividers are the same with their old settings.
3331 	           In this case we really don't need to fiddle with PLL registers.
3332 	           By doing this we can avoid the blanking problem with some panels.
3333 	        */
3334 		if ((mode->ppll_ref_div == (INPLL(PPLL_REF_DIV) & PPLL_REF_DIV_MASK)) &&
3335 		    (mode->ppll_div_3 == (INPLL(PPLL_DIV_3) &
3336 		    		(PPLL_POST3_DIV_MASK | PPLL_FB3_DIV_MASK))))
3337             		return;
3338 	}
3339 
3340 	while ((INREG(CLOCK_CNTL_INDEX) & PPLL_DIV_SEL_MASK) !=
3341 	       PPLL_DIV_SEL_MASK) {
3342 		OUTREGP(CLOCK_CNTL_INDEX, PPLL_DIV_SEL_MASK, 0xffff);
3343 	}
3344 
3345 	OUTPLLP(PPLL_CNTL, PPLL_RESET, 0xffff);
3346 
3347 	while ((INPLL(PPLL_REF_DIV) & PPLL_REF_DIV_MASK) !=
3348 	       (mode->ppll_ref_div & PPLL_REF_DIV_MASK)) {
3349 		OUTPLLP(PPLL_REF_DIV, mode->ppll_ref_div, ~PPLL_REF_DIV_MASK);
3350 	}
3351 
3352 	while ((INPLL(PPLL_DIV_3) & PPLL_FB3_DIV_MASK) !=
3353 	       (mode->ppll_div_3 & PPLL_FB3_DIV_MASK)) {
3354 		OUTPLLP(PPLL_DIV_3, mode->ppll_div_3, ~PPLL_FB3_DIV_MASK);
3355 	}
3356 
3357 	while ((INPLL(PPLL_DIV_3) & PPLL_POST3_DIV_MASK) !=
3358 	       (mode->ppll_div_3 & PPLL_POST3_DIV_MASK)) {
3359 		OUTPLLP(PPLL_DIV_3, mode->ppll_div_3, ~PPLL_POST3_DIV_MASK);
3360 	}
3361 
3362 	OUTPLL(HTOTAL_CNTL, 0);
3363 
3364 	OUTPLLP(PPLL_CNTL, 0, ~PPLL_RESET);
3365 }
3366 
radeon_write_mode(struct radeonfb_info * rinfo,struct radeon_regs * mode)3367 static void radeon_write_mode (struct radeonfb_info *rinfo,
3368                                struct radeon_regs *mode)
3369 {
3370 	int i;
3371 	int primary_mon = PRIMARY_MONITOR(rinfo);
3372 
3373 	radeonfb_blank(VESA_POWERDOWN, (struct fb_info *)rinfo);
3374 
3375         if (rinfo->arch == RADEON_M6) {
3376 		for (i=0; i<8; i++)
3377 			OUTREG(common_regs_m6[i].reg, common_regs_m6[i].val);
3378 	} else {
3379 		for (i=0; i<9; i++)
3380 			OUTREG(common_regs[i].reg, common_regs[i].val);
3381 	}
3382 
3383 	OUTREG(CRTC_GEN_CNTL, mode->crtc_gen_cntl);
3384 	OUTREGP(CRTC_EXT_CNTL, mode->crtc_ext_cntl,
3385 		CRTC_HSYNC_DIS | CRTC_VSYNC_DIS | CRTC_DISPLAY_DIS);
3386 	OUTREG(CRTC_MORE_CNTL, mode->crtc_more_cntl);
3387 	OUTREGP(DAC_CNTL, mode->dac_cntl, DAC_RANGE_CNTL | DAC_BLANKING);
3388 	OUTREG(CRTC_H_TOTAL_DISP, mode->crtc_h_total_disp);
3389 	OUTREG(CRTC_H_SYNC_STRT_WID, mode->crtc_h_sync_strt_wid);
3390 	OUTREG(CRTC_V_TOTAL_DISP, mode->crtc_v_total_disp);
3391 	OUTREG(CRTC_V_SYNC_STRT_WID, mode->crtc_v_sync_strt_wid);
3392 	OUTREG(CRTC_OFFSET, 0);
3393 	OUTREG(CRTC_OFFSET_CNTL, 0);
3394 	OUTREG(CRTC_PITCH, mode->crtc_pitch);
3395 	OUTREG(SURFACE_CNTL, mode->surface_cntl);
3396 
3397 	radeon_write_pll_regs(rinfo, mode);
3398 
3399 #if 0
3400 	/* Those don't seem to actually exist in radeon's, despite some drivers still
3401 	 * apparently trying to fill them, including some ATI sample codes ...
3402 	 * Can someone confirm what's up ? --BenH.
3403 	 */
3404 	OUTREG(DDA_CONFIG, mode->dda_config);
3405 	OUTREG(DDA_ON_OFF, mode->dda_on_off);
3406 #endif
3407 
3408 	if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) {
3409 		OUTREG(FP_CRTC_H_TOTAL_DISP, mode->fp_crtc_h_total_disp);
3410 		OUTREG(FP_CRTC_V_TOTAL_DISP, mode->fp_crtc_v_total_disp);
3411 		OUTREG(FP_H_SYNC_STRT_WID, mode->fp_h_sync_strt_wid);
3412 		OUTREG(FP_V_SYNC_STRT_WID, mode->fp_v_sync_strt_wid);
3413 		OUTREG(FP_HORZ_STRETCH, mode->fp_horz_stretch);
3414 		OUTREG(FP_VERT_STRETCH, mode->fp_vert_stretch);
3415 		OUTREG(FP_GEN_CNTL, mode->fp_gen_cntl);
3416 		OUTREG(TMDS_CRC, mode->tmds_crc);
3417 		OUTREG(TMDS_TRANSMITTER_CNTL, mode->tmds_transmitter_cntl);
3418 
3419 		if (primary_mon == MT_LCD) {
3420 			unsigned int tmp = INREG(LVDS_GEN_CNTL);
3421 
3422 			mode->lvds_gen_cntl &= ~LVDS_STATE_MASK;
3423 			mode->lvds_gen_cntl |= (rinfo->init_state.lvds_gen_cntl & LVDS_STATE_MASK);
3424 
3425 			if ((tmp & (LVDS_ON | LVDS_BLON)) ==
3426 			    (mode->lvds_gen_cntl & (LVDS_ON | LVDS_BLON))) {
3427 				OUTREG(LVDS_GEN_CNTL, mode->lvds_gen_cntl);
3428 			} else {
3429 				if (mode->lvds_gen_cntl & (LVDS_ON | LVDS_BLON)) {
3430 					udelay(1000);
3431 					OUTREG(LVDS_GEN_CNTL, mode->lvds_gen_cntl);
3432 				} else {
3433 					OUTREG(LVDS_GEN_CNTL, mode->lvds_gen_cntl |
3434 					       LVDS_BLON);
3435 					udelay(1000);
3436 					OUTREG(LVDS_GEN_CNTL, mode->lvds_gen_cntl);
3437 				}
3438 			}
3439 		}
3440 	}
3441 
3442 	radeonfb_blank(VESA_NO_BLANKING, (struct fb_info *)rinfo);
3443 
3444 	OUTPLL(VCLK_ECP_CNTL, mode->vclk_ecp_cntl);
3445 
3446 	return;
3447 }
3448 
3449 
3450 #ifdef CONFIG_PMAC_BACKLIGHT
3451 
3452 /* TODO: Dbl check these tables, we don't go up to full ON backlight
3453  * in these, possibly because we noticed MacOS doesn't, but I'd prefer
3454  * having some more official numbers from ATI
3455  */
3456 static int backlight_conv_m6[] = {
3457         0xff, 0xc0, 0xb5, 0xaa, 0x9f, 0x94, 0x89, 0x7e,
3458         0x73, 0x68, 0x5d, 0x52, 0x47, 0x3c, 0x31, 0x24
3459 };
3460 static int backlight_conv_m7[] = {
3461         0x00, 0x3f, 0x4a, 0x55, 0x60, 0x6b, 0x76, 0x81,
3462         0x8c, 0x97, 0xa2, 0xad, 0xb8, 0xc3, 0xce, 0xd9
3463 };
3464 
3465 /* We turn off the LCD completely instead of just dimming the backlight.
3466  * This provides some greater power saving and the display is useless
3467  * without backlight anyway.
3468  */
3469 
3470 
radeon_set_backlight_enable(int on,int level,void * data)3471 static int radeon_set_backlight_enable(int on, int level, void *data)
3472 {
3473 	struct radeonfb_info *rinfo = (struct radeonfb_info *)data;
3474 	unsigned int lvds_gen_cntl = INREG(LVDS_GEN_CNTL);
3475 	int* conv_table;
3476 
3477 	/* Pardon me for that hack... maybe some day we can figure
3478 	 * out in what direction backlight should work on a given
3479 	 * panel ?
3480 	 */
3481 	if ((rinfo->arch == RADEON_M7 || rinfo->arch == RADEON_M9)
3482 		&& !machine_is_compatible("PowerBook4,3"))
3483 		conv_table = backlight_conv_m7;
3484 	else
3485 		conv_table = backlight_conv_m6;
3486 
3487 	lvds_gen_cntl |= (LVDS_BL_MOD_EN | LVDS_BLON);
3488 	if (on && (level > BACKLIGHT_OFF)) {
3489 		lvds_gen_cntl |= LVDS_DIGON;
3490 		if ((lvds_gen_cntl & LVDS_ON) == 0) {
3491 			lvds_gen_cntl &= ~LVDS_BLON;
3492 			OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl);
3493 			(void)INREG(LVDS_GEN_CNTL);
3494 			mdelay(10);
3495 			lvds_gen_cntl |= LVDS_BLON;
3496 			OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl);
3497 		}
3498 		lvds_gen_cntl &= ~LVDS_BL_MOD_LEVEL_MASK;
3499 		lvds_gen_cntl |= (conv_table[level] <<
3500 				  LVDS_BL_MOD_LEVEL_SHIFT);
3501 		lvds_gen_cntl |= (LVDS_ON | LVDS_EN);
3502 		lvds_gen_cntl &= ~LVDS_DISPLAY_DIS;
3503 	} else {
3504 		lvds_gen_cntl &= ~LVDS_BL_MOD_LEVEL_MASK;
3505 		lvds_gen_cntl |= (conv_table[0] <<
3506 				  LVDS_BL_MOD_LEVEL_SHIFT);
3507 		lvds_gen_cntl |= LVDS_DISPLAY_DIS;
3508 		OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl);
3509 		udelay(10);
3510 		lvds_gen_cntl &= ~(LVDS_ON | LVDS_EN | LVDS_BLON | LVDS_DIGON);
3511 	}
3512 
3513 	OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl);
3514 	rinfo->init_state.lvds_gen_cntl &= ~LVDS_STATE_MASK;
3515 	rinfo->init_state.lvds_gen_cntl |= (lvds_gen_cntl & LVDS_STATE_MASK);
3516 
3517 	return 0;
3518 }
3519 
radeon_set_backlight_level(int level,void * data)3520 static int radeon_set_backlight_level(int level, void *data)
3521 {
3522 	return radeon_set_backlight_enable(1, level, data);
3523 }
3524 #endif /* CONFIG_PMAC_BACKLIGHT */
3525 
3526 
3527 #ifdef CONFIG_PMAC_PBOOK
3528 
3529 /*
3530  * Radeon M6, M7 and M9 Power Management code. This code currently
3531  * only supports the mobile chips in D2 mode, that is typically what
3532  * is used on Apple laptops, it's based from some informations provided by ATI
3533  * along with hours of tracing of MacOS drivers.
3534  *
3535  * New version of this code almost totally rewritten by ATI, many thanks
3536  * for their support.
3537  */
3538 
OUTMC(struct radeonfb_info * rinfo,u8 indx,u32 value)3539 static void OUTMC( struct radeonfb_info *rinfo, u8 indx, u32 value)
3540 {
3541 	OUTREG( MC_IND_INDEX, indx | MC_IND_INDEX__MC_IND_WR_EN);
3542 	OUTREG( MC_IND_DATA, value);
3543 }
3544 
INMC(struct radeonfb_info * rinfo,u8 indx)3545 static u32 INMC(struct radeonfb_info *rinfo, u8 indx)
3546 {
3547 	OUTREG( MC_IND_INDEX, indx);
3548 	return INREG( MC_IND_DATA);
3549 }
3550 
radeon_pm_save_regs(struct radeonfb_info * rinfo)3551 static void radeon_pm_save_regs(struct radeonfb_info *rinfo)
3552 {
3553 	rinfo->save_regs[0] = INPLL(PLL_PWRMGT_CNTL);
3554 	rinfo->save_regs[1] = INPLL(CLK_PWRMGT_CNTL);
3555 	rinfo->save_regs[2] = INPLL(MCLK_CNTL);
3556 	rinfo->save_regs[3] = INPLL(SCLK_CNTL);
3557 	rinfo->save_regs[4] = INPLL(CLK_PIN_CNTL);
3558 	rinfo->save_regs[5] = INPLL(VCLK_ECP_CNTL);
3559 	rinfo->save_regs[6] = INPLL(PIXCLKS_CNTL);
3560 	rinfo->save_regs[7] = INPLL(MCLK_MISC);
3561 	rinfo->save_regs[8] = INPLL(P2PLL_CNTL);
3562 
3563 	rinfo->save_regs[9] = INREG(DISP_MISC_CNTL);
3564 	rinfo->save_regs[10] = INREG(DISP_PWR_MAN);
3565 	rinfo->save_regs[11] = INREG(LVDS_GEN_CNTL);
3566 	rinfo->save_regs[12] = INREG(LVDS_PLL_CNTL);
3567 	rinfo->save_regs[13] = INREG(TV_DAC_CNTL);
3568 	rinfo->save_regs[14] = INREG(BUS_CNTL1);
3569 	rinfo->save_regs[15] = INREG(CRTC_OFFSET_CNTL);
3570 	rinfo->save_regs[16] = INREG(AGP_CNTL);
3571 	rinfo->save_regs[17] = (INREG(CRTC_GEN_CNTL) & 0xfdffffff) | 0x04000000;
3572 	rinfo->save_regs[18] = (INREG(CRTC2_GEN_CNTL) & 0xfdffffff) | 0x04000000;
3573 	rinfo->save_regs[19] = INREG(GPIOPAD_A);
3574 	rinfo->save_regs[20] = INREG(GPIOPAD_EN);
3575 	rinfo->save_regs[21] = INREG(GPIOPAD_MASK);
3576 	rinfo->save_regs[22] = INREG(ZV_LCDPAD_A);
3577 	rinfo->save_regs[23] = INREG(ZV_LCDPAD_EN);
3578 	rinfo->save_regs[24] = INREG(ZV_LCDPAD_MASK);
3579 	rinfo->save_regs[25] = INREG(GPIO_VGA_DDC);
3580 	rinfo->save_regs[26] = INREG(GPIO_DVI_DDC);
3581 	rinfo->save_regs[27] = INREG(GPIO_MONID);
3582 	rinfo->save_regs[28] = INREG(GPIO_CRT2_DDC);
3583 
3584 	rinfo->save_regs[29] = INREG(SURFACE_CNTL);
3585 	rinfo->save_regs[30] = INREG(MC_FB_LOCATION);
3586 	rinfo->save_regs[31] = INREG(DISPLAY_BASE_ADDR);
3587 	rinfo->save_regs[32] = INREG(MC_AGP_LOCATION);
3588 	rinfo->save_regs[33] = INREG(CRTC2_DISPLAY_BASE_ADDR);
3589 }
3590 
radeon_pm_restore_regs(struct radeonfb_info * rinfo)3591 static void radeon_pm_restore_regs(struct radeonfb_info *rinfo)
3592 {
3593 	OUTPLL(P2PLL_CNTL, rinfo->save_regs[8] & 0xFFFFFFFE); /* First */
3594 
3595 	OUTPLL(PLL_PWRMGT_CNTL, rinfo->save_regs[0]);
3596 	OUTPLL(CLK_PWRMGT_CNTL, rinfo->save_regs[1]);
3597 	OUTPLL(MCLK_CNTL, rinfo->save_regs[2]);
3598 	OUTPLL(SCLK_CNTL, rinfo->save_regs[3]);
3599 	OUTPLL(CLK_PIN_CNTL, rinfo->save_regs[4]);
3600 	OUTPLL(VCLK_ECP_CNTL, rinfo->save_regs[5]);
3601 	OUTPLL(PIXCLKS_CNTL, rinfo->save_regs[6]);
3602 	OUTPLL(MCLK_MISC, rinfo->save_regs[7]);
3603 
3604 	OUTREG(SURFACE_CNTL, rinfo->save_regs[29]);
3605 	OUTREG(MC_FB_LOCATION, rinfo->save_regs[30]);
3606 	OUTREG(DISPLAY_BASE_ADDR, rinfo->save_regs[31]);
3607 	OUTREG(MC_AGP_LOCATION, rinfo->save_regs[32]);
3608 	OUTREG(CRTC2_DISPLAY_BASE_ADDR, rinfo->save_regs[33]);
3609 
3610 	OUTREG(DISP_MISC_CNTL, rinfo->save_regs[9]);
3611 	OUTREG(DISP_PWR_MAN, rinfo->save_regs[10]);
3612 	OUTREG(LVDS_GEN_CNTL, rinfo->save_regs[11]);
3613 	OUTREG(LVDS_PLL_CNTL,rinfo->save_regs[12]);
3614 	OUTREG(TV_DAC_CNTL, rinfo->save_regs[13]);
3615 	OUTREG(BUS_CNTL1, rinfo->save_regs[14]);
3616 	OUTREG(CRTC_OFFSET_CNTL, rinfo->save_regs[15]);
3617 	OUTREG(AGP_CNTL, rinfo->save_regs[16]);
3618 	OUTREG(CRTC_GEN_CNTL, rinfo->save_regs[17]);
3619 	OUTREG(CRTC2_GEN_CNTL, rinfo->save_regs[18]);
3620 
3621 	// wait VBL before that one  ?
3622 	OUTPLL(P2PLL_CNTL, rinfo->save_regs[8]);
3623 
3624 	OUTREG(GPIOPAD_A, rinfo->save_regs[19]);
3625 	OUTREG(GPIOPAD_EN, rinfo->save_regs[20]);
3626 	OUTREG(GPIOPAD_MASK, rinfo->save_regs[21]);
3627 	OUTREG(ZV_LCDPAD_A, rinfo->save_regs[22]);
3628 	OUTREG(ZV_LCDPAD_EN, rinfo->save_regs[23]);
3629 	OUTREG(ZV_LCDPAD_MASK, rinfo->save_regs[24]);
3630 	OUTREG(GPIO_VGA_DDC, rinfo->save_regs[25]);
3631 	OUTREG(GPIO_DVI_DDC, rinfo->save_regs[26]);
3632 	OUTREG(GPIO_MONID, rinfo->save_regs[27]);
3633 	OUTREG(GPIO_CRT2_DDC, rinfo->save_regs[28]);
3634 }
3635 
radeon_pm_disable_iopad(struct radeonfb_info * rinfo)3636 static void radeon_pm_disable_iopad(struct radeonfb_info *rinfo)
3637 {
3638 	OUTREG(GPIOPAD_MASK, 0x0001ffff);
3639 	OUTREG(GPIOPAD_EN, 0x00000400);
3640 	OUTREG(GPIOPAD_A, 0x00000000);
3641         OUTREG(ZV_LCDPAD_MASK, 0x00000000);
3642         OUTREG(ZV_LCDPAD_EN, 0x00000000);
3643       	OUTREG(ZV_LCDPAD_A, 0x00000000);
3644 	OUTREG(GPIO_VGA_DDC, 0x00030000);
3645 	OUTREG(GPIO_DVI_DDC, 0x00000000);
3646 	OUTREG(GPIO_MONID, 0x00030000);
3647 	OUTREG(GPIO_CRT2_DDC, 0x00000000);
3648 }
3649 
radeon_pm_program_v2clk(struct radeonfb_info * rinfo)3650 static void radeon_pm_program_v2clk(struct radeonfb_info *rinfo)
3651 {
3652 	/* Set v2clk to 65MHz */
3653   	OUTPLL(pllPIXCLKS_CNTL,
3654   		INPLL(pllPIXCLKS_CNTL) & ~PIXCLKS_CNTL__PIX2CLK_SRC_SEL_MASK);
3655 
3656   	OUTPLL(pllP2PLL_REF_DIV, 0x0000000c);
3657 	OUTPLL(pllP2PLL_CNTL, 0x0000bf00);
3658 	OUTPLL(pllP2PLL_DIV_0, 0x00020074 | P2PLL_DIV_0__P2PLL_ATOMIC_UPDATE_W);
3659 
3660 	OUTPLL(pllP2PLL_CNTL, INPLL(pllP2PLL_CNTL) & ~P2PLL_CNTL__P2PLL_SLEEP);
3661 	mdelay(1);
3662 
3663 	OUTPLL(pllP2PLL_CNTL, INPLL(pllP2PLL_CNTL) & ~P2PLL_CNTL__P2PLL_RESET);
3664 	mdelay( 1);
3665 
3666   	OUTPLL(pllPIXCLKS_CNTL,
3667   		(INPLL(pllPIXCLKS_CNTL) & ~PIXCLKS_CNTL__PIX2CLK_SRC_SEL_MASK)
3668   		| (0x03 << PIXCLKS_CNTL__PIX2CLK_SRC_SEL__SHIFT));
3669 	mdelay( 1);
3670 }
3671 
radeon_pm_low_current(struct radeonfb_info * rinfo)3672 static void radeon_pm_low_current(struct radeonfb_info *rinfo)
3673 {
3674 	u32 reg;
3675 
3676 	reg  = INREG(BUS_CNTL1);
3677 	reg &= ~BUS_CNTL1_MOBILE_PLATFORM_SEL_MASK;
3678 	reg |= BUS_CNTL1_AGPCLK_VALID | (1<<BUS_CNTL1_MOBILE_PLATFORM_SEL_SHIFT);
3679 	OUTREG(BUS_CNTL1, reg);
3680 
3681 	reg  = INPLL(PLL_PWRMGT_CNTL);
3682 	reg |= PLL_PWRMGT_CNTL_SPLL_TURNOFF | PLL_PWRMGT_CNTL_PPLL_TURNOFF |
3683 		PLL_PWRMGT_CNTL_P2PLL_TURNOFF | PLL_PWRMGT_CNTL_TVPLL_TURNOFF;
3684 	reg &= ~PLL_PWRMGT_CNTL_SU_MCLK_USE_BCLK;
3685 	reg &= ~PLL_PWRMGT_CNTL_MOBILE_SU;
3686 	OUTPLL(PLL_PWRMGT_CNTL, reg);
3687 
3688 	reg  = INREG(TV_DAC_CNTL);
3689 	reg &= ~(TV_DAC_CNTL_BGADJ_MASK |TV_DAC_CNTL_DACADJ_MASK);
3690 	reg |=TV_DAC_CNTL_BGSLEEP | TV_DAC_CNTL_RDACPD | TV_DAC_CNTL_GDACPD |
3691 		TV_DAC_CNTL_BDACPD |
3692 		(8<<TV_DAC_CNTL_BGADJ__SHIFT) | (8<<TV_DAC_CNTL_DACADJ__SHIFT);
3693 	OUTREG(TV_DAC_CNTL, reg);
3694 
3695 	reg  = INREG(TMDS_TRANSMITTER_CNTL);
3696 	reg &= ~(TMDS_PLL_EN | TMDS_PLLRST);
3697 	OUTREG(TMDS_TRANSMITTER_CNTL, reg);
3698 
3699 	reg = INREG(DAC_CNTL);
3700 	reg &= ~DAC_CMP_EN;
3701 	OUTREG(DAC_CNTL, reg);
3702 
3703 	reg = INREG(DAC_CNTL2);
3704 	reg &= ~DAC2_CMP_EN;
3705 	OUTREG(DAC_CNTL2, reg);
3706 
3707 	reg  = INREG(TV_DAC_CNTL);
3708 	reg &= ~TV_DAC_CNTL_DETECT;
3709 	OUTREG(TV_DAC_CNTL, reg);
3710 }
3711 
radeon_pm_setup_for_suspend(struct radeonfb_info * rinfo)3712 static void radeon_pm_setup_for_suspend(struct radeonfb_info *rinfo)
3713 {
3714 
3715 	u32 sclk_cntl, mclk_cntl, sclk_more_cntl;
3716 
3717 	u32 pll_pwrmgt_cntl;
3718 	u32 clk_pwrmgt_cntl;
3719 	u32 clk_pin_cntl;
3720 	u32 vclk_ecp_cntl;
3721 	u32 pixclks_cntl;
3722 	u32 disp_mis_cntl;
3723 	u32 disp_pwr_man;
3724 
3725 
3726 	/* Force Core Clocks */
3727 	sclk_cntl = INPLL( pllSCLK_CNTL_M6);
3728 	sclk_cntl |= 	SCLK_CNTL_M6__IDCT_MAX_DYN_STOP_LAT|
3729 			SCLK_CNTL_M6__VIP_MAX_DYN_STOP_LAT|
3730 			SCLK_CNTL_M6__RE_MAX_DYN_STOP_LAT|
3731 			SCLK_CNTL_M6__PB_MAX_DYN_STOP_LAT|
3732 			SCLK_CNTL_M6__TAM_MAX_DYN_STOP_LAT|
3733 			SCLK_CNTL_M6__TDM_MAX_DYN_STOP_LAT|
3734 			SCLK_CNTL_M6__RB_MAX_DYN_STOP_LAT|
3735 
3736 			SCLK_CNTL_M6__FORCE_DISP2|
3737 			SCLK_CNTL_M6__FORCE_CP|
3738 			SCLK_CNTL_M6__FORCE_HDP|
3739 			SCLK_CNTL_M6__FORCE_DISP1|
3740 			SCLK_CNTL_M6__FORCE_TOP|
3741 			SCLK_CNTL_M6__FORCE_E2|
3742 			SCLK_CNTL_M6__FORCE_SE|
3743 			SCLK_CNTL_M6__FORCE_IDCT|
3744 			SCLK_CNTL_M6__FORCE_VIP|
3745 
3746 			SCLK_CNTL_M6__FORCE_RE|
3747 			SCLK_CNTL_M6__FORCE_PB|
3748 			SCLK_CNTL_M6__FORCE_TAM|
3749 			SCLK_CNTL_M6__FORCE_TDM|
3750 			SCLK_CNTL_M6__FORCE_RB|
3751 			SCLK_CNTL_M6__FORCE_TV_SCLK|
3752 			SCLK_CNTL_M6__FORCE_SUBPIC|
3753 			SCLK_CNTL_M6__FORCE_OV0;
3754 
3755 	OUTPLL( pllSCLK_CNTL_M6, sclk_cntl);
3756 
3757 	sclk_more_cntl = INPLL(pllSCLK_MORE_CNTL);
3758 	sclk_more_cntl |= 	SCLK_MORE_CNTL__FORCE_DISPREGS |
3759 				SCLK_MORE_CNTL__FORCE_MC_GUI |
3760 				SCLK_MORE_CNTL__FORCE_MC_HOST;
3761 
3762 	OUTPLL(pllSCLK_MORE_CNTL, sclk_more_cntl);
3763 
3764 
3765 	mclk_cntl = INPLL( pllMCLK_CNTL_M6);
3766 	mclk_cntl &= ~(	MCLK_CNTL_M6__FORCE_MCLKA |
3767 			MCLK_CNTL_M6__FORCE_MCLKB |
3768 			MCLK_CNTL_M6__FORCE_YCLKA |
3769 			MCLK_CNTL_M6__FORCE_YCLKB |
3770 			MCLK_CNTL_M6__FORCE_MC
3771 		      );
3772     	OUTPLL( pllMCLK_CNTL_M6, mclk_cntl);
3773 
3774 	/* Force Display clocks	*/
3775 	vclk_ecp_cntl = INPLL( pllVCLK_ECP_CNTL);
3776 	vclk_ecp_cntl &= ~(VCLK_ECP_CNTL__PIXCLK_ALWAYS_ONb |VCLK_ECP_CNTL__PIXCLK_DAC_ALWAYS_ONb);
3777 	vclk_ecp_cntl |= VCLK_ECP_CNTL__ECP_FORCE_ON;
3778 	OUTPLL( pllVCLK_ECP_CNTL, vclk_ecp_cntl);
3779 
3780 
3781 	pixclks_cntl = INPLL( pllPIXCLKS_CNTL);
3782 	pixclks_cntl &= ~(	PIXCLKS_CNTL__PIXCLK_GV_ALWAYS_ONb |
3783 				PIXCLKS_CNTL__PIXCLK_BLEND_ALWAYS_ONb|
3784 				PIXCLKS_CNTL__PIXCLK_DIG_TMDS_ALWAYS_ONb |
3785 				PIXCLKS_CNTL__PIXCLK_LVDS_ALWAYS_ONb|
3786 				PIXCLKS_CNTL__PIXCLK_TMDS_ALWAYS_ONb|
3787 				PIXCLKS_CNTL__PIX2CLK_ALWAYS_ONb|
3788 				PIXCLKS_CNTL__PIX2CLK_DAC_ALWAYS_ONb);
3789 
3790  	OUTPLL( pllPIXCLKS_CNTL, pixclks_cntl);
3791 
3792 
3793 
3794 	/* Enable System power management */
3795 	pll_pwrmgt_cntl = INPLL( pllPLL_PWRMGT_CNTL);
3796 
3797 	pll_pwrmgt_cntl |= 	PLL_PWRMGT_CNTL__SPLL_TURNOFF |
3798 				PLL_PWRMGT_CNTL__MPLL_TURNOFF|
3799 				PLL_PWRMGT_CNTL__PPLL_TURNOFF|
3800 				PLL_PWRMGT_CNTL__P2PLL_TURNOFF|
3801 				PLL_PWRMGT_CNTL__TVPLL_TURNOFF;
3802 
3803 	OUTPLL( pllPLL_PWRMGT_CNTL, pll_pwrmgt_cntl);
3804 
3805 	clk_pwrmgt_cntl	 = INPLL( pllCLK_PWRMGT_CNTL_M6);
3806 
3807 	clk_pwrmgt_cntl &= ~(	CLK_PWRMGT_CNTL_M6__MPLL_PWRMGT_OFF|
3808 				CLK_PWRMGT_CNTL_M6__SPLL_PWRMGT_OFF|
3809 				CLK_PWRMGT_CNTL_M6__PPLL_PWRMGT_OFF|
3810 				CLK_PWRMGT_CNTL_M6__P2PLL_PWRMGT_OFF|
3811 				CLK_PWRMGT_CNTL_M6__MCLK_TURNOFF|
3812 				CLK_PWRMGT_CNTL_M6__SCLK_TURNOFF|
3813 				CLK_PWRMGT_CNTL_M6__PCLK_TURNOFF|
3814 				CLK_PWRMGT_CNTL_M6__P2CLK_TURNOFF|
3815 				CLK_PWRMGT_CNTL_M6__TVPLL_PWRMGT_OFF|
3816 				CLK_PWRMGT_CNTL_M6__GLOBAL_PMAN_EN|
3817 				CLK_PWRMGT_CNTL_M6__ENGINE_DYNCLK_MODE|
3818 				CLK_PWRMGT_CNTL_M6__ACTIVE_HILO_LAT_MASK|
3819 				CLK_PWRMGT_CNTL_M6__CG_NO1_DEBUG_MASK
3820 			);
3821 
3822 	clk_pwrmgt_cntl |= CLK_PWRMGT_CNTL_M6__GLOBAL_PMAN_EN | CLK_PWRMGT_CNTL_M6__DISP_PM;
3823 
3824 	OUTPLL( pllCLK_PWRMGT_CNTL_M6, clk_pwrmgt_cntl);
3825 
3826 	clk_pin_cntl = INPLL( pllCLK_PIN_CNTL);
3827 
3828 	clk_pin_cntl &= ~CLK_PIN_CNTL__ACCESS_REGS_IN_SUSPEND;
3829 	OUTPLL( pllMCLK_MISC, INPLL( pllMCLK_MISC) | MCLK_MISC__EN_MCLK_TRISTATE_IN_SUSPEND);
3830 
3831 	/* AGP PLL control */
3832 	OUTREG(BUS_CNTL1, INREG(BUS_CNTL1) |  BUS_CNTL1__AGPCLK_VALID);
3833 
3834 	OUTREG(BUS_CNTL1,
3835 		(INREG(BUS_CNTL1) & ~BUS_CNTL1__MOBILE_PLATFORM_SEL_MASK)
3836 		| (2<<BUS_CNTL1__MOBILE_PLATFORM_SEL__SHIFT));	// 440BX
3837 	OUTREG(CRTC_OFFSET_CNTL, (INREG(CRTC_OFFSET_CNTL) & ~CRTC_OFFSET_CNTL__CRTC_STEREO_SYNC_OUT_EN));
3838 
3839 	clk_pin_cntl &= ~CLK_PIN_CNTL__CG_CLK_TO_OUTPIN;
3840 	clk_pin_cntl |= CLK_PIN_CNTL__XTALIN_ALWAYS_ONb;
3841 	OUTPLL( pllCLK_PIN_CNTL, clk_pin_cntl);
3842 
3843 	/* Solano2M */
3844 	OUTREG(AGP_CNTL,
3845 		(INREG(AGP_CNTL) & ~(AGP_CNTL__MAX_IDLE_CLK_MASK))
3846 		| (0x20<<AGP_CNTL__MAX_IDLE_CLK__SHIFT));
3847 
3848 	/* ACPI mode */
3849 	OUTPLL( pllPLL_PWRMGT_CNTL, INPLL( pllPLL_PWRMGT_CNTL) & ~PLL_PWRMGT_CNTL__PM_MODE_SEL);
3850 
3851 
3852 	disp_mis_cntl = INREG(DISP_MISC_CNTL);
3853 
3854 	disp_mis_cntl &= ~(	DISP_MISC_CNTL__SOFT_RESET_GRPH_PP |
3855 				DISP_MISC_CNTL__SOFT_RESET_SUBPIC_PP |
3856 				DISP_MISC_CNTL__SOFT_RESET_OV0_PP |
3857 				DISP_MISC_CNTL__SOFT_RESET_GRPH_SCLK|
3858 				DISP_MISC_CNTL__SOFT_RESET_SUBPIC_SCLK|
3859 				DISP_MISC_CNTL__SOFT_RESET_OV0_SCLK|
3860 				DISP_MISC_CNTL__SOFT_RESET_GRPH2_PP|
3861 				DISP_MISC_CNTL__SOFT_RESET_GRPH2_SCLK|
3862 				DISP_MISC_CNTL__SOFT_RESET_LVDS|
3863 				DISP_MISC_CNTL__SOFT_RESET_TMDS|
3864 				DISP_MISC_CNTL__SOFT_RESET_DIG_TMDS|
3865 				DISP_MISC_CNTL__SOFT_RESET_TV);
3866 
3867 	OUTREG(DISP_MISC_CNTL, disp_mis_cntl);
3868 
3869 	disp_pwr_man = INREG(DISP_PWR_MAN);
3870 
3871 	disp_pwr_man &= ~(	DISP_PWR_MAN__DISP_PWR_MAN_D3_CRTC_EN	|
3872 						DISP_PWR_MAN__DISP2_PWR_MAN_D3_CRTC2_EN |
3873 						DISP_PWR_MAN__DISP_PWR_MAN_DPMS_MASK|
3874 						DISP_PWR_MAN__DISP_D3_RST|
3875 						DISP_PWR_MAN__DISP_D3_REG_RST
3876 					);
3877 
3878 	disp_pwr_man |= DISP_PWR_MAN__DISP_D3_GRPH_RST|
3879 					DISP_PWR_MAN__DISP_D3_SUBPIC_RST|
3880 					DISP_PWR_MAN__DISP_D3_OV0_RST|
3881 					DISP_PWR_MAN__DISP_D1D2_GRPH_RST|
3882 					DISP_PWR_MAN__DISP_D1D2_SUBPIC_RST|
3883 					DISP_PWR_MAN__DISP_D1D2_OV0_RST|
3884 					DISP_PWR_MAN__DIG_TMDS_ENABLE_RST|
3885 					DISP_PWR_MAN__TV_ENABLE_RST|
3886 //					DISP_PWR_MAN__AUTO_PWRUP_EN|
3887 					0;
3888 
3889 	OUTREG(DISP_PWR_MAN, disp_pwr_man);
3890 
3891 	clk_pwrmgt_cntl = INPLL( pllCLK_PWRMGT_CNTL_M6);
3892 	pll_pwrmgt_cntl = INPLL( pllPLL_PWRMGT_CNTL) ;
3893 	clk_pin_cntl 	= INPLL( pllCLK_PIN_CNTL);
3894 	disp_pwr_man	= INREG(DISP_PWR_MAN);
3895 
3896 
3897 	/* D2 */
3898 	clk_pwrmgt_cntl |= CLK_PWRMGT_CNTL_M6__DISP_PM;
3899 	pll_pwrmgt_cntl |= PLL_PWRMGT_CNTL__MOBILE_SU | PLL_PWRMGT_CNTL__SU_SCLK_USE_BCLK;
3900 	clk_pin_cntl	|= CLK_PIN_CNTL__XTALIN_ALWAYS_ONb;
3901 	disp_pwr_man 	&= ~(DISP_PWR_MAN__DISP_PWR_MAN_D3_CRTC_EN_MASK | DISP_PWR_MAN__DISP2_PWR_MAN_D3_CRTC2_EN_MASK);
3902 
3903 
3904 	OUTPLL( pllCLK_PWRMGT_CNTL_M6, clk_pwrmgt_cntl);
3905 	OUTPLL( pllPLL_PWRMGT_CNTL, pll_pwrmgt_cntl);
3906 	OUTPLL( pllCLK_PIN_CNTL, clk_pin_cntl);
3907 	OUTREG(DISP_PWR_MAN, disp_pwr_man);
3908 
3909 	/* disable display request & disable display */
3910 	OUTREG( CRTC_GEN_CNTL, (INREG( CRTC_GEN_CNTL) & ~CRTC_GEN_CNTL__CRTC_EN) | CRTC_GEN_CNTL__CRTC_DISP_REQ_EN_B);
3911 	OUTREG( CRTC2_GEN_CNTL, (INREG( CRTC2_GEN_CNTL) & ~CRTC2_GEN_CNTL__CRTC2_EN) | CRTC2_GEN_CNTL__CRTC2_DISP_REQ_EN_B);
3912 
3913 	mdelay(17);
3914 
3915 }
3916 
radeon_pm_disable_dynamic_mode(struct radeonfb_info * rinfo)3917 static void radeon_pm_disable_dynamic_mode(struct radeonfb_info *rinfo)
3918 {
3919 
3920 	u32 sclk_cntl;
3921 	u32 mclk_cntl;
3922 	u32 sclk_more_cntl;
3923 
3924 	u32 vclk_ecp_cntl;
3925 	u32 pixclks_cntl;
3926 
3927 	/* Mobility chips only */
3928 	if ((rinfo->arch != RADEON_M6) && (rinfo->arch != RADEON_M7) && (rinfo->arch != RADEON_M9))
3929 		return;
3930 
3931 	/* Force Core Clocks */
3932 	sclk_cntl = INPLL( pllSCLK_CNTL_M6);
3933 	sclk_cntl |= 	SCLK_CNTL_M6__FORCE_CP|
3934 			SCLK_CNTL_M6__FORCE_HDP|
3935 			SCLK_CNTL_M6__FORCE_DISP1|
3936 			SCLK_CNTL_M6__FORCE_DISP2|
3937 			SCLK_CNTL_M6__FORCE_TOP|
3938 			SCLK_CNTL_M6__FORCE_E2|
3939 			SCLK_CNTL_M6__FORCE_SE|
3940 			SCLK_CNTL_M6__FORCE_IDCT|
3941 			SCLK_CNTL_M6__FORCE_VIP|
3942 			SCLK_CNTL_M6__FORCE_RE|
3943 			SCLK_CNTL_M6__FORCE_PB|
3944 			SCLK_CNTL_M6__FORCE_TAM|
3945 			SCLK_CNTL_M6__FORCE_TDM|
3946 			SCLK_CNTL_M6__FORCE_RB|
3947 			SCLK_CNTL_M6__FORCE_TV_SCLK|
3948 			SCLK_CNTL_M6__FORCE_SUBPIC|
3949 			SCLK_CNTL_M6__FORCE_OV0;
3950     	OUTPLL( pllSCLK_CNTL_M6, sclk_cntl);
3951 
3952 
3953 
3954 	sclk_more_cntl = INPLL(pllSCLK_MORE_CNTL);
3955 	sclk_more_cntl |= 	SCLK_MORE_CNTL__FORCE_DISPREGS|
3956 				SCLK_MORE_CNTL__FORCE_MC_GUI|
3957 				SCLK_MORE_CNTL__FORCE_MC_HOST;
3958 	OUTPLL(pllSCLK_MORE_CNTL, sclk_more_cntl);
3959 
3960 	/* Force Display clocks	*/
3961 	vclk_ecp_cntl = INPLL( pllVCLK_ECP_CNTL);
3962 	vclk_ecp_cntl &= ~(	VCLK_ECP_CNTL__PIXCLK_ALWAYS_ONb |
3963 			 	VCLK_ECP_CNTL__PIXCLK_DAC_ALWAYS_ONb);
3964 
3965 	OUTPLL( pllVCLK_ECP_CNTL, vclk_ecp_cntl);
3966 
3967 	pixclks_cntl = INPLL( pllPIXCLKS_CNTL);
3968 	pixclks_cntl &= ~(	PIXCLKS_CNTL__PIXCLK_GV_ALWAYS_ONb |
3969 			 	PIXCLKS_CNTL__PIXCLK_BLEND_ALWAYS_ONb|
3970 				PIXCLKS_CNTL__PIXCLK_DIG_TMDS_ALWAYS_ONb |
3971 				PIXCLKS_CNTL__PIXCLK_LVDS_ALWAYS_ONb|
3972 				PIXCLKS_CNTL__PIXCLK_TMDS_ALWAYS_ONb|
3973 				PIXCLKS_CNTL__PIX2CLK_ALWAYS_ONb|
3974 				PIXCLKS_CNTL__PIX2CLK_DAC_ALWAYS_ONb);
3975 
3976  	OUTPLL( pllPIXCLKS_CNTL, pixclks_cntl);
3977 
3978 	/* Force Memory Clocks */
3979 	mclk_cntl  = INPLL( pllMCLK_CNTL_M6);
3980 	mclk_cntl |= 	MCLK_CNTL_M6__FORCE_MCLKA|
3981 			MCLK_CNTL_M6__FORCE_MCLKB|
3982 			MCLK_CNTL_M6__FORCE_YCLKA|
3983 			MCLK_CNTL_M6__FORCE_YCLKB;
3984 
3985     	OUTPLL( pllMCLK_CNTL_M6, mclk_cntl);
3986 }
3987 
radeon_pm_enable_dynamic_mode(struct radeonfb_info * rinfo)3988 static void radeon_pm_enable_dynamic_mode(struct radeonfb_info *rinfo)
3989 {
3990 	u32 clk_pwrmgt_cntl;
3991 	u32 sclk_cntl;
3992 	u32 sclk_more_cntl;
3993 	u32 clk_pin_cntl;
3994 	u32 pixclks_cntl;
3995 	u32 vclk_ecp_cntl;
3996 	u32 mclk_cntl;
3997 	u32 mclk_misc;
3998 
3999 	/* Mobility chips only */
4000 	if ((rinfo->arch != RADEON_M6) && (rinfo->arch != RADEON_M7) && (rinfo->arch != RADEON_M9))
4001 		return;
4002 
4003 	/* Set Latencies */
4004 	clk_pwrmgt_cntl = INPLL( pllCLK_PWRMGT_CNTL_M6);
4005 
4006 	clk_pwrmgt_cntl &= ~(	 CLK_PWRMGT_CNTL_M6__ENGINE_DYNCLK_MODE_MASK|
4007 				 CLK_PWRMGT_CNTL_M6__ACTIVE_HILO_LAT_MASK|
4008 				 CLK_PWRMGT_CNTL_M6__DISP_DYN_STOP_LAT_MASK|
4009 				 CLK_PWRMGT_CNTL_M6__DYN_STOP_MODE_MASK);
4010 	/* Mode 1 */
4011 	clk_pwrmgt_cntl = 	CLK_PWRMGT_CNTL_M6__MC_CH_MODE|
4012 				CLK_PWRMGT_CNTL_M6__ENGINE_DYNCLK_MODE |
4013 				(1<<CLK_PWRMGT_CNTL_M6__ACTIVE_HILO_LAT__SHIFT) |
4014 				(0<<CLK_PWRMGT_CNTL_M6__DISP_DYN_STOP_LAT__SHIFT)|
4015 				(0<<CLK_PWRMGT_CNTL_M6__DYN_STOP_MODE__SHIFT);
4016 
4017 	OUTPLL( pllCLK_PWRMGT_CNTL_M6, clk_pwrmgt_cntl);
4018 
4019 
4020 	clk_pin_cntl = INPLL( pllCLK_PIN_CNTL);
4021 	clk_pin_cntl |= CLK_PIN_CNTL__SCLK_DYN_START_CNTL;
4022 
4023 	OUTPLL( pllCLK_PIN_CNTL, clk_pin_cntl);
4024 
4025 	/* Enable Dyanmic mode for SCLK */
4026 
4027 	sclk_cntl = INPLL( pllSCLK_CNTL_M6);
4028 	sclk_cntl &= SCLK_CNTL_M6__SCLK_SRC_SEL_MASK;
4029 	sclk_cntl |= SCLK_CNTL_M6__FORCE_VIP;
4030 
4031 	OUTPLL( pllSCLK_CNTL_M6, sclk_cntl);
4032 
4033 
4034 	sclk_more_cntl = INPLL(pllSCLK_MORE_CNTL);
4035 	sclk_more_cntl &= ~(SCLK_MORE_CNTL__FORCE_DISPREGS);
4036 
4037 	OUTPLL(pllSCLK_MORE_CNTL, sclk_more_cntl);
4038 
4039 
4040 	/* Enable Dynamic mode for PIXCLK & PIX2CLK */
4041 
4042 	pixclks_cntl = INPLL( pllPIXCLKS_CNTL);
4043 
4044 	pixclks_cntl|=  PIXCLKS_CNTL__PIX2CLK_ALWAYS_ONb |
4045 			PIXCLKS_CNTL__PIX2CLK_DAC_ALWAYS_ONb|
4046 			PIXCLKS_CNTL__PIXCLK_BLEND_ALWAYS_ONb|
4047 			PIXCLKS_CNTL__PIXCLK_GV_ALWAYS_ONb|
4048 			PIXCLKS_CNTL__PIXCLK_DIG_TMDS_ALWAYS_ONb|
4049 			PIXCLKS_CNTL__PIXCLK_LVDS_ALWAYS_ONb|
4050 			PIXCLKS_CNTL__PIXCLK_TMDS_ALWAYS_ONb;
4051 
4052 	OUTPLL( pllPIXCLKS_CNTL, pixclks_cntl);
4053 
4054 
4055 	vclk_ecp_cntl = INPLL( pllVCLK_ECP_CNTL);
4056 
4057 	vclk_ecp_cntl|=  VCLK_ECP_CNTL__PIXCLK_ALWAYS_ONb |
4058 			 VCLK_ECP_CNTL__PIXCLK_DAC_ALWAYS_ONb;
4059 
4060 	OUTPLL( pllVCLK_ECP_CNTL, vclk_ecp_cntl);
4061 
4062 
4063 	/* Enable Dynamic mode for MCLK	*/
4064 	mclk_cntl = INPLL( pllMCLK_CNTL_M6);
4065 	mclk_cntl &= ~(	MCLK_CNTL_M6__FORCE_MCLKA |
4066 			MCLK_CNTL_M6__FORCE_MCLKB |
4067 			MCLK_CNTL_M6__FORCE_YCLKA |
4068 			MCLK_CNTL_M6__FORCE_YCLKB );
4069     	OUTPLL( pllMCLK_CNTL_M6, mclk_cntl);
4070 
4071 	mclk_misc = INPLL(pllMCLK_MISC);
4072 	mclk_misc |= 	MCLK_MISC__MC_MCLK_MAX_DYN_STOP_LAT|
4073 			MCLK_MISC__IO_MCLK_MAX_DYN_STOP_LAT|
4074 			MCLK_MISC__MC_MCLK_DYN_ENABLE|
4075 			MCLK_MISC__IO_MCLK_DYN_ENABLE;
4076 
4077 	OUTPLL(pllMCLK_MISC, mclk_misc);
4078 }
4079 
4080 
radeon_pm_yclk_mclk_sync(struct radeonfb_info * rinfo)4081 static void radeon_pm_yclk_mclk_sync(struct radeonfb_info *rinfo)
4082 {
4083 	u32 mc_chp_io_cntl_a1, mc_chp_io_cntl_b1;
4084 
4085 	mc_chp_io_cntl_a1 = INMC( rinfo, ixMC_CHP_IO_CNTL_A1) & ~MC_CHP_IO_CNTL_A1__MEM_SYNC_ENA_MASK;
4086 	mc_chp_io_cntl_b1 = INMC( rinfo, ixMC_CHP_IO_CNTL_B1) & ~MC_CHP_IO_CNTL_B1__MEM_SYNC_ENB_MASK;
4087 
4088 	OUTMC( rinfo, ixMC_CHP_IO_CNTL_A1, mc_chp_io_cntl_a1 | (1<<MC_CHP_IO_CNTL_A1__MEM_SYNC_ENA__SHIFT));
4089 	OUTMC( rinfo, ixMC_CHP_IO_CNTL_B1, mc_chp_io_cntl_b1 | (1<<MC_CHP_IO_CNTL_B1__MEM_SYNC_ENB__SHIFT));
4090 
4091 	/* Wassup ? This doesn't seem to be defined, let's hope we are ok this way --BenH */
4092 #ifdef MCLK_YCLK_SYNC_ENABLE
4093 	mc_chp_io_cntl_a1 |= (2<<MC_CHP_IO_CNTL_A1__MEM_SYNC_ENA__SHIFT);
4094 	mc_chp_io_cntl_b1 |= (2<<MC_CHP_IO_CNTL_B1__MEM_SYNC_ENB__SHIFT);
4095 #endif
4096 
4097 	OUTMC( rinfo, ixMC_CHP_IO_CNTL_A1, mc_chp_io_cntl_a1);
4098 	OUTMC( rinfo, ixMC_CHP_IO_CNTL_B1, mc_chp_io_cntl_b1);
4099 
4100 	mdelay( 1);
4101 }
4102 
radeon_pm_program_mode_reg(struct radeonfb_info * rinfo,u16 value,u8 delay_required)4103 static void radeon_pm_program_mode_reg(struct radeonfb_info *rinfo, u16 value, u8 delay_required)
4104 {
4105 	u32 mem_sdram_mode;
4106 
4107 	mem_sdram_mode  = INREG( MEM_SDRAM_MODE_REG);
4108 
4109 	mem_sdram_mode &= ~MEM_SDRAM_MODE_REG__MEM_MODE_REG_MASK;
4110 	mem_sdram_mode |= (value<<MEM_SDRAM_MODE_REG__MEM_MODE_REG__SHIFT) | MEM_SDRAM_MODE_REG__MEM_CFG_TYPE;
4111 	OUTREG( MEM_SDRAM_MODE_REG, mem_sdram_mode);
4112 
4113 	mem_sdram_mode |=  MEM_SDRAM_MODE_REG__MEM_SDRAM_RESET;
4114 	OUTREG( MEM_SDRAM_MODE_REG, mem_sdram_mode);
4115 
4116 	mem_sdram_mode &= ~MEM_SDRAM_MODE_REG__MEM_SDRAM_RESET;
4117 	OUTREG( MEM_SDRAM_MODE_REG, mem_sdram_mode);
4118 
4119 	if (delay_required == 1)
4120 		while( (INREG( MC_STATUS) & (MC_STATUS__MEM_PWRUP_COMPL_A | MC_STATUS__MEM_PWRUP_COMPL_B) ) == 0 )
4121 			{ };
4122 }
4123 
4124 
radeon_pm_enable_dll(struct radeonfb_info * rinfo)4125 static void radeon_pm_enable_dll(struct radeonfb_info *rinfo)
4126 {
4127 #define DLL_RESET_DELAY 	5
4128 #define DLL_SLEEP_DELAY		1
4129 
4130 	u32 DLL_CKO_Value = INPLL(pllMDLL_CKO)   | MDLL_CKO__MCKOA_SLEEP |  MDLL_CKO__MCKOA_RESET;
4131 	u32 DLL_CKA_Value = INPLL(pllMDLL_RDCKA) | MDLL_RDCKA__MRDCKA0_SLEEP | MDLL_RDCKA__MRDCKA1_SLEEP | MDLL_RDCKA__MRDCKA0_RESET | MDLL_RDCKA__MRDCKA1_RESET;
4132 	u32 DLL_CKB_Value = INPLL(pllMDLL_RDCKB) | MDLL_RDCKB__MRDCKB0_SLEEP | MDLL_RDCKB__MRDCKB1_SLEEP | MDLL_RDCKB__MRDCKB0_RESET | MDLL_RDCKB__MRDCKB1_RESET;
4133 
4134 	/* Setting up the DLL range for write */
4135 	OUTPLL(pllMDLL_CKO,   	DLL_CKO_Value);
4136 	OUTPLL(pllMDLL_RDCKA,  	DLL_CKA_Value);
4137 	OUTPLL(pllMDLL_RDCKB,	DLL_CKB_Value);
4138 
4139 	mdelay( DLL_RESET_DELAY);
4140 
4141 	/* Channel A */
4142 
4143 	/* Power Up */
4144 	DLL_CKO_Value &= ~(MDLL_CKO__MCKOA_SLEEP );
4145 	OUTPLL(pllMDLL_CKO,   	DLL_CKO_Value);
4146 	mdelay( DLL_SLEEP_DELAY);
4147 
4148 	DLL_CKO_Value &= ~(MDLL_CKO__MCKOA_RESET );
4149 	OUTPLL(pllMDLL_CKO,	DLL_CKO_Value);
4150 	mdelay( DLL_RESET_DELAY);
4151 
4152 	/* Power Up */
4153 	DLL_CKA_Value &= ~(MDLL_RDCKA__MRDCKA0_SLEEP );
4154 	OUTPLL(pllMDLL_RDCKA,  	DLL_CKA_Value);
4155 	mdelay( DLL_SLEEP_DELAY);
4156 
4157 	DLL_CKA_Value &= ~(MDLL_RDCKA__MRDCKA0_RESET );
4158 	OUTPLL(pllMDLL_RDCKA,	DLL_CKA_Value);
4159 	mdelay( DLL_RESET_DELAY);
4160 
4161 	/* Power Up */
4162 	DLL_CKA_Value &= ~(MDLL_RDCKA__MRDCKA1_SLEEP);
4163 	OUTPLL(pllMDLL_RDCKA,	DLL_CKA_Value);
4164 	mdelay( DLL_SLEEP_DELAY);
4165 
4166 	DLL_CKA_Value &= ~(MDLL_RDCKA__MRDCKA1_RESET);
4167 	OUTPLL(pllMDLL_RDCKA,	DLL_CKA_Value);
4168 	mdelay( DLL_RESET_DELAY);
4169 
4170 
4171 	/* Channel B */
4172 
4173 	/* Power Up */
4174 	DLL_CKO_Value &= ~(MDLL_CKO__MCKOB_SLEEP );
4175 	OUTPLL(pllMDLL_CKO,   	DLL_CKO_Value);
4176 	mdelay( DLL_SLEEP_DELAY);
4177 
4178 	DLL_CKO_Value &= ~(MDLL_CKO__MCKOB_RESET );
4179 	OUTPLL(pllMDLL_CKO,   	DLL_CKO_Value);
4180 	mdelay( DLL_RESET_DELAY);
4181 
4182 	/* Power Up */
4183 	DLL_CKB_Value &= ~(MDLL_RDCKB__MRDCKB0_SLEEP);
4184 	OUTPLL(pllMDLL_RDCKB,   DLL_CKB_Value);
4185 	mdelay( DLL_SLEEP_DELAY);
4186 
4187 	DLL_CKB_Value &= ~(MDLL_RDCKB__MRDCKB0_RESET);
4188 	OUTPLL(pllMDLL_RDCKB,   DLL_CKB_Value);
4189 	mdelay( DLL_RESET_DELAY);
4190 
4191 	/* Power Up */
4192 	DLL_CKB_Value &= ~(MDLL_RDCKB__MRDCKB1_SLEEP);
4193 	OUTPLL(pllMDLL_RDCKB,   DLL_CKB_Value);
4194 	mdelay( DLL_SLEEP_DELAY);
4195 
4196 	DLL_CKB_Value &= ~(MDLL_RDCKB__MRDCKB1_RESET);
4197 	OUTPLL(pllMDLL_RDCKB,   DLL_CKB_Value);
4198 	mdelay( DLL_RESET_DELAY);
4199 
4200 #undef DLL_RESET_DELAY
4201 #undef DLL_SLEEP_DELAY
4202 }
4203 
radeon_pm_full_reset_sdram(struct radeonfb_info * rinfo)4204 static void radeon_pm_full_reset_sdram(struct radeonfb_info *rinfo)
4205 {
4206 	u32 crtcGenCntl, crtcGenCntl2, memRefreshCntl, crtc_more_cntl, fp_gen_cntl, fp2_gen_cntl;
4207 
4208 	crtcGenCntl  = INREG( CRTC_GEN_CNTL);
4209 	crtcGenCntl2 = INREG( CRTC2_GEN_CNTL);
4210 
4211 	memRefreshCntl 	= INREG( MEM_REFRESH_CNTL);
4212 	crtc_more_cntl 	= INREG( CRTC_MORE_CNTL);
4213 	fp_gen_cntl 	= INREG( FP_GEN_CNTL);
4214 	fp2_gen_cntl 	= INREG( FP2_GEN_CNTL);
4215 
4216 
4217 	OUTREG( CRTC_MORE_CNTL, 	0);
4218 	OUTREG( FP_GEN_CNTL, 	0);
4219 	OUTREG( FP2_GEN_CNTL, 	0);
4220 
4221 	OUTREG( CRTC_GEN_CNTL,  (crtcGenCntl | CRTC_GEN_CNTL__CRTC_DISP_REQ_EN_B) );
4222 	OUTREG( CRTC2_GEN_CNTL, (crtcGenCntl2 | CRTC2_GEN_CNTL__CRTC2_DISP_REQ_EN_B) );
4223 
4224 	/* Disable refresh */
4225 	OUTREG( MEM_REFRESH_CNTL, memRefreshCntl | MEM_REFRESH_CNTL__MEM_REFRESH_DIS);
4226 
4227 	/* Reset memory */
4228 	OUTREG( MEM_SDRAM_MODE_REG,
4229 		INREG( MEM_SDRAM_MODE_REG) & ~MEM_SDRAM_MODE_REG__MC_INIT_COMPLETE); // Init  Not Complete
4230 
4231 	/* DLL */
4232 	radeon_pm_enable_dll(rinfo);
4233 
4234 	// MLCK /YCLK sync
4235 	radeon_pm_yclk_mclk_sync(rinfo);
4236 
4237 	if ((rinfo->arch == RADEON_M6) || (rinfo->arch == RADEON_M7) || (rinfo->arch == RADEON_M9)) {
4238 		radeon_pm_program_mode_reg(rinfo, 0x2000, 1);
4239 		radeon_pm_program_mode_reg(rinfo, 0x2001, 1);
4240 		radeon_pm_program_mode_reg(rinfo, 0x2002, 1);
4241 		radeon_pm_program_mode_reg(rinfo, 0x0132, 1);
4242 		radeon_pm_program_mode_reg(rinfo, 0x0032, 1);
4243 	}
4244 
4245 	OUTREG( MEM_SDRAM_MODE_REG,
4246 		INREG( MEM_SDRAM_MODE_REG) |  MEM_SDRAM_MODE_REG__MC_INIT_COMPLETE); // Init Complete
4247 
4248 	OUTREG( MEM_REFRESH_CNTL, 	memRefreshCntl);
4249 
4250 	OUTREG( CRTC_GEN_CNTL, 		crtcGenCntl);
4251 	OUTREG( CRTC2_GEN_CNTL, 	crtcGenCntl2);
4252 	OUTREG( FP_GEN_CNTL, 		fp_gen_cntl);
4253 	OUTREG( FP2_GEN_CNTL, 		fp2_gen_cntl);
4254 
4255 	OUTREG( CRTC_MORE_CNTL, 	crtc_more_cntl);
4256 
4257 	mdelay( 15);
4258 }
4259 
4260 
radeon_set_suspend(struct radeonfb_info * rinfo,int suspend)4261 static void radeon_set_suspend(struct radeonfb_info *rinfo, int suspend)
4262 {
4263 	u16 pwr_cmd;
4264 
4265 	if (!rinfo->pm_reg)
4266 		return;
4267 
4268 	/* Set the chip into appropriate suspend mode (we use D2,
4269 	 * D3 would require a compete re-initialization of the chip,
4270 	 * including PCI config registers, clocks, AGP conf, ...)
4271 	 */
4272 	if (suspend) {
4273 		/* Disable dynamic power management of clocks for the
4274 		 * duration of the suspend/resume process
4275 		 */
4276 		radeon_pm_disable_dynamic_mode(rinfo);
4277 		/* Save some registers */
4278 		radeon_pm_save_regs(rinfo);
4279 
4280 		/* Prepare mobility chips for suspend
4281 		 */
4282 		if (rinfo->arch == RADEON_M6 || rinfo->arch == RADEON_M7 || rinfo->arch == RADEON_M9) {
4283 			/* Program V2CLK */
4284 			radeon_pm_program_v2clk(rinfo);
4285 
4286 			/* Disable IO PADs */
4287 			radeon_pm_disable_iopad(rinfo);
4288 
4289 			/* Set low current */
4290 			radeon_pm_low_current(rinfo);
4291 
4292 			/* Prepare chip for power management */
4293 			radeon_pm_setup_for_suspend(rinfo);
4294 
4295 			/* Reset the MDLL */
4296 			OUTPLL( pllMDLL_CKO, INPLL( pllMDLL_CKO) | MDLL_CKO__MCKOA_RESET | MDLL_CKO__MCKOB_RESET);
4297 		}
4298 
4299 		/* Switch PCI power managment to D2. */
4300 		for (;;) {
4301 			pci_read_config_word(
4302 				rinfo->pdev, rinfo->pm_reg+PCI_PM_CTRL,
4303 				&pwr_cmd);
4304 			if (pwr_cmd & 2)
4305 				break;
4306 			pci_write_config_word(
4307 				rinfo->pdev, rinfo->pm_reg+PCI_PM_CTRL,
4308 				(pwr_cmd & ~PCI_PM_CTRL_STATE_MASK) | 2);
4309 			mdelay(500);
4310 		}
4311 	} else {
4312 		/* Switch back PCI powermanagment to D0 */
4313 		mdelay(200);
4314 		pci_write_config_word(rinfo->pdev, rinfo->pm_reg+PCI_PM_CTRL, 0);
4315 		mdelay(500);
4316 
4317 		/* Reset the SDRAM controller */
4318 		if (rinfo->arch == RADEON_M6 || rinfo->arch == RADEON_M7 || rinfo->arch == RADEON_M9)
4319 			radeon_pm_full_reset_sdram(rinfo);
4320 
4321 		/* Restore some registers */
4322 		radeon_pm_restore_regs(rinfo);
4323 		radeon_pm_enable_dynamic_mode(rinfo);
4324 		mdelay(10);
4325 	}
4326 }
4327 
4328 /*
4329  * Save the contents of the framebuffer when we go to sleep,
4330  * and restore it when we wake up again.
4331  */
4332 
radeon_sleep_notify(struct pmu_sleep_notifier * self,int when)4333 static int radeon_sleep_notify(struct pmu_sleep_notifier *self, int when)
4334 {
4335 	struct radeonfb_info *rinfo;
4336 
4337 	for (rinfo = board_list; rinfo != NULL; rinfo = rinfo->next) {
4338 		struct fb_fix_screeninfo fix;
4339 		int nb;
4340 	        struct display *disp;
4341 
4342         	disp = (rinfo->currcon < 0) ? rinfo->info.disp : &fb_display[rinfo->currcon];
4343 
4344 		switch (rinfo->arch) {
4345 			case RADEON_M6:
4346 			case RADEON_M7:
4347 			case RADEON_M9:
4348 				break;
4349 			default:
4350 				return PBOOK_SLEEP_REFUSE;
4351 		}
4352 
4353 		radeonfb_get_fix(&fix, fg_console, (struct fb_info *)rinfo);
4354 		nb = fb_display[fg_console].var.yres * fix.line_length;
4355 
4356 		switch (when) {
4357 			case PBOOK_SLEEP_NOW:
4358 				acquire_console_sem();
4359 				disp->dispsw = &fbcon_dummy;
4360 
4361 				if (!noaccel) {
4362 					/* Make sure engine is idle and reset */
4363 					radeon_engine_idle();
4364 					radeon_engine_reset();
4365 					radeon_engine_idle();
4366 				}
4367 
4368 				/* Blank display and LCD */
4369 				radeonfb_blank(VESA_POWERDOWN+1,
4370 					       (struct fb_info *)rinfo);
4371 
4372 				/* Sleep */
4373 				rinfo->asleep = 1;
4374 				radeon_set_suspend(rinfo, 1);
4375 				release_console_sem();
4376 
4377 				break;
4378 			case PBOOK_WAKE:
4379 				acquire_console_sem();
4380 				/* Wakeup chip*/
4381 				radeon_set_suspend(rinfo, 0);
4382 
4383 				/* Re-set mode */
4384 				rinfo->asleep = 0;
4385 				radeon_load_video_mode(rinfo, &disp->var);
4386 				if ((disp->var.accel_flags & FB_ACCELF_TEXT) && !noaccel)
4387 					radeon_engine_init(rinfo);
4388 				do_install_cmap(rinfo->currcon < 0 ? 0 : rinfo->currcon,
4389 						(struct fb_info *)rinfo);
4390 				/* Allow fbdev to tap us again */
4391 				radeon_set_dispsw(rinfo, disp);
4392 
4393 				/* Unblank screen */
4394 				radeonfb_blank(0, (struct fb_info *)rinfo);
4395 				release_console_sem();
4396 				break;
4397 		}
4398 	}
4399 
4400 	return PBOOK_SLEEP_OK;
4401 }
4402 
4403 #endif /* CONFIG_PMAC_PBOOK */
4404 
4405 /*
4406  * text console acceleration
4407  */
4408 
4409 
fbcon_radeon_bmove(struct display * p,int srcy,int srcx,int dsty,int dstx,int height,int width)4410 static void fbcon_radeon_bmove(struct display *p, int srcy, int srcx,
4411 			       int dsty, int dstx, int height, int width)
4412 {
4413 	struct radeonfb_info *rinfo = (struct radeonfb_info *)(p->fb_info);
4414 	u32 dp_cntl = DST_LAST_PEL;
4415 	u32 dp_cntl_save = 0;
4416 
4417 	srcx *= fontwidth(p);
4418 	srcy *= fontheight(p);
4419 	dstx *= fontwidth(p);
4420 	dsty *= fontheight(p);
4421 	width *= fontwidth(p);
4422 	height *= fontheight(p);
4423 
4424 	if (srcy < dsty) {
4425 		srcy += height;
4426 		dsty += height;
4427 	} else
4428 		dp_cntl |= DST_Y_TOP_TO_BOTTOM;
4429 
4430 	if (srcx < dstx) {
4431 		srcx += width;
4432 		dstx += width;
4433 	} else
4434 		dp_cntl |= DST_X_LEFT_TO_RIGHT;
4435 
4436 	dp_cntl_save = INREG(DP_CNTL);
4437 
4438 	radeon_fifo_wait(6);
4439 	OUTREG(DP_GUI_MASTER_CNTL, (rinfo->dp_gui_master_cntl |
4440 				    GMC_BRUSH_NONE |
4441 				    GMC_SRC_DATATYPE_COLOR |
4442 				    ROP3_S |
4443 				    DP_SRC_SOURCE_MEMORY));
4444 	OUTREG(DP_WRITE_MSK, 0xffffffff);
4445 	OUTREG(DP_CNTL, dp_cntl);
4446 	OUTREG(SRC_Y_X, (srcy << 16) | srcx);
4447 	OUTREG(DST_Y_X, (dsty << 16) | dstx);
4448 	OUTREG(DST_HEIGHT_WIDTH, (height << 16) | width);
4449 
4450 	radeon_fifo_wait(1);
4451 	OUTREG(DP_CNTL, dp_cntl_save);
4452 
4453 	radeon_engine_idle();
4454 }
4455 
4456 
4457 
radeon_rectfill(struct radeonfb_info * rinfo,int dsty,int dstx,int height,int width,u32 clr)4458 static void radeon_rectfill(struct radeonfb_info *rinfo,
4459 			    int dsty, int dstx,
4460 			    int height, int width,
4461 			    u32 clr)
4462 {
4463 	radeon_fifo_wait(6);
4464 	OUTREG(DP_GUI_MASTER_CNTL, (rinfo->dp_gui_master_cntl |
4465 				    GMC_BRUSH_SOLID_COLOR |
4466 				    GMC_SRC_DATATYPE_COLOR |
4467 				    ROP3_P));
4468 	OUTREG(DP_BRUSH_FRGD_CLR, clr);
4469 	OUTREG(DP_WRITE_MSK, 0xffffffff);
4470 	OUTREG(DP_CNTL, (DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM));
4471 	OUTREG(DST_Y_X, (dsty << 16) | dstx);
4472 	OUTREG(DST_WIDTH_HEIGHT, (width << 16) | height);
4473 
4474 	radeon_engine_idle();
4475 }
4476 
4477 
4478 
4479 #ifdef FBCON_HAS_CFB8
4480 
fbcon_radeon8_clear(struct vc_data * conp,struct display * p,int srcy,int srcx,int height,int width)4481 static void fbcon_radeon8_clear(struct vc_data *conp, struct display *p,
4482 			       int srcy, int srcx, int height, int width)
4483 {
4484 	struct radeonfb_info *rinfo = (struct radeonfb_info *)(p->fb_info);
4485 	u32 clr;
4486 
4487 	clr = attr_bgcol_ec(p, conp);
4488 	clr |= (clr << 8);
4489 	clr |= (clr << 16);
4490 
4491 	srcx *= fontwidth(p);
4492 	srcy *= fontheight(p);
4493 	width *= fontwidth(p);
4494 	height *= fontheight(p);
4495 
4496 	radeon_rectfill(rinfo, srcy, srcx, height, width, clr);
4497 }
4498 
4499 
4500 
4501 static struct display_switch fbcon_radeon8 = {
4502 	setup:			fbcon_cfb8_setup,
4503 	bmove:			fbcon_radeon_bmove,
4504 	clear:			fbcon_radeon8_clear,
4505 	putc:			fbcon_cfb8_putc,
4506 	putcs:			fbcon_cfb8_putcs,
4507 	revc:			fbcon_cfb8_revc,
4508 	clear_margins:		fbcon_cfb8_clear_margins,
4509 	fontwidthmask:		FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
4510 };
4511 #endif
4512 
4513 #ifdef FBCON_HAS_CFB16
4514 
4515 
fbcon_radeon16_clear(struct vc_data * conp,struct display * p,int srcy,int srcx,int height,int width)4516 static void fbcon_radeon16_clear(struct vc_data *conp, struct display *p,
4517 			       int srcy, int srcx, int height, int width)
4518 {
4519 	struct radeonfb_info *rinfo = (struct radeonfb_info *)(p->fb_info);
4520 	u32 clr;
4521 
4522 	clr = ((u16 *)p->dispsw_data)[attr_bgcol_ec(p, conp)];
4523 	clr |= (clr << 16);
4524 
4525 	srcx *= fontwidth(p);
4526 	srcy *= fontheight(p);
4527 	width *= fontwidth(p);
4528 	height *= fontheight(p);
4529 
4530 	radeon_rectfill(rinfo, srcy, srcx, height, width, clr);
4531 }
4532 
4533 
4534 
4535 static struct display_switch fbcon_radeon16 = {
4536 	setup:			fbcon_cfb16_setup,
4537 	bmove:			fbcon_radeon_bmove,
4538 	clear:			fbcon_radeon16_clear,
4539 	putc:			fbcon_cfb16_putc,
4540 	putcs:			fbcon_cfb16_putcs,
4541 	revc:			fbcon_cfb16_revc,
4542 	clear_margins:		fbcon_cfb16_clear_margins,
4543 	fontwidthmask:		FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
4544 };
4545 #endif
4546 
4547 #ifdef FBCON_HAS_CFB32
4548 
4549 
fbcon_radeon32_clear(struct vc_data * conp,struct display * p,int srcy,int srcx,int height,int width)4550 static void fbcon_radeon32_clear(struct vc_data *conp, struct display *p,
4551 			       int srcy, int srcx, int height, int width)
4552 {
4553 	struct radeonfb_info *rinfo = (struct radeonfb_info *)(p->fb_info);
4554 	u32 clr;
4555 
4556 	clr = ((u32 *)p->dispsw_data)[attr_bgcol_ec(p, conp)];
4557 
4558 	srcx *= fontwidth(p);
4559 	srcy *= fontheight(p);
4560 	width *= fontwidth(p);
4561 	height *= fontheight(p);
4562 
4563 	radeon_rectfill(rinfo, srcy, srcx, height, width, clr);
4564 }
4565 
4566 
4567 
4568 static struct display_switch fbcon_radeon32 = {
4569 	setup:			fbcon_cfb32_setup,
4570 	bmove:			fbcon_radeon_bmove,
4571 	clear:			fbcon_radeon32_clear,
4572 	putc:			fbcon_cfb32_putc,
4573 	putcs:			fbcon_cfb32_putcs,
4574 	revc:			fbcon_cfb32_revc,
4575 	clear_margins:		fbcon_cfb32_clear_margins,
4576 	fontwidthmask:		FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
4577 };
4578 #endif
4579 
4580