File: /usr/src/linux/drivers/video/aty/atyfb_base.c
1
2 /*
3 * ATI Frame Buffer Device Driver Core
4 *
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 * This file is subject to the terms and conditions of the GNU General Public
29 * License. See the file COPYING in the main directory of this archive for
30 * more details.
31 *
32 * Many thanks to Nitya from ATI devrel for support and patience !
33 */
34
35 /******************************************************************************
36
37 TODO:
38
39 - cursor support on all cards and all ramdacs.
40 - cursor parameters controlable via ioctl()s.
41 - guess PLL and MCLK based on the original PLL register values initialized
42 by the BIOS or Open Firmware (if they are initialized).
43
44 (Anyone to help with this?)
45
46 ******************************************************************************/
47
48
49 #include <linux/config.h>
50 #include <linux/module.h>
51 #include <linux/kernel.h>
52 #include <linux/errno.h>
53 #include <linux/string.h>
54 #include <linux/mm.h>
55 #include <linux/slab.h>
56 #include <linux/vmalloc.h>
57 #include <linux/delay.h>
58 #include <linux/selection.h>
59 #include <linux/console.h>
60 #include <linux/fb.h>
61 #include <linux/init.h>
62 #include <linux/pci.h>
63 #include <linux/vt_kern.h>
64 #include <linux/kd.h>
65
66 #include <asm/io.h>
67 #include <asm/uaccess.h>
68
69 #include <video/fbcon.h>
70 #include <video/fbcon-cfb8.h>
71 #include <video/fbcon-cfb16.h>
72 #include <video/fbcon-cfb24.h>
73 #include <video/fbcon-cfb32.h>
74
75 #include "mach64.h"
76 #include "atyfb.h"
77
78 #ifdef __powerpc__
79 #include <asm/prom.h>
80 #include <video/macmodes.h>
81 #endif
82 #ifdef __sparc__
83 #include <asm/pbm.h>
84 #include <asm/fbio.h>
85 #endif
86
87 #ifdef CONFIG_ADB_PMU
88 #include <linux/adb.h>
89 #include <linux/pmu.h>
90 #endif
91 #ifdef CONFIG_NVRAM
92 #include <linux/nvram.h>
93 #endif
94 #ifdef CONFIG_FB_COMPAT_XPMAC
95 #include <asm/vc_ioctl.h>
96 #endif
97 #ifdef CONFIG_PMAC_BACKLIGHT
98 #include <asm/backlight.h>
99 #endif
100
101
102 /*
103 * Debug flags.
104 */
105 #undef DEBUG
106
107 /* Make sure n * PAGE_SIZE is protected at end of Aperture for GUI-regs */
108 /* - must be large enough to catch all GUI-Regs */
109 /* - must be aligned to a PAGE boundary */
110 #define GUI_RESERVE (1 * PAGE_SIZE)
111
112
113 /* FIXME: remove the FAIL definition */
114 #define FAIL(x) do { printk(x "\n"); return -EINVAL; } while (0)
115
116
117 /*
118 * The Hardware parameters for each card
119 */
120
121 struct aty_cmap_regs {
122 u8 windex;
123 u8 lut;
124 u8 mask;
125 u8 rindex;
126 u8 cntl;
127 };
128
129 struct pci_mmap_map {
130 unsigned long voff;
131 unsigned long poff;
132 unsigned long size;
133 unsigned long prot_flag;
134 unsigned long prot_mask;
135 };
136
137
138 /*
139 * Frame buffer device API
140 */
141
142 static int atyfb_open(struct fb_info *info, int user);
143 static int atyfb_release(struct fb_info *info, int user);
144 static int atyfb_get_fix(struct fb_fix_screeninfo *fix, int con,
145 struct fb_info *fb);
146 static int atyfb_get_var(struct fb_var_screeninfo *var, int con,
147 struct fb_info *fb);
148 static int atyfb_set_var(struct fb_var_screeninfo *var, int con,
149 struct fb_info *fb);
150 static int atyfb_pan_display(struct fb_var_screeninfo *var, int con,
151 struct fb_info *fb);
152 static int atyfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
153 struct fb_info *info);
154 static int atyfb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
155 struct fb_info *info);
156 static int atyfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
157 u_long arg, int con, struct fb_info *info);
158 #ifdef __sparc__
159 static int atyfb_mmap(struct fb_info *info, struct file *file,
160 struct vm_area_struct *vma);
161 #endif
162 static int atyfb_rasterimg(struct fb_info *info, int start);
163
164
165 /*
166 * Interface to the low level console driver
167 */
168
169 static int atyfbcon_switch(int con, struct fb_info *fb);
170 static int atyfbcon_updatevar(int con, struct fb_info *fb);
171 static void atyfbcon_blank(int blank, struct fb_info *fb);
172
173
174 /*
175 * Internal routines
176 */
177
178 static int aty_init(struct fb_info_aty *info, const char *name);
179 #ifdef CONFIG_ATARI
180 static int store_video_par(char *videopar, unsigned char m64_num);
181 static char *strtoke(char *s, const char *ct);
182 #endif
183
184 static void aty_set_crtc(const struct fb_info_aty *info,
185 const struct crtc *crtc);
186 static int aty_var_to_crtc(const struct fb_info_aty *info,
187 const struct fb_var_screeninfo *var,
188 struct crtc *crtc);
189 static int aty_crtc_to_var(const struct crtc *crtc,
190 struct fb_var_screeninfo *var);
191
192 static void atyfb_set_par(const struct atyfb_par *par,
193 struct fb_info_aty *info);
194 static int atyfb_decode_var(const struct fb_var_screeninfo *var,
195 struct atyfb_par *par,
196 const struct fb_info_aty *info);
197 static int atyfb_encode_var(struct fb_var_screeninfo *var,
198 const struct atyfb_par *par,
199 const struct fb_info_aty *info);
200 static void set_off_pitch(struct atyfb_par *par,
201 const struct fb_info_aty *info);
202 static int encode_fix(struct fb_fix_screeninfo *fix,
203 const struct atyfb_par *par,
204 const struct fb_info_aty *info);
205 static void atyfb_set_dispsw(struct display *disp, struct fb_info_aty *info,
206 int bpp, int accel);
207 static int atyfb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
208 u_int *transp, struct fb_info *fb);
209 static int atyfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
210 u_int transp, struct fb_info *fb);
211 static void do_install_cmap(int con, struct fb_info *info);
212 #ifdef CONFIG_PPC
213 static int read_aty_sense(const struct fb_info_aty *info);
214 #endif
215
216
217 /*
218 * Interface used by the world
219 */
220
221 int atyfb_init(void);
222 #ifndef MODULE
223 int atyfb_setup(char*);
224 #endif
225
226 static int currcon = 0;
227
228 static struct fb_ops atyfb_ops = {
229 owner: THIS_MODULE,
230 fb_open: atyfb_open,
231 fb_release: atyfb_release,
232 fb_get_fix: atyfb_get_fix,
233 fb_get_var: atyfb_get_var,
234 fb_set_var: atyfb_set_var,
235 fb_get_cmap: atyfb_get_cmap,
236 fb_set_cmap: atyfb_set_cmap,
237 fb_pan_display: atyfb_pan_display,
238 fb_ioctl: atyfb_ioctl,
239 #ifdef __sparc__
240 fb_mmap: atyfb_mmap,
241 #endif
242 fb_rasterimg: atyfb_rasterimg,
243 };
244
245 static char atyfb_name[16] = "ATY Mach64";
246 static char fontname[40] __initdata = { 0 };
247 static char curblink __initdata = 1;
248 static char noaccel __initdata = 0;
249 static u32 default_vram __initdata = 0;
250 static int default_pll __initdata = 0;
251 static int default_mclk __initdata = 0;
252
253 #ifndef MODULE
254 static const char *mode_option __initdata = NULL;
255 #endif
256
257 #ifdef CONFIG_PPC
258 #ifdef CONFIG_NVRAM_NOT_DEFINED
259 static int default_vmode __initdata = VMODE_NVRAM;
260 static int default_cmode __initdata = CMODE_NVRAM;
261 #else
262 static int default_vmode __initdata = VMODE_CHOOSE;
263 static int default_cmode __initdata = CMODE_CHOOSE;
264 #endif
265 #endif
266
267 #ifdef CONFIG_ATARI
268 static unsigned int mach64_count __initdata = 0;
269 static unsigned long phys_vmembase[FB_MAX] __initdata = { 0, };
270 static unsigned long phys_size[FB_MAX] __initdata = { 0, };
271 static unsigned long phys_guiregbase[FB_MAX] __initdata = { 0, };
272 #endif
273
274 static const char m64n_gx[] __initdata = "mach64GX (ATI888GX00)";
275 static const char m64n_cx[] __initdata = "mach64CX (ATI888CX00)";
276 static const char m64n_ct[] __initdata = "mach64CT (ATI264CT)";
277 static const char m64n_et[] __initdata = "mach64ET (ATI264ET)";
278 static const char m64n_vta3[] __initdata = "mach64VTA3 (ATI264VT)";
279 static const char m64n_vta4[] __initdata = "mach64VTA4 (ATI264VT)";
280 static const char m64n_vtb[] __initdata = "mach64VTB (ATI264VTB)";
281 static const char m64n_vt4[] __initdata = "mach64VT4 (ATI264VT4)";
282 static const char m64n_gt[] __initdata = "3D RAGE (GT)";
283 static const char m64n_gtb[] __initdata = "3D RAGE II+ (GTB)";
284 static const char m64n_iic_p[] __initdata = "3D RAGE IIC (PCI)";
285 static const char m64n_iic_a[] __initdata = "3D RAGE IIC (AGP)";
286 static const char m64n_lt[] __initdata = "3D RAGE LT";
287 static const char m64n_ltg[] __initdata = "3D RAGE LT-G";
288 static const char m64n_gtc_ba[] __initdata = "3D RAGE PRO (BGA, AGP)";
289 static const char m64n_gtc_ba1[] __initdata = "3D RAGE PRO (BGA, AGP, 1x only)";
290 static const char m64n_gtc_bp[] __initdata = "3D RAGE PRO (BGA, PCI)";
291 static const char m64n_gtc_pp[] __initdata = "3D RAGE PRO (PQFP, PCI)";
292 static const char m64n_gtc_ppl[] __initdata = "3D RAGE PRO (PQFP, PCI, limited 3D)";
293 static const char m64n_xl[] __initdata = "3D RAGE (XL)";
294 static const char m64n_ltp_a[] __initdata = "3D RAGE LT PRO (AGP)";
295 static const char m64n_ltp_p[] __initdata = "3D RAGE LT PRO (PCI)";
296 static const char m64n_mob_p[] __initdata = "3D RAGE Mobility (PCI)";
297 static const char m64n_mob_a[] __initdata = "3D RAGE Mobility (AGP)";
298
299
300 static const struct {
301 u16 pci_id, chip_type;
302 u8 rev_mask, rev_val;
303 const char *name;
304 int pll, mclk;
305 u32 features;
306 } aty_chips[] __initdata = {
307 #ifdef CONFIG_FB_ATY_GX
308 /* Mach64 GX */
309 { 0x4758, 0x00d7, 0x00, 0x00, m64n_gx, 135, 50, M64F_GX },
310 { 0x4358, 0x0057, 0x00, 0x00, m64n_cx, 135, 50, M64F_GX },
311 #endif /* CONFIG_FB_ATY_GX */
312
313 #ifdef CONFIG_FB_ATY_CT
314 /* Mach64 CT */
315 { 0x4354, 0x4354, 0x00, 0x00, m64n_ct, 135, 60, M64F_CT | M64F_INTEGRATED | M64F_CT_BUS | M64F_MAGIC_FIFO },
316 { 0x4554, 0x4554, 0x00, 0x00, m64n_et, 135, 60, M64F_CT | M64F_INTEGRATED | M64F_CT_BUS | M64F_MAGIC_FIFO },
317
318 /* Mach64 VT */
319 { 0x5654, 0x5654, 0xc7, 0x00, m64n_vta3, 170, 67, M64F_VT | M64F_INTEGRATED | M64F_VT_BUS | M64F_MAGIC_FIFO | M64F_FIFO_24 },
320 { 0x5654, 0x5654, 0xc7, 0x40, m64n_vta4, 200, 67, M64F_VT | M64F_INTEGRATED | M64F_VT_BUS | M64F_MAGIC_FIFO | M64F_FIFO_24 | M64F_MAGIC_POSTDIV },
321 { 0x5654, 0x5654, 0x00, 0x00, m64n_vtb, 200, 67, M64F_VT | M64F_INTEGRATED | M64F_VT_BUS | M64F_GTB_DSP | M64F_FIFO_24 },
322 { 0x5655, 0x5655, 0x00, 0x00, m64n_vtb, 200, 67, M64F_VT | M64F_INTEGRATED | M64F_VT_BUS | M64F_GTB_DSP | M64F_FIFO_24 | M64F_SDRAM_MAGIC_PLL },
323 { 0x5656, 0x5656, 0x00, 0x00, m64n_vt4, 230, 83, M64F_VT | M64F_INTEGRATED | M64F_GTB_DSP },
324
325 /* Mach64 GT (3D RAGE) */
326 { 0x4754, 0x4754, 0x07, 0x00, m64n_gt, 135, 63, M64F_GT | M64F_INTEGRATED | M64F_MAGIC_FIFO | M64F_FIFO_24 | M64F_EXTRA_BRIGHT },
327 { 0x4754, 0x4754, 0x07, 0x01, m64n_gt, 170, 67, M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP | M64F_FIFO_24 | M64F_SDRAM_MAGIC_PLL | M64F_EXTRA_BRIGHT },
328 { 0x4754, 0x4754, 0x07, 0x02, m64n_gt, 200, 67, M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP | M64F_FIFO_24 | M64F_SDRAM_MAGIC_PLL | M64F_EXTRA_BRIGHT },
329 { 0x4755, 0x4755, 0x00, 0x00, m64n_gtb, 200, 67, M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP | M64F_FIFO_24 | M64F_SDRAM_MAGIC_PLL | M64F_EXTRA_BRIGHT },
330 { 0x4756, 0x4756, 0x00, 0x00, m64n_iic_p, 230, 83, M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP | M64F_FIFO_24 | M64F_SDRAM_MAGIC_PLL | M64F_EXTRA_BRIGHT },
331 { 0x4757, 0x4757, 0x00, 0x00, m64n_iic_a, 230, 83, M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP | M64F_FIFO_24 | M64F_SDRAM_MAGIC_PLL | M64F_EXTRA_BRIGHT },
332 { 0x475a, 0x475a, 0x00, 0x00, m64n_iic_a, 230, 83, M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP | M64F_FIFO_24 | M64F_SDRAM_MAGIC_PLL | M64F_EXTRA_BRIGHT },
333
334 /* Mach64 LT */
335 { 0x4c54, 0x4c54, 0x00, 0x00, m64n_lt, 135, 63, M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP },
336 { 0x4c47, 0x4c47, 0x00, 0x00, m64n_ltg, 230, 63, M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL | M64F_EXTRA_BRIGHT | M64F_LT_SLEEP | M64F_G3_PB_1024x768 },
337
338 /* Mach64 GTC (3D RAGE PRO) */
339 { 0x4742, 0x4742, 0x00, 0x00, m64n_gtc_ba, 230, 100, M64F_GT | M64F_INTEGRATED | M64F_RESET_3D | M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL | M64F_EXTRA_BRIGHT },
340 { 0x4744, 0x4744, 0x00, 0x00, m64n_gtc_ba1, 230, 100, M64F_GT | M64F_INTEGRATED | M64F_RESET_3D | M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL | M64F_EXTRA_BRIGHT },
341 { 0x4749, 0x4749, 0x00, 0x00, m64n_gtc_bp, 230, 100, M64F_GT | M64F_INTEGRATED | M64F_RESET_3D | M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL | M64F_EXTRA_BRIGHT | M64F_MAGIC_VRAM_SIZE },
342 { 0x4750, 0x4750, 0x00, 0x00, m64n_gtc_pp, 230, 100, M64F_GT | M64F_INTEGRATED | M64F_RESET_3D | M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL | M64F_EXTRA_BRIGHT },
343 { 0x4751, 0x4751, 0x00, 0x00, m64n_gtc_ppl, 230, 100, M64F_GT | M64F_INTEGRATED | M64F_RESET_3D | M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL | M64F_EXTRA_BRIGHT },
344
345 /* 3D RAGE XL */
346 { 0x4752, 0x4752, 0x00, 0x00, m64n_xl, 230, 120, M64F_GT | M64F_INTEGRATED | M64F_RESET_3D | M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL | M64F_EXTRA_BRIGHT | M64F_XL_DLL },
347
348 /* Mach64 LT PRO */
349 { 0x4c42, 0x4c42, 0x00, 0x00, m64n_ltp_a, 230, 100, M64F_GT | M64F_INTEGRATED | M64F_RESET_3D | M64F_GTB_DSP },
350 { 0x4c44, 0x4c44, 0x00, 0x00, m64n_ltp_p, 230, 100, M64F_GT | M64F_INTEGRATED | M64F_RESET_3D | M64F_GTB_DSP },
351 { 0x4c49, 0x4c49, 0x00, 0x00, m64n_ltp_p, 230, 100, M64F_GT | M64F_INTEGRATED | M64F_RESET_3D | M64F_GTB_DSP | M64F_EXTRA_BRIGHT | M64F_G3_PB_1_1 | M64F_G3_PB_1024x768 },
352 { 0x4c50, 0x4c50, 0x00, 0x00, m64n_ltp_p, 230, 100, M64F_GT | M64F_INTEGRATED | M64F_RESET_3D | M64F_GTB_DSP },
353
354 /* 3D RAGE Mobility */
355 { 0x4c4d, 0x4c4d, 0x00, 0x00, m64n_mob_p, 230, 50, M64F_GT | M64F_INTEGRATED | M64F_RESET_3D | M64F_GTB_DSP | M64F_MOBIL_BUS },
356 { 0x4c4e, 0x4c4e, 0x00, 0x00, m64n_mob_a, 230, 50, M64F_GT | M64F_INTEGRATED | M64F_RESET_3D | M64F_GTB_DSP | M64F_MOBIL_BUS },
357 #endif /* CONFIG_FB_ATY_CT */
358 };
359
360 static const char ram_dram[] __initdata = "DRAM";
361 static const char ram_vram[] __initdata = "VRAM";
362 static const char ram_edo[] __initdata = "EDO";
363 static const char ram_sdram[] __initdata = "SDRAM";
364 static const char ram_sgram[] __initdata = "SGRAM";
365 static const char ram_wram[] __initdata = "WRAM";
366 static const char ram_off[] __initdata = "OFF";
367 static const char ram_resv[] __initdata = "RESV";
368
369 #ifdef CONFIG_FB_ATY_GX
370 static const char *aty_gx_ram[8] __initdata = {
371 ram_dram, ram_vram, ram_vram, ram_dram,
372 ram_dram, ram_vram, ram_vram, ram_resv
373 };
374 #endif /* CONFIG_FB_ATY_GX */
375
376 #ifdef CONFIG_FB_ATY_CT
377 static const char *aty_ct_ram[8] __initdata = {
378 ram_off, ram_dram, ram_edo, ram_edo,
379 ram_sdram, ram_sgram, ram_wram, ram_resv
380 };
381 #endif /* CONFIG_FB_ATY_CT */
382
383
384 #if defined(CONFIG_PPC)
385
386 /*
387 * Apple monitor sense
388 */
389
390 static int __init read_aty_sense(const struct fb_info_aty *info)
391 {
392 int sense, i;
393
394 aty_st_le32(GP_IO, 0x31003100, info); /* drive outputs high */
395 __delay(200);
396 aty_st_le32(GP_IO, 0, info); /* turn off outputs */
397 __delay(2000);
398 i = aty_ld_le32(GP_IO, info); /* get primary sense value */
399 sense = ((i & 0x3000) >> 3) | (i & 0x100);
400
401 /* drive each sense line low in turn and collect the other 2 */
402 aty_st_le32(GP_IO, 0x20000000, info); /* drive A low */
403 __delay(2000);
404 i = aty_ld_le32(GP_IO, info);
405 sense |= ((i & 0x1000) >> 7) | ((i & 0x100) >> 4);
406 aty_st_le32(GP_IO, 0x20002000, info); /* drive A high again */
407 __delay(200);
408
409 aty_st_le32(GP_IO, 0x10000000, info); /* drive B low */
410 __delay(2000);
411 i = aty_ld_le32(GP_IO, info);
412 sense |= ((i & 0x2000) >> 10) | ((i & 0x100) >> 6);
413 aty_st_le32(GP_IO, 0x10001000, info); /* drive B high again */
414 __delay(200);
415
416 aty_st_le32(GP_IO, 0x01000000, info); /* drive C low */
417 __delay(2000);
418 sense |= (aty_ld_le32(GP_IO, info) & 0x3000) >> 12;
419 aty_st_le32(GP_IO, 0, info); /* turn off outputs */
420
421 return sense;
422 }
423
424 #endif /* defined(CONFIG_PPC) */
425
426 #if defined(CONFIG_PMAC_PBOOK) || defined(CONFIG_PMAC_BACKLIGHT)
427 static void aty_st_lcd(int index, u32 val, const struct fb_info_aty *info)
428 {
429 unsigned long temp;
430
431 /* write addr byte */
432 temp = aty_ld_le32(LCD_INDEX, info);
433 aty_st_le32(LCD_INDEX, (temp & ~LCD_INDEX_MASK) | index, info);
434 /* write the register value */
435 aty_st_le32(LCD_DATA, val, info);
436 }
437
438 static u32 aty_ld_lcd(int index, const struct fb_info_aty *info)
439 {
440 unsigned long temp;
441
442 /* write addr byte */
443 temp = aty_ld_le32(LCD_INDEX, info);
444 aty_st_le32(LCD_INDEX, (temp & ~LCD_INDEX_MASK) | index, info);
445 /* read the register value */
446 return aty_ld_le32(LCD_DATA, info);
447 }
448 #endif /* CONFIG_PMAC_PBOOK || CONFIG_PMAC_BACKLIGHT */
449
450 /* ------------------------------------------------------------------------- */
451
452 /*
453 * CRTC programming
454 */
455
456 static void aty_set_crtc(const struct fb_info_aty *info,
457 const struct crtc *crtc)
458 {
459 aty_st_le32(CRTC_H_TOTAL_DISP, crtc->h_tot_disp, info);
460 aty_st_le32(CRTC_H_SYNC_STRT_WID, crtc->h_sync_strt_wid, info);
461 aty_st_le32(CRTC_V_TOTAL_DISP, crtc->v_tot_disp, info);
462 aty_st_le32(CRTC_V_SYNC_STRT_WID, crtc->v_sync_strt_wid, info);
463 aty_st_le32(CRTC_VLINE_CRNT_VLINE, 0, info);
464 aty_st_le32(CRTC_OFF_PITCH, crtc->off_pitch, info);
465 aty_st_le32(CRTC_GEN_CNTL, crtc->gen_cntl, info);
466 }
467
468 static int aty_var_to_crtc(const struct fb_info_aty *info,
469 const struct fb_var_screeninfo *var,
470 struct crtc *crtc)
471 {
472 u32 xres, yres, vxres, vyres, xoffset, yoffset, bpp;
473 u32 left, right, upper, lower, hslen, vslen, sync, vmode;
474 u32 h_total, h_disp, h_sync_strt, h_sync_dly, h_sync_wid, h_sync_pol;
475 u32 v_total, v_disp, v_sync_strt, v_sync_wid, v_sync_pol, c_sync;
476 u32 pix_width, dp_pix_width, dp_chain_mask;
477
478 /* input */
479 xres = var->xres;
480 yres = var->yres;
481 vxres = var->xres_virtual;
482 vyres = var->yres_virtual;
483 xoffset = var->xoffset;
484 yoffset = var->yoffset;
485 bpp = var->bits_per_pixel;
486 left = var->left_margin;
487 right = var->right_margin;
488 upper = var->upper_margin;
489 lower = var->lower_margin;
490 hslen = var->hsync_len;
491 vslen = var->vsync_len;
492 sync = var->sync;
493 vmode = var->vmode;
494
495 /* convert (and round up) and validate */
496 xres = (xres+7) & ~7;
497 xoffset = (xoffset+7) & ~7;
498 vxres = (vxres+7) & ~7;
499 if (vxres < xres+xoffset)
500 vxres = xres+xoffset;
501 h_disp = xres/8-1;
502 if (h_disp > 0xff)
503 FAIL("h_disp too large");
504 h_sync_strt = h_disp+(right/8);
505 if (h_sync_strt > 0x1ff)
506 FAIL("h_sync_start too large");
507 h_sync_dly = right & 7;
508 h_sync_wid = (hslen+7)/8;
509 if (h_sync_wid > 0x1f)
510 FAIL("h_sync_wid too large");
511 h_total = h_sync_strt+h_sync_wid+(h_sync_dly+left+7)/8;
512 if (h_total > 0x1ff)
513 FAIL("h_total too large");
514 h_sync_pol = sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1;
515
516 if (vyres < yres+yoffset)
517 vyres = yres+yoffset;
518 v_disp = yres-1;
519 if (v_disp > 0x7ff)
520 FAIL("v_disp too large");
521 v_sync_strt = v_disp+lower;
522 if (v_sync_strt > 0x7ff)
523 FAIL("v_sync_strt too large");
524 v_sync_wid = vslen;
525 if (v_sync_wid > 0x1f)
526 FAIL("v_sync_wid too large");
527 v_total = v_sync_strt+v_sync_wid+upper;
528 if (v_total > 0x7ff)
529 FAIL("v_total too large");
530 v_sync_pol = sync & FB_SYNC_VERT_HIGH_ACT ? 0 : 1;
531
532 c_sync = sync & FB_SYNC_COMP_HIGH_ACT ? CRTC_CSYNC_EN : 0;
533
534 if (bpp <= 8) {
535 bpp = 8;
536 pix_width = CRTC_PIX_WIDTH_8BPP;
537 dp_pix_width = HOST_8BPP | SRC_8BPP | DST_8BPP | BYTE_ORDER_LSB_TO_MSB;
538 dp_chain_mask = 0x8080;
539 } else if (bpp <= 16) {
540 bpp = 16;
541 pix_width = CRTC_PIX_WIDTH_15BPP;
542 dp_pix_width = HOST_15BPP | SRC_15BPP | DST_15BPP |
543 BYTE_ORDER_LSB_TO_MSB;
544 dp_chain_mask = 0x4210;
545 } else if (bpp <= 24 && M64_HAS(INTEGRATED)) {
546 bpp = 24;
547 pix_width = CRTC_PIX_WIDTH_24BPP;
548 dp_pix_width = HOST_8BPP | SRC_8BPP | DST_8BPP | BYTE_ORDER_LSB_TO_MSB;
549 dp_chain_mask = 0x8080;
550 } else if (bpp <= 32) {
551 bpp = 32;
552 pix_width = CRTC_PIX_WIDTH_32BPP;
553 dp_pix_width = HOST_32BPP | SRC_32BPP | DST_32BPP |
554 BYTE_ORDER_LSB_TO_MSB;
555 dp_chain_mask = 0x8080;
556 } else
557 FAIL("invalid bpp");
558
559 if (vxres*vyres*bpp/8 > info->total_vram)
560 FAIL("not enough video RAM");
561
562 if ((vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED)
563 FAIL("invalid vmode");
564
565 /* output */
566 crtc->vxres = vxres;
567 crtc->vyres = vyres;
568 crtc->xoffset = xoffset;
569 crtc->yoffset = yoffset;
570 crtc->bpp = bpp;
571 crtc->h_tot_disp = h_total | (h_disp<<16);
572 crtc->h_sync_strt_wid = (h_sync_strt & 0xff) | (h_sync_dly<<8) |
573 ((h_sync_strt & 0x100)<<4) | (h_sync_wid<<16) |
574 (h_sync_pol<<21);
575 crtc->v_tot_disp = v_total | (v_disp<<16);
576 crtc->v_sync_strt_wid = v_sync_strt | (v_sync_wid<<16) | (v_sync_pol<<21);
577 crtc->off_pitch = ((yoffset*vxres+xoffset)*bpp/64) | (vxres<<19);
578 crtc->gen_cntl = pix_width | c_sync | CRTC_EXT_DISP_EN | CRTC_ENABLE;
579 if (M64_HAS(MAGIC_FIFO)) {
580 /* Not VTB/GTB */
581 /* FIXME: magic FIFO values */
582 crtc->gen_cntl |= aty_ld_le32(CRTC_GEN_CNTL, info) & 0x000e0000;
583 }
584 crtc->dp_pix_width = dp_pix_width;
585 crtc->dp_chain_mask = dp_chain_mask;
586
587 return 0;
588 }
589
590
591 static int aty_crtc_to_var(const struct crtc *crtc,
592 struct fb_var_screeninfo *var)
593 {
594 u32 xres, yres, bpp, left, right, upper, lower, hslen, vslen, sync;
595 u32 h_total, h_disp, h_sync_strt, h_sync_dly, h_sync_wid, h_sync_pol;
596 u32 v_total, v_disp, v_sync_strt, v_sync_wid, v_sync_pol, c_sync;
597 u32 pix_width;
598
599 /* input */
600 h_total = crtc->h_tot_disp & 0x1ff;
601 h_disp = (crtc->h_tot_disp>>16) & 0xff;
602 h_sync_strt = (crtc->h_sync_strt_wid & 0xff) |
603 ((crtc->h_sync_strt_wid>>4) & 0x100);
604 h_sync_dly = (crtc->h_sync_strt_wid>>8) & 0x7;
605 h_sync_wid = (crtc->h_sync_strt_wid>>16) & 0x1f;
606 h_sync_pol = (crtc->h_sync_strt_wid>>21) & 0x1;
607 v_total = crtc->v_tot_disp & 0x7ff;
608 v_disp = (crtc->v_tot_disp>>16) & 0x7ff;
609 v_sync_strt = crtc->v_sync_strt_wid & 0x7ff;
610 v_sync_wid = (crtc->v_sync_strt_wid>>16) & 0x1f;
611 v_sync_pol = (crtc->v_sync_strt_wid>>21) & 0x1;
612 c_sync = crtc->gen_cntl & CRTC_CSYNC_EN ? 1 : 0;
613 pix_width = crtc->gen_cntl & CRTC_PIX_WIDTH_MASK;
614
615 /* convert */
616 xres = (h_disp+1)*8;
617 yres = v_disp+1;
618 left = (h_total-h_sync_strt-h_sync_wid)*8-h_sync_dly;
619 right = (h_sync_strt-h_disp)*8+h_sync_dly;
620 hslen = h_sync_wid*8;
621 upper = v_total-v_sync_strt-v_sync_wid;
622 lower = v_sync_strt-v_disp;
623 vslen = v_sync_wid;
624 sync = (h_sync_pol ? 0 : FB_SYNC_HOR_HIGH_ACT) |
625 (v_sync_pol ? 0 : FB_SYNC_VERT_HIGH_ACT) |
626 (c_sync ? FB_SYNC_COMP_HIGH_ACT : 0);
627
628 switch (pix_width) {
629 #if 0
630 case CRTC_PIX_WIDTH_4BPP:
631 bpp = 4;
632 var->red.offset = 0;
633 var->red.length = 8;
634 var->green.offset = 0;
635 var->green.length = 8;
636 var->blue.offset = 0;
637 var->blue.length = 8;
638 var->transp.offset = 0;
639 var->transp.length = 0;
640 break;
641 #endif
642 case CRTC_PIX_WIDTH_8BPP:
643 bpp = 8;
644 var->red.offset = 0;
645 var->red.length = 8;
646 var->green.offset = 0;
647 var->green.length = 8;
648 var->blue.offset = 0;
649 var->blue.length = 8;
650 var->transp.offset = 0;
651 var->transp.length = 0;
652 break;
653 case CRTC_PIX_WIDTH_15BPP: /* RGB 555 */
654 bpp = 16;
655 var->red.offset = 10;
656 var->red.length = 5;
657 var->green.offset = 5;
658 var->green.length = 5;
659 var->blue.offset = 0;
660 var->blue.length = 5;
661 var->transp.offset = 0;
662 var->transp.length = 0;
663 break;
664 #if 0
665 case CRTC_PIX_WIDTH_16BPP: /* RGB 565 */
666 bpp = 16;
667 var->red.offset = 11;
668 var->red.length = 5;
669 var->green.offset = 5;
670 var->green.length = 6;
671 var->blue.offset = 0;
672 var->blue.length = 5;
673 var->transp.offset = 0;
674 var->transp.length = 0;
675 break;
676 #endif
677 case CRTC_PIX_WIDTH_24BPP: /* RGB 888 */
678 bpp = 24;
679 var->red.offset = 16;
680 var->red.length = 8;
681 var->green.offset = 8;
682 var->green.length = 8;
683 var->blue.offset = 0;
684 var->blue.length = 8;
685 var->transp.offset = 0;
686 var->transp.length = 0;
687 break;
688 case CRTC_PIX_WIDTH_32BPP: /* ARGB 8888 */
689 bpp = 32;
690 var->red.offset = 16;
691 var->red.length = 8;
692 var->green.offset = 8;
693 var->green.length = 8;
694 var->blue.offset = 0;
695 var->blue.length = 8;
696 var->transp.offset = 24;
697 var->transp.length = 8;
698 break;
699 default:
700 FAIL("Invalid pixel width");
701 }
702
703 /* output */
704 var->xres = xres;
705 var->yres = yres;
706 var->xres_virtual = crtc->vxres;
707 var->yres_virtual = crtc->vyres;
708 var->bits_per_pixel = bpp;
709 var->xoffset = crtc->xoffset;
710 var->yoffset = crtc->yoffset;
711 var->left_margin = left;
712 var->right_margin = right;
713 var->upper_margin = upper;
714 var->lower_margin = lower;
715 var->hsync_len = hslen;
716 var->vsync_len = vslen;
717 var->sync = sync;
718 var->vmode = FB_VMODE_NONINTERLACED;
719
720 return 0;
721 }
722
723 /* ------------------------------------------------------------------------- */
724
725 static void atyfb_set_par(const struct atyfb_par *par,
726 struct fb_info_aty *info)
727 {
728 u32 i;
729 int accelmode;
730 u8 tmp;
731
732 accelmode = par->accel_flags; /* hack */
733
734 info->current_par = *par;
735
736 if (info->blitter_may_be_busy)
737 wait_for_idle(info);
738 tmp = aty_ld_8(CRTC_GEN_CNTL + 3, info);
739 aty_set_crtc(info, &par->crtc);
740 aty_st_8(CLOCK_CNTL + info->clk_wr_offset, 0, info);
741 /* better call aty_StrobeClock ?? */
742 aty_st_8(CLOCK_CNTL + info->clk_wr_offset, CLOCK_STROBE, info);
743
744 info->dac_ops->set_dac(info, &par->pll, par->crtc.bpp, accelmode);
745 info->pll_ops->set_pll(info, &par->pll);
746
747 if (!M64_HAS(INTEGRATED)) {
748 /* Don't forget MEM_CNTL */
749 i = aty_ld_le32(MEM_CNTL, info) & 0xf0ffffff;
750 switch (par->crtc.bpp) {
751 case 8:
752 i |= 0x02000000;
753 break;
754 case 16:
755 i |= 0x03000000;
756 break;
757 case 32:
758 i |= 0x06000000;
759 break;
760 }
761 aty_st_le32(MEM_CNTL, i, info);
762 } else {
763 i = aty_ld_le32(MEM_CNTL, info) & 0xf00fffff;
764 if (!M64_HAS(MAGIC_POSTDIV))
765 i |= info->mem_refresh_rate << 20;
766 switch (par->crtc.bpp) {
767 case 8:
768 case 24:
769 i |= 0x00000000;
770 break;
771 case 16:
772 i |= 0x04000000;
773 break;
774 case 32:
775 i |= 0x08000000;
776 break;
777 }
778 if (M64_HAS(CT_BUS)) {
779 aty_st_le32(DAC_CNTL, 0x87010184, info);
780 aty_st_le32(BUS_CNTL, 0x680000f9, info);
781 } else if (M64_HAS(VT_BUS)) {
782 aty_st_le32(DAC_CNTL, 0x87010184, info);
783 aty_st_le32(BUS_CNTL, 0x680000f9, info);
784 } else if (M64_HAS(MOBIL_BUS)) {
785 aty_st_le32(DAC_CNTL, 0x80010102, info);
786 aty_st_le32(BUS_CNTL, 0x7b33a040, info);
787 } else {
788 /* GT */
789 aty_st_le32(DAC_CNTL, 0x86010102, info);
790 aty_st_le32(BUS_CNTL, 0x7b23a040, info);
791 aty_st_le32(EXT_MEM_CNTL,
792 aty_ld_le32(EXT_MEM_CNTL, info) | 0x5000001, info);
793 }
794 aty_st_le32(MEM_CNTL, i, info);
795 }
796 aty_st_8(DAC_MASK, 0xff, info);
797
798 /* Initialize the graphics engine */
799 if (par->accel_flags & FB_ACCELF_TEXT)
800 aty_init_engine(par, info);
801
802 #ifdef CONFIG_FB_COMPAT_XPMAC
803 if (!console_fb_info || console_fb_info == &info->fb_info) {
804 struct fb_var_screeninfo var;
805 int vmode, cmode;
806 display_info.height = ((par->crtc.v_tot_disp>>16) & 0x7ff)+1;
807 display_info.width = (((par->crtc.h_tot_disp>>16) & 0xff)+1)*8;
808 display_info.depth = par->crtc.bpp;
809 display_info.pitch = par->crtc.vxres*par->crtc.bpp/8;
810 atyfb_encode_var(&var, par, info);
811 if (mac_var_to_vmode(&var, &vmode, &cmode))
812 display_info.mode = 0;
813 else
814 display_info.mode = vmode;
815 strcpy(display_info.name, atyfb_name);
816 display_info.fb_address = info->frame_buffer_phys;
817 display_info.cmap_adr_address = info->ati_regbase_phys+0xc0;
818 display_info.cmap_data_address = info->ati_regbase_phys+0xc1;
819 display_info.disp_reg_address = info->ati_regbase_phys;
820 }
821 #endif /* CONFIG_FB_COMPAT_XPMAC */
822 }
823
824 static int atyfb_decode_var(const struct fb_var_screeninfo *var,
825 struct atyfb_par *par,
826 const struct fb_info_aty *info)
827 {
828 int err;
829
830 if ((err = aty_var_to_crtc(info, var, &par->crtc)) ||
831 (err = info->pll_ops->var_to_pll(info, var->pixclock, par->crtc.bpp,
832 &par->pll)))
833 return err;
834
835 if (var->accel_flags & FB_ACCELF_TEXT)
836 par->accel_flags = FB_ACCELF_TEXT;
837 else
838 par->accel_flags = 0;
839
840 #if 0 /* fbmon is not done. uncomment for 2.5.x -brad */
841 if (!fbmon_valid_timings(var->pixclock, htotal, vtotal, info))
842 return -EINVAL;
843 #endif
844
845 return 0;
846 }
847
848 static int atyfb_encode_var(struct fb_var_screeninfo *var,
849 const struct atyfb_par *par,
850 const struct fb_info_aty *info)
851 {
852 int err;
853
854 memset(var, 0, sizeof(struct fb_var_screeninfo));
855
856 if ((err = aty_crtc_to_var(&par->crtc, var)))
857 return err;
858 var->pixclock = info->pll_ops->pll_to_var(info, &par->pll);
859
860 var->height = -1;
861 var->width = -1;
862 var->accel_flags = par->accel_flags;
863
864 return 0;
865 }
866
867
868
869 static void set_off_pitch(struct atyfb_par *par,
870 const struct fb_info_aty *info)
871 {
872 u32 xoffset = par->crtc.xoffset;
873 u32 yoffset = par->crtc.yoffset;
874 u32 vxres = par->crtc.vxres;
875 u32 bpp = par->crtc.bpp;
876
877 par->crtc.off_pitch = ((yoffset*vxres+xoffset)*bpp/64) | (vxres<<19);
878 aty_st_le32(CRTC_OFF_PITCH, par->crtc.off_pitch, info);
879 }
880
881
882 /*
883 * Open/Release the frame buffer device
884 */
885
886 static int atyfb_open(struct fb_info *info, int user)
887
888 {
889 #ifdef __sparc__
890 struct fb_info_aty *fb = (struct fb_info_aty *)info;
891
892 if (user) {
893 fb->open++;
894 fb->mmaped = 0;
895 fb->vtconsole = -1;
896 } else {
897 fb->consolecnt++;
898 }
899 #endif
900 return(0);
901 }
902
903 struct fb_var_screeninfo default_var = {
904 /* 640x480, 60 Hz, Non-Interlaced (25.175 MHz dotclock) */
905 640, 480, 640, 480, 0, 0, 8, 0,
906 {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
907 0, 0, -1, -1, 0, 39722, 48, 16, 33, 10, 96, 2,
908 0, FB_VMODE_NONINTERLACED
909 };
910
911 static int atyfb_release(struct fb_info *info, int user)
912 {
913 #ifdef __sparc__
914 struct fb_info_aty *fb = (struct fb_info_aty *)info;
915
916 if (user) {
917 fb->open--;
918 mdelay(1);
919 wait_for_idle(fb);
920 if (!fb->open) {
921 int was_mmaped = fb->mmaped;
922
923 fb->mmaped = 0;
924 if (fb->vtconsole != -1)
925 vt_cons[fb->vtconsole]->vc_mode = KD_TEXT;
926 fb->vtconsole = -1;
927
928 if (was_mmaped) {
929 struct fb_var_screeninfo var;
930
931 /* Now reset the default display config, we have no
932 * idea what the program(s) which mmap'd the chip did
933 * to the configuration, nor whether it restored it
934 * correctly.
935 */
936 var = default_var;
937 if (noaccel)
938 var.accel_flags &= ~FB_ACCELF_TEXT;
939 else
940 var.accel_flags |= FB_ACCELF_TEXT;
941 if (var.yres == var.yres_virtual) {
942 u32 vram = (fb->total_vram - (PAGE_SIZE << 2));
943 var.yres_virtual = ((vram * 8) / var.bits_per_pixel) /
944 var.xres_virtual;
945 if (var.yres_virtual < var.yres)
946 var.yres_virtual = var.yres;
947 }
948 atyfb_set_var(&var, -1, &fb->fb_info);
949 }
950 }
951 } else {
952 fb->consolecnt--;
953 }
954 #endif
955 return(0);
956 }
957
958
959 static int encode_fix(struct fb_fix_screeninfo *fix,
960 const struct atyfb_par *par,
961 const struct fb_info_aty *info)
962 {
963 memset(fix, 0, sizeof(struct fb_fix_screeninfo));
964
965 strcpy(fix->id, atyfb_name);
966 fix->smem_start = info->frame_buffer_phys;
967 fix->smem_len = (u32)info->total_vram;
968
969 /*
970 * Reg Block 0 (CT-compatible block) is at ati_regbase_phys
971 * Reg Block 1 (multimedia extensions) is at ati_regbase_phys-0x400
972 */
973 if (M64_HAS(GX)) {
974 fix->mmio_start = info->ati_regbase_phys;
975 fix->mmio_len = 0x400;
976 fix->accel = FB_ACCEL_ATI_MACH64GX;
977 } else if (M64_HAS(CT)) {
978 fix->mmio_start = info->ati_regbase_phys;
979 fix->mmio_len = 0x400;
980 fix->accel = FB_ACCEL_ATI_MACH64CT;
981 } else if (M64_HAS(VT)) {
982 fix->mmio_start = info->ati_regbase_phys-0x400;
983 fix->mmio_len = 0x800;
984 fix->accel = FB_ACCEL_ATI_MACH64VT;
985 } else /* if (M64_HAS(GT)) */ {
986 fix->mmio_start = info->ati_regbase_phys-0x400;
987 fix->mmio_len = 0x800;
988 fix->accel = FB_ACCEL_ATI_MACH64GT;
989 }
990 fix->type = FB_TYPE_PACKED_PIXELS;
991 fix->type_aux = 0;
992 fix->line_length = par->crtc.vxres*par->crtc.bpp/8;
993 fix->visual = par->crtc.bpp <= 8 ? FB_VISUAL_PSEUDOCOLOR
994 : FB_VISUAL_DIRECTCOLOR;
995 fix->ywrapstep = 0;
996 fix->xpanstep = 8;
997 fix->ypanstep = 1;
998
999 return 0;
1000 }
1001
1002
1003 /*
1004 * Get the Fixed Part of the Display
1005 */
1006
1007 static int atyfb_get_fix(struct fb_fix_screeninfo *fix, int con,
1008 struct fb_info *fb)
1009 {
1010 const struct fb_info_aty *info = (struct fb_info_aty *)fb;
1011 struct atyfb_par par;
1012
1013 if (con == -1)
1014 par = info->default_par;
1015 else
1016 atyfb_decode_var(&fb_display[con].var, &par, info);
1017 encode_fix(fix, &par, info);
1018 return 0;
1019 }
1020
1021
1022 /*
1023 * Get the User Defined Part of the Display
1024 */
1025
1026 static int atyfb_get_var(struct fb_var_screeninfo *var, int con,
1027 struct fb_info *fb)
1028 {
1029 const struct fb_info_aty *info = (struct fb_info_aty *)fb;
1030
1031 if (con == -1)
1032 atyfb_encode_var(var, &info->default_par, info);
1033 else
1034 *var = fb_display[con].var;
1035 return 0;
1036 }
1037
1038
1039 static void atyfb_set_dispsw(struct display *disp, struct fb_info_aty *info,
1040 int bpp, int accel)
1041 {
1042 switch (bpp) {
1043 #ifdef FBCON_HAS_CFB8
1044 case 8:
1045 info->dispsw = accel ? fbcon_aty8 : fbcon_cfb8;
1046 disp->dispsw = &info->dispsw;
1047 break;
1048 #endif
1049 #ifdef FBCON_HAS_CFB16
1050 case 16:
1051 info->dispsw = accel ? fbcon_aty16 : fbcon_cfb16;
1052 disp->dispsw = &info->dispsw;
1053 disp->dispsw_data = info->fbcon_cmap.cfb16;
1054 break;
1055 #endif
1056 #ifdef FBCON_HAS_CFB24
1057 case 24:
1058 info->dispsw = accel ? fbcon_aty24 : fbcon_cfb24;
1059 disp->dispsw = &info->dispsw;
1060 disp->dispsw_data = info->fbcon_cmap.cfb24;
1061 break;
1062 #endif
1063 #ifdef FBCON_HAS_CFB32
1064 case 32:
1065 info->dispsw = accel ? fbcon_aty32 : fbcon_cfb32;
1066 disp->dispsw = &info->dispsw;
1067 disp->dispsw_data = info->fbcon_cmap.cfb32;
1068 break;
1069 #endif
1070 default:
1071 disp->dispsw = &fbcon_dummy;
1072 }
1073 #ifdef CONFIG_FB_ATY_CT
1074 if (info->cursor) {
1075 info->dispsw.cursor = atyfb_cursor;
1076 info->dispsw.set_font = atyfb_set_font;
1077 }
1078 #endif /* CONFIG_FB_ATY_CT */
1079 }
1080
1081
1082 /*
1083 * Set the User Defined Part of the Display
1084 */
1085
1086 static int atyfb_set_var(struct fb_var_screeninfo *var, int con,
1087 struct fb_info *fb)
1088 {
1089 struct fb_info_aty *info = (struct fb_info_aty *)fb;
1090 struct atyfb_par par;
1091 struct display *display;
1092 int oldxres, oldyres, oldvxres, oldvyres, oldbpp, oldaccel, accel, err;
1093 int activate = var->activate;
1094
1095 if (con >= 0)
1096 display = &fb_display[con];
1097 else
1098 display = fb->disp; /* used during initialization */
1099
1100 if ((err = atyfb_decode_var(var, &par, info)))
1101 return err;
1102
1103 atyfb_encode_var(var, &par, (struct fb_info_aty *)info);
1104
1105 if ((activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {
1106 oldxres = display->var.xres;
1107 oldyres = display->var.yres;
1108 oldvxres = display->var.xres_virtual;
1109 oldvyres = display->var.yres_virtual;
1110 oldbpp = display->var.bits_per_pixel;
1111 oldaccel = display->var.accel_flags;
1112 display->var = *var;
1113 accel = var->accel_flags & FB_ACCELF_TEXT;
1114 if (oldxres != var->xres || oldyres != var->yres ||
1115 oldvxres != var->xres_virtual || oldvyres != var->yres_virtual ||
1116 oldbpp != var->bits_per_pixel || oldaccel != var->accel_flags) {
1117 struct fb_fix_screeninfo fix;
1118
1119 encode_fix(&fix, &par, info);
1120 display->screen_base = (char *)info->frame_buffer;
1121 display->visual = fix.visual;
1122 display->type = fix.type;
1123 display->type_aux = fix.type_aux;
1124 display->ypanstep = fix.ypanstep;
1125 display->ywrapstep = fix.ywrapstep;
1126 display->line_length = fix.line_length;
1127 display->can_soft_blank = 1;
1128 display->inverse = 0;
1129 if (accel)
1130 display->scrollmode = (info->bus_type == PCI) ? SCROLL_YNOMOVE : 0;
1131 else
1132 display->scrollmode = SCROLL_YREDRAW;
1133 if (info->fb_info.changevar)
1134 (*info->fb_info.changevar)(con);
1135 }
1136 if (!info->fb_info.display_fg ||
1137 info->fb_info.display_fg->vc_num == con) {
1138 atyfb_set_par(&par, info);
1139 atyfb_set_dispsw(display, info, par.crtc.bpp, accel);
1140 }
1141 if (oldbpp != var->bits_per_pixel) {
1142 if ((err = fb_alloc_cmap(&display->cmap, 0, 0)))
1143 return err;
1144 do_install_cmap(con, &info->fb_info);
1145 }
1146 }
1147
1148 return 0;
1149 }
1150
1151
1152 /*
1153 * Pan or Wrap the Display
1154 *
1155 * This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
1156 */
1157
1158 static int atyfb_pan_display(struct fb_var_screeninfo *var, int con,
1159 struct fb_info *fb)
1160 {
1161 struct fb_info_aty *info = (struct fb_info_aty *)fb;
1162 u32 xres, yres, xoffset, yoffset;
1163 struct atyfb_par *par = &info->current_par;
1164
1165 xres = (((par->crtc.h_tot_disp>>16) & 0xff)+1)*8;
1166 yres = ((par->crtc.v_tot_disp>>16) & 0x7ff)+1;
1167 xoffset = (var->xoffset+7) & ~7;
1168 yoffset = var->yoffset;
1169 if (xoffset+xres > par->crtc.vxres || yoffset+yres > par->crtc.vyres)
1170 return -EINVAL;
1171 par->crtc.xoffset = xoffset;
1172 par->crtc.yoffset = yoffset;
1173 set_off_pitch(par, info);
1174 return 0;
1175 }
1176
1177 /*
1178 * Get the Colormap
1179 */
1180
1181 static int atyfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
1182 struct fb_info *info)
1183 {
1184 if (!info->display_fg || con == info->display_fg->vc_num) /* current console? */
1185 return fb_get_cmap(cmap, kspc, atyfb_getcolreg, info);
1186 else if (fb_display[con].cmap.len) /* non default colormap? */
1187 fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
1188 else {
1189 int size = fb_display[con].var.bits_per_pixel == 16 ? 32 : 256;
1190 fb_copy_cmap(fb_default_cmap(size), cmap, kspc ? 0 : 2);
1191 }
1192 return 0;
1193 }
1194
1195 /*
1196 * Set the Colormap
1197 */
1198
1199 static int atyfb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
1200 struct fb_info *info)
1201 {
1202 int err;
1203 struct display *disp;
1204
1205 if (con >= 0)
1206 disp = &fb_display[con];
1207 else
1208 disp = info->disp;
1209 if (!disp->cmap.len) { /* no colormap allocated? */
1210 int size = disp->var.bits_per_pixel == 16 ? 32 : 256;
1211 if ((err = fb_alloc_cmap(&disp->cmap, size, 0)))
1212 return err;
1213 }
1214 if (!info->display_fg || con == info->display_fg->vc_num) /* current console? */
1215 return fb_set_cmap(cmap, kspc, atyfb_setcolreg, info);
1216 else
1217 fb_copy_cmap(cmap, &disp->cmap, kspc ? 0 : 1);
1218 return 0;
1219 }
1220
1221
1222 #ifdef DEBUG
1223 #define ATYIO_CLKR 0x41545900 /* ATY\00 */
1224 #define ATYIO_CLKW 0x41545901 /* ATY\01 */
1225
1226 struct atyclk {
1227 u32 ref_clk_per;
1228 u8 pll_ref_div;
1229 u8 mclk_fb_div;
1230 u8 mclk_post_div; /* 1,2,3,4,8 */
1231 u8 vclk_fb_div;
1232 u8 vclk_post_div; /* 1,2,3,4,6,8,12 */
1233 u32 dsp_xclks_per_row; /* 0-16383 */
1234 u32 dsp_loop_latency; /* 0-15 */
1235 u32 dsp_precision; /* 0-7 */
1236 u32 dsp_on; /* 0-2047 */
1237 u32 dsp_off; /* 0-2047 */
1238 };
1239
1240 #define ATYIO_FEATR 0x41545902 /* ATY\02 */
1241 #define ATYIO_FEATW 0x41545903 /* ATY\03 */
1242 #endif
1243
1244 static int atyfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
1245 u_long arg, int con, struct fb_info *info2)
1246 {
1247 #if defined(__sparc__) || (defined(DEBUG) && defined(CONFIG_FB_ATY_CT))
1248 struct fb_info_aty *info = (struct fb_info_aty *)info2;
1249 #endif /* __sparc__ || DEBUG */
1250 #ifdef __sparc__
1251 struct fbtype fbtyp;
1252 struct display *disp;
1253
1254 if (con >= 0)
1255 disp = &fb_display[con];
1256 else
1257 disp = info2->disp;
1258 #endif
1259
1260 switch (cmd) {
1261 #ifdef __sparc__
1262 case FBIOGTYPE:
1263 fbtyp.fb_type = FBTYPE_PCI_GENERIC;
1264 fbtyp.fb_width = info->current_par.crtc.vxres;
1265 fbtyp.fb_height = info->current_par.crtc.vyres;
1266 fbtyp.fb_depth = info->current_par.crtc.bpp;
1267 fbtyp.fb_cmsize = disp->cmap.len;
1268 fbtyp.fb_size = info->total_vram;
1269 if (copy_to_user((struct fbtype *)arg, &fbtyp, sizeof(fbtyp)))
1270 return -EFAULT;
1271 break;
1272 #endif /* __sparc__ */
1273 #if defined(DEBUG) && defined(CONFIG_FB_ATY_CT)
1274 case ATYIO_CLKR:
1275 if (M64_HAS(INTEGRATED)) {
1276 struct atyclk clk;
1277 union aty_pll *pll = &info->current_par.pll;
1278 u32 dsp_config = pll->ct.dsp_config;
1279 u32 dsp_on_off = pll->ct.dsp_on_off;
1280 clk.ref_clk_per = info->ref_clk_per;
1281 clk.pll_ref_div = pll->ct.pll_ref_div;
1282 clk.mclk_fb_div = pll->ct.mclk_fb_div;
1283 clk.mclk_post_div = pll->ct.mclk_post_div_real;
1284 clk.vclk_fb_div = pll->ct.vclk_fb_div;
1285 clk.vclk_post_div = pll->ct.vclk_post_div_real;
1286 clk.dsp_xclks_per_row = dsp_config & 0x3fff;
1287 clk.dsp_loop_latency = (dsp_config>>16) & 0xf;
1288 clk.dsp_precision = (dsp_config>>20) & 7;
1289 clk.dsp_on = dsp_on_off & 0x7ff;
1290 clk.dsp_off = (dsp_on_off>>16) & 0x7ff;
1291 if (copy_to_user((struct atyclk *)arg, &clk, sizeof(clk)))
1292 return -EFAULT;
1293 } else
1294 return -EINVAL;
1295 break;
1296 case ATYIO_CLKW:
1297 if (M64_HAS(INTEGRATED)) {
1298 struct atyclk clk;
1299 union aty_pll *pll = &info->current_par.pll;
1300 if (copy_from_user(&clk, (struct atyclk *)arg, sizeof(clk)))
1301 return -EFAULT;
1302 info->ref_clk_per = clk.ref_clk_per;
1303 pll->ct.pll_ref_div = clk.pll_ref_div;
1304 pll->ct.mclk_fb_div = clk.mclk_fb_div;
1305 pll->ct.mclk_post_div_real = clk.mclk_post_div;
1306 pll->ct.vclk_fb_div = clk.vclk_fb_div;
1307 pll->ct.vclk_post_div_real = clk.vclk_post_div;
1308 pll->ct.dsp_config = (clk.dsp_xclks_per_row & 0x3fff) |
1309 ((clk.dsp_loop_latency & 0xf)<<16) |
1310 ((clk.dsp_precision & 7)<<20);
1311 pll->ct.dsp_on_off = (clk.dsp_on & 0x7ff) |
1312 ((clk.dsp_off & 0x7ff)<<16);
1313 aty_calc_pll_ct(info, &pll->ct);
1314 aty_set_pll_ct(info, pll);
1315 } else
1316 return -EINVAL;
1317 break;
1318 case ATYIO_FEATR:
1319 if (get_user(info->features, (u32 *)arg))
1320 return -EFAULT;
1321 break;
1322 case ATYIO_FEATW:
1323 if (put_user(info->features, (u32 *)arg))
1324 return -EFAULT;
1325 break;
1326 #endif /* DEBUG && CONFIG_FB_ATY_CT */
1327 default:
1328 return -EINVAL;
1329 }
1330 return 0;
1331 }
1332
1333 static int atyfb_rasterimg(struct fb_info *info, int start)
1334 {
1335 struct fb_info_aty *fb = (struct fb_info_aty *)info;
1336
1337 if (fb->blitter_may_be_busy)
1338 wait_for_idle(fb);
1339 return 0;
1340 }
1341
1342 #ifdef __sparc__
1343 static int atyfb_mmap(struct fb_info *info, struct file *file,
1344 struct vm_area_struct *vma)
1345 {
1346 struct fb_info_aty *fb = (struct fb_info_aty *)info;
1347 unsigned int size, page, map_size = 0;
1348 unsigned long map_offset = 0;
1349 unsigned long off;
1350 int i;
1351
1352 if (!fb->mmap_map)
1353 return -ENXIO;
1354
1355 if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
1356 return -EINVAL;
1357
1358 off = vma->vm_pgoff << PAGE_SHIFT;
1359 size = vma->vm_end - vma->vm_start;
1360
1361 /* To stop the swapper from even considering these pages. */
1362 vma->vm_flags |= (VM_SHM | VM_LOCKED);
1363
1364 if (((vma->vm_pgoff == 0) && (size == fb->total_vram)) ||
1365 ((off == fb->total_vram) && (size == PAGE_SIZE)))
1366 off += 0x8000000000000000UL;
1367
1368 vma->vm_pgoff = off >> PAGE_SHIFT; /* propagate off changes */
1369
1370 /* Each page, see which map applies */
1371 for (page = 0; page < size; ) {
1372 map_size = 0;
1373 for (i = 0; fb->mmap_map[i].size; i++) {
1374 unsigned long start = fb->mmap_map[i].voff;
1375 unsigned long end = start + fb->mmap_map[i].size;
1376 unsigned long offset = off + page;
1377
1378 if (start > offset)
1379 continue;
1380 if (offset >= end)
1381 continue;
1382
1383 map_size = fb->mmap_map[i].size - (offset - start);
1384 map_offset = fb->mmap_map[i].poff + (offset - start);
1385 break;
1386 }
1387 if (!map_size) {
1388 page += PAGE_SIZE;
1389 continue;
1390 }
1391 if (page + map_size > size)
1392 map_size = size - page;
1393
1394 pgprot_val(vma->vm_page_prot) &= ~(fb->mmap_map[i].prot_mask);
1395 pgprot_val(vma->vm_page_prot) |= fb->mmap_map[i].prot_flag;
1396
1397 if (remap_page_range(vma->vm_start + page, map_offset,
1398 map_size, vma->vm_page_prot))
1399 return -EAGAIN;
1400
1401 page += map_size;
1402 }
1403
1404 if (!map_size)
1405 return -EINVAL;
1406
1407 vma->vm_flags |= VM_IO;
1408
1409 if (!fb->mmaped) {
1410 int lastconsole = 0;
1411
1412 if (info->display_fg)
1413 lastconsole = info->display_fg->vc_num;
1414 fb->mmaped = 1;
1415 if (fb->consolecnt && fb_display[lastconsole].fb_info == info) {
1416 fb->vtconsole = lastconsole;
1417 vt_cons[lastconsole]->vc_mode = KD_GRAPHICS;
1418 }
1419 }
1420 return 0;
1421 }
1422
1423 static struct {
1424 u32 yoffset;
1425 u8 r[2][256];
1426 u8 g[2][256];
1427 u8 b[2][256];
1428 } atyfb_save;
1429
1430 static void atyfb_save_palette(struct fb_info *fb, int enter)
1431 {
1432 struct fb_info_aty *info = (struct fb_info_aty *)fb;
1433 int i, tmp;
1434
1435 for (i = 0; i < 256; i++) {
1436 tmp = aty_ld_8(DAC_CNTL, info) & 0xfc;
1437 if (M64_HAS(EXTRA_BRIGHT))
1438 tmp |= 0x2;
1439 aty_st_8(DAC_CNTL, tmp, info);
1440 aty_st_8(DAC_MASK, 0xff, info);
1441
1442 writeb(i, &info->aty_cmap_regs->rindex);
1443 atyfb_save.r[enter][i] = readb(&info->aty_cmap_regs->lut);
1444 atyfb_save.g[enter][i] = readb(&info->aty_cmap_regs->lut);
1445 atyfb_save.b[enter][i] = readb(&info->aty_cmap_regs->lut);
1446 writeb(i, &info->aty_cmap_regs->windex);
1447 writeb(atyfb_save.r[1-enter][i], &info->aty_cmap_regs->lut);
1448 writeb(atyfb_save.g[1-enter][i], &info->aty_cmap_regs->lut);
1449 writeb(atyfb_save.b[1-enter][i], &info->aty_cmap_regs->lut);
1450 }
1451 }
1452
1453 static void atyfb_palette(int enter)
1454 {
1455 struct fb_info_aty *info;
1456 struct atyfb_par *par;
1457 struct display *d;
1458 int i;
1459
1460 for (i = 0; i < MAX_NR_CONSOLES; i++) {
1461 d = &fb_display[i];
1462 if (d->fb_info &&
1463 d->fb_info->fbops == &atyfb_ops &&
1464 d->fb_info->display_fg &&
1465 d->fb_info->display_fg->vc_num == i) {
1466 atyfb_save_palette(d->fb_info, enter);
1467 info = (struct fb_info_aty *)d->fb_info;
1468 par = &info->current_par;
1469 if (enter) {
1470 atyfb_save.yoffset = par->crtc.yoffset;
1471 par->crtc.yoffset = 0;
1472 set_off_pitch(par, info);
1473 } else {
1474 par->crtc.yoffset = atyfb_save.yoffset;
1475 set_off_pitch(par, info);
1476 }
1477 break;
1478 }
1479 }
1480 }
1481 #endif /* __sparc__ */
1482
1483
1484
1485 #ifdef CONFIG_PMAC_PBOOK
1486
1487 static struct fb_info_aty* first_display = NULL;
1488
1489 /* Power management routines. Those are used for PowerBook sleep.
1490 *
1491 * It appears that Rage LT and Rage LT Pro have different power
1492 * management registers. There's is some confusion about which
1493 * chipID is a Rage LT or LT pro :(
1494 */
1495 static int aty_power_mgmt_LT(int sleep, struct fb_info_aty *info)
1496 {
1497 unsigned int pm;
1498 int timeout;
1499
1500 pm = aty_ld_le32(POWER_MANAGEMENT_LG, info);
1501 pm = (pm & ~PWR_MGT_MODE_MASK) | PWR_MGT_MODE_REG;
1502 aty_st_le32(POWER_MANAGEMENT_LG, pm, info);
1503 pm = aty_ld_le32(POWER_MANAGEMENT_LG, info);
1504
1505 timeout = 200000;
1506 if (sleep) {
1507 /* Sleep */
1508 pm &= ~PWR_MGT_ON;
1509 aty_st_le32(POWER_MANAGEMENT_LG, pm, info);
1510 pm = aty_ld_le32(POWER_MANAGEMENT_LG, info);
1511 udelay(10);
1512 pm &= ~(PWR_BLON | AUTO_PWR_UP);
1513 pm |= SUSPEND_NOW;
1514 aty_st_le32(POWER_MANAGEMENT_LG, pm, info);
1515 pm = aty_ld_le32(POWER_MANAGEMENT_LG, info);
1516 udelay(10);
1517 pm |= PWR_MGT_ON;
1518 aty_st_le32(POWER_MANAGEMENT_LG, pm, info);
1519 do {
1520 pm = aty_ld_le32(POWER_MANAGEMENT_LG, info);
1521 udelay(10);
1522 if ((--timeout) == 0)
1523 break;
1524 } while ((pm & PWR_MGT_STATUS_MASK) != PWR_MGT_STATUS_SUSPEND);
1525 } else {
1526 /* Wakeup */
1527 pm &= ~PWR_MGT_ON;
1528 aty_st_le32(POWER_MANAGEMENT_LG, pm, info);
1529 pm = aty_ld_le32(POWER_MANAGEMENT_LG, info);
1530 udelay(10);
1531 pm |= (PWR_BLON | AUTO_PWR_UP);
1532 pm &= ~SUSPEND_NOW;
1533 aty_st_le32(POWER_MANAGEMENT_LG, pm, info);
1534 pm = aty_ld_le32(POWER_MANAGEMENT_LG, info);
1535 udelay(10);
1536 pm |= PWR_MGT_ON;
1537 aty_st_le32(POWER_MANAGEMENT_LG, pm, info);
1538 do {
1539 pm = aty_ld_le32(POWER_MANAGEMENT_LG, info);
1540 udelay(10);
1541 if ((--timeout) == 0)
1542 break;
1543 } while ((pm & PWR_MGT_STATUS_MASK) != 0);
1544 }
1545 mdelay(500);
1546
1547 return timeout ? PBOOK_SLEEP_OK : PBOOK_SLEEP_REFUSE;
1548 }
1549
1550 static int aty_power_mgmt_LTPro(int sleep, struct fb_info_aty *info)
1551 {
1552 unsigned int pm;
1553 int timeout;
1554
1555 pm = aty_ld_lcd(POWER_MANAGEMENT, info);
1556 pm = (pm & ~PWR_MGT_MODE_MASK) | PWR_MGT_MODE_REG;
1557 aty_st_lcd(POWER_MANAGEMENT, pm, info);
1558 pm = aty_ld_lcd(POWER_MANAGEMENT, info);
1559
1560 timeout = 200;
1561 if (sleep) {
1562 /* Sleep */
1563 pm &= ~PWR_MGT_ON;
1564 aty_st_lcd(POWER_MANAGEMENT, pm, info);
1565 pm = aty_ld_lcd(POWER_MANAGEMENT, info);
1566 udelay(10);
1567 pm &= ~(PWR_BLON | AUTO_PWR_UP);
1568 pm |= SUSPEND_NOW;
1569 aty_st_lcd(POWER_MANAGEMENT, pm, info);
1570 pm = aty_ld_lcd(POWER_MANAGEMENT, info);
1571 udelay(10);
1572 pm |= PWR_MGT_ON;
1573 aty_st_lcd(POWER_MANAGEMENT, pm, info);
1574 do {
1575 pm = aty_ld_lcd(POWER_MANAGEMENT, info);
1576 mdelay(1);
1577 if ((--timeout) == 0)
1578 break;
1579 } while ((pm & PWR_MGT_STATUS_MASK) != PWR_MGT_STATUS_SUSPEND);
1580 } else {
1581 /* Wakeup */
1582 pm &= ~PWR_MGT_ON;
1583 aty_st_lcd(POWER_MANAGEMENT, pm, info);
1584 pm = aty_ld_lcd(POWER_MANAGEMENT, info);
1585 udelay(10);
1586 pm &= ~SUSPEND_NOW;
1587 pm |= (PWR_BLON | AUTO_PWR_UP);
1588 aty_st_lcd(POWER_MANAGEMENT, pm, info);
1589 pm = aty_ld_lcd(POWER_MANAGEMENT, info);
1590 udelay(10);
1591 pm |= PWR_MGT_ON;
1592 aty_st_lcd(POWER_MANAGEMENT, pm, info);
1593 do {
1594 pm = aty_ld_lcd(POWER_MANAGEMENT, info);
1595 mdelay(1);
1596 if ((--timeout) == 0)
1597 break;
1598 } while ((pm & PWR_MGT_STATUS_MASK) != 0);
1599 }
1600
1601 return timeout ? PBOOK_SLEEP_OK : PBOOK_SLEEP_REFUSE;
1602 }
1603
1604 static int aty_power_mgmt(int sleep, struct fb_info_aty *info)
1605 {
1606 return M64_HAS(LT_SLEEP) ? aty_power_mgmt_LT(sleep, info)
1607 : aty_power_mgmt_LTPro(sleep, info);
1608 }
1609
1610 /*
1611 * Save the contents of the frame buffer when we go to sleep,
1612 * and restore it when we wake up again.
1613 */
1614 static int aty_sleep_notify(struct pmu_sleep_notifier *self, int when)
1615 {
1616 struct fb_info_aty *info;
1617 int result;
1618
1619 result = PBOOK_SLEEP_OK;
1620
1621 for (info = first_display; info != NULL; info = info->next) {
1622 struct fb_fix_screeninfo fix;
1623 int nb;
1624
1625 atyfb_get_fix(&fix, fg_console, (struct fb_info *)info);
1626 nb = fb_display[fg_console].var.yres * fix.line_length;
1627
1628 switch (when) {
1629 case PBOOK_SLEEP_REQUEST:
1630 info->save_framebuffer = vmalloc(nb);
1631 if (info->save_framebuffer == NULL)
1632 return PBOOK_SLEEP_REFUSE;
1633 break;
1634 case PBOOK_SLEEP_REJECT:
1635 if (info->save_framebuffer) {
1636 vfree(info->save_framebuffer);
1637 info->save_framebuffer = 0;
1638 }
1639 break;
1640 case PBOOK_SLEEP_NOW:
1641 if (info->blitter_may_be_busy)
1642 wait_for_idle(info);
1643 /* Stop accel engine (stop bus mastering) */
1644 if (info->current_par.accel_flags & FB_ACCELF_TEXT)
1645 aty_reset_engine(info);
1646
1647 /* Backup fb content */
1648 if (info->save_framebuffer)
1649 memcpy_fromio(info->save_framebuffer,
1650 (void *)info->frame_buffer, nb);
1651
1652 /* Blank display and LCD */
1653 atyfbcon_blank(VESA_POWERDOWN+1, (struct fb_info *)info);
1654
1655 /* Set chip to "suspend" mode */
1656 result = aty_power_mgmt(1, info);
1657 break;
1658 case PBOOK_WAKE:
1659 /* Wakeup chip */
1660 result = aty_power_mgmt(0, info);
1661
1662 /* Restore fb content */
1663 if (info->save_framebuffer) {
1664 memcpy_toio((void *)info->frame_buffer,
1665 info->save_framebuffer, nb);
1666 vfree(info->save_framebuffer);
1667 info->save_framebuffer = 0;
1668 }
1669 /* Restore display */
1670 atyfb_set_par(&info->current_par, info);
1671 atyfbcon_blank(0, (struct fb_info *)info);
1672 break;
1673 }
1674 }
1675 return result;
1676 }
1677
1678 static struct pmu_sleep_notifier aty_sleep_notifier = {
1679 aty_sleep_notify, SLEEP_LEVEL_VIDEO,
1680 };
1681 #endif /* CONFIG_PMAC_PBOOK */
1682
1683 #ifdef CONFIG_PMAC_BACKLIGHT
1684
1685 /*
1686 * LCD backlight control
1687 */
1688
1689 static int backlight_conv[] = {
1690 0x00, 0x3f, 0x4c, 0x59, 0x66, 0x73, 0x80, 0x8d,
1691 0x9a, 0xa7, 0xb4, 0xc1, 0xcf, 0xdc, 0xe9, 0xff
1692 };
1693
1694 static int
1695 aty_set_backlight_enable(int on, int level, void* data)
1696 {
1697 struct fb_info_aty *info = (struct fb_info_aty *)data;
1698 unsigned int reg = aty_ld_lcd(LCD_MISC_CNTL, info);
1699
1700 reg |= (BLMOD_EN | BIASMOD_EN);
1701 if (on && level > BACKLIGHT_OFF) {
1702 reg &= ~BIAS_MOD_LEVEL_MASK;
1703 reg |= (backlight_conv[level] << BIAS_MOD_LEVEL_SHIFT);
1704 } else {
1705 reg &= ~BIAS_MOD_LEVEL_MASK;
1706 reg |= (backlight_conv[0] << BIAS_MOD_LEVEL_SHIFT);
1707 }
1708 aty_st_lcd(LCD_MISC_CNTL, reg, info);
1709
1710 return 0;
1711 }
1712
1713 static int
1714 aty_set_backlight_level(int level, void* data)
1715 {
1716 return aty_set_backlight_enable(1, level, data);
1717 }
1718
1719 static struct backlight_controller aty_backlight_controller = {
1720 aty_set_backlight_enable,
1721 aty_set_backlight_level
1722 };
1723 #endif /* CONFIG_PMAC_BACKLIGHT */
1724
1725
1726
1727 /*
1728 * Initialisation
1729 */
1730
1731 static struct fb_info_aty *fb_list = NULL;
1732
1733 static int __init aty_init(struct fb_info_aty *info, const char *name)
1734 {
1735 u32 chip_id;
1736 u32 i;
1737 int j, k;
1738 struct fb_var_screeninfo var;
1739 struct display *disp;
1740 u16 type;
1741 u8 rev;
1742 const char *chipname = NULL, *ramname = NULL, *xtal;
1743 int pll, mclk, gtb_memsize;
1744 #if defined(CONFIG_PPC)
1745 int sense;
1746 #endif
1747 u8 pll_ref_div;
1748
1749 info->aty_cmap_regs = (struct aty_cmap_regs *)(info->ati_regbase+0xc0);
1750 chip_id = aty_ld_le32(CONFIG_CHIP_ID, info);
1751 type = chip_id & CFG_CHIP_TYPE;
1752 rev = (chip_id & CFG_CHIP_REV)>>24;
1753 for (j = 0; j < (sizeof(aty_chips)/sizeof(*aty_chips)); j++)
1754 if (type == aty_chips[j].chip_type &&
1755 (rev & aty_chips[j].rev_mask) == aty_chips[j].rev_val) {
1756 chipname = aty_chips[j].name;
1757 pll = aty_chips[j].pll;
1758 mclk = aty_chips[j].mclk;
1759 info->features = aty_chips[j].features;
1760 goto found;
1761 }
1762 printk("atyfb: Unknown mach64 0x%04x rev 0x%04x\n", type, rev);
1763 return 0;
1764
1765 found:
1766 printk("atyfb: %s [0x%04x rev 0x%02x] ", chipname, type, rev);
1767 #ifdef CONFIG_FB_ATY_GX
1768 if (!M64_HAS(INTEGRATED)) {
1769 u32 stat0;
1770 u8 dac_type, dac_subtype, clk_type;
1771 stat0 = aty_ld_le32(CONFIG_STAT0, info);
1772 info->bus_type = (stat0 >> 0) & 0x07;
1773 info->ram_type = (stat0 >> 3) & 0x07;
1774 ramname = aty_gx_ram[info->ram_type];
1775 /* FIXME: clockchip/RAMDAC probing? */
1776 dac_type = (aty_ld_le32(DAC_CNTL, info) >> 16) & 0x07;
1777 #ifdef CONFIG_ATARI
1778 clk_type = CLK_ATI18818_1;
1779 dac_type = (stat0 >> 9) & 0x07;
1780 if (dac_type == 0x07)
1781 dac_subtype = DAC_ATT20C408;
1782 else
1783 dac_subtype = (aty_ld_8(SCRATCH_REG1 + 1, info) & 0xF0) | dac_type;
1784 #else
1785 dac_type = DAC_IBMRGB514;
1786 dac_subtype = DAC_IBMRGB514;
1787 clk_type = CLK_IBMRGB514;
1788 #endif
1789 switch (dac_subtype) {
1790 case DAC_IBMRGB514:
1791 info->dac_ops = &aty_dac_ibm514;
1792 break;
1793 case DAC_ATI68860_B:
1794 case DAC_ATI68860_C:
1795 info->dac_ops = &aty_dac_ati68860b;
1796 break;
1797 case DAC_ATT20C408:
1798 case DAC_ATT21C498:
1799 info->dac_ops = &aty_dac_att21c498;
1800 break;
1801 default:
1802 printk(" atyfb_set_par: DAC type not implemented yet!\n");
1803 info->dac_ops = &aty_dac_unsupported;
1804 break;
1805 }
1806 switch (clk_type) {
1807 case CLK_ATI18818_1:
1808 info->pll_ops = &aty_pll_ati18818_1;
1809 break;
1810 case CLK_STG1703:
1811 info->pll_ops = &aty_pll_stg1703;
1812 break;
1813 case CLK_CH8398:
1814 info->pll_ops = &aty_pll_ch8398;
1815 break;
1816 case CLK_ATT20C408:
1817 info->pll_ops = &aty_pll_att20c408;
1818 break;
1819 case CLK_IBMRGB514:
1820 info->pll_ops = &aty_pll_ibm514;
1821 break;
1822 default:
1823 printk(" atyfb_set_par: CLK type not implemented yet!");
1824 info->pll_ops = &aty_pll_unsupported;
1825 break;
1826 }
1827 }
1828 #endif /* CONFIG_FB_ATY_GX */
1829 #ifdef CONFIG_FB_ATY_CT
1830 if (M64_HAS(INTEGRATED)) {
1831 info->bus_type = PCI;
1832 info->ram_type = (aty_ld_le32(CONFIG_STAT0, info) & 0x07);
1833 ramname = aty_ct_ram[info->ram_type];
1834 info->dac_ops = &aty_dac_ct;
1835 info->pll_ops = &aty_pll_ct;
1836 /* for many chips, the mclk is 67 MHz for SDRAM, 63 MHz otherwise */
1837 if (mclk == 67 && info->ram_type < SDRAM)
1838 mclk = 63;
1839 }
1840 #endif /* CONFIG_FB_ATY_CT */
1841
1842 info->ref_clk_per = 1000000000000ULL/14318180;
1843 xtal = "14.31818";
1844 if (M64_HAS(GTB_DSP) && (pll_ref_div = aty_ld_pll(PLL_REF_DIV, info))) {
1845 int diff1, diff2;
1846 diff1 = 510*14/pll_ref_div-pll;
1847 diff2 = 510*29/pll_ref_div-pll;
1848 if (diff1 < 0)
1849 diff1 = -diff1;
1850 if (diff2 < 0)
1851 diff2 = -diff2;
1852 if (diff2 < diff1) {
1853 info->ref_clk_per = 1000000000000ULL/29498928;
1854 xtal = "29.498928";
1855 }
1856 }
1857
1858 i = aty_ld_le32(MEM_CNTL, info);
1859 gtb_memsize = M64_HAS(GTB_DSP);
1860 if (gtb_memsize)
1861 switch (i & 0xF) { /* 0xF used instead of MEM_SIZE_ALIAS */
1862 case MEM_SIZE_512K:
1863 info->total_vram = 0x80000;
1864 break;
1865 case MEM_SIZE_1M:
1866 info->total_vram = 0x100000;
1867 break;
1868 case MEM_SIZE_2M_GTB:
1869 info->total_vram = 0x200000;
1870 break;
1871 case MEM_SIZE_4M_GTB:
1872 info->total_vram = 0x400000;
1873 break;
1874 case MEM_SIZE_6M_GTB:
1875 info->total_vram = 0x600000;
1876 break;
1877 case MEM_SIZE_8M_GTB:
1878 info->total_vram = 0x800000;
1879 break;
1880 default:
1881 info->total_vram = 0x80000;
1882 }
1883 else
1884 switch (i & MEM_SIZE_ALIAS) {
1885 case MEM_SIZE_512K:
1886 info->total_vram = 0x80000;
1887 break;
1888 case MEM_SIZE_1M:
1889 info->total_vram = 0x100000;
1890 break;
1891 case MEM_SIZE_2M:
1892 info->total_vram = 0x200000;
1893 break;
1894 case MEM_SIZE_4M:
1895 info->total_vram = 0x400000;
1896 break;
1897 case MEM_SIZE_6M:
1898 info->total_vram = 0x600000;
1899 break;
1900 case MEM_SIZE_8M:
1901 info->total_vram = 0x800000;
1902 break;
1903 default:
1904 info->total_vram = 0x80000;
1905 }
1906
1907 if (M64_HAS(MAGIC_VRAM_SIZE)) {
1908 if (aty_ld_le32(CONFIG_STAT1, info) & 0x40000000)
1909 info->total_vram += 0x400000;
1910 }
1911
1912 if (default_vram) {
1913 info->total_vram = default_vram*1024;
1914 i = i & ~(gtb_memsize ? 0xF : MEM_SIZE_ALIAS);
1915 if (info->total_vram <= 0x80000)
1916 i |= MEM_SIZE_512K;
1917 else if (info->total_vram <= 0x100000)
1918 i |= MEM_SIZE_1M;
1919 else if (info->total_vram <= 0x200000)
1920 i |= gtb_memsize ? MEM_SIZE_2M_GTB : MEM_SIZE_2M;
1921 else if (info->total_vram <= 0x400000)
1922 i |= gtb_memsize ? MEM_SIZE_4M_GTB : MEM_SIZE_4M;
1923 else if (info->total_vram <= 0x600000)
1924 i |= gtb_memsize ? MEM_SIZE_6M_GTB : MEM_SIZE_6M;
1925 else
1926 i |= gtb_memsize ? MEM_SIZE_8M_GTB : MEM_SIZE_8M;
1927 aty_st_le32(MEM_CNTL, i, info);
1928 }
1929 if (default_pll)
1930 pll = default_pll;
1931 if (default_mclk)
1932 mclk = default_mclk;
1933
1934 printk("%d%c %s, %s MHz XTAL, %d MHz PLL, %d Mhz MCLK\n",
1935 info->total_vram == 0x80000 ? 512 : (info->total_vram >> 20),
1936 info->total_vram == 0x80000 ? 'K' : 'M', ramname, xtal, pll, mclk);
1937
1938 if (mclk < 44)
1939 info->mem_refresh_rate = 0; /* 000 = 10 Mhz - 43 Mhz */
1940 else if (mclk < 50)
1941 info->mem_refresh_rate = 1; /* 001 = 44 Mhz - 49 Mhz */
1942 else if (mclk < 55)
1943 info->mem_refresh_rate = 2; /* 010 = 50 Mhz - 54 Mhz */
1944 else if (mclk < 66)
1945 info->mem_refresh_rate = 3; /* 011 = 55 Mhz - 65 Mhz */
1946 else if (mclk < 75)
1947 info->mem_refresh_rate = 4; /* 100 = 66 Mhz - 74 Mhz */
1948 else if (mclk < 80)
1949 info->mem_refresh_rate = 5; /* 101 = 75 Mhz - 79 Mhz */
1950 else if (mclk < 100)
1951 info->mem_refresh_rate = 6; /* 110 = 80 Mhz - 100 Mhz */
1952 else
1953 info->mem_refresh_rate = 7; /* 111 = 100 Mhz and above */
1954 info->pll_per = 1000000/pll;
1955 info->mclk_per = 1000000/mclk;
1956
1957 #ifdef DEBUG
1958 if (M64_HAS(INTEGRATED)) {
1959 int i;
1960 printk("BUS_CNTL DAC_CNTL MEM_CNTL EXT_MEM_CNTL CRTC_GEN_CNTL "
1961 "DSP_CONFIG DSP_ON_OFF\n"
1962 "%08x %08x %08x %08x %08x %08x %08x\n"
1963 "PLL",
1964 aty_ld_le32(BUS_CNTL, info), aty_ld_le32(DAC_CNTL, info),
1965 aty_ld_le32(MEM_CNTL, info), aty_ld_le32(EXT_MEM_CNTL, info),
1966 aty_ld_le32(CRTC_GEN_CNTL, info), aty_ld_le32(DSP_CONFIG, info),
1967 aty_ld_le32(DSP_ON_OFF, info));
1968 for (i = 0; i < 16; i++)
1969 printk(" %02x", aty_ld_pll(i, info));
1970 printk("\n");
1971 }
1972 #endif
1973
1974 /*
1975 * Last page of 8 MB (4 MB on ISA) aperture is MMIO
1976 * FIXME: we should use the auxiliary aperture instead so we can access
1977 * the full 8 MB of video RAM on 8 MB boards
1978 */
1979 if (info->total_vram == 0x800000 ||
1980 (info->bus_type == ISA && info->total_vram == 0x400000))
1981 info->total_vram -= GUI_RESERVE;
1982
1983 /* Clear the video memory */
1984 fb_memset((void *)info->frame_buffer, 0, info->total_vram);
1985
1986 disp = &info->disp;
1987
1988 strcpy(info->fb_info.modename, atyfb_name);
1989 info->fb_info.node = -1;
1990 info->fb_info.fbops = &atyfb_ops;
1991 info->fb_info.disp = disp;
1992 strcpy(info->fb_info.fontname, fontname);
1993 info->fb_info.changevar = NULL;
1994 info->fb_info.switch_con = &atyfbcon_switch;
1995 info->fb_info.updatevar = &atyfbcon_updatevar;
1996 info->fb_info.blank = &atyfbcon_blank;
1997 info->fb_info.flags = FBINFO_FLAG_DEFAULT;
1998
1999 #ifdef CONFIG_PMAC_BACKLIGHT
2000 if (M64_HAS(G3_PB_1_1) && machine_is_compatible("PowerBook1,1")) {
2001 /* these bits let the 101 powerbook wake up from sleep -- paulus */
2002 aty_st_lcd(POWER_MANAGEMENT, aty_ld_lcd(POWER_MANAGEMENT, info)
2003 | (USE_F32KHZ | TRISTATE_MEM_EN), info);
2004 }
2005 if (M64_HAS(MOBIL_BUS))
2006 register_backlight_controller(&aty_backlight_controller, info, "ati");
2007 #endif /* CONFIG_PMAC_BACKLIGHT */
2008
2009 #ifdef MODULE
2010 var = default_var;
2011 #else /* !MODULE */
2012 memset(&var, 0, sizeof(var));
2013 #ifdef CONFIG_PPC
2014 if (_machine == _MACH_Pmac) {
2015 /*
2016 * FIXME: The NVRAM stuff should be put in a Mac-specific file, as it
2017 * applies to all Mac video cards
2018 */
2019 if (mode_option) {
2020 if (!mac_find_mode(&var, &info->fb_info, mode_option, 8))
2021 var = default_var;
2022 } else {
2023 #ifdef CONFIG_NVRAM
2024 if (default_vmode == VMODE_NVRAM) {
2025 default_vmode = nvram_read_byte(NV_VMODE);
2026 if (default_vmode <= 0 || default_vmode > VMODE_MAX)
2027 default_vmode = VMODE_CHOOSE;
2028 }
2029 #endif
2030 if (default_vmode == VMODE_CHOOSE) {
2031 if (M64_HAS(G3_PB_1024x768))
2032 /* G3 PowerBook with 1024x768 LCD */
2033 default_vmode = VMODE_1024_768_60;
2034 else if (machine_is_compatible("iMac"))
2035 default_vmode = VMODE_1024_768_75;
2036 else if (machine_is_compatible("PowerBook2,1"))
2037 /* iBook with 800x600 LCD */
2038 default_vmode = VMODE_800_600_60;
2039 else
2040 default_vmode = VMODE_640_480_67;
2041 sense = read_aty_sense(info);
2042 printk(KERN_INFO "atyfb: monitor sense=%x, mode %d\n",
2043 sense, mac_map_monitor_sense(sense));
2044 }
2045 if (default_vmode <= 0 || default_vmode > VMODE_MAX)
2046 default_vmode = VMODE_640_480_60;
2047 #ifdef CONFIG_NVRAM
2048 if (default_cmode == CMODE_NVRAM)
2049 default_cmode = nvram_read_byte(NV_CMODE);
2050 #endif
2051 if (default_cmode < CMODE_8 || default_cmode > CMODE_32)
2052 default_cmode = CMODE_8;
2053 if (mac_vmode_to_var(default_vmode, default_cmode, &var))
2054 var = default_var;
2055 }
2056 }
2057 else if (!fb_find_mode(&var, &info->fb_info, mode_option, NULL, 0, NULL, 8))
2058 var = default_var;
2059 #else /* !CONFIG_PPC */
2060 #ifdef __sparc__
2061 if (mode_option) {
2062 if (!fb_find_mode(&var, &info->fb_info, mode_option, NULL, 0, NULL, 8))
2063 var = default_var;
2064 } else
2065 var = default_var;
2066 #else
2067 if (!fb_find_mode(&var, &info->fb_info, mode_option, NULL, 0, NULL, 8))
2068 var = default_var;
2069 #endif /* !__sparc__ */
2070 #endif /* !CONFIG_PPC */
2071 #endif /* !MODULE */
2072 if (noaccel)
2073 var.accel_flags &= ~FB_ACCELF_TEXT;
2074 else
2075 var.accel_flags |= FB_ACCELF_TEXT;
2076
2077 if (var.yres == var.yres_virtual) {
2078 u32 vram = (info->total_vram - (PAGE_SIZE << 2));
2079 var.yres_virtual = ((vram * 8) / var.bits_per_pixel) / var.xres_virtual;
2080 if (var.yres_virtual < var.yres)
2081 var.yres_virtual = var.yres;
2082 }
2083
2084 if (atyfb_decode_var(&var, &info->default_par, info)) {
2085 printk("atyfb: can't set default video mode\n");
2086 return 0;
2087 }
2088
2089 #ifdef __sparc__
2090 atyfb_save_palette(&info->fb_info, 0);
2091 #endif
2092 for (j = 0; j < 16; j++) {
2093 k = color_table[j];
2094 info->palette[j].red = default_red[k];
2095 info->palette[j].green = default_grn[k];
2096 info->palette[j].blue = default_blu[k];
2097 }
2098
2099 #ifdef CONFIG_FB_ATY_CT
2100 if (curblink && M64_HAS(INTEGRATED)) {
2101 info->cursor = aty_init_cursor(info);
2102 if (info->cursor) {
2103 info->dispsw.cursor = atyfb_cursor;
2104 info->dispsw.set_font = atyfb_set_font;
2105 }
2106 }
2107 #endif /* CONFIG_FB_ATY_CT */
2108
2109 atyfb_set_var(&var, -1, &info->fb_info);
2110
2111 if (register_framebuffer(&info->fb_info) < 0)
2112 return 0;
2113
2114 info->next = fb_list;
2115 fb_list = info;
2116
2117 printk("fb%d: %s frame buffer device on %s\n",
2118 GET_FB_IDX(info->fb_info.node), atyfb_name, name);
2119 return 1;
2120 }
2121
2122 int __init atyfb_init(void)
2123 {
2124 #if defined(CONFIG_PCI)
2125 struct pci_dev *pdev = NULL;
2126 struct fb_info_aty *info;
2127 unsigned long addr, res_start, res_size;
2128 int i;
2129 #ifdef __sparc__
2130 extern void (*prom_palette) (int);
2131 extern int con_is_present(void);
2132 struct pcidev_cookie *pcp;
2133 char prop[128];
2134 int node, len, j;
2135 u32 mem, chip_id;
2136
2137 /* Do not attach when we have a serial console. */
2138 if (!con_is_present())
2139 return -ENXIO;
2140 #else
2141 u16 tmp;
2142 #endif
2143
2144 while ((pdev = pci_find_device(PCI_VENDOR_ID_ATI, PCI_ANY_ID, pdev))) {
2145 if ((pdev->class >> 16) == PCI_BASE_CLASS_DISPLAY) {
2146 struct resource *rp;
2147
2148 for (i = sizeof(aty_chips)/sizeof(*aty_chips)-1; i >= 0; i--)
2149 if (pdev->device == aty_chips[i].pci_id)
2150 break;
2151 if (i < 0)
2152 continue;
2153
2154 info = kmalloc(sizeof(struct fb_info_aty), GFP_ATOMIC);
2155 if (!info) {
2156 printk("atyfb_init: can't alloc fb_info_aty\n");
2157 return -ENXIO;
2158 }
2159 memset(info, 0, sizeof(struct fb_info_aty));
2160
2161 rp = &pdev->resource[0];
2162 if (rp->flags & IORESOURCE_IO)
2163 rp = &pdev->resource[1];
2164 addr = rp->start;
2165 if (!addr)
2166 continue;
2167
2168 res_start = rp->start;
2169 res_size = rp->end-rp->start+1;
2170 if (!request_mem_region(res_start, res_size, "atyfb"))
2171 continue;
2172
2173 #ifdef __sparc__
2174 /*
2175 * Map memory-mapped registers.
2176 */
2177 info->ati_regbase = addr + 0x7ffc00UL;
2178 info->ati_regbase_phys = addr + 0x7ffc00UL;
2179
2180 /*
2181 * Map in big-endian aperture.
2182 */
2183 info->frame_buffer = (unsigned long) addr + 0x800000UL;
2184 info->frame_buffer_phys = addr + 0x800000UL;
2185
2186 /*
2187 * Figure mmap addresses from PCI config space.
2188 * Split Framebuffer in big- and little-endian halfs.
2189 */
2190 for (i = 0; i < 6 && pdev->resource[i].start; i++)
2191 /* nothing */;
2192 j = i + 4;
2193
2194 info->mmap_map = kmalloc(j * sizeof(*info->mmap_map), GFP_ATOMIC);
2195 if (!info->mmap_map) {
2196 printk("atyfb_init: can't alloc mmap_map\n");
2197 kfree(info);
2198 release_mem_region(res_start, res_size);
2199 return -ENXIO;
2200 }
2201 memset(info->mmap_map, 0, j * sizeof(*info->mmap_map));
2202
2203 for (i = 0, j = 2; i < 6 && pdev->resource[i].start; i++) {
2204 struct resource *rp = &pdev->resource[i];
2205 int io, breg = PCI_BASE_ADDRESS_0 + (i << 2);
2206 unsigned long base;
2207 u32 size, pbase;
2208
2209 base = rp->start;
2210
2211 io = (rp->flags & IORESOURCE_IO);
2212
2213 size = rp->end - base + 1;
2214
2215 pci_read_config_dword(pdev, breg, &pbase);
2216
2217 if (io)
2218 size &= ~1;
2219
2220 /*
2221 * Map the framebuffer a second time, this time without
2222 * the braindead _PAGE_IE setting. This is used by the
2223 * fixed Xserver, but we need to maintain the old mapping
2224 * to stay compatible with older ones...
2225 */
2226 if (base == addr) {
2227 info->mmap_map[j].voff = (pbase + 0x10000000) & PAGE_MASK;
2228 info->mmap_map[j].poff = base & PAGE_MASK;
2229 info->mmap_map[j].size = (size + ~PAGE_MASK) & PAGE_MASK;
2230 info->mmap_map[j].prot_mask = _PAGE_CACHE;
2231 info->mmap_map[j].prot_flag = _PAGE_E;
2232 j++;
2233 }
2234
2235 /*
2236 * Here comes the old framebuffer mapping with _PAGE_IE
2237 * set for the big endian half of the framebuffer...
2238 */
2239 if (base == addr) {
2240 info->mmap_map[j].voff = (pbase + 0x800000) & PAGE_MASK;
2241 info->mmap_map[j].poff = (base+0x800000) & PAGE_MASK;
2242 info->mmap_map[j].size = 0x800000;
2243 info->mmap_map[j].prot_mask = _PAGE_CACHE;
2244 info->mmap_map[j].prot_flag = _PAGE_E|_PAGE_IE;
2245 size -= 0x800000;
2246 j++;
2247 }
2248
2249 info->mmap_map[j].voff = pbase & PAGE_MASK;
2250 info->mmap_map[j].poff = base & PAGE_MASK;
2251 info->mmap_map[j].size = (size + ~PAGE_MASK) & PAGE_MASK;
2252 info->mmap_map[j].prot_mask = _PAGE_CACHE;
2253 info->mmap_map[j].prot_flag = _PAGE_E;
2254 j++;
2255 }
2256
2257 if (pdev->device != XL_CHIP_ID) {
2258 /*
2259 * Fix PROMs idea of MEM_CNTL settings...
2260 */
2261 mem = aty_ld_le32(MEM_CNTL, info);
2262 chip_id = aty_ld_le32(CONFIG_CHIP_ID, info);
2263 if (((chip_id & CFG_CHIP_TYPE) == VT_CHIP_ID) &&
2264 !((chip_id >> 24) & 1)) {
2265 switch (mem & 0x0f) {
2266 case 3:
2267 mem = (mem & ~(0x0f)) | 2;
2268 break;
2269 case 7:
2270 mem = (mem & ~(0x0f)) | 3;
2271 break;
2272 case 9:
2273 mem = (mem & ~(0x0f)) | 4;
2274 break;
2275 case 11:
2276 mem = (mem & ~(0x0f)) | 5;
2277 break;
2278 default:
2279 break;
2280 }
2281 if ((aty_ld_le32(CONFIG_STAT0, info) & 7) >= SDRAM)
2282 mem &= ~(0x00700000);
2283 }
2284 mem &= ~(0xcf80e000); /* Turn off all undocumented bits. */
2285 aty_st_le32(MEM_CNTL, mem, info);
2286 }
2287
2288 /*
2289 * If this is the console device, we will set default video
2290 * settings to what the PROM left us with.
2291 */
2292 node = prom_getchild(prom_root_node);
2293 node = prom_searchsiblings(node, "aliases");
2294 if (node) {
2295 len = prom_getproperty(node, "screen", prop, sizeof(prop));
2296 if (len > 0) {
2297 prop[len] = '\0';
2298 node = prom_finddevice(prop);
2299 } else {
2300 node = 0;
2301 }
2302 }
2303
2304 pcp = pdev->sysdata;
2305 if (node == pcp->prom_node) {
2306
2307 struct fb_var_screeninfo *var = &default_var;
2308 unsigned int N, P, Q, M, T, R;
2309 u32 v_total, h_total;
2310 struct crtc crtc;
2311 u8 pll_regs[16];
2312 u8 clock_cntl;
2313
2314 crtc.vxres = prom_getintdefault(node, "width", 1024);
2315 crtc.vyres = prom_getintdefault(node, "height", 768);
2316 crtc.bpp = prom_getintdefault(node, "depth", 8);
2317 crtc.xoffset = crtc.yoffset = 0;
2318 crtc.h_tot_disp = aty_ld_le32(CRTC_H_TOTAL_DISP, info);
2319 crtc.h_sync_strt_wid = aty_ld_le32(CRTC_H_SYNC_STRT_WID, info);
2320 crtc.v_tot_disp = aty_ld_le32(CRTC_V_TOTAL_DISP, info);
2321 crtc.v_sync_strt_wid = aty_ld_le32(CRTC_V_SYNC_STRT_WID, info);
2322 crtc.gen_cntl = aty_ld_le32(CRTC_GEN_CNTL, info);
2323 aty_crtc_to_var(&crtc, var);
2324
2325 h_total = var->xres + var->right_margin +
2326 var->hsync_len + var->left_margin;
2327 v_total = var->yres + var->lower_margin +
2328 var->vsync_len + var->upper_margin;
2329
2330 /*
2331 * Read the PLL to figure actual Refresh Rate.
2332 */
2333 clock_cntl = aty_ld_8(CLOCK_CNTL, info);
2334 /* printk("atyfb: CLOCK_CNTL: %02x\n", clock_cntl); */
2335 for (i = 0; i < 16; i++)
2336 pll_regs[i] = aty_ld_pll(i, info);
2337
2338 /*
2339 * PLL Reference Divider M:
2340 */
2341 M = pll_regs[2];
2342
2343 /*
2344 * PLL Feedback Divider N (Dependant on CLOCK_CNTL):
2345 */
2346 N = pll_regs[7 + (clock_cntl & 3)];
2347
2348 /*
2349 * PLL Post Divider P (Dependant on CLOCK_CNTL):
2350 */
2351 P = 1 << (pll_regs[6] >> ((clock_cntl & 3) << 1));
2352
2353 /*
2354 * PLL Divider Q:
2355 */
2356 Q = N / P;
2357
2358 /*
2359 * Target Frequency:
2360 *
2361 * T * M
2362 * Q = -------
2363 * 2 * R
2364 *
2365 * where R is XTALIN (= 14318 or 29498 kHz).
2366 */
2367 if (pdev->device == XL_CHIP_ID)
2368 R = 29498;
2369 else
2370 R = 14318;
2371
2372 T = 2 * Q * R / M;
2373
2374 default_var.pixclock = 1000000000 / T;
2375 }
2376 #else /* __sparc__ */
2377
2378 info->ati_regbase_phys = 0x7ff000 + addr;
2379 info->ati_regbase = (unsigned long)
2380 ioremap(info->ati_regbase_phys, 0x1000);
2381
2382 if(!info->ati_regbase) {
2383 kfree(info);
2384 release_mem_region(res_start, res_size);
2385 return -ENOMEM;
2386 }
2387
2388 info->ati_regbase_phys += 0xc00;
2389 info->ati_regbase += 0xc00;
2390
2391 /*
2392 * Enable memory-space accesses using config-space
2393 * command register.
2394 */
2395 pci_read_config_word(pdev, PCI_COMMAND, &tmp);
2396 if (!(tmp & PCI_COMMAND_MEMORY)) {
2397 tmp |= PCI_COMMAND_MEMORY;
2398 pci_write_config_word(pdev, PCI_COMMAND, tmp);
2399 }
2400
2401 #ifdef __BIG_ENDIAN
2402 /* Use the big-endian aperture */
2403 addr += 0x800000;
2404 #endif
2405
2406 /* Map in frame buffer */
2407 info->frame_buffer_phys = addr;
2408 info->frame_buffer = (unsigned long)ioremap(addr, 0x800000);
2409
2410 if(!info->frame_buffer) {
2411 kfree(info);
2412 release_mem_region(res_start, res_size);
2413 return -ENXIO;
2414 }
2415
2416 #endif /* __sparc__ */
2417
2418 if (!aty_init(info, "PCI")) {
2419 if (info->mmap_map)
2420 kfree(info->mmap_map);
2421 kfree(info);
2422 release_mem_region(res_start, res_size);
2423 return -ENXIO;
2424 }
2425
2426 #ifdef __sparc__
2427 if (!prom_palette)
2428 prom_palette = atyfb_palette;
2429
2430 /*
2431 * Add /dev/fb mmap values.
2432 */
2433 info->mmap_map[0].voff = 0x8000000000000000UL;
2434 info->mmap_map[0].poff = info->frame_buffer & PAGE_MASK;
2435 info->mmap_map[0].size = info->total_vram;
2436 info->mmap_map[0].prot_mask = _PAGE_CACHE;
2437 info->mmap_map[0].prot_flag = _PAGE_E;
2438 info->mmap_map[1].voff = info->mmap_map[0].voff + info->total_vram;
2439 info->mmap_map[1].poff = info->ati_regbase & PAGE_MASK;
2440 info->mmap_map[1].size = PAGE_SIZE;
2441 info->mmap_map[1].prot_mask = _PAGE_CACHE;
2442 info->mmap_map[1].prot_flag = _PAGE_E;
2443 #endif /* __sparc__ */
2444
2445 #ifdef CONFIG_PMAC_PBOOK
2446 if (first_display == NULL)
2447 pmu_register_sleep_notifier(&aty_sleep_notifier);
2448 info->next = first_display;
2449 first_display = info;
2450 #endif
2451
2452 #ifdef CONFIG_FB_COMPAT_XPMAC
2453 if (!console_fb_info)
2454 console_fb_info = &info->fb_info;
2455 #endif /* CONFIG_FB_COMPAT_XPMAC */
2456 }
2457 }
2458
2459 #elif defined(CONFIG_ATARI)
2460 u32 clock_r;
2461 int m64_num;
2462 struct fb_info_aty *info;
2463
2464 for (m64_num = 0; m64_num < mach64_count; m64_num++) {
2465 if (!phys_vmembase[m64_num] || !phys_size[m64_num] ||
2466 !phys_guiregbase[m64_num]) {
2467 printk(" phys_*[%d] parameters not set => returning early. \n",
2468 m64_num);
2469 continue;
2470 }
2471
2472 info = kmalloc(sizeof(struct fb_info_aty), GFP_ATOMIC);
2473 if (!info) {
2474 printk("atyfb_init: can't alloc fb_info_aty\n");
2475 return -ENOMEM;
2476 }
2477 memset(info, 0, sizeof(struct fb_info_aty));
2478
2479 /*
2480 * Map the video memory (physical address given) to somewhere in the
2481 * kernel address space.
2482 */
2483 info->frame_buffer = ioremap(phys_vmembase[m64_num], phys_size[m64_num]);
2484 info->frame_buffer_phys = info->frame_buffer; /* Fake! */
2485 info->ati_regbase = ioremap(phys_guiregbase[m64_num], 0x10000)+0xFC00ul;
2486 info->ati_regbase_phys = info->ati_regbase; /* Fake! */
2487
2488 aty_st_le32(CLOCK_CNTL, 0x12345678, info);
2489 clock_r = aty_ld_le32(CLOCK_CNTL, info);
2490
2491 switch (clock_r & 0x003F) {
2492 case 0x12:
2493 info->clk_wr_offset = 3; /* */
2494 break;
2495 case 0x34:
2496 info->clk_wr_offset = 2; /* Medusa ST-IO ISA Adapter etc. */
2497 break;
2498 case 0x16:
2499 info->clk_wr_offset = 1; /* */
2500 break;
2501 case 0x38:
2502 info->clk_wr_offset = 0; /* Panther 1 ISA Adapter (Gerald) */
2503 break;
2504 }
2505
2506 if (!aty_init(info, "ISA bus")) {
2507 kfree(info);
2508 /* This is insufficient! kernel_map has added two large chunks!! */
2509 return -ENXIO;
2510 }
2511 }
2512 #endif /* CONFIG_ATARI */
2513 return 0;
2514 }
2515
2516 #ifndef MODULE
2517 int __init atyfb_setup(char *options)
2518 {
2519 char *this_opt;
2520
2521 if (!options || !*options)
2522 return 0;
2523
2524 for (this_opt = strtok(options, ","); this_opt;
2525 this_opt = strtok(NULL, ",")) {
2526 if (!strncmp(this_opt, "font:", 5)) {
2527 char *p;
2528 int i;
2529
2530 p = this_opt + 5;
2531 for (i = 0; i < sizeof(fontname) - 1; i++)
2532 if (!*p || *p == ' ' || *p == ',')
2533 break;
2534 memcpy(fontname, this_opt + 5, i);
2535 fontname[i] = 0;
2536 } else if (!strncmp(this_opt, "noblink", 7)) {
2537 curblink = 0;
2538 } else if (!strncmp(this_opt, "noaccel", 7)) {
2539 noaccel = 1;
2540 } else if (!strncmp(this_opt, "vram:", 5))
2541 default_vram = simple_strtoul(this_opt+5, NULL, 0);
2542 else if (!strncmp(this_opt, "pll:", 4))
2543 default_pll = simple_strtoul(this_opt+4, NULL, 0);
2544 else if (!strncmp(this_opt, "mclk:", 5))
2545 default_mclk = simple_strtoul(this_opt+5, NULL, 0);
2546 #ifdef CONFIG_PPC
2547 else if (!strncmp(this_opt, "vmode:", 6)) {
2548 unsigned int vmode = simple_strtoul(this_opt+6, NULL, 0);
2549 if (vmode > 0 && vmode <= VMODE_MAX)
2550 default_vmode = vmode;
2551 } else if (!strncmp(this_opt, "cmode:", 6)) {
2552 unsigned int cmode = simple_strtoul(this_opt+6, NULL, 0);
2553 switch (cmode) {
2554 case 0:
2555 case 8:
2556 default_cmode = CMODE_8;
2557 break;
2558 case 15:
2559 case 16:
2560 default_cmode = CMODE_16;
2561 break;
2562 case 24:
2563 case 32:
2564 default_cmode = CMODE_32;
2565 break;
2566 }
2567 }
2568 #endif
2569 #ifdef CONFIG_ATARI
2570 /*
2571 * Why do we need this silly Mach64 argument?
2572 * We are already here because of mach64= so its redundant.
2573 */
2574 else if (MACH_IS_ATARI && (!strncmp(this_opt, "Mach64:", 7))) {
2575 static unsigned char m64_num;
2576 static char mach64_str[80];
2577 strncpy(mach64_str, this_opt+7, 80);
2578 if (!store_video_par(mach64_str, m64_num)) {
2579 m64_num++;
2580 mach64_count = m64_num;
2581 }
2582 }
2583 #endif
2584 else
2585 mode_option = this_opt;
2586 }
2587 return 0;
2588 }
2589 #endif /* !MODULE */
2590
2591 #ifdef CONFIG_ATARI
2592 static int __init store_video_par(char *video_str, unsigned char m64_num)
2593 {
2594 char *p;
2595 unsigned long vmembase, size, guiregbase;
2596
2597 printk("store_video_par() '%s' \n", video_str);
2598
2599 if (!(p = strtoke(video_str, ";")) || !*p)
2600 goto mach64_invalid;
2601 vmembase = simple_strtoul(p, NULL, 0);
2602 if (!(p = strtoke(NULL, ";")) || !*p)
2603 goto mach64_invalid;
2604 size = simple_strtoul(p, NULL, 0);
2605 if (!(p = strtoke(NULL, ";")) || !*p)
2606 goto mach64_invalid;
2607 guiregbase = simple_strtoul(p, NULL, 0);
2608
2609 phys_vmembase[m64_num] = vmembase;
2610 phys_size[m64_num] = size;
2611 phys_guiregbase[m64_num] = guiregbase;
2612 printk(" stored them all: $%08lX $%08lX $%08lX \n", vmembase, size,
2613 guiregbase);
2614 return 0;
2615
2616 mach64_invalid:
2617 phys_vmembase[m64_num] = 0;
2618 return -1;
2619 }
2620
2621 static char __init *strtoke(char *s, const char *ct)
2622 {
2623 static char *ssave = NULL;
2624 char *sbegin, *send;
2625
2626 sbegin = s ? s : ssave;
2627 if (!sbegin)
2628 return NULL;
2629 if (*sbegin == '\0') {
2630 ssave = NULL;
2631 return NULL;
2632 }
2633 send = strpbrk(sbegin, ct);
2634 if (send && *send != '\0')
2635 *send++ = '\0';
2636 ssave = send;
2637 return sbegin;
2638 }
2639 #endif /* CONFIG_ATARI */
2640
2641 static int atyfbcon_switch(int con, struct fb_info *fb)
2642 {
2643 struct fb_info_aty *info = (struct fb_info_aty *)fb;
2644 struct atyfb_par par;
2645
2646 /* Do we have to save the colormap? */
2647 if (fb_display[currcon].cmap.len)
2648 fb_get_cmap(&fb_display[currcon].cmap, 1, atyfb_getcolreg, fb);
2649
2650 #ifdef CONFIG_FB_ATY_CT
2651 /* Erase HW Cursor */
2652 if (info->cursor)
2653 atyfb_cursor(&fb_display[currcon], CM_ERASE,
2654 info->cursor->pos.x, info->cursor->pos.y);
2655 #endif /* CONFIG_FB_ATY_CT */
2656
2657 currcon = con;
2658
2659 atyfb_decode_var(&fb_display[con].var, &par, info);
2660 atyfb_set_par(&par, info);
2661 atyfb_set_dispsw(&fb_display[con], info, par.crtc.bpp,
2662 par.accel_flags & FB_ACCELF_TEXT);
2663
2664 /* Install new colormap */
2665 do_install_cmap(con, fb);
2666
2667 #ifdef CONFIG_FB_ATY_CT
2668 /* Install hw cursor */
2669 if (info->cursor) {
2670 aty_set_cursor_color(info);
2671 aty_set_cursor_shape(info);
2672 }
2673 #endif /* CONFIG_FB_ATY_CT */
2674 return 1;
2675 }
2676
2677 /*
2678 * Blank the display.
2679 */
2680
2681 static void atyfbcon_blank(int blank, struct fb_info *fb)
2682 {
2683 struct fb_info_aty *info = (struct fb_info_aty *)fb;
2684 u8 gen_cntl;
2685
2686 #ifdef CONFIG_PMAC_BACKLIGHT
2687 if ((_machine == _MACH_Pmac) && blank)
2688 set_backlight_enable(0);
2689 #endif /* CONFIG_PMAC_BACKLIGHT */
2690
2691 gen_cntl = aty_ld_8(CRTC_GEN_CNTL, info);
2692 if (blank > 0)
2693 switch (blank-1) {
2694 case VESA_NO_BLANKING:
2695 gen_cntl |= 0x40;
2696 break;
2697 case VESA_VSYNC_SUSPEND:
2698 gen_cntl |= 0x8;
2699 break;
2700 case VESA_HSYNC_SUSPEND:
2701 gen_cntl |= 0x4;
2702 break;
2703 case VESA_POWERDOWN:
2704 gen_cntl |= 0x4c;
2705 break;
2706 }
2707 else
2708 gen_cntl &= ~(0x4c);
2709 aty_st_8(CRTC_GEN_CNTL, gen_cntl, info);
2710
2711 #ifdef CONFIG_PMAC_BACKLIGHT
2712 if ((_machine == _MACH_Pmac) && !blank)
2713 set_backlight_enable(1);
2714 #endif /* CONFIG_PMAC_BACKLIGHT */
2715 }
2716
2717
2718 /*
2719 * Read a single color register and split it into
2720 * colors/transparent. Return != 0 for invalid regno.
2721 */
2722
2723 static int atyfb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
2724 u_int *transp, struct fb_info *fb)
2725 {
2726 struct fb_info_aty *info = (struct fb_info_aty *)fb;
2727
2728 if (regno > 255)
2729 return 1;
2730 *red = (info->palette[regno].red<<8) | info->palette[regno].red;
2731 *green = (info->palette[regno].green<<8) | info->palette[regno].green;
2732 *blue = (info->palette[regno].blue<<8) | info->palette[regno].blue;
2733 *transp = 0;
2734 return 0;
2735 }
2736
2737
2738 /*
2739 * Set a single color register. The values supplied are already
2740 * rounded down to the hardware's capabilities (according to the
2741 * entries in the var structure). Return != 0 for invalid regno.
2742 */
2743
2744 static int atyfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
2745 u_int transp, struct fb_info *fb)
2746 {
2747 struct fb_info_aty *info = (struct fb_info_aty *)fb;
2748 int i, scale;
2749
2750 if (regno > 255)
2751 return 1;
2752 red >>= 8;
2753 green >>= 8;
2754 blue >>= 8;
2755 info->palette[regno].red = red;
2756 info->palette[regno].green = green;
2757 info->palette[regno].blue = blue;
2758 i = aty_ld_8(DAC_CNTL, info) & 0xfc;
2759 if (M64_HAS(EXTRA_BRIGHT))
2760 i |= 0x2; /*DAC_CNTL|0x2 turns off the extra brightness for gt*/
2761 aty_st_8(DAC_CNTL, i, info);
2762 aty_st_8(DAC_MASK, 0xff, info);
2763 scale = (M64_HAS(INTEGRATED) && info->current_par.crtc.bpp == 16) ? 3 : 0;
2764 writeb(regno << scale, &info->aty_cmap_regs->windex);
2765 writeb(red, &info->aty_cmap_regs->lut);
2766 writeb(green, &info->aty_cmap_regs->lut);
2767 writeb(blue, &info->aty_cmap_regs->lut);
2768 if (regno < 16)
2769 switch (info->current_par.crtc.bpp) {
2770 #ifdef FBCON_HAS_CFB16
2771 case 16:
2772 info->fbcon_cmap.cfb16[regno] = (regno << 10) | (regno << 5) |
2773 regno;
2774 break;
2775 #endif
2776 #ifdef FBCON_HAS_CFB24
2777 case 24:
2778 info->fbcon_cmap.cfb24[regno] = (regno << 16) | (regno << 8) |
2779 regno;
2780 break;
2781 #endif
2782 #ifdef FBCON_HAS_CFB32
2783 case 32:
2784 i = (regno << 8) | regno;
2785 info->fbcon_cmap.cfb32[regno] = (i << 16) | i;
2786 break;
2787 #endif
2788 }
2789 return 0;
2790 }
2791
2792
2793 static void do_install_cmap(int con, struct fb_info *info)
2794 {
2795 if (con != currcon)
2796 return;
2797 if (fb_display[con].cmap.len)
2798 fb_set_cmap(&fb_display[con].cmap, 1, atyfb_setcolreg, info);
2799 else {
2800 int size = fb_display[con].var.bits_per_pixel == 16 ? 32 : 256;
2801 fb_set_cmap(fb_default_cmap(size), 1, atyfb_setcolreg, info);
2802 }
2803 }
2804
2805
2806 /*
2807 * Update the `var' structure (called by fbcon.c)
2808 */
2809
2810 static int atyfbcon_updatevar(int con, struct fb_info *fb)
2811 {
2812 struct fb_info_aty *info = (struct fb_info_aty *)fb;
2813 struct atyfb_par *par = &info->current_par;
2814 struct display *p = &fb_display[con];
2815 struct vc_data *conp = p->conp;
2816 u32 yres, yoffset, sy, height;
2817
2818 yres = ((par->crtc.v_tot_disp >> 16) & 0x7ff) + 1;
2819 yoffset = fb_display[con].var.yoffset;
2820
2821 sy = (conp->vc_rows + p->yscroll) * fontheight(p);
2822 height = yres - conp->vc_rows * fontheight(p);
2823
2824 if (height && (yoffset + yres > sy)) {
2825 u32 xres, xoffset;
2826 u32 bgx;
2827
2828 xres = (((par->crtc.h_tot_disp >> 16) & 0xff) + 1) * 8;
2829 xoffset = fb_display[con].var.xoffset;
2830
2831
2832 bgx = attr_bgcol_ec(p, conp);
2833 bgx |= (bgx << 8);
2834 bgx |= (bgx << 16);
2835
2836 if (sy + height > par->crtc.vyres) {
2837 wait_for_fifo(1, info);
2838 aty_st_le32(SC_BOTTOM, sy + height - 1, info);
2839 }
2840 aty_rectfill(xoffset, sy, xres, height, bgx, info);
2841 }
2842
2843 #ifdef CONFIG_FB_ATY_CT
2844 if (info->cursor && (yoffset + yres <= sy))
2845 atyfb_cursor(p, CM_ERASE, info->cursor->pos.x, info->cursor->pos.y);
2846 #endif /* CONFIG_FB_ATY_CT */
2847
2848 info->current_par.crtc.yoffset = yoffset;
2849 set_off_pitch(&info->current_par, info);
2850 return 0;
2851 }
2852
2853
2854
2855 #ifdef MODULE
2856 int __init init_module(void)
2857 {
2858 atyfb_init();
2859 return fb_list ? 0 : -ENXIO;
2860 }
2861
2862 void cleanup_module(void)
2863 {
2864 while (fb_list) {
2865 struct fb_info_aty *info = fb_list;
2866 fb_list = info->next;
2867
2868 unregister_framebuffer(&info->fb_info);
2869
2870 #ifndef __sparc__
2871 if (info->ati_regbase)
2872 iounmap((void *)info->ati_regbase);
2873 if (info->frame_buffer)
2874 iounmap((void *)info->frame_buffer);
2875 #ifdef __BIG_ENDIAN
2876 if (info->cursor && info->cursor->ram)
2877 iounmap(info->cursor->ram);
2878 #endif
2879 #endif
2880
2881 if (info->cursor) {
2882 if (info->cursor->timer)
2883 kfree(info->cursor->timer);
2884 kfree(info->cursor);
2885 }
2886 #ifdef __sparc__
2887 if (info->mmap_map)
2888 kfree(info->mmap_map);
2889 #endif
2890 kfree(info);
2891 }
2892 }
2893
2894 #endif
2895