1/*
2 *	drivers/video/radeonfb.c
3 *	framebuffer driver for ATI Radeon chipset video boards
4 *
5 *	Copyright 2000	Ani Joshi <ajoshi@unixbox.com>
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 *
23 *	Special thanks to ATI DevRel team for their hardware donations.
24 *
25 */
26
27
28#define RADEON_VERSION	"0.1.4"
29
30
31#include <linux/config.h>
32#include <linux/module.h>
33#include <linux/kernel.h>
34#include <linux/errno.h>
35#include <linux/string.h>
36#include <linux/mm.h>
37#include <linux/tty.h>
38#include <linux/slab.h>
39#include <linux/delay.h>
40#include <linux/fb.h>
41#include <linux/console.h>
42#include <linux/selection.h>
43#include <linux/ioport.h>
44#include <linux/init.h>
45#include <linux/pci.h>
46#include <linux/vmalloc.h>
47
48#include <asm/io.h>
49#if defined(__powerpc__)
50#include <asm/prom.h>
51#include <asm/pci-bridge.h>
52#include <video/macmodes.h>
53
54#ifdef CONFIG_NVRAM
55#include <linux/nvram.h>
56#endif
57
58#ifdef CONFIG_PMAC_BACKLIGHT
59#include <asm/backlight.h>
60#endif
61
62#ifdef CONFIG_BOOTX_TEXT
63#include <asm/btext.h>
64#endif
65
66#ifdef CONFIG_ADB_PMU
67#include <linux/adb.h>
68#include <linux/pmu.h>
69#endif
70
71#endif /* __powerpc__ */
72
73#include <video/fbcon.h>
74#include <video/fbcon-cfb8.h>
75#include <video/fbcon-cfb16.h>
76#include <video/fbcon-cfb24.h>
77#include <video/fbcon-cfb32.h>
78
79#include "radeon.h"
80
81
82#define DEBUG	0
83
84#if DEBUG
85#define RTRACE		printk
86#else
87#define RTRACE		if(0) printk
88#endif
89
90
91
92enum radeon_chips {
93	RADEON_QD,	/* Radeon R100 */
94	RADEON_QE,	/* Radeon R100 */
95	RADEON_QF,	/* Radeon R100 */
96	RADEON_QG,	/* Radeon R100 */
97	RADEON_QY,	/* Radeon RV100 (VE) */
98	RADEON_QZ,	/* Radeon RV100 (VE) */
99	RADEON_QL,	/* Radeon R200 (8500) */
100	RADEON_QW,	/* Radeon RV200 (7500) */
101	RADEON_LW,	/* Radeon Mobility M7 */
102	RADEON_LY,	/* Radeon Mobility M6 */
103	RADEON_LZ,	/* Radeon Mobility M6 */
104	RADEON_PM	/* Radeon Mobility P/M */
105};
106
107
108enum radeon_montype
109{
110	MT_NONE,
111	MT_CRT,		/* CRT */
112	MT_LCD,		/* LCD */
113	MT_DFP,		/* DVI */
114	MT_CTV,		/* composite TV */
115	MT_STV		/* S-Video out */
116};
117
118
119static struct pci_device_id radeonfb_pci_table[] __devinitdata = {
120	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_QD, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QD},
121	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_QE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QE},
122	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_QF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QF},
123	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_QG, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QG},
124	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_QY, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QY},
125	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_QZ, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QZ},
126	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_QL, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QL},
127	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_QW, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QW},
128	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_LW, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_LW},
129	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_LY, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_LY},
130	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_LZ, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_LZ},
131	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_PM, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_PM},
132	{ 0, }
133};
134MODULE_DEVICE_TABLE(pci, radeonfb_pci_table);
135
136
137typedef struct {
138	u16 reg;
139	u32 val;
140} reg_val;
141
142
143/* these common regs are cleared before mode setting so they do not
144 * interfere with anything
145 */
146reg_val common_regs[] = {
147	{ OVR_CLR, 0 },
148	{ OVR_WID_LEFT_RIGHT, 0 },
149	{ OVR_WID_TOP_BOTTOM, 0 },
150	{ OV0_SCALE_CNTL, 0 },
151	{ SUBPIC_CNTL, 0 },
152	{ VIPH_CONTROL, 0 },
153	{ I2C_CNTL_1, 0 },
154	{ GEN_INT_CNTL, 0 },
155	{ CAP0_TRIG_CNTL, 0 },
156};
157
158#define COMMON_REGS_SIZE = (sizeof(common_regs)/sizeof(common_regs[0]))
159
160typedef struct {
161        u8 clock_chip_type;
162        u8 struct_size;
163        u8 accelerator_entry;
164        u8 VGA_entry;
165        u16 VGA_table_offset;
166        u16 POST_table_offset;
167        u16 XCLK;
168        u16 MCLK;
169        u8 num_PLL_blocks;
170        u8 size_PLL_blocks;
171        u16 PCLK_ref_freq;
172        u16 PCLK_ref_divider;
173        u32 PCLK_min_freq;
174        u32 PCLK_max_freq;
175        u16 MCLK_ref_freq;
176        u16 MCLK_ref_divider;
177        u32 MCLK_min_freq;
178        u32 MCLK_max_freq;
179        u16 XCLK_ref_freq;
180        u16 XCLK_ref_divider;
181        u32 XCLK_min_freq;
182        u32 XCLK_max_freq;
183} __attribute__ ((packed)) PLL_BLOCK;
184
185
186struct pll_info {
187	int ppll_max;
188	int ppll_min;
189	int xclk;
190	int ref_div;
191	int ref_clk;
192};
193
194
195struct ram_info {
196	int ml;
197	int mb;
198	int trcd;
199	int trp;
200	int twr;
201	int cl;
202	int tr2w;
203	int loop_latency;
204	int rloop;
205};
206
207
208struct radeon_regs {
209	/* CRTC regs */
210	u32 crtc_h_total_disp;
211	u32 crtc_h_sync_strt_wid;
212	u32 crtc_v_total_disp;
213	u32 crtc_v_sync_strt_wid;
214	u32 crtc_pitch;
215	u32 crtc_gen_cntl;
216	u32 crtc_ext_cntl;
217	u32 dac_cntl;
218
219	u32 flags;
220	u32 pix_clock;
221	int xres, yres;
222
223	/* DDA regs */
224	u32 dda_config;
225	u32 dda_on_off;
226
227	/* PLL regs */
228	u32 ppll_div_3;
229	u32 ppll_ref_div;
230
231	/* Flat panel regs */
232	u32 fp_crtc_h_total_disp;
233	u32 fp_crtc_v_total_disp;
234	u32 fp_gen_cntl;
235	u32 fp_h_sync_strt_wid;
236	u32 fp_horz_stretch;
237	u32 fp_panel_cntl;
238	u32 fp_v_sync_strt_wid;
239	u32 fp_vert_stretch;
240	u32 lvds_gen_cntl;
241	u32 lvds_pll_cntl;
242	u32 tmds_crc;
243	u32 tmds_transmitter_cntl;
244
245#if defined(__BIG_ENDIAN)
246	u32 surface_cntl;
247#endif
248};
249
250
251struct radeonfb_info {
252	struct fb_info info;
253
254	struct radeon_regs state;
255	struct radeon_regs init_state;
256
257	char name[17];
258	char ram_type[12];
259
260	u32 mmio_base_phys;
261	u32 fb_base_phys;
262
263	unsigned long mmio_base;
264	unsigned long fb_base;
265
266	struct pci_dev *pdev;
267
268	unsigned char *EDID;
269	unsigned char *bios_seg;
270
271	struct display disp;
272	int currcon;
273	struct display *currcon_display;
274
275	struct { u8 red, green, blue, pad; } palette[256];
276
277	int chipset;
278	int video_ram;
279	u8 rev;
280	int pitch, bpp, depth;
281	int xres, yres, pixclock;
282
283	int use_default_var;
284	int got_dfpinfo;
285
286	int hasCRTC2;
287	int crtDisp_type;
288	int dviDisp_type;
289
290	int panel_xres, panel_yres;
291	int clock;
292	int hOver_plus, hSync_width, hblank;
293	int vOver_plus, vSync_width, vblank;
294	int hAct_high, vAct_high, interlaced;
295	int synct, misc;
296
297	u32 dp_gui_master_cntl;
298
299	struct pll_info pll;
300	int pll_output_freq, post_div, fb_div;
301
302	struct ram_info ram;
303
304        u32 hack_crtc_ext_cntl;
305        u32 hack_crtc_v_sync_strt_wid;
306
307#if defined(FBCON_HAS_CFB16) || defined(FBCON_HAS_CFB32)
308        union {
309#if defined(FBCON_HAS_CFB16)
310                u_int16_t cfb16[16];
311#endif
312#if defined(FBCON_HAS_CFB24)
313                u_int32_t cfb24[16];
314#endif
315#if defined(FBCON_HAS_CFB32)
316                u_int32_t cfb32[16];
317#endif
318        } con_cmap;
319#endif
320
321#ifdef CONFIG_PMAC_PBOOK
322	unsigned char *save_framebuffer;
323	int pm_reg;
324#endif
325
326	struct radeonfb_info *next;
327};
328
329
330static struct fb_var_screeninfo radeonfb_default_var = {
331        640, 480, 640, 480, 0, 0, 8, 0,
332        {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0},
333        0, 0, -1, -1, 0, 39721, 40, 24, 32, 11, 96, 2,
334        0, FB_VMODE_NONINTERLACED
335};
336
337
338/*
339 * IO macros
340 */
341
342#define INREG8(addr)		readb((rinfo->mmio_base)+addr)
343#define OUTREG8(addr,val)	writeb(val, (rinfo->mmio_base)+addr)
344#define INREG(addr)		readl((rinfo->mmio_base)+addr)
345#define OUTREG(addr,val)	writel(val, (rinfo->mmio_base)+addr)
346
347#define OUTPLL(addr,val)	OUTREG8(CLOCK_CNTL_INDEX, (addr & 0x0000001f) | 0x00000080); \
348				OUTREG(CLOCK_CNTL_DATA, val)
349#define OUTPLLP(addr,val,mask)  					\
350	do {								\
351		unsigned int _tmp = INPLL(addr);			\
352		_tmp &= (mask);						\
353		_tmp |= (val);						\
354		OUTPLL(addr, _tmp);					\
355	} while (0)
356
357#define OUTREGP(addr,val,mask)  					\
358	do {								\
359		unsigned int _tmp = INREG(addr);			\
360		_tmp &= (mask);						\
361		_tmp |= (val);						\
362		OUTREG(addr, _tmp);					\
363	} while (0)
364
365
366static __inline__ u32 _INPLL(struct radeonfb_info *rinfo, unsigned long addr)
367{
368	OUTREG8(CLOCK_CNTL_INDEX, addr & 0x0000001f);
369	return (INREG(CLOCK_CNTL_DATA));
370}
371
372#define INPLL(addr)		_INPLL(rinfo, addr)
373
374#define PRIMARY_MONITOR(rinfo)	((rinfo->dviDisp_type != MT_NONE) &&	\
375				 (rinfo->dviDisp_type != MT_STV) &&	\
376				 (rinfo->dviDisp_type != MT_CTV) ?	\
377				 rinfo->dviDisp_type : rinfo->crtDisp_type)
378
379static char *GET_MON_NAME(int type)
380{
381	char *pret = NULL;
382
383	switch (type) {
384		case MT_NONE:
385			pret = "no";
386			break;
387		case MT_CRT:
388			pret = "CRT";
389			break;
390		case MT_DFP:
391			pret = "DFP";
392			break;
393		case MT_LCD:
394			pret = "LCD";
395			break;
396		case MT_CTV:
397			pret = "CTV";
398			break;
399		case MT_STV:
400			pret = "STV";
401			break;
402	}
403
404	return pret;
405}
406
407
408/*
409 * 2D engine routines
410 */
411
412static __inline__ void radeon_engine_flush (struct radeonfb_info *rinfo)
413{
414	int i;
415
416	/* initiate flush */
417	OUTREGP(RB2D_DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL,
418	        ~RB2D_DC_FLUSH_ALL);
419
420	for (i=0; i < 2000000; i++) {
421		if (!(INREG(RB2D_DSTCACHE_CTLSTAT) & RB2D_DC_BUSY))
422			break;
423	}
424}
425
426
427static __inline__ void _radeon_fifo_wait (struct radeonfb_info *rinfo, int entries)
428{
429	int i;
430
431	for (i=0; i<2000000; i++)
432		if ((INREG(RBBM_STATUS) & 0x7f) >= entries)
433			return;
434}
435
436
437static __inline__ void _radeon_engine_idle (struct radeonfb_info *rinfo)
438{
439	int i;
440
441	/* ensure FIFO is empty before waiting for idle */
442	_radeon_fifo_wait (rinfo, 64);
443
444	for (i=0; i<2000000; i++) {
445		if (((INREG(RBBM_STATUS) & GUI_ACTIVE)) == 0) {
446			radeon_engine_flush (rinfo);
447			return;
448		}
449	}
450}
451
452
453#define radeon_engine_idle()		_radeon_engine_idle(rinfo)
454#define radeon_fifo_wait(entries)	_radeon_fifo_wait(rinfo,entries)
455
456
457
458/*
459 * helper routines
460 */
461
462static __inline__ u32 radeon_get_dstbpp(u16 depth)
463{
464	switch (depth) {
465		case 8:
466			return DST_8BPP;
467		case 15:
468			return DST_15BPP;
469		case 16:
470			return DST_16BPP;
471		case 32:
472			return DST_32BPP;
473		default:
474			return 0;
475	}
476}
477
478
479static inline int var_to_depth(const struct fb_var_screeninfo *var)
480{
481	if (var->bits_per_pixel != 16)
482		return var->bits_per_pixel;
483	return (var->green.length == 6) ? 16 : 15;
484}
485
486
487static void _radeon_engine_reset(struct radeonfb_info *rinfo)
488{
489	u32 clock_cntl_index, mclk_cntl, rbbm_soft_reset;
490
491	radeon_engine_flush (rinfo);
492
493	clock_cntl_index = INREG(CLOCK_CNTL_INDEX);
494	mclk_cntl = INPLL(MCLK_CNTL);
495
496	OUTPLL(MCLK_CNTL, (mclk_cntl |
497			   FORCEON_MCLKA |
498			   FORCEON_MCLKB |
499			   FORCEON_YCLKA |
500			   FORCEON_YCLKB |
501			   FORCEON_MC |
502			   FORCEON_AIC));
503	rbbm_soft_reset = INREG(RBBM_SOFT_RESET);
504
505	OUTREG(RBBM_SOFT_RESET, rbbm_soft_reset |
506				SOFT_RESET_CP |
507				SOFT_RESET_HI |
508				SOFT_RESET_SE |
509				SOFT_RESET_RE |
510				SOFT_RESET_PP |
511				SOFT_RESET_E2 |
512				SOFT_RESET_RB |
513				SOFT_RESET_HDP);
514	INREG(RBBM_SOFT_RESET);
515	OUTREG(RBBM_SOFT_RESET, rbbm_soft_reset & (u32)
516				~(SOFT_RESET_CP |
517				  SOFT_RESET_HI |
518				  SOFT_RESET_SE |
519				  SOFT_RESET_RE |
520				  SOFT_RESET_PP |
521				  SOFT_RESET_E2 |
522				  SOFT_RESET_RB |
523				  SOFT_RESET_HDP));
524	INREG(RBBM_SOFT_RESET);
525
526	OUTPLL(MCLK_CNTL, mclk_cntl);
527	OUTREG(CLOCK_CNTL_INDEX, clock_cntl_index);
528	OUTREG(RBBM_SOFT_RESET, rbbm_soft_reset);
529
530	return;
531}
532
533#define radeon_engine_reset()		_radeon_engine_reset(rinfo)
534
535
536static __inline__ u8 radeon_get_post_div_bitval(int post_div)
537{
538        switch (post_div) {
539                case 1:
540                        return 0x00;
541                case 2:
542                        return 0x01;
543                case 3:
544                        return 0x04;
545                case 4:
546                        return 0x02;
547                case 6:
548                        return 0x06;
549                case 8:
550                        return 0x03;
551                case 12:
552                        return 0x07;
553                default:
554                        return 0x02;
555        }
556}
557
558
559
560static __inline__ int round_div(int num, int den)
561{
562        return (num + (den / 2)) / den;
563}
564
565
566
567static __inline__ int min_bits_req(int val)
568{
569        int bits_req = 0;
570
571        if (val == 0)
572                bits_req = 1;
573
574        while (val) {
575                val >>= 1;
576                bits_req++;
577        }
578
579        return (bits_req);
580}
581
582
583static __inline__ int _max(int val1, int val2)
584{
585        if (val1 >= val2)
586                return val1;
587        else
588                return val2;
589}
590
591
592
593/*
594 * globals
595 */
596
597static char fontname[40] __initdata;
598static char *mode_option __initdata;
599static char noaccel __initdata = 0;
600static int panel_yres __initdata = 0;
601static char force_dfp __initdata = 0;
602static struct radeonfb_info *board_list = NULL;
603
604#ifdef FBCON_HAS_CFB8
605static struct display_switch fbcon_radeon8;
606#endif
607
608
609/*
610 * prototypes
611 */
612
613static int radeonfb_get_fix (struct fb_fix_screeninfo *fix, int con,
614                             struct fb_info *info);
615static int radeonfb_get_var (struct fb_var_screeninfo *var, int con,
616                             struct fb_info *info);
617static int radeonfb_set_var (struct fb_var_screeninfo *var, int con,
618                             struct fb_info *info);
619static int radeonfb_get_cmap (struct fb_cmap *cmap, int kspc, int con,
620                              struct fb_info *info);
621static int radeonfb_set_cmap (struct fb_cmap *cmap, int kspc, int con,
622                              struct fb_info *info);
623static int radeonfb_pan_display (struct fb_var_screeninfo *var, int con,
624                                 struct fb_info *info);
625static int radeonfb_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
626                           unsigned long arg, int con, struct fb_info *info);
627static int radeonfb_switch (int con, struct fb_info *info);
628static int radeonfb_updatevar (int con, struct fb_info *info);
629static void radeonfb_blank (int blank, struct fb_info *info);
630static int radeon_get_cmap_len (const struct fb_var_screeninfo *var);
631static int radeon_getcolreg (unsigned regno, unsigned *red, unsigned *green,
632                             unsigned *blue, unsigned *transp,
633                             struct fb_info *info);
634static int radeon_setcolreg (unsigned regno, unsigned red, unsigned green,
635                             unsigned blue, unsigned transp, struct fb_info *info);
636static void radeon_set_dispsw (struct radeonfb_info *rinfo, struct display *disp);
637static void radeon_save_state (struct radeonfb_info *rinfo,
638                               struct radeon_regs *save);
639static void radeon_engine_init (struct radeonfb_info *rinfo);
640static void radeon_load_video_mode (struct radeonfb_info *rinfo,
641                                    struct fb_var_screeninfo *mode);
642static void radeon_write_mode (struct radeonfb_info *rinfo,
643                               struct radeon_regs *mode);
644static int __devinit radeon_set_fbinfo (struct radeonfb_info *rinfo);
645static int __devinit radeon_init_disp (struct radeonfb_info *rinfo);
646static int radeon_init_disp_var (struct radeonfb_info *rinfo);
647static int radeonfb_pci_register (struct pci_dev *pdev,
648                                 const struct pci_device_id *ent);
649static void __devexit radeonfb_pci_unregister (struct pci_dev *pdev);
650static char *radeon_find_rom(struct radeonfb_info *rinfo);
651static void radeon_get_pllinfo(struct radeonfb_info *rinfo, char *bios_seg);
652static void radeon_get_moninfo (struct radeonfb_info *rinfo);
653static int radeon_get_dfpinfo (struct radeonfb_info *rinfo);
654static int radeon_get_dfpinfo_BIOS(struct radeonfb_info *rinfo);
655static void radeon_get_EDID(struct radeonfb_info *rinfo);
656static int radeon_dfp_parse_EDID(struct radeonfb_info *rinfo);
657static void radeon_update_default_var(struct radeonfb_info *rinfo);
658
659
660#ifdef CONFIG_ALL_PPC
661static int radeon_read_OF (struct radeonfb_info *rinfo);
662static int radeon_get_EDID_OF(struct radeonfb_info *rinfo);
663extern struct device_node *pci_device_to_OF_node(struct pci_dev *dev);
664
665#ifdef CONFIG_PMAC_PBOOK
666int radeon_sleep_notify(struct pmu_sleep_notifier *self, int when);
667static struct pmu_sleep_notifier radeon_sleep_notifier = {
668	radeon_sleep_notify, SLEEP_LEVEL_VIDEO,
669};
670static int radeon_set_backlight_enable(int on, int level, void *data);
671static int radeon_set_backlight_level(int level, void *data);
672static struct backlight_controller radeon_backlight_controller = {
673	radeon_set_backlight_enable,
674	radeon_set_backlight_level
675};
676#endif /* CONFIG_PMAC_PBOOK */
677
678#endif /* CONFIG_ALL_PPC */
679
680static struct fb_ops radeon_fb_ops = {
681	fb_get_fix:		radeonfb_get_fix,
682	fb_get_var:		radeonfb_get_var,
683	fb_set_var:		radeonfb_set_var,
684	fb_get_cmap:		radeonfb_get_cmap,
685	fb_set_cmap:		radeonfb_set_cmap,
686	fb_pan_display:		radeonfb_pan_display,
687	fb_ioctl:		radeonfb_ioctl,
688};
689
690
691static struct pci_driver radeonfb_driver = {
692	name:		"radeonfb",
693	id_table:	radeonfb_pci_table,
694	probe:		radeonfb_pci_register,
695	remove:		__devexit_p(radeonfb_pci_unregister),
696};
697
698
699int __init radeonfb_init (void)
700{
701	return pci_module_init (&radeonfb_driver);
702}
703
704
705void __exit radeonfb_exit (void)
706{
707	pci_unregister_driver (&radeonfb_driver);
708}
709
710
711int __init radeonfb_setup (char *options)
712{
713        char *this_opt;
714
715        if (!options || !*options)
716                return 0;
717
718	while ((this_opt = strsep (&options, ",")) != NULL) {
719		if (!*this_opt)
720			continue;
721                if (!strncmp (this_opt, "font:", 5)) {
722                        char *p;
723                        int i;
724
725                        p = this_opt + 5;
726                        for (i=0; i<sizeof (fontname) - 1; i++)
727                                if (!*p || *p == ' ' || *p == ',')
728                                        break;
729                        memcpy(fontname, this_opt + 5, i);
730                } else if (!strncmp(this_opt, "noaccel", 7)) {
731			noaccel = 1;
732		} else if (!strncmp(this_opt, "dfp", 3)) {
733			force_dfp = 1;
734		} else if (!strncmp(this_opt, "panel_yres:", 11)) {
735			panel_yres = simple_strtoul((this_opt+11), NULL, 0);
736                } else
737			mode_option = this_opt;
738        }
739
740	return 0;
741}
742
743#ifdef MODULE
744module_init(radeonfb_init);
745module_exit(radeonfb_exit);
746#endif
747
748
749MODULE_AUTHOR("Ani Joshi");
750MODULE_DESCRIPTION("framebuffer driver for ATI Radeon chipset");
751MODULE_LICENSE("GPL");
752
753static int radeonfb_pci_register (struct pci_dev *pdev,
754				  const struct pci_device_id *ent)
755{
756	struct radeonfb_info *rinfo;
757	u32 tmp;
758	int i, j;
759
760	RTRACE("radeonfb_pci_register BEGIN\n");
761
762	rinfo = kmalloc (sizeof (struct radeonfb_info), GFP_KERNEL);
763	if (!rinfo) {
764		printk ("radeonfb: could not allocate memory\n");
765		return -ENODEV;
766	}
767
768	memset (rinfo, 0, sizeof (struct radeonfb_info));
769
770	rinfo->pdev = pdev;
771
772	/* enable device */
773	{
774		int err;
775
776		if ((err = pci_enable_device(pdev))) {
777			printk("radeonfb: cannot enable device\n");
778			kfree (rinfo);
779			return -ENODEV;
780		}
781	}
782
783	/* set base addrs */
784	rinfo->fb_base_phys = pci_resource_start (pdev, 0);
785	rinfo->mmio_base_phys = pci_resource_start (pdev, 2);
786
787	/* request the mem regions */
788	if (!request_mem_region (rinfo->fb_base_phys,
789				 pci_resource_len(pdev, 0), "radeonfb")) {
790		printk ("radeonfb: cannot reserve FB region\n");
791		kfree (rinfo);
792		return -ENODEV;
793	}
794
795	if (!request_mem_region (rinfo->mmio_base_phys,
796				 pci_resource_len(pdev, 2), "radeonfb")) {
797		printk ("radeonfb: cannot reserve MMIO region\n");
798		release_mem_region (rinfo->fb_base_phys,
799				    pci_resource_len(pdev, 0));
800		kfree (rinfo);
801		return -ENODEV;
802	}
803
804	/* map the regions */
805	rinfo->mmio_base = (unsigned long)ioremap (rinfo->mmio_base_phys,
806				    		    RADEON_REGSIZE);
807	if (!rinfo->mmio_base) {
808		printk ("radeonfb: cannot map MMIO\n");
809		release_mem_region (rinfo->mmio_base_phys,
810				    pci_resource_len(pdev, 2));
811		release_mem_region (rinfo->fb_base_phys,
812				    pci_resource_len(pdev, 0));
813		kfree (rinfo);
814		return -ENODEV;
815	}
816
817	rinfo->chipset = pdev->device;
818
819	/* chipset */
820	switch (pdev->device) {
821		case PCI_DEVICE_ID_RADEON_QD:
822			strcpy(rinfo->name, "Radeon QD ");
823			break;
824		case PCI_DEVICE_ID_RADEON_QE:
825			strcpy(rinfo->name, "Radeon QE ");
826			break;
827		case PCI_DEVICE_ID_RADEON_QF:
828			strcpy(rinfo->name, "Radeon QF ");
829			break;
830		case PCI_DEVICE_ID_RADEON_QG:
831			strcpy(rinfo->name, "Radeon QG ");
832			break;
833		case PCI_DEVICE_ID_RADEON_QY:
834			strcpy(rinfo->name, "Radeon QY VE ");
835			rinfo->hasCRTC2 = 1;
836			break;
837		case PCI_DEVICE_ID_RADEON_QZ:
838			strcpy(rinfo->name, "Radeon QZ VE ");
839			rinfo->hasCRTC2 = 1;
840			break;
841		case PCI_DEVICE_ID_RADEON_QW:
842			strcpy(rinfo->name, "Radeon 7500 QW ");
843			rinfo->hasCRTC2 = 1;
844			break;
845		case PCI_DEVICE_ID_RADEON_QL:
846			strcpy(rinfo->name, "Radeon 8500 QL ");
847			rinfo->hasCRTC2 = 1;
848			break;
849		case PCI_DEVICE_ID_RADEON_LW:
850			strcpy(rinfo->name, "Radeon M7 LW ");
851			rinfo->hasCRTC2 = 1;
852			break;
853		case PCI_DEVICE_ID_RADEON_LY:
854			strcpy(rinfo->name, "Radeon M6 LY ");
855			rinfo->hasCRTC2 = 1;
856			break;
857		case PCI_DEVICE_ID_RADEON_LZ:
858			strcpy(rinfo->name, "Radeon M6 LZ ");
859			rinfo->hasCRTC2 = 1;
860			break;
861	        case PCI_DEVICE_ID_RADEON_PM:
862			strcpy(rinfo->name, "Radeon P/M ");
863			rinfo->hasCRTC2 = 1;
864		default:
865			return -ENODEV;
866	}
867
868	/* framebuffer size */
869	tmp = INREG(CONFIG_MEMSIZE);
870
871	/* mem size is bits [28:0], mask off the rest */
872	rinfo->video_ram = tmp & CONFIG_MEMSIZE_MASK;
873
874	/* ram type */
875	tmp = INREG(MEM_SDRAM_MODE_REG);
876	switch ((MEM_CFG_TYPE & tmp) >> 30) {
877		case 0:
878			/* SDR SGRAM (2:1) */
879			strcpy(rinfo->ram_type, "SDR SGRAM");
880			rinfo->ram.ml = 4;
881			rinfo->ram.mb = 4;
882			rinfo->ram.trcd = 1;
883			rinfo->ram.trp = 2;
884			rinfo->ram.twr = 1;
885			rinfo->ram.cl = 2;
886			rinfo->ram.loop_latency = 16;
887			rinfo->ram.rloop = 16;
888
889			break;
890		case 1:
891			/* DDR SGRAM */
892			strcpy(rinfo->ram_type, "DDR SGRAM");
893			rinfo->ram.ml = 4;
894			rinfo->ram.mb = 4;
895			rinfo->ram.trcd = 3;
896			rinfo->ram.trp = 3;
897			rinfo->ram.twr = 2;
898			rinfo->ram.cl = 3;
899			rinfo->ram.tr2w = 1;
900			rinfo->ram.loop_latency = 16;
901			rinfo->ram.rloop = 16;
902
903			break;
904		default:
905			/* 64-bit SDR SGRAM */
906			strcpy(rinfo->ram_type, "SDR SGRAM 64");
907			rinfo->ram.ml = 4;
908			rinfo->ram.mb = 8;
909			rinfo->ram.trcd = 3;
910			rinfo->ram.trp = 3;
911			rinfo->ram.twr = 1;
912			rinfo->ram.cl = 3;
913			rinfo->ram.tr2w = 1;
914			rinfo->ram.loop_latency = 17;
915			rinfo->ram.rloop = 17;
916
917			break;
918	}
919
920	rinfo->bios_seg = radeon_find_rom(rinfo);
921	radeon_get_pllinfo(rinfo, rinfo->bios_seg);
922
923	RTRACE("radeonfb: probed %s %dk videoram\n", (rinfo->ram_type), (rinfo->video_ram/1024));
924
925#if !defined(__powerpc__)
926	radeon_get_moninfo(rinfo);
927#else
928	switch (pdev->device) {
929		case PCI_DEVICE_ID_RADEON_LW:
930		case PCI_DEVICE_ID_RADEON_LY:
931		case PCI_DEVICE_ID_RADEON_LZ:
932		case PCI_DEVICE_ID_RADEON_PM:
933			rinfo->dviDisp_type = MT_LCD;
934			break;
935		default:
936			radeon_get_moninfo(rinfo);
937			break;
938	}
939#endif
940
941	radeon_get_EDID(rinfo);
942
943	if ((rinfo->dviDisp_type == MT_DFP) || (rinfo->dviDisp_type == MT_LCD) ||
944	    (rinfo->crtDisp_type == MT_DFP)) {
945		if (!radeon_get_dfpinfo(rinfo)) {
946			iounmap ((void*)rinfo->mmio_base);
947			release_mem_region (rinfo->mmio_base_phys,
948					    pci_resource_len(pdev, 2));
949			release_mem_region (rinfo->fb_base_phys,
950					    pci_resource_len(pdev, 0));
951			kfree (rinfo);
952			return -ENODEV;
953		}
954	}
955
956	rinfo->fb_base = (unsigned long) ioremap (rinfo->fb_base_phys,
957				  		  rinfo->video_ram);
958	if (!rinfo->fb_base) {
959		printk ("radeonfb: cannot map FB\n");
960		iounmap ((void*)rinfo->mmio_base);
961		release_mem_region (rinfo->mmio_base_phys,
962				    pci_resource_len(pdev, 2));
963		release_mem_region (rinfo->fb_base_phys,
964				    pci_resource_len(pdev, 0));
965		kfree (rinfo);
966		return -ENODEV;
967	}
968
969	noaccel = 1;
970
971	/* currcon not yet configured, will be set by first switch */
972	rinfo->currcon = -1;
973
974	/* set all the vital stuff */
975	radeon_set_fbinfo (rinfo);
976
977	/* save current mode regs before we switch into the new one
978	 * so we can restore this upon __exit
979	 */
980	radeon_save_state (rinfo, &rinfo->init_state);
981
982	/* init palette */
983	for (i=0; i<16; i++) {
984		j = color_table[i];
985		rinfo->palette[i].red = default_red[j];
986		rinfo->palette[i].green = default_grn[j];
987		rinfo->palette[i].blue = default_blu[j];
988	}
989
990	pci_set_drvdata(pdev, rinfo);
991	rinfo->next = board_list;
992	board_list = rinfo;
993
994	if (register_framebuffer ((struct fb_info *) rinfo) < 0) {
995		printk ("radeonfb: could not register framebuffer\n");
996		iounmap ((void*)rinfo->fb_base);
997		iounmap ((void*)rinfo->mmio_base);
998		release_mem_region (rinfo->mmio_base_phys,
999				    pci_resource_len(pdev, 2));
1000		release_mem_region (rinfo->fb_base_phys,
1001				    pci_resource_len(pdev, 0));
1002		kfree (rinfo);
1003		return -ENODEV;
1004	}
1005
1006	if (!noaccel) {
1007		/* initialize the engine */
1008		radeon_engine_init (rinfo);
1009	}
1010
1011#ifdef CONFIG_PMAC_BACKLIGHT
1012	if (rinfo->dviDisp_type == MT_LCD)
1013		register_backlight_controller(&radeon_backlight_controller,
1014					      rinfo, "ati");
1015#endif
1016
1017#ifdef CONFIG_PMAC_PBOOK
1018	if (rinfo->dviDisp_type == MT_LCD) {
1019		rinfo->pm_reg = pci_find_capability(pdev, PCI_CAP_ID_PM);
1020		pmu_register_sleep_notifier(&radeon_sleep_notifier);
1021	}
1022#endif
1023
1024	printk ("radeonfb: ATI %s %s %d MB\n", rinfo->name, rinfo->ram_type,
1025		(rinfo->video_ram/(1024*1024)));
1026
1027	if (rinfo->hasCRTC2) {
1028		printk("radeonfb: DVI port %s monitor connected\n",
1029			GET_MON_NAME(rinfo->dviDisp_type));
1030		printk("radeonfb: CRT port %s monitor connected\n",
1031			GET_MON_NAME(rinfo->crtDisp_type));
1032	} else {
1033		printk("radeonfb: CRT port %s monitor connected\n",
1034			GET_MON_NAME(rinfo->crtDisp_type));
1035	}
1036
1037	RTRACE("radeonfb_pci_register END\n");
1038
1039	return 0;
1040}
1041
1042
1043
1044static void __devexit radeonfb_pci_unregister (struct pci_dev *pdev)
1045{
1046        struct radeonfb_info *rinfo = pci_get_drvdata(pdev);
1047
1048        if (!rinfo)
1049                return;
1050
1051	/* restore original state */
1052        radeon_write_mode (rinfo, &rinfo->init_state);
1053
1054        unregister_framebuffer ((struct fb_info *) rinfo);
1055
1056        iounmap ((void*)rinfo->mmio_base);
1057        iounmap ((void*)rinfo->fb_base);
1058
1059	release_mem_region (rinfo->mmio_base_phys,
1060			    pci_resource_len(pdev, 2));
1061	release_mem_region (rinfo->fb_base_phys,
1062			    pci_resource_len(pdev, 0));
1063
1064        kfree (rinfo);
1065}
1066
1067
1068
1069static char *radeon_find_rom(struct radeonfb_info *rinfo)
1070{
1071#if defined(__i386__)
1072        u32  segstart;
1073        char *rom_base;
1074        char *rom;
1075        int  stage;
1076        int  i,j;
1077        char aty_rom_sig[] = "761295520";
1078        char *radeon_sig[] = {
1079          "RG6",
1080          "RADEON"
1081        };
1082
1083        for(segstart=0x000c0000; segstart<0x000f0000; segstart+=0x00001000) {
1084
1085                stage = 1;
1086
1087                rom_base = (char *)ioremap(segstart, 0x1000);
1088
1089                if ((*rom_base == 0x55) && (((*(rom_base + 1)) & 0xff) == 0xaa))
1090                        stage = 2;
1091
1092
1093                if (stage != 2) {
1094                        iounmap(rom_base);
1095                        continue;
1096                }
1097
1098                rom = rom_base;
1099
1100                for (i = 0; (i < 128 - strlen(aty_rom_sig)) && (stage != 3); i++) {
1101                        if (aty_rom_sig[0] == *rom)
1102                                if (strncmp(aty_rom_sig, rom,
1103                                                strlen(aty_rom_sig)) == 0)
1104                                        stage = 3;
1105                        rom++;
1106                }
1107                if (stage != 3) {
1108                        iounmap(rom_base);
1109                        continue;
1110                }
1111                rom = rom_base;
1112
1113                for (i = 0; (i < 512) && (stage != 4); i++) {
1114                    for(j = 0;j < sizeof(radeon_sig)/sizeof(char *);j++) {
1115                        if (radeon_sig[j][0] == *rom)
1116                                if (strncmp(radeon_sig[j], rom,
1117                                            strlen(radeon_sig[j])) == 0) {
1118                                              stage = 4;
1119                                              break;
1120                                            }
1121                    }
1122                        rom++;
1123                }
1124                if (stage != 4) {
1125                        iounmap(rom_base);
1126                        continue;
1127                }
1128
1129                return rom_base;
1130        }
1131#endif
1132        return NULL;
1133}
1134
1135
1136
1137
1138static void radeon_get_pllinfo(struct radeonfb_info *rinfo, char *bios_seg)
1139{
1140        void *bios_header;
1141        void *header_ptr;
1142        u16 bios_header_offset, pll_info_offset;
1143        PLL_BLOCK pll;
1144
1145	if (bios_seg) {
1146	        bios_header = bios_seg + 0x48L;
1147       		header_ptr  = bios_header;
1148
1149        	bios_header_offset = readw(header_ptr);
1150	        bios_header = bios_seg + bios_header_offset;
1151        	bios_header += 0x30;
1152
1153        	header_ptr = bios_header;
1154        	pll_info_offset = readw(header_ptr);
1155        	header_ptr = bios_seg + pll_info_offset;
1156
1157        	memcpy_fromio(&pll, header_ptr, 50);
1158
1159        	rinfo->pll.xclk = (u32)pll.XCLK;
1160        	rinfo->pll.ref_clk = (u32)pll.PCLK_ref_freq;
1161        	rinfo->pll.ref_div = (u32)pll.PCLK_ref_divider;
1162        	rinfo->pll.ppll_min = pll.PCLK_min_freq;
1163        	rinfo->pll.ppll_max = pll.PCLK_max_freq;
1164
1165		printk("radeonfb: ref_clk=%d, ref_div=%d, xclk=%d from BIOS\n",
1166			rinfo->pll.ref_clk, rinfo->pll.ref_div, rinfo->pll.xclk);
1167	} else {
1168#ifdef CONFIG_ALL_PPC
1169		if (radeon_read_OF(rinfo)) {
1170			unsigned int tmp, Nx, M, ref_div, xclk;
1171
1172			tmp = INPLL(M_SPLL_REF_FB_DIV);
1173			ref_div = INPLL(PPLL_REF_DIV) & 0x3ff;
1174
1175			Nx = (tmp & 0xff00) >> 8;
1176			M = (tmp & 0xff);
1177			xclk = ((((2 * Nx * rinfo->pll.ref_clk) + (M)) /
1178				(2 * M)));
1179
1180			rinfo->pll.xclk = xclk;
1181			rinfo->pll.ref_div = ref_div;
1182			rinfo->pll.ppll_min = 12000;
1183			rinfo->pll.ppll_max = 35000;
1184
1185			printk("radeonfb: ref_clk=%d, ref_div=%d, xclk=%d from OF\n",
1186				rinfo->pll.ref_clk, rinfo->pll.ref_div, rinfo->pll.xclk);
1187
1188			return;
1189		}
1190#endif
1191		/* no BIOS or BIOS not found, use defaults */
1192		switch (rinfo->chipset) {
1193			case PCI_DEVICE_ID_RADEON_QW:
1194				rinfo->pll.ppll_max = 35000;
1195				rinfo->pll.ppll_min = 12000;
1196				rinfo->pll.xclk = 23000;
1197				rinfo->pll.ref_div = 12;
1198				rinfo->pll.ref_clk = 2700;
1199				break;
1200			case PCI_DEVICE_ID_RADEON_QL:
1201				rinfo->pll.ppll_max = 35000;
1202				rinfo->pll.ppll_min = 12000;
1203				rinfo->pll.xclk = 27500;
1204				rinfo->pll.ref_div = 12;
1205				rinfo->pll.ref_clk = 2700;
1206				break;
1207			case PCI_DEVICE_ID_RADEON_QD:
1208			case PCI_DEVICE_ID_RADEON_QE:
1209			case PCI_DEVICE_ID_RADEON_QF:
1210			case PCI_DEVICE_ID_RADEON_QG:
1211			default:
1212				rinfo->pll.ppll_max = 35000;
1213				rinfo->pll.ppll_min = 12000;
1214				rinfo->pll.xclk = 16600;
1215				rinfo->pll.ref_div = 67;
1216				rinfo->pll.ref_clk = 2700;
1217				break;
1218		}
1219
1220		printk("radeonfb: ref_clk=%d, ref_div=%d, xclk=%d defaults\n",
1221			rinfo->pll.ref_clk, rinfo->pll.ref_div, rinfo->pll.xclk);
1222	}
1223}
1224
1225
1226static void radeon_get_moninfo (struct radeonfb_info *rinfo)
1227{
1228	unsigned int tmp;
1229
1230	if (force_dfp) {
1231		rinfo->dviDisp_type = MT_DFP;
1232		return;
1233	}
1234
1235	tmp = INREG(RADEON_BIOS_4_SCRATCH);
1236
1237	if (rinfo->hasCRTC2) {
1238		/* primary DVI port */
1239		if (tmp & 0x08)
1240			rinfo->dviDisp_type = MT_DFP;
1241		else if (tmp & 0x4)
1242			rinfo->dviDisp_type = MT_LCD;
1243		else if (tmp & 0x200)
1244			rinfo->dviDisp_type = MT_CRT;
1245		else if (tmp & 0x10)
1246			rinfo->dviDisp_type = MT_CTV;
1247		else if (tmp & 0x20)
1248			rinfo->dviDisp_type = MT_STV;
1249
1250		/* secondary CRT port */
1251		if (tmp & 0x2)
1252			rinfo->crtDisp_type = MT_CRT;
1253		else if (tmp & 0x800)
1254			rinfo->crtDisp_type = MT_DFP;
1255		else if (tmp & 0x400)
1256			rinfo->crtDisp_type = MT_LCD;
1257		else if (tmp & 0x1000)
1258			rinfo->crtDisp_type = MT_CTV;
1259		else if (tmp & 0x2000)
1260			rinfo->crtDisp_type = MT_STV;
1261	} else {
1262		rinfo->dviDisp_type = MT_NONE;
1263
1264		tmp = INREG(FP_GEN_CNTL);
1265
1266		if (tmp & FP_EN_TMDS)
1267			rinfo->crtDisp_type = MT_DFP;
1268		else
1269			rinfo->crtDisp_type = MT_CRT;
1270	}
1271}
1272
1273
1274
1275static void radeon_get_EDID(struct radeonfb_info *rinfo)
1276{
1277#ifdef CONFIG_ALL_PPC
1278	if (!radeon_get_EDID_OF(rinfo))
1279		RTRACE("radeonfb: could not retrieve EDID from OF\n");
1280#else
1281#endif
1282}
1283
1284
1285#ifdef CONFIG_ALL_PPC
1286static int radeon_get_EDID_OF(struct radeonfb_info *rinfo)
1287{
1288	struct device_node *dp;
1289	unsigned char *pedid = NULL;
1290
1291	dp = pci_device_to_OF_node(rinfo->pdev);
1292	pedid = (unsigned char *) get_property(dp, "DFP,EDID", 0);
1293	if (!pedid)
1294		pedid = (unsigned char *) get_property(dp, "LCD,EDID", 0);
1295	if (!pedid)
1296		pedid = (unsigned char *) get_property(dp, "EDID", 0);
1297
1298	if (pedid) {
1299		rinfo->EDID = pedid;
1300		return 1;
1301	} else
1302		return 0;
1303}
1304#endif /* CONFIG_ALL_PPC */
1305
1306
1307static int radeon_dfp_parse_EDID(struct radeonfb_info *rinfo)
1308{
1309	unsigned char *block = rinfo->EDID;
1310
1311	if (!block)
1312		return 0;
1313
1314	/* jump to the detailed timing block section */
1315	block += 54;
1316
1317	rinfo->clock = (block[0] + (block[1] << 8));
1318	rinfo->panel_xres = (block[2] + ((block[4] & 0xf0) << 4));
1319	rinfo->hblank = (block[3] + ((block[4] & 0x0f) << 8));
1320	rinfo->panel_yres = (block[5] + ((block[7] & 0xf0) << 4));
1321	rinfo->vblank = (block[6] + ((block[7] & 0x0f) << 8));
1322	rinfo->hOver_plus = (block[8] + ((block[11] & 0xc0) << 2));
1323	rinfo->hSync_width = (block[9] + ((block[11] & 0x30) << 4));
1324	rinfo->vOver_plus = ((block[10] >> 4) + ((block[11] & 0x0c) << 2));
1325	rinfo->vSync_width = ((block[10] & 0x0f) + ((block[11] & 0x03) << 4));
1326	rinfo->interlaced = ((block[17] & 0x80) >> 7);
1327	rinfo->synct = ((block[17] & 0x18) >> 3);
1328	rinfo->misc = ((block[17] & 0x06) >> 1);
1329	rinfo->hAct_high = rinfo->vAct_high = 0;
1330	if (rinfo->synct == 3) {
1331		if (rinfo->misc & 2)
1332			rinfo->hAct_high = 1;
1333		if (rinfo->misc & 1)
1334			rinfo->vAct_high = 1;
1335	}
1336
1337	printk("radeonfb: detected DFP panel size from EDID: %dx%d\n",
1338		rinfo->panel_xres, rinfo->panel_yres);
1339
1340	rinfo->got_dfpinfo = 1;
1341
1342	return 1;
1343}
1344
1345
1346static void radeon_update_default_var(struct radeonfb_info *rinfo)
1347{
1348	struct fb_var_screeninfo *var = &radeonfb_default_var;
1349
1350	var->xres = rinfo->panel_xres;
1351	var->yres = rinfo->panel_yres;
1352	var->xres_virtual = rinfo->panel_xres;
1353	var->yres_virtual = rinfo->panel_yres;
1354	var->xoffset = var->yoffset = 0;
1355	var->bits_per_pixel = 8;
1356	var->pixclock = 100000000 / rinfo->clock;
1357	var->left_margin = (rinfo->hblank - rinfo->hOver_plus - rinfo->hSync_width);
1358	var->right_margin = rinfo->hOver_plus;
1359	var->upper_margin = (rinfo->vblank - rinfo->vOver_plus - rinfo->vSync_width);
1360	var->lower_margin = rinfo->vOver_plus;
1361	var->hsync_len = rinfo->hSync_width;
1362	var->vsync_len = rinfo->vSync_width;
1363	var->sync = 0;
1364	if (rinfo->synct == 3) {
1365		if (rinfo->hAct_high)
1366			var->sync |= FB_SYNC_HOR_HIGH_ACT;
1367		if (rinfo->vAct_high)
1368			var->sync |= FB_SYNC_VERT_HIGH_ACT;
1369	}
1370
1371	var->vmode = 0;
1372	if (rinfo->interlaced)
1373		var->vmode |= FB_VMODE_INTERLACED;
1374
1375	rinfo->use_default_var = 1;
1376}
1377
1378
1379static int radeon_get_dfpinfo_BIOS(struct radeonfb_info *rinfo)
1380{
1381	char *fpbiosstart, *tmp, *tmp0;
1382	char stmp[30];
1383	int i;
1384
1385	if (!rinfo->bios_seg)
1386		return 0;
1387
1388	if (!(fpbiosstart = rinfo->bios_seg + readw(rinfo->bios_seg + 0x48))) {
1389		printk("radeonfb: Failed to detect DFP panel info using BIOS\n");
1390		return 0;
1391	}
1392
1393	if (!(tmp = rinfo->bios_seg + readw(fpbiosstart + 0x40))) {
1394		printk("radeonfb: Failed to detect DFP panel info using BIOS\n");
1395		return 0;
1396	}
1397
1398	for(i=0; i<24; i++)
1399		stmp[i] = readb(tmp+i+1);
1400	stmp[24] = 0;
1401	printk("radeonfb: panel ID string: %s\n", stmp);
1402	rinfo->panel_xres = readw(tmp + 25);
1403	rinfo->panel_yres = readw(tmp + 27);
1404	printk("radeonfb: detected DFP panel size from BIOS: %dx%d\n",
1405		rinfo->panel_xres, rinfo->panel_yres);
1406
1407	for(i=0; i<20; i++) {
1408		tmp0 = rinfo->bios_seg + readw(tmp+64+i*2);
1409		if (tmp0 == 0)
1410			break;
1411		if ((readw(tmp0) == rinfo->panel_xres) &&
1412		    (readw(tmp0+2) == rinfo->panel_yres)) {
1413			rinfo->hblank = (readw(tmp0+17) - readw(tmp0+19)) * 8;
1414			rinfo->hOver_plus = ((readw(tmp0+21) - readw(tmp0+19) -1) * 8) & 0x7fff;
1415			rinfo->hSync_width = readb(tmp0+23) * 8;
1416			rinfo->vblank = readw(tmp0+24) - readw(tmp0+26);
1417			rinfo->vOver_plus = (readw(tmp0+28) & 0x7ff) - readw(tmp0+26);
1418			rinfo->vSync_width = (readw(tmp0+28) & 0xf800) >> 11;
1419			rinfo->clock = readw(tmp0+9);
1420
1421			rinfo->got_dfpinfo = 1;
1422			return 1;
1423		}
1424	}
1425
1426	return 0;
1427}
1428
1429
1430
1431static int radeon_get_dfpinfo (struct radeonfb_info *rinfo)
1432{
1433	unsigned int tmp;
1434	unsigned short a, b;
1435
1436	if (radeon_get_dfpinfo_BIOS(rinfo))
1437		radeon_update_default_var(rinfo);
1438
1439	if (radeon_dfp_parse_EDID(rinfo))
1440		radeon_update_default_var(rinfo);
1441
1442	if (!rinfo->got_dfpinfo) {
1443		/*
1444		 * it seems all else has failed now and we
1445		 * resort to probing registers for our DFP info
1446	         */
1447		if (panel_yres) {
1448			rinfo->panel_yres = panel_yres;
1449		} else {
1450			tmp = INREG(FP_VERT_STRETCH);
1451			tmp &= 0x00fff000;
1452			rinfo->panel_yres = (unsigned short)(tmp >> 0x0c) + 1;
1453		}
1454
1455		switch (rinfo->panel_yres) {
1456			case 480:
1457				rinfo->panel_xres = 640;
1458				break;
1459			case 600:
1460				rinfo->panel_xres = 800;
1461				break;
1462			case 768:
1463#if defined(__powerpc__)
1464				if (rinfo->dviDisp_type == MT_LCD)
1465					rinfo->panel_xres = 1152;
1466				else
1467#endif
1468				rinfo->panel_xres = 1024;
1469				break;
1470			case 1024:
1471				rinfo->panel_xres = 1280;
1472				break;
1473			case 1050:
1474				rinfo->panel_xres = 1400;
1475				break;
1476			case 1200:
1477				rinfo->panel_xres = 1600;
1478				break;
1479			default:
1480				printk("radeonfb: Failed to detect DFP panel size\n");
1481				return 0;
1482		}
1483
1484		printk("radeonfb: detected DFP panel size from registers: %dx%d\n",
1485			rinfo->panel_xres, rinfo->panel_yres);
1486
1487		tmp = INREG(FP_CRTC_H_TOTAL_DISP);
1488		a = (tmp & FP_CRTC_H_TOTAL_MASK) + 4;
1489		b = (tmp & 0x01ff0000) >> FP_CRTC_H_DISP_SHIFT;
1490		rinfo->hblank = (a - b + 1) * 8;
1491
1492		tmp = INREG(FP_H_SYNC_STRT_WID);
1493		rinfo->hOver_plus = (unsigned short) ((tmp & FP_H_SYNC_STRT_CHAR_MASK) >>
1494					FP_H_SYNC_STRT_CHAR_SHIFT) - b - 1;
1495		rinfo->hOver_plus *= 8;
1496		rinfo->hSync_width = (unsigned short) ((tmp & FP_H_SYNC_WID_MASK) >>
1497					FP_H_SYNC_WID_SHIFT);
1498		rinfo->hSync_width *= 8;
1499		tmp = INREG(FP_CRTC_V_TOTAL_DISP);
1500		a = (tmp & FP_CRTC_V_TOTAL_MASK) + 1;
1501		b = (tmp & FP_CRTC_V_DISP_MASK) >> FP_CRTC_V_DISP_SHIFT;
1502		rinfo->vblank = a - b /* + 24 */ ;
1503
1504		tmp = INREG(FP_V_SYNC_STRT_WID);
1505		rinfo->vOver_plus = (unsigned short) (tmp & FP_V_SYNC_STRT_MASK)
1506					- b + 1;
1507		rinfo->vSync_width = (unsigned short) ((tmp & FP_V_SYNC_WID_MASK) >>
1508					FP_V_SYNC_WID_SHIFT);
1509
1510		return 1;
1511	}
1512
1513	return 1;
1514}
1515
1516
1517#ifdef CONFIG_ALL_PPC
1518static int radeon_read_OF (struct radeonfb_info *rinfo)
1519{
1520	struct device_node *dp;
1521	unsigned int *xtal;
1522
1523	dp = pci_device_to_OF_node(rinfo->pdev);
1524
1525	xtal = (unsigned int *) get_property(dp, "ATY,RefCLK", 0);
1526
1527	rinfo->pll.ref_clk = *xtal / 10;
1528
1529	if (*xtal)
1530		return 1;
1531	else
1532		return 0;
1533}
1534#endif
1535
1536
1537static void radeon_engine_init (struct radeonfb_info *rinfo)
1538{
1539	u32 temp;
1540
1541	/* disable 3D engine */
1542	OUTREG(RB3D_CNTL, 0);
1543
1544	radeon_engine_reset ();
1545
1546	radeon_fifo_wait (1);
1547	OUTREG(DSTCACHE_MODE, 0);
1548
1549	rinfo->pitch = ((rinfo->xres * (rinfo->bpp / 8) + 0x3f)) >> 6;
1550
1551	radeon_fifo_wait (1);
1552	temp = INREG(DEFAULT_PITCH_OFFSET);
1553	OUTREG(DEFAULT_PITCH_OFFSET, ((temp & 0xc0000000) |
1554				      (rinfo->pitch << 0x16)));
1555
1556	radeon_fifo_wait (1);
1557	OUTREGP(DP_DATATYPE, 0, ~HOST_BIG_ENDIAN_EN);
1558
1559	radeon_fifo_wait (1);
1560	OUTREG(DEFAULT_SC_BOTTOM_RIGHT, (DEFAULT_SC_RIGHT_MAX |
1561					 DEFAULT_SC_BOTTOM_MAX));
1562
1563	temp = radeon_get_dstbpp(rinfo->depth);
1564	rinfo->dp_gui_master_cntl = ((temp << 8) | GMC_CLR_CMP_CNTL_DIS);
1565	radeon_fifo_wait (1);
1566	OUTREG(DP_GUI_MASTER_CNTL, (rinfo->dp_gui_master_cntl |
1567				    GMC_BRUSH_SOLID_COLOR |
1568				    GMC_SRC_DATATYPE_COLOR));
1569
1570	radeon_fifo_wait (7);
1571
1572	/* clear line drawing regs */
1573	OUTREG(DST_LINE_START, 0);
1574	OUTREG(DST_LINE_END, 0);
1575
1576	/* set brush color regs */
1577	OUTREG(DP_BRUSH_FRGD_CLR, 0xffffffff);
1578	OUTREG(DP_BRUSH_BKGD_CLR, 0x00000000);
1579
1580	/* set source color regs */
1581	OUTREG(DP_SRC_FRGD_CLR, 0xffffffff);
1582	OUTREG(DP_SRC_BKGD_CLR, 0x00000000);
1583
1584	/* default write mask */
1585	OUTREG(DP_WRITE_MSK, 0xffffffff);
1586
1587	radeon_engine_idle ();
1588}
1589
1590
1591
1592static int __devinit radeon_set_fbinfo (struct radeonfb_info *rinfo)
1593{
1594	struct fb_info *info;
1595
1596	info = &rinfo->info;
1597
1598	strcpy (info->modename, rinfo->name);
1599        info->node = -1;
1600        info->flags = FBINFO_FLAG_DEFAULT;
1601        info->fbops = &radeon_fb_ops;
1602        info->display_fg = NULL;
1603        strncpy (info->fontname, fontname, sizeof (info->fontname));
1604        info->fontname[sizeof (info->fontname) - 1] = 0;
1605        info->changevar = NULL;
1606        info->switch_con = radeonfb_switch;
1607        info->updatevar = radeonfb_updatevar;
1608        info->blank = radeonfb_blank;
1609
1610        if (radeon_init_disp (rinfo) < 0)
1611                return -1;
1612
1613        return 0;
1614}
1615
1616
1617
1618static int __devinit radeon_init_disp (struct radeonfb_info *rinfo)
1619{
1620        struct fb_info *info;
1621        struct display *disp;
1622
1623        info = &rinfo->info;
1624        disp = &rinfo->disp;
1625
1626        disp->var = radeonfb_default_var;
1627#if defined(__powerpc__)
1628	if (rinfo->dviDisp_type == MT_LCD) {
1629		if (mac_vmode_to_var(VMODE_1152_768_60, CMODE_8, &disp->var))
1630			disp->var = radeonfb_default_var;
1631	}
1632#endif
1633
1634	rinfo->depth = var_to_depth(&disp->var);
1635	rinfo->bpp = disp->var.bits_per_pixel;
1636
1637        info->disp = disp;
1638
1639        radeon_set_dispsw (rinfo, disp);
1640
1641	if (noaccel)
1642	        disp->scrollmode = SCROLL_YREDRAW;
1643	else
1644		disp->scrollmode = 0;
1645
1646        rinfo->currcon_display = disp;
1647
1648        if ((radeon_init_disp_var (rinfo)) < 0)
1649                return -1;
1650
1651        return 0;
1652}
1653
1654
1655
1656static int radeon_init_disp_var (struct radeonfb_info *rinfo)
1657{
1658#ifndef MODULE
1659        if (mode_option)
1660                fb_find_mode (&rinfo->disp.var, &rinfo->info, mode_option,
1661                              NULL, 0, NULL, 8);
1662        else
1663#endif
1664#if defined(__powerpc__)
1665	if (rinfo->dviDisp_type == MT_LCD) {
1666		if (mac_vmode_to_var(VMODE_1152_768_60, CMODE_8, &rinfo->disp.var))
1667			rinfo->disp.var = radeonfb_default_var;
1668	}
1669	else
1670#endif
1671	if (rinfo->use_default_var)
1672		/* We will use the modified default far */
1673		rinfo->disp.var = radeonfb_default_var;
1674	else
1675
1676                fb_find_mode (&rinfo->disp.var, &rinfo->info, "640x480-8@60",
1677                              NULL, 0, NULL, 0);
1678
1679	if (noaccel)
1680		rinfo->disp.var.accel_flags &= ~FB_ACCELF_TEXT;
1681	else
1682		rinfo->disp.var.accel_flags |= FB_ACCELF_TEXT;
1683
1684        return 0;
1685}
1686
1687
1688
1689static void radeon_set_dispsw (struct radeonfb_info *rinfo, struct display *disp)
1690
1691{
1692        int accel;
1693
1694        accel = disp->var.accel_flags & FB_ACCELF_TEXT;
1695
1696        disp->dispsw_data = NULL;
1697
1698        disp->screen_base = (char*)rinfo->fb_base;
1699        disp->type = FB_TYPE_PACKED_PIXELS;
1700        disp->type_aux = 0;
1701        disp->ypanstep = 1;
1702        disp->ywrapstep = 0;
1703        disp->can_soft_blank = 1;
1704        disp->inverse = 0;
1705
1706        switch (disp->var.bits_per_pixel) {
1707#ifdef FBCON_HAS_CFB8
1708                case 8:
1709                        disp->dispsw = &fbcon_cfb8;
1710                        disp->visual = FB_VISUAL_PSEUDOCOLOR;
1711                        disp->line_length = disp->var.xres_virtual;
1712                        break;
1713#endif
1714#ifdef FBCON_HAS_CFB16
1715                case 16:
1716                        disp->dispsw = &fbcon_cfb16;
1717                        disp->dispsw_data = &rinfo->con_cmap.cfb16;
1718                        disp->visual = FB_VISUAL_DIRECTCOLOR;
1719                        disp->line_length = disp->var.xres_virtual * 2;
1720                        break;
1721#endif
1722#ifdef FBCON_HAS_CFB32
1723                case 24:
1724                        disp->dispsw = &fbcon_cfb24;
1725                        disp->dispsw_data = &rinfo->con_cmap.cfb24;
1726                        disp->visual = FB_VISUAL_DIRECTCOLOR;
1727                        disp->line_length = disp->var.xres_virtual * 4;
1728                        break;
1729#endif
1730#ifdef FBCON_HAS_CFB32
1731                case 32:
1732                        disp->dispsw = &fbcon_cfb32;
1733                        disp->dispsw_data = &rinfo->con_cmap.cfb32;
1734                        disp->visual = FB_VISUAL_DIRECTCOLOR;
1735                        disp->line_length = disp->var.xres_virtual * 4;
1736                        break;
1737#endif
1738                default:
1739                        printk ("radeonfb: setting fbcon_dummy renderer\n");
1740                        disp->dispsw = &fbcon_dummy;
1741        }
1742
1743        return;
1744}
1745
1746
1747
1748static void do_install_cmap(int con, struct fb_info *info)
1749{
1750        struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
1751
1752        if (con != rinfo->currcon)
1753                return;
1754
1755        if (fb_display[con].cmap.len)
1756                fb_set_cmap(&fb_display[con].cmap, 1, radeon_setcolreg, info);
1757        else {
1758		int size = radeon_get_cmap_len(&fb_display[con].var);
1759                fb_set_cmap(fb_default_cmap(size), 1, radeon_setcolreg, info);
1760        }
1761}
1762
1763
1764
1765static int radeonfb_do_maximize(struct radeonfb_info *rinfo,
1766                                struct fb_var_screeninfo *var,
1767                                struct fb_var_screeninfo *v,
1768                                int nom, int den)
1769{
1770        static struct {
1771                int xres, yres;
1772        } modes[] = {
1773                {1600, 1280},
1774                {1280, 1024},
1775                {1024, 768},
1776                {800, 600},
1777                {640, 480},
1778                {-1, -1}
1779        };
1780        int i;
1781
1782        /* use highest possible virtual resolution */
1783        if (v->xres_virtual == -1 && v->yres_virtual == -1) {
1784                printk("radeonfb: using max available virtual resolution\n");
1785                for (i=0; modes[i].xres != -1; i++) {
1786                        if (modes[i].xres * nom / den * modes[i].yres <
1787                            rinfo->video_ram / 2)
1788                                break;
1789                }
1790                if (modes[i].xres == -1) {
1791                        printk("radeonfb: could not find virtual resolution that fits into video memory!\n");
1792                        return -EINVAL;
1793                }
1794                v->xres_virtual = modes[i].xres;
1795                v->yres_virtual = modes[i].yres;
1796
1797                printk("radeonfb: virtual resolution set to max of %dx%d\n",
1798                        v->xres_virtual, v->yres_virtual);
1799        } else if (v->xres_virtual == -1) {
1800                v->xres_virtual = (rinfo->video_ram * den /
1801                                (nom * v->yres_virtual * 2)) & ~15;
1802        } else if (v->yres_virtual == -1) {
1803                v->xres_virtual = (v->xres_virtual + 15) & ~15;
1804                v->yres_virtual = rinfo->video_ram * den /
1805                        (nom * v->xres_virtual *2);
1806        } else {
1807                if (v->xres_virtual * nom / den * v->yres_virtual >
1808                        rinfo->video_ram) {
1809                        return -EINVAL;
1810                }
1811        }
1812
1813        if (v->xres_virtual * nom / den >= 8192) {
1814                v->xres_virtual = 8192 * den / nom - 16;
1815        }
1816
1817        if (v->xres_virtual < v->xres)
1818                return -EINVAL;
1819
1820        if (v->yres_virtual < v->yres)
1821                return -EINVAL;
1822
1823        return 0;
1824}
1825
1826
1827
1828/*
1829 * fb ops
1830 */
1831
1832static int radeonfb_get_fix (struct fb_fix_screeninfo *fix, int con,
1833                             struct fb_info *info)
1834{
1835        struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
1836        struct display *disp;
1837
1838        disp = (con < 0) ? rinfo->info.disp : &fb_display[con];
1839
1840        memset (fix, 0, sizeof (struct fb_fix_screeninfo));
1841	strcpy (fix->id, rinfo->name);
1842
1843        fix->smem_start = rinfo->fb_base_phys;
1844        fix->smem_len = rinfo->video_ram;
1845
1846        fix->type = disp->type;
1847        fix->type_aux = disp->type_aux;
1848        fix->visual = disp->visual;
1849
1850        fix->xpanstep = 8;
1851        fix->ypanstep = 1;
1852        fix->ywrapstep = 0;
1853
1854        fix->line_length = disp->line_length;
1855
1856        fix->mmio_start = rinfo->mmio_base_phys;
1857        fix->mmio_len = RADEON_REGSIZE;
1858	if (noaccel)
1859	        fix->accel = FB_ACCEL_NONE;
1860	else
1861		fix->accel = FB_ACCEL_ATI_RADEON;
1862
1863        return 0;
1864}
1865
1866
1867
1868static int radeonfb_get_var (struct fb_var_screeninfo *var, int con,
1869                             struct fb_info *info)
1870{
1871        struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
1872
1873        *var = (con < 0) ? rinfo->disp.var : fb_display[con].var;
1874
1875        return 0;
1876}
1877
1878
1879
1880static int radeonfb_set_var (struct fb_var_screeninfo *var, int con,
1881                             struct fb_info *info)
1882{
1883        struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
1884        struct display *disp;
1885        struct fb_var_screeninfo v;
1886        int nom, den, accel;
1887        unsigned chgvar = 0;
1888
1889        disp = (con < 0) ? rinfo->info.disp : &fb_display[con];
1890
1891        accel = var->accel_flags & FB_ACCELF_TEXT;
1892
1893        if (con >= 0) {
1894                chgvar = ((disp->var.xres != var->xres) ||
1895                          (disp->var.yres != var->yres) ||
1896                          (disp->var.xres_virtual != var->xres_virtual) ||
1897                          (disp->var.yres_virtual != var->yres_virtual) ||
1898                          (disp->var.bits_per_pixel != var->bits_per_pixel) ||
1899                          memcmp (&disp->var.red, &var->red, sizeof (var->red)) ||
1900                          memcmp (&disp->var.green, &var->green, sizeof (var->green)) ||
1901                          memcmp (&disp->var.blue, &var->blue, sizeof (var->blue)));
1902        }
1903
1904        memcpy (&v, var, sizeof (v));
1905
1906        switch (v.bits_per_pixel) {
1907		case 0 ... 8:
1908			v.bits_per_pixel = 8;
1909			break;
1910		case 9 ... 16:
1911			v.bits_per_pixel = 16;
1912			break;
1913		case 17 ... 24:
1914			v.bits_per_pixel = 24;
1915			break;
1916		case 25 ... 32:
1917			v.bits_per_pixel = 32;
1918			break;
1919		default:
1920			return -EINVAL;
1921	}
1922
1923	switch (var_to_depth(&v)) {
1924#ifdef FBCON_HAS_CFB8
1925                case 8:
1926                        nom = den = 1;
1927                        disp->line_length = v.xres_virtual;
1928                        disp->visual = FB_VISUAL_PSEUDOCOLOR;
1929                        v.red.offset = v.green.offset = v.blue.offset = 0;
1930                        v.red.length = v.green.length = v.blue.length = 8;
1931                        v.transp.offset = v.transp.length = 0;
1932                        break;
1933#endif
1934
1935#ifdef FBCON_HAS_CFB16
1936		case 15:
1937			nom = 2;
1938			den = 1;
1939			disp->line_length = v.xres_virtual * 2;
1940			disp->visual = FB_VISUAL_DIRECTCOLOR;
1941			v.red.offset = 10;
1942			v.green.offset = 5;
1943			v.red.offset = 0;
1944			v.red.length = v.green.length = v.blue.length = 5;
1945			v.transp.offset = v.transp.length = 0;
1946			break;
1947                case 16:
1948                        nom = 2;
1949                        den = 1;
1950                        disp->line_length = v.xres_virtual * 2;
1951                        disp->visual = FB_VISUAL_DIRECTCOLOR;
1952                        v.red.offset = 11;
1953                        v.green.offset = 5;
1954                        v.blue.offset = 0;
1955                        v.red.length = 5;
1956                        v.green.length = 6;
1957                        v.blue.length = 5;
1958                        v.transp.offset = v.transp.length = 0;
1959                        break;
1960#endif
1961
1962#ifdef FBCON_HAS_CFB24
1963                case 24:
1964                        nom = 4;
1965                        den = 1;
1966                        disp->line_length = v.xres_virtual * 3;
1967                        disp->visual = FB_VISUAL_DIRECTCOLOR;
1968                        v.red.offset = 16;
1969                        v.green.offset = 8;
1970                        v.blue.offset = 0;
1971                        v.red.length = v.blue.length = v.green.length = 8;
1972                        v.transp.offset = v.transp.length = 0;
1973                        break;
1974#endif
1975#ifdef FBCON_HAS_CFB32
1976                case 32:
1977                        nom = 4;
1978                        den = 1;
1979                        disp->line_length = v.xres_virtual * 4;
1980                        disp->visual = FB_VISUAL_DIRECTCOLOR;
1981                        v.red.offset = 16;
1982                        v.green.offset = 8;
1983                        v.blue.offset = 0;
1984                        v.red.length = v.blue.length = v.green.length = 8;
1985                        v.transp.offset = 24;
1986                        v.transp.length = 8;
1987                        break;
1988#endif
1989                default:
1990                        printk ("radeonfb: mode %dx%dx%d rejected, color depth invalid\n",
1991                                var->xres, var->yres, var->bits_per_pixel);
1992                        return -EINVAL;
1993        }
1994
1995        if (radeonfb_do_maximize(rinfo, var, &v, nom, den) < 0)
1996                return -EINVAL;
1997
1998        if (v.xoffset < 0)
1999                v.xoffset = 0;
2000        if (v.yoffset < 0)
2001                v.yoffset = 0;
2002
2003        if (v.xoffset > v.xres_virtual - v.xres)
2004                v.xoffset = v.xres_virtual - v.xres - 1;
2005
2006        if (v.yoffset > v.yres_virtual - v.yres)
2007                v.yoffset = v.yres_virtual - v.yres - 1;
2008
2009        v.red.msb_right = v.green.msb_right = v.blue.msb_right =
2010                          v.transp.offset = v.transp.length =
2011                          v.transp.msb_right = 0;
2012
2013        switch (v.activate & FB_ACTIVATE_MASK) {
2014                case FB_ACTIVATE_TEST:
2015                        return 0;
2016                case FB_ACTIVATE_NXTOPEN:
2017                case FB_ACTIVATE_NOW:
2018                        break;
2019                default:
2020                        return -EINVAL;
2021        }
2022
2023        memcpy (&disp->var, &v, sizeof (v));
2024
2025        if (chgvar) {
2026                radeon_set_dispsw(rinfo, disp);
2027
2028                if (noaccel)
2029                        disp->scrollmode = SCROLL_YREDRAW;
2030                else
2031                        disp->scrollmode = 0;
2032
2033                if (info && info->changevar)
2034                        info->changevar(con);
2035        }
2036
2037        radeon_load_video_mode (rinfo, &v);
2038
2039        do_install_cmap(con, info);
2040
2041        return 0;
2042}
2043
2044
2045
2046static int radeonfb_get_cmap (struct fb_cmap *cmap, int kspc, int con,
2047                              struct fb_info *info)
2048{
2049        struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
2050        struct display *disp;
2051
2052        disp = (con < 0) ? rinfo->info.disp : &fb_display[con];
2053
2054        if (con == rinfo->currcon) {
2055                int rc = fb_get_cmap (cmap, kspc, radeon_getcolreg, info);
2056                return rc;
2057        } else if (disp->cmap.len)
2058                fb_copy_cmap (&disp->cmap, cmap, kspc ? 0 : 2);
2059        else
2060                fb_copy_cmap (fb_default_cmap (radeon_get_cmap_len (&disp->var)),
2061                              cmap, kspc ? 0 : 2);
2062
2063        return 0;
2064}
2065
2066
2067
2068static int radeonfb_set_cmap (struct fb_cmap *cmap, int kspc, int con,
2069                              struct fb_info *info)
2070{
2071        struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
2072        struct display *disp;
2073        unsigned int cmap_len;
2074
2075        disp = (con < 0) ? rinfo->info.disp : &fb_display[con];
2076
2077        cmap_len = radeon_get_cmap_len (&disp->var);
2078        if (disp->cmap.len != cmap_len) {
2079                int err = fb_alloc_cmap (&disp->cmap, cmap_len, 0);
2080                if (err)
2081                        return err;
2082        }
2083
2084        if (con == rinfo->currcon) {
2085                int rc = fb_set_cmap (cmap, kspc, radeon_setcolreg, info);
2086                return rc;
2087        } else
2088                fb_copy_cmap (cmap, &disp->cmap, kspc ? 0 : 1);
2089
2090        return 0;
2091}
2092
2093
2094
2095static int radeonfb_pan_display (struct fb_var_screeninfo *var, int con,
2096                                 struct fb_info *info)
2097{
2098        struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
2099        u32 offset, xoffset, yoffset;
2100
2101        xoffset = (var->xoffset + 7) & ~7;
2102        yoffset = var->yoffset;
2103
2104        if ((xoffset + var->xres > var->xres_virtual) || (yoffset+var->yres >
2105                var->yres_virtual))
2106                return -EINVAL;
2107
2108        offset = ((yoffset * var->xres + xoffset) * var->bits_per_pixel) >> 6;
2109
2110        OUTREG(CRTC_OFFSET, offset);
2111
2112        return 0;
2113}
2114
2115
2116static int radeonfb_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
2117                           unsigned long arg, int con, struct fb_info *info)
2118{
2119	return -EINVAL;
2120}
2121
2122
2123static int radeonfb_switch (int con, struct fb_info *info)
2124{
2125        struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
2126        struct display *disp;
2127        struct fb_cmap *cmap;
2128        int switchmode = 0;
2129
2130        disp = (con < 0) ? rinfo->info.disp : &fb_display[con];
2131
2132        if (rinfo->currcon >= 0) {
2133                cmap = &(rinfo->currcon_display->cmap);
2134                if (cmap->len)
2135                        fb_get_cmap (cmap, 1, radeon_getcolreg, info);
2136        }
2137
2138	switchmode = (con != rinfo->currcon);
2139
2140	rinfo->currcon = con;
2141	rinfo->currcon_display = disp;
2142	disp->var.activate = FB_ACTIVATE_NOW;
2143
2144        if (switchmode) {
2145                radeonfb_set_var (&disp->var, con, info);
2146                radeon_set_dispsw (rinfo, disp);
2147                do_install_cmap(con, info);
2148        }
2149
2150        {
2151		OUTREGP(CRTC_EXT_CNTL, rinfo->hack_crtc_ext_cntl,
2152			CRTC_HSYNC_DIS | CRTC_VSYNC_DIS | CRTC_DISPLAY_DIS);
2153                OUTREG(CRTC_V_SYNC_STRT_WID, rinfo->hack_crtc_v_sync_strt_wid);
2154        }
2155
2156        return 0;
2157}
2158
2159
2160
2161static int radeonfb_updatevar (int con, struct fb_info *info)
2162{
2163        int rc;
2164
2165        rc = (con < 0) ? -EINVAL : radeonfb_pan_display (&fb_display[con].var,
2166                                                         con, info);
2167
2168        return rc;
2169}
2170
2171static void radeonfb_blank (int blank, struct fb_info *info)
2172{
2173        struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
2174        u32 val = INREG(CRTC_EXT_CNTL);
2175	u32 val2 = INREG(LVDS_GEN_CNTL);
2176
2177#ifdef CONFIG_PMAC_BACKLIGHT
2178	if (rinfo->dviDisp_type == MT_LCD && _machine == _MACH_Pmac) {
2179		set_backlight_enable(!blank);
2180		return;
2181	}
2182#endif
2183
2184        /* reset it */
2185        val &= ~(CRTC_DISPLAY_DIS | CRTC_HSYNC_DIS |
2186                 CRTC_VSYNC_DIS);
2187	val2 &= ~(LVDS_DISPLAY_DIS);
2188
2189        switch (blank) {
2190                case VESA_NO_BLANKING:
2191                        break;
2192                case VESA_VSYNC_SUSPEND:
2193                        val |= (CRTC_DISPLAY_DIS | CRTC_VSYNC_DIS);
2194                        break;
2195                case VESA_HSYNC_SUSPEND:
2196                        val |= (CRTC_DISPLAY_DIS | CRTC_HSYNC_DIS);
2197                        break;
2198                case VESA_POWERDOWN:
2199                        val |= (CRTC_DISPLAY_DIS | CRTC_VSYNC_DIS |
2200                                CRTC_HSYNC_DIS);
2201			val2 |= (LVDS_DISPLAY_DIS);
2202                        break;
2203        }
2204
2205	switch (rinfo->dviDisp_type) {
2206		case MT_LCD:
2207			OUTREG(LVDS_GEN_CNTL, val2);
2208			break;
2209		case MT_CRT:
2210		default:
2211		        OUTREG(CRTC_EXT_CNTL, val);
2212			break;
2213	}
2214}
2215
2216
2217static int radeon_get_cmap_len (const struct fb_var_screeninfo *var)
2218{
2219        int rc = 256;            /* reasonable default */
2220
2221        switch (var_to_depth(var)) {
2222                case 15:
2223                        rc = 32;
2224                        break;
2225		case 16:
2226			rc = 64;
2227			break;
2228        }
2229
2230        return rc;
2231}
2232
2233
2234
2235static int radeon_getcolreg (unsigned regno, unsigned *red, unsigned *green,
2236                             unsigned *blue, unsigned *transp,
2237                             struct fb_info *info)
2238{
2239        struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
2240
2241	if (regno > 255)
2242		return 1;
2243
2244 	*red = (rinfo->palette[regno].red<<8) | rinfo->palette[regno].red;
2245    	*green = (rinfo->palette[regno].green<<8) | rinfo->palette[regno].green;
2246    	*blue = (rinfo->palette[regno].blue<<8) | rinfo->palette[regno].blue;
2247    	*transp = 0;
2248
2249	return 0;
2250}
2251
2252
2253
2254static int radeon_setcolreg (unsigned regno, unsigned red, unsigned green,
2255                             unsigned blue, unsigned transp, struct fb_info *info)
2256{
2257        struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
2258	u32 pindex;
2259
2260	if (regno > 255)
2261		return 1;
2262
2263	red >>= 8;
2264	green >>= 8;
2265	blue >>= 8;
2266	rinfo->palette[regno].red = red;
2267	rinfo->palette[regno].green = green;
2268	rinfo->palette[regno].blue = blue;
2269
2270        /* default */
2271        pindex = regno;
2272
2273	if (rinfo->bpp == 16) {
2274		pindex = regno * 8;
2275
2276		if (rinfo->depth == 16 && regno > 63)
2277			return 1;
2278		if (rinfo->depth == 15 && regno > 31)
2279			return 1;
2280
2281		/* For 565, the green component is mixed one order below */
2282		if (rinfo->depth == 16) {
2283	                OUTREG(PALETTE_INDEX, pindex>>1);
2284       	         	OUTREG(PALETTE_DATA, (rinfo->palette[regno>>1].red << 16) |
2285                        	(green << 8) | (rinfo->palette[regno>>1].blue));
2286                	green = rinfo->palette[regno<<1].green;
2287        	}
2288	}
2289
2290	if (rinfo->depth != 16 || regno < 32) {
2291		OUTREG(PALETTE_INDEX, pindex);
2292		OUTREG(PALETTE_DATA, (red << 16) | (green << 8) | blue);
2293	}
2294
2295 	if (regno < 16) {
2296        	switch (rinfo->depth) {
2297#ifdef FBCON_HAS_CFB16
2298		        case 15:
2299        			rinfo->con_cmap.cfb16[regno] = (regno << 10) | (regno << 5) |
2300				                       	 	  regno;
2301			        break;
2302		        case 16:
2303        			rinfo->con_cmap.cfb16[regno] = (regno << 11) | (regno << 5) |
2304				                       	 	  regno;
2305			        break;
2306#endif
2307#ifdef FBCON_HAS_CFB24
2308                        case 24:
2309                                rinfo->con_cmap.cfb24[regno] = (regno << 16) | (regno << 8) | regno;
2310                                break;
2311#endif
2312#ifdef FBCON_HAS_CFB32
2313	        	case 32: {
2314            			u32 i;
2315
2316  		       		i = (regno << 8) | regno;
2317            			rinfo->con_cmap.cfb32[regno] = (i << 16) | i;
2318		        	break;
2319        		}
2320#endif
2321		}
2322        }
2323	return 0;
2324}
2325
2326
2327
2328static void radeon_save_state (struct radeonfb_info *rinfo,
2329                               struct radeon_regs *save)
2330{
2331	/* CRTC regs */
2332	save->crtc_gen_cntl = INREG(CRTC_GEN_CNTL);
2333	save->crtc_ext_cntl = INREG(CRTC_EXT_CNTL);
2334	save->dac_cntl = INREG(DAC_CNTL);
2335        save->crtc_h_total_disp = INREG(CRTC_H_TOTAL_DISP);
2336        save->crtc_h_sync_strt_wid = INREG(CRTC_H_SYNC_STRT_WID);
2337        save->crtc_v_total_disp = INREG(CRTC_V_TOTAL_DISP);
2338        save->crtc_v_sync_strt_wid = INREG(CRTC_V_SYNC_STRT_WID);
2339	save->crtc_pitch = INREG(CRTC_PITCH);
2340#if defined(__BIG_ENDIAN)
2341	save->surface_cntl = INREG(SURFACE_CNTL);
2342#endif
2343
2344	/* FP regs */
2345	save->fp_crtc_h_total_disp = INREG(FP_CRTC_H_TOTAL_DISP);
2346	save->fp_crtc_v_total_disp = INREG(FP_CRTC_V_TOTAL_DISP);
2347	save->fp_gen_cntl = INREG(FP_GEN_CNTL);
2348	save->fp_h_sync_strt_wid = INREG(FP_H_SYNC_STRT_WID);
2349	save->fp_horz_stretch = INREG(FP_HORZ_STRETCH);
2350	save->fp_v_sync_strt_wid = INREG(FP_V_SYNC_STRT_WID);
2351	save->fp_vert_stretch = INREG(FP_VERT_STRETCH);
2352	save->lvds_gen_cntl = INREG(LVDS_GEN_CNTL);
2353	save->lvds_pll_cntl = INREG(LVDS_PLL_CNTL);
2354	save->tmds_crc = INREG(TMDS_CRC);
2355	save->tmds_transmitter_cntl = INREG(TMDS_TRANSMITTER_CNTL);
2356}
2357
2358
2359
2360static void radeon_load_video_mode (struct radeonfb_info *rinfo,
2361                                    struct fb_var_screeninfo *mode)
2362{
2363	struct radeon_regs newmode;
2364	int hTotal, vTotal, hSyncStart, hSyncEnd,
2365	    hSyncPol, vSyncStart, vSyncEnd, vSyncPol, cSync;
2366	u8 hsync_adj_tab[] = {0, 0x12, 9, 9, 6, 5};
2367	u8 hsync_fudge_fp[] = {2, 2, 0, 0, 5, 5};
2368	u32 dotClock = 1000000000 / mode->pixclock,
2369	    sync, h_sync_pol, v_sync_pol;
2370	int freq = dotClock / 10;  /* x 100 */
2371        int xclk_freq, vclk_freq, xclk_per_trans, xclk_per_trans_precise;
2372        int useable_precision, roff, ron;
2373        int min_bits, format = 0;
2374	int hsync_start, hsync_fudge, bytpp, hsync_wid, vsync_wid;
2375	int primary_mon = PRIMARY_MONITOR(rinfo);
2376	int depth = var_to_depth(mode);
2377
2378	rinfo->xres = mode->xres;
2379	rinfo->yres = mode->yres;
2380	rinfo->pixclock = mode->pixclock;
2381
2382	hSyncStart = mode->xres + mode->right_margin;
2383	hSyncEnd = hSyncStart + mode->hsync_len;
2384	hTotal = hSyncEnd + mode->left_margin;
2385
2386	vSyncStart = mode->yres + mode->lower_margin;
2387	vSyncEnd = vSyncStart + mode->vsync_len;
2388	vTotal = vSyncEnd + mode->upper_margin;
2389
2390	if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) {
2391		if (rinfo->panel_xres < mode->xres)
2392			rinfo->xres = mode->xres = rinfo->panel_xres;
2393		if (rinfo->panel_yres < mode->yres)
2394			rinfo->yres = mode->yres = rinfo->panel_yres;
2395
2396		hTotal = mode->xres + rinfo->hblank;
2397		hSyncStart = mode->xres + rinfo->hOver_plus;
2398		hSyncEnd = hSyncStart + rinfo->hSync_width;
2399
2400		vTotal = mode->yres + rinfo->vblank;
2401		vSyncStart = mode->yres + rinfo->vOver_plus;
2402		vSyncEnd = vSyncStart + rinfo->vSync_width;
2403	}
2404
2405	sync = mode->sync;
2406	h_sync_pol = sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1;
2407	v_sync_pol = sync & FB_SYNC_VERT_HIGH_ACT ? 0 : 1;
2408
2409	RTRACE("hStart = %d, hEnd = %d, hTotal = %d\n",
2410		hSyncStart, hSyncEnd, hTotal);
2411	RTRACE("vStart = %d, vEnd = %d, vTotal = %d\n",
2412		vSyncStart, vSyncEnd, vTotal);
2413
2414	hsync_wid = (hSyncEnd - hSyncStart) / 8;
2415	vsync_wid = vSyncEnd - vSyncStart;
2416	if (hsync_wid == 0)
2417		hsync_wid = 1;
2418	else if (hsync_wid > 0x3f)	/* max */
2419		hsync_wid = 0x3f;
2420
2421	if (vsync_wid == 0)
2422		vsync_wid = 1;
2423	else if (vsync_wid > 0x1f)	/* max */
2424		vsync_wid = 0x1f;
2425
2426	hSyncPol = mode->sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1;
2427	vSyncPol = mode->sync & FB_SYNC_VERT_HIGH_ACT ? 0 : 1;
2428
2429	cSync = mode->sync & FB_SYNC_COMP_HIGH_ACT ? (1 << 4) : 0;
2430
2431	format = radeon_get_dstbpp(depth);
2432	bytpp = mode->bits_per_pixel >> 3;
2433
2434	if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD))
2435		hsync_fudge = hsync_fudge_fp[format-1];
2436	else
2437		hsync_fudge = hsync_adj_tab[format-1];
2438
2439	hsync_start = hSyncStart - 8 + hsync_fudge;
2440
2441	newmode.crtc_gen_cntl = CRTC_EXT_DISP_EN | CRTC_EN |
2442				(format << 8);
2443
2444	if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) {
2445		newmode.crtc_ext_cntl = VGA_ATI_LINEAR | XCRT_CNT_EN;
2446		newmode.crtc_gen_cntl &= ~(CRTC_DBL_SCAN_EN |
2447					   CRTC_INTERLACE_EN);
2448	} else {
2449		newmode.crtc_ext_cntl = VGA_ATI_LINEAR | XCRT_CNT_EN |
2450					CRTC_CRT_ON;
2451	}
2452
2453	newmode.dac_cntl = /* INREG(DAC_CNTL) | */ DAC_MASK_ALL | DAC_VGA_ADR_EN |
2454			   DAC_8BIT_EN;
2455
2456	newmode.crtc_h_total_disp = ((((hTotal / 8) - 1) & 0x3ff) |
2457				     (((mode->xres / 8) - 1) << 16));
2458
2459	newmode.crtc_h_sync_strt_wid = ((hsync_start & 0x1fff) |
2460					(hsync_wid << 16) | (h_sync_pol << 23));
2461
2462	newmode.crtc_v_total_disp = ((vTotal - 1) & 0xffff) |
2463				    ((mode->yres - 1) << 16);
2464
2465	newmode.crtc_v_sync_strt_wid = (((vSyncStart - 1) & 0xfff) |
2466					 (vsync_wid << 16) | (v_sync_pol  << 23));
2467
2468	newmode.crtc_pitch = (mode->xres >> 3);
2469	newmode.crtc_pitch |= (newmode.crtc_pitch << 16);
2470
2471#if defined(__BIG_ENDIAN)
2472	newmode.surface_cntl = SURF_TRANSLATION_DIS;
2473	switch (mode->bits_per_pixel) {
2474		case 16:
2475			newmode.surface_cntl |= NONSURF_AP0_SWP_16BPP;
2476			break;
2477		case 24:
2478		case 32:
2479			newmode.surface_cntl |= NONSURF_AP0_SWP_32BPP;
2480			break;
2481	}
2482#endif
2483
2484	rinfo->pitch = ((mode->xres * ((mode->bits_per_pixel + 1) / 8) + 0x3f)
2485			& ~(0x3f)) / 64;
2486
2487	RTRACE("h_total_disp = 0x%x\t   hsync_strt_wid = 0x%x\n",
2488		newmode.crtc_h_total_disp, newmode.crtc_h_sync_strt_wid);
2489	RTRACE("v_total_disp = 0x%x\t   vsync_strt_wid = 0x%x\n",
2490		newmode.crtc_v_total_disp, newmode.crtc_v_sync_strt_wid);
2491
2492	newmode.xres = mode->xres;
2493	newmode.yres = mode->yres;
2494
2495	rinfo->bpp = mode->bits_per_pixel;
2496	rinfo->depth = depth;
2497
2498	rinfo->hack_crtc_ext_cntl = newmode.crtc_ext_cntl;
2499	rinfo->hack_crtc_v_sync_strt_wid = newmode.crtc_v_sync_strt_wid;
2500
2501	if (freq > rinfo->pll.ppll_max)
2502		freq = rinfo->pll.ppll_max;
2503	if (freq*12 < rinfo->pll.ppll_min)
2504		freq = rinfo->pll.ppll_min / 12;
2505
2506	{
2507		struct {
2508			int divider;
2509			int bitvalue;
2510		} *post_div,
2511		  post_divs[] = {
2512			{ 1,  0 },
2513			{ 2,  1 },
2514			{ 4,  2 },
2515			{ 8,  3 },
2516			{ 3,  4 },
2517			{ 16, 5 },
2518			{ 6,  6 },
2519			{ 12, 7 },
2520			{ 0,  0 },
2521		};
2522
2523		for (post_div = &post_divs[0]; post_div->divider; ++post_div) {
2524			rinfo->pll_output_freq = post_div->divider * freq;
2525			if (rinfo->pll_output_freq >= rinfo->pll.ppll_min  &&
2526			    rinfo->pll_output_freq <= rinfo->pll.ppll_max)
2527				break;
2528		}
2529
2530		rinfo->post_div = post_div->divider;
2531		rinfo->fb_div = round_div(rinfo->pll.ref_div*rinfo->pll_output_freq,
2532					  rinfo->pll.ref_clk);
2533		newmode.ppll_ref_div = rinfo->pll.ref_div;
2534		newmode.ppll_div_3 = rinfo->fb_div | (post_div->bitvalue << 16);
2535	}
2536
2537	RTRACE("post div = 0x%x\n", rinfo->post_div);
2538	RTRACE("fb_div = 0x%x\n", rinfo->fb_div);
2539	RTRACE("ppll_div_3 = 0x%x\n", newmode.ppll_div_3);
2540
2541	/* DDA */
2542	vclk_freq = round_div(rinfo->pll.ref_clk * rinfo->fb_div,
2543			      rinfo->pll.ref_div * rinfo->post_div);
2544	xclk_freq = rinfo->pll.xclk;
2545
2546	xclk_per_trans = round_div(xclk_freq * 128, vclk_freq * mode->bits_per_pixel);
2547
2548	min_bits = min_bits_req(xclk_per_trans);
2549	useable_precision = min_bits + 1;
2550
2551	xclk_per_trans_precise = round_div((xclk_freq * 128) << (11 - useable_precision),
2552					   vclk_freq * mode->bits_per_pixel);
2553
2554	ron = (4 * rinfo->ram.mb + 3 * _max(rinfo->ram.trcd - 2, 0) +
2555	       2 * rinfo->ram.trp + rinfo->ram.twr + rinfo->ram.cl + rinfo->ram.tr2w +
2556	       xclk_per_trans) << (11 - useable_precision);
2557	roff = xclk_per_trans_precise * (32 - 4);
2558
2559	RTRACE("ron = %d, roff = %d\n", ron, roff);
2560	RTRACE("vclk_freq = %d, per = %d\n", vclk_freq, xclk_per_trans_precise);
2561
2562	if ((ron + rinfo->ram.rloop) >= roff) {
2563		printk("radeonfb: error ron out of range\n");
2564		return;
2565	}
2566
2567	newmode.dda_config = (xclk_per_trans_precise |
2568			      (useable_precision << 16) |
2569			      (rinfo->ram.rloop << 20));
2570	newmode.dda_on_off = (ron << 16) | roff;
2571
2572	if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) {
2573		unsigned int hRatio, vRatio;
2574
2575		if (mode->xres > rinfo->panel_xres)
2576			mode->xres = rinfo->panel_xres;
2577		if (mode->yres > rinfo->panel_yres)
2578			mode->yres = rinfo->panel_yres;
2579
2580		newmode.fp_horz_stretch = (((rinfo->panel_xres / 8) - 1)
2581					   << HORZ_PANEL_SHIFT);
2582		newmode.fp_vert_stretch = ((rinfo->panel_yres - 1)
2583					   << VERT_PANEL_SHIFT);
2584
2585		if (mode->xres != rinfo->panel_xres) {
2586			hRatio = round_div(mode->xres * HORZ_STRETCH_RATIO_MAX,
2587					   rinfo->panel_xres);
2588			newmode.fp_horz_stretch = (((((unsigned long)hRatio) & HORZ_STRETCH_RATIO_MASK)) |
2589						   (newmode.fp_horz_stretch &
2590						    (HORZ_PANEL_SIZE | HORZ_FP_LOOP_STRETCH |
2591						     HORZ_AUTO_RATIO_INC)));
2592			newmode.fp_horz_stretch |= (HORZ_STRETCH_BLEND |
2593						    HORZ_STRETCH_ENABLE);
2594		}
2595		newmode.fp_horz_stretch &= ~HORZ_AUTO_RATIO;
2596
2597		if (mode->yres != rinfo->panel_yres) {
2598				vRatio = round_div(mode->yres * VERT_STRETCH_RATIO_MAX,
2599						   rinfo->panel_yres);
2600				newmode.fp_vert_stretch = (((((unsigned long)vRatio) & VERT_STRETCH_RATIO_MASK)) |
2601							   (newmode.fp_vert_stretch &
2602							   (VERT_PANEL_SIZE | VERT_STRETCH_RESERVED)));
2603				newmode.fp_vert_stretch |= (VERT_STRETCH_BLEND |
2604							    VERT_STRETCH_ENABLE);
2605		}
2606		newmode.fp_vert_stretch &= ~VERT_AUTO_RATIO_EN;
2607
2608		newmode.fp_gen_cntl = (rinfo->init_state.fp_gen_cntl & (u32)
2609				       ~(FP_SEL_CRTC2 |
2610					 FP_RMX_HVSYNC_CONTROL_EN |
2611					 FP_DFP_SYNC_SEL |
2612					 FP_CRT_SYNC_SEL |
2613					 FP_CRTC_LOCK_8DOT |
2614					 FP_USE_SHADOW_EN |
2615					 FP_CRTC_USE_SHADOW_VEND |
2616					 FP_CRT_SYNC_ALT));
2617
2618		newmode.fp_gen_cntl |= (FP_CRTC_DONT_SHADOW_VPAR |
2619					FP_CRTC_DONT_SHADOW_HEND);
2620
2621		newmode.lvds_gen_cntl = rinfo->init_state.lvds_gen_cntl;
2622		newmode.lvds_pll_cntl = rinfo->init_state.lvds_pll_cntl;
2623		newmode.tmds_crc = rinfo->init_state.tmds_crc;
2624		newmode.tmds_transmitter_cntl = rinfo->init_state.tmds_transmitter_cntl;
2625
2626		if (primary_mon == MT_LCD) {
2627			newmode.lvds_gen_cntl |= (LVDS_ON | LVDS_BLON);
2628			newmode.fp_gen_cntl &= ~(FP_FPON | FP_TMDS_EN);
2629		} else {
2630			/* DFP */
2631			newmode.fp_gen_cntl |= (FP_FPON | FP_TMDS_EN);
2632			newmode.tmds_transmitter_cntl = (TMDS_RAN_PAT_RST |
2633							 ICHCSEL) & ~(TMDS_PLLRST);
2634			newmode.crtc_ext_cntl &= ~CRTC_CRT_ON;
2635		}
2636
2637		newmode.fp_crtc_h_total_disp = newmode.crtc_h_total_disp;
2638		newmode.fp_crtc_v_total_disp = newmode.crtc_v_total_disp;
2639		newmode.fp_h_sync_strt_wid = newmode.crtc_h_sync_strt_wid;
2640		newmode.fp_v_sync_strt_wid = newmode.crtc_v_sync_strt_wid;
2641	}
2642
2643	/* do it! */
2644	radeon_write_mode (rinfo, &newmode);
2645
2646#if defined(CONFIG_BOOTX_TEXT)
2647	btext_update_display(rinfo->fb_base_phys, mode->xres, mode->yres,
2648			     rinfo->depth, rinfo->pitch*64);
2649#endif
2650
2651	return;
2652}
2653
2654
2655static void radeon_write_mode (struct radeonfb_info *rinfo,
2656                               struct radeon_regs *mode)
2657{
2658	int i;
2659	int primary_mon = PRIMARY_MONITOR(rinfo);
2660
2661	/* blank screen */
2662	OUTREGP(CRTC_EXT_CNTL, CRTC_DISPLAY_DIS | CRTC_VSYNC_DIS | CRTC_HSYNC_DIS,
2663		~(CRTC_DISPLAY_DIS | CRTC_VSYNC_DIS | CRTC_HSYNC_DIS));
2664
2665	for (i=0; i<9; i++)
2666		OUTREG(common_regs[i].reg, common_regs[i].val);
2667
2668	OUTREG(CRTC_GEN_CNTL, mode->crtc_gen_cntl);
2669	OUTREGP(CRTC_EXT_CNTL, mode->crtc_ext_cntl,
2670		CRTC_HSYNC_DIS | CRTC_VSYNC_DIS | CRTC_DISPLAY_DIS);
2671	OUTREGP(DAC_CNTL, mode->dac_cntl, DAC_RANGE_CNTL | DAC_BLANKING);
2672	OUTREG(CRTC_H_TOTAL_DISP, mode->crtc_h_total_disp);
2673	OUTREG(CRTC_H_SYNC_STRT_WID, mode->crtc_h_sync_strt_wid);
2674	OUTREG(CRTC_V_TOTAL_DISP, mode->crtc_v_total_disp);
2675	OUTREG(CRTC_V_SYNC_STRT_WID, mode->crtc_v_sync_strt_wid);
2676	OUTREG(CRTC_OFFSET, 0);
2677	OUTREG(CRTC_OFFSET_CNTL, 0);
2678	OUTREG(CRTC_PITCH, mode->crtc_pitch);
2679
2680#if defined(__BIG_ENDIAN)
2681	OUTREG(SURFACE_CNTL, mode->surface_cntl);
2682#endif
2683
2684	while ((INREG(CLOCK_CNTL_INDEX) & PPLL_DIV_SEL_MASK) !=
2685	       PPLL_DIV_SEL_MASK) {
2686		OUTREGP(CLOCK_CNTL_INDEX, PPLL_DIV_SEL_MASK, 0xffff);
2687	}
2688
2689	OUTPLLP(PPLL_CNTL, PPLL_RESET, 0xffff);
2690
2691	while ((INPLL(PPLL_REF_DIV) & PPLL_REF_DIV_MASK) !=
2692	       (mode->ppll_ref_div & PPLL_REF_DIV_MASK)) {
2693		OUTPLLP(PPLL_REF_DIV, mode->ppll_ref_div, ~PPLL_REF_DIV_MASK);
2694	}
2695
2696	while ((INPLL(PPLL_DIV_3) & PPLL_FB3_DIV_MASK) !=
2697	       (mode->ppll_div_3 & PPLL_FB3_DIV_MASK)) {
2698		OUTPLLP(PPLL_DIV_3, mode->ppll_div_3, ~PPLL_FB3_DIV_MASK);
2699	}
2700
2701	while ((INPLL(PPLL_DIV_3) & PPLL_POST3_DIV_MASK) !=
2702	       (mode->ppll_div_3 & PPLL_POST3_DIV_MASK)) {
2703		OUTPLLP(PPLL_DIV_3, mode->ppll_div_3, ~PPLL_POST3_DIV_MASK);
2704	}
2705
2706	OUTPLL(HTOTAL_CNTL, 0);
2707
2708	OUTPLLP(PPLL_CNTL, 0, ~PPLL_RESET);
2709
2710	OUTREG(DDA_CONFIG, mode->dda_config);
2711	OUTREG(DDA_ON_OFF, mode->dda_on_off);
2712
2713	if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) {
2714		OUTREG(FP_CRTC_H_TOTAL_DISP, mode->fp_crtc_h_total_disp);
2715		OUTREG(FP_CRTC_V_TOTAL_DISP, mode->fp_crtc_v_total_disp);
2716		OUTREG(FP_H_SYNC_STRT_WID, mode->fp_h_sync_strt_wid);
2717		OUTREG(FP_V_SYNC_STRT_WID, mode->fp_v_sync_strt_wid);
2718		OUTREG(FP_HORZ_STRETCH, mode->fp_horz_stretch);
2719		OUTREG(FP_VERT_STRETCH, mode->fp_vert_stretch);
2720		OUTREG(FP_GEN_CNTL, mode->fp_gen_cntl);
2721		OUTREG(TMDS_CRC, mode->tmds_crc);
2722		OUTREG(TMDS_TRANSMITTER_CNTL, mode->tmds_transmitter_cntl);
2723
2724		if (primary_mon == MT_LCD) {
2725			unsigned int tmp = INREG(LVDS_GEN_CNTL);
2726
2727			mode->lvds_gen_cntl &= ~LVDS_STATE_MASK;
2728			mode->lvds_gen_cntl |= (rinfo->init_state.lvds_gen_cntl & LVDS_STATE_MASK);
2729
2730			if ((tmp & (LVDS_ON | LVDS_BLON)) ==
2731			    (mode->lvds_gen_cntl & (LVDS_ON | LVDS_BLON))) {
2732				OUTREG(LVDS_GEN_CNTL, mode->lvds_gen_cntl);
2733			} else {
2734				if (mode->lvds_gen_cntl & (LVDS_ON | LVDS_BLON)) {
2735					udelay(1000);
2736					OUTREG(LVDS_GEN_CNTL, mode->lvds_gen_cntl);
2737				} else {
2738					OUTREG(LVDS_GEN_CNTL, mode->lvds_gen_cntl |
2739					       LVDS_BLON);
2740					udelay(1000);
2741					OUTREG(LVDS_GEN_CNTL, mode->lvds_gen_cntl);
2742				}
2743			}
2744		}
2745	}
2746
2747	/* unblank screen */
2748	OUTREG8(CRTC_EXT_CNTL + 1, 0);
2749
2750	return;
2751}
2752
2753
2754#ifdef CONFIG_PMAC_BACKLIGHT
2755
2756static int backlight_conv[] = {
2757	0xff, 0xc0, 0xb5, 0xaa, 0x9f, 0x94, 0x89, 0x7e,
2758	0x73, 0x68, 0x5d, 0x52, 0x47, 0x3c, 0x31, 0x24
2759};
2760
2761#define BACKLIGHT_LVDS_OFF
2762#undef BACKLIGHT_DAC_OFF
2763
2764/* We turn off the LCD completely instead of just dimming the backlight.
2765 * This provides some greater power saving and the display is useless
2766 * without backlight anyway.
2767 */
2768
2769static int radeon_set_backlight_enable(int on, int level, void *data)
2770{
2771	struct radeonfb_info *rinfo = (struct radeonfb_info *)data;
2772	unsigned int lvds_gen_cntl = INREG(LVDS_GEN_CNTL);
2773
2774	lvds_gen_cntl |= (LVDS_BL_MOD_EN | LVDS_BLON);
2775	if (on && (level > BACKLIGHT_OFF)) {
2776		lvds_gen_cntl |= LVDS_DIGON;
2777		if (!lvds_gen_cntl & LVDS_ON) {
2778			lvds_gen_cntl &= ~LVDS_BLON;
2779			OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl);
2780			(void)INREG(LVDS_GEN_CNTL);
2781			mdelay(10);
2782			lvds_gen_cntl |= LVDS_BLON;
2783			OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl);
2784		}
2785		lvds_gen_cntl &= ~LVDS_BL_MOD_LEVEL_MASK;
2786		lvds_gen_cntl |= (backlight_conv[level] <<
2787				  LVDS_BL_MOD_LEVEL_SHIFT);
2788		lvds_gen_cntl |= (LVDS_ON | LVDS_EN);
2789		lvds_gen_cntl &= ~LVDS_DISPLAY_DIS;
2790	} else {
2791		lvds_gen_cntl &= ~LVDS_BL_MOD_LEVEL_MASK;
2792		lvds_gen_cntl |= (backlight_conv[0] <<
2793				  LVDS_BL_MOD_LEVEL_SHIFT);
2794		lvds_gen_cntl |= LVDS_DISPLAY_DIS;
2795		OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl);
2796		udelay(10);
2797		lvds_gen_cntl &= ~(LVDS_ON | LVDS_EN | LVDS_BLON | LVDS_DIGON);
2798	}
2799
2800	OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl);
2801	rinfo->init_state.lvds_gen_cntl &= ~LVDS_STATE_MASK;
2802	rinfo->init_state.lvds_gen_cntl |= (lvds_gen_cntl & LVDS_STATE_MASK);
2803
2804	return 0;
2805}
2806
2807static int radeon_set_backlight_level(int level, void *data)
2808{
2809	return radeon_set_backlight_enable(1, level, data);
2810}
2811#endif /* CONFIG_PMAC_BACKLIGHT */
2812
2813
2814#ifdef CONFIG_PMAC_PBOOK
2815static void radeon_set_suspend(struct radeonfb_info *rinfo, int suspend)
2816{
2817	u16 pwr_cmd;
2818
2819	if (!rinfo->pm_reg)
2820		return;
2821
2822	/* Set the chip into appropriate suspend mode (we use D2,
2823	 * D3 would require a compete re-initialization of the chip,
2824	 * including PCI config registers, clocks, AGP conf, ...)
2825	 */
2826	if (suspend) {
2827		/* Make sure CRTC2 is reset.  Remove that the day
2828		 * we decide to actually use CRTC2 and replace it with
2829		 * real code for disabling the CRTC2 output during sleep.
2830		 */
2831
2832		pci_read_config_word(rinfo->pdev, rinfo->pm_reg+PCI_PM_CTRL,
2833				     &pwr_cmd);
2834
2835		/* Switch PCI power managment to D2 */
2836		pci_write_config_word(rinfo->pdev, rinfo->pm_reg+PCI_PM_CTRL,
2837				      (pwr_cmd & ~PCI_PM_CTRL_STATE_MASK)
2838				      | 2);
2839		pci_read_config_word(rinfo->pdev, rinfo->pm_reg+PCI_PM_CTRL,
2840				     &pwr_cmd);
2841	} else {
2842		/* Switch back PCI powermanagment to D0 */
2843		mdelay(100);
2844		pci_write_config_word(rinfo->pdev, rinfo->pm_reg+PCI_PM_CTRL, 0);
2845		mdelay(100);
2846		pci_read_config_word(rinfo->pdev, rinfo->pm_reg+PCI_PM_CTRL,
2847				     &pwr_cmd);
2848		mdelay(100);
2849	}
2850}
2851
2852/*
2853 * Save the contents of the framebuffer when we go to sleep,
2854 * and restore it when we wake up again.
2855 */
2856
2857int radeon_sleep_notify(struct pmu_sleep_notifier *self, int when)
2858{
2859	struct radeonfb_info *rinfo;
2860
2861	for (rinfo = board_list; rinfo != NULL; rinfo = rinfo->next) {
2862		struct fb_fix_screeninfo fix;
2863		int nb;
2864
2865		switch (rinfo->chipset) {
2866			case PCI_DEVICE_ID_RADEON_LW:
2867			case PCI_DEVICE_ID_RADEON_LY:
2868			case PCI_DEVICE_ID_RADEON_LZ:
2869			case PCI_DEVICE_ID_RADEON_PM:
2870				break;
2871			default:
2872				return PBOOK_SLEEP_REFUSE;
2873		}
2874
2875		radeonfb_get_fix(&fix, fg_console, (struct fb_info *)rinfo);
2876		nb = fb_display[fg_console].var.yres * fix.line_length;
2877
2878		switch (when) {
2879			case PBOOK_SLEEP_REQUEST:
2880				break;
2881			case PBOOK_SLEEP_REJECT:
2882				break;
2883			case PBOOK_SLEEP_NOW:
2884				radeon_engine_idle();
2885				radeon_engine_reset();
2886				radeon_engine_idle();
2887
2888
2889				/* Blank display and LCD */
2890				radeonfb_blank(VESA_POWERDOWN+1,
2891					       (struct fb_info *)rinfo);
2892
2893				/* Sleep */
2894				radeon_set_suspend(rinfo, 1);
2895
2896				break;
2897			case PBOOK_WAKE:
2898				/* Wakeup */
2899				radeon_set_suspend(rinfo, 0);
2900
2901				radeon_engine_reset();
2902				if (!noaccel) {
2903					radeon_engine_init(rinfo);
2904					radeon_engine_reset();
2905				}
2906
2907
2908				if (rinfo->currcon_display) {
2909					radeonfb_set_var(&rinfo->currcon_display->var, rinfo->currcon,
2910							 (struct fb_info *) rinfo);
2911					radeon_set_dispsw(rinfo, rinfo->currcon_display);
2912					do_install_cmap(rinfo->currcon,
2913							(struct fb_info *)rinfo);
2914				}
2915
2916				radeonfb_blank(0, (struct fb_info *)rinfo);
2917				break;
2918		}
2919	}
2920
2921	return PBOOK_SLEEP_OK;
2922}
2923
2924#endif /* CONFIG_PMAC_PBOOK */
2925
2926/*
2927 * text console acceleration
2928 */
2929
2930
2931static void fbcon_radeon_bmove(struct display *p, int srcy, int srcx,
2932			       int dsty, int dstx, int height, int width)
2933{
2934	struct radeonfb_info *rinfo = (struct radeonfb_info *)(p->fb_info);
2935	u32 dp_cntl = DST_LAST_PEL;
2936
2937	srcx *= fontwidth(p);
2938	srcy *= fontheight(p);
2939	dstx *= fontwidth(p);
2940	dsty *= fontheight(p);
2941	width *= fontwidth(p);
2942	height *= fontheight(p);
2943
2944	if (srcy < dsty) {
2945		srcy += height - 1;
2946		dsty += height - 1;
2947	} else
2948		dp_cntl |= DST_Y_TOP_TO_BOTTOM;
2949
2950	if (srcx < dstx) {
2951		srcx += width - 1;
2952		dstx += width - 1;
2953	} else
2954		dp_cntl |= DST_X_LEFT_TO_RIGHT;
2955
2956	radeon_fifo_wait(6);
2957	OUTREG(DP_GUI_MASTER_CNTL, (rinfo->dp_gui_master_cntl |
2958				    GMC_BRUSH_NONE |
2959				    GMC_SRC_DATATYPE_COLOR |
2960				    ROP3_S |
2961				    DP_SRC_SOURCE_MEMORY));
2962	OUTREG(DP_WRITE_MSK, 0xffffffff);
2963	OUTREG(DP_CNTL, dp_cntl);
2964	OUTREG(SRC_Y_X, (srcy << 16) | srcx);
2965	OUTREG(DST_Y_X, (dsty << 16) | dstx);
2966	OUTREG(DST_HEIGHT_WIDTH, (height << 16) | width);
2967}
2968
2969
2970
2971static void fbcon_radeon_clear(struct vc_data *conp, struct display *p,
2972			       int srcy, int srcx, int height, int width)
2973{
2974	struct radeonfb_info *rinfo = (struct radeonfb_info *)(p->fb_info);
2975	u32 clr;
2976
2977	clr = attr_bgcol_ec(p, conp);
2978	clr |= (clr << 8);
2979	clr |= (clr << 16);
2980
2981	srcx *= fontwidth(p);
2982	srcy *= fontheight(p);
2983	width *= fontwidth(p);
2984	height *= fontheight(p);
2985
2986	radeon_fifo_wait(6);
2987	OUTREG(DP_GUI_MASTER_CNTL, (rinfo->dp_gui_master_cntl |
2988				    GMC_BRUSH_SOLID_COLOR |
2989				    GMC_SRC_DATATYPE_COLOR |
2990				    ROP3_P));
2991	OUTREG(DP_BRUSH_FRGD_CLR, clr);
2992	OUTREG(DP_WRITE_MSK, 0xffffffff);
2993	OUTREG(DP_CNTL, (DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM));
2994	OUTREG(DST_Y_X, (srcy << 16) | srcx);
2995	OUTREG(DST_WIDTH_HEIGHT, (width << 16) | height);
2996}
2997
2998
2999
3000#ifdef FBCON_HAS_CFB8
3001static struct display_switch fbcon_radeon8 = {
3002	setup:			fbcon_cfb8_setup,
3003	bmove:			fbcon_radeon_bmove,
3004	clear:			fbcon_radeon_clear,
3005	putc:			fbcon_cfb8_putc,
3006	putcs:			fbcon_cfb8_putcs,
3007	revc:			fbcon_cfb8_revc,
3008	clear_margins:		fbcon_cfb8_clear_margins,
3009	fontwidthmask:		FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
3010};
3011#endif
3012