1 /*
2 * ATI Frame Buffer Device Driver Core
3 *
4 * Copyright (C) 2004 Alex Kern <alex.kern@gmx.de>
5 * Copyright (C) 1997-2001 Geert Uytterhoeven
6 * Copyright (C) 1998 Bernd Harries
7 * Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be)
8 *
9 * This driver supports the following ATI graphics chips:
10 * - ATI Mach64
11 *
12 * To do: add support for
13 * - ATI Rage128 (from aty128fb.c)
14 * - ATI Radeon (from radeonfb.c)
15 *
16 * This driver is partly based on the PowerMac console driver:
17 *
18 * Copyright (C) 1996 Paul Mackerras
19 *
20 * and on the PowerMac ATI/mach64 display driver:
21 *
22 * Copyright (C) 1997 Michael AK Tesch
23 *
24 * with work by Jon Howell
25 * Harry AC Eaton
26 * Anthony Tong <atong@uiuc.edu>
27 *
28 * Generic LCD support written by Daniel Mantione, ported from 2.4.20 by Alex Kern
29 * Many Thanks to Ville Syrjälä for patches and fixing nasting 16 bit color bug.
30 *
31 * This file is subject to the terms and conditions of the GNU General Public
32 * License. See the file COPYING in the main directory of this archive for
33 * more details.
34 *
35 * Many thanks to Nitya from ATI devrel for support and patience !
36 */
37
38 /******************************************************************************
39
40 TODO:
41
42 - cursor support on all cards and all ramdacs.
43 - cursor parameters controlable via ioctl()s.
44 - guess PLL and MCLK based on the original PLL register values initialized
45 by Open Firmware (if they are initialized). BIOS is done
46
47 (Anyone with Mac to help with this?)
48
49 ******************************************************************************/
50
51
52 #include <linux/module.h>
53 #include <linux/moduleparam.h>
54 #include <linux/kernel.h>
55 #include <linux/errno.h>
56 #include <linux/string.h>
57 #include <linux/mm.h>
58 #include <linux/slab.h>
59 #include <linux/vmalloc.h>
60 #include <linux/delay.h>
61 #include <linux/compiler.h>
62 #include <linux/console.h>
63 #include <linux/fb.h>
64 #include <linux/init.h>
65 #include <linux/pci.h>
66 #include <linux/interrupt.h>
67 #include <linux/spinlock.h>
68 #include <linux/wait.h>
69 #include <linux/backlight.h>
70 #include <linux/reboot.h>
71 #include <linux/dmi.h>
72
73 #include <asm/io.h>
74 #include <linux/uaccess.h>
75
76 #include <video/mach64.h>
77 #include "atyfb.h"
78 #include "ati_ids.h"
79
80 #ifdef __powerpc__
81 #include <asm/machdep.h>
82 #include <asm/prom.h>
83 #include "../macmodes.h"
84 #endif
85 #ifdef __sparc__
86 #include <asm/fbio.h>
87 #include <asm/oplib.h>
88 #include <asm/prom.h>
89 #endif
90
91 #ifdef CONFIG_ADB_PMU
92 #include <linux/adb.h>
93 #include <linux/pmu.h>
94 #endif
95 #ifdef CONFIG_BOOTX_TEXT
96 #include <asm/btext.h>
97 #endif
98 #ifdef CONFIG_PMAC_BACKLIGHT
99 #include <asm/backlight.h>
100 #endif
101
102 /*
103 * Debug flags.
104 */
105 #undef DEBUG
106 /*#define DEBUG*/
107
108 /* Make sure n * PAGE_SIZE is protected at end of Aperture for GUI-regs */
109 /* - must be large enough to catch all GUI-Regs */
110 /* - must be aligned to a PAGE boundary */
111 #define GUI_RESERVE (1 * PAGE_SIZE)
112
113 /* FIXME: remove the FAIL definition */
114 #define FAIL(msg) do { \
115 if (!(var->activate & FB_ACTIVATE_TEST)) \
116 printk(KERN_CRIT "atyfb: " msg "\n"); \
117 return -EINVAL; \
118 } while (0)
119 #define FAIL_MAX(msg, x, _max_) do { \
120 if (x > _max_) { \
121 if (!(var->activate & FB_ACTIVATE_TEST)) \
122 printk(KERN_CRIT "atyfb: " msg " %x(%x)\n", x, _max_); \
123 return -EINVAL; \
124 } \
125 } while (0)
126 #ifdef DEBUG
127 #define DPRINTK(fmt, args...) printk(KERN_DEBUG "atyfb: " fmt, ## args)
128 #else
129 #define DPRINTK(fmt, args...)
130 #endif
131
132 #define PRINTKI(fmt, args...) printk(KERN_INFO "atyfb: " fmt, ## args)
133 #define PRINTKE(fmt, args...) printk(KERN_ERR "atyfb: " fmt, ## args)
134
135 #if defined(CONFIG_PM) || defined(CONFIG_PMAC_BACKLIGHT) || \
136 defined (CONFIG_FB_ATY_GENERIC_LCD) || defined(CONFIG_FB_ATY_BACKLIGHT)
137 static const u32 lt_lcd_regs[] = {
138 CNFG_PANEL_LG,
139 LCD_GEN_CNTL_LG,
140 DSTN_CONTROL_LG,
141 HFB_PITCH_ADDR_LG,
142 HORZ_STRETCHING_LG,
143 VERT_STRETCHING_LG,
144 0, /* EXT_VERT_STRETCH */
145 LT_GIO_LG,
146 POWER_MANAGEMENT_LG
147 };
148
aty_st_lcd(int index,u32 val,const struct atyfb_par * par)149 void aty_st_lcd(int index, u32 val, const struct atyfb_par *par)
150 {
151 if (M64_HAS(LT_LCD_REGS)) {
152 aty_st_le32(lt_lcd_regs[index], val, par);
153 } else {
154 unsigned long temp;
155
156 /* write addr byte */
157 temp = aty_ld_le32(LCD_INDEX, par);
158 aty_st_le32(LCD_INDEX, (temp & ~LCD_INDEX_MASK) | index, par);
159 /* write the register value */
160 aty_st_le32(LCD_DATA, val, par);
161 }
162 }
163
aty_ld_lcd(int index,const struct atyfb_par * par)164 u32 aty_ld_lcd(int index, const struct atyfb_par *par)
165 {
166 if (M64_HAS(LT_LCD_REGS)) {
167 return aty_ld_le32(lt_lcd_regs[index], par);
168 } else {
169 unsigned long temp;
170
171 /* write addr byte */
172 temp = aty_ld_le32(LCD_INDEX, par);
173 aty_st_le32(LCD_INDEX, (temp & ~LCD_INDEX_MASK) | index, par);
174 /* read the register value */
175 return aty_ld_le32(LCD_DATA, par);
176 }
177 }
178 #endif /* defined(CONFIG_PM) || defined(CONFIG_PMAC_BACKLIGHT) || defined (CONFIG_FB_ATY_GENERIC_LCD) */
179
180 #ifdef CONFIG_FB_ATY_GENERIC_LCD
181 /*
182 * ATIReduceRatio --
183 *
184 * Reduce a fraction by factoring out the largest common divider of the
185 * fraction's numerator and denominator.
186 */
ATIReduceRatio(int * Numerator,int * Denominator)187 static void ATIReduceRatio(int *Numerator, int *Denominator)
188 {
189 int Multiplier, Divider, Remainder;
190
191 Multiplier = *Numerator;
192 Divider = *Denominator;
193
194 while ((Remainder = Multiplier % Divider)) {
195 Multiplier = Divider;
196 Divider = Remainder;
197 }
198
199 *Numerator /= Divider;
200 *Denominator /= Divider;
201 }
202 #endif
203 /*
204 * The Hardware parameters for each card
205 */
206
207 struct pci_mmap_map {
208 unsigned long voff;
209 unsigned long poff;
210 unsigned long size;
211 unsigned long prot_flag;
212 unsigned long prot_mask;
213 };
214
215 static const struct fb_fix_screeninfo atyfb_fix = {
216 .id = "ATY Mach64",
217 .type = FB_TYPE_PACKED_PIXELS,
218 .visual = FB_VISUAL_PSEUDOCOLOR,
219 .xpanstep = 8,
220 .ypanstep = 1,
221 };
222
223 /*
224 * Frame buffer device API
225 */
226
227 static int atyfb_open(struct fb_info *info, int user);
228 static int atyfb_release(struct fb_info *info, int user);
229 static int atyfb_check_var(struct fb_var_screeninfo *var,
230 struct fb_info *info);
231 static int atyfb_set_par(struct fb_info *info);
232 static int atyfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
233 u_int transp, struct fb_info *info);
234 static int atyfb_pan_display(struct fb_var_screeninfo *var,
235 struct fb_info *info);
236 static int atyfb_blank(int blank, struct fb_info *info);
237 static int atyfb_ioctl(struct fb_info *info, u_int cmd, u_long arg);
238 #ifdef __sparc__
239 static int atyfb_mmap(struct fb_info *info, struct vm_area_struct *vma);
240 #endif
241 static int atyfb_sync(struct fb_info *info);
242
243 /*
244 * Internal routines
245 */
246
247 static int aty_init(struct fb_info *info);
248
249 static void aty_get_crtc(const struct atyfb_par *par, struct crtc *crtc);
250
251 static void aty_set_crtc(const struct atyfb_par *par, const struct crtc *crtc);
252 static int aty_var_to_crtc(const struct fb_info *info,
253 const struct fb_var_screeninfo *var,
254 struct crtc *crtc);
255 static int aty_crtc_to_var(const struct crtc *crtc,
256 struct fb_var_screeninfo *var);
257 static void set_off_pitch(struct atyfb_par *par, const struct fb_info *info);
258 #ifdef CONFIG_PPC
259 static int read_aty_sense(const struct atyfb_par *par);
260 #endif
261
262 static DEFINE_MUTEX(reboot_lock);
263 static struct fb_info *reboot_info;
264
265 /*
266 * Interface used by the world
267 */
268
269 static struct fb_var_screeninfo default_var = {
270 /* 640x480, 60 Hz, Non-Interlaced (25.175 MHz dotclock) */
271 640, 480, 640, 480, 0, 0, 8, 0,
272 {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
273 0, 0, -1, -1, 0, 39722, 48, 16, 33, 10, 96, 2,
274 0, FB_VMODE_NONINTERLACED
275 };
276
277 static const struct fb_videomode defmode = {
278 /* 640x480 @ 60 Hz, 31.5 kHz hsync */
279 NULL, 60, 640, 480, 39721, 40, 24, 32, 11, 96, 2,
280 0, FB_VMODE_NONINTERLACED
281 };
282
283 static struct fb_ops atyfb_ops = {
284 .owner = THIS_MODULE,
285 .fb_open = atyfb_open,
286 .fb_release = atyfb_release,
287 .fb_check_var = atyfb_check_var,
288 .fb_set_par = atyfb_set_par,
289 .fb_setcolreg = atyfb_setcolreg,
290 .fb_pan_display = atyfb_pan_display,
291 .fb_blank = atyfb_blank,
292 .fb_ioctl = atyfb_ioctl,
293 .fb_fillrect = atyfb_fillrect,
294 .fb_copyarea = atyfb_copyarea,
295 .fb_imageblit = atyfb_imageblit,
296 #ifdef __sparc__
297 .fb_mmap = atyfb_mmap,
298 #endif
299 .fb_sync = atyfb_sync,
300 };
301
302 static bool noaccel;
303 static bool nomtrr;
304 static int vram;
305 static int pll;
306 static int mclk;
307 static int xclk;
308 static int comp_sync = -1;
309 static char *mode;
310
311 #ifdef CONFIG_PMAC_BACKLIGHT
312 static int backlight = 1;
313 #else
314 static int backlight = 0;
315 #endif
316
317 #ifdef CONFIG_PPC
318 static int default_vmode = VMODE_CHOOSE;
319 static int default_cmode = CMODE_CHOOSE;
320
321 module_param_named(vmode, default_vmode, int, 0);
322 MODULE_PARM_DESC(vmode, "int: video mode for mac");
323 module_param_named(cmode, default_cmode, int, 0);
324 MODULE_PARM_DESC(cmode, "int: color mode for mac");
325 #endif
326
327 #ifdef CONFIG_ATARI
328 static unsigned int mach64_count = 0;
329 static unsigned long phys_vmembase[FB_MAX] = { 0, };
330 static unsigned long phys_size[FB_MAX] = { 0, };
331 static unsigned long phys_guiregbase[FB_MAX] = { 0, };
332 #endif
333
334 /* top -> down is an evolution of mach64 chipset, any corrections? */
335 #define ATI_CHIP_88800GX (M64F_GX)
336 #define ATI_CHIP_88800CX (M64F_GX)
337
338 #define ATI_CHIP_264CT (M64F_CT | M64F_INTEGRATED | M64F_CT_BUS | M64F_MAGIC_FIFO)
339 #define ATI_CHIP_264ET (M64F_CT | M64F_INTEGRATED | M64F_CT_BUS | M64F_MAGIC_FIFO)
340
341 #define ATI_CHIP_264VT (M64F_VT | M64F_INTEGRATED | M64F_VT_BUS | M64F_MAGIC_FIFO)
342 #define ATI_CHIP_264GT (M64F_GT | M64F_INTEGRATED | M64F_MAGIC_FIFO | M64F_EXTRA_BRIGHT)
343
344 #define ATI_CHIP_264VTB (M64F_VT | M64F_INTEGRATED | M64F_VT_BUS | M64F_GTB_DSP)
345 #define ATI_CHIP_264VT3 (M64F_VT | M64F_INTEGRATED | M64F_VT_BUS | M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL)
346 #define ATI_CHIP_264VT4 (M64F_VT | M64F_INTEGRATED | M64F_GTB_DSP)
347
348 /* FIXME what is this chip? */
349 #define ATI_CHIP_264LT (M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP)
350
351 /* make sets shorter */
352 #define ATI_MODERN_SET (M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP | M64F_EXTRA_BRIGHT)
353
354 #define ATI_CHIP_264GTB (ATI_MODERN_SET | M64F_SDRAM_MAGIC_PLL)
355 /*#define ATI_CHIP_264GTDVD ?*/
356 #define ATI_CHIP_264LTG (ATI_MODERN_SET | M64F_SDRAM_MAGIC_PLL)
357
358 #define ATI_CHIP_264GT2C (ATI_MODERN_SET | M64F_SDRAM_MAGIC_PLL | M64F_HW_TRIPLE)
359 #define ATI_CHIP_264GTPRO (ATI_MODERN_SET | M64F_SDRAM_MAGIC_PLL | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D)
360 #define ATI_CHIP_264LTPRO (ATI_MODERN_SET | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D)
361
362 #define ATI_CHIP_264XL (ATI_MODERN_SET | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D | M64F_XL_DLL | M64F_MFB_FORCE_4 | M64F_XL_MEM)
363 #define ATI_CHIP_MOBILITY (ATI_MODERN_SET | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D | M64F_XL_DLL | M64F_MFB_FORCE_4 | M64F_XL_MEM | M64F_MOBIL_BUS)
364
365 static struct {
366 u16 pci_id;
367 const char *name;
368 int pll, mclk, xclk, ecp_max;
369 u32 features;
370 } aty_chips[] = {
371 #ifdef CONFIG_FB_ATY_GX
372 /* Mach64 GX */
373 { PCI_CHIP_MACH64GX, "ATI888GX00 (Mach64 GX)", 135, 50, 50, 0, ATI_CHIP_88800GX },
374 { PCI_CHIP_MACH64CX, "ATI888CX00 (Mach64 CX)", 135, 50, 50, 0, ATI_CHIP_88800CX },
375 #endif /* CONFIG_FB_ATY_GX */
376
377 #ifdef CONFIG_FB_ATY_CT
378 { PCI_CHIP_MACH64CT, "ATI264CT (Mach64 CT)", 135, 60, 60, 0, ATI_CHIP_264CT },
379 { PCI_CHIP_MACH64ET, "ATI264ET (Mach64 ET)", 135, 60, 60, 0, ATI_CHIP_264ET },
380
381 /* FIXME what is this chip? */
382 { PCI_CHIP_MACH64LT, "ATI264LT (Mach64 LT)", 135, 63, 63, 0, ATI_CHIP_264LT },
383
384 { PCI_CHIP_MACH64VT, "ATI264VT (Mach64 VT)", 170, 67, 67, 80, ATI_CHIP_264VT },
385 { PCI_CHIP_MACH64GT, "3D RAGE (Mach64 GT)", 135, 63, 63, 80, ATI_CHIP_264GT },
386
387 { PCI_CHIP_MACH64VU, "ATI264VT3 (Mach64 VU)", 200, 67, 67, 80, ATI_CHIP_264VT3 },
388 { PCI_CHIP_MACH64GU, "3D RAGE II+ (Mach64 GU)", 200, 67, 67, 100, ATI_CHIP_264GTB },
389
390 { PCI_CHIP_MACH64LG, "3D RAGE LT (Mach64 LG)", 230, 63, 63, 100, ATI_CHIP_264LTG | M64F_LT_LCD_REGS | M64F_G3_PB_1024x768 },
391
392 { PCI_CHIP_MACH64VV, "ATI264VT4 (Mach64 VV)", 230, 83, 83, 100, ATI_CHIP_264VT4 },
393
394 { PCI_CHIP_MACH64GV, "3D RAGE IIC (Mach64 GV, PCI)", 230, 83, 83, 100, ATI_CHIP_264GT2C },
395 { PCI_CHIP_MACH64GW, "3D RAGE IIC (Mach64 GW, AGP)", 230, 83, 83, 100, ATI_CHIP_264GT2C },
396 { PCI_CHIP_MACH64GY, "3D RAGE IIC (Mach64 GY, PCI)", 230, 83, 83, 100, ATI_CHIP_264GT2C },
397 { PCI_CHIP_MACH64GZ, "3D RAGE IIC (Mach64 GZ, AGP)", 230, 83, 83, 100, ATI_CHIP_264GT2C },
398
399 { PCI_CHIP_MACH64GB, "3D RAGE PRO (Mach64 GB, BGA, AGP)", 230, 100, 100, 125, ATI_CHIP_264GTPRO },
400 { PCI_CHIP_MACH64GD, "3D RAGE PRO (Mach64 GD, BGA, AGP 1x)", 230, 100, 100, 125, ATI_CHIP_264GTPRO },
401 { PCI_CHIP_MACH64GI, "3D RAGE PRO (Mach64 GI, BGA, PCI)", 230, 100, 100, 125, ATI_CHIP_264GTPRO | M64F_MAGIC_VRAM_SIZE },
402 { PCI_CHIP_MACH64GP, "3D RAGE PRO (Mach64 GP, PQFP, PCI)", 230, 100, 100, 125, ATI_CHIP_264GTPRO },
403 { PCI_CHIP_MACH64GQ, "3D RAGE PRO (Mach64 GQ, PQFP, PCI, limited 3D)", 230, 100, 100, 125, ATI_CHIP_264GTPRO },
404
405 { PCI_CHIP_MACH64LB, "3D RAGE LT PRO (Mach64 LB, AGP)", 236, 75, 100, 135, ATI_CHIP_264LTPRO },
406 { PCI_CHIP_MACH64LD, "3D RAGE LT PRO (Mach64 LD, AGP)", 230, 100, 100, 135, ATI_CHIP_264LTPRO },
407 { PCI_CHIP_MACH64LI, "3D RAGE LT PRO (Mach64 LI, PCI)", 230, 100, 100, 135, ATI_CHIP_264LTPRO | M64F_G3_PB_1_1 | M64F_G3_PB_1024x768 },
408 { PCI_CHIP_MACH64LP, "3D RAGE LT PRO (Mach64 LP, PCI)", 230, 100, 100, 135, ATI_CHIP_264LTPRO | M64F_G3_PB_1024x768 },
409 { PCI_CHIP_MACH64LQ, "3D RAGE LT PRO (Mach64 LQ, PCI)", 230, 100, 100, 135, ATI_CHIP_264LTPRO },
410
411 { PCI_CHIP_MACH64GM, "3D RAGE XL (Mach64 GM, AGP 2x)", 230, 83, 63, 135, ATI_CHIP_264XL },
412 { PCI_CHIP_MACH64GN, "3D RAGE XC (Mach64 GN, AGP 2x)", 230, 83, 63, 135, ATI_CHIP_264XL },
413 { PCI_CHIP_MACH64GO, "3D RAGE XL (Mach64 GO, PCI-66)", 230, 83, 63, 135, ATI_CHIP_264XL },
414 { PCI_CHIP_MACH64GL, "3D RAGE XC (Mach64 GL, PCI-66)", 230, 83, 63, 135, ATI_CHIP_264XL },
415 { PCI_CHIP_MACH64GR, "3D RAGE XL (Mach64 GR, PCI-33)", 230, 83, 63, 135, ATI_CHIP_264XL | M64F_SDRAM_MAGIC_PLL },
416 { PCI_CHIP_MACH64GS, "3D RAGE XC (Mach64 GS, PCI-33)", 230, 83, 63, 135, ATI_CHIP_264XL },
417
418 { PCI_CHIP_MACH64LM, "3D RAGE Mobility P/M (Mach64 LM, AGP 2x)", 230, 83, 125, 135, ATI_CHIP_MOBILITY },
419 { PCI_CHIP_MACH64LN, "3D RAGE Mobility L (Mach64 LN, AGP 2x)", 230, 83, 125, 135, ATI_CHIP_MOBILITY },
420 { PCI_CHIP_MACH64LR, "3D RAGE Mobility P/M (Mach64 LR, PCI)", 230, 83, 125, 135, ATI_CHIP_MOBILITY },
421 { PCI_CHIP_MACH64LS, "3D RAGE Mobility L (Mach64 LS, PCI)", 230, 83, 125, 135, ATI_CHIP_MOBILITY },
422 #endif /* CONFIG_FB_ATY_CT */
423 };
424
425 /*
426 * Last page of 8 MB (4 MB on ISA) aperture is MMIO,
427 * unless the auxiliary register aperture is used.
428 */
aty_fudge_framebuffer_len(struct fb_info * info)429 static void aty_fudge_framebuffer_len(struct fb_info *info)
430 {
431 struct atyfb_par *par = (struct atyfb_par *) info->par;
432
433 if (!par->aux_start &&
434 (info->fix.smem_len == 0x800000 ||
435 (par->bus_type == ISA && info->fix.smem_len == 0x400000)))
436 info->fix.smem_len -= GUI_RESERVE;
437 }
438
correct_chipset(struct atyfb_par * par)439 static int correct_chipset(struct atyfb_par *par)
440 {
441 u8 rev;
442 u16 type;
443 u32 chip_id;
444 const char *name;
445 int i;
446
447 for (i = (int)ARRAY_SIZE(aty_chips) - 1; i >= 0; i--)
448 if (par->pci_id == aty_chips[i].pci_id)
449 break;
450
451 if (i < 0)
452 return -ENODEV;
453
454 name = aty_chips[i].name;
455 par->pll_limits.pll_max = aty_chips[i].pll;
456 par->pll_limits.mclk = aty_chips[i].mclk;
457 par->pll_limits.xclk = aty_chips[i].xclk;
458 par->pll_limits.ecp_max = aty_chips[i].ecp_max;
459 par->features = aty_chips[i].features;
460
461 chip_id = aty_ld_le32(CNFG_CHIP_ID, par);
462 type = chip_id & CFG_CHIP_TYPE;
463 rev = (chip_id & CFG_CHIP_REV) >> 24;
464
465 switch (par->pci_id) {
466 #ifdef CONFIG_FB_ATY_GX
467 case PCI_CHIP_MACH64GX:
468 if (type != 0x00d7)
469 return -ENODEV;
470 break;
471 case PCI_CHIP_MACH64CX:
472 if (type != 0x0057)
473 return -ENODEV;
474 break;
475 #endif
476 #ifdef CONFIG_FB_ATY_CT
477 case PCI_CHIP_MACH64VT:
478 switch (rev & 0x07) {
479 case 0x00:
480 switch (rev & 0xc0) {
481 case 0x00:
482 name = "ATI264VT (A3) (Mach64 VT)";
483 par->pll_limits.pll_max = 170;
484 par->pll_limits.mclk = 67;
485 par->pll_limits.xclk = 67;
486 par->pll_limits.ecp_max = 80;
487 par->features = ATI_CHIP_264VT;
488 break;
489 case 0x40:
490 name = "ATI264VT2 (A4) (Mach64 VT)";
491 par->pll_limits.pll_max = 200;
492 par->pll_limits.mclk = 67;
493 par->pll_limits.xclk = 67;
494 par->pll_limits.ecp_max = 80;
495 par->features = ATI_CHIP_264VT | M64F_MAGIC_POSTDIV;
496 break;
497 }
498 break;
499 case 0x01:
500 name = "ATI264VT3 (B1) (Mach64 VT)";
501 par->pll_limits.pll_max = 200;
502 par->pll_limits.mclk = 67;
503 par->pll_limits.xclk = 67;
504 par->pll_limits.ecp_max = 80;
505 par->features = ATI_CHIP_264VTB;
506 break;
507 case 0x02:
508 name = "ATI264VT3 (B2) (Mach64 VT)";
509 par->pll_limits.pll_max = 200;
510 par->pll_limits.mclk = 67;
511 par->pll_limits.xclk = 67;
512 par->pll_limits.ecp_max = 80;
513 par->features = ATI_CHIP_264VT3;
514 break;
515 }
516 break;
517 case PCI_CHIP_MACH64GT:
518 switch (rev & 0x07) {
519 case 0x01:
520 name = "3D RAGE II (Mach64 GT)";
521 par->pll_limits.pll_max = 170;
522 par->pll_limits.mclk = 67;
523 par->pll_limits.xclk = 67;
524 par->pll_limits.ecp_max = 80;
525 par->features = ATI_CHIP_264GTB;
526 break;
527 case 0x02:
528 name = "3D RAGE II+ (Mach64 GT)";
529 par->pll_limits.pll_max = 200;
530 par->pll_limits.mclk = 67;
531 par->pll_limits.xclk = 67;
532 par->pll_limits.ecp_max = 100;
533 par->features = ATI_CHIP_264GTB;
534 break;
535 }
536 break;
537 #endif
538 }
539
540 PRINTKI("%s [0x%04x rev 0x%02x]\n", name, type, rev);
541 return 0;
542 }
543
544 static char ram_dram[] __maybe_unused = "DRAM";
545 static char ram_resv[] __maybe_unused = "RESV";
546 #ifdef CONFIG_FB_ATY_GX
547 static char ram_vram[] = "VRAM";
548 #endif /* CONFIG_FB_ATY_GX */
549 #ifdef CONFIG_FB_ATY_CT
550 static char ram_edo[] = "EDO";
551 static char ram_sdram[] = "SDRAM (1:1)";
552 static char ram_sgram[] = "SGRAM (1:1)";
553 static char ram_sdram32[] = "SDRAM (2:1) (32-bit)";
554 static char ram_wram[] = "WRAM";
555 static char ram_off[] = "OFF";
556 #endif /* CONFIG_FB_ATY_CT */
557
558
559 #ifdef CONFIG_FB_ATY_GX
560 static char *aty_gx_ram[8] = {
561 ram_dram, ram_vram, ram_vram, ram_dram,
562 ram_dram, ram_vram, ram_vram, ram_resv
563 };
564 #endif /* CONFIG_FB_ATY_GX */
565
566 #ifdef CONFIG_FB_ATY_CT
567 static char *aty_ct_ram[8] = {
568 ram_off, ram_dram, ram_edo, ram_edo,
569 ram_sdram, ram_sgram, ram_wram, ram_resv
570 };
571 static char *aty_xl_ram[8] = {
572 ram_off, ram_dram, ram_edo, ram_edo,
573 ram_sdram, ram_sgram, ram_sdram32, ram_resv
574 };
575 #endif /* CONFIG_FB_ATY_CT */
576
atyfb_get_pixclock(struct fb_var_screeninfo * var,struct atyfb_par * par)577 static u32 atyfb_get_pixclock(struct fb_var_screeninfo *var,
578 struct atyfb_par *par)
579 {
580 u32 pixclock = var->pixclock;
581 #ifdef CONFIG_FB_ATY_GENERIC_LCD
582 u32 lcd_on_off;
583 par->pll.ct.xres = 0;
584 if (par->lcd_table != 0) {
585 lcd_on_off = aty_ld_lcd(LCD_GEN_CNTL, par);
586 if (lcd_on_off & LCD_ON) {
587 par->pll.ct.xres = var->xres;
588 pixclock = par->lcd_pixclock;
589 }
590 }
591 #endif
592 return pixclock;
593 }
594
595 #if defined(CONFIG_PPC)
596
597 /*
598 * Apple monitor sense
599 */
600
read_aty_sense(const struct atyfb_par * par)601 static int read_aty_sense(const struct atyfb_par *par)
602 {
603 int sense, i;
604
605 aty_st_le32(GP_IO, 0x31003100, par); /* drive outputs high */
606 __delay(200);
607 aty_st_le32(GP_IO, 0, par); /* turn off outputs */
608 __delay(2000);
609 i = aty_ld_le32(GP_IO, par); /* get primary sense value */
610 sense = ((i & 0x3000) >> 3) | (i & 0x100);
611
612 /* drive each sense line low in turn and collect the other 2 */
613 aty_st_le32(GP_IO, 0x20000000, par); /* drive A low */
614 __delay(2000);
615 i = aty_ld_le32(GP_IO, par);
616 sense |= ((i & 0x1000) >> 7) | ((i & 0x100) >> 4);
617 aty_st_le32(GP_IO, 0x20002000, par); /* drive A high again */
618 __delay(200);
619
620 aty_st_le32(GP_IO, 0x10000000, par); /* drive B low */
621 __delay(2000);
622 i = aty_ld_le32(GP_IO, par);
623 sense |= ((i & 0x2000) >> 10) | ((i & 0x100) >> 6);
624 aty_st_le32(GP_IO, 0x10001000, par); /* drive B high again */
625 __delay(200);
626
627 aty_st_le32(GP_IO, 0x01000000, par); /* drive C low */
628 __delay(2000);
629 sense |= (aty_ld_le32(GP_IO, par) & 0x3000) >> 12;
630 aty_st_le32(GP_IO, 0, par); /* turn off outputs */
631 return sense;
632 }
633
634 #endif /* defined(CONFIG_PPC) */
635
636 /* ------------------------------------------------------------------------- */
637
638 /*
639 * CRTC programming
640 */
641
aty_get_crtc(const struct atyfb_par * par,struct crtc * crtc)642 static void aty_get_crtc(const struct atyfb_par *par, struct crtc *crtc)
643 {
644 #ifdef CONFIG_FB_ATY_GENERIC_LCD
645 if (par->lcd_table != 0) {
646 if (!M64_HAS(LT_LCD_REGS)) {
647 crtc->lcd_index = aty_ld_le32(LCD_INDEX, par);
648 aty_st_le32(LCD_INDEX, crtc->lcd_index, par);
649 }
650 crtc->lcd_config_panel = aty_ld_lcd(CNFG_PANEL, par);
651 crtc->lcd_gen_cntl = aty_ld_lcd(LCD_GEN_CNTL, par);
652
653
654 /* switch to non shadow registers */
655 aty_st_lcd(LCD_GEN_CNTL, crtc->lcd_gen_cntl &
656 ~(CRTC_RW_SELECT | SHADOW_EN | SHADOW_RW_EN), par);
657
658 /* save stretching */
659 crtc->horz_stretching = aty_ld_lcd(HORZ_STRETCHING, par);
660 crtc->vert_stretching = aty_ld_lcd(VERT_STRETCHING, par);
661 if (!M64_HAS(LT_LCD_REGS))
662 crtc->ext_vert_stretch = aty_ld_lcd(EXT_VERT_STRETCH, par);
663 }
664 #endif
665 crtc->h_tot_disp = aty_ld_le32(CRTC_H_TOTAL_DISP, par);
666 crtc->h_sync_strt_wid = aty_ld_le32(CRTC_H_SYNC_STRT_WID, par);
667 crtc->v_tot_disp = aty_ld_le32(CRTC_V_TOTAL_DISP, par);
668 crtc->v_sync_strt_wid = aty_ld_le32(CRTC_V_SYNC_STRT_WID, par);
669 crtc->vline_crnt_vline = aty_ld_le32(CRTC_VLINE_CRNT_VLINE, par);
670 crtc->off_pitch = aty_ld_le32(CRTC_OFF_PITCH, par);
671 crtc->gen_cntl = aty_ld_le32(CRTC_GEN_CNTL, par);
672
673 #ifdef CONFIG_FB_ATY_GENERIC_LCD
674 if (par->lcd_table != 0) {
675 /* switch to shadow registers */
676 aty_st_lcd(LCD_GEN_CNTL, (crtc->lcd_gen_cntl & ~CRTC_RW_SELECT) |
677 SHADOW_EN | SHADOW_RW_EN, par);
678
679 crtc->shadow_h_tot_disp = aty_ld_le32(CRTC_H_TOTAL_DISP, par);
680 crtc->shadow_h_sync_strt_wid = aty_ld_le32(CRTC_H_SYNC_STRT_WID, par);
681 crtc->shadow_v_tot_disp = aty_ld_le32(CRTC_V_TOTAL_DISP, par);
682 crtc->shadow_v_sync_strt_wid = aty_ld_le32(CRTC_V_SYNC_STRT_WID, par);
683
684 aty_st_le32(LCD_GEN_CNTL, crtc->lcd_gen_cntl, par);
685 }
686 #endif /* CONFIG_FB_ATY_GENERIC_LCD */
687 }
688
aty_set_crtc(const struct atyfb_par * par,const struct crtc * crtc)689 static void aty_set_crtc(const struct atyfb_par *par, const struct crtc *crtc)
690 {
691 #ifdef CONFIG_FB_ATY_GENERIC_LCD
692 if (par->lcd_table != 0) {
693 /* stop CRTC */
694 aty_st_le32(CRTC_GEN_CNTL, crtc->gen_cntl &
695 ~(CRTC_EXT_DISP_EN | CRTC_EN), par);
696
697 /* update non-shadow registers first */
698 aty_st_lcd(CNFG_PANEL, crtc->lcd_config_panel, par);
699 aty_st_lcd(LCD_GEN_CNTL, crtc->lcd_gen_cntl &
700 ~(CRTC_RW_SELECT | SHADOW_EN | SHADOW_RW_EN), par);
701
702 /* temporarily disable stretching */
703 aty_st_lcd(HORZ_STRETCHING, crtc->horz_stretching &
704 ~(HORZ_STRETCH_MODE | HORZ_STRETCH_EN), par);
705 aty_st_lcd(VERT_STRETCHING, crtc->vert_stretching &
706 ~(VERT_STRETCH_RATIO1 | VERT_STRETCH_RATIO2 |
707 VERT_STRETCH_USE0 | VERT_STRETCH_EN), par);
708 }
709 #endif
710 /* turn off CRT */
711 aty_st_le32(CRTC_GEN_CNTL, crtc->gen_cntl & ~CRTC_EN, par);
712
713 DPRINTK("setting up CRTC\n");
714 DPRINTK("set primary CRT to %ix%i %c%c composite %c\n",
715 ((((crtc->h_tot_disp >> 16) & 0xff) + 1) << 3),
716 (((crtc->v_tot_disp >> 16) & 0x7ff) + 1),
717 (crtc->h_sync_strt_wid & 0x200000) ? 'N' : 'P',
718 (crtc->v_sync_strt_wid & 0x200000) ? 'N' : 'P',
719 (crtc->gen_cntl & CRTC_CSYNC_EN) ? 'P' : 'N');
720
721 DPRINTK("CRTC_H_TOTAL_DISP: %x\n", crtc->h_tot_disp);
722 DPRINTK("CRTC_H_SYNC_STRT_WID: %x\n", crtc->h_sync_strt_wid);
723 DPRINTK("CRTC_V_TOTAL_DISP: %x\n", crtc->v_tot_disp);
724 DPRINTK("CRTC_V_SYNC_STRT_WID: %x\n", crtc->v_sync_strt_wid);
725 DPRINTK("CRTC_OFF_PITCH: %x\n", crtc->off_pitch);
726 DPRINTK("CRTC_VLINE_CRNT_VLINE: %x\n", crtc->vline_crnt_vline);
727 DPRINTK("CRTC_GEN_CNTL: %x\n", crtc->gen_cntl);
728
729 aty_st_le32(CRTC_H_TOTAL_DISP, crtc->h_tot_disp, par);
730 aty_st_le32(CRTC_H_SYNC_STRT_WID, crtc->h_sync_strt_wid, par);
731 aty_st_le32(CRTC_V_TOTAL_DISP, crtc->v_tot_disp, par);
732 aty_st_le32(CRTC_V_SYNC_STRT_WID, crtc->v_sync_strt_wid, par);
733 aty_st_le32(CRTC_OFF_PITCH, crtc->off_pitch, par);
734 aty_st_le32(CRTC_VLINE_CRNT_VLINE, crtc->vline_crnt_vline, par);
735
736 aty_st_le32(CRTC_GEN_CNTL, crtc->gen_cntl, par);
737 #if 0
738 FIXME
739 if (par->accel_flags & FB_ACCELF_TEXT)
740 aty_init_engine(par, info);
741 #endif
742 #ifdef CONFIG_FB_ATY_GENERIC_LCD
743 /* after setting the CRTC registers we should set the LCD registers. */
744 if (par->lcd_table != 0) {
745 /* switch to shadow registers */
746 aty_st_lcd(LCD_GEN_CNTL, (crtc->lcd_gen_cntl & ~CRTC_RW_SELECT) |
747 SHADOW_EN | SHADOW_RW_EN, par);
748
749 DPRINTK("set shadow CRT to %ix%i %c%c\n",
750 ((((crtc->shadow_h_tot_disp >> 16) & 0xff) + 1) << 3),
751 (((crtc->shadow_v_tot_disp >> 16) & 0x7ff) + 1),
752 (crtc->shadow_h_sync_strt_wid & 0x200000) ? 'N' : 'P',
753 (crtc->shadow_v_sync_strt_wid & 0x200000) ? 'N' : 'P');
754
755 DPRINTK("SHADOW CRTC_H_TOTAL_DISP: %x\n",
756 crtc->shadow_h_tot_disp);
757 DPRINTK("SHADOW CRTC_H_SYNC_STRT_WID: %x\n",
758 crtc->shadow_h_sync_strt_wid);
759 DPRINTK("SHADOW CRTC_V_TOTAL_DISP: %x\n",
760 crtc->shadow_v_tot_disp);
761 DPRINTK("SHADOW CRTC_V_SYNC_STRT_WID: %x\n",
762 crtc->shadow_v_sync_strt_wid);
763
764 aty_st_le32(CRTC_H_TOTAL_DISP, crtc->shadow_h_tot_disp, par);
765 aty_st_le32(CRTC_H_SYNC_STRT_WID, crtc->shadow_h_sync_strt_wid, par);
766 aty_st_le32(CRTC_V_TOTAL_DISP, crtc->shadow_v_tot_disp, par);
767 aty_st_le32(CRTC_V_SYNC_STRT_WID, crtc->shadow_v_sync_strt_wid, par);
768
769 /* restore CRTC selection & shadow state and enable stretching */
770 DPRINTK("LCD_GEN_CNTL: %x\n", crtc->lcd_gen_cntl);
771 DPRINTK("HORZ_STRETCHING: %x\n", crtc->horz_stretching);
772 DPRINTK("VERT_STRETCHING: %x\n", crtc->vert_stretching);
773 if (!M64_HAS(LT_LCD_REGS))
774 DPRINTK("EXT_VERT_STRETCH: %x\n", crtc->ext_vert_stretch);
775
776 aty_st_lcd(LCD_GEN_CNTL, crtc->lcd_gen_cntl, par);
777 aty_st_lcd(HORZ_STRETCHING, crtc->horz_stretching, par);
778 aty_st_lcd(VERT_STRETCHING, crtc->vert_stretching, par);
779 if (!M64_HAS(LT_LCD_REGS)) {
780 aty_st_lcd(EXT_VERT_STRETCH, crtc->ext_vert_stretch, par);
781 aty_ld_le32(LCD_INDEX, par);
782 aty_st_le32(LCD_INDEX, crtc->lcd_index, par);
783 }
784 }
785 #endif /* CONFIG_FB_ATY_GENERIC_LCD */
786 }
787
calc_line_length(struct atyfb_par * par,u32 vxres,u32 bpp)788 static u32 calc_line_length(struct atyfb_par *par, u32 vxres, u32 bpp)
789 {
790 u32 line_length = vxres * bpp / 8;
791
792 if (par->ram_type == SGRAM ||
793 (!M64_HAS(XL_MEM) && par->ram_type == WRAM))
794 line_length = (line_length + 63) & ~63;
795
796 return line_length;
797 }
798
aty_var_to_crtc(const struct fb_info * info,const struct fb_var_screeninfo * var,struct crtc * crtc)799 static int aty_var_to_crtc(const struct fb_info *info,
800 const struct fb_var_screeninfo *var,
801 struct crtc *crtc)
802 {
803 struct atyfb_par *par = (struct atyfb_par *) info->par;
804 u32 xres, yres, vxres, vyres, xoffset, yoffset, bpp;
805 u32 sync, vmode;
806 u32 h_total, h_disp, h_sync_strt, h_sync_end, h_sync_dly, h_sync_wid, h_sync_pol;
807 u32 v_total, v_disp, v_sync_strt, v_sync_end, v_sync_wid, v_sync_pol, c_sync;
808 u32 pix_width, dp_pix_width, dp_chain_mask;
809 u32 line_length;
810
811 /* input */
812 xres = (var->xres + 7) & ~7;
813 yres = var->yres;
814 vxres = (var->xres_virtual + 7) & ~7;
815 vyres = var->yres_virtual;
816 xoffset = (var->xoffset + 7) & ~7;
817 yoffset = var->yoffset;
818 bpp = var->bits_per_pixel;
819 if (bpp == 16)
820 bpp = (var->green.length == 5) ? 15 : 16;
821 sync = var->sync;
822 vmode = var->vmode;
823
824 /* convert (and round up) and validate */
825 if (vxres < xres + xoffset)
826 vxres = xres + xoffset;
827 h_disp = xres;
828
829 if (vyres < yres + yoffset)
830 vyres = yres + yoffset;
831 v_disp = yres;
832
833 if (bpp <= 8) {
834 bpp = 8;
835 pix_width = CRTC_PIX_WIDTH_8BPP;
836 dp_pix_width = HOST_8BPP | SRC_8BPP | DST_8BPP |
837 BYTE_ORDER_LSB_TO_MSB;
838 dp_chain_mask = DP_CHAIN_8BPP;
839 } else if (bpp <= 15) {
840 bpp = 16;
841 pix_width = CRTC_PIX_WIDTH_15BPP;
842 dp_pix_width = HOST_15BPP | SRC_15BPP | DST_15BPP |
843 BYTE_ORDER_LSB_TO_MSB;
844 dp_chain_mask = DP_CHAIN_15BPP;
845 } else if (bpp <= 16) {
846 bpp = 16;
847 pix_width = CRTC_PIX_WIDTH_16BPP;
848 dp_pix_width = HOST_16BPP | SRC_16BPP | DST_16BPP |
849 BYTE_ORDER_LSB_TO_MSB;
850 dp_chain_mask = DP_CHAIN_16BPP;
851 } else if (bpp <= 24 && M64_HAS(INTEGRATED)) {
852 bpp = 24;
853 pix_width = CRTC_PIX_WIDTH_24BPP;
854 dp_pix_width = HOST_8BPP | SRC_8BPP | DST_8BPP |
855 BYTE_ORDER_LSB_TO_MSB;
856 dp_chain_mask = DP_CHAIN_24BPP;
857 } else if (bpp <= 32) {
858 bpp = 32;
859 pix_width = CRTC_PIX_WIDTH_32BPP;
860 dp_pix_width = HOST_32BPP | SRC_32BPP | DST_32BPP |
861 BYTE_ORDER_LSB_TO_MSB;
862 dp_chain_mask = DP_CHAIN_32BPP;
863 } else
864 FAIL("invalid bpp");
865
866 line_length = calc_line_length(par, vxres, bpp);
867
868 if (vyres * line_length > info->fix.smem_len)
869 FAIL("not enough video RAM");
870
871 h_sync_pol = sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1;
872 v_sync_pol = sync & FB_SYNC_VERT_HIGH_ACT ? 0 : 1;
873
874 if ((xres > 1920) || (yres > 1200)) {
875 FAIL("MACH64 chips are designed for max 1920x1200\n"
876 "select another resolution.");
877 }
878 h_sync_strt = h_disp + var->right_margin;
879 h_sync_end = h_sync_strt + var->hsync_len;
880 h_sync_dly = var->right_margin & 7;
881 h_total = h_sync_end + h_sync_dly + var->left_margin;
882
883 v_sync_strt = v_disp + var->lower_margin;
884 v_sync_end = v_sync_strt + var->vsync_len;
885 v_total = v_sync_end + var->upper_margin;
886
887 #ifdef CONFIG_FB_ATY_GENERIC_LCD
888 if (par->lcd_table != 0) {
889 if (!M64_HAS(LT_LCD_REGS)) {
890 u32 lcd_index = aty_ld_le32(LCD_INDEX, par);
891 crtc->lcd_index = lcd_index &
892 ~(LCD_INDEX_MASK | LCD_DISPLAY_DIS |
893 LCD_SRC_SEL | CRTC2_DISPLAY_DIS);
894 aty_st_le32(LCD_INDEX, lcd_index, par);
895 }
896
897 if (!M64_HAS(MOBIL_BUS))
898 crtc->lcd_index |= CRTC2_DISPLAY_DIS;
899
900 crtc->lcd_config_panel = aty_ld_lcd(CNFG_PANEL, par) | 0x4000;
901 crtc->lcd_gen_cntl = aty_ld_lcd(LCD_GEN_CNTL, par) & ~CRTC_RW_SELECT;
902
903 crtc->lcd_gen_cntl &=
904 ~(HORZ_DIVBY2_EN | DIS_HOR_CRT_DIVBY2 | TVCLK_PM_EN |
905 /*VCLK_DAC_PM_EN | USE_SHADOWED_VEND |*/
906 USE_SHADOWED_ROWCUR | SHADOW_EN | SHADOW_RW_EN);
907 crtc->lcd_gen_cntl |= DONT_SHADOW_VPAR | LOCK_8DOT;
908
909 if ((crtc->lcd_gen_cntl & LCD_ON) &&
910 ((xres > par->lcd_width) || (yres > par->lcd_height))) {
911 /*
912 * We cannot display the mode on the LCD. If the CRT is
913 * enabled we can turn off the LCD.
914 * If the CRT is off, it isn't a good idea to switch it
915 * on; we don't know if one is connected. So it's better
916 * to fail then.
917 */
918 if (crtc->lcd_gen_cntl & CRT_ON) {
919 if (!(var->activate & FB_ACTIVATE_TEST))
920 PRINTKI("Disable LCD panel, because video mode does not fit.\n");
921 crtc->lcd_gen_cntl &= ~LCD_ON;
922 /*aty_st_lcd(LCD_GEN_CNTL, crtc->lcd_gen_cntl, par);*/
923 } else {
924 if (!(var->activate & FB_ACTIVATE_TEST))
925 PRINTKE("Video mode exceeds size of LCD panel.\nConnect this computer to a conventional monitor if you really need this mode.\n");
926 return -EINVAL;
927 }
928 }
929 }
930
931 if ((par->lcd_table != 0) && (crtc->lcd_gen_cntl & LCD_ON)) {
932 int VScan = 1;
933 /* bpp -> bytespp, 1,4 -> 0; 8 -> 2; 15,16 -> 1; 24 -> 6; 32 -> 5
934 const u8 DFP_h_sync_dly_LT[] = { 0, 2, 1, 6, 5 };
935 const u8 ADD_to_strt_wid_and_dly_LT_DAC[] = { 0, 5, 6, 9, 9, 12, 12 }; */
936
937 vmode &= ~(FB_VMODE_DOUBLE | FB_VMODE_INTERLACED);
938
939 /*
940 * This is horror! When we simulate, say 640x480 on an 800x600
941 * LCD monitor, the CRTC should be programmed 800x600 values for
942 * the non visible part, but 640x480 for the visible part.
943 * This code has been tested on a laptop with it's 1400x1050 LCD
944 * monitor and a conventional monitor both switched on.
945 * Tested modes: 1280x1024, 1152x864, 1024x768, 800x600,
946 * works with little glitches also with DOUBLESCAN modes
947 */
948 if (yres < par->lcd_height) {
949 VScan = par->lcd_height / yres;
950 if (VScan > 1) {
951 VScan = 2;
952 vmode |= FB_VMODE_DOUBLE;
953 }
954 }
955
956 h_sync_strt = h_disp + par->lcd_right_margin;
957 h_sync_end = h_sync_strt + par->lcd_hsync_len;
958 h_sync_dly = /*DFP_h_sync_dly[ ( bpp + 1 ) / 3 ]; */par->lcd_hsync_dly;
959 h_total = h_disp + par->lcd_hblank_len;
960
961 v_sync_strt = v_disp + par->lcd_lower_margin / VScan;
962 v_sync_end = v_sync_strt + par->lcd_vsync_len / VScan;
963 v_total = v_disp + par->lcd_vblank_len / VScan;
964 }
965 #endif /* CONFIG_FB_ATY_GENERIC_LCD */
966
967 h_disp = (h_disp >> 3) - 1;
968 h_sync_strt = (h_sync_strt >> 3) - 1;
969 h_sync_end = (h_sync_end >> 3) - 1;
970 h_total = (h_total >> 3) - 1;
971 h_sync_wid = h_sync_end - h_sync_strt;
972
973 FAIL_MAX("h_disp too large", h_disp, 0xff);
974 FAIL_MAX("h_sync_strt too large", h_sync_strt, 0x1ff);
975 /*FAIL_MAX("h_sync_wid too large", h_sync_wid, 0x1f);*/
976 if (h_sync_wid > 0x1f)
977 h_sync_wid = 0x1f;
978 FAIL_MAX("h_total too large", h_total, 0x1ff);
979
980 if (vmode & FB_VMODE_DOUBLE) {
981 v_disp <<= 1;
982 v_sync_strt <<= 1;
983 v_sync_end <<= 1;
984 v_total <<= 1;
985 }
986
987 v_disp--;
988 v_sync_strt--;
989 v_sync_end--;
990 v_total--;
991 v_sync_wid = v_sync_end - v_sync_strt;
992
993 FAIL_MAX("v_disp too large", v_disp, 0x7ff);
994 FAIL_MAX("v_sync_stsrt too large", v_sync_strt, 0x7ff);
995 /*FAIL_MAX("v_sync_wid too large", v_sync_wid, 0x1f);*/
996 if (v_sync_wid > 0x1f)
997 v_sync_wid = 0x1f;
998 FAIL_MAX("v_total too large", v_total, 0x7ff);
999
1000 c_sync = sync & FB_SYNC_COMP_HIGH_ACT ? CRTC_CSYNC_EN : 0;
1001
1002 /* output */
1003 crtc->vxres = vxres;
1004 crtc->vyres = vyres;
1005 crtc->xoffset = xoffset;
1006 crtc->yoffset = yoffset;
1007 crtc->bpp = bpp;
1008 crtc->off_pitch =
1009 ((yoffset * line_length + xoffset * bpp / 8) / 8) |
1010 ((line_length / bpp) << 22);
1011 crtc->vline_crnt_vline = 0;
1012
1013 crtc->h_tot_disp = h_total | (h_disp << 16);
1014 crtc->h_sync_strt_wid = (h_sync_strt & 0xff) | (h_sync_dly << 8) |
1015 ((h_sync_strt & 0x100) << 4) | (h_sync_wid << 16) |
1016 (h_sync_pol << 21);
1017 crtc->v_tot_disp = v_total | (v_disp << 16);
1018 crtc->v_sync_strt_wid = v_sync_strt | (v_sync_wid << 16) |
1019 (v_sync_pol << 21);
1020
1021 /* crtc->gen_cntl = aty_ld_le32(CRTC_GEN_CNTL, par) & CRTC_PRESERVED_MASK; */
1022 crtc->gen_cntl = CRTC_EXT_DISP_EN | CRTC_EN | pix_width | c_sync;
1023 crtc->gen_cntl |= CRTC_VGA_LINEAR;
1024
1025 /* Enable doublescan mode if requested */
1026 if (vmode & FB_VMODE_DOUBLE)
1027 crtc->gen_cntl |= CRTC_DBL_SCAN_EN;
1028 /* Enable interlaced mode if requested */
1029 if (vmode & FB_VMODE_INTERLACED)
1030 crtc->gen_cntl |= CRTC_INTERLACE_EN;
1031 #ifdef CONFIG_FB_ATY_GENERIC_LCD
1032 if (par->lcd_table != 0) {
1033 u32 vdisplay = yres;
1034 if (vmode & FB_VMODE_DOUBLE)
1035 vdisplay <<= 1;
1036 crtc->gen_cntl &= ~(CRTC2_EN | CRTC2_PIX_WIDTH);
1037 crtc->lcd_gen_cntl &= ~(HORZ_DIVBY2_EN | DIS_HOR_CRT_DIVBY2 |
1038 /*TVCLK_PM_EN | VCLK_DAC_PM_EN |*/
1039 USE_SHADOWED_VEND |
1040 USE_SHADOWED_ROWCUR |
1041 SHADOW_EN | SHADOW_RW_EN);
1042 crtc->lcd_gen_cntl |= DONT_SHADOW_VPAR/* | LOCK_8DOT*/;
1043
1044 /* MOBILITY M1 tested, FIXME: LT */
1045 crtc->horz_stretching = aty_ld_lcd(HORZ_STRETCHING, par);
1046 if (!M64_HAS(LT_LCD_REGS))
1047 crtc->ext_vert_stretch = aty_ld_lcd(EXT_VERT_STRETCH, par) &
1048 ~(AUTO_VERT_RATIO | VERT_STRETCH_MODE | VERT_STRETCH_RATIO3);
1049
1050 crtc->horz_stretching &= ~(HORZ_STRETCH_RATIO |
1051 HORZ_STRETCH_LOOP | AUTO_HORZ_RATIO |
1052 HORZ_STRETCH_MODE | HORZ_STRETCH_EN);
1053 if (xres < par->lcd_width && crtc->lcd_gen_cntl & LCD_ON) {
1054 do {
1055 /*
1056 * The horizontal blender misbehaves when
1057 * HDisplay is less than a certain threshold
1058 * (440 for a 1024-wide panel). It doesn't
1059 * stretch such modes enough. Use pixel
1060 * replication instead of blending to stretch
1061 * modes that can be made to exactly fit the
1062 * panel width. The undocumented "NoLCDBlend"
1063 * option allows the pixel-replicated mode to
1064 * be slightly wider or narrower than the
1065 * panel width. It also causes a mode that is
1066 * exactly half as wide as the panel to be
1067 * pixel-replicated, rather than blended.
1068 */
1069 int HDisplay = xres & ~7;
1070 int nStretch = par->lcd_width / HDisplay;
1071 int Remainder = par->lcd_width % HDisplay;
1072
1073 if ((!Remainder && ((nStretch > 2))) ||
1074 (((HDisplay * 16) / par->lcd_width) < 7)) {
1075 static const char StretchLoops[] = { 10, 12, 13, 15, 16 };
1076 int horz_stretch_loop = -1, BestRemainder;
1077 int Numerator = HDisplay, Denominator = par->lcd_width;
1078 int Index = 5;
1079 ATIReduceRatio(&Numerator, &Denominator);
1080
1081 BestRemainder = (Numerator * 16) / Denominator;
1082 while (--Index >= 0) {
1083 Remainder = ((Denominator - Numerator) * StretchLoops[Index]) %
1084 Denominator;
1085 if (Remainder < BestRemainder) {
1086 horz_stretch_loop = Index;
1087 if (!(BestRemainder = Remainder))
1088 break;
1089 }
1090 }
1091
1092 if ((horz_stretch_loop >= 0) && !BestRemainder) {
1093 int horz_stretch_ratio = 0, Accumulator = 0;
1094 int reuse_previous = 1;
1095
1096 Index = StretchLoops[horz_stretch_loop];
1097
1098 while (--Index >= 0) {
1099 if (Accumulator > 0)
1100 horz_stretch_ratio |= reuse_previous;
1101 else
1102 Accumulator += Denominator;
1103 Accumulator -= Numerator;
1104 reuse_previous <<= 1;
1105 }
1106
1107 crtc->horz_stretching |= (HORZ_STRETCH_EN |
1108 ((horz_stretch_loop & HORZ_STRETCH_LOOP) << 16) |
1109 (horz_stretch_ratio & HORZ_STRETCH_RATIO));
1110 break; /* Out of the do { ... } while (0) */
1111 }
1112 }
1113
1114 crtc->horz_stretching |= (HORZ_STRETCH_MODE | HORZ_STRETCH_EN |
1115 (((HDisplay * (HORZ_STRETCH_BLEND + 1)) / par->lcd_width) & HORZ_STRETCH_BLEND));
1116 } while (0);
1117 }
1118
1119 if (vdisplay < par->lcd_height && crtc->lcd_gen_cntl & LCD_ON) {
1120 crtc->vert_stretching = (VERT_STRETCH_USE0 | VERT_STRETCH_EN |
1121 (((vdisplay * (VERT_STRETCH_RATIO0 + 1)) / par->lcd_height) & VERT_STRETCH_RATIO0));
1122
1123 if (!M64_HAS(LT_LCD_REGS) &&
1124 xres <= (M64_HAS(MOBIL_BUS) ? 1024 : 800))
1125 crtc->ext_vert_stretch |= VERT_STRETCH_MODE;
1126 } else {
1127 /*
1128 * Don't use vertical blending if the mode is too wide
1129 * or not vertically stretched.
1130 */
1131 crtc->vert_stretching = 0;
1132 }
1133 /* copy to shadow crtc */
1134 crtc->shadow_h_tot_disp = crtc->h_tot_disp;
1135 crtc->shadow_h_sync_strt_wid = crtc->h_sync_strt_wid;
1136 crtc->shadow_v_tot_disp = crtc->v_tot_disp;
1137 crtc->shadow_v_sync_strt_wid = crtc->v_sync_strt_wid;
1138 }
1139 #endif /* CONFIG_FB_ATY_GENERIC_LCD */
1140
1141 if (M64_HAS(MAGIC_FIFO)) {
1142 /* FIXME: display FIFO low watermark values */
1143 crtc->gen_cntl |= (aty_ld_le32(CRTC_GEN_CNTL, par) & CRTC_FIFO_LWM);
1144 }
1145 crtc->dp_pix_width = dp_pix_width;
1146 crtc->dp_chain_mask = dp_chain_mask;
1147
1148 return 0;
1149 }
1150
aty_crtc_to_var(const struct crtc * crtc,struct fb_var_screeninfo * var)1151 static int aty_crtc_to_var(const struct crtc *crtc,
1152 struct fb_var_screeninfo *var)
1153 {
1154 u32 xres, yres, bpp, left, right, upper, lower, hslen, vslen, sync;
1155 u32 h_total, h_disp, h_sync_strt, h_sync_dly, h_sync_wid, h_sync_pol;
1156 u32 v_total, v_disp, v_sync_strt, v_sync_wid, v_sync_pol, c_sync;
1157 u32 pix_width;
1158 u32 double_scan, interlace;
1159
1160 /* input */
1161 h_total = crtc->h_tot_disp & 0x1ff;
1162 h_disp = (crtc->h_tot_disp >> 16) & 0xff;
1163 h_sync_strt = (crtc->h_sync_strt_wid & 0xff) | ((crtc->h_sync_strt_wid >> 4) & 0x100);
1164 h_sync_dly = (crtc->h_sync_strt_wid >> 8) & 0x7;
1165 h_sync_wid = (crtc->h_sync_strt_wid >> 16) & 0x1f;
1166 h_sync_pol = (crtc->h_sync_strt_wid >> 21) & 0x1;
1167 v_total = crtc->v_tot_disp & 0x7ff;
1168 v_disp = (crtc->v_tot_disp >> 16) & 0x7ff;
1169 v_sync_strt = crtc->v_sync_strt_wid & 0x7ff;
1170 v_sync_wid = (crtc->v_sync_strt_wid >> 16) & 0x1f;
1171 v_sync_pol = (crtc->v_sync_strt_wid >> 21) & 0x1;
1172 c_sync = crtc->gen_cntl & CRTC_CSYNC_EN ? 1 : 0;
1173 pix_width = crtc->gen_cntl & CRTC_PIX_WIDTH_MASK;
1174 double_scan = crtc->gen_cntl & CRTC_DBL_SCAN_EN;
1175 interlace = crtc->gen_cntl & CRTC_INTERLACE_EN;
1176
1177 /* convert */
1178 xres = (h_disp + 1) * 8;
1179 yres = v_disp + 1;
1180 left = (h_total - h_sync_strt - h_sync_wid) * 8 - h_sync_dly;
1181 right = (h_sync_strt - h_disp) * 8 + h_sync_dly;
1182 hslen = h_sync_wid * 8;
1183 upper = v_total - v_sync_strt - v_sync_wid;
1184 lower = v_sync_strt - v_disp;
1185 vslen = v_sync_wid;
1186 sync = (h_sync_pol ? 0 : FB_SYNC_HOR_HIGH_ACT) |
1187 (v_sync_pol ? 0 : FB_SYNC_VERT_HIGH_ACT) |
1188 (c_sync ? FB_SYNC_COMP_HIGH_ACT : 0);
1189
1190 switch (pix_width) {
1191 case CRTC_PIX_WIDTH_8BPP:
1192 bpp = 8;
1193 var->red.offset = 0;
1194 var->red.length = 8;
1195 var->green.offset = 0;
1196 var->green.length = 8;
1197 var->blue.offset = 0;
1198 var->blue.length = 8;
1199 var->transp.offset = 0;
1200 var->transp.length = 0;
1201 break;
1202 case CRTC_PIX_WIDTH_15BPP: /* RGB 555 */
1203 bpp = 16;
1204 var->red.offset = 10;
1205 var->red.length = 5;
1206 var->green.offset = 5;
1207 var->green.length = 5;
1208 var->blue.offset = 0;
1209 var->blue.length = 5;
1210 var->transp.offset = 0;
1211 var->transp.length = 0;
1212 break;
1213 case CRTC_PIX_WIDTH_16BPP: /* RGB 565 */
1214 bpp = 16;
1215 var->red.offset = 11;
1216 var->red.length = 5;
1217 var->green.offset = 5;
1218 var->green.length = 6;
1219 var->blue.offset = 0;
1220 var->blue.length = 5;
1221 var->transp.offset = 0;
1222 var->transp.length = 0;
1223 break;
1224 case CRTC_PIX_WIDTH_24BPP: /* RGB 888 */
1225 bpp = 24;
1226 var->red.offset = 16;
1227 var->red.length = 8;
1228 var->green.offset = 8;
1229 var->green.length = 8;
1230 var->blue.offset = 0;
1231 var->blue.length = 8;
1232 var->transp.offset = 0;
1233 var->transp.length = 0;
1234 break;
1235 case CRTC_PIX_WIDTH_32BPP: /* ARGB 8888 */
1236 bpp = 32;
1237 var->red.offset = 16;
1238 var->red.length = 8;
1239 var->green.offset = 8;
1240 var->green.length = 8;
1241 var->blue.offset = 0;
1242 var->blue.length = 8;
1243 var->transp.offset = 24;
1244 var->transp.length = 8;
1245 break;
1246 default:
1247 PRINTKE("Invalid pixel width\n");
1248 return -EINVAL;
1249 }
1250
1251 /* output */
1252 var->xres = xres;
1253 var->yres = yres;
1254 var->xres_virtual = crtc->vxres;
1255 var->yres_virtual = crtc->vyres;
1256 var->bits_per_pixel = bpp;
1257 var->left_margin = left;
1258 var->right_margin = right;
1259 var->upper_margin = upper;
1260 var->lower_margin = lower;
1261 var->hsync_len = hslen;
1262 var->vsync_len = vslen;
1263 var->sync = sync;
1264 var->vmode = FB_VMODE_NONINTERLACED;
1265 /*
1266 * In double scan mode, the vertical parameters are doubled,
1267 * so we need to halve them to get the right values.
1268 * In interlaced mode the values are already correct,
1269 * so no correction is necessary.
1270 */
1271 if (interlace)
1272 var->vmode = FB_VMODE_INTERLACED;
1273
1274 if (double_scan) {
1275 var->vmode = FB_VMODE_DOUBLE;
1276 var->yres >>= 1;
1277 var->upper_margin >>= 1;
1278 var->lower_margin >>= 1;
1279 var->vsync_len >>= 1;
1280 }
1281
1282 return 0;
1283 }
1284
1285 /* ------------------------------------------------------------------------- */
1286
atyfb_set_par(struct fb_info * info)1287 static int atyfb_set_par(struct fb_info *info)
1288 {
1289 struct atyfb_par *par = (struct atyfb_par *) info->par;
1290 struct fb_var_screeninfo *var = &info->var;
1291 u32 tmp, pixclock;
1292 int err;
1293 #ifdef DEBUG
1294 struct fb_var_screeninfo debug;
1295 u32 pixclock_in_ps;
1296 #endif
1297 if (par->asleep)
1298 return 0;
1299
1300 err = aty_var_to_crtc(info, var, &par->crtc);
1301 if (err)
1302 return err;
1303
1304 pixclock = atyfb_get_pixclock(var, par);
1305
1306 if (pixclock == 0) {
1307 PRINTKE("Invalid pixclock\n");
1308 return -EINVAL;
1309 } else {
1310 err = par->pll_ops->var_to_pll(info, pixclock,
1311 var->bits_per_pixel, &par->pll);
1312 if (err)
1313 return err;
1314 }
1315
1316 par->accel_flags = var->accel_flags; /* hack */
1317
1318 if (var->accel_flags) {
1319 info->fbops->fb_sync = atyfb_sync;
1320 info->flags &= ~FBINFO_HWACCEL_DISABLED;
1321 } else {
1322 info->fbops->fb_sync = NULL;
1323 info->flags |= FBINFO_HWACCEL_DISABLED;
1324 }
1325
1326 if (par->blitter_may_be_busy)
1327 wait_for_idle(par);
1328
1329 aty_set_crtc(par, &par->crtc);
1330 par->dac_ops->set_dac(info, &par->pll,
1331 var->bits_per_pixel, par->accel_flags);
1332 par->pll_ops->set_pll(info, &par->pll);
1333
1334 #ifdef DEBUG
1335 if (par->pll_ops && par->pll_ops->pll_to_var)
1336 pixclock_in_ps = par->pll_ops->pll_to_var(info, &par->pll);
1337 else
1338 pixclock_in_ps = 0;
1339
1340 if (0 == pixclock_in_ps) {
1341 PRINTKE("ALERT ops->pll_to_var get 0\n");
1342 pixclock_in_ps = pixclock;
1343 }
1344
1345 memset(&debug, 0, sizeof(debug));
1346 if (!aty_crtc_to_var(&par->crtc, &debug)) {
1347 u32 hSync, vRefresh;
1348 u32 h_disp, h_sync_strt, h_sync_end, h_total;
1349 u32 v_disp, v_sync_strt, v_sync_end, v_total;
1350
1351 h_disp = debug.xres;
1352 h_sync_strt = h_disp + debug.right_margin;
1353 h_sync_end = h_sync_strt + debug.hsync_len;
1354 h_total = h_sync_end + debug.left_margin;
1355 v_disp = debug.yres;
1356 v_sync_strt = v_disp + debug.lower_margin;
1357 v_sync_end = v_sync_strt + debug.vsync_len;
1358 v_total = v_sync_end + debug.upper_margin;
1359
1360 hSync = 1000000000 / (pixclock_in_ps * h_total);
1361 vRefresh = (hSync * 1000) / v_total;
1362 if (par->crtc.gen_cntl & CRTC_INTERLACE_EN)
1363 vRefresh *= 2;
1364 if (par->crtc.gen_cntl & CRTC_DBL_SCAN_EN)
1365 vRefresh /= 2;
1366
1367 DPRINTK("atyfb_set_par\n");
1368 DPRINTK(" Set Visible Mode to %ix%i-%i\n",
1369 var->xres, var->yres, var->bits_per_pixel);
1370 DPRINTK(" Virtual resolution %ix%i, "
1371 "pixclock_in_ps %i (calculated %i)\n",
1372 var->xres_virtual, var->yres_virtual,
1373 pixclock, pixclock_in_ps);
1374 DPRINTK(" Dot clock: %i MHz\n",
1375 1000000 / pixclock_in_ps);
1376 DPRINTK(" Horizontal sync: %i kHz\n", hSync);
1377 DPRINTK(" Vertical refresh: %i Hz\n", vRefresh);
1378 DPRINTK(" x style: %i.%03i %i %i %i %i %i %i %i %i\n",
1379 1000000 / pixclock_in_ps, 1000000 % pixclock_in_ps,
1380 h_disp, h_sync_strt, h_sync_end, h_total,
1381 v_disp, v_sync_strt, v_sync_end, v_total);
1382 DPRINTK(" fb style: %i %i %i %i %i %i %i %i %i\n",
1383 pixclock_in_ps,
1384 debug.left_margin, h_disp, debug.right_margin, debug.hsync_len,
1385 debug.upper_margin, v_disp, debug.lower_margin, debug.vsync_len);
1386 }
1387 #endif /* DEBUG */
1388
1389 if (!M64_HAS(INTEGRATED)) {
1390 /* Don't forget MEM_CNTL */
1391 tmp = aty_ld_le32(MEM_CNTL, par) & 0xf0ffffff;
1392 switch (var->bits_per_pixel) {
1393 case 8:
1394 tmp |= 0x02000000;
1395 break;
1396 case 16:
1397 tmp |= 0x03000000;
1398 break;
1399 case 32:
1400 tmp |= 0x06000000;
1401 break;
1402 }
1403 aty_st_le32(MEM_CNTL, tmp, par);
1404 } else {
1405 tmp = aty_ld_le32(MEM_CNTL, par) & 0xf00fffff;
1406 if (!M64_HAS(MAGIC_POSTDIV))
1407 tmp |= par->mem_refresh_rate << 20;
1408 switch (var->bits_per_pixel) {
1409 case 8:
1410 case 24:
1411 tmp |= 0x00000000;
1412 break;
1413 case 16:
1414 tmp |= 0x04000000;
1415 break;
1416 case 32:
1417 tmp |= 0x08000000;
1418 break;
1419 }
1420 if (M64_HAS(CT_BUS)) {
1421 aty_st_le32(DAC_CNTL, 0x87010184, par);
1422 aty_st_le32(BUS_CNTL, 0x680000f9, par);
1423 } else if (M64_HAS(VT_BUS)) {
1424 aty_st_le32(DAC_CNTL, 0x87010184, par);
1425 aty_st_le32(BUS_CNTL, 0x680000f9, par);
1426 } else if (M64_HAS(MOBIL_BUS)) {
1427 aty_st_le32(DAC_CNTL, 0x80010102, par);
1428 aty_st_le32(BUS_CNTL, 0x7b33a040 | (par->aux_start ? BUS_APER_REG_DIS : 0), par);
1429 } else {
1430 /* GT */
1431 aty_st_le32(DAC_CNTL, 0x86010102, par);
1432 aty_st_le32(BUS_CNTL, 0x7b23a040 | (par->aux_start ? BUS_APER_REG_DIS : 0), par);
1433 aty_st_le32(EXT_MEM_CNTL, aty_ld_le32(EXT_MEM_CNTL, par) | 0x5000001, par);
1434 }
1435 aty_st_le32(MEM_CNTL, tmp, par);
1436 }
1437 aty_st_8(DAC_MASK, 0xff, par);
1438
1439 info->fix.line_length = calc_line_length(par, var->xres_virtual,
1440 var->bits_per_pixel);
1441
1442 info->fix.visual = var->bits_per_pixel <= 8 ?
1443 FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
1444
1445 /* Initialize the graphics engine */
1446 if (par->accel_flags & FB_ACCELF_TEXT)
1447 aty_init_engine(par, info);
1448
1449 #ifdef CONFIG_BOOTX_TEXT
1450 btext_update_display(info->fix.smem_start,
1451 (((par->crtc.h_tot_disp >> 16) & 0xff) + 1) * 8,
1452 ((par->crtc.v_tot_disp >> 16) & 0x7ff) + 1,
1453 var->bits_per_pixel,
1454 par->crtc.vxres * var->bits_per_pixel / 8);
1455 #endif /* CONFIG_BOOTX_TEXT */
1456 #ifdef DEBUG
1457 {
1458 /* dump non shadow CRTC, pll, LCD registers */
1459 int i; u32 base;
1460
1461 /* CRTC registers */
1462 base = 0x2000;
1463 printk("debug atyfb: Mach64 non-shadow register values:");
1464 for (i = 0; i < 256; i = i+4) {
1465 if (i % 16 == 0) {
1466 pr_cont("\n");
1467 printk("debug atyfb: 0x%04X: ", base + i);
1468 }
1469 pr_cont(" %08X", aty_ld_le32(i, par));
1470 }
1471 pr_cont("\n\n");
1472
1473 #ifdef CONFIG_FB_ATY_CT
1474 /* PLL registers */
1475 base = 0x00;
1476 printk("debug atyfb: Mach64 PLL register values:");
1477 for (i = 0; i < 64; i++) {
1478 if (i % 16 == 0) {
1479 pr_cont("\n");
1480 printk("debug atyfb: 0x%02X: ", base + i);
1481 }
1482 if (i % 4 == 0)
1483 pr_cont(" ");
1484 pr_cont("%02X", aty_ld_pll_ct(i, par));
1485 }
1486 pr_cont("\n\n");
1487 #endif /* CONFIG_FB_ATY_CT */
1488
1489 #ifdef CONFIG_FB_ATY_GENERIC_LCD
1490 if (par->lcd_table != 0) {
1491 /* LCD registers */
1492 base = 0x00;
1493 printk("debug atyfb: LCD register values:");
1494 if (M64_HAS(LT_LCD_REGS)) {
1495 for (i = 0; i <= POWER_MANAGEMENT; i++) {
1496 if (i == EXT_VERT_STRETCH)
1497 continue;
1498 pr_cont("\ndebug atyfb: 0x%04X: ",
1499 lt_lcd_regs[i]);
1500 pr_cont(" %08X", aty_ld_lcd(i, par));
1501 }
1502 } else {
1503 for (i = 0; i < 64; i++) {
1504 if (i % 4 == 0)
1505 pr_cont("\ndebug atyfb: 0x%02X: ",
1506 base + i);
1507 pr_cont(" %08X", aty_ld_lcd(i, par));
1508 }
1509 }
1510 pr_cont("\n\n");
1511 }
1512 #endif /* CONFIG_FB_ATY_GENERIC_LCD */
1513 }
1514 #endif /* DEBUG */
1515 return 0;
1516 }
1517
atyfb_check_var(struct fb_var_screeninfo * var,struct fb_info * info)1518 static int atyfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
1519 {
1520 struct atyfb_par *par = (struct atyfb_par *) info->par;
1521 int err;
1522 struct crtc crtc;
1523 union aty_pll pll;
1524 u32 pixclock;
1525
1526 memcpy(&pll, &par->pll, sizeof(pll));
1527
1528 err = aty_var_to_crtc(info, var, &crtc);
1529 if (err)
1530 return err;
1531
1532 pixclock = atyfb_get_pixclock(var, par);
1533
1534 if (pixclock == 0) {
1535 if (!(var->activate & FB_ACTIVATE_TEST))
1536 PRINTKE("Invalid pixclock\n");
1537 return -EINVAL;
1538 } else {
1539 err = par->pll_ops->var_to_pll(info, pixclock,
1540 var->bits_per_pixel, &pll);
1541 if (err)
1542 return err;
1543 }
1544
1545 if (var->accel_flags & FB_ACCELF_TEXT)
1546 info->var.accel_flags = FB_ACCELF_TEXT;
1547 else
1548 info->var.accel_flags = 0;
1549
1550 aty_crtc_to_var(&crtc, var);
1551 var->pixclock = par->pll_ops->pll_to_var(info, &pll);
1552 return 0;
1553 }
1554
set_off_pitch(struct atyfb_par * par,const struct fb_info * info)1555 static void set_off_pitch(struct atyfb_par *par, const struct fb_info *info)
1556 {
1557 u32 xoffset = info->var.xoffset;
1558 u32 yoffset = info->var.yoffset;
1559 u32 line_length = info->fix.line_length;
1560 u32 bpp = info->var.bits_per_pixel;
1561
1562 par->crtc.off_pitch =
1563 ((yoffset * line_length + xoffset * bpp / 8) / 8) |
1564 ((line_length / bpp) << 22);
1565 }
1566
1567
1568 /*
1569 * Open/Release the frame buffer device
1570 */
1571
atyfb_open(struct fb_info * info,int user)1572 static int atyfb_open(struct fb_info *info, int user)
1573 {
1574 struct atyfb_par *par = (struct atyfb_par *) info->par;
1575
1576 if (user) {
1577 par->open++;
1578 #ifdef __sparc__
1579 par->mmaped = 0;
1580 #endif
1581 }
1582 return 0;
1583 }
1584
aty_irq(int irq,void * dev_id)1585 static irqreturn_t aty_irq(int irq, void *dev_id)
1586 {
1587 struct atyfb_par *par = dev_id;
1588 int handled = 0;
1589 u32 int_cntl;
1590
1591 spin_lock(&par->int_lock);
1592
1593 int_cntl = aty_ld_le32(CRTC_INT_CNTL, par);
1594
1595 if (int_cntl & CRTC_VBLANK_INT) {
1596 /* clear interrupt */
1597 aty_st_le32(CRTC_INT_CNTL, (int_cntl & CRTC_INT_EN_MASK) |
1598 CRTC_VBLANK_INT_AK, par);
1599 par->vblank.count++;
1600 if (par->vblank.pan_display) {
1601 par->vblank.pan_display = 0;
1602 aty_st_le32(CRTC_OFF_PITCH, par->crtc.off_pitch, par);
1603 }
1604 wake_up_interruptible(&par->vblank.wait);
1605 handled = 1;
1606 }
1607
1608 spin_unlock(&par->int_lock);
1609
1610 return IRQ_RETVAL(handled);
1611 }
1612
aty_enable_irq(struct atyfb_par * par,int reenable)1613 static int aty_enable_irq(struct atyfb_par *par, int reenable)
1614 {
1615 u32 int_cntl;
1616
1617 if (!test_and_set_bit(0, &par->irq_flags)) {
1618 if (request_irq(par->irq, aty_irq, IRQF_SHARED, "atyfb", par)) {
1619 clear_bit(0, &par->irq_flags);
1620 return -EINVAL;
1621 }
1622 spin_lock_irq(&par->int_lock);
1623 int_cntl = aty_ld_le32(CRTC_INT_CNTL, par) & CRTC_INT_EN_MASK;
1624 /* clear interrupt */
1625 aty_st_le32(CRTC_INT_CNTL, int_cntl | CRTC_VBLANK_INT_AK, par);
1626 /* enable interrupt */
1627 aty_st_le32(CRTC_INT_CNTL, int_cntl | CRTC_VBLANK_INT_EN, par);
1628 spin_unlock_irq(&par->int_lock);
1629 } else if (reenable) {
1630 spin_lock_irq(&par->int_lock);
1631 int_cntl = aty_ld_le32(CRTC_INT_CNTL, par) & CRTC_INT_EN_MASK;
1632 if (!(int_cntl & CRTC_VBLANK_INT_EN)) {
1633 printk("atyfb: someone disabled IRQ [%08x]\n",
1634 int_cntl);
1635 /* re-enable interrupt */
1636 aty_st_le32(CRTC_INT_CNTL, int_cntl |
1637 CRTC_VBLANK_INT_EN, par);
1638 }
1639 spin_unlock_irq(&par->int_lock);
1640 }
1641
1642 return 0;
1643 }
1644
aty_disable_irq(struct atyfb_par * par)1645 static int aty_disable_irq(struct atyfb_par *par)
1646 {
1647 u32 int_cntl;
1648
1649 if (test_and_clear_bit(0, &par->irq_flags)) {
1650 if (par->vblank.pan_display) {
1651 par->vblank.pan_display = 0;
1652 aty_st_le32(CRTC_OFF_PITCH, par->crtc.off_pitch, par);
1653 }
1654 spin_lock_irq(&par->int_lock);
1655 int_cntl = aty_ld_le32(CRTC_INT_CNTL, par) & CRTC_INT_EN_MASK;
1656 /* disable interrupt */
1657 aty_st_le32(CRTC_INT_CNTL, int_cntl & ~CRTC_VBLANK_INT_EN, par);
1658 spin_unlock_irq(&par->int_lock);
1659 free_irq(par->irq, par);
1660 }
1661
1662 return 0;
1663 }
1664
atyfb_release(struct fb_info * info,int user)1665 static int atyfb_release(struct fb_info *info, int user)
1666 {
1667 struct atyfb_par *par = (struct atyfb_par *) info->par;
1668 #ifdef __sparc__
1669 int was_mmaped;
1670 #endif
1671
1672 if (!user)
1673 return 0;
1674
1675 par->open--;
1676 mdelay(1);
1677 wait_for_idle(par);
1678
1679 if (par->open)
1680 return 0;
1681
1682 #ifdef __sparc__
1683 was_mmaped = par->mmaped;
1684
1685 par->mmaped = 0;
1686
1687 if (was_mmaped) {
1688 struct fb_var_screeninfo var;
1689
1690 /*
1691 * Now reset the default display config, we have
1692 * no idea what the program(s) which mmap'd the
1693 * chip did to the configuration, nor whether it
1694 * restored it correctly.
1695 */
1696 var = default_var;
1697 if (noaccel)
1698 var.accel_flags &= ~FB_ACCELF_TEXT;
1699 else
1700 var.accel_flags |= FB_ACCELF_TEXT;
1701 if (var.yres == var.yres_virtual) {
1702 u32 videoram = (info->fix.smem_len - (PAGE_SIZE << 2));
1703 var.yres_virtual =
1704 ((videoram * 8) / var.bits_per_pixel) /
1705 var.xres_virtual;
1706 if (var.yres_virtual < var.yres)
1707 var.yres_virtual = var.yres;
1708 }
1709 }
1710 #endif
1711 aty_disable_irq(par);
1712
1713 return 0;
1714 }
1715
1716 /*
1717 * Pan or Wrap the Display
1718 *
1719 * This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
1720 */
1721
atyfb_pan_display(struct fb_var_screeninfo * var,struct fb_info * info)1722 static int atyfb_pan_display(struct fb_var_screeninfo *var,
1723 struct fb_info *info)
1724 {
1725 struct atyfb_par *par = (struct atyfb_par *) info->par;
1726 u32 xres, yres, xoffset, yoffset;
1727
1728 xres = (((par->crtc.h_tot_disp >> 16) & 0xff) + 1) * 8;
1729 yres = ((par->crtc.v_tot_disp >> 16) & 0x7ff) + 1;
1730 if (par->crtc.gen_cntl & CRTC_DBL_SCAN_EN)
1731 yres >>= 1;
1732 xoffset = (var->xoffset + 7) & ~7;
1733 yoffset = var->yoffset;
1734 if (xoffset + xres > par->crtc.vxres ||
1735 yoffset + yres > par->crtc.vyres)
1736 return -EINVAL;
1737 info->var.xoffset = xoffset;
1738 info->var.yoffset = yoffset;
1739 if (par->asleep)
1740 return 0;
1741
1742 set_off_pitch(par, info);
1743 if ((var->activate & FB_ACTIVATE_VBL) && !aty_enable_irq(par, 0)) {
1744 par->vblank.pan_display = 1;
1745 } else {
1746 par->vblank.pan_display = 0;
1747 aty_st_le32(CRTC_OFF_PITCH, par->crtc.off_pitch, par);
1748 }
1749
1750 return 0;
1751 }
1752
aty_waitforvblank(struct atyfb_par * par,u32 crtc)1753 static int aty_waitforvblank(struct atyfb_par *par, u32 crtc)
1754 {
1755 struct aty_interrupt *vbl;
1756 unsigned int count;
1757 int ret;
1758
1759 switch (crtc) {
1760 case 0:
1761 vbl = &par->vblank;
1762 break;
1763 default:
1764 return -ENODEV;
1765 }
1766
1767 ret = aty_enable_irq(par, 0);
1768 if (ret)
1769 return ret;
1770
1771 count = vbl->count;
1772 ret = wait_event_interruptible_timeout(vbl->wait,
1773 count != vbl->count, HZ/10);
1774 if (ret < 0)
1775 return ret;
1776 if (ret == 0) {
1777 aty_enable_irq(par, 1);
1778 return -ETIMEDOUT;
1779 }
1780
1781 return 0;
1782 }
1783
1784
1785 #ifdef DEBUG
1786 #define ATYIO_CLKR 0x41545900 /* ATY\00 */
1787 #define ATYIO_CLKW 0x41545901 /* ATY\01 */
1788
1789 struct atyclk {
1790 u32 ref_clk_per;
1791 u8 pll_ref_div;
1792 u8 mclk_fb_div;
1793 u8 mclk_post_div; /* 1,2,3,4,8 */
1794 u8 mclk_fb_mult; /* 2 or 4 */
1795 u8 xclk_post_div; /* 1,2,3,4,8 */
1796 u8 vclk_fb_div;
1797 u8 vclk_post_div; /* 1,2,3,4,6,8,12 */
1798 u32 dsp_xclks_per_row; /* 0-16383 */
1799 u32 dsp_loop_latency; /* 0-15 */
1800 u32 dsp_precision; /* 0-7 */
1801 u32 dsp_on; /* 0-2047 */
1802 u32 dsp_off; /* 0-2047 */
1803 };
1804
1805 #define ATYIO_FEATR 0x41545902 /* ATY\02 */
1806 #define ATYIO_FEATW 0x41545903 /* ATY\03 */
1807 #endif
1808
atyfb_ioctl(struct fb_info * info,u_int cmd,u_long arg)1809 static int atyfb_ioctl(struct fb_info *info, u_int cmd, u_long arg)
1810 {
1811 struct atyfb_par *par = (struct atyfb_par *) info->par;
1812 #ifdef __sparc__
1813 struct fbtype fbtyp;
1814 #endif
1815
1816 switch (cmd) {
1817 #ifdef __sparc__
1818 case FBIOGTYPE:
1819 fbtyp.fb_type = FBTYPE_PCI_GENERIC;
1820 fbtyp.fb_width = par->crtc.vxres;
1821 fbtyp.fb_height = par->crtc.vyres;
1822 fbtyp.fb_depth = info->var.bits_per_pixel;
1823 fbtyp.fb_cmsize = info->cmap.len;
1824 fbtyp.fb_size = info->fix.smem_len;
1825 if (copy_to_user((struct fbtype __user *) arg, &fbtyp,
1826 sizeof(fbtyp)))
1827 return -EFAULT;
1828 break;
1829 #endif /* __sparc__ */
1830
1831 case FBIO_WAITFORVSYNC:
1832 {
1833 u32 crtc;
1834
1835 if (get_user(crtc, (__u32 __user *) arg))
1836 return -EFAULT;
1837
1838 return aty_waitforvblank(par, crtc);
1839 }
1840
1841 #if defined(DEBUG) && defined(CONFIG_FB_ATY_CT)
1842 case ATYIO_CLKR:
1843 if (M64_HAS(INTEGRATED)) {
1844 struct atyclk clk = { 0 };
1845 union aty_pll *pll = &par->pll;
1846 u32 dsp_config = pll->ct.dsp_config;
1847 u32 dsp_on_off = pll->ct.dsp_on_off;
1848 clk.ref_clk_per = par->ref_clk_per;
1849 clk.pll_ref_div = pll->ct.pll_ref_div;
1850 clk.mclk_fb_div = pll->ct.mclk_fb_div;
1851 clk.mclk_post_div = pll->ct.mclk_post_div_real;
1852 clk.mclk_fb_mult = pll->ct.mclk_fb_mult;
1853 clk.xclk_post_div = pll->ct.xclk_post_div_real;
1854 clk.vclk_fb_div = pll->ct.vclk_fb_div;
1855 clk.vclk_post_div = pll->ct.vclk_post_div_real;
1856 clk.dsp_xclks_per_row = dsp_config & 0x3fff;
1857 clk.dsp_loop_latency = (dsp_config >> 16) & 0xf;
1858 clk.dsp_precision = (dsp_config >> 20) & 7;
1859 clk.dsp_off = dsp_on_off & 0x7ff;
1860 clk.dsp_on = (dsp_on_off >> 16) & 0x7ff;
1861 if (copy_to_user((struct atyclk __user *) arg, &clk,
1862 sizeof(clk)))
1863 return -EFAULT;
1864 } else
1865 return -EINVAL;
1866 break;
1867 case ATYIO_CLKW:
1868 if (M64_HAS(INTEGRATED)) {
1869 struct atyclk clk;
1870 union aty_pll *pll = &par->pll;
1871 if (copy_from_user(&clk, (struct atyclk __user *) arg,
1872 sizeof(clk)))
1873 return -EFAULT;
1874 par->ref_clk_per = clk.ref_clk_per;
1875 pll->ct.pll_ref_div = clk.pll_ref_div;
1876 pll->ct.mclk_fb_div = clk.mclk_fb_div;
1877 pll->ct.mclk_post_div_real = clk.mclk_post_div;
1878 pll->ct.mclk_fb_mult = clk.mclk_fb_mult;
1879 pll->ct.xclk_post_div_real = clk.xclk_post_div;
1880 pll->ct.vclk_fb_div = clk.vclk_fb_div;
1881 pll->ct.vclk_post_div_real = clk.vclk_post_div;
1882 pll->ct.dsp_config = (clk.dsp_xclks_per_row & 0x3fff) |
1883 ((clk.dsp_loop_latency & 0xf) << 16) |
1884 ((clk.dsp_precision & 7) << 20);
1885 pll->ct.dsp_on_off = (clk.dsp_off & 0x7ff) |
1886 ((clk.dsp_on & 0x7ff) << 16);
1887 /*aty_calc_pll_ct(info, &pll->ct);*/
1888 aty_set_pll_ct(info, pll);
1889 } else
1890 return -EINVAL;
1891 break;
1892 case ATYIO_FEATR:
1893 if (get_user(par->features, (u32 __user *) arg))
1894 return -EFAULT;
1895 break;
1896 case ATYIO_FEATW:
1897 if (put_user(par->features, (u32 __user *) arg))
1898 return -EFAULT;
1899 break;
1900 #endif /* DEBUG && CONFIG_FB_ATY_CT */
1901 default:
1902 return -EINVAL;
1903 }
1904 return 0;
1905 }
1906
atyfb_sync(struct fb_info * info)1907 static int atyfb_sync(struct fb_info *info)
1908 {
1909 struct atyfb_par *par = (struct atyfb_par *) info->par;
1910
1911 if (par->blitter_may_be_busy)
1912 wait_for_idle(par);
1913 return 0;
1914 }
1915
1916 #ifdef __sparc__
atyfb_mmap(struct fb_info * info,struct vm_area_struct * vma)1917 static int atyfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
1918 {
1919 struct atyfb_par *par = (struct atyfb_par *) info->par;
1920 unsigned int size, page, map_size = 0;
1921 unsigned long map_offset = 0;
1922 unsigned long off;
1923 int i;
1924
1925 if (!par->mmap_map)
1926 return -ENXIO;
1927
1928 if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
1929 return -EINVAL;
1930
1931 off = vma->vm_pgoff << PAGE_SHIFT;
1932 size = vma->vm_end - vma->vm_start;
1933
1934 /* VM_IO | VM_DONTEXPAND | VM_DONTDUMP are set by remap_pfn_range() */
1935
1936 if (((vma->vm_pgoff == 0) && (size == info->fix.smem_len)) ||
1937 ((off == info->fix.smem_len) && (size == PAGE_SIZE)))
1938 off += 0x8000000000000000UL;
1939
1940 vma->vm_pgoff = off >> PAGE_SHIFT; /* propagate off changes */
1941
1942 /* Each page, see which map applies */
1943 for (page = 0; page < size;) {
1944 map_size = 0;
1945 for (i = 0; par->mmap_map[i].size; i++) {
1946 unsigned long start = par->mmap_map[i].voff;
1947 unsigned long end = start + par->mmap_map[i].size;
1948 unsigned long offset = off + page;
1949
1950 if (start > offset)
1951 continue;
1952 if (offset >= end)
1953 continue;
1954
1955 map_size = par->mmap_map[i].size - (offset - start);
1956 map_offset = par->mmap_map[i].poff + (offset - start);
1957 break;
1958 }
1959 if (!map_size) {
1960 page += PAGE_SIZE;
1961 continue;
1962 }
1963 if (page + map_size > size)
1964 map_size = size - page;
1965
1966 pgprot_val(vma->vm_page_prot) &= ~(par->mmap_map[i].prot_mask);
1967 pgprot_val(vma->vm_page_prot) |= par->mmap_map[i].prot_flag;
1968
1969 if (remap_pfn_range(vma, vma->vm_start + page,
1970 map_offset >> PAGE_SHIFT, map_size, vma->vm_page_prot))
1971 return -EAGAIN;
1972
1973 page += map_size;
1974 }
1975
1976 if (!map_size)
1977 return -EINVAL;
1978
1979 if (!par->mmaped)
1980 par->mmaped = 1;
1981 return 0;
1982 }
1983 #endif /* __sparc__ */
1984
1985
1986
1987 #if defined(CONFIG_PM) && defined(CONFIG_PCI)
1988
1989 #ifdef CONFIG_PPC_PMAC
1990 /* Power management routines. Those are used for PowerBook sleep.
1991 */
aty_power_mgmt(int sleep,struct atyfb_par * par)1992 static int aty_power_mgmt(int sleep, struct atyfb_par *par)
1993 {
1994 u32 pm;
1995 int timeout;
1996
1997 pm = aty_ld_lcd(POWER_MANAGEMENT, par);
1998 pm = (pm & ~PWR_MGT_MODE_MASK) | PWR_MGT_MODE_REG;
1999 aty_st_lcd(POWER_MANAGEMENT, pm, par);
2000 pm = aty_ld_lcd(POWER_MANAGEMENT, par);
2001
2002 timeout = 2000;
2003 if (sleep) {
2004 /* Sleep */
2005 pm &= ~PWR_MGT_ON;
2006 aty_st_lcd(POWER_MANAGEMENT, pm, par);
2007 pm = aty_ld_lcd(POWER_MANAGEMENT, par);
2008 udelay(10);
2009 pm &= ~(PWR_BLON | AUTO_PWR_UP);
2010 pm |= SUSPEND_NOW;
2011 aty_st_lcd(POWER_MANAGEMENT, pm, par);
2012 pm = aty_ld_lcd(POWER_MANAGEMENT, par);
2013 udelay(10);
2014 pm |= PWR_MGT_ON;
2015 aty_st_lcd(POWER_MANAGEMENT, pm, par);
2016 do {
2017 pm = aty_ld_lcd(POWER_MANAGEMENT, par);
2018 mdelay(1);
2019 if ((--timeout) == 0)
2020 break;
2021 } while ((pm & PWR_MGT_STATUS_MASK) != PWR_MGT_STATUS_SUSPEND);
2022 } else {
2023 /* Wakeup */
2024 pm &= ~PWR_MGT_ON;
2025 aty_st_lcd(POWER_MANAGEMENT, pm, par);
2026 pm = aty_ld_lcd(POWER_MANAGEMENT, par);
2027 udelay(10);
2028 pm &= ~SUSPEND_NOW;
2029 pm |= (PWR_BLON | AUTO_PWR_UP);
2030 aty_st_lcd(POWER_MANAGEMENT, pm, par);
2031 pm = aty_ld_lcd(POWER_MANAGEMENT, par);
2032 udelay(10);
2033 pm |= PWR_MGT_ON;
2034 aty_st_lcd(POWER_MANAGEMENT, pm, par);
2035 do {
2036 pm = aty_ld_lcd(POWER_MANAGEMENT, par);
2037 mdelay(1);
2038 if ((--timeout) == 0)
2039 break;
2040 } while ((pm & PWR_MGT_STATUS_MASK) != 0);
2041 }
2042 mdelay(500);
2043
2044 return timeout ? 0 : -EIO;
2045 }
2046 #endif /* CONFIG_PPC_PMAC */
2047
atyfb_pci_suspend(struct pci_dev * pdev,pm_message_t state)2048 static int atyfb_pci_suspend(struct pci_dev *pdev, pm_message_t state)
2049 {
2050 struct fb_info *info = pci_get_drvdata(pdev);
2051 struct atyfb_par *par = (struct atyfb_par *) info->par;
2052
2053 if (state.event == pdev->dev.power.power_state.event)
2054 return 0;
2055
2056 console_lock();
2057
2058 fb_set_suspend(info, 1);
2059
2060 /* Idle & reset engine */
2061 wait_for_idle(par);
2062 aty_reset_engine(par);
2063
2064 /* Blank display and LCD */
2065 atyfb_blank(FB_BLANK_POWERDOWN, info);
2066
2067 par->asleep = 1;
2068 par->lock_blank = 1;
2069
2070 /*
2071 * Because we may change PCI D state ourselves, we need to
2072 * first save the config space content so the core can
2073 * restore it properly on resume.
2074 */
2075 pci_save_state(pdev);
2076
2077 #ifdef CONFIG_PPC_PMAC
2078 /* Set chip to "suspend" mode */
2079 if (machine_is(powermac) && aty_power_mgmt(1, par)) {
2080 par->asleep = 0;
2081 par->lock_blank = 0;
2082 atyfb_blank(FB_BLANK_UNBLANK, info);
2083 fb_set_suspend(info, 0);
2084 console_unlock();
2085 return -EIO;
2086 }
2087 #else
2088 pci_set_power_state(pdev, pci_choose_state(pdev, state));
2089 #endif
2090
2091 console_unlock();
2092
2093 pdev->dev.power.power_state = state;
2094
2095 return 0;
2096 }
2097
aty_resume_chip(struct fb_info * info)2098 static void aty_resume_chip(struct fb_info *info)
2099 {
2100 struct atyfb_par *par = info->par;
2101
2102 aty_st_le32(MEM_CNTL, par->mem_cntl, par);
2103
2104 if (par->pll_ops->resume_pll)
2105 par->pll_ops->resume_pll(info, &par->pll);
2106
2107 if (par->aux_start)
2108 aty_st_le32(BUS_CNTL,
2109 aty_ld_le32(BUS_CNTL, par) | BUS_APER_REG_DIS, par);
2110 }
2111
atyfb_pci_resume(struct pci_dev * pdev)2112 static int atyfb_pci_resume(struct pci_dev *pdev)
2113 {
2114 struct fb_info *info = pci_get_drvdata(pdev);
2115 struct atyfb_par *par = (struct atyfb_par *) info->par;
2116
2117 if (pdev->dev.power.power_state.event == PM_EVENT_ON)
2118 return 0;
2119
2120 console_lock();
2121
2122 /*
2123 * PCI state will have been restored by the core, so
2124 * we should be in D0 now with our config space fully
2125 * restored
2126 */
2127
2128 #ifdef CONFIG_PPC_PMAC
2129 if (machine_is(powermac) &&
2130 pdev->dev.power.power_state.event == PM_EVENT_SUSPEND)
2131 aty_power_mgmt(0, par);
2132 #endif
2133
2134 aty_resume_chip(info);
2135
2136 par->asleep = 0;
2137
2138 /* Restore display */
2139 atyfb_set_par(info);
2140
2141 /* Refresh */
2142 fb_set_suspend(info, 0);
2143
2144 /* Unblank */
2145 par->lock_blank = 0;
2146 atyfb_blank(FB_BLANK_UNBLANK, info);
2147
2148 console_unlock();
2149
2150 pdev->dev.power.power_state = PMSG_ON;
2151
2152 return 0;
2153 }
2154
2155 #endif /* defined(CONFIG_PM) && defined(CONFIG_PCI) */
2156
2157 /* Backlight */
2158 #ifdef CONFIG_FB_ATY_BACKLIGHT
2159 #define MAX_LEVEL 0xFF
2160
aty_bl_get_level_brightness(struct atyfb_par * par,int level)2161 static int aty_bl_get_level_brightness(struct atyfb_par *par, int level)
2162 {
2163 struct fb_info *info = pci_get_drvdata(par->pdev);
2164 int atylevel;
2165
2166 /* Get and convert the value */
2167 /* No locking of bl_curve since we read a single value */
2168 atylevel = info->bl_curve[level] * FB_BACKLIGHT_MAX / MAX_LEVEL;
2169
2170 if (atylevel < 0)
2171 atylevel = 0;
2172 else if (atylevel > MAX_LEVEL)
2173 atylevel = MAX_LEVEL;
2174
2175 return atylevel;
2176 }
2177
aty_bl_update_status(struct backlight_device * bd)2178 static int aty_bl_update_status(struct backlight_device *bd)
2179 {
2180 struct atyfb_par *par = bl_get_data(bd);
2181 unsigned int reg = aty_ld_lcd(LCD_MISC_CNTL, par);
2182 int level;
2183
2184 if (bd->props.power != FB_BLANK_UNBLANK ||
2185 bd->props.fb_blank != FB_BLANK_UNBLANK)
2186 level = 0;
2187 else
2188 level = bd->props.brightness;
2189
2190 reg |= (BLMOD_EN | BIASMOD_EN);
2191 if (level > 0) {
2192 reg &= ~BIAS_MOD_LEVEL_MASK;
2193 reg |= (aty_bl_get_level_brightness(par, level) << BIAS_MOD_LEVEL_SHIFT);
2194 } else {
2195 reg &= ~BIAS_MOD_LEVEL_MASK;
2196 reg |= (aty_bl_get_level_brightness(par, 0) << BIAS_MOD_LEVEL_SHIFT);
2197 }
2198 aty_st_lcd(LCD_MISC_CNTL, reg, par);
2199
2200 return 0;
2201 }
2202
2203 static const struct backlight_ops aty_bl_data = {
2204 .update_status = aty_bl_update_status,
2205 };
2206
aty_bl_init(struct atyfb_par * par)2207 static void aty_bl_init(struct atyfb_par *par)
2208 {
2209 struct backlight_properties props;
2210 struct fb_info *info = pci_get_drvdata(par->pdev);
2211 struct backlight_device *bd;
2212 char name[12];
2213
2214 #ifdef CONFIG_PMAC_BACKLIGHT
2215 if (!pmac_has_backlight_type("ati"))
2216 return;
2217 #endif
2218
2219 snprintf(name, sizeof(name), "atybl%d", info->node);
2220
2221 memset(&props, 0, sizeof(struct backlight_properties));
2222 props.type = BACKLIGHT_RAW;
2223 props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
2224 bd = backlight_device_register(name, info->dev, par, &aty_bl_data,
2225 &props);
2226 if (IS_ERR(bd)) {
2227 info->bl_dev = NULL;
2228 printk(KERN_WARNING "aty: Backlight registration failed\n");
2229 goto error;
2230 }
2231
2232 info->bl_dev = bd;
2233 fb_bl_default_curve(info, 0,
2234 0x3F * FB_BACKLIGHT_MAX / MAX_LEVEL,
2235 0xFF * FB_BACKLIGHT_MAX / MAX_LEVEL);
2236
2237 bd->props.brightness = bd->props.max_brightness;
2238 bd->props.power = FB_BLANK_UNBLANK;
2239 backlight_update_status(bd);
2240
2241 printk("aty: Backlight initialized (%s)\n", name);
2242
2243 return;
2244
2245 error:
2246 return;
2247 }
2248
2249 #ifdef CONFIG_PCI
aty_bl_exit(struct backlight_device * bd)2250 static void aty_bl_exit(struct backlight_device *bd)
2251 {
2252 backlight_device_unregister(bd);
2253 printk("aty: Backlight unloaded\n");
2254 }
2255 #endif /* CONFIG_PCI */
2256
2257 #endif /* CONFIG_FB_ATY_BACKLIGHT */
2258
aty_calc_mem_refresh(struct atyfb_par * par,int xclk)2259 static void aty_calc_mem_refresh(struct atyfb_par *par, int xclk)
2260 {
2261 static const int ragepro_tbl[] = {
2262 44, 50, 55, 66, 75, 80, 100
2263 };
2264 static const int ragexl_tbl[] = {
2265 50, 66, 75, 83, 90, 95, 100, 105,
2266 110, 115, 120, 125, 133, 143, 166
2267 };
2268 const int *refresh_tbl;
2269 int i, size;
2270
2271 if (M64_HAS(XL_MEM)) {
2272 refresh_tbl = ragexl_tbl;
2273 size = ARRAY_SIZE(ragexl_tbl);
2274 } else {
2275 refresh_tbl = ragepro_tbl;
2276 size = ARRAY_SIZE(ragepro_tbl);
2277 }
2278
2279 for (i = 0; i < size; i++) {
2280 if (xclk < refresh_tbl[i])
2281 break;
2282 }
2283 par->mem_refresh_rate = i;
2284 }
2285
2286 /*
2287 * Initialisation
2288 */
2289
2290 static struct fb_info *fb_list = NULL;
2291
2292 #if defined(__i386__) && defined(CONFIG_FB_ATY_GENERIC_LCD)
atyfb_get_timings_from_lcd(struct atyfb_par * par,struct fb_var_screeninfo * var)2293 static int atyfb_get_timings_from_lcd(struct atyfb_par *par,
2294 struct fb_var_screeninfo *var)
2295 {
2296 int ret = -EINVAL;
2297
2298 if (par->lcd_table != 0 && (aty_ld_lcd(LCD_GEN_CNTL, par) & LCD_ON)) {
2299 *var = default_var;
2300 var->xres = var->xres_virtual = par->lcd_hdisp;
2301 var->right_margin = par->lcd_right_margin;
2302 var->left_margin = par->lcd_hblank_len -
2303 (par->lcd_right_margin + par->lcd_hsync_dly +
2304 par->lcd_hsync_len);
2305 var->hsync_len = par->lcd_hsync_len + par->lcd_hsync_dly;
2306 var->yres = var->yres_virtual = par->lcd_vdisp;
2307 var->lower_margin = par->lcd_lower_margin;
2308 var->upper_margin = par->lcd_vblank_len -
2309 (par->lcd_lower_margin + par->lcd_vsync_len);
2310 var->vsync_len = par->lcd_vsync_len;
2311 var->pixclock = par->lcd_pixclock;
2312 ret = 0;
2313 }
2314
2315 return ret;
2316 }
2317 #endif /* defined(__i386__) && defined(CONFIG_FB_ATY_GENERIC_LCD) */
2318
aty_init(struct fb_info * info)2319 static int aty_init(struct fb_info *info)
2320 {
2321 struct atyfb_par *par = (struct atyfb_par *) info->par;
2322 const char *ramname = NULL, *xtal;
2323 int gtb_memsize, has_var = 0;
2324 struct fb_var_screeninfo var;
2325 int ret;
2326
2327 init_waitqueue_head(&par->vblank.wait);
2328 spin_lock_init(&par->int_lock);
2329
2330 #ifdef CONFIG_FB_ATY_GX
2331 if (!M64_HAS(INTEGRATED)) {
2332 u32 stat0;
2333 u8 dac_type, dac_subtype, clk_type;
2334 stat0 = aty_ld_le32(CNFG_STAT0, par);
2335 par->bus_type = (stat0 >> 0) & 0x07;
2336 par->ram_type = (stat0 >> 3) & 0x07;
2337 ramname = aty_gx_ram[par->ram_type];
2338 /* FIXME: clockchip/RAMDAC probing? */
2339 dac_type = (aty_ld_le32(DAC_CNTL, par) >> 16) & 0x07;
2340 #ifdef CONFIG_ATARI
2341 clk_type = CLK_ATI18818_1;
2342 dac_type = (stat0 >> 9) & 0x07;
2343 if (dac_type == 0x07)
2344 dac_subtype = DAC_ATT20C408;
2345 else
2346 dac_subtype = (aty_ld_8(SCRATCH_REG1 + 1, par) & 0xF0) | dac_type;
2347 #else
2348 dac_type = DAC_IBMRGB514;
2349 dac_subtype = DAC_IBMRGB514;
2350 clk_type = CLK_IBMRGB514;
2351 #endif
2352 switch (dac_subtype) {
2353 case DAC_IBMRGB514:
2354 par->dac_ops = &aty_dac_ibm514;
2355 break;
2356 #ifdef CONFIG_ATARI
2357 case DAC_ATI68860_B:
2358 case DAC_ATI68860_C:
2359 par->dac_ops = &aty_dac_ati68860b;
2360 break;
2361 case DAC_ATT20C408:
2362 case DAC_ATT21C498:
2363 par->dac_ops = &aty_dac_att21c498;
2364 break;
2365 #endif
2366 default:
2367 PRINTKI("aty_init: DAC type not implemented yet!\n");
2368 par->dac_ops = &aty_dac_unsupported;
2369 break;
2370 }
2371 switch (clk_type) {
2372 #ifdef CONFIG_ATARI
2373 case CLK_ATI18818_1:
2374 par->pll_ops = &aty_pll_ati18818_1;
2375 break;
2376 #else
2377 case CLK_IBMRGB514:
2378 par->pll_ops = &aty_pll_ibm514;
2379 break;
2380 #endif
2381 default:
2382 PRINTKI("aty_init: CLK type not implemented yet!");
2383 par->pll_ops = &aty_pll_unsupported;
2384 break;
2385 }
2386 }
2387 #endif /* CONFIG_FB_ATY_GX */
2388 #ifdef CONFIG_FB_ATY_CT
2389 if (M64_HAS(INTEGRATED)) {
2390 par->dac_ops = &aty_dac_ct;
2391 par->pll_ops = &aty_pll_ct;
2392 par->bus_type = PCI;
2393 par->ram_type = (aty_ld_le32(CNFG_STAT0, par) & 0x07);
2394 if (M64_HAS(XL_MEM))
2395 ramname = aty_xl_ram[par->ram_type];
2396 else
2397 ramname = aty_ct_ram[par->ram_type];
2398 /* for many chips, the mclk is 67 MHz for SDRAM, 63 MHz otherwise */
2399 if (par->pll_limits.mclk == 67 && par->ram_type < SDRAM)
2400 par->pll_limits.mclk = 63;
2401 /* Mobility + 32bit memory interface need halved XCLK. */
2402 if (M64_HAS(MOBIL_BUS) && par->ram_type == SDRAM32)
2403 par->pll_limits.xclk = (par->pll_limits.xclk + 1) >> 1;
2404 }
2405 #endif
2406 #ifdef CONFIG_PPC_PMAC
2407 /*
2408 * The Apple iBook1 uses non-standard memory frequencies.
2409 * We detect it and set the frequency manually.
2410 */
2411 if (of_machine_is_compatible("PowerBook2,1")) {
2412 par->pll_limits.mclk = 70;
2413 par->pll_limits.xclk = 53;
2414 }
2415 #endif
2416
2417 /* Allow command line to override clocks. */
2418 if (pll)
2419 par->pll_limits.pll_max = pll;
2420 if (mclk)
2421 par->pll_limits.mclk = mclk;
2422 if (xclk)
2423 par->pll_limits.xclk = xclk;
2424
2425 aty_calc_mem_refresh(par, par->pll_limits.xclk);
2426 par->pll_per = 1000000/par->pll_limits.pll_max;
2427 par->mclk_per = 1000000/par->pll_limits.mclk;
2428 par->xclk_per = 1000000/par->pll_limits.xclk;
2429
2430 par->ref_clk_per = 1000000000000ULL / 14318180;
2431 xtal = "14.31818";
2432
2433 #ifdef CONFIG_FB_ATY_CT
2434 if (M64_HAS(GTB_DSP)) {
2435 u8 pll_ref_div = aty_ld_pll_ct(PLL_REF_DIV, par);
2436
2437 if (pll_ref_div) {
2438 int diff1, diff2;
2439 diff1 = 510 * 14 / pll_ref_div - par->pll_limits.pll_max;
2440 diff2 = 510 * 29 / pll_ref_div - par->pll_limits.pll_max;
2441 if (diff1 < 0)
2442 diff1 = -diff1;
2443 if (diff2 < 0)
2444 diff2 = -diff2;
2445 if (diff2 < diff1) {
2446 par->ref_clk_per = 1000000000000ULL / 29498928;
2447 xtal = "29.498928";
2448 }
2449 }
2450 }
2451 #endif /* CONFIG_FB_ATY_CT */
2452
2453 /* save previous video mode */
2454 aty_get_crtc(par, &par->saved_crtc);
2455 if (par->pll_ops->get_pll)
2456 par->pll_ops->get_pll(info, &par->saved_pll);
2457
2458 par->mem_cntl = aty_ld_le32(MEM_CNTL, par);
2459 gtb_memsize = M64_HAS(GTB_DSP);
2460 if (gtb_memsize)
2461 /* 0xF used instead of MEM_SIZE_ALIAS */
2462 switch (par->mem_cntl & 0xF) {
2463 case MEM_SIZE_512K:
2464 info->fix.smem_len = 0x80000;
2465 break;
2466 case MEM_SIZE_1M:
2467 info->fix.smem_len = 0x100000;
2468 break;
2469 case MEM_SIZE_2M_GTB:
2470 info->fix.smem_len = 0x200000;
2471 break;
2472 case MEM_SIZE_4M_GTB:
2473 info->fix.smem_len = 0x400000;
2474 break;
2475 case MEM_SIZE_6M_GTB:
2476 info->fix.smem_len = 0x600000;
2477 break;
2478 case MEM_SIZE_8M_GTB:
2479 info->fix.smem_len = 0x800000;
2480 break;
2481 default:
2482 info->fix.smem_len = 0x80000;
2483 } else
2484 switch (par->mem_cntl & MEM_SIZE_ALIAS) {
2485 case MEM_SIZE_512K:
2486 info->fix.smem_len = 0x80000;
2487 break;
2488 case MEM_SIZE_1M:
2489 info->fix.smem_len = 0x100000;
2490 break;
2491 case MEM_SIZE_2M:
2492 info->fix.smem_len = 0x200000;
2493 break;
2494 case MEM_SIZE_4M:
2495 info->fix.smem_len = 0x400000;
2496 break;
2497 case MEM_SIZE_6M:
2498 info->fix.smem_len = 0x600000;
2499 break;
2500 case MEM_SIZE_8M:
2501 info->fix.smem_len = 0x800000;
2502 break;
2503 default:
2504 info->fix.smem_len = 0x80000;
2505 }
2506
2507 if (M64_HAS(MAGIC_VRAM_SIZE)) {
2508 if (aty_ld_le32(CNFG_STAT1, par) & 0x40000000)
2509 info->fix.smem_len += 0x400000;
2510 }
2511
2512 if (vram) {
2513 info->fix.smem_len = vram * 1024;
2514 par->mem_cntl &= ~(gtb_memsize ? 0xF : MEM_SIZE_ALIAS);
2515 if (info->fix.smem_len <= 0x80000)
2516 par->mem_cntl |= MEM_SIZE_512K;
2517 else if (info->fix.smem_len <= 0x100000)
2518 par->mem_cntl |= MEM_SIZE_1M;
2519 else if (info->fix.smem_len <= 0x200000)
2520 par->mem_cntl |= gtb_memsize ? MEM_SIZE_2M_GTB : MEM_SIZE_2M;
2521 else if (info->fix.smem_len <= 0x400000)
2522 par->mem_cntl |= gtb_memsize ? MEM_SIZE_4M_GTB : MEM_SIZE_4M;
2523 else if (info->fix.smem_len <= 0x600000)
2524 par->mem_cntl |= gtb_memsize ? MEM_SIZE_6M_GTB : MEM_SIZE_6M;
2525 else
2526 par->mem_cntl |= gtb_memsize ? MEM_SIZE_8M_GTB : MEM_SIZE_8M;
2527 aty_st_le32(MEM_CNTL, par->mem_cntl, par);
2528 }
2529
2530 /*
2531 * Reg Block 0 (CT-compatible block) is at mmio_start
2532 * Reg Block 1 (multimedia extensions) is at mmio_start - 0x400
2533 */
2534 if (M64_HAS(GX)) {
2535 info->fix.mmio_len = 0x400;
2536 info->fix.accel = FB_ACCEL_ATI_MACH64GX;
2537 } else if (M64_HAS(CT)) {
2538 info->fix.mmio_len = 0x400;
2539 info->fix.accel = FB_ACCEL_ATI_MACH64CT;
2540 } else if (M64_HAS(VT)) {
2541 info->fix.mmio_start -= 0x400;
2542 info->fix.mmio_len = 0x800;
2543 info->fix.accel = FB_ACCEL_ATI_MACH64VT;
2544 } else {/* GT */
2545 info->fix.mmio_start -= 0x400;
2546 info->fix.mmio_len = 0x800;
2547 info->fix.accel = FB_ACCEL_ATI_MACH64GT;
2548 }
2549
2550 PRINTKI("%d%c %s, %s MHz XTAL, %d MHz PLL, %d Mhz MCLK, %d MHz XCLK\n",
2551 info->fix.smem_len == 0x80000 ? 512 : (info->fix.smem_len>>20),
2552 info->fix.smem_len == 0x80000 ? 'K' : 'M', ramname, xtal,
2553 par->pll_limits.pll_max, par->pll_limits.mclk,
2554 par->pll_limits.xclk);
2555
2556 #if defined(DEBUG) && defined(CONFIG_FB_ATY_CT)
2557 if (M64_HAS(INTEGRATED)) {
2558 int i;
2559 printk("debug atyfb: BUS_CNTL DAC_CNTL MEM_CNTL "
2560 "EXT_MEM_CNTL CRTC_GEN_CNTL DSP_CONFIG "
2561 "DSP_ON_OFF CLOCK_CNTL\n"
2562 "debug atyfb: %08x %08x %08x "
2563 "%08x %08x %08x "
2564 "%08x %08x\n"
2565 "debug atyfb: PLL",
2566 aty_ld_le32(BUS_CNTL, par),
2567 aty_ld_le32(DAC_CNTL, par),
2568 aty_ld_le32(MEM_CNTL, par),
2569 aty_ld_le32(EXT_MEM_CNTL, par),
2570 aty_ld_le32(CRTC_GEN_CNTL, par),
2571 aty_ld_le32(DSP_CONFIG, par),
2572 aty_ld_le32(DSP_ON_OFF, par),
2573 aty_ld_le32(CLOCK_CNTL, par));
2574 for (i = 0; i < 40; i++)
2575 pr_cont(" %02x", aty_ld_pll_ct(i, par));
2576 pr_cont("\n");
2577 }
2578 #endif
2579 if (par->pll_ops->init_pll)
2580 par->pll_ops->init_pll(info, &par->pll);
2581 if (par->pll_ops->resume_pll)
2582 par->pll_ops->resume_pll(info, &par->pll);
2583
2584 aty_fudge_framebuffer_len(info);
2585
2586 /*
2587 * Disable register access through the linear aperture
2588 * if the auxiliary aperture is used so we can access
2589 * the full 8 MB of video RAM on 8 MB boards.
2590 */
2591 if (par->aux_start)
2592 aty_st_le32(BUS_CNTL, aty_ld_le32(BUS_CNTL, par) |
2593 BUS_APER_REG_DIS, par);
2594
2595 if (!nomtrr)
2596 /*
2597 * Only the ioremap_wc()'d area will get WC here
2598 * since ioremap_uc() was used on the entire PCI BAR.
2599 */
2600 par->wc_cookie = arch_phys_wc_add(par->res_start,
2601 par->res_size);
2602
2603 info->fbops = &atyfb_ops;
2604 info->pseudo_palette = par->pseudo_palette;
2605 info->flags = FBINFO_DEFAULT |
2606 FBINFO_HWACCEL_IMAGEBLIT |
2607 FBINFO_HWACCEL_FILLRECT |
2608 FBINFO_HWACCEL_COPYAREA |
2609 FBINFO_HWACCEL_YPAN |
2610 FBINFO_READS_FAST;
2611
2612 #ifdef CONFIG_PMAC_BACKLIGHT
2613 if (M64_HAS(G3_PB_1_1) && of_machine_is_compatible("PowerBook1,1")) {
2614 /*
2615 * these bits let the 101 powerbook
2616 * wake up from sleep -- paulus
2617 */
2618 aty_st_lcd(POWER_MANAGEMENT, aty_ld_lcd(POWER_MANAGEMENT, par) |
2619 USE_F32KHZ | TRISTATE_MEM_EN, par);
2620 } else
2621 #endif
2622 if (M64_HAS(MOBIL_BUS) && backlight) {
2623 #ifdef CONFIG_FB_ATY_BACKLIGHT
2624 aty_bl_init(par);
2625 #endif
2626 }
2627
2628 memset(&var, 0, sizeof(var));
2629 #ifdef CONFIG_PPC
2630 if (machine_is(powermac)) {
2631 /*
2632 * FIXME: The NVRAM stuff should be put in a Mac-specific file,
2633 * as it applies to all Mac video cards
2634 */
2635 if (mode) {
2636 if (mac_find_mode(&var, info, mode, 8))
2637 has_var = 1;
2638 } else {
2639 if (default_vmode == VMODE_CHOOSE) {
2640 int sense;
2641 if (M64_HAS(G3_PB_1024x768))
2642 /* G3 PowerBook with 1024x768 LCD */
2643 default_vmode = VMODE_1024_768_60;
2644 else if (of_machine_is_compatible("iMac"))
2645 default_vmode = VMODE_1024_768_75;
2646 else if (of_machine_is_compatible("PowerBook2,1"))
2647 /* iBook with 800x600 LCD */
2648 default_vmode = VMODE_800_600_60;
2649 else
2650 default_vmode = VMODE_640_480_67;
2651 sense = read_aty_sense(par);
2652 PRINTKI("monitor sense=%x, mode %d\n",
2653 sense, mac_map_monitor_sense(sense));
2654 }
2655 if (default_vmode <= 0 || default_vmode > VMODE_MAX)
2656 default_vmode = VMODE_640_480_60;
2657 if (default_cmode < CMODE_8 || default_cmode > CMODE_32)
2658 default_cmode = CMODE_8;
2659 if (!mac_vmode_to_var(default_vmode, default_cmode,
2660 &var))
2661 has_var = 1;
2662 }
2663 }
2664
2665 #endif /* !CONFIG_PPC */
2666
2667 #if defined(__i386__) && defined(CONFIG_FB_ATY_GENERIC_LCD)
2668 if (!atyfb_get_timings_from_lcd(par, &var))
2669 has_var = 1;
2670 #endif
2671
2672 if (mode && fb_find_mode(&var, info, mode, NULL, 0, &defmode, 8))
2673 has_var = 1;
2674
2675 if (!has_var)
2676 var = default_var;
2677
2678 if (noaccel)
2679 var.accel_flags &= ~FB_ACCELF_TEXT;
2680 else
2681 var.accel_flags |= FB_ACCELF_TEXT;
2682
2683 if (comp_sync != -1) {
2684 if (!comp_sync)
2685 var.sync &= ~FB_SYNC_COMP_HIGH_ACT;
2686 else
2687 var.sync |= FB_SYNC_COMP_HIGH_ACT;
2688 }
2689
2690 if (var.yres == var.yres_virtual) {
2691 u32 videoram = (info->fix.smem_len - (PAGE_SIZE << 2));
2692 var.yres_virtual = ((videoram * 8) / var.bits_per_pixel) / var.xres_virtual;
2693 if (var.yres_virtual < var.yres)
2694 var.yres_virtual = var.yres;
2695 }
2696
2697 ret = atyfb_check_var(&var, info);
2698 if (ret) {
2699 PRINTKE("can't set default video mode\n");
2700 goto aty_init_exit;
2701 }
2702
2703 #ifdef CONFIG_FB_ATY_CT
2704 if (!noaccel && M64_HAS(INTEGRATED))
2705 aty_init_cursor(info);
2706 #endif /* CONFIG_FB_ATY_CT */
2707 info->var = var;
2708
2709 ret = fb_alloc_cmap(&info->cmap, 256, 0);
2710 if (ret < 0)
2711 goto aty_init_exit;
2712
2713 ret = register_framebuffer(info);
2714 if (ret < 0) {
2715 fb_dealloc_cmap(&info->cmap);
2716 goto aty_init_exit;
2717 }
2718
2719 fb_list = info;
2720
2721 PRINTKI("fb%d: %s frame buffer device on %s\n",
2722 info->node, info->fix.id, par->bus_type == ISA ? "ISA" : "PCI");
2723 return 0;
2724
2725 aty_init_exit:
2726 /* restore video mode */
2727 aty_set_crtc(par, &par->saved_crtc);
2728 par->pll_ops->set_pll(info, &par->saved_pll);
2729 arch_phys_wc_del(par->wc_cookie);
2730
2731 return ret;
2732 }
2733
2734 #if defined(CONFIG_ATARI) && !defined(MODULE)
store_video_par(char * video_str,unsigned char m64_num)2735 static int store_video_par(char *video_str, unsigned char m64_num)
2736 {
2737 char *p;
2738 unsigned long vmembase, size, guiregbase;
2739
2740 PRINTKI("store_video_par() '%s' \n", video_str);
2741
2742 if (!(p = strsep(&video_str, ";")) || !*p)
2743 goto mach64_invalid;
2744 vmembase = simple_strtoul(p, NULL, 0);
2745 if (!(p = strsep(&video_str, ";")) || !*p)
2746 goto mach64_invalid;
2747 size = simple_strtoul(p, NULL, 0);
2748 if (!(p = strsep(&video_str, ";")) || !*p)
2749 goto mach64_invalid;
2750 guiregbase = simple_strtoul(p, NULL, 0);
2751
2752 phys_vmembase[m64_num] = vmembase;
2753 phys_size[m64_num] = size;
2754 phys_guiregbase[m64_num] = guiregbase;
2755 PRINTKI("stored them all: $%08lX $%08lX $%08lX \n", vmembase, size,
2756 guiregbase);
2757 return 0;
2758
2759 mach64_invalid:
2760 phys_vmembase[m64_num] = 0;
2761 return -1;
2762 }
2763 #endif /* CONFIG_ATARI && !MODULE */
2764
2765 /*
2766 * Blank the display.
2767 */
2768
atyfb_blank(int blank,struct fb_info * info)2769 static int atyfb_blank(int blank, struct fb_info *info)
2770 {
2771 struct atyfb_par *par = (struct atyfb_par *) info->par;
2772 u32 gen_cntl;
2773
2774 if (par->lock_blank || par->asleep)
2775 return 0;
2776
2777 #ifdef CONFIG_FB_ATY_GENERIC_LCD
2778 if (par->lcd_table && blank > FB_BLANK_NORMAL &&
2779 (aty_ld_lcd(LCD_GEN_CNTL, par) & LCD_ON)) {
2780 u32 pm = aty_ld_lcd(POWER_MANAGEMENT, par);
2781 pm &= ~PWR_BLON;
2782 aty_st_lcd(POWER_MANAGEMENT, pm, par);
2783 }
2784 #endif
2785
2786 gen_cntl = aty_ld_le32(CRTC_GEN_CNTL, par);
2787 gen_cntl &= ~0x400004c;
2788 switch (blank) {
2789 case FB_BLANK_UNBLANK:
2790 break;
2791 case FB_BLANK_NORMAL:
2792 gen_cntl |= 0x4000040;
2793 break;
2794 case FB_BLANK_VSYNC_SUSPEND:
2795 gen_cntl |= 0x4000048;
2796 break;
2797 case FB_BLANK_HSYNC_SUSPEND:
2798 gen_cntl |= 0x4000044;
2799 break;
2800 case FB_BLANK_POWERDOWN:
2801 gen_cntl |= 0x400004c;
2802 break;
2803 }
2804 aty_st_le32(CRTC_GEN_CNTL, gen_cntl, par);
2805
2806 #ifdef CONFIG_FB_ATY_GENERIC_LCD
2807 if (par->lcd_table && blank <= FB_BLANK_NORMAL &&
2808 (aty_ld_lcd(LCD_GEN_CNTL, par) & LCD_ON)) {
2809 u32 pm = aty_ld_lcd(POWER_MANAGEMENT, par);
2810 pm |= PWR_BLON;
2811 aty_st_lcd(POWER_MANAGEMENT, pm, par);
2812 }
2813 #endif
2814
2815 return 0;
2816 }
2817
aty_st_pal(u_int regno,u_int red,u_int green,u_int blue,const struct atyfb_par * par)2818 static void aty_st_pal(u_int regno, u_int red, u_int green, u_int blue,
2819 const struct atyfb_par *par)
2820 {
2821 aty_st_8(DAC_W_INDEX, regno, par);
2822 aty_st_8(DAC_DATA, red, par);
2823 aty_st_8(DAC_DATA, green, par);
2824 aty_st_8(DAC_DATA, blue, par);
2825 }
2826
2827 /*
2828 * Set a single color register. The values supplied are already
2829 * rounded down to the hardware's capabilities (according to the
2830 * entries in the var structure). Return != 0 for invalid regno.
2831 * !! 4 & 8 = PSEUDO, > 8 = DIRECTCOLOR
2832 */
2833
atyfb_setcolreg(u_int regno,u_int red,u_int green,u_int blue,u_int transp,struct fb_info * info)2834 static int atyfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
2835 u_int transp, struct fb_info *info)
2836 {
2837 struct atyfb_par *par = (struct atyfb_par *) info->par;
2838 int i, depth;
2839 u32 *pal = info->pseudo_palette;
2840
2841 depth = info->var.bits_per_pixel;
2842 if (depth == 16)
2843 depth = (info->var.green.length == 5) ? 15 : 16;
2844
2845 if (par->asleep)
2846 return 0;
2847
2848 if (regno > 255 ||
2849 (depth == 16 && regno > 63) ||
2850 (depth == 15 && regno > 31))
2851 return 1;
2852
2853 red >>= 8;
2854 green >>= 8;
2855 blue >>= 8;
2856
2857 par->palette[regno].red = red;
2858 par->palette[regno].green = green;
2859 par->palette[regno].blue = blue;
2860
2861 if (regno < 16) {
2862 switch (depth) {
2863 case 15:
2864 pal[regno] = (regno << 10) | (regno << 5) | regno;
2865 break;
2866 case 16:
2867 pal[regno] = (regno << 11) | (regno << 5) | regno;
2868 break;
2869 case 24:
2870 pal[regno] = (regno << 16) | (regno << 8) | regno;
2871 break;
2872 case 32:
2873 i = (regno << 8) | regno;
2874 pal[regno] = (i << 16) | i;
2875 break;
2876 }
2877 }
2878
2879 i = aty_ld_8(DAC_CNTL, par) & 0xfc;
2880 if (M64_HAS(EXTRA_BRIGHT))
2881 i |= 0x2; /* DAC_CNTL | 0x2 turns off the extra brightness for gt */
2882 aty_st_8(DAC_CNTL, i, par);
2883 aty_st_8(DAC_MASK, 0xff, par);
2884
2885 if (M64_HAS(INTEGRATED)) {
2886 if (depth == 16) {
2887 if (regno < 32)
2888 aty_st_pal(regno << 3, red,
2889 par->palette[regno << 1].green,
2890 blue, par);
2891 red = par->palette[regno >> 1].red;
2892 blue = par->palette[regno >> 1].blue;
2893 regno <<= 2;
2894 } else if (depth == 15) {
2895 regno <<= 3;
2896 for (i = 0; i < 8; i++)
2897 aty_st_pal(regno + i, red, green, blue, par);
2898 }
2899 }
2900 aty_st_pal(regno, red, green, blue, par);
2901
2902 return 0;
2903 }
2904
2905 #ifdef CONFIG_PCI
2906
2907 #ifdef __sparc__
2908
atyfb_setup_sparc(struct pci_dev * pdev,struct fb_info * info,unsigned long addr)2909 static int atyfb_setup_sparc(struct pci_dev *pdev, struct fb_info *info,
2910 unsigned long addr)
2911 {
2912 struct atyfb_par *par = info->par;
2913 struct device_node *dp;
2914 u32 mem, chip_id;
2915 int i, j, ret;
2916
2917 /*
2918 * Map memory-mapped registers.
2919 */
2920 par->ati_regbase = (void *)addr + 0x7ffc00UL;
2921 info->fix.mmio_start = addr + 0x7ffc00UL;
2922
2923 /*
2924 * Map in big-endian aperture.
2925 */
2926 info->screen_base = (char *) (addr + 0x800000UL);
2927 info->fix.smem_start = addr + 0x800000UL;
2928
2929 /*
2930 * Figure mmap addresses from PCI config space.
2931 * Split Framebuffer in big- and little-endian halfs.
2932 */
2933 for (i = 0; i < 6 && pdev->resource[i].start; i++)
2934 /* nothing */ ;
2935 j = i + 4;
2936
2937 par->mmap_map = kcalloc(j, sizeof(*par->mmap_map), GFP_ATOMIC);
2938 if (!par->mmap_map) {
2939 PRINTKE("atyfb_setup_sparc() can't alloc mmap_map\n");
2940 return -ENOMEM;
2941 }
2942
2943 for (i = 0, j = 2; i < 6 && pdev->resource[i].start; i++) {
2944 struct resource *rp = &pdev->resource[i];
2945 int io, breg = PCI_BASE_ADDRESS_0 + (i << 2);
2946 unsigned long base;
2947 u32 size, pbase;
2948
2949 base = rp->start;
2950
2951 io = (rp->flags & IORESOURCE_IO);
2952
2953 size = rp->end - base + 1;
2954
2955 pci_read_config_dword(pdev, breg, &pbase);
2956
2957 if (io)
2958 size &= ~1;
2959
2960 /*
2961 * Map the framebuffer a second time, this time without
2962 * the braindead _PAGE_IE setting. This is used by the
2963 * fixed Xserver, but we need to maintain the old mapping
2964 * to stay compatible with older ones...
2965 */
2966 if (base == addr) {
2967 par->mmap_map[j].voff = (pbase + 0x10000000) & PAGE_MASK;
2968 par->mmap_map[j].poff = base & PAGE_MASK;
2969 par->mmap_map[j].size = (size + ~PAGE_MASK) & PAGE_MASK;
2970 par->mmap_map[j].prot_mask = _PAGE_CACHE;
2971 par->mmap_map[j].prot_flag = _PAGE_E;
2972 j++;
2973 }
2974
2975 /*
2976 * Here comes the old framebuffer mapping with _PAGE_IE
2977 * set for the big endian half of the framebuffer...
2978 */
2979 if (base == addr) {
2980 par->mmap_map[j].voff = (pbase + 0x800000) & PAGE_MASK;
2981 par->mmap_map[j].poff = (base + 0x800000) & PAGE_MASK;
2982 par->mmap_map[j].size = 0x800000;
2983 par->mmap_map[j].prot_mask = _PAGE_CACHE;
2984 par->mmap_map[j].prot_flag = _PAGE_E | _PAGE_IE;
2985 size -= 0x800000;
2986 j++;
2987 }
2988
2989 par->mmap_map[j].voff = pbase & PAGE_MASK;
2990 par->mmap_map[j].poff = base & PAGE_MASK;
2991 par->mmap_map[j].size = (size + ~PAGE_MASK) & PAGE_MASK;
2992 par->mmap_map[j].prot_mask = _PAGE_CACHE;
2993 par->mmap_map[j].prot_flag = _PAGE_E;
2994 j++;
2995 }
2996
2997 ret = correct_chipset(par);
2998 if (ret)
2999 return ret;
3000
3001 if (IS_XL(pdev->device)) {
3002 /*
3003 * Fix PROMs idea of MEM_CNTL settings...
3004 */
3005 mem = aty_ld_le32(MEM_CNTL, par);
3006 chip_id = aty_ld_le32(CNFG_CHIP_ID, par);
3007 if (((chip_id & CFG_CHIP_TYPE) == VT_CHIP_ID) && !((chip_id >> 24) & 1)) {
3008 switch (mem & 0x0f) {
3009 case 3:
3010 mem = (mem & ~(0x0f)) | 2;
3011 break;
3012 case 7:
3013 mem = (mem & ~(0x0f)) | 3;
3014 break;
3015 case 9:
3016 mem = (mem & ~(0x0f)) | 4;
3017 break;
3018 case 11:
3019 mem = (mem & ~(0x0f)) | 5;
3020 break;
3021 default:
3022 break;
3023 }
3024 if ((aty_ld_le32(CNFG_STAT0, par) & 7) >= SDRAM)
3025 mem &= ~(0x00700000);
3026 }
3027 mem &= ~(0xcf80e000); /* Turn off all undocumented bits. */
3028 aty_st_le32(MEM_CNTL, mem, par);
3029 }
3030
3031 dp = pci_device_to_OF_node(pdev);
3032 if (dp == of_console_device) {
3033 struct fb_var_screeninfo *var = &default_var;
3034 unsigned int N, P, Q, M, T, R;
3035 u32 v_total, h_total;
3036 struct crtc crtc;
3037 u8 pll_regs[16];
3038 u8 clock_cntl;
3039
3040 crtc.vxres = of_getintprop_default(dp, "width", 1024);
3041 crtc.vyres = of_getintprop_default(dp, "height", 768);
3042 var->bits_per_pixel = of_getintprop_default(dp, "depth", 8);
3043 var->xoffset = var->yoffset = 0;
3044 crtc.h_tot_disp = aty_ld_le32(CRTC_H_TOTAL_DISP, par);
3045 crtc.h_sync_strt_wid = aty_ld_le32(CRTC_H_SYNC_STRT_WID, par);
3046 crtc.v_tot_disp = aty_ld_le32(CRTC_V_TOTAL_DISP, par);
3047 crtc.v_sync_strt_wid = aty_ld_le32(CRTC_V_SYNC_STRT_WID, par);
3048 crtc.gen_cntl = aty_ld_le32(CRTC_GEN_CNTL, par);
3049 aty_crtc_to_var(&crtc, var);
3050
3051 h_total = var->xres + var->right_margin + var->hsync_len + var->left_margin;
3052 v_total = var->yres + var->lower_margin + var->vsync_len + var->upper_margin;
3053
3054 /*
3055 * Read the PLL to figure actual Refresh Rate.
3056 */
3057 clock_cntl = aty_ld_8(CLOCK_CNTL, par);
3058 /* DPRINTK("CLOCK_CNTL %02x\n", clock_cntl); */
3059 for (i = 0; i < 16; i++)
3060 pll_regs[i] = aty_ld_pll_ct(i, par);
3061
3062 /*
3063 * PLL Reference Divider M:
3064 */
3065 M = pll_regs[PLL_REF_DIV];
3066
3067 /*
3068 * PLL Feedback Divider N (Dependent on CLOCK_CNTL):
3069 */
3070 N = pll_regs[VCLK0_FB_DIV + (clock_cntl & 3)];
3071
3072 /*
3073 * PLL Post Divider P (Dependent on CLOCK_CNTL):
3074 */
3075 P = aty_postdividers[((pll_regs[VCLK_POST_DIV] >> ((clock_cntl & 3) << 1)) & 3) |
3076 ((pll_regs[PLL_EXT_CNTL] >> (2 + (clock_cntl & 3))) & 4)];
3077
3078 /*
3079 * PLL Divider Q:
3080 */
3081 Q = N / P;
3082
3083 /*
3084 * Target Frequency:
3085 *
3086 * T * M
3087 * Q = -------
3088 * 2 * R
3089 *
3090 * where R is XTALIN (= 14318 or 29498 kHz).
3091 */
3092 if (IS_XL(pdev->device))
3093 R = 29498;
3094 else
3095 R = 14318;
3096
3097 T = 2 * Q * R / M;
3098
3099 default_var.pixclock = 1000000000 / T;
3100 }
3101
3102 return 0;
3103 }
3104
3105 #else /* __sparc__ */
3106
3107 #ifdef __i386__
3108 #ifdef CONFIG_FB_ATY_GENERIC_LCD
aty_init_lcd(struct atyfb_par * par,u32 bios_base)3109 static void aty_init_lcd(struct atyfb_par *par, u32 bios_base)
3110 {
3111 u32 driv_inf_tab, sig;
3112 u16 lcd_ofs;
3113
3114 /*
3115 * To support an LCD panel, we should know it's dimensions and
3116 * it's desired pixel clock.
3117 * There are two ways to do it:
3118 * - Check the startup video mode and calculate the panel
3119 * size from it. This is unreliable.
3120 * - Read it from the driver information table in the video BIOS.
3121 */
3122 /* Address of driver information table is at offset 0x78. */
3123 driv_inf_tab = bios_base + *((u16 *)(bios_base+0x78));
3124
3125 /* Check for the driver information table signature. */
3126 sig = *(u32 *)driv_inf_tab;
3127 if ((sig == 0x54504c24) || /* Rage LT pro */
3128 (sig == 0x544d5224) || /* Rage mobility */
3129 (sig == 0x54435824) || /* Rage XC */
3130 (sig == 0x544c5824)) { /* Rage XL */
3131 PRINTKI("BIOS contains driver information table.\n");
3132 lcd_ofs = *(u16 *)(driv_inf_tab + 10);
3133 par->lcd_table = 0;
3134 if (lcd_ofs != 0)
3135 par->lcd_table = bios_base + lcd_ofs;
3136 }
3137
3138 if (par->lcd_table != 0) {
3139 char model[24];
3140 char strbuf[16];
3141 char refresh_rates_buf[100];
3142 int id, tech, f, i, m, default_refresh_rate;
3143 char *txtcolour;
3144 char *txtmonitor;
3145 char *txtdual;
3146 char *txtformat;
3147 u16 width, height, panel_type, refresh_rates;
3148 u16 *lcdmodeptr;
3149 u32 format;
3150 u8 lcd_refresh_rates[16] = { 50, 56, 60, 67, 70, 72, 75, 76, 85,
3151 90, 100, 120, 140, 150, 160, 200 };
3152 /*
3153 * The most important information is the panel size at
3154 * offset 25 and 27, but there's some other nice information
3155 * which we print to the screen.
3156 */
3157 id = *(u8 *)par->lcd_table;
3158 strncpy(model, (char *)par->lcd_table+1, 24);
3159 model[23] = 0;
3160
3161 width = par->lcd_width = *(u16 *)(par->lcd_table+25);
3162 height = par->lcd_height = *(u16 *)(par->lcd_table+27);
3163 panel_type = *(u16 *)(par->lcd_table+29);
3164 if (panel_type & 1)
3165 txtcolour = "colour";
3166 else
3167 txtcolour = "monochrome";
3168 if (panel_type & 2)
3169 txtdual = "dual (split) ";
3170 else
3171 txtdual = "";
3172 tech = (panel_type >> 2) & 63;
3173 switch (tech) {
3174 case 0:
3175 txtmonitor = "passive matrix";
3176 break;
3177 case 1:
3178 txtmonitor = "active matrix";
3179 break;
3180 case 2:
3181 txtmonitor = "active addressed STN";
3182 break;
3183 case 3:
3184 txtmonitor = "EL";
3185 break;
3186 case 4:
3187 txtmonitor = "plasma";
3188 break;
3189 default:
3190 txtmonitor = "unknown";
3191 }
3192 format = *(u32 *)(par->lcd_table+57);
3193 if (tech == 0 || tech == 2) {
3194 switch (format & 7) {
3195 case 0:
3196 txtformat = "12 bit interface";
3197 break;
3198 case 1:
3199 txtformat = "16 bit interface";
3200 break;
3201 case 2:
3202 txtformat = "24 bit interface";
3203 break;
3204 default:
3205 txtformat = "unknown format";
3206 }
3207 } else {
3208 switch (format & 7) {
3209 case 0:
3210 txtformat = "8 colours";
3211 break;
3212 case 1:
3213 txtformat = "512 colours";
3214 break;
3215 case 2:
3216 txtformat = "4096 colours";
3217 break;
3218 case 4:
3219 txtformat = "262144 colours (LT mode)";
3220 break;
3221 case 5:
3222 txtformat = "16777216 colours";
3223 break;
3224 case 6:
3225 txtformat = "262144 colours (FDPI-2 mode)";
3226 break;
3227 default:
3228 txtformat = "unknown format";
3229 }
3230 }
3231 PRINTKI("%s%s %s monitor detected: %s\n",
3232 txtdual, txtcolour, txtmonitor, model);
3233 PRINTKI(" id=%d, %dx%d pixels, %s\n",
3234 id, width, height, txtformat);
3235 refresh_rates_buf[0] = 0;
3236 refresh_rates = *(u16 *)(par->lcd_table+62);
3237 m = 1;
3238 f = 0;
3239 for (i = 0; i < 16; i++) {
3240 if (refresh_rates & m) {
3241 if (f == 0) {
3242 sprintf(strbuf, "%d",
3243 lcd_refresh_rates[i]);
3244 f++;
3245 } else {
3246 sprintf(strbuf, ",%d",
3247 lcd_refresh_rates[i]);
3248 }
3249 strcat(refresh_rates_buf, strbuf);
3250 }
3251 m = m << 1;
3252 }
3253 default_refresh_rate = (*(u8 *)(par->lcd_table+61) & 0xf0) >> 4;
3254 PRINTKI(" supports refresh rates [%s], default %d Hz\n",
3255 refresh_rates_buf, lcd_refresh_rates[default_refresh_rate]);
3256 par->lcd_refreshrate = lcd_refresh_rates[default_refresh_rate];
3257 /*
3258 * We now need to determine the crtc parameters for the
3259 * LCD monitor. This is tricky, because they are not stored
3260 * individually in the BIOS. Instead, the BIOS contains a
3261 * table of display modes that work for this monitor.
3262 *
3263 * The idea is that we search for a mode of the same dimensions
3264 * as the dimensions of the LCD monitor. Say our LCD monitor
3265 * is 800x600 pixels, we search for a 800x600 monitor.
3266 * The CRTC parameters we find here are the ones that we need
3267 * to use to simulate other resolutions on the LCD screen.
3268 */
3269 lcdmodeptr = (u16 *)(par->lcd_table + 64);
3270 while (*lcdmodeptr != 0) {
3271 u32 modeptr;
3272 u16 mwidth, mheight, lcd_hsync_start, lcd_vsync_start;
3273 modeptr = bios_base + *lcdmodeptr;
3274
3275 mwidth = *((u16 *)(modeptr+0));
3276 mheight = *((u16 *)(modeptr+2));
3277
3278 if (mwidth == width && mheight == height) {
3279 par->lcd_pixclock = 100000000 / *((u16 *)(modeptr+9));
3280 par->lcd_htotal = *((u16 *)(modeptr+17)) & 511;
3281 par->lcd_hdisp = *((u16 *)(modeptr+19)) & 511;
3282 lcd_hsync_start = *((u16 *)(modeptr+21)) & 511;
3283 par->lcd_hsync_dly = (*((u16 *)(modeptr+21)) >> 9) & 7;
3284 par->lcd_hsync_len = *((u8 *)(modeptr+23)) & 63;
3285
3286 par->lcd_vtotal = *((u16 *)(modeptr+24)) & 2047;
3287 par->lcd_vdisp = *((u16 *)(modeptr+26)) & 2047;
3288 lcd_vsync_start = *((u16 *)(modeptr+28)) & 2047;
3289 par->lcd_vsync_len = (*((u16 *)(modeptr+28)) >> 11) & 31;
3290
3291 par->lcd_htotal = (par->lcd_htotal + 1) * 8;
3292 par->lcd_hdisp = (par->lcd_hdisp + 1) * 8;
3293 lcd_hsync_start = (lcd_hsync_start + 1) * 8;
3294 par->lcd_hsync_len = par->lcd_hsync_len * 8;
3295
3296 par->lcd_vtotal++;
3297 par->lcd_vdisp++;
3298 lcd_vsync_start++;
3299
3300 par->lcd_right_margin = lcd_hsync_start - par->lcd_hdisp;
3301 par->lcd_lower_margin = lcd_vsync_start - par->lcd_vdisp;
3302 par->lcd_hblank_len = par->lcd_htotal - par->lcd_hdisp;
3303 par->lcd_vblank_len = par->lcd_vtotal - par->lcd_vdisp;
3304 break;
3305 }
3306
3307 lcdmodeptr++;
3308 }
3309 if (*lcdmodeptr == 0) {
3310 PRINTKE("LCD monitor CRTC parameters not found!!!\n");
3311 /* To do: Switch to CRT if possible. */
3312 } else {
3313 PRINTKI(" LCD CRTC parameters: %d.%d %d %d %d %d %d %d %d %d\n",
3314 1000000 / par->lcd_pixclock, 1000000 % par->lcd_pixclock,
3315 par->lcd_hdisp,
3316 par->lcd_hdisp + par->lcd_right_margin,
3317 par->lcd_hdisp + par->lcd_right_margin
3318 + par->lcd_hsync_dly + par->lcd_hsync_len,
3319 par->lcd_htotal,
3320 par->lcd_vdisp,
3321 par->lcd_vdisp + par->lcd_lower_margin,
3322 par->lcd_vdisp + par->lcd_lower_margin + par->lcd_vsync_len,
3323 par->lcd_vtotal);
3324 PRINTKI(" : %d %d %d %d %d %d %d %d %d\n",
3325 par->lcd_pixclock,
3326 par->lcd_hblank_len - (par->lcd_right_margin +
3327 par->lcd_hsync_dly + par->lcd_hsync_len),
3328 par->lcd_hdisp,
3329 par->lcd_right_margin,
3330 par->lcd_hsync_len,
3331 par->lcd_vblank_len - (par->lcd_lower_margin + par->lcd_vsync_len),
3332 par->lcd_vdisp,
3333 par->lcd_lower_margin,
3334 par->lcd_vsync_len);
3335 }
3336 }
3337 }
3338 #endif /* CONFIG_FB_ATY_GENERIC_LCD */
3339
init_from_bios(struct atyfb_par * par)3340 static int init_from_bios(struct atyfb_par *par)
3341 {
3342 u32 bios_base, rom_addr;
3343 int ret;
3344
3345 rom_addr = 0xc0000 + ((aty_ld_le32(SCRATCH_REG1, par) & 0x7f) << 11);
3346 bios_base = (unsigned long)ioremap(rom_addr, 0x10000);
3347
3348 /* The BIOS starts with 0xaa55. */
3349 if (*((u16 *)bios_base) == 0xaa55) {
3350
3351 u8 *bios_ptr;
3352 u16 rom_table_offset, freq_table_offset;
3353 PLL_BLOCK_MACH64 pll_block;
3354
3355 PRINTKI("Mach64 BIOS is located at %x, mapped at %x.\n", rom_addr, bios_base);
3356
3357 /* check for frequncy table */
3358 bios_ptr = (u8*)bios_base;
3359 rom_table_offset = (u16)(bios_ptr[0x48] | (bios_ptr[0x49] << 8));
3360 freq_table_offset = bios_ptr[rom_table_offset + 16] | (bios_ptr[rom_table_offset + 17] << 8);
3361 memcpy(&pll_block, bios_ptr + freq_table_offset, sizeof(PLL_BLOCK_MACH64));
3362
3363 PRINTKI("BIOS frequency table:\n");
3364 PRINTKI("PCLK_min_freq %d, PCLK_max_freq %d, ref_freq %d, ref_divider %d\n",
3365 pll_block.PCLK_min_freq, pll_block.PCLK_max_freq,
3366 pll_block.ref_freq, pll_block.ref_divider);
3367 PRINTKI("MCLK_pwd %d, MCLK_max_freq %d, XCLK_max_freq %d, SCLK_freq %d\n",
3368 pll_block.MCLK_pwd, pll_block.MCLK_max_freq,
3369 pll_block.XCLK_max_freq, pll_block.SCLK_freq);
3370
3371 par->pll_limits.pll_min = pll_block.PCLK_min_freq/100;
3372 par->pll_limits.pll_max = pll_block.PCLK_max_freq/100;
3373 par->pll_limits.ref_clk = pll_block.ref_freq/100;
3374 par->pll_limits.ref_div = pll_block.ref_divider;
3375 par->pll_limits.sclk = pll_block.SCLK_freq/100;
3376 par->pll_limits.mclk = pll_block.MCLK_max_freq/100;
3377 par->pll_limits.mclk_pm = pll_block.MCLK_pwd/100;
3378 par->pll_limits.xclk = pll_block.XCLK_max_freq/100;
3379 #ifdef CONFIG_FB_ATY_GENERIC_LCD
3380 aty_init_lcd(par, bios_base);
3381 #endif
3382 ret = 0;
3383 } else {
3384 PRINTKE("no BIOS frequency table found, use parameters\n");
3385 ret = -ENXIO;
3386 }
3387 iounmap((void __iomem *)bios_base);
3388
3389 return ret;
3390 }
3391 #endif /* __i386__ */
3392
atyfb_setup_generic(struct pci_dev * pdev,struct fb_info * info,unsigned long addr)3393 static int atyfb_setup_generic(struct pci_dev *pdev, struct fb_info *info,
3394 unsigned long addr)
3395 {
3396 struct atyfb_par *par = info->par;
3397 u16 tmp;
3398 unsigned long raddr;
3399 struct resource *rrp;
3400 int ret = 0;
3401
3402 raddr = addr + 0x7ff000UL;
3403 rrp = &pdev->resource[2];
3404 if ((rrp->flags & IORESOURCE_MEM) &&
3405 request_mem_region(rrp->start, resource_size(rrp), "atyfb")) {
3406 par->aux_start = rrp->start;
3407 par->aux_size = resource_size(rrp);
3408 raddr = rrp->start;
3409 PRINTKI("using auxiliary register aperture\n");
3410 }
3411
3412 info->fix.mmio_start = raddr;
3413 /*
3414 * By using strong UC we force the MTRR to never have an
3415 * effect on the MMIO region on both non-PAT and PAT systems.
3416 */
3417 par->ati_regbase = ioremap_uc(info->fix.mmio_start, 0x1000);
3418 if (par->ati_regbase == NULL)
3419 return -ENOMEM;
3420
3421 info->fix.mmio_start += par->aux_start ? 0x400 : 0xc00;
3422 par->ati_regbase += par->aux_start ? 0x400 : 0xc00;
3423
3424 /*
3425 * Enable memory-space accesses using config-space
3426 * command register.
3427 */
3428 pci_read_config_word(pdev, PCI_COMMAND, &tmp);
3429 if (!(tmp & PCI_COMMAND_MEMORY)) {
3430 tmp |= PCI_COMMAND_MEMORY;
3431 pci_write_config_word(pdev, PCI_COMMAND, tmp);
3432 }
3433 #ifdef __BIG_ENDIAN
3434 /* Use the big-endian aperture */
3435 addr += 0x800000;
3436 #endif
3437
3438 /* Map in frame buffer */
3439 info->fix.smem_start = addr;
3440
3441 /*
3442 * The framebuffer is not always 8 MiB, that's just the size of the
3443 * PCI BAR. We temporarily abuse smem_len here to store the size
3444 * of the BAR. aty_init() will later correct it to match the actual
3445 * framebuffer size.
3446 *
3447 * On devices that don't have the auxiliary register aperture, the
3448 * registers are housed at the top end of the framebuffer PCI BAR.
3449 * aty_fudge_framebuffer_len() is used to reduce smem_len to not
3450 * overlap with the registers.
3451 */
3452 info->fix.smem_len = 0x800000;
3453
3454 aty_fudge_framebuffer_len(info);
3455
3456 info->screen_base = ioremap_wc(info->fix.smem_start,
3457 info->fix.smem_len);
3458 if (info->screen_base == NULL) {
3459 ret = -ENOMEM;
3460 goto atyfb_setup_generic_fail;
3461 }
3462
3463 ret = correct_chipset(par);
3464 if (ret)
3465 goto atyfb_setup_generic_fail;
3466 #ifdef __i386__
3467 ret = init_from_bios(par);
3468 if (ret)
3469 goto atyfb_setup_generic_fail;
3470 #endif
3471 if (!(aty_ld_le32(CRTC_GEN_CNTL, par) & CRTC_EXT_DISP_EN))
3472 par->clk_wr_offset = (inb(R_GENMO) & 0x0CU) >> 2;
3473 else
3474 par->clk_wr_offset = aty_ld_8(CLOCK_CNTL, par) & 0x03U;
3475
3476 /* according to ATI, we should use clock 3 for acelerated mode */
3477 par->clk_wr_offset = 3;
3478
3479 return 0;
3480
3481 atyfb_setup_generic_fail:
3482 iounmap(par->ati_regbase);
3483 par->ati_regbase = NULL;
3484 if (info->screen_base) {
3485 iounmap(info->screen_base);
3486 info->screen_base = NULL;
3487 }
3488 return ret;
3489 }
3490
3491 #endif /* !__sparc__ */
3492
atyfb_pci_probe(struct pci_dev * pdev,const struct pci_device_id * ent)3493 static int atyfb_pci_probe(struct pci_dev *pdev,
3494 const struct pci_device_id *ent)
3495 {
3496 unsigned long addr, res_start, res_size;
3497 struct fb_info *info;
3498 struct resource *rp;
3499 struct atyfb_par *par;
3500 int rc = -ENOMEM;
3501
3502 /* Enable device in PCI config */
3503 if (pci_enable_device(pdev)) {
3504 PRINTKE("Cannot enable PCI device\n");
3505 return -ENXIO;
3506 }
3507
3508 /* Find which resource to use */
3509 rp = &pdev->resource[0];
3510 if (rp->flags & IORESOURCE_IO)
3511 rp = &pdev->resource[1];
3512 addr = rp->start;
3513 if (!addr)
3514 return -ENXIO;
3515
3516 /* Reserve space */
3517 res_start = rp->start;
3518 res_size = resource_size(rp);
3519 if (!request_mem_region(res_start, res_size, "atyfb"))
3520 return -EBUSY;
3521
3522 /* Allocate framebuffer */
3523 info = framebuffer_alloc(sizeof(struct atyfb_par), &pdev->dev);
3524 if (!info)
3525 return -ENOMEM;
3526
3527 par = info->par;
3528 par->bus_type = PCI;
3529 info->fix = atyfb_fix;
3530 info->device = &pdev->dev;
3531 par->pci_id = pdev->device;
3532 par->res_start = res_start;
3533 par->res_size = res_size;
3534 par->irq = pdev->irq;
3535 par->pdev = pdev;
3536
3537 /* Setup "info" structure */
3538 #ifdef __sparc__
3539 rc = atyfb_setup_sparc(pdev, info, addr);
3540 #else
3541 rc = atyfb_setup_generic(pdev, info, addr);
3542 #endif
3543 if (rc)
3544 goto err_release_mem;
3545
3546 pci_set_drvdata(pdev, info);
3547
3548 /* Init chip & register framebuffer */
3549 rc = aty_init(info);
3550 if (rc)
3551 goto err_release_io;
3552
3553 #ifdef __sparc__
3554 /*
3555 * Add /dev/fb mmap values.
3556 */
3557 par->mmap_map[0].voff = 0x8000000000000000UL;
3558 par->mmap_map[0].poff = (unsigned long) info->screen_base & PAGE_MASK;
3559 par->mmap_map[0].size = info->fix.smem_len;
3560 par->mmap_map[0].prot_mask = _PAGE_CACHE;
3561 par->mmap_map[0].prot_flag = _PAGE_E;
3562 par->mmap_map[1].voff = par->mmap_map[0].voff + info->fix.smem_len;
3563 par->mmap_map[1].poff = (long)par->ati_regbase & PAGE_MASK;
3564 par->mmap_map[1].size = PAGE_SIZE;
3565 par->mmap_map[1].prot_mask = _PAGE_CACHE;
3566 par->mmap_map[1].prot_flag = _PAGE_E;
3567 #endif /* __sparc__ */
3568
3569 mutex_lock(&reboot_lock);
3570 if (!reboot_info)
3571 reboot_info = info;
3572 mutex_unlock(&reboot_lock);
3573
3574 return 0;
3575
3576 err_release_io:
3577 #ifdef __sparc__
3578 kfree(par->mmap_map);
3579 #else
3580 if (par->ati_regbase)
3581 iounmap(par->ati_regbase);
3582 if (info->screen_base)
3583 iounmap(info->screen_base);
3584 #endif
3585 err_release_mem:
3586 if (par->aux_start)
3587 release_mem_region(par->aux_start, par->aux_size);
3588
3589 release_mem_region(par->res_start, par->res_size);
3590 framebuffer_release(info);
3591
3592 return rc;
3593 }
3594
3595 #endif /* CONFIG_PCI */
3596
3597 #ifdef CONFIG_ATARI
3598
atyfb_atari_probe(void)3599 static int __init atyfb_atari_probe(void)
3600 {
3601 struct atyfb_par *par;
3602 struct fb_info *info;
3603 int m64_num;
3604 u32 clock_r;
3605 int num_found = 0;
3606
3607 for (m64_num = 0; m64_num < mach64_count; m64_num++) {
3608 if (!phys_vmembase[m64_num] || !phys_size[m64_num] ||
3609 !phys_guiregbase[m64_num]) {
3610 PRINTKI("phys_*[%d] parameters not set => "
3611 "returning early. \n", m64_num);
3612 continue;
3613 }
3614
3615 info = framebuffer_alloc(sizeof(struct atyfb_par), NULL);
3616 if (!info)
3617 return -ENOMEM;
3618
3619 par = info->par;
3620
3621 info->fix = atyfb_fix;
3622
3623 par->irq = (unsigned int) -1; /* something invalid */
3624
3625 /*
3626 * Map the video memory (physical address given)
3627 * to somewhere in the kernel address space.
3628 */
3629 info->screen_base = ioremap_wc(phys_vmembase[m64_num],
3630 phys_size[m64_num]);
3631 info->fix.smem_start = (unsigned long)info->screen_base; /* Fake! */
3632 par->ati_regbase = ioremap(phys_guiregbase[m64_num], 0x10000) +
3633 0xFC00ul;
3634 info->fix.mmio_start = (unsigned long)par->ati_regbase; /* Fake! */
3635
3636 aty_st_le32(CLOCK_CNTL, 0x12345678, par);
3637 clock_r = aty_ld_le32(CLOCK_CNTL, par);
3638
3639 switch (clock_r & 0x003F) {
3640 case 0x12:
3641 par->clk_wr_offset = 3; /* */
3642 break;
3643 case 0x34:
3644 par->clk_wr_offset = 2; /* Medusa ST-IO ISA Adapter etc. */
3645 break;
3646 case 0x16:
3647 par->clk_wr_offset = 1; /* */
3648 break;
3649 case 0x38:
3650 par->clk_wr_offset = 0; /* Panther 1 ISA Adapter (Gerald) */
3651 break;
3652 }
3653
3654 /* Fake pci_id for correct_chipset() */
3655 switch (aty_ld_le32(CNFG_CHIP_ID, par) & CFG_CHIP_TYPE) {
3656 case 0x00d7:
3657 par->pci_id = PCI_CHIP_MACH64GX;
3658 break;
3659 case 0x0057:
3660 par->pci_id = PCI_CHIP_MACH64CX;
3661 break;
3662 default:
3663 break;
3664 }
3665
3666 if (correct_chipset(par) || aty_init(info)) {
3667 iounmap(info->screen_base);
3668 iounmap(par->ati_regbase);
3669 framebuffer_release(info);
3670 } else {
3671 num_found++;
3672 }
3673 }
3674
3675 return num_found ? 0 : -ENXIO;
3676 }
3677
3678 #endif /* CONFIG_ATARI */
3679
3680 #ifdef CONFIG_PCI
3681
atyfb_remove(struct fb_info * info)3682 static void atyfb_remove(struct fb_info *info)
3683 {
3684 struct atyfb_par *par = (struct atyfb_par *) info->par;
3685
3686 /* restore video mode */
3687 aty_set_crtc(par, &par->saved_crtc);
3688 par->pll_ops->set_pll(info, &par->saved_pll);
3689
3690 unregister_framebuffer(info);
3691
3692 #ifdef CONFIG_FB_ATY_BACKLIGHT
3693 if (M64_HAS(MOBIL_BUS))
3694 aty_bl_exit(info->bl_dev);
3695 #endif
3696 arch_phys_wc_del(par->wc_cookie);
3697
3698 #ifndef __sparc__
3699 if (par->ati_regbase)
3700 iounmap(par->ati_regbase);
3701 if (info->screen_base)
3702 iounmap(info->screen_base);
3703 #ifdef __BIG_ENDIAN
3704 if (info->sprite.addr)
3705 iounmap(info->sprite.addr);
3706 #endif
3707 #endif
3708 #ifdef __sparc__
3709 kfree(par->mmap_map);
3710 #endif
3711 if (par->aux_start)
3712 release_mem_region(par->aux_start, par->aux_size);
3713
3714 if (par->res_start)
3715 release_mem_region(par->res_start, par->res_size);
3716
3717 framebuffer_release(info);
3718 }
3719
3720
atyfb_pci_remove(struct pci_dev * pdev)3721 static void atyfb_pci_remove(struct pci_dev *pdev)
3722 {
3723 struct fb_info *info = pci_get_drvdata(pdev);
3724
3725 mutex_lock(&reboot_lock);
3726 if (reboot_info == info)
3727 reboot_info = NULL;
3728 mutex_unlock(&reboot_lock);
3729
3730 atyfb_remove(info);
3731 }
3732
3733 static const struct pci_device_id atyfb_pci_tbl[] = {
3734 #ifdef CONFIG_FB_ATY_GX
3735 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GX) },
3736 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64CX) },
3737 #endif /* CONFIG_FB_ATY_GX */
3738
3739 #ifdef CONFIG_FB_ATY_CT
3740 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64CT) },
3741 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64ET) },
3742
3743 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64LT) },
3744
3745 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64VT) },
3746 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GT) },
3747
3748 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64VU) },
3749 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GU) },
3750
3751 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64LG) },
3752
3753 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64VV) },
3754
3755 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GV) },
3756 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GW) },
3757 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GY) },
3758 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GZ) },
3759
3760 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GB) },
3761 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GD) },
3762 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GI) },
3763 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GP) },
3764 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GQ) },
3765
3766 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64LB) },
3767 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64LD) },
3768 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64LI) },
3769 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64LP) },
3770 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64LQ) },
3771
3772 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GM) },
3773 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GN) },
3774 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GO) },
3775 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GL) },
3776 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GR) },
3777 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GS) },
3778
3779 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64LM) },
3780 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64LN) },
3781 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64LR) },
3782 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64LS) },
3783 #endif /* CONFIG_FB_ATY_CT */
3784 { }
3785 };
3786
3787 MODULE_DEVICE_TABLE(pci, atyfb_pci_tbl);
3788
3789 static struct pci_driver atyfb_driver = {
3790 .name = "atyfb",
3791 .id_table = atyfb_pci_tbl,
3792 .probe = atyfb_pci_probe,
3793 .remove = atyfb_pci_remove,
3794 #ifdef CONFIG_PM
3795 .suspend = atyfb_pci_suspend,
3796 .resume = atyfb_pci_resume,
3797 #endif /* CONFIG_PM */
3798 };
3799
3800 #endif /* CONFIG_PCI */
3801
3802 #ifndef MODULE
atyfb_setup(char * options)3803 static int __init atyfb_setup(char *options)
3804 {
3805 char *this_opt;
3806
3807 if (!options || !*options)
3808 return 0;
3809
3810 while ((this_opt = strsep(&options, ",")) != NULL) {
3811 if (!strncmp(this_opt, "noaccel", 7)) {
3812 noaccel = 1;
3813 } else if (!strncmp(this_opt, "nomtrr", 6)) {
3814 nomtrr = 1;
3815 } else if (!strncmp(this_opt, "vram:", 5))
3816 vram = simple_strtoul(this_opt + 5, NULL, 0);
3817 else if (!strncmp(this_opt, "pll:", 4))
3818 pll = simple_strtoul(this_opt + 4, NULL, 0);
3819 else if (!strncmp(this_opt, "mclk:", 5))
3820 mclk = simple_strtoul(this_opt + 5, NULL, 0);
3821 else if (!strncmp(this_opt, "xclk:", 5))
3822 xclk = simple_strtoul(this_opt+5, NULL, 0);
3823 else if (!strncmp(this_opt, "comp_sync:", 10))
3824 comp_sync = simple_strtoul(this_opt+10, NULL, 0);
3825 else if (!strncmp(this_opt, "backlight:", 10))
3826 backlight = simple_strtoul(this_opt+10, NULL, 0);
3827 #ifdef CONFIG_PPC
3828 else if (!strncmp(this_opt, "vmode:", 6)) {
3829 unsigned int vmode =
3830 simple_strtoul(this_opt + 6, NULL, 0);
3831 if (vmode > 0 && vmode <= VMODE_MAX)
3832 default_vmode = vmode;
3833 } else if (!strncmp(this_opt, "cmode:", 6)) {
3834 unsigned int cmode =
3835 simple_strtoul(this_opt + 6, NULL, 0);
3836 switch (cmode) {
3837 case 0:
3838 case 8:
3839 default_cmode = CMODE_8;
3840 break;
3841 case 15:
3842 case 16:
3843 default_cmode = CMODE_16;
3844 break;
3845 case 24:
3846 case 32:
3847 default_cmode = CMODE_32;
3848 break;
3849 }
3850 }
3851 #endif
3852 #ifdef CONFIG_ATARI
3853 /*
3854 * Why do we need this silly Mach64 argument?
3855 * We are already here because of mach64= so its redundant.
3856 */
3857 else if (MACH_IS_ATARI
3858 && (!strncmp(this_opt, "Mach64:", 7))) {
3859 static unsigned char m64_num;
3860 static char mach64_str[80];
3861 strlcpy(mach64_str, this_opt + 7, sizeof(mach64_str));
3862 if (!store_video_par(mach64_str, m64_num)) {
3863 m64_num++;
3864 mach64_count = m64_num;
3865 }
3866 }
3867 #endif
3868 else
3869 mode = this_opt;
3870 }
3871 return 0;
3872 }
3873 #endif /* MODULE */
3874
atyfb_reboot_notify(struct notifier_block * nb,unsigned long code,void * unused)3875 static int atyfb_reboot_notify(struct notifier_block *nb,
3876 unsigned long code, void *unused)
3877 {
3878 struct atyfb_par *par;
3879
3880 if (code != SYS_RESTART)
3881 return NOTIFY_DONE;
3882
3883 mutex_lock(&reboot_lock);
3884
3885 if (!reboot_info)
3886 goto out;
3887
3888 lock_fb_info(reboot_info);
3889
3890 par = reboot_info->par;
3891
3892 /*
3893 * HP OmniBook 500's BIOS doesn't like the state of the
3894 * hardware after atyfb has been used. Restore the hardware
3895 * to the original state to allow successful reboots.
3896 */
3897 aty_set_crtc(par, &par->saved_crtc);
3898 par->pll_ops->set_pll(reboot_info, &par->saved_pll);
3899
3900 unlock_fb_info(reboot_info);
3901 out:
3902 mutex_unlock(&reboot_lock);
3903
3904 return NOTIFY_DONE;
3905 }
3906
3907 static struct notifier_block atyfb_reboot_notifier = {
3908 .notifier_call = atyfb_reboot_notify,
3909 };
3910
3911 static const struct dmi_system_id atyfb_reboot_ids[] __initconst = {
3912 {
3913 .ident = "HP OmniBook 500",
3914 .matches = {
3915 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
3916 DMI_MATCH(DMI_PRODUCT_NAME, "HP OmniBook PC"),
3917 DMI_MATCH(DMI_PRODUCT_VERSION, "HP OmniBook 500 FA"),
3918 },
3919 },
3920
3921 { }
3922 };
3923 static bool registered_notifier = false;
3924
atyfb_init(void)3925 static int __init atyfb_init(void)
3926 {
3927 int err1 = 1, err2 = 1;
3928 #ifndef MODULE
3929 char *option = NULL;
3930
3931 if (fb_get_options("atyfb", &option))
3932 return -ENODEV;
3933 atyfb_setup(option);
3934 #endif
3935
3936 #ifdef CONFIG_PCI
3937 err1 = pci_register_driver(&atyfb_driver);
3938 #endif
3939 #ifdef CONFIG_ATARI
3940 err2 = atyfb_atari_probe();
3941 #endif
3942
3943 if (err1 && err2)
3944 return -ENODEV;
3945
3946 if (dmi_check_system(atyfb_reboot_ids)) {
3947 register_reboot_notifier(&atyfb_reboot_notifier);
3948 registered_notifier = true;
3949 }
3950
3951 return 0;
3952 }
3953
atyfb_exit(void)3954 static void __exit atyfb_exit(void)
3955 {
3956 if (registered_notifier)
3957 unregister_reboot_notifier(&atyfb_reboot_notifier);
3958
3959 #ifdef CONFIG_PCI
3960 pci_unregister_driver(&atyfb_driver);
3961 #endif
3962 }
3963
3964 module_init(atyfb_init);
3965 module_exit(atyfb_exit);
3966
3967 MODULE_DESCRIPTION("FBDev driver for ATI Mach64 cards");
3968 MODULE_LICENSE("GPL");
3969 module_param(noaccel, bool, 0);
3970 MODULE_PARM_DESC(noaccel, "bool: disable acceleration");
3971 module_param(vram, int, 0);
3972 MODULE_PARM_DESC(vram, "int: override size of video ram");
3973 module_param(pll, int, 0);
3974 MODULE_PARM_DESC(pll, "int: override video clock");
3975 module_param(mclk, int, 0);
3976 MODULE_PARM_DESC(mclk, "int: override memory clock");
3977 module_param(xclk, int, 0);
3978 MODULE_PARM_DESC(xclk, "int: override accelerated engine clock");
3979 module_param(comp_sync, int, 0);
3980 MODULE_PARM_DESC(comp_sync, "Set composite sync signal to low (0) or high (1)");
3981 module_param(mode, charp, 0);
3982 MODULE_PARM_DESC(mode, "Specify resolution as \"<xres>x<yres>[-<bpp>][@<refresh>]\" ");
3983 module_param(nomtrr, bool, 0);
3984 MODULE_PARM_DESC(nomtrr, "bool: disable use of MTRR registers");
3985