1 /* $Id: atyfb.c,v 1.147 2000/08/29 07:01:56 davem Exp $
2 * linux/drivers/video/atyfb.c -- Frame buffer device for ATI Mach64
3 *
4 * Copyright (C) 1997-1998 Geert Uytterhoeven
5 * Copyright (C) 1998 Bernd Harries
6 * Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be)
7 *
8 * This driver is partly based on the PowerMac console driver:
9 *
10 * Copyright (C) 1996 Paul Mackerras
11 *
12 * and on the PowerMac ATI/mach64 display driver:
13 *
14 * Copyright (C) 1997 Michael AK Tesch
15 *
16 * with work by Jon Howell
17 * Harry AC Eaton
18 * Anthony Tong <atong@uiuc.edu>
19 *
20 * This file is subject to the terms and conditions of the GNU General Public
21 * License. See the file COPYING in the main directory of this archive for
22 * more details.
23 *
24 * Many thanks to Nitya from ATI devrel for support and patience !
25 */
26
27 /******************************************************************************
28
29 TODO:
30
31 - cursor support on all cards and all ramdacs.
32 - cursor parameters controlable via ioctl()s.
33 - guess PLL and MCLK based on the original PLL register values initialized
34 by the BIOS or Open Firmware (if they are initialized).
35
36 (Anyone to help with this?)
37
38 ******************************************************************************/
39
40
41 #include <linux/config.h>
42 #include <linux/module.h>
43 #include <linux/kernel.h>
44 #include <linux/errno.h>
45 #include <linux/string.h>
46 #include <linux/mm.h>
47 #include <linux/tty.h>
48 #include <linux/malloc.h>
49 #include <linux/vmalloc.h>
50 #include <linux/delay.h>
51 #include <linux/interrupt.h>
52 #include <linux/fb.h>
53 #include <linux/selection.h>
54 #include <linux/console.h>
55 #include <linux/init.h>
56 #include <linux/pci.h>
57 #include <linux/kd.h>
58 #include <linux/vt_kern.h>
59
60 #ifdef CONFIG_FB_COMPAT_XPMAC
61 #include <asm/vc_ioctl.h>
62 #endif
63
64 #include <asm/io.h>
65
66 #ifdef __powerpc__
67 #include <linux/adb.h>
68 #include <asm/prom.h>
69 #include <asm/pci-bridge.h>
70 #include <video/macmodes.h>
71 #endif
72 #ifdef CONFIG_ADB_PMU
73 #include <linux/pmu.h>
74 #endif
75 #ifdef CONFIG_NVRAM
76 #include <linux/nvram.h>
77 #endif
78 #ifdef CONFIG_PMAC_BACKLIGHT
79 #include <asm/backlight.h>
80 #endif
81
82 #ifdef __sparc__
83 #include <asm/pbm.h>
84 #include <asm/fbio.h>
85 #endif
86 #include <asm/uaccess.h>
87
88 #include <video/fbcon.h>
89 #include <video/fbcon-cfb8.h>
90 #include <video/fbcon-cfb16.h>
91 #include <video/fbcon-cfb24.h>
92 #include <video/fbcon-cfb32.h>
93
94 #include "aty.h"
95
96
97 /*
98 * Debug flags.
99 */
100 #undef DEBUG
101
102 /* Definitions for the ICS 2595 == ATI 18818_1 Clockchip */
103
104 #define REF_FREQ_2595 1432 /* 14.33 MHz (exact 14.31818) */
105 #define REF_DIV_2595 46 /* really 43 on ICS 2595 !!! */
106 /* ohne Prescaler */
107 #define MAX_FREQ_2595 15938 /* 159.38 MHz (really 170.486) */
108 #define MIN_FREQ_2595 8000 /* 80.00 MHz ( 85.565) */
109 /* mit Prescaler 2, 4, 8 */
110 #define ABS_MIN_FREQ_2595 1000 /* 10.00 MHz (really 10.697) */
111 #define N_ADJ_2595 257
112
113 #define STOP_BITS_2595 0x1800
114
115
116 #define MIN_N_408 2
117
118 #define MIN_N_1703 6
119
120 #define MIN_M 2
121 #define MAX_M 30
122 #define MIN_N 35
123 #define MAX_N 255-8
124
125
126 /* Make sure n * PAGE_SIZE is protected at end of Aperture for GUI-regs */
127 /* - must be large enough to catch all GUI-Regs */
128 /* - must be aligned to a PAGE boundary */
129 #define GUI_RESERVE (1 * PAGE_SIZE)
130
131
132 /* FIXME: remove the FAIL definition */
133 #define FAIL(x) do { printk(x "\n"); return -EINVAL; } while (0)
134
135
136 /*
137 * Elements of the Hardware specific atyfb_par structure
138 */
139
140 struct crtc {
141 u32 vxres;
142 u32 vyres;
143 u32 xoffset;
144 u32 yoffset;
145 u32 bpp;
146 u32 h_tot_disp;
147 u32 h_sync_strt_wid;
148 u32 v_tot_disp;
149 u32 v_sync_strt_wid;
150 u32 off_pitch;
151 u32 gen_cntl;
152 u32 dp_pix_width; /* acceleration */
153 u32 dp_chain_mask; /* acceleration */
154 };
155
156 struct pll_gx {
157 u8 m;
158 u8 n;
159 };
160
161 struct pll_18818
162 {
163 u32 program_bits;
164 u32 locationAddr;
165 u32 period_in_ps;
166 u32 post_divider;
167 };
168
169 struct pll_ct {
170 u8 pll_ref_div;
171 u8 pll_gen_cntl;
172 u8 mclk_fb_div;
173 u8 pll_vclk_cntl;
174 u8 vclk_post_div;
175 u8 vclk_fb_div;
176 u8 pll_ext_cntl;
177 u32 dsp_config; /* Mach64 GTB DSP */
178 u32 dsp_on_off; /* Mach64 GTB DSP */
179 u8 mclk_post_div_real;
180 u8 vclk_post_div_real;
181 };
182
183
184 /*
185 * The Hardware parameters for each card
186 */
187
188 struct atyfb_par {
189 struct crtc crtc;
190 union {
191 struct pll_gx gx;
192 struct pll_ct ct;
193 struct pll_18818 ics2595;
194 } pll;
195 u32 accel_flags;
196 };
197
198 struct aty_cmap_regs {
199 u8 windex;
200 u8 lut;
201 u8 mask;
202 u8 rindex;
203 u8 cntl;
204 };
205
206 struct pci_mmap_map {
207 unsigned long voff;
208 unsigned long poff;
209 unsigned long size;
210 unsigned long prot_flag;
211 unsigned long prot_mask;
212 };
213
214 #define DEFAULT_CURSOR_BLINK_RATE (20)
215 #define CURSOR_DRAW_DELAY (2)
216
217 struct aty_cursor {
218 int enable;
219 int on;
220 int vbl_cnt;
221 int blink_rate;
222 u32 offset;
223 struct {
224 u16 x, y;
225 } pos, hot, size;
226 u32 color[2];
227 u8 bits[8][64];
228 u8 mask[8][64];
229 u8 *ram;
230 struct timer_list *timer;
231 };
232
233 struct fb_info_aty {
234 struct fb_info fb_info;
235 struct fb_info_aty *next;
236 unsigned long ati_regbase_phys;
237 unsigned long ati_regbase;
238 unsigned long frame_buffer_phys;
239 unsigned long frame_buffer;
240 unsigned long clk_wr_offset;
241 struct pci_mmap_map *mmap_map;
242 struct aty_cursor *cursor;
243 struct aty_cmap_regs *aty_cmap_regs;
244 struct { u8 red, green, blue, pad; } palette[256];
245 struct atyfb_par default_par;
246 struct atyfb_par current_par;
247 u32 total_vram;
248 u32 ref_clk_per;
249 u32 pll_per;
250 u32 mclk_per;
251 u16 chip_type;
252 #define Gx info->chip_type
253 u8 chip_rev;
254 #define Rev info->chip_rev
255 u8 bus_type;
256 u8 ram_type;
257 u8 dac_type;
258 u8 dac_subtype;
259 u8 clk_type;
260 u8 mem_refresh_rate;
261 struct display disp;
262 struct display_switch dispsw;
263 union {
264 #ifdef FBCON_HAS_CFB16
265 u16 cfb16[16];
266 #endif
267 #ifdef FBCON_HAS_CFB24
268 u32 cfb24[16];
269 #endif
270 #ifdef FBCON_HAS_CFB32
271 u32 cfb32[16];
272 #endif
273 } fbcon_cmap;
274 u8 blitter_may_be_busy;
275 #ifdef __sparc__
276 u8 mmaped;
277 int open;
278 int vtconsole;
279 int consolecnt;
280 #endif
281 #ifdef CONFIG_PMAC_PBOOK
282 unsigned char *save_framebuffer;
283 unsigned long save_pll[64];
284 #endif
285 };
286
287 #ifdef CONFIG_PMAC_PBOOK
288 int aty_sleep_notify(struct pmu_sleep_notifier *self, int when);
289 static struct pmu_sleep_notifier aty_sleep_notifier = {
290 aty_sleep_notify, SLEEP_LEVEL_VIDEO,
291 };
292 static struct fb_info_aty* first_display = NULL;
293 #endif
294
295 #ifdef CONFIG_PMAC_BACKLIGHT
296 static int aty_set_backlight_enable(int on, int level, void* data);
297 static int aty_set_backlight_level(int level, void* data);
298
299 static struct backlight_controller aty_backlight_controller = {
300 aty_set_backlight_enable,
301 aty_set_backlight_level
302 };
303 #endif /* CONFIG_PMAC_BACKLIGHT */
304
305 /*
306 * Frame buffer device API
307 */
308
309 static int atyfb_open(struct fb_info *info, int user);
310 static int atyfb_release(struct fb_info *info, int user);
311 static int atyfb_get_fix(struct fb_fix_screeninfo *fix, int con,
312 struct fb_info *fb);
313 static int atyfb_get_var(struct fb_var_screeninfo *var, int con,
314 struct fb_info *fb);
315 static int atyfb_set_var(struct fb_var_screeninfo *var, int con,
316 struct fb_info *fb);
317 static int atyfb_pan_display(struct fb_var_screeninfo *var, int con,
318 struct fb_info *fb);
319 static int atyfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
320 struct fb_info *info);
321 static int atyfb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
322 struct fb_info *info);
323 static int atyfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
324 u_long arg, int con, struct fb_info *info);
325 #ifdef __sparc__
326 static int atyfb_mmap(struct fb_info *info, struct file *file,
327 struct vm_area_struct *vma);
328 #endif
329 static int atyfb_rasterimg(struct fb_info *info, int start);
330
331
332 /*
333 * Interface to the low level console driver
334 */
335
336 static int atyfbcon_switch(int con, struct fb_info *fb);
337 static int atyfbcon_updatevar(int con, struct fb_info *fb);
338 static void atyfbcon_blank(int blank, struct fb_info *fb);
339
340
341 /*
342 * Text console acceleration
343 */
344
345 static void fbcon_aty_bmove(struct display *p, int sy, int sx, int dy, int dx,
346 int height, int width);
347 static void fbcon_aty_clear(struct vc_data *conp, struct display *p, int sy,
348 int sx, int height, int width);
349 #ifdef FBCON_HAS_CFB8
350 static struct display_switch fbcon_aty8;
351 static void fbcon_aty8_putc(struct vc_data *conp, struct display *p, int c,
352 int yy, int xx);
353 static void fbcon_aty8_putcs(struct vc_data *conp, struct display *p,
354 const unsigned short *s, int count, int yy,
355 int xx);
356 #endif
357 #ifdef FBCON_HAS_CFB16
358 static struct display_switch fbcon_aty16;
359 static void fbcon_aty16_putc(struct vc_data *conp, struct display *p, int c,
360 int yy, int xx);
361 static void fbcon_aty16_putcs(struct vc_data *conp, struct display *p,
362 const unsigned short *s, int count, int yy,
363 int xx);
364 #endif
365 #ifdef FBCON_HAS_CFB24
366 static struct display_switch fbcon_aty24;
367 static void fbcon_aty24_putc(struct vc_data *conp, struct display *p, int c,
368 int yy, int xx);
369 static void fbcon_aty24_putcs(struct vc_data *conp, struct display *p,
370 const unsigned short *s, int count, int yy,
371 int xx);
372 #endif
373 #ifdef FBCON_HAS_CFB32
374 static struct display_switch fbcon_aty32;
375 static void fbcon_aty32_putc(struct vc_data *conp, struct display *p, int c,
376 int yy, int xx);
377 static void fbcon_aty32_putcs(struct vc_data *conp, struct display *p,
378 const unsigned short *s, int count, int yy,
379 int xx);
380 #endif
381
382
383 /*
384 * Internal routines
385 */
386
387 static int aty_init(struct fb_info_aty *info, const char *name);
388 static struct aty_cursor *aty_init_cursor(struct fb_info_aty *fb);
389 #ifdef CONFIG_ATARI
390 static int store_video_par(char *videopar, unsigned char m64_num);
391 static char *strtoke(char *s, const char *ct);
392 #endif
393
394 static void reset_engine(const struct fb_info_aty *info);
395 static void init_engine(const struct atyfb_par *par, struct fb_info_aty *info);
396
397 static void aty_st_514(int offset, u8 val, const struct fb_info_aty *info);
398 static void aty_st_pll(int offset, u8 val, const struct fb_info_aty *info);
399 static u8 aty_ld_pll(int offset, const struct fb_info_aty *info);
400 static void aty_set_crtc(const struct fb_info_aty *info,
401 const struct crtc *crtc);
402 static int aty_var_to_crtc(const struct fb_info_aty *info,
403 const struct fb_var_screeninfo *var,
404 struct crtc *crtc);
405 static void aty_set_dac_514(const struct fb_info_aty *info, u32 bpp);
406 static int aty_crtc_to_var(const struct crtc *crtc,
407 struct fb_var_screeninfo *var);
408 static void aty_set_pll_gx(const struct fb_info_aty *info,
409 const struct pll_gx *pll);
410
411 static int aty_set_dac_ATI68860_B(const struct fb_info_aty *info, u32 bpp,
412 u32 AccelMode);
413 static int aty_set_dac_ATT21C498(const struct fb_info_aty *info,
414 const struct pll_18818 *pll, u32 bpp);
415 void aty_dac_waste4(const struct fb_info_aty *info);
416
417 static int aty_var_to_pll_18818(u32 period_in_ps, struct pll_18818 *pll);
418 static u32 aty_pll_18818_to_var(const struct pll_18818 *pll);
419 static void aty_set_pll18818(const struct fb_info_aty *info,
420 const struct pll_18818 *pll);
421
422 static void aty_StrobeClock(const struct fb_info_aty *info);
423
424 static void aty_ICS2595_put1bit(u8 data, const struct fb_info_aty *info);
425
426 static int aty_var_to_pll_408(u32 period_in_ps, struct pll_18818 *pll);
427 static u32 aty_pll_408_to_var(const struct pll_18818 *pll);
428 static void aty_set_pll_408(const struct fb_info_aty *info,
429 const struct pll_18818 *pll);
430
431 static int aty_var_to_pll_1703(u32 period_in_ps, struct pll_18818 *pll);
432 static u32 aty_pll_1703_to_var(const struct pll_18818 *pll);
433 static void aty_set_pll_1703(const struct fb_info_aty *info,
434 const struct pll_18818 *pll);
435
436 static int aty_var_to_pll_8398(u32 period_in_ps, struct pll_18818 *pll);
437 static u32 aty_pll_8398_to_var(const struct pll_18818 *pll);
438 static void aty_set_pll_8398(const struct fb_info_aty *info,
439 const struct pll_18818 *pll);
440
441 static int aty_var_to_pll_514(u32 vclk_per, struct pll_gx *pll);
442 static u32 aty_pll_gx_to_var(const struct pll_gx *pll,
443 const struct fb_info_aty *info);
444 static void aty_set_pll_ct(const struct fb_info_aty *info,
445 const struct pll_ct *pll);
446 static int aty_valid_pll_ct(const struct fb_info_aty *info, u32 vclk_per,
447 struct pll_ct *pll);
448 static int aty_dsp_gt(const struct fb_info_aty *info, u8 bpp,
449 struct pll_ct *pll);
450 static void aty_calc_pll_ct(const struct fb_info_aty *info,
451 struct pll_ct *pll);
452 static int aty_var_to_pll_ct(const struct fb_info_aty *info, u32 vclk_per,
453 u8 bpp, struct pll_ct *pll);
454 static u32 aty_pll_ct_to_var(const struct pll_ct *pll,
455 const struct fb_info_aty *info);
456 static void atyfb_set_par(const struct atyfb_par *par,
457 struct fb_info_aty *info);
458 static int atyfb_decode_var(const struct fb_var_screeninfo *var,
459 struct atyfb_par *par,
460 const struct fb_info_aty *info);
461 static int atyfb_encode_var(struct fb_var_screeninfo *var,
462 const struct atyfb_par *par,
463 const struct fb_info_aty *info);
464 static void set_off_pitch(struct atyfb_par *par,
465 const struct fb_info_aty *info);
466 static int encode_fix(struct fb_fix_screeninfo *fix,
467 const struct atyfb_par *par,
468 const struct fb_info_aty *info);
469 static void atyfb_set_dispsw(struct display *disp, struct fb_info_aty *info,
470 int bpp, int accel);
471 static int atyfb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
472 u_int *transp, struct fb_info *fb);
473 static int atyfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
474 u_int transp, struct fb_info *fb);
475 static void do_install_cmap(int con, struct fb_info *info);
476 #ifdef CONFIG_PPC
477 static int read_aty_sense(const struct fb_info_aty *info);
478 #endif
479
480
481 /*
482 * Interface used by the world
483 */
484
485 int atyfb_init(void);
486 #ifndef MODULE
487 int atyfb_setup(char*);
488 #endif
489
490 static int currcon = 0;
491
492 static struct fb_ops atyfb_ops = {
493 owner: THIS_MODULE,
494 fb_open: atyfb_open,
495 fb_release: atyfb_release,
496 fb_get_fix: atyfb_get_fix,
497 fb_get_var: atyfb_get_var,
498 fb_set_var: atyfb_set_var,
499 fb_get_cmap: atyfb_get_cmap,
500 fb_set_cmap: atyfb_set_cmap,
501 fb_pan_display: atyfb_pan_display,
502 fb_ioctl: atyfb_ioctl,
503 #ifdef __sparc__
504 fb_mmap: atyfb_mmap,
505 #endif
506 fb_rasterimg: atyfb_rasterimg,
507 };
508
509 static char atyfb_name[16] = "ATY Mach64";
510 static char fontname[40] __initdata = { 0 };
511 static char curblink __initdata = 1;
512 static char noaccel __initdata = 0;
513 static u32 default_vram __initdata = 0;
514 static int default_pll __initdata = 0;
515 static int default_mclk __initdata = 0;
516
517 #ifndef MODULE
518 static const char *mode_option __initdata = NULL;
519 #endif
520
521 #ifdef CONFIG_PPC
522 #ifdef CONFIG_NVRAM_NOT_DEFINED
523 static int default_vmode __initdata = VMODE_NVRAM;
524 static int default_cmode __initdata = CMODE_NVRAM;
525 #else
526 static int default_vmode __initdata = VMODE_CHOOSE;
527 static int default_cmode __initdata = CMODE_CHOOSE;
528 #endif
529 #endif
530
531 #ifdef CONFIG_ATARI
532 static unsigned int mach64_count __initdata = 0;
533 static unsigned long phys_vmembase[FB_MAX] __initdata = { 0, };
534 static unsigned long phys_size[FB_MAX] __initdata = { 0, };
535 static unsigned long phys_guiregbase[FB_MAX] __initdata = { 0, };
536 #endif
537
538
539 static struct aty_features {
540 u16 pci_id;
541 u16 chip_type;
542 const char *name;
543 } aty_features[] __initdata = {
544 /* mach64GX family */
545 { 0x4758, 0x00d7, "mach64GX (ATI888GX00)" },
546 { 0x4358, 0x0057, "mach64CX (ATI888CX00)" },
547
548 /* mach64CT family */
549 { 0x4354, 0x4354, "mach64CT (ATI264CT)" },
550 { 0x4554, 0x4554, "mach64ET (ATI264ET)" },
551
552 /* mach64CT family / mach64VT class */
553 { 0x5654, 0x5654, "mach64VT (ATI264VT)" },
554 { 0x5655, 0x5655, "mach64VTB (ATI264VTB)" },
555 { 0x5656, 0x5656, "mach64VT4 (ATI264VT4)" },
556
557 /* mach64CT family / mach64GT (3D RAGE) class */
558 { 0x4c42, 0x4c42, "3D RAGE LT PRO (AGP)" },
559 { 0x4c44, 0x4c44, "3D RAGE LT PRO" },
560 { 0x4c47, 0x4c47, "3D RAGE LT-G" },
561 { 0x4c49, 0x4c49, "3D RAGE LT PRO" },
562 { 0x4c50, 0x4c50, "3D RAGE LT PRO" },
563 { 0x4c54, 0x4c54, "3D RAGE LT" },
564 { 0x4754, 0x4754, "3D RAGE (GT)" },
565 { 0x4755, 0x4755, "3D RAGE II+ (GTB)" },
566 { 0x4756, 0x4756, "3D RAGE IIC (PCI)" },
567 { 0x4757, 0x4757, "3D RAGE IIC (AGP)" },
568 { 0x475a, 0x475a, "3D RAGE IIC (AGP)" },
569 { 0x4742, 0x4742, "3D RAGE PRO (BGA, AGP)" },
570 { 0x4744, 0x4744, "3D RAGE PRO (BGA, AGP, 1x only)" },
571 { 0x4749, 0x4749, "3D RAGE PRO (BGA, PCI)" },
572 { 0x4750, 0x4750, "3D RAGE PRO (PQFP, PCI)" },
573 { 0x4751, 0x4751, "3D RAGE PRO (PQFP, PCI, limited 3D)" },
574 { 0x4c4d, 0x4c4d, "3D RAGE Mobility (PCI)" },
575 { 0x4c4e, 0x4c4e, "3D RAGE Mobility (AGP)" },
576 };
577
578 static const char *aty_gx_ram[8] __initdata = {
579 "DRAM", "VRAM", "VRAM", "DRAM", "DRAM", "VRAM", "VRAM", "RESV"
580 };
581
582 static const char *aty_ct_ram[8] __initdata = {
583 "OFF", "DRAM", "EDO", "EDO", "SDRAM", "SGRAM", "WRAM", "RESV"
584 };
585
586
587 static inline u32 aty_ld_le32(int regindex,
588 const struct fb_info_aty *info)
589 {
590 /* Hack for bloc 1, should be cleanly optimized by compiler */
591 if (regindex >= 0x400)
592 regindex -= 0x800;
593
594 #if defined(__mc68000__)
595 return le32_to_cpu(*((volatile u32 *)(info->ati_regbase+regindex)));
596 #else
597 return readl (info->ati_regbase + regindex);
598 #endif
599 }
600
601 static inline void aty_st_le32(int regindex, u32 val,
602 const struct fb_info_aty *info)
603 {
604 /* Hack for bloc 1, should be cleanly optimized by compiler */
605 if (regindex >= 0x400)
606 regindex -= 0x800;
607
608 #if defined(__mc68000__)
609 *((volatile u32 *)(info->ati_regbase+regindex)) = cpu_to_le32(val);
610 #else
611 writel (val, info->ati_regbase + regindex);
612 #endif
613 }
614
615 static inline u8 aty_ld_8(int regindex,
616 const struct fb_info_aty *info)
617 {
618 /* Hack for bloc 1, should be cleanly optimized by compiler */
619 if (regindex >= 0x400)
620 regindex -= 0x800;
621
622 return readb (info->ati_regbase + regindex);
623 }
624
625 static inline void aty_st_8(int regindex, u8 val,
626 const struct fb_info_aty *info)
627 {
628 /* Hack for bloc 1, should be cleanly optimized by compiler */
629 if (regindex >= 0x400)
630 regindex -= 0x800;
631
632 writeb (val, info->ati_regbase + regindex);
633 }
634
635 #if defined(CONFIG_PPC) || defined(CONFIG_PMAC_PBOOK)
636 static void aty_st_lcd(int index, u32 val, const struct fb_info_aty *info)
637 {
638 unsigned long temp;
639
640 /* write addr byte */
641 temp = aty_ld_le32(LCD_INDEX, info);
642 aty_st_le32(LCD_INDEX, (temp & ~LCD_INDEX_MASK) | index, info);
643 /* write the register value */
644 aty_st_le32(LCD_DATA, val, info);
645 }
646
647 static u32 aty_ld_lcd(int index, const struct fb_info_aty *info)
648 {
649 unsigned long temp;
650
651 /* write addr byte */
652 temp = aty_ld_le32(LCD_INDEX, info);
653 aty_st_le32(LCD_INDEX, (temp & ~LCD_INDEX_MASK) | index, info);
654 /* read the register value */
655 return aty_ld_le32(LCD_DATA, info);
656 }
657 #endif
658
659 /*
660 * Generic Mach64 routines
661 */
662
663 /*
664 * All writes to draw engine registers are automatically routed through a
665 * 32-bit-wide, 16-entry-deep command FIFO ...
666 * Register writes to registers with DWORD offsets less than 40h are not
667 * FIFOed.
668 * (from Chapter 5 of the Mach64 Programmer's Guide)
669 */
670
671 static inline void wait_for_fifo(u16 entries, const struct fb_info_aty *info)
672 {
673 while ((aty_ld_le32(FIFO_STAT, info) & 0xffff) >
674 ((u32)(0x8000 >> entries)));
675 }
676
677 static inline void wait_for_idle(struct fb_info_aty *info)
678 {
679 wait_for_fifo(16, info);
680 while ((aty_ld_le32(GUI_STAT, info) & 1)!= 0);
681 info->blitter_may_be_busy = 0;
682 }
683
684 static void reset_engine(const struct fb_info_aty *info)
685 {
686 /* reset engine */
687 aty_st_le32(GEN_TEST_CNTL,
688 aty_ld_le32(GEN_TEST_CNTL, info) & ~GUI_ENGINE_ENABLE, info);
689 /* enable engine */
690 aty_st_le32(GEN_TEST_CNTL,
691 aty_ld_le32(GEN_TEST_CNTL, info) | GUI_ENGINE_ENABLE, info);
692 /* ensure engine is not locked up by clearing any FIFO or */
693 /* HOST errors */
694 aty_st_le32(BUS_CNTL, aty_ld_le32(BUS_CNTL, info) | BUS_HOST_ERR_ACK |
695 BUS_FIFO_ERR_ACK, info);
696 }
697
698 static void reset_GTC_3D_engine(const struct fb_info_aty *info)
699 {
700 aty_st_le32(SCALE_3D_CNTL, 0xc0, info);
701 mdelay(GTC_3D_RESET_DELAY);
702 aty_st_le32(SETUP_CNTL, 0x00, info);
703 mdelay(GTC_3D_RESET_DELAY);
704 aty_st_le32(SCALE_3D_CNTL, 0x00, info);
705 mdelay(GTC_3D_RESET_DELAY);
706 }
707
708 static void init_engine(const struct atyfb_par *par, struct fb_info_aty *info)
709 {
710 u32 pitch_value;
711
712 /* determine modal information from global mode structure */
713 pitch_value = par->crtc.vxres;
714
715 if (par->crtc.bpp == 24) {
716 /* In 24 bpp, the engine is in 8 bpp - this requires that all */
717 /* horizontal coordinates and widths must be adjusted */
718 pitch_value = pitch_value * 3;
719 }
720
721 /* On GTC (RagePro), we need to reset the 3D engine before */
722 if (Gx == LB_CHIP_ID || Gx == LD_CHIP_ID || Gx == LI_CHIP_ID ||
723 Gx == LP_CHIP_ID || Gx == GB_CHIP_ID || Gx == GD_CHIP_ID ||
724 Gx == GI_CHIP_ID || Gx == GP_CHIP_ID || Gx == GQ_CHIP_ID ||
725 Gx == LM_CHIP_ID || Gx == LN_CHIP_ID)
726 reset_GTC_3D_engine(info);
727
728 /* Reset engine, enable, and clear any engine errors */
729 reset_engine(info);
730 /* Ensure that vga page pointers are set to zero - the upper */
731 /* page pointers are set to 1 to handle overflows in the */
732 /* lower page */
733 aty_st_le32(MEM_VGA_WP_SEL, 0x00010000, info);
734 aty_st_le32(MEM_VGA_RP_SEL, 0x00010000, info);
735
736 /* ---- Setup standard engine context ---- */
737
738 /* All GUI registers here are FIFOed - therefore, wait for */
739 /* the appropriate number of empty FIFO entries */
740 wait_for_fifo(14, info);
741
742 /* enable all registers to be loaded for context loads */
743 aty_st_le32(CONTEXT_MASK, 0xFFFFFFFF, info);
744
745 /* set destination pitch to modal pitch, set offset to zero */
746 aty_st_le32(DST_OFF_PITCH, (pitch_value / 8) << 22, info);
747
748 /* zero these registers (set them to a known state) */
749 aty_st_le32(DST_Y_X, 0, info);
750 aty_st_le32(DST_HEIGHT, 0, info);
751 aty_st_le32(DST_BRES_ERR, 0, info);
752 aty_st_le32(DST_BRES_INC, 0, info);
753 aty_st_le32(DST_BRES_DEC, 0, info);
754
755 /* set destination drawing attributes */
756 aty_st_le32(DST_CNTL, DST_LAST_PEL | DST_Y_TOP_TO_BOTTOM |
757 DST_X_LEFT_TO_RIGHT, info);
758
759 /* set source pitch to modal pitch, set offset to zero */
760 aty_st_le32(SRC_OFF_PITCH, (pitch_value / 8) << 22, info);
761
762 /* set these registers to a known state */
763 aty_st_le32(SRC_Y_X, 0, info);
764 aty_st_le32(SRC_HEIGHT1_WIDTH1, 1, info);
765 aty_st_le32(SRC_Y_X_START, 0, info);
766 aty_st_le32(SRC_HEIGHT2_WIDTH2, 1, info);
767
768 /* set source pixel retrieving attributes */
769 aty_st_le32(SRC_CNTL, SRC_LINE_X_LEFT_TO_RIGHT, info);
770
771 /* set host attributes */
772 wait_for_fifo(13, info);
773 aty_st_le32(HOST_CNTL, 0, info);
774
775 /* set pattern attributes */
776 aty_st_le32(PAT_REG0, 0, info);
777 aty_st_le32(PAT_REG1, 0, info);
778 aty_st_le32(PAT_CNTL, 0, info);
779
780 /* set scissors to modal size */
781 aty_st_le32(SC_LEFT, 0, info);
782 aty_st_le32(SC_TOP, 0, info);
783 aty_st_le32(SC_BOTTOM, par->crtc.vyres-1, info);
784 aty_st_le32(SC_RIGHT, pitch_value-1, info);
785
786 /* set background color to minimum value (usually BLACK) */
787 aty_st_le32(DP_BKGD_CLR, 0, info);
788
789 /* set foreground color to maximum value (usually WHITE) */
790 aty_st_le32(DP_FRGD_CLR, 0xFFFFFFFF, info);
791
792 /* set write mask to effect all pixel bits */
793 aty_st_le32(DP_WRITE_MASK, 0xFFFFFFFF, info);
794
795 /* set foreground mix to overpaint and background mix to */
796 /* no-effect */
797 aty_st_le32(DP_MIX, FRGD_MIX_S | BKGD_MIX_D, info);
798
799 /* set primary source pixel channel to foreground color */
800 /* register */
801 aty_st_le32(DP_SRC, FRGD_SRC_FRGD_CLR, info);
802
803 /* set compare functionality to false (no-effect on */
804 /* destination) */
805 wait_for_fifo(3, info);
806 aty_st_le32(CLR_CMP_CLR, 0, info);
807 aty_st_le32(CLR_CMP_MASK, 0xFFFFFFFF, info);
808 aty_st_le32(CLR_CMP_CNTL, 0, info);
809
810 /* set pixel depth */
811 wait_for_fifo(2, info);
812 aty_st_le32(DP_PIX_WIDTH, par->crtc.dp_pix_width, info);
813 aty_st_le32(DP_CHAIN_MASK, par->crtc.dp_chain_mask, info);
814
815 wait_for_fifo(5, info);
816 aty_st_le32(SCALE_3D_CNTL, 0, info);
817 aty_st_le32(Z_CNTL, 0, info);
818 aty_st_le32(CRTC_INT_CNTL, aty_ld_le32(CRTC_INT_CNTL, info) & ~0x20, info);
819 aty_st_le32(GUI_TRAJ_CNTL, 0x100023, info);
820
821 /* insure engine is idle before leaving */
822 wait_for_idle(info);
823 }
824
825 static void aty_st_514(int offset, u8 val, const struct fb_info_aty *info)
826 {
827 aty_st_8(DAC_CNTL, 1, info);
828 /* right addr byte */
829 aty_st_8(DAC_W_INDEX, offset & 0xff, info);
830 /* left addr byte */
831 aty_st_8(DAC_DATA, (offset >> 8) & 0xff, info);
832 aty_st_8(DAC_MASK, val, info);
833 aty_st_8(DAC_CNTL, 0, info);
834 }
835
836 static void aty_st_pll(int offset, u8 val, const struct fb_info_aty *info)
837 {
838 /* write addr byte */
839 aty_st_8(CLOCK_CNTL + 1, (offset << 2) | PLL_WR_EN, info);
840 /* write the register value */
841 aty_st_8(CLOCK_CNTL + 2, val, info);
842 aty_st_8(CLOCK_CNTL + 1, (offset << 2) & ~PLL_WR_EN, info);
843 }
844
845 static u8 aty_ld_pll(int offset, const struct fb_info_aty *info)
846 {
847 u8 res;
848
849 /* write addr byte */
850 aty_st_8(CLOCK_CNTL + 1, (offset << 2), info);
851 /* read the register value */
852 res = aty_ld_8(CLOCK_CNTL + 2, info);
853 return res;
854 }
855
856 #if defined(CONFIG_PPC)
857
858 /*
859 * Apple monitor sense
860 */
861
862 static int read_aty_sense(const struct fb_info_aty *info)
863 {
864 int sense, i;
865
866 aty_st_le32(GP_IO, 0x31003100, info); /* drive outputs high */
867 __delay(200);
868 aty_st_le32(GP_IO, 0, info); /* turn off outputs */
869 __delay(2000);
870 i = aty_ld_le32(GP_IO, info); /* get primary sense value */
871 sense = ((i & 0x3000) >> 3) | (i & 0x100);
872
873 /* drive each sense line low in turn and collect the other 2 */
874 aty_st_le32(GP_IO, 0x20000000, info); /* drive A low */
875 __delay(2000);
876 i = aty_ld_le32(GP_IO, info);
877 sense |= ((i & 0x1000) >> 7) | ((i & 0x100) >> 4);
878 aty_st_le32(GP_IO, 0x20002000, info); /* drive A high again */
879 __delay(200);
880
881 aty_st_le32(GP_IO, 0x10000000, info); /* drive B low */
882 __delay(2000);
883 i = aty_ld_le32(GP_IO, info);
884 sense |= ((i & 0x2000) >> 10) | ((i & 0x100) >> 6);
885 aty_st_le32(GP_IO, 0x10001000, info); /* drive B high again */
886 __delay(200);
887
888 aty_st_le32(GP_IO, 0x01000000, info); /* drive C low */
889 __delay(2000);
890 sense |= (aty_ld_le32(GP_IO, info) & 0x3000) >> 12;
891 aty_st_le32(GP_IO, 0, info); /* turn off outputs */
892
893 return sense;
894 }
895
896 #endif /* defined(CONFIG_PPC) */
897
898 /* ------------------------------------------------------------------------- */
899
900 /*
901 * Hardware Cursor support.
902 */
903
904 static u8 cursor_pixel_map[2] = { 0, 15 };
905 static u8 cursor_color_map[2] = { 0, 0xff };
906
907 static u8 cursor_bits_lookup[16] =
908 {
909 0x00, 0x40, 0x10, 0x50, 0x04, 0x44, 0x14, 0x54,
910 0x01, 0x41, 0x11, 0x51, 0x05, 0x45, 0x15, 0x55
911 };
912
913 static u8 cursor_mask_lookup[16] =
914 {
915 0xaa, 0x2a, 0x8a, 0x0a, 0xa2, 0x22, 0x82, 0x02,
916 0xa8, 0x28, 0x88, 0x08, 0xa0, 0x20, 0x80, 0x00
917 };
918
919 static void
920 aty_set_cursor_color(struct fb_info_aty *fb, u8 *pixel,
921 u8 *red, u8 *green, u8 *blue)
922 {
923 struct aty_cursor *c = fb->cursor;
924 int i;
925
926 if (!c)
927 return;
928
929 #ifdef __sparc__
930 if (fb->mmaped && (!fb->fb_info.display_fg
931 || fb->fb_info.display_fg->vc_num == fb->vtconsole))
932 return;
933 #endif
934
935 for (i = 0; i < 2; i++) {
936 c->color[i] = (u32)red[i] << 24;
937 c->color[i] |= (u32)green[i] << 16;
938 c->color[i] |= (u32)blue[i] << 8;
939 c->color[i] |= (u32)pixel[i];
940 }
941
942 wait_for_fifo(2, fb);
943 aty_st_le32(CUR_CLR0, c->color[0], fb);
944 aty_st_le32(CUR_CLR1, c->color[1], fb);
945 }
946
947 static void
948 aty_set_cursor_shape(struct fb_info_aty *fb)
949 {
950 struct aty_cursor *c = fb->cursor;
951 u8 *ram, m, b;
952 int x, y;
953
954 if (!c)
955 return;
956
957 #ifdef __sparc__
958 if (fb->mmaped && (!fb->fb_info.display_fg
959 || fb->fb_info.display_fg->vc_num == fb->vtconsole))
960 return;
961 #endif
962
963 ram = c->ram;
964 for (y = 0; y < c->size.y; y++) {
965 for (x = 0; x < c->size.x >> 2; x++) {
966 m = c->mask[x][y];
967 b = c->bits[x][y];
968 fb_writeb (cursor_mask_lookup[m >> 4] |
969 cursor_bits_lookup[(b & m) >> 4],
970 ram++);
971 fb_writeb (cursor_mask_lookup[m & 0x0f] |
972 cursor_bits_lookup[(b & m) & 0x0f],
973 ram++);
974 }
975 for ( ; x < 8; x++) {
976 fb_writeb (0xaa, ram++);
977 fb_writeb (0xaa, ram++);
978 }
979 }
980 fb_memset (ram, 0xaa, (64 - c->size.y) * 16);
981 }
982
983 static void
984 aty_set_cursor(struct fb_info_aty *fb, int on)
985 {
986 struct atyfb_par *par = &fb->current_par;
987 struct aty_cursor *c = fb->cursor;
988 u16 xoff, yoff;
989 int x, y;
990
991 if (!c)
992 return;
993
994 #ifdef __sparc__
995 if (fb->mmaped && (!fb->fb_info.display_fg
996 || fb->fb_info.display_fg->vc_num == fb->vtconsole))
997 return;
998 #endif
999
1000 if (on) {
1001 x = c->pos.x - c->hot.x - par->crtc.xoffset;
1002 if (x < 0) {
1003 xoff = -x;
1004 x = 0;
1005 } else {
1006 xoff = 0;
1007 }
1008
1009 y = c->pos.y - c->hot.y - par->crtc.yoffset;
1010 if (y < 0) {
1011 yoff = -y;
1012 y = 0;
1013 } else {
1014 yoff = 0;
1015 }
1016
1017 wait_for_fifo(4, fb);
1018 aty_st_le32(CUR_OFFSET, (c->offset >> 3) + (yoff << 1), fb);
1019 aty_st_le32(CUR_HORZ_VERT_OFF,
1020 ((u32)(64 - c->size.y + yoff) << 16) | xoff, fb);
1021 aty_st_le32(CUR_HORZ_VERT_POSN, ((u32)y << 16) | x, fb);
1022 aty_st_le32(GEN_TEST_CNTL, aty_ld_le32(GEN_TEST_CNTL, fb)
1023 | HWCURSOR_ENABLE, fb);
1024 } else {
1025 wait_for_fifo(1, fb);
1026 aty_st_le32(GEN_TEST_CNTL,
1027 aty_ld_le32(GEN_TEST_CNTL, fb) & ~HWCURSOR_ENABLE,
1028 fb);
1029 }
1030 if (fb->blitter_may_be_busy)
1031 wait_for_idle(fb);
1032 }
1033
1034 static void
1035 aty_cursor_timer_handler(unsigned long dev_addr)
1036 {
1037 struct fb_info_aty *fb = (struct fb_info_aty *)dev_addr;
1038
1039 if (!fb->cursor)
1040 return;
1041
1042 if (!fb->cursor->enable)
1043 goto out;
1044
1045 if (fb->cursor->vbl_cnt && --fb->cursor->vbl_cnt == 0) {
1046 fb->cursor->on ^= 1;
1047 aty_set_cursor(fb, fb->cursor->on);
1048 fb->cursor->vbl_cnt = fb->cursor->blink_rate;
1049 }
1050
1051 out:
1052 fb->cursor->timer->expires = jiffies + (HZ / 50);
1053 add_timer(fb->cursor->timer);
1054 }
1055
1056 static void
1057 atyfb_cursor(struct display *p, int mode, int x, int y)
1058 {
1059 struct fb_info_aty *fb = (struct fb_info_aty *)p->fb_info;
1060 struct aty_cursor *c = fb->cursor;
1061
1062 if (!c)
1063 return;
1064
1065 #ifdef __sparc__
1066 if (fb->mmaped && (!fb->fb_info.display_fg
1067 || fb->fb_info.display_fg->vc_num == fb->vtconsole))
1068 return;
1069 #endif
1070
1071 x *= fontwidth(p);
1072 y *= fontheight(p);
1073 if (c->pos.x == x && c->pos.y == y && (mode == CM_ERASE) == !c->enable)
1074 return;
1075
1076 c->enable = 0;
1077 if (c->on)
1078 aty_set_cursor(fb, 0);
1079 c->pos.x = x;
1080 c->pos.y = y;
1081
1082 switch (mode) {
1083 case CM_ERASE:
1084 c->on = 0;
1085 break;
1086
1087 case CM_DRAW:
1088 case CM_MOVE:
1089 if (c->on)
1090 aty_set_cursor(fb, 1);
1091 else
1092 c->vbl_cnt = CURSOR_DRAW_DELAY;
1093 c->enable = 1;
1094 break;
1095 }
1096 }
1097
1098 static struct fb_info_aty *fb_list = NULL;
1099
1100 static struct aty_cursor * __init
1101 aty_init_cursor(struct fb_info_aty *fb)
1102 {
1103 struct aty_cursor *cursor;
1104 unsigned long addr;
1105
1106 cursor = kmalloc(sizeof(struct aty_cursor), GFP_ATOMIC);
1107 if (!cursor)
1108 return 0;
1109 memset(cursor, 0, sizeof(*cursor));
1110
1111 cursor->timer = kmalloc(sizeof(*cursor->timer), GFP_KERNEL);
1112 if (!cursor->timer) {
1113 kfree(cursor);
1114 return 0;
1115 }
1116 memset(cursor->timer, 0, sizeof(*cursor->timer));
1117
1118 cursor->blink_rate = DEFAULT_CURSOR_BLINK_RATE;
1119 fb->total_vram -= PAGE_SIZE;
1120 cursor->offset = fb->total_vram;
1121
1122 #ifdef __sparc__
1123 addr = fb->frame_buffer - 0x800000 + cursor->offset;
1124 cursor->ram = (u8 *)addr;
1125 #else
1126 #ifdef __BIG_ENDIAN
1127 addr = fb->frame_buffer_phys - 0x800000 + cursor->offset;
1128 cursor->ram = (u8 *)ioremap(addr, 1024);
1129 #else
1130 addr = fb->frame_buffer + cursor->offset;
1131 cursor->ram = (u8 *)addr;
1132 #endif
1133 #endif
1134
1135 if (! cursor->ram) {
1136 kfree(cursor);
1137 return NULL;
1138 }
1139
1140 if (curblink) {
1141 init_timer(cursor->timer);
1142 cursor->timer->expires = jiffies + (HZ / 50);
1143 cursor->timer->data = (unsigned long)fb;
1144 cursor->timer->function = aty_cursor_timer_handler;
1145 add_timer(cursor->timer);
1146 }
1147
1148 return cursor;
1149 }
1150
1151 static int
1152 atyfb_set_font(struct display *d, int width, int height)
1153 {
1154 struct fb_info_aty *fb = (struct fb_info_aty *)d->fb_info;
1155 struct aty_cursor *c = fb->cursor;
1156 int i, j;
1157
1158 if (c) {
1159 if (!width || !height) {
1160 width = 8;
1161 height = 16;
1162 }
1163
1164 c->hot.x = 0;
1165 c->hot.y = 0;
1166 c->size.x = width;
1167 c->size.y = height;
1168
1169 memset(c->bits, 0xff, sizeof(c->bits));
1170 memset(c->mask, 0, sizeof(c->mask));
1171
1172 for (i = 0, j = width; j >= 0; j -= 8, i++) {
1173 c->mask[i][height-2] = (j >= 8) ? 0xff : (0xff << (8 - j));
1174 c->mask[i][height-1] = (j >= 8) ? 0xff : (0xff << (8 - j));
1175 }
1176
1177 aty_set_cursor_color(fb, cursor_pixel_map, cursor_color_map,
1178 cursor_color_map, cursor_color_map);
1179 aty_set_cursor_shape(fb);
1180 }
1181 return 1;
1182 }
1183
1184
1185
1186
1187 /* ------------------------------------------------------------------------- */
1188
1189 /*
1190 * CRTC programming
1191 */
1192
1193 static void aty_set_crtc(const struct fb_info_aty *info,
1194 const struct crtc *crtc)
1195 {
1196 aty_st_le32(CRTC_H_TOTAL_DISP, crtc->h_tot_disp, info);
1197 aty_st_le32(CRTC_H_SYNC_STRT_WID, crtc->h_sync_strt_wid, info);
1198 aty_st_le32(CRTC_V_TOTAL_DISP, crtc->v_tot_disp, info);
1199 aty_st_le32(CRTC_V_SYNC_STRT_WID, crtc->v_sync_strt_wid, info);
1200 aty_st_le32(CRTC_VLINE_CRNT_VLINE, 0, info);
1201 aty_st_le32(CRTC_OFF_PITCH, crtc->off_pitch, info);
1202 aty_st_le32(CRTC_GEN_CNTL, crtc->gen_cntl, info);
1203 }
1204
1205 static int aty_var_to_crtc(const struct fb_info_aty *info,
1206 const struct fb_var_screeninfo *var,
1207 struct crtc *crtc)
1208 {
1209 u32 xres, yres, vxres, vyres, xoffset, yoffset, bpp;
1210 u32 left, right, upper, lower, hslen, vslen, sync, vmode;
1211 u32 h_total, h_disp, h_sync_strt, h_sync_dly, h_sync_wid, h_sync_pol;
1212 u32 v_total, v_disp, v_sync_strt, v_sync_wid, v_sync_pol, c_sync;
1213 u32 pix_width, dp_pix_width, dp_chain_mask;
1214
1215 /* input */
1216 xres = var->xres;
1217 yres = var->yres;
1218 vxres = var->xres_virtual;
1219 vyres = var->yres_virtual;
1220 xoffset = var->xoffset;
1221 yoffset = var->yoffset;
1222 bpp = var->bits_per_pixel;
1223 left = var->left_margin;
1224 right = var->right_margin;
1225 upper = var->upper_margin;
1226 lower = var->lower_margin;
1227 hslen = var->hsync_len;
1228 vslen = var->vsync_len;
1229 sync = var->sync;
1230 vmode = var->vmode;
1231
1232 /* convert (and round up) and validate */
1233 xres = (xres+7) & ~7;
1234 xoffset = (xoffset+7) & ~7;
1235 vxres = (vxres+7) & ~7;
1236 if (vxres < xres+xoffset)
1237 vxres = xres+xoffset;
1238 h_disp = xres/8-1;
1239 if (h_disp > 0xff)
1240 FAIL("h_disp too large");
1241 h_sync_strt = h_disp+(right/8);
1242 if (h_sync_strt > 0x1ff)
1243 FAIL("h_sync_start too large");
1244 h_sync_dly = right & 7;
1245 h_sync_wid = (hslen+7)/8;
1246 if (h_sync_wid > 0x1f)
1247 FAIL("h_sync_wid too large");
1248 h_total = h_sync_strt+h_sync_wid+(h_sync_dly+left+7)/8;
1249 if (h_total > 0x1ff)
1250 FAIL("h_total too large");
1251 h_sync_pol = sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1;
1252
1253 if (vyres < yres+yoffset)
1254 vyres = yres+yoffset;
1255 v_disp = yres-1;
1256 if (v_disp > 0x7ff)
1257 FAIL("v_disp too large");
1258 v_sync_strt = v_disp+lower;
1259 if (v_sync_strt > 0x7ff)
1260 FAIL("v_sync_strt too large");
1261 v_sync_wid = vslen;
1262 if (v_sync_wid > 0x1f)
1263 FAIL("v_sync_wid too large");
1264 v_total = v_sync_strt+v_sync_wid+upper;
1265 if (v_total > 0x7ff)
1266 FAIL("v_total too large");
1267 v_sync_pol = sync & FB_SYNC_VERT_HIGH_ACT ? 0 : 1;
1268
1269 c_sync = sync & FB_SYNC_COMP_HIGH_ACT ? CRTC_CSYNC_EN : 0;
1270
1271 if (bpp <= 8) {
1272 bpp = 8;
1273 pix_width = CRTC_PIX_WIDTH_8BPP;
1274 dp_pix_width = HOST_8BPP | SRC_8BPP | DST_8BPP | BYTE_ORDER_LSB_TO_MSB;
1275 dp_chain_mask = 0x8080;
1276 } else if (bpp <= 16) {
1277 bpp = 16;
1278 pix_width = CRTC_PIX_WIDTH_15BPP;
1279 dp_pix_width = HOST_15BPP | SRC_15BPP | DST_15BPP |
1280 BYTE_ORDER_LSB_TO_MSB;
1281 dp_chain_mask = 0x4210;
1282 } else if ((bpp <= 24) && (Gx != GX_CHIP_ID) && (Gx != CX_CHIP_ID)) {
1283 bpp = 24;
1284 pix_width = CRTC_PIX_WIDTH_24BPP;
1285 dp_pix_width = HOST_8BPP | SRC_8BPP | DST_8BPP | BYTE_ORDER_LSB_TO_MSB;
1286 dp_chain_mask = 0x8080;
1287 } else if (bpp <= 32) {
1288 bpp = 32;
1289 pix_width = CRTC_PIX_WIDTH_32BPP;
1290 dp_pix_width = HOST_32BPP | SRC_32BPP | DST_32BPP |
1291 BYTE_ORDER_LSB_TO_MSB;
1292 dp_chain_mask = 0x8080;
1293 } else
1294 FAIL("invalid bpp");
1295
1296 if (vxres*vyres*bpp/8 > info->total_vram)
1297 FAIL("not enough video RAM");
1298
1299 if ((vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED)
1300 FAIL("invalid vmode");
1301
1302 /* output */
1303 crtc->vxres = vxres;
1304 crtc->vyres = vyres;
1305 crtc->xoffset = xoffset;
1306 crtc->yoffset = yoffset;
1307 crtc->bpp = bpp;
1308 crtc->h_tot_disp = h_total | (h_disp<<16);
1309 crtc->h_sync_strt_wid = (h_sync_strt & 0xff) | (h_sync_dly<<8) |
1310 ((h_sync_strt & 0x100)<<4) | (h_sync_wid<<16) |
1311 (h_sync_pol<<21);
1312 crtc->v_tot_disp = v_total | (v_disp<<16);
1313 crtc->v_sync_strt_wid = v_sync_strt | (v_sync_wid<<16) | (v_sync_pol<<21);
1314 crtc->off_pitch = ((yoffset*vxres+xoffset)*bpp/64) | (vxres<<19);
1315 crtc->gen_cntl = pix_width | c_sync | CRTC_EXT_DISP_EN | CRTC_ENABLE;
1316 if ((Gx == CT_CHIP_ID) || (Gx == ET_CHIP_ID) ||
1317 ((Gx == VT_CHIP_ID || Gx == GT_CHIP_ID) && !(Rev & 0x07))) {
1318 /* Not VTB/GTB */
1319 /* FIXME: magic FIFO values */
1320 crtc->gen_cntl |= aty_ld_le32(CRTC_GEN_CNTL, info) & 0x000e0000;
1321 }
1322 crtc->dp_pix_width = dp_pix_width;
1323 crtc->dp_chain_mask = dp_chain_mask;
1324
1325 return 0;
1326 }
1327
1328
1329 static int aty_set_dac_ATI68860_B(const struct fb_info_aty *info, u32 bpp,
1330 u32 AccelMode)
1331 {
1332 u32 gModeReg, devSetupRegA, temp, mask;
1333
1334 gModeReg = 0;
1335 devSetupRegA = 0;
1336
1337 switch (bpp) {
1338 case 8:
1339 gModeReg = 0x83;
1340 devSetupRegA = 0x60 | 0x00 /*(info->mach64DAC8Bit ? 0x00 : 0x01) */;
1341 break;
1342 case 15:
1343 gModeReg = 0xA0;
1344 devSetupRegA = 0x60;
1345 break;
1346 case 16:
1347 gModeReg = 0xA1;
1348 devSetupRegA = 0x60;
1349 break;
1350 case 24:
1351 gModeReg = 0xC0;
1352 devSetupRegA = 0x60;
1353 break;
1354 case 32:
1355 gModeReg = 0xE3;
1356 devSetupRegA = 0x60;
1357 break;
1358 }
1359
1360 if (!AccelMode) {
1361 gModeReg = 0x80;
1362 devSetupRegA = 0x61;
1363 }
1364
1365 temp = aty_ld_8(DAC_CNTL, info);
1366 aty_st_8(DAC_CNTL, (temp & ~DAC_EXT_SEL_RS2) | DAC_EXT_SEL_RS3, info);
1367
1368 aty_st_8(DAC_REGS + 2, 0x1D, info);
1369 aty_st_8(DAC_REGS + 3, gModeReg, info);
1370 aty_st_8(DAC_REGS, 0x02, info);
1371
1372 temp = aty_ld_8(DAC_CNTL, info);
1373 aty_st_8(DAC_CNTL, temp | DAC_EXT_SEL_RS2 | DAC_EXT_SEL_RS3, info);
1374
1375 if (info->total_vram < MEM_SIZE_1M)
1376 mask = 0x04;
1377 else if (info->total_vram == MEM_SIZE_1M)
1378 mask = 0x08;
1379 else
1380 mask = 0x0C;
1381
1382 /* The following assumes that the BIOS has correctly set R7 of the
1383 * Device Setup Register A at boot time.
1384 */
1385 #define A860_DELAY_L 0x80
1386
1387 temp = aty_ld_8(DAC_REGS, info);
1388 aty_st_8(DAC_REGS, (devSetupRegA | mask) | (temp & A860_DELAY_L), info);
1389 temp = aty_ld_8(DAC_CNTL, info);
1390 aty_st_8(DAC_CNTL, (temp & ~(DAC_EXT_SEL_RS2 | DAC_EXT_SEL_RS3)), info);
1391
1392 return 0;
1393 }
1394
1395 static int aty_set_dac_ATT21C498(const struct fb_info_aty *info,
1396 const struct pll_18818 *pll, u32 bpp)
1397 {
1398 u32 dotClock;
1399 int muxmode = 0;
1400 int DACMask = 0;
1401
1402 dotClock = 100000000 / pll->period_in_ps;
1403
1404 switch (bpp) {
1405 case 8:
1406 if (dotClock > 8000) {
1407 DACMask = 0x24;
1408 muxmode = 1;
1409 } else
1410 DACMask = 0x04;
1411 break;
1412 case 15:
1413 DACMask = 0x16;
1414 break;
1415 case 16:
1416 DACMask = 0x36;
1417 break;
1418 case 24:
1419 DACMask = 0xE6;
1420 break;
1421 case 32:
1422 DACMask = 0xE6;
1423 break;
1424 }
1425
1426 if (1 /* info->mach64DAC8Bit */)
1427 DACMask |= 0x02;
1428
1429 aty_dac_waste4(info);
1430 aty_st_8(DAC_REGS + 2, DACMask, info);
1431
1432 return muxmode;
1433 }
1434
1435 void aty_dac_waste4(const struct fb_info_aty *info)
1436 {
1437 (void)aty_ld_8(DAC_REGS, info);
1438
1439 (void)aty_ld_8(DAC_REGS + 2, info);
1440 (void)aty_ld_8(DAC_REGS + 2, info);
1441 (void)aty_ld_8(DAC_REGS + 2, info);
1442 (void)aty_ld_8(DAC_REGS + 2, info);
1443 }
1444
1445
1446 static void aty_set_dac_514(const struct fb_info_aty *info, u32 bpp)
1447 {
1448 static struct {
1449 u8 pixel_dly;
1450 u8 misc2_cntl;
1451 u8 pixel_rep;
1452 u8 pixel_cntl_index;
1453 u8 pixel_cntl_v1;
1454 } tab[3] = {
1455 { 0, 0x41, 0x03, 0x71, 0x45 }, /* 8 bpp */
1456 { 0, 0x45, 0x04, 0x0c, 0x01 }, /* 555 */
1457 { 0, 0x45, 0x06, 0x0e, 0x00 }, /* XRGB */
1458 };
1459 int i;
1460
1461 switch (bpp) {
1462 case 8:
1463 default:
1464 i = 0;
1465 break;
1466 case 16:
1467 i = 1;
1468 break;
1469 case 32:
1470 i = 2;
1471 break;
1472 }
1473 aty_st_514(0x90, 0x00, info); /* VRAM Mask Low */
1474 aty_st_514(0x04, tab[i].pixel_dly, info); /* Horizontal Sync Control */
1475 aty_st_514(0x05, 0x00, info); /* Power Management */
1476 aty_st_514(0x02, 0x01, info); /* Misc Clock Control */
1477 aty_st_514(0x71, tab[i].misc2_cntl, info); /* Misc Control 2 */
1478 aty_st_514(0x0a, tab[i].pixel_rep, info); /* Pixel Format */
1479 aty_st_514(tab[i].pixel_cntl_index, tab[i].pixel_cntl_v1, info);
1480 /* Misc Control 2 / 16 BPP Control / 32 BPP Control */
1481 }
1482
1483 static int aty_crtc_to_var(const struct crtc *crtc,
1484 struct fb_var_screeninfo *var)
1485 {
1486 u32 xres, yres, bpp, left, right, upper, lower, hslen, vslen, sync;
1487 u32 h_total, h_disp, h_sync_strt, h_sync_dly, h_sync_wid, h_sync_pol;
1488 u32 v_total, v_disp, v_sync_strt, v_sync_wid, v_sync_pol, c_sync;
1489 u32 pix_width;
1490
1491 /* input */
1492 h_total = crtc->h_tot_disp & 0x1ff;
1493 h_disp = (crtc->h_tot_disp>>16) & 0xff;
1494 h_sync_strt = (crtc->h_sync_strt_wid & 0xff) |
1495 ((crtc->h_sync_strt_wid>>4) & 0x100);
1496 h_sync_dly = (crtc->h_sync_strt_wid>>8) & 0x7;
1497 h_sync_wid = (crtc->h_sync_strt_wid>>16) & 0x1f;
1498 h_sync_pol = (crtc->h_sync_strt_wid>>21) & 0x1;
1499 v_total = crtc->v_tot_disp & 0x7ff;
1500 v_disp = (crtc->v_tot_disp>>16) & 0x7ff;
1501 v_sync_strt = crtc->v_sync_strt_wid & 0x7ff;
1502 v_sync_wid = (crtc->v_sync_strt_wid>>16) & 0x1f;
1503 v_sync_pol = (crtc->v_sync_strt_wid>>21) & 0x1;
1504 c_sync = crtc->gen_cntl & CRTC_CSYNC_EN ? 1 : 0;
1505 pix_width = crtc->gen_cntl & CRTC_PIX_WIDTH_MASK;
1506
1507 /* convert */
1508 xres = (h_disp+1)*8;
1509 yres = v_disp+1;
1510 left = (h_total-h_sync_strt-h_sync_wid)*8-h_sync_dly;
1511 right = (h_sync_strt-h_disp)*8+h_sync_dly;
1512 hslen = h_sync_wid*8;
1513 upper = v_total-v_sync_strt-v_sync_wid;
1514 lower = v_sync_strt-v_disp;
1515 vslen = v_sync_wid;
1516 sync = (h_sync_pol ? 0 : FB_SYNC_HOR_HIGH_ACT) |
1517 (v_sync_pol ? 0 : FB_SYNC_VERT_HIGH_ACT) |
1518 (c_sync ? FB_SYNC_COMP_HIGH_ACT : 0);
1519
1520 switch (pix_width) {
1521 #if 0
1522 case CRTC_PIX_WIDTH_4BPP:
1523 bpp = 4;
1524 var->red.offset = 0;
1525 var->red.length = 8;
1526 var->green.offset = 0;
1527 var->green.length = 8;
1528 var->blue.offset = 0;
1529 var->blue.length = 8;
1530 var->transp.offset = 0;
1531 var->transp.length = 0;
1532 break;
1533 #endif
1534 case CRTC_PIX_WIDTH_8BPP:
1535 bpp = 8;
1536 var->red.offset = 0;
1537 var->red.length = 8;
1538 var->green.offset = 0;
1539 var->green.length = 8;
1540 var->blue.offset = 0;
1541 var->blue.length = 8;
1542 var->transp.offset = 0;
1543 var->transp.length = 0;
1544 break;
1545 case CRTC_PIX_WIDTH_15BPP: /* RGB 555 */
1546 bpp = 16;
1547 var->red.offset = 10;
1548 var->red.length = 5;
1549 var->green.offset = 5;
1550 var->green.length = 5;
1551 var->blue.offset = 0;
1552 var->blue.length = 5;
1553 var->transp.offset = 0;
1554 var->transp.length = 0;
1555 break;
1556 #if 0
1557 case CRTC_PIX_WIDTH_16BPP: /* RGB 565 */
1558 bpp = 16;
1559 var->red.offset = 11;
1560 var->red.length = 5;
1561 var->green.offset = 5;
1562 var->green.length = 6;
1563 var->blue.offset = 0;
1564 var->blue.length = 5;
1565 var->transp.offset = 0;
1566 var->transp.length = 0;
1567 break;
1568 #endif
1569 case CRTC_PIX_WIDTH_24BPP: /* RGB 888 */
1570 bpp = 24;
1571 var->red.offset = 16;
1572 var->red.length = 8;
1573 var->green.offset = 8;
1574 var->green.length = 8;
1575 var->blue.offset = 0;
1576 var->blue.length = 8;
1577 var->transp.offset = 0;
1578 var->transp.length = 0;
1579 break;
1580 case CRTC_PIX_WIDTH_32BPP: /* ARGB 8888 */
1581 bpp = 32;
1582 var->red.offset = 16;
1583 var->red.length = 8;
1584 var->green.offset = 8;
1585 var->green.length = 8;
1586 var->blue.offset = 0;
1587 var->blue.length = 8;
1588 var->transp.offset = 24;
1589 var->transp.length = 8;
1590 break;
1591 default:
1592 FAIL("Invalid pixel width");
1593 }
1594
1595 /* output */
1596 var->xres = xres;
1597 var->yres = yres;
1598 var->xres_virtual = crtc->vxres;
1599 var->yres_virtual = crtc->vyres;
1600 var->bits_per_pixel = bpp;
1601 var->xoffset = crtc->xoffset;
1602 var->yoffset = crtc->yoffset;
1603 var->left_margin = left;
1604 var->right_margin = right;
1605 var->upper_margin = upper;
1606 var->lower_margin = lower;
1607 var->hsync_len = hslen;
1608 var->vsync_len = vslen;
1609 var->sync = sync;
1610 var->vmode = FB_VMODE_NONINTERLACED;
1611
1612 return 0;
1613 }
1614
1615 /* ------------------------------------------------------------------------- */
1616
1617 /*
1618 * PLL programming (Mach64 GX family)
1619 *
1620 * FIXME: use function pointer tables instead of switch statements
1621 */
1622
1623 static void aty_set_pll_gx(const struct fb_info_aty *info,
1624 const struct pll_gx *pll)
1625 {
1626 switch (info->clk_type) {
1627 case CLK_ATI18818_1:
1628 aty_st_8(CLOCK_CNTL, pll->m, info);
1629 break;
1630 case CLK_IBMRGB514:
1631 aty_st_514(0x06, 0x02, info); /* DAC Operation */
1632 aty_st_514(0x10, 0x01, info); /* PLL Control 1 */
1633 aty_st_514(0x70, 0x01, info); /* Misc Control 1 */
1634 aty_st_514(0x8f, 0x1f, info); /* PLL Ref. Divider Input */
1635 aty_st_514(0x03, 0x00, info); /* Sync Control */
1636 aty_st_514(0x05, 0x00, info); /* Power Management */
1637 aty_st_514(0x20, pll->m, info); /* F0 / M0 */
1638 aty_st_514(0x21, pll->n, info); /* F1 / N0 */
1639 break;
1640 }
1641 }
1642
1643
1644 static int aty_var_to_pll_18818(u32 period_in_ps, struct pll_18818 *pll)
1645 {
1646 u32 MHz100; /* in 0.01 MHz */
1647 u32 program_bits;
1648 u32 post_divider;
1649
1650 /* Calculate the programming word */
1651 MHz100 = 100000000 / period_in_ps;
1652
1653 program_bits = -1;
1654 post_divider = 1;
1655
1656 if (MHz100 > MAX_FREQ_2595) {
1657 MHz100 = MAX_FREQ_2595;
1658 return -EINVAL;
1659 } else if (MHz100 < ABS_MIN_FREQ_2595) {
1660 program_bits = 0; /* MHz100 = 257 */
1661 return -EINVAL;
1662 } else {
1663 while (MHz100 < MIN_FREQ_2595) {
1664 MHz100 *= 2;
1665 post_divider *= 2;
1666 }
1667 }
1668 MHz100 *= 1000;
1669 MHz100 = (REF_DIV_2595 * MHz100) / REF_FREQ_2595;
1670
1671 MHz100 += 500; /* + 0.5 round */
1672 MHz100 /= 1000;
1673
1674 if (program_bits == -1) {
1675 program_bits = MHz100 - N_ADJ_2595;
1676 switch (post_divider) {
1677 case 1:
1678 program_bits |= 0x0600;
1679 break;
1680 case 2:
1681 program_bits |= 0x0400;
1682 break;
1683 case 4:
1684 program_bits |= 0x0200;
1685 break;
1686 case 8:
1687 default:
1688 break;
1689 }
1690 }
1691
1692 program_bits |= STOP_BITS_2595;
1693
1694 pll->program_bits = program_bits;
1695 pll->locationAddr = 0;
1696 pll->post_divider = post_divider;
1697 pll->period_in_ps = period_in_ps;
1698
1699 return 0;
1700 }
1701
1702 static u32 aty_pll_18818_to_var(const struct pll_18818 *pll)
1703 {
1704 return(pll->period_in_ps); /* default for now */
1705 }
1706
1707 static void aty_set_pll18818(const struct fb_info_aty *info,
1708 const struct pll_18818 *pll)
1709 {
1710 u32 program_bits;
1711 u32 locationAddr;
1712
1713 u32 i;
1714
1715 u8 old_clock_cntl;
1716 u8 old_crtc_ext_disp;
1717
1718 old_clock_cntl = aty_ld_8(CLOCK_CNTL, info);
1719 aty_st_8(CLOCK_CNTL + info->clk_wr_offset, 0, info);
1720
1721 old_crtc_ext_disp = aty_ld_8(CRTC_GEN_CNTL + 3, info);
1722 aty_st_8(CRTC_GEN_CNTL + 3, old_crtc_ext_disp | (CRTC_EXT_DISP_EN >> 24),
1723 info);
1724
1725 mdelay(15); /* delay for 50 (15) ms */
1726
1727 program_bits = pll->program_bits;
1728 locationAddr = pll->locationAddr;
1729
1730 /* Program the clock chip */
1731 aty_st_8(CLOCK_CNTL + info->clk_wr_offset, 0, info); /* Strobe = 0 */
1732 aty_StrobeClock(info);
1733 aty_st_8(CLOCK_CNTL + info->clk_wr_offset, 1, info); /* Strobe = 0 */
1734 aty_StrobeClock(info);
1735
1736 aty_ICS2595_put1bit(1, info); /* Send start bits */
1737 aty_ICS2595_put1bit(0, info); /* Start bit */
1738 aty_ICS2595_put1bit(0, info); /* Read / ~Write */
1739
1740 for (i = 0; i < 5; i++) { /* Location 0..4 */
1741 aty_ICS2595_put1bit(locationAddr & 1, info);
1742 locationAddr >>= 1;
1743 }
1744
1745 for (i = 0; i < 8 + 1 + 2 + 2; i++) {
1746 aty_ICS2595_put1bit(program_bits & 1, info);
1747 program_bits >>= 1;
1748 }
1749
1750 udelay(1000); /* delay for 1 ms */
1751
1752 (void)aty_ld_8(DAC_REGS, info); /* Clear DAC Counter */
1753 aty_st_8(CRTC_GEN_CNTL + 3, old_crtc_ext_disp, info);
1754 aty_st_8(CLOCK_CNTL + info->clk_wr_offset, old_clock_cntl | CLOCK_STROBE,
1755 info);
1756
1757 mdelay(50); /* delay for 50 (15) ms */
1758 aty_st_8(CLOCK_CNTL + info->clk_wr_offset,
1759 ((pll->locationAddr & 0x0F) | CLOCK_STROBE), info);
1760
1761 return;
1762 }
1763
1764
1765 static int aty_var_to_pll_408(u32 period_in_ps, struct pll_18818 *pll)
1766 {
1767 u32 mhz100; /* in 0.01 MHz */
1768 u32 program_bits;
1769 /* u32 post_divider; */
1770 u32 mach64MinFreq, mach64MaxFreq, mach64RefFreq;
1771 u32 temp, tempB;
1772 u16 remainder, preRemainder;
1773 short divider = 0, tempA;
1774
1775 /* Calculate the programming word */
1776 mhz100 = 100000000 / period_in_ps;
1777 mach64MinFreq = MIN_FREQ_2595;
1778 mach64MaxFreq = MAX_FREQ_2595;
1779 mach64RefFreq = REF_FREQ_2595; /* 14.32 MHz */
1780
1781 /* Calculate program word */
1782 if (mhz100 == 0)
1783 program_bits = 0xFF;
1784 else {
1785 if (mhz100 < mach64MinFreq)
1786 mhz100 = mach64MinFreq;
1787 if (mhz100 > mach64MaxFreq)
1788 mhz100 = mach64MaxFreq;
1789
1790 while (mhz100 < (mach64MinFreq << 3)) {
1791 mhz100 <<= 1;
1792 divider += 0x40;
1793 }
1794
1795 temp = (unsigned int)mhz100;
1796 temp = (unsigned int)(temp * (MIN_N_408 + 2));
1797 temp -= ((short)(mach64RefFreq << 1));
1798
1799 tempA = MIN_N_408;
1800 preRemainder = 0xFFFF;
1801
1802 do {
1803 tempB = temp;
1804 remainder = tempB % mach64RefFreq;
1805 tempB = tempB / mach64RefFreq;
1806 if (((tempB & 0xFFFF) <= 255) && (remainder <= preRemainder)) {
1807 preRemainder = remainder;
1808 divider &= ~0x3f;
1809 divider |= tempA;
1810 divider = (divider & 0x00FF) + ((tempB & 0xFF) << 8);
1811 }
1812 temp += mhz100;
1813 tempA++;
1814 } while(tempA <= 32);
1815
1816 program_bits = divider;
1817 }
1818
1819 pll->program_bits = program_bits;
1820 pll->locationAddr = 0;
1821 pll->post_divider = divider; /* fuer nix */
1822 pll->period_in_ps = period_in_ps;
1823
1824 return 0;
1825 }
1826
1827 static u32 aty_pll_408_to_var(const struct pll_18818 *pll)
1828 {
1829 return(pll->period_in_ps); /* default for now */
1830 }
1831
1832 static void aty_set_pll_408(const struct fb_info_aty *info,
1833 const struct pll_18818 *pll)
1834 {
1835 u32 program_bits;
1836 u32 locationAddr;
1837
1838 u8 tmpA, tmpB, tmpC;
1839 char old_crtc_ext_disp;
1840
1841 old_crtc_ext_disp = aty_ld_8(CRTC_GEN_CNTL + 3, info);
1842 aty_st_8(CRTC_GEN_CNTL + 3, old_crtc_ext_disp | (CRTC_EXT_DISP_EN >> 24),
1843 info);
1844
1845 program_bits = pll->program_bits;
1846 locationAddr = pll->locationAddr;
1847
1848 /* Program clock */
1849 aty_dac_waste4(info);
1850 tmpB = aty_ld_8(DAC_REGS + 2, info) | 1;
1851 aty_dac_waste4(info);
1852 aty_st_8(DAC_REGS + 2, tmpB, info);
1853
1854 tmpA = tmpB;
1855 tmpC = tmpA;
1856 tmpA |= 8;
1857 tmpB = 1;
1858
1859 aty_st_8(DAC_REGS, tmpB, info);
1860 aty_st_8(DAC_REGS + 2, tmpA, info);
1861
1862 udelay(400); /* delay for 400 us */
1863
1864 locationAddr = (locationAddr << 2) + 0x40;
1865 tmpB = locationAddr;
1866 tmpA = program_bits >> 8;
1867
1868 aty_st_8(DAC_REGS, tmpB, info);
1869 aty_st_8(DAC_REGS + 2, tmpA, info);
1870
1871 tmpB = locationAddr + 1;
1872 tmpA = (u8)program_bits;
1873
1874 aty_st_8(DAC_REGS, tmpB, info);
1875 aty_st_8(DAC_REGS + 2, tmpA, info);
1876
1877 tmpB = locationAddr + 2;
1878 tmpA = 0x77;
1879
1880 aty_st_8(DAC_REGS, tmpB, info);
1881 aty_st_8(DAC_REGS + 2, tmpA, info);
1882
1883 udelay(400); /* delay for 400 us */
1884 tmpA = tmpC & (~(1 | 8));
1885 tmpB = 1;
1886
1887 aty_st_8(DAC_REGS, tmpB, info);
1888 aty_st_8(DAC_REGS + 2, tmpA, info);
1889
1890 (void)aty_ld_8(DAC_REGS, info); /* Clear DAC Counter */
1891 aty_st_8(CRTC_GEN_CNTL + 3, old_crtc_ext_disp, info);
1892
1893 return;
1894 }
1895
1896
1897 static int aty_var_to_pll_1703(u32 period_in_ps, struct pll_18818 *pll)
1898 {
1899 u32 mhz100; /* in 0.01 MHz */
1900 u32 program_bits;
1901 /* u32 post_divider; */
1902 u32 mach64MinFreq, mach64MaxFreq, mach64RefFreq;
1903 u32 temp, tempB;
1904 u16 remainder, preRemainder;
1905 short divider = 0, tempA;
1906
1907 /* Calculate the programming word */
1908 mhz100 = 100000000 / period_in_ps;
1909 mach64MinFreq = MIN_FREQ_2595;
1910 mach64MaxFreq = MAX_FREQ_2595;
1911 mach64RefFreq = REF_FREQ_2595; /* 14.32 MHz */
1912
1913 /* Calculate program word */
1914 if (mhz100 == 0)
1915 program_bits = 0xE0;
1916 else {
1917 if (mhz100 < mach64MinFreq)
1918 mhz100 = mach64MinFreq;
1919 if (mhz100 > mach64MaxFreq)
1920 mhz100 = mach64MaxFreq;
1921
1922 divider = 0;
1923 while (mhz100 < (mach64MinFreq << 3)) {
1924 mhz100 <<= 1;
1925 divider += 0x20;
1926 }
1927
1928 temp = (unsigned int)(mhz100);
1929 temp = (unsigned int)(temp * (MIN_N_1703 + 2));
1930 temp -= (short)(mach64RefFreq << 1);
1931
1932 tempA = MIN_N_1703;
1933 preRemainder = 0xffff;
1934
1935 do {
1936 tempB = temp;
1937 remainder = tempB % mach64RefFreq;
1938 tempB = tempB / mach64RefFreq;
1939
1940 if ((tempB & 0xffff) <= 127 && (remainder <= preRemainder)) {
1941 preRemainder = remainder;
1942 divider &= ~0x1f;
1943 divider |= tempA;
1944 divider = (divider & 0x00ff) + ((tempB & 0xff) << 8);
1945 }
1946
1947 temp += mhz100;
1948 tempA++;
1949 } while (tempA <= (MIN_N_1703 << 1));
1950
1951 program_bits = divider;
1952 }
1953
1954 pll->program_bits = program_bits;
1955 pll->locationAddr = 0;
1956 pll->post_divider = divider; /* fuer nix */
1957 pll->period_in_ps = period_in_ps;
1958
1959 return 0;
1960 }
1961
1962 static u32 aty_pll_1703_to_var(const struct pll_18818 *pll)
1963 {
1964 return(pll->period_in_ps); /* default for now */
1965 }
1966
1967 static void aty_set_pll_1703(const struct fb_info_aty *info,
1968 const struct pll_18818 *pll)
1969 {
1970 u32 program_bits;
1971 u32 locationAddr;
1972
1973 char old_crtc_ext_disp;
1974
1975 old_crtc_ext_disp = aty_ld_8(CRTC_GEN_CNTL + 3, info);
1976 aty_st_8(CRTC_GEN_CNTL + 3, old_crtc_ext_disp | (CRTC_EXT_DISP_EN >> 24),
1977 info);
1978
1979 program_bits = pll->program_bits;
1980 locationAddr = pll->locationAddr;
1981
1982 /* Program clock */
1983 aty_dac_waste4(info);
1984
1985 (void)aty_ld_8(DAC_REGS + 2, info);
1986 aty_st_8(DAC_REGS+2, (locationAddr << 1) + 0x20, info);
1987 aty_st_8(DAC_REGS+2, 0, info);
1988 aty_st_8(DAC_REGS+2, (program_bits & 0xFF00) >> 8, info);
1989 aty_st_8(DAC_REGS+2, (program_bits & 0xFF), info);
1990
1991 (void)aty_ld_8(DAC_REGS, info); /* Clear DAC Counter */
1992 aty_st_8(CRTC_GEN_CNTL + 3, old_crtc_ext_disp, info);
1993
1994 return;
1995 }
1996
1997
1998 static int aty_var_to_pll_8398(u32 period_in_ps, struct pll_18818 *pll)
1999 {
2000
2001 u32 tempA, tempB, fOut, longMHz100, diff, preDiff;
2002
2003 u32 mhz100; /* in 0.01 MHz */
2004 u32 program_bits;
2005 /* u32 post_divider; */
2006 u32 mach64MinFreq, mach64MaxFreq, mach64RefFreq;
2007 u16 m, n, k=0, save_m, save_n, twoToKth;
2008
2009 /* Calculate the programming word */
2010 mhz100 = 100000000 / period_in_ps;
2011 mach64MinFreq = MIN_FREQ_2595;
2012 mach64MaxFreq = MAX_FREQ_2595;
2013 mach64RefFreq = REF_FREQ_2595; /* 14.32 MHz */
2014
2015 save_m = 0;
2016 save_n = 0;
2017
2018 /* Calculate program word */
2019 if (mhz100 == 0)
2020 program_bits = 0xE0;
2021 else
2022 {
2023 if (mhz100 < mach64MinFreq)
2024 mhz100 = mach64MinFreq;
2025 if (mhz100 > mach64MaxFreq)
2026 mhz100 = mach64MaxFreq;
2027
2028 longMHz100 = mhz100 * 256 / 100; /* 8 bit scale this */
2029
2030 while (mhz100 < (mach64MinFreq << 3))
2031 {
2032 mhz100 <<= 1;
2033 k++;
2034 }
2035
2036 twoToKth = 1 << k;
2037 diff = 0;
2038 preDiff = 0xFFFFFFFF;
2039
2040 for (m = MIN_M; m <= MAX_M; m++)
2041 {
2042 for (n = MIN_N; n <= MAX_N; n++)
2043 {
2044 tempA = (14.31818 * 65536);
2045 tempA *= (n + 8); /* 43..256 */
2046 tempB = twoToKth * 256;
2047 tempB *= (m + 2); /* 4..32 */
2048 fOut = tempA / tempB; /* 8 bit scale */
2049
2050 if (longMHz100 > fOut)
2051 diff = longMHz100 - fOut;
2052 else
2053 diff = fOut - longMHz100;
2054
2055 if (diff < preDiff)
2056 {
2057 save_m = m;
2058 save_n = n;
2059 preDiff = diff;
2060 }
2061 }
2062 }
2063
2064 program_bits = (k << 6) + (save_m) + (save_n << 8);
2065 }
2066
2067 pll->program_bits = program_bits;
2068 pll->locationAddr = 0;
2069 pll->post_divider = 0;
2070 pll->period_in_ps = period_in_ps;
2071
2072 return 0;
2073 }
2074
2075 static u32 aty_pll_8398_to_var(const struct pll_18818 *pll)
2076 {
2077 return(pll->period_in_ps); /* default for now */
2078 }
2079
2080 static void aty_set_pll_8398(const struct fb_info_aty *info,
2081 const struct pll_18818 *pll)
2082 {
2083 u32 program_bits;
2084 u32 locationAddr;
2085
2086 char old_crtc_ext_disp;
2087 char tmp;
2088
2089 old_crtc_ext_disp = aty_ld_8(CRTC_GEN_CNTL + 3, info);
2090 aty_st_8(CRTC_GEN_CNTL + 3, old_crtc_ext_disp | (CRTC_EXT_DISP_EN >> 24),
2091 info);
2092
2093 program_bits = pll->program_bits;
2094 locationAddr = pll->locationAddr;
2095
2096 /* Program clock */
2097 tmp = aty_ld_8(DAC_CNTL, info);
2098 aty_st_8(DAC_CNTL, tmp | DAC_EXT_SEL_RS2 | DAC_EXT_SEL_RS3, info);
2099
2100 aty_st_8(DAC_REGS, locationAddr, info);
2101 aty_st_8(DAC_REGS+1, (program_bits & 0xff00) >> 8, info);
2102 aty_st_8(DAC_REGS+1, (program_bits & 0xff), info);
2103
2104 tmp = aty_ld_8(DAC_CNTL, info);
2105 aty_st_8(DAC_CNTL, (tmp & ~DAC_EXT_SEL_RS2) | DAC_EXT_SEL_RS3, info);
2106
2107 (void)aty_ld_8(DAC_REGS, info); /* Clear DAC Counter */
2108 aty_st_8(CRTC_GEN_CNTL + 3, old_crtc_ext_disp, info);
2109
2110 return;
2111 }
2112
2113
2114 static int aty_var_to_pll_514(u32 vclk_per, struct pll_gx *pll)
2115 {
2116 /*
2117 * FIXME: use real calculations instead of using fixed values from the old
2118 * driver
2119 */
2120 static struct {
2121 u32 limit; /* pixlock rounding limit (arbitrary) */
2122 u8 m; /* (df<<6) | vco_div_count */
2123 u8 n; /* ref_div_count */
2124 } RGB514_clocks[7] = {
2125 { 8000, (3<<6) | 20, 9 }, /* 7395 ps / 135.2273 MHz */
2126 { 10000, (1<<6) | 19, 3 }, /* 9977 ps / 100.2273 MHz */
2127 { 13000, (1<<6) | 2, 3 }, /* 12509 ps / 79.9432 MHz */
2128 { 14000, (2<<6) | 8, 7 }, /* 13394 ps / 74.6591 MHz */
2129 { 16000, (1<<6) | 44, 6 }, /* 15378 ps / 65.0284 MHz */
2130 { 25000, (1<<6) | 15, 5 }, /* 17460 ps / 57.2727 MHz */
2131 { 50000, (0<<6) | 53, 7 }, /* 33145 ps / 30.1705 MHz */
2132 };
2133 int i;
2134
2135 for (i = 0; i < sizeof(RGB514_clocks)/sizeof(*RGB514_clocks); i++)
2136 if (vclk_per <= RGB514_clocks[i].limit) {
2137 pll->m = RGB514_clocks[i].m;
2138 pll->n = RGB514_clocks[i].n;
2139 return 0;
2140 }
2141 return -EINVAL;
2142 }
2143
2144
2145 static void aty_StrobeClock(const struct fb_info_aty *info)
2146 {
2147 u8 tmp;
2148
2149 udelay(26);
2150
2151 tmp = aty_ld_8(CLOCK_CNTL, info);
2152 aty_st_8(CLOCK_CNTL + info->clk_wr_offset, tmp | CLOCK_STROBE, info);
2153
2154 return;
2155 }
2156
2157
2158 static void aty_ICS2595_put1bit(u8 data, const struct fb_info_aty *info)
2159 {
2160 u8 tmp;
2161
2162 data &= 0x01;
2163 tmp = aty_ld_8(CLOCK_CNTL, info);
2164 aty_st_8(CLOCK_CNTL + info->clk_wr_offset, (tmp & ~0x04) | (data << 2),
2165 info);
2166
2167 tmp = aty_ld_8(CLOCK_CNTL, info);
2168 aty_st_8(CLOCK_CNTL + info->clk_wr_offset, (tmp & ~0x08) | (0 << 3), info);
2169
2170 aty_StrobeClock(info);
2171
2172 tmp = aty_ld_8(CLOCK_CNTL, info);
2173 aty_st_8(CLOCK_CNTL + info->clk_wr_offset, (tmp & ~0x08) | (1 << 3), info);
2174
2175 aty_StrobeClock(info);
2176
2177 return;
2178 }
2179
2180
2181 static u32 aty_pll_gx_to_var(const struct pll_gx *pll,
2182 const struct fb_info_aty *info)
2183 {
2184 u8 df, vco_div_count, ref_div_count;
2185
2186 df = pll->m >> 6;
2187 vco_div_count = pll->m & 0x3f;
2188 ref_div_count = pll->n;
2189
2190 return ((info->ref_clk_per*ref_div_count)<<(3-df))/(vco_div_count+65);
2191 }
2192
2193
2194 /*
2195 * PLL programming (Mach64 CT family)
2196 */
2197
2198 static void aty_set_pll_ct(const struct fb_info_aty *info,
2199 const struct pll_ct *pll)
2200 {
2201 aty_st_pll(PLL_REF_DIV, pll->pll_ref_div, info);
2202 aty_st_pll(PLL_GEN_CNTL, pll->pll_gen_cntl, info);
2203 aty_st_pll(MCLK_FB_DIV, pll->mclk_fb_div, info);
2204 aty_st_pll(PLL_VCLK_CNTL, pll->pll_vclk_cntl, info);
2205 aty_st_pll(VCLK_POST_DIV, pll->vclk_post_div, info);
2206 aty_st_pll(VCLK0_FB_DIV, pll->vclk_fb_div, info);
2207 aty_st_pll(PLL_EXT_CNTL, pll->pll_ext_cntl, info);
2208
2209 if (!(Gx == GX_CHIP_ID || Gx == CX_CHIP_ID || Gx == CT_CHIP_ID ||
2210 Gx == ET_CHIP_ID ||
2211 ((Gx == VT_CHIP_ID || Gx == GT_CHIP_ID) && !(Rev & 0x07)))) {
2212 if (info->ram_type >= SDRAM)
2213 aty_st_pll(DLL_CNTL, 0xa6, info);
2214 else
2215 aty_st_pll(DLL_CNTL, 0xa0, info);
2216 aty_st_pll(VFC_CNTL, 0x1b, info);
2217 aty_st_le32(DSP_CONFIG, pll->dsp_config, info);
2218 aty_st_le32(DSP_ON_OFF, pll->dsp_on_off, info);
2219 }
2220 }
2221
2222 static int aty_dsp_gt(const struct fb_info_aty *info, u8 bpp,
2223 struct pll_ct *pll)
2224 {
2225 u32 dsp_xclks_per_row, dsp_loop_latency, dsp_precision, dsp_off, dsp_on;
2226 u32 xclks_per_row, fifo_off, fifo_on, y, fifo_size, page_size;
2227
2228 /* xclocks_per_row<<11 */
2229 xclks_per_row = (pll->mclk_fb_div*pll->vclk_post_div_real*64<<11)/
2230 (pll->vclk_fb_div*pll->mclk_post_div_real*bpp);
2231 if (xclks_per_row < (1<<11))
2232 FAIL("Dotclock to high");
2233 if (Gx == GT_CHIP_ID || Gx == GU_CHIP_ID || Gx == VT_CHIP_ID ||
2234 Gx == VU_CHIP_ID || Gx == GV_CHIP_ID || Gx == GW_CHIP_ID ||
2235 Gx == GZ_CHIP_ID) {
2236 fifo_size = 24;
2237 dsp_loop_latency = 0;
2238 } else {
2239 fifo_size = 32;
2240 dsp_loop_latency = 2;
2241 }
2242 dsp_precision = 0;
2243 y = (xclks_per_row*fifo_size)>>11;
2244 while (y) {
2245 y >>= 1;
2246 dsp_precision++;
2247 }
2248 dsp_precision -= 5;
2249 /* fifo_off<<6 */
2250 fifo_off = ((xclks_per_row*(fifo_size-1))>>5)+(3<<6);
2251
2252 if (info->total_vram > 1*1024*1024) {
2253 if (info->ram_type >= SDRAM) {
2254 /* >1 MB SDRAM */
2255 dsp_loop_latency += 8;
2256 page_size = 8;
2257 } else {
2258 /* >1 MB DRAM */
2259 dsp_loop_latency += 6;
2260 page_size = 9;
2261 }
2262 } else {
2263 if (info->ram_type >= SDRAM) {
2264 /* <2 MB SDRAM */
2265 dsp_loop_latency += 9;
2266 page_size = 10;
2267 } else {
2268 /* <2 MB DRAM */
2269 dsp_loop_latency += 8;
2270 page_size = 10;
2271 }
2272 }
2273 /* fifo_on<<6 */
2274 if (xclks_per_row >= (page_size<<11))
2275 fifo_on = ((2*page_size+1)<<6)+(xclks_per_row>>5);
2276 else
2277 fifo_on = (3*page_size+2)<<6;
2278
2279 dsp_xclks_per_row = xclks_per_row>>dsp_precision;
2280 dsp_on = fifo_on>>dsp_precision;
2281 dsp_off = fifo_off>>dsp_precision;
2282
2283 pll->dsp_config = (dsp_xclks_per_row & 0x3fff) |
2284 ((dsp_loop_latency & 0xf)<<16) |
2285 ((dsp_precision & 7)<<20);
2286 pll->dsp_on_off = (dsp_on & 0x7ff) | ((dsp_off & 0x7ff)<<16);
2287 return 0;
2288 }
2289
2290 static int aty_valid_pll_ct(const struct fb_info_aty *info, u32 vclk_per,
2291 struct pll_ct *pll)
2292 {
2293 u32 q, x; /* x is a workaround for sparc64-linux-gcc */
2294 x = x; /* x is a workaround for sparc64-linux-gcc */
2295
2296 pll->pll_ref_div = info->pll_per*2*255/info->ref_clk_per;
2297
2298 /* FIXME: use the VTB/GTB /3 post divider if it's better suited */
2299 q = info->ref_clk_per*pll->pll_ref_div*4/info->mclk_per; /* actually 8*q */
2300 if (q < 16*8 || q > 255*8)
2301 FAIL("mclk out of range");
2302 else if (q < 32*8)
2303 pll->mclk_post_div_real = 8;
2304 else if (q < 64*8)
2305 pll->mclk_post_div_real = 4;
2306 else if (q < 128*8)
2307 pll->mclk_post_div_real = 2;
2308 else
2309 pll->mclk_post_div_real = 1;
2310 pll->mclk_fb_div = q*pll->mclk_post_div_real/8;
2311
2312 /* FIXME: use the VTB/GTB /{3,6,12} post dividers if they're better suited */
2313 q = info->ref_clk_per*pll->pll_ref_div*4/vclk_per; /* actually 8*q */
2314 if (q < 16*8 || q > 255*8)
2315 FAIL("vclk out of range");
2316 else if (q < 32*8)
2317 pll->vclk_post_div_real = 8;
2318 else if (q < 64*8)
2319 pll->vclk_post_div_real = 4;
2320 else if (q < 128*8)
2321 pll->vclk_post_div_real = 2;
2322 else
2323 pll->vclk_post_div_real = 1;
2324 pll->vclk_fb_div = q*pll->vclk_post_div_real/8;
2325 return 0;
2326 }
2327
2328 static void aty_calc_pll_ct(const struct fb_info_aty *info, struct pll_ct *pll)
2329 {
2330 u8 mpostdiv = 0;
2331 u8 vpostdiv = 0;
2332
2333 if ((((Gx == GT_CHIP_ID) && (Rev & 0x03)) || (Gx == GU_CHIP_ID) ||
2334 (Gx == GV_CHIP_ID) || (Gx == GW_CHIP_ID) || (Gx == GZ_CHIP_ID) ||
2335 (Gx == LG_CHIP_ID) || (Gx == GB_CHIP_ID) || (Gx == GD_CHIP_ID) ||
2336 (Gx == GI_CHIP_ID) || (Gx == GP_CHIP_ID) || (Gx == GQ_CHIP_ID) ||
2337 (Gx == VU_CHIP_ID)) && (info->ram_type >= SDRAM))
2338 pll->pll_gen_cntl = 0x04;
2339 else
2340 pll->pll_gen_cntl = 0x84;
2341
2342 switch (pll->mclk_post_div_real) {
2343 case 1:
2344 mpostdiv = 0;
2345 break;
2346 case 2:
2347 mpostdiv = 1;
2348 break;
2349 case 3:
2350 mpostdiv = 4;
2351 break;
2352 case 4:
2353 mpostdiv = 2;
2354 break;
2355 case 8:
2356 mpostdiv = 3;
2357 break;
2358 }
2359 pll->pll_gen_cntl |= mpostdiv<<4; /* mclk */
2360
2361 if (Gx == VT_CHIP_ID && (Rev == 0x40 || Rev == 0x48))
2362 pll->pll_ext_cntl = 0;
2363 else
2364 pll->pll_ext_cntl = mpostdiv; /* xclk == mclk */
2365
2366 switch (pll->vclk_post_div_real) {
2367 case 2:
2368 vpostdiv = 1;
2369 break;
2370 case 3:
2371 pll->pll_ext_cntl |= 0x10;
2372 case 1:
2373 vpostdiv = 0;
2374 break;
2375 case 6:
2376 pll->pll_ext_cntl |= 0x10;
2377 case 4:
2378 vpostdiv = 2;
2379 break;
2380 case 12:
2381 pll->pll_ext_cntl |= 0x10;
2382 case 8:
2383 vpostdiv = 3;
2384 break;
2385 }
2386
2387 pll->pll_vclk_cntl = 0x03; /* VCLK = PLL_VCLK/VCLKx_POST */
2388 pll->vclk_post_div = vpostdiv;
2389 }
2390
2391 static int aty_var_to_pll_ct(const struct fb_info_aty *info, u32 vclk_per,
2392 u8 bpp, struct pll_ct *pll)
2393 {
2394 int err;
2395
2396 if ((err = aty_valid_pll_ct(info, vclk_per, pll)))
2397 return err;
2398 if (!(Gx == GX_CHIP_ID || Gx == CX_CHIP_ID || Gx == CT_CHIP_ID ||
2399 Gx == ET_CHIP_ID ||
2400 ((Gx == VT_CHIP_ID || Gx == GT_CHIP_ID) && !(Rev & 0x07)))) {
2401 if ((err = aty_dsp_gt(info, bpp, pll)))
2402 return err;
2403 }
2404 aty_calc_pll_ct(info, pll);
2405 return 0;
2406 }
2407
2408 static u32 aty_pll_ct_to_var(const struct pll_ct *pll,
2409 const struct fb_info_aty *info)
2410 {
2411 u32 ref_clk_per = info->ref_clk_per;
2412 u8 pll_ref_div = pll->pll_ref_div;
2413 u8 vclk_fb_div = pll->vclk_fb_div;
2414 u8 vclk_post_div = pll->vclk_post_div_real;
2415
2416 return ref_clk_per*pll_ref_div*vclk_post_div/vclk_fb_div/2;
2417 }
2418
2419 /* ------------------------------------------------------------------------- */
2420
2421 static void atyfb_set_par(const struct atyfb_par *par,
2422 struct fb_info_aty *info)
2423 {
2424 u32 i;
2425 int accelmode;
2426 int muxmode;
2427 u8 tmp;
2428
2429 accelmode = par->accel_flags; /* hack */
2430
2431 info->current_par = *par;
2432
2433 if (info->blitter_may_be_busy)
2434 wait_for_idle(info);
2435 tmp = aty_ld_8(CRTC_GEN_CNTL + 3, info);
2436 aty_set_crtc(info, &par->crtc);
2437 aty_st_8(CLOCK_CNTL + info->clk_wr_offset, 0, info);
2438 /* better call aty_StrobeClock ?? */
2439 aty_st_8(CLOCK_CNTL + info->clk_wr_offset, CLOCK_STROBE, info);
2440
2441 if ((Gx == GX_CHIP_ID) || (Gx == CX_CHIP_ID)) {
2442 switch (info->dac_subtype) {
2443 case DAC_IBMRGB514:
2444 aty_set_dac_514(info, par->crtc.bpp);
2445 break;
2446 case DAC_ATI68860_B:
2447 case DAC_ATI68860_C:
2448 muxmode = aty_set_dac_ATI68860_B(info, par->crtc.bpp,
2449 accelmode);
2450 aty_st_le32(BUS_CNTL, 0x890e20f1, info);
2451 aty_st_le32(DAC_CNTL, 0x47052100, info);
2452 break;
2453 case DAC_ATT20C408:
2454 muxmode = aty_set_dac_ATT21C498(info, &par->pll.ics2595,
2455 par->crtc.bpp);
2456 aty_st_le32(BUS_CNTL, 0x890e20f1, info);
2457 aty_st_le32(DAC_CNTL, 0x00072000, info);
2458 break;
2459 case DAC_ATT21C498:
2460 muxmode = aty_set_dac_ATT21C498(info, &par->pll.ics2595,
2461 par->crtc.bpp);
2462 aty_st_le32(BUS_CNTL, 0x890e20f1, info);
2463 aty_st_le32(DAC_CNTL, 0x00072000, info);
2464 break;
2465 default:
2466 printk(" atyfb_set_par: DAC type not implemented yet!\n");
2467 aty_st_le32(BUS_CNTL, 0x890e20f1, info);
2468 aty_st_le32(DAC_CNTL, 0x47052100, info);
2469 /* new in 2.2.3p1 from Geert. ???????? */
2470 aty_st_le32(BUS_CNTL, 0x590e10ff, info);
2471 aty_st_le32(DAC_CNTL, 0x47012100, info);
2472 break;
2473 }
2474
2475 switch (info->clk_type) {
2476 case CLK_ATI18818_1:
2477 aty_set_pll18818(info, &par->pll.ics2595);
2478 break;
2479 case CLK_STG1703:
2480 aty_set_pll_1703(info, &par->pll.ics2595);
2481 break;
2482 case CLK_CH8398:
2483 aty_set_pll_8398(info, &par->pll.ics2595);
2484 break;
2485 case CLK_ATT20C408:
2486 aty_set_pll_408(info, &par->pll.ics2595);
2487 break;
2488 case CLK_IBMRGB514:
2489 aty_set_pll_gx(info, &par->pll.gx);
2490 break;
2491 default:
2492 printk(" atyfb_set_par: CLK type not implemented yet!");
2493 break;
2494 }
2495
2496 /* Don't forget MEM_CNTL */
2497 i = aty_ld_le32(MEM_CNTL, info) & 0xf0ffffff;
2498 switch (par->crtc.bpp) {
2499 case 8:
2500 i |= 0x02000000;
2501 break;
2502 case 16:
2503 i |= 0x03000000;
2504 break;
2505 case 32:
2506 i |= 0x06000000;
2507 break;
2508 }
2509 aty_st_le32(MEM_CNTL, i, info);
2510
2511 } else {
2512 aty_set_pll_ct(info, &par->pll.ct);
2513 i = aty_ld_le32(MEM_CNTL, info) & 0xf00fffff;
2514 if (!(Gx == VT_CHIP_ID && (Rev == 0x40 || Rev == 0x48)))
2515 i |= info->mem_refresh_rate << 20;
2516 switch (par->crtc.bpp) {
2517 case 8:
2518 case 24:
2519 i |= 0x00000000;
2520 break;
2521 case 16:
2522 i |= 0x04000000;
2523 break;
2524 case 32:
2525 i |= 0x08000000;
2526 break;
2527 }
2528 if ((Gx == CT_CHIP_ID) || (Gx == ET_CHIP_ID)) {
2529 aty_st_le32(DAC_CNTL, 0x87010184, info);
2530 aty_st_le32(BUS_CNTL, 0x680000f9, info);
2531 } else if ((Gx == VT_CHIP_ID) || (Gx == VU_CHIP_ID)) {
2532 aty_st_le32(DAC_CNTL, 0x87010184, info);
2533 aty_st_le32(BUS_CNTL, 0x680000f9, info);
2534 } else if ((Gx == LN_CHIP_ID) || (Gx == LM_CHIP_ID)) {
2535 aty_st_le32(DAC_CNTL, 0x80010102, info);
2536 aty_st_le32(BUS_CNTL, 0x7b33a040, info);
2537 } else {
2538 /* GT */
2539 aty_st_le32(DAC_CNTL, 0x86010102, info);
2540 aty_st_le32(BUS_CNTL, 0x7b23a040, info);
2541 aty_st_le32(EXT_MEM_CNTL,
2542 aty_ld_le32(EXT_MEM_CNTL, info) | 0x5000001, info);
2543 }
2544 aty_st_le32(MEM_CNTL, i, info);
2545 }
2546 aty_st_8(DAC_MASK, 0xff, info);
2547
2548 /* Initialize the graphics engine */
2549 if (par->accel_flags & FB_ACCELF_TEXT)
2550 init_engine(par, info);
2551
2552 #ifdef CONFIG_FB_COMPAT_XPMAC
2553 if (!console_fb_info || console_fb_info == &info->fb_info) {
2554 struct fb_var_screeninfo var;
2555 int vmode, cmode;
2556 display_info.height = ((par->crtc.v_tot_disp>>16) & 0x7ff)+1;
2557 display_info.width = (((par->crtc.h_tot_disp>>16) & 0xff)+1)*8;
2558 display_info.depth = par->crtc.bpp;
2559 display_info.pitch = par->crtc.vxres*par->crtc.bpp/8;
2560 atyfb_encode_var(&var, par, info);
2561 if (mac_var_to_vmode(&var, &vmode, &cmode))
2562 display_info.mode = 0;
2563 else
2564 display_info.mode = vmode;
2565 strcpy(display_info.name, atyfb_name);
2566 display_info.fb_address = info->frame_buffer_phys;
2567 display_info.cmap_adr_address = info->ati_regbase_phys+0xc0;
2568 display_info.cmap_data_address = info->ati_regbase_phys+0xc1;
2569 display_info.disp_reg_address = info->ati_regbase_phys;
2570 }
2571 #endif /* CONFIG_FB_COMPAT_XPMAC */
2572 }
2573
2574 static int atyfb_decode_var(const struct fb_var_screeninfo *var,
2575 struct atyfb_par *par,
2576 const struct fb_info_aty *info)
2577 {
2578 int err;
2579
2580 if ((err = aty_var_to_crtc(info, var, &par->crtc)))
2581 return err;
2582 if ((Gx == GX_CHIP_ID) || (Gx == CX_CHIP_ID))
2583 switch (info->clk_type) {
2584 case CLK_ATI18818_1:
2585 err = aty_var_to_pll_18818(var->pixclock, &par->pll.ics2595);
2586 break;
2587 case CLK_STG1703:
2588 err = aty_var_to_pll_1703(var->pixclock, &par->pll.ics2595);
2589 break;
2590 case CLK_CH8398:
2591 err = aty_var_to_pll_8398(var->pixclock, &par->pll.ics2595);
2592 break;
2593 case CLK_ATT20C408:
2594 err = aty_var_to_pll_408(var->pixclock, &par->pll.ics2595);
2595 break;
2596 case CLK_IBMRGB514:
2597 err = aty_var_to_pll_514(var->pixclock, &par->pll.gx);
2598 break;
2599 }
2600 else
2601 err = aty_var_to_pll_ct(info, var->pixclock, par->crtc.bpp,
2602 &par->pll.ct);
2603 if (err)
2604 return err;
2605
2606 if (var->accel_flags & FB_ACCELF_TEXT)
2607 par->accel_flags = FB_ACCELF_TEXT;
2608 else
2609 par->accel_flags = 0;
2610
2611 #if 0 /* fbmon is not done. uncomment for 2.5.x -brad */
2612 if (!fbmon_valid_timings(var->pixclock, htotal, vtotal, info))
2613 return -EINVAL;
2614 #endif
2615
2616 return 0;
2617 }
2618
2619 static int atyfb_encode_var(struct fb_var_screeninfo *var,
2620 const struct atyfb_par *par,
2621 const struct fb_info_aty *info)
2622 {
2623 int err;
2624
2625 memset(var, 0, sizeof(struct fb_var_screeninfo));
2626
2627 if ((err = aty_crtc_to_var(&par->crtc, var)))
2628 return err;
2629 if ((Gx == GX_CHIP_ID) || (Gx == CX_CHIP_ID))
2630 switch (info->clk_type) {
2631 case CLK_ATI18818_1:
2632 var->pixclock = aty_pll_18818_to_var(&par->pll.ics2595);
2633 break;
2634 case CLK_STG1703:
2635 var->pixclock = aty_pll_1703_to_var(&par->pll.ics2595);
2636 break;
2637 case CLK_CH8398:
2638 var->pixclock = aty_pll_8398_to_var(&par->pll.ics2595);
2639 break;
2640 case CLK_ATT20C408:
2641 var->pixclock = aty_pll_408_to_var(&par->pll.ics2595);
2642 break;
2643 case CLK_IBMRGB514:
2644 var->pixclock = aty_pll_gx_to_var(&par->pll.gx, info);
2645 break;
2646 }
2647 else
2648 var->pixclock = aty_pll_ct_to_var(&par->pll.ct, info);
2649
2650 var->height = -1;
2651 var->width = -1;
2652 var->accel_flags = par->accel_flags;
2653
2654 return 0;
2655 }
2656
2657
2658
2659 static void set_off_pitch(struct atyfb_par *par,
2660 const struct fb_info_aty *info)
2661 {
2662 u32 xoffset = par->crtc.xoffset;
2663 u32 yoffset = par->crtc.yoffset;
2664 u32 vxres = par->crtc.vxres;
2665 u32 bpp = par->crtc.bpp;
2666
2667 par->crtc.off_pitch = ((yoffset*vxres+xoffset)*bpp/64) | (vxres<<19);
2668 aty_st_le32(CRTC_OFF_PITCH, par->crtc.off_pitch, info);
2669 }
2670
2671
2672 /*
2673 * Open/Release the frame buffer device
2674 */
2675
2676 static int atyfb_open(struct fb_info *info, int user)
2677
2678 {
2679 #ifdef __sparc__
2680 struct fb_info_aty *fb = (struct fb_info_aty *)info;
2681
2682 if (user) {
2683 fb->open++;
2684 fb->mmaped = 0;
2685 fb->vtconsole = -1;
2686 } else {
2687 fb->consolecnt++;
2688 }
2689 #endif
2690 return(0);
2691 }
2692
2693 struct fb_var_screeninfo default_var = {
2694 /* 640x480, 60 Hz, Non-Interlaced (25.175 MHz dotclock) */
2695 640, 480, 640, 480, 0, 0, 8, 0,
2696 {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
2697 0, 0, -1, -1, 0, 39722, 48, 16, 33, 10, 96, 2,
2698 0, FB_VMODE_NONINTERLACED
2699 };
2700
2701 static int atyfb_release(struct fb_info *info, int user)
2702 {
2703 #ifdef __sparc__
2704 struct fb_info_aty *fb = (struct fb_info_aty *)info;
2705
2706 if (user) {
2707 fb->open--;
2708 udelay(1000);
2709 wait_for_idle(fb);
2710 if (!fb->open) {
2711 int was_mmaped = fb->mmaped;
2712
2713 fb->mmaped = 0;
2714 if (fb->vtconsole != -1)
2715 vt_cons[fb->vtconsole]->vc_mode = KD_TEXT;
2716 fb->vtconsole = -1;
2717
2718 if (was_mmaped) {
2719 struct fb_var_screeninfo var;
2720
2721 /* Now reset the default display config, we have no
2722 * idea what the program(s) which mmap'd the chip did
2723 * to the configuration, nor whether it restored it
2724 * correctly.
2725 */
2726 var = default_var;
2727 if (noaccel)
2728 var.accel_flags &= ~FB_ACCELF_TEXT;
2729 else
2730 var.accel_flags |= FB_ACCELF_TEXT;
2731 if (var.yres == var.yres_virtual) {
2732 u32 vram = (fb->total_vram - (PAGE_SIZE << 2));
2733 var.yres_virtual = ((vram * 8) / var.bits_per_pixel) /
2734 var.xres_virtual;
2735 if (var.yres_virtual < var.yres)
2736 var.yres_virtual = var.yres;
2737 }
2738 atyfb_set_var(&var, -1, &fb->fb_info);
2739 }
2740 }
2741 } else {
2742 fb->consolecnt--;
2743 }
2744 #endif
2745 return(0);
2746 }
2747
2748
2749 static int encode_fix(struct fb_fix_screeninfo *fix,
2750 const struct atyfb_par *par,
2751 const struct fb_info_aty *info)
2752 {
2753 memset(fix, 0, sizeof(struct fb_fix_screeninfo));
2754
2755 strcpy(fix->id, atyfb_name);
2756 fix->smem_start = info->frame_buffer_phys;
2757 fix->smem_len = (u32)info->total_vram;
2758
2759 /*
2760 * Reg Block 0 (CT-compatible block) is at ati_regbase_phys
2761 * Reg Block 1 (multimedia extensions) is at ati_regbase_phys-0x400
2762 */
2763 if (Gx == GX_CHIP_ID || Gx == CX_CHIP_ID) {
2764 fix->mmio_start = info->ati_regbase_phys;
2765 fix->mmio_len = 0x400;
2766 fix->accel = FB_ACCEL_ATI_MACH64GX;
2767 } else if (Gx == CT_CHIP_ID || Gx == ET_CHIP_ID) {
2768 fix->mmio_start = info->ati_regbase_phys;
2769 fix->mmio_len = 0x400;
2770 fix->accel = FB_ACCEL_ATI_MACH64CT;
2771 } else if (Gx == VT_CHIP_ID || Gx == VU_CHIP_ID || Gx == VV_CHIP_ID) {
2772 fix->mmio_start = info->ati_regbase_phys-0x400;
2773 fix->mmio_len = 0x800;
2774 fix->accel = FB_ACCEL_ATI_MACH64VT;
2775 } else {
2776 fix->mmio_start = info->ati_regbase_phys-0x400;
2777 fix->mmio_len = 0x800;
2778 fix->accel = FB_ACCEL_ATI_MACH64GT;
2779 }
2780 fix->type = FB_TYPE_PACKED_PIXELS;
2781 fix->type_aux = 0;
2782 fix->line_length = par->crtc.vxres*par->crtc.bpp/8;
2783 fix->visual = par->crtc.bpp <= 8 ? FB_VISUAL_PSEUDOCOLOR
2784 : FB_VISUAL_DIRECTCOLOR;
2785 fix->ywrapstep = 0;
2786 fix->xpanstep = 8;
2787 fix->ypanstep = 1;
2788
2789 return 0;
2790 }
2791
2792
2793 /*
2794 * Get the Fixed Part of the Display
2795 */
2796
2797 static int atyfb_get_fix(struct fb_fix_screeninfo *fix, int con,
2798 struct fb_info *fb)
2799 {
2800 const struct fb_info_aty *info = (struct fb_info_aty *)fb;
2801 struct atyfb_par par;
2802
2803 if (con == -1)
2804 par = info->default_par;
2805 else
2806 atyfb_decode_var(&fb_display[con].var, &par, info);
2807 encode_fix(fix, &par, info);
2808 return 0;
2809 }
2810
2811
2812 /*
2813 * Get the User Defined Part of the Display
2814 */
2815
2816 static int atyfb_get_var(struct fb_var_screeninfo *var, int con,
2817 struct fb_info *fb)
2818 {
2819 const struct fb_info_aty *info = (struct fb_info_aty *)fb;
2820
2821 if (con == -1)
2822 atyfb_encode_var(var, &info->default_par, info);
2823 else
2824 *var = fb_display[con].var;
2825 return 0;
2826 }
2827
2828
2829 static void atyfb_set_dispsw(struct display *disp, struct fb_info_aty *info,
2830 int bpp, int accel)
2831 {
2832 switch (bpp) {
2833 #ifdef FBCON_HAS_CFB8
2834 case 8:
2835 info->dispsw = accel ? fbcon_aty8 : fbcon_cfb8;
2836 disp->dispsw = &info->dispsw;
2837 break;
2838 #endif
2839 #ifdef FBCON_HAS_CFB16
2840 case 16:
2841 info->dispsw = accel ? fbcon_aty16 : fbcon_cfb16;
2842 disp->dispsw = &info->dispsw;
2843 disp->dispsw_data = info->fbcon_cmap.cfb16;
2844 break;
2845 #endif
2846 #ifdef FBCON_HAS_CFB24
2847 case 24:
2848 info->dispsw = accel ? fbcon_aty24 : fbcon_cfb24;
2849 disp->dispsw = &info->dispsw;
2850 disp->dispsw_data = info->fbcon_cmap.cfb24;
2851 break;
2852 #endif
2853 #ifdef FBCON_HAS_CFB32
2854 case 32:
2855 info->dispsw = accel ? fbcon_aty32 : fbcon_cfb32;
2856 disp->dispsw = &info->dispsw;
2857 disp->dispsw_data = info->fbcon_cmap.cfb32;
2858 break;
2859 #endif
2860 default:
2861 disp->dispsw = &fbcon_dummy;
2862 }
2863 if (info->cursor) {
2864 info->dispsw.cursor = atyfb_cursor;
2865 info->dispsw.set_font = atyfb_set_font;
2866 }
2867 }
2868
2869
2870 /*
2871 * Set the User Defined Part of the Display
2872 */
2873
2874 static int atyfb_set_var(struct fb_var_screeninfo *var, int con,
2875 struct fb_info *fb)
2876 {
2877 struct fb_info_aty *info = (struct fb_info_aty *)fb;
2878 struct atyfb_par par;
2879 struct display *display;
2880 int oldxres, oldyres, oldvxres, oldvyres, oldbpp, oldaccel, accel, err;
2881 int activate = var->activate;
2882
2883 if (con >= 0)
2884 display = &fb_display[con];
2885 else
2886 display = fb->disp; /* used during initialization */
2887
2888 if ((err = atyfb_decode_var(var, &par, info)))
2889 return err;
2890
2891 atyfb_encode_var(var, &par, (struct fb_info_aty *)info);
2892
2893 if ((activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {
2894 oldxres = display->var.xres;
2895 oldyres = display->var.yres;
2896 oldvxres = display->var.xres_virtual;
2897 oldvyres = display->var.yres_virtual;
2898 oldbpp = display->var.bits_per_pixel;
2899 oldaccel = display->var.accel_flags;
2900 display->var = *var;
2901 accel = var->accel_flags & FB_ACCELF_TEXT;
2902 if (oldxres != var->xres || oldyres != var->yres ||
2903 oldvxres != var->xres_virtual || oldvyres != var->yres_virtual ||
2904 oldbpp != var->bits_per_pixel || oldaccel != var->accel_flags) {
2905 struct fb_fix_screeninfo fix;
2906
2907 encode_fix(&fix, &par, info);
2908 display->screen_base = (char *)info->frame_buffer;
2909 display->visual = fix.visual;
2910 display->type = fix.type;
2911 display->type_aux = fix.type_aux;
2912 display->ypanstep = fix.ypanstep;
2913 display->ywrapstep = fix.ywrapstep;
2914 display->line_length = fix.line_length;
2915 display->can_soft_blank = 1;
2916 display->inverse = 0;
2917 if (accel)
2918 display->scrollmode = (info->bus_type == PCI) ? SCROLL_YNOMOVE : 0;
2919 else
2920 display->scrollmode = SCROLL_YREDRAW;
2921 if (info->fb_info.changevar)
2922 (*info->fb_info.changevar)(con);
2923 }
2924 if (!info->fb_info.display_fg ||
2925 info->fb_info.display_fg->vc_num == con) {
2926 atyfb_set_par(&par, info);
2927 atyfb_set_dispsw(display, info, par.crtc.bpp, accel);
2928 }
2929 if (oldbpp != var->bits_per_pixel) {
2930 if ((err = fb_alloc_cmap(&display->cmap, 0, 0)))
2931 return err;
2932 do_install_cmap(con, &info->fb_info);
2933 }
2934 }
2935
2936 return 0;
2937 }
2938
2939
2940 /*
2941 * Pan or Wrap the Display
2942 *
2943 * This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
2944 */
2945
2946 static int atyfb_pan_display(struct fb_var_screeninfo *var, int con,
2947 struct fb_info *fb)
2948 {
2949 struct fb_info_aty *info = (struct fb_info_aty *)fb;
2950 u32 xres, yres, xoffset, yoffset;
2951 struct atyfb_par *par = &info->current_par;
2952
2953 xres = (((par->crtc.h_tot_disp>>16) & 0xff)+1)*8;
2954 yres = ((par->crtc.v_tot_disp>>16) & 0x7ff)+1;
2955 xoffset = (var->xoffset+7) & ~7;
2956 yoffset = var->yoffset;
2957 if (xoffset+xres > par->crtc.vxres || yoffset+yres > par->crtc.vyres)
2958 return -EINVAL;
2959 par->crtc.xoffset = xoffset;
2960 par->crtc.yoffset = yoffset;
2961 set_off_pitch(par, info);
2962 return 0;
2963 }
2964
2965 /*
2966 * Get the Colormap
2967 */
2968
2969 static int atyfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
2970 struct fb_info *info)
2971 {
2972 if (!info->display_fg || con == info->display_fg->vc_num) /* current console? */
2973 return fb_get_cmap(cmap, kspc, atyfb_getcolreg, info);
2974 else if (fb_display[con].cmap.len) /* non default colormap? */
2975 fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
2976 else {
2977 int size = fb_display[con].var.bits_per_pixel == 16 ? 32 : 256;
2978 fb_copy_cmap(fb_default_cmap(size), cmap, kspc ? 0 : 2);
2979 }
2980 return 0;
2981 }
2982
2983 /*
2984 * Set the Colormap
2985 */
2986
2987 static int atyfb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
2988 struct fb_info *info)
2989 {
2990 int err;
2991 struct display *disp;
2992
2993 if (con >= 0)
2994 disp = &fb_display[con];
2995 else
2996 disp = info->disp;
2997 if (!disp->cmap.len) { /* no colormap allocated? */
2998 int size = disp->var.bits_per_pixel == 16 ? 32 : 256;
2999 if ((err = fb_alloc_cmap(&disp->cmap, size, 0)))
3000 return err;
3001 }
3002 if (!info->display_fg || con == info->display_fg->vc_num) /* current console? */
3003 return fb_set_cmap(cmap, kspc, atyfb_setcolreg, info);
3004 else
3005 fb_copy_cmap(cmap, &disp->cmap, kspc ? 0 : 1);
3006 return 0;
3007 }
3008
3009
3010 #ifdef DEBUG
3011 #define ATYIO_CLKR 0x41545900 /* ATY\00 */
3012 #define ATYIO_CLKW 0x41545901 /* ATY\01 */
3013
3014 struct atyclk {
3015 u32 ref_clk_per;
3016 u8 pll_ref_div;
3017 u8 mclk_fb_div;
3018 u8 mclk_post_div; /* 1,2,3,4,8 */
3019 u8 vclk_fb_div;
3020 u8 vclk_post_div; /* 1,2,3,4,6,8,12 */
3021 u32 dsp_xclks_per_row; /* 0-16383 */
3022 u32 dsp_loop_latency; /* 0-15 */
3023 u32 dsp_precision; /* 0-7 */
3024 u32 dsp_on; /* 0-2047 */
3025 u32 dsp_off; /* 0-2047 */
3026 };
3027 #endif
3028
3029 static int atyfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
3030 u_long arg, int con, struct fb_info *info2)
3031 {
3032 #if defined(__sparc__) || defined(DEBUG)
3033 struct fb_info_aty *info = (struct fb_info_aty *)info2;
3034 #endif /* __sparc__ || DEBUG */
3035 #ifdef __sparc__
3036 struct fbtype fbtyp;
3037 struct display *disp;
3038
3039 if (con >= 0)
3040 disp = &fb_display[con];
3041 else
3042 disp = info2->disp;
3043 #endif
3044
3045 switch (cmd) {
3046 #ifdef __sparc__
3047 case FBIOGTYPE:
3048 fbtyp.fb_type = FBTYPE_PCI_GENERIC;
3049 fbtyp.fb_width = info->current_par.crtc.vxres;
3050 fbtyp.fb_height = info->current_par.crtc.vyres;
3051 fbtyp.fb_depth = info->current_par.crtc.bpp;
3052 fbtyp.fb_cmsize = disp->cmap.len;
3053 fbtyp.fb_size = info->total_vram;
3054 if (copy_to_user((struct fbtype *)arg, &fbtyp, sizeof(fbtyp)))
3055 return -EFAULT;
3056 break;
3057 #endif /* __sparc__ */
3058 #ifdef DEBUG
3059 case ATYIO_CLKR:
3060 if ((Gx != GX_CHIP_ID) && (Gx != CX_CHIP_ID)) {
3061 struct atyclk clk;
3062 struct pll_ct *pll = &info->current_par.pll.ct;
3063 u32 dsp_config = pll->dsp_config;
3064 u32 dsp_on_off = pll->dsp_on_off;
3065 clk.ref_clk_per = info->ref_clk_per;
3066 clk.pll_ref_div = pll->pll_ref_div;
3067 clk.mclk_fb_div = pll->mclk_fb_div;
3068 clk.mclk_post_div = pll->mclk_post_div_real;
3069 clk.vclk_fb_div = pll->vclk_fb_div;
3070 clk.vclk_post_div = pll->vclk_post_div_real;
3071 clk.dsp_xclks_per_row = dsp_config & 0x3fff;
3072 clk.dsp_loop_latency = (dsp_config>>16) & 0xf;
3073 clk.dsp_precision = (dsp_config>>20) & 7;
3074 clk.dsp_on = dsp_on_off & 0x7ff;
3075 clk.dsp_off = (dsp_on_off>>16) & 0x7ff;
3076 if (copy_to_user((struct atyclk *)arg, &clk, sizeof(clk)))
3077 return -EFAULT;
3078 } else
3079 return -EINVAL;
3080 break;
3081 case ATYIO_CLKW:
3082 if ((Gx != GX_CHIP_ID) && (Gx != CX_CHIP_ID)) {
3083 struct atyclk clk;
3084 struct pll_ct *pll = &info->current_par.pll.ct;
3085 if (copy_from_user(&clk, (struct atyclk *)arg, sizeof(clk)))
3086 return -EFAULT;
3087 info->ref_clk_per = clk.ref_clk_per;
3088 pll->pll_ref_div = clk.pll_ref_div;
3089 pll->mclk_fb_div = clk.mclk_fb_div;
3090 pll->mclk_post_div_real = clk.mclk_post_div;
3091 pll->vclk_fb_div = clk.vclk_fb_div;
3092 pll->vclk_post_div_real = clk.vclk_post_div;
3093 pll->dsp_config = (clk.dsp_xclks_per_row & 0x3fff) |
3094 ((clk.dsp_loop_latency & 0xf)<<16) |
3095 ((clk.dsp_precision & 7)<<20);
3096 pll->dsp_on_off = (clk.dsp_on & 0x7ff) |
3097 ((clk.dsp_off & 0x7ff)<<16);
3098 aty_calc_pll_ct(info, pll);
3099 aty_set_pll_ct(info, pll);
3100 } else
3101 return -EINVAL;
3102 break;
3103 #endif /* DEBUG */
3104 default:
3105 return -EINVAL;
3106 }
3107 return 0;
3108 }
3109
3110 static int atyfb_rasterimg(struct fb_info *info, int start)
3111 {
3112 struct fb_info_aty *fb = (struct fb_info_aty *)info;
3113
3114 if (fb->blitter_may_be_busy)
3115 wait_for_idle(fb);
3116 return 0;
3117 }
3118
3119 #ifdef __sparc__
3120 static int atyfb_mmap(struct fb_info *info, struct file *file,
3121 struct vm_area_struct *vma)
3122 {
3123 struct fb_info_aty *fb = (struct fb_info_aty *)info;
3124 unsigned int size, page, map_size = 0;
3125 unsigned long map_offset = 0;
3126 unsigned long off;
3127 int i;
3128
3129 if (!fb->mmap_map)
3130 return -ENXIO;
3131
3132 if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
3133 return -EINVAL;
3134
3135 off = vma->vm_pgoff << PAGE_SHIFT;
3136 size = vma->vm_end - vma->vm_start;
3137
3138 /* To stop the swapper from even considering these pages. */
3139 vma->vm_flags |= (VM_SHM | VM_LOCKED);
3140
3141 if (((vma->vm_pgoff == 0) && (size == fb->total_vram)) ||
3142 ((off == fb->total_vram) && (size == PAGE_SIZE)))
3143 off += 0x8000000000000000UL;
3144
3145 vma->vm_pgoff = off >> PAGE_SHIFT; /* propagate off changes */
3146
3147 #ifdef __sparc_v9__
3148 /* Align it as much as desirable */
3149 {
3150 unsigned long j, align;
3151 int max = -1;
3152
3153 map_offset = off + size;
3154 for (i = 0; fb->mmap_map[i].size; i++) {
3155 if (fb->mmap_map[i].voff < off)
3156 continue;
3157 if (fb->mmap_map[i].voff >= map_offset)
3158 break;
3159 if (max < 0 ||
3160 fb->mmap_map[i].size > fb->mmap_map[max].size)
3161 max = i;
3162 }
3163 if (max >= 0) {
3164 j = fb->mmap_map[max].size;
3165 if (fb->mmap_map[max].voff + j > map_offset)
3166 j = map_offset - fb->mmap_map[max].voff;
3167 for (align = 0x400000; align > PAGE_SIZE; align >>= 3)
3168 if (j >= align &&
3169 !(fb->mmap_map[max].poff & (align - 1)))
3170 break;
3171 if (align > PAGE_SIZE) {
3172 j = align;
3173 align = j - ((vma->vm_start
3174 + fb->mmap_map[max].voff
3175 - off) & (j - 1));
3176 if (align != j) {
3177 struct vm_area_struct *vmm;
3178
3179 vmm = find_vma(current->mm,
3180 vma->vm_start);
3181 if (!vmm || vmm->vm_start
3182 >= vma->vm_end + align) {
3183 vma->vm_start += align;
3184 vma->vm_end += align;
3185 }
3186 }
3187 }
3188 }
3189 }
3190 #endif
3191
3192 /* Each page, see which map applies */
3193 for (page = 0; page < size; ) {
3194 map_size = 0;
3195 for (i = 0; fb->mmap_map[i].size; i++) {
3196 unsigned long start = fb->mmap_map[i].voff;
3197 unsigned long end = start + fb->mmap_map[i].size;
3198 unsigned long offset = off + page;
3199
3200 if (start > offset)
3201 continue;
3202 if (offset >= end)
3203 continue;
3204
3205 map_size = fb->mmap_map[i].size - (offset - start);
3206 map_offset = fb->mmap_map[i].poff + (offset - start);
3207 break;
3208 }
3209 if (!map_size) {
3210 page += PAGE_SIZE;
3211 continue;
3212 }
3213 if (page + map_size > size)
3214 map_size = size - page;
3215
3216 pgprot_val(vma->vm_page_prot) &= ~(fb->mmap_map[i].prot_mask);
3217 pgprot_val(vma->vm_page_prot) |= fb->mmap_map[i].prot_flag;
3218
3219 if (remap_page_range(vma->vm_start + page, map_offset,
3220 map_size, vma->vm_page_prot))
3221 return -EAGAIN;
3222
3223 page += map_size;
3224 }
3225
3226 if (!map_size)
3227 return -EINVAL;
3228
3229 vma->vm_flags |= VM_IO;
3230
3231 if (!fb->mmaped) {
3232 int lastconsole = 0;
3233
3234 if (info->display_fg)
3235 lastconsole = info->display_fg->vc_num;
3236 fb->mmaped = 1;
3237 if (fb->consolecnt && fb_display[lastconsole].fb_info == info) {
3238 fb->vtconsole = lastconsole;
3239 vt_cons[lastconsole]->vc_mode = KD_GRAPHICS;
3240 }
3241 }
3242 return 0;
3243 }
3244
3245 static struct {
3246 u32 yoffset;
3247 u8 r[2][256];
3248 u8 g[2][256];
3249 u8 b[2][256];
3250 } atyfb_save;
3251
3252 static void atyfb_save_palette(struct fb_info *fb, int enter)
3253 {
3254 struct fb_info_aty *info = (struct fb_info_aty *)fb;
3255 int i, tmp, scale;
3256
3257 for (i = 0; i < 256; i++) {
3258 tmp = aty_ld_8(DAC_CNTL, info) & 0xfc;
3259 if (Gx == GT_CHIP_ID || Gx == GU_CHIP_ID || Gx == GV_CHIP_ID ||
3260 Gx == GW_CHIP_ID || Gx == GZ_CHIP_ID || Gx == LG_CHIP_ID ||
3261 Gx == GB_CHIP_ID || Gx == GD_CHIP_ID || Gx == GI_CHIP_ID ||
3262 Gx == GP_CHIP_ID || Gx == GQ_CHIP_ID)
3263 tmp |= 0x2;
3264 aty_st_8(DAC_CNTL, tmp, info);
3265 aty_st_8(DAC_MASK, 0xff, info);
3266
3267 scale = ((Gx != GX_CHIP_ID) && (Gx != CX_CHIP_ID) &&
3268 (info->current_par.crtc.bpp == 16)) ? 3 : 0;
3269 writeb(i << scale, &info->aty_cmap_regs->rindex);
3270
3271 atyfb_save.r[enter][i] = readb(&info->aty_cmap_regs->lut);
3272 atyfb_save.g[enter][i] = readb(&info->aty_cmap_regs->lut);
3273 atyfb_save.b[enter][i] = readb(&info->aty_cmap_regs->lut);
3274 writeb(i << scale, &info->aty_cmap_regs->windex);
3275 writeb(atyfb_save.r[1-enter][i], &info->aty_cmap_regs->lut);
3276 writeb(atyfb_save.g[1-enter][i], &info->aty_cmap_regs->lut);
3277 writeb(atyfb_save.b[1-enter][i], &info->aty_cmap_regs->lut);
3278 }
3279 }
3280
3281 static void atyfb_palette(int enter)
3282 {
3283 struct fb_info_aty *info;
3284 struct atyfb_par *par;
3285 struct display *d;
3286 int i;
3287
3288 for (i = 0; i < MAX_NR_CONSOLES; i++) {
3289 d = &fb_display[i];
3290 if (d->fb_info &&
3291 d->fb_info->fbops == &atyfb_ops &&
3292 d->fb_info->display_fg &&
3293 d->fb_info->display_fg->vc_num == i) {
3294 atyfb_save_palette(d->fb_info, enter);
3295 info = (struct fb_info_aty *)d->fb_info;
3296 par = &info->current_par;
3297 if (enter) {
3298 atyfb_save.yoffset = par->crtc.yoffset;
3299 par->crtc.yoffset = 0;
3300 set_off_pitch(par, info);
3301 } else {
3302 par->crtc.yoffset = atyfb_save.yoffset;
3303 set_off_pitch(par, info);
3304 }
3305 break;
3306 }
3307 }
3308 }
3309 #endif /* __sparc__ */
3310
3311 /*
3312 * Initialisation
3313 */
3314
3315 static int __init aty_init(struct fb_info_aty *info, const char *name)
3316 {
3317 u32 chip_id;
3318 u32 i;
3319 int j, k;
3320 struct fb_var_screeninfo var;
3321 struct display *disp;
3322 const char *chipname = NULL, *ramname = NULL, *xtal;
3323 int pll, mclk, gtb_memsize;
3324 #if defined(CONFIG_PPC)
3325 int sense;
3326 #endif
3327 u8 pll_ref_div;
3328
3329 info->aty_cmap_regs = (struct aty_cmap_regs *)(info->ati_regbase+0xc0);
3330 chip_id = aty_ld_le32(CONFIG_CHIP_ID, info);
3331 Gx = chip_id & CFG_CHIP_TYPE;
3332 Rev = (chip_id & CFG_CHIP_REV)>>24;
3333 for (j = 0; j < (sizeof(aty_features)/sizeof(*aty_features)); j++)
3334 if (aty_features[j].chip_type == Gx) {
3335 chipname = aty_features[j].name;
3336 info->dac_type = (aty_ld_le32(DAC_CNTL, info) >> 16) & 0x07;
3337 break;
3338 }
3339 if (!chipname) {
3340 printk("atyfb: Unknown mach64 0x%04x\n", Gx);
3341 return 0;
3342 } else
3343 printk("atyfb: %s [0x%04x rev 0x%02x] ", chipname, Gx, Rev);
3344 if ((Gx == GX_CHIP_ID) || (Gx == CX_CHIP_ID)) {
3345 info->bus_type = (aty_ld_le32(CONFIG_STAT0, info) >> 0) & 0x07;
3346 info->ram_type = (aty_ld_le32(CONFIG_STAT0, info) >> 3) & 0x07;
3347 ramname = aty_gx_ram[info->ram_type];
3348 /* FIXME: clockchip/RAMDAC probing? */
3349 #ifdef CONFIG_ATARI
3350 info->clk_type = CLK_ATI18818_1;
3351 info->dac_type = (aty_ld_le32(CONFIG_STAT0, info) >> 9) & 0x07;
3352 if (info->dac_type == 0x07)
3353 info->dac_subtype = DAC_ATT20C408;
3354 else
3355 info->dac_subtype = (aty_ld_8(SCRATCH_REG1 + 1, info) & 0xF0) |
3356 info->dac_type;
3357 #else
3358 info->dac_type = DAC_IBMRGB514;
3359 info->dac_subtype = DAC_IBMRGB514;
3360 info->clk_type = CLK_IBMRGB514;
3361 #endif
3362 /* FIXME */
3363 pll = 135;
3364 mclk = 50;
3365 } else {
3366 info->bus_type = PCI;
3367 info->ram_type = (aty_ld_le32(CONFIG_STAT0, info) & 0x07);
3368 ramname = aty_ct_ram[info->ram_type];
3369 info->dac_type = DAC_INTERNAL;
3370 info->dac_subtype = DAC_INTERNAL;
3371 info->clk_type = CLK_INTERNAL;
3372 if ((Gx == CT_CHIP_ID) || (Gx == ET_CHIP_ID)) {
3373 pll = 135;
3374 mclk = 60;
3375 } else {
3376 mclk = info->ram_type >= SDRAM ? 67 : 63;
3377 if ((Gx == VT_CHIP_ID) && (Rev == 0x08)) {
3378 /* VTA3 */
3379 pll = 170;
3380 } else if (((Gx == VT_CHIP_ID) && ((Rev == 0x40) ||
3381 (Rev == 0x48))) ||
3382 ((Gx == VT_CHIP_ID) && ((Rev == 0x01) ||
3383 (Rev == 0x9a))) ||
3384 Gx == VU_CHIP_ID) {
3385 /* VTA4 or VTB */
3386 pll = 200;
3387 } else if (Gx == VV_CHIP_ID) {
3388 /* VT4 */
3389 pll = 230;
3390 mclk = 83;
3391 } else if (Gx == VT_CHIP_ID) {
3392 /* other VT */
3393 pll = 135;
3394 mclk = 63;
3395 } else if ((Gx == GT_CHIP_ID) && (Rev & 0x01)) {
3396 /* RAGE II */
3397 pll = 170;
3398 } else if (((Gx == GT_CHIP_ID) && (Rev & 0x02)) ||
3399 (Gx == GU_CHIP_ID)) {
3400 /* RAGE II+ */
3401 pll = 200;
3402 } else if (Gx == GV_CHIP_ID || Gx == GW_CHIP_ID ||
3403 Gx == GZ_CHIP_ID) {
3404 /* RAGE IIC */
3405 pll = 230;
3406 mclk = 83;
3407 } else if (Gx == GB_CHIP_ID || Gx == GD_CHIP_ID ||
3408 Gx == GI_CHIP_ID || Gx == GP_CHIP_ID ||
3409 Gx == GQ_CHIP_ID || Gx == LB_CHIP_ID ||
3410 Gx == LD_CHIP_ID ||
3411 Gx == LI_CHIP_ID || Gx == LP_CHIP_ID) {
3412 /* RAGE PRO or LT PRO */
3413 pll = 230;
3414 mclk = 100;
3415 } else if (Gx == LG_CHIP_ID) {
3416 /* Rage LT */
3417 pll = 230;
3418 mclk = 63;
3419 } else if ((Gx == LN_CHIP_ID) || (Gx == LM_CHIP_ID)) {
3420 /* Rage mobility M1 */
3421 pll = 230;
3422 mclk = 50;
3423 } else {
3424 /* other RAGE */
3425 pll = 135;
3426 mclk = 63;
3427 }
3428 }
3429 }
3430
3431 info->ref_clk_per = 1000000000000ULL/14318180;
3432 xtal = "14.31818";
3433 if (!(Gx == GX_CHIP_ID || Gx == CX_CHIP_ID || Gx == CT_CHIP_ID ||
3434 Gx == ET_CHIP_ID ||
3435 ((Gx == VT_CHIP_ID || Gx == GT_CHIP_ID) && !(Rev & 0x07))) &&
3436 (pll_ref_div = aty_ld_pll(PLL_REF_DIV, info))) {
3437 int diff1, diff2;
3438 diff1 = 510*14/pll_ref_div-pll;
3439 diff2 = 510*29/pll_ref_div-pll;
3440 if (diff1 < 0)
3441 diff1 = -diff1;
3442 if (diff2 < 0)
3443 diff2 = -diff2;
3444 if (diff2 < diff1) {
3445 info->ref_clk_per = 1000000000000ULL/29498928;
3446 xtal = "29.498928";
3447 }
3448 }
3449
3450 i = aty_ld_le32(MEM_CNTL, info);
3451 gtb_memsize = !(Gx == GX_CHIP_ID || Gx == CX_CHIP_ID || Gx == CT_CHIP_ID ||
3452 Gx == ET_CHIP_ID ||
3453 ((Gx == VT_CHIP_ID || Gx == GT_CHIP_ID) && !(Rev & 0x07)));
3454 if (gtb_memsize)
3455 switch (i & 0xF) { /* 0xF used instead of MEM_SIZE_ALIAS */
3456 case MEM_SIZE_512K:
3457 info->total_vram = 0x80000;
3458 break;
3459 case MEM_SIZE_1M:
3460 info->total_vram = 0x100000;
3461 break;
3462 case MEM_SIZE_2M_GTB:
3463 info->total_vram = 0x200000;
3464 break;
3465 case MEM_SIZE_4M_GTB:
3466 info->total_vram = 0x400000;
3467 break;
3468 case MEM_SIZE_6M_GTB:
3469 info->total_vram = 0x600000;
3470 break;
3471 case MEM_SIZE_8M_GTB:
3472 info->total_vram = 0x800000;
3473 break;
3474 default:
3475 info->total_vram = 0x80000;
3476 }
3477 else
3478 switch (i & MEM_SIZE_ALIAS) {
3479 case MEM_SIZE_512K:
3480 info->total_vram = 0x80000;
3481 break;
3482 case MEM_SIZE_1M:
3483 info->total_vram = 0x100000;
3484 break;
3485 case MEM_SIZE_2M:
3486 info->total_vram = 0x200000;
3487 break;
3488 case MEM_SIZE_4M:
3489 info->total_vram = 0x400000;
3490 break;
3491 case MEM_SIZE_6M:
3492 info->total_vram = 0x600000;
3493 break;
3494 case MEM_SIZE_8M:
3495 info->total_vram = 0x800000;
3496 break;
3497 default:
3498 info->total_vram = 0x80000;
3499 }
3500
3501 if (Gx == GI_CHIP_ID) {
3502 if (aty_ld_le32(CONFIG_STAT1, info) & 0x40000000)
3503 info->total_vram += 0x400000;
3504 }
3505
3506 if (default_vram) {
3507 info->total_vram = default_vram*1024;
3508 i = i & ~(gtb_memsize ? 0xF : MEM_SIZE_ALIAS);
3509 if (info->total_vram <= 0x80000)
3510 i |= MEM_SIZE_512K;
3511 else if (info->total_vram <= 0x100000)
3512 i |= MEM_SIZE_1M;
3513 else if (info->total_vram <= 0x200000)
3514 i |= gtb_memsize ? MEM_SIZE_2M_GTB : MEM_SIZE_2M;
3515 else if (info->total_vram <= 0x400000)
3516 i |= gtb_memsize ? MEM_SIZE_4M_GTB : MEM_SIZE_4M;
3517 else if (info->total_vram <= 0x600000)
3518 i |= gtb_memsize ? MEM_SIZE_6M_GTB : MEM_SIZE_6M;
3519 else
3520 i |= gtb_memsize ? MEM_SIZE_8M_GTB : MEM_SIZE_8M;
3521 aty_st_le32(MEM_CNTL, i, info);
3522 }
3523 if (default_pll)
3524 pll = default_pll;
3525 if (default_mclk)
3526 mclk = default_mclk;
3527
3528 printk("%d%c %s, %s MHz XTAL, %d MHz PLL, %d Mhz MCLK\n",
3529 info->total_vram == 0x80000 ? 512 : (info->total_vram >> 20),
3530 info->total_vram == 0x80000 ? 'K' : 'M', ramname, xtal, pll, mclk);
3531
3532 if (mclk < 44)
3533 info->mem_refresh_rate = 0; /* 000 = 10 Mhz - 43 Mhz */
3534 else if (mclk < 50)
3535 info->mem_refresh_rate = 1; /* 001 = 44 Mhz - 49 Mhz */
3536 else if (mclk < 55)
3537 info->mem_refresh_rate = 2; /* 010 = 50 Mhz - 54 Mhz */
3538 else if (mclk < 66)
3539 info->mem_refresh_rate = 3; /* 011 = 55 Mhz - 65 Mhz */
3540 else if (mclk < 75)
3541 info->mem_refresh_rate = 4; /* 100 = 66 Mhz - 74 Mhz */
3542 else if (mclk < 80)
3543 info->mem_refresh_rate = 5; /* 101 = 75 Mhz - 79 Mhz */
3544 else if (mclk < 100)
3545 info->mem_refresh_rate = 6; /* 110 = 80 Mhz - 100 Mhz */
3546 else
3547 info->mem_refresh_rate = 7; /* 111 = 100 Mhz and above */
3548 info->pll_per = 1000000/pll;
3549 info->mclk_per = 1000000/mclk;
3550
3551 #ifdef DEBUG
3552 if ((Gx != GX_CHIP_ID) && (Gx != CX_CHIP_ID)) {
3553 int i;
3554 printk("BUS_CNTL DAC_CNTL MEM_CNTL EXT_MEM_CNTL CRTC_GEN_CNTL "
3555 "DSP_CONFIG DSP_ON_OFF\n"
3556 "%08x %08x %08x %08x %08x %08x %08x\n"
3557 "PLL",
3558 aty_ld_le32(BUS_CNTL, info), aty_ld_le32(DAC_CNTL, info),
3559 aty_ld_le32(MEM_CNTL, info), aty_ld_le32(EXT_MEM_CNTL, info),
3560 aty_ld_le32(CRTC_GEN_CNTL, info), aty_ld_le32(DSP_CONFIG, info),
3561 aty_ld_le32(DSP_ON_OFF, info));
3562 for (i = 0; i < 16; i++)
3563 printk(" %02x", aty_ld_pll(i, info));
3564 printk("\n");
3565 }
3566 #endif
3567
3568 /*
3569 * Last page of 8 MB (4 MB on ISA) aperture is MMIO
3570 * FIXME: we should use the auxiliary aperture instead so we can acces the
3571 * full 8 MB of video RAM on 8 MB boards
3572 */
3573 if (info->total_vram == 0x800000 ||
3574 (info->bus_type == ISA && info->total_vram == 0x400000))
3575 info->total_vram -= GUI_RESERVE;
3576
3577 /* Clear the video memory */
3578 fb_memset((void *)info->frame_buffer, 0, info->total_vram);
3579
3580 disp = &info->disp;
3581
3582 strcpy(info->fb_info.modename, atyfb_name);
3583 info->fb_info.node = -1;
3584 info->fb_info.fbops = &atyfb_ops;
3585 info->fb_info.disp = disp;
3586 strcpy(info->fb_info.fontname, fontname);
3587 info->fb_info.changevar = NULL;
3588 info->fb_info.switch_con = &atyfbcon_switch;
3589 info->fb_info.updatevar = &atyfbcon_updatevar;
3590 info->fb_info.blank = &atyfbcon_blank;
3591 info->fb_info.flags = FBINFO_FLAG_DEFAULT;
3592
3593 #ifdef CONFIG_PMAC_BACKLIGHT
3594 if (Gx == LI_CHIP_ID && machine_is_compatible("PowerBook1,1")) {
3595 /* these bits let the 101 powerbook wake up from sleep -- paulus */
3596 aty_st_lcd(LCD_POWER_MANAGEMENT, aty_ld_lcd(LCD_POWER_MANAGEMENT, info)
3597 | (USE_F32KHZ | TRISTATE_MEM_EN), info);
3598 }
3599 if ((Gx == LN_CHIP_ID) || (Gx == LM_CHIP_ID))
3600 register_backlight_controller(&aty_backlight_controller, info, "ati");
3601 #endif /* CONFIG_PMAC_BACKLIGHT */
3602
3603 #ifdef MODULE
3604 var = default_var;
3605 #else /* !MODULE */
3606 memset(&var, 0, sizeof(var));
3607 #ifdef CONFIG_PPC
3608 if (_machine == _MACH_Pmac) {
3609 /*
3610 * FIXME: The NVRAM stuff should be put in a Mac-specific file, as it
3611 * applies to all Mac video cards
3612 */
3613 if (mode_option) {
3614 if (!mac_find_mode(&var, &info->fb_info, mode_option, 8))
3615 var = default_var;
3616 } else {
3617 #ifdef CONFIG_NVRAM
3618 if (default_vmode == VMODE_NVRAM) {
3619 default_vmode = nvram_read_byte(NV_VMODE);
3620 if (default_vmode <= 0 || default_vmode > VMODE_MAX)
3621 default_vmode = VMODE_CHOOSE;
3622 }
3623 #endif
3624 if (default_vmode == VMODE_CHOOSE) {
3625 if (Gx == LG_CHIP_ID || Gx == LI_CHIP_ID)
3626 /* G3 PowerBook with 1024x768 LCD */
3627 default_vmode = VMODE_1024_768_60;
3628 else if (machine_is_compatible("iMac"))
3629 default_vmode = VMODE_1024_768_75;
3630 else if (machine_is_compatible("PowerBook2,1"))
3631 /* iBook with 800x600 LCD */
3632 default_vmode = VMODE_800_600_60;
3633 else
3634 default_vmode = VMODE_640_480_67;
3635 sense = read_aty_sense(info);
3636 printk(KERN_INFO "atyfb: monitor sense=%x, mode %d\n",
3637 sense, mac_map_monitor_sense(sense));
3638 }
3639 if (default_vmode <= 0 || default_vmode > VMODE_MAX)
3640 default_vmode = VMODE_640_480_60;
3641 #ifdef CONFIG_NVRAM
3642 if (default_cmode == CMODE_NVRAM)
3643 default_cmode = nvram_read_byte(NV_CMODE);
3644 #endif
3645 if (default_cmode < CMODE_8 || default_cmode > CMODE_32)
3646 default_cmode = CMODE_8;
3647 if (mac_vmode_to_var(default_vmode, default_cmode, &var))
3648 var = default_var;
3649 }
3650 }
3651 else if (!fb_find_mode(&var, &info->fb_info, mode_option, NULL, 0, NULL, 8))
3652 var = default_var;
3653 #else /* !CONFIG_PPC */
3654 #ifdef __sparc__
3655 if (mode_option) {
3656 if (!fb_find_mode(&var, &info->fb_info, mode_option, NULL, 0, NULL, 8))
3657 var = default_var;
3658 } else
3659 var = default_var;
3660 #else
3661 if (!fb_find_mode(&var, &info->fb_info, mode_option, NULL, 0, NULL, 8))
3662 var = default_var;
3663 #endif /* !__sparc__ */
3664 #endif /* !CONFIG_PPC */
3665 #endif /* !MODULE */
3666 if (noaccel)
3667 var.accel_flags &= ~FB_ACCELF_TEXT;
3668 else
3669 var.accel_flags |= FB_ACCELF_TEXT;
3670
3671 if (var.yres == var.yres_virtual) {
3672 u32 vram = (info->total_vram - (PAGE_SIZE << 2));
3673 var.yres_virtual = ((vram * 8) / var.bits_per_pixel) / var.xres_virtual;
3674 if (var.yres_virtual < var.yres)
3675 var.yres_virtual = var.yres;
3676 }
3677
3678 if (atyfb_decode_var(&var, &info->default_par, info)) {
3679 printk("atyfb: can't set default video mode\n");
3680 return 0;
3681 }
3682
3683 #ifdef __sparc__
3684 atyfb_save_palette(&info->fb_info, 0);
3685 #endif
3686 for (j = 0; j < 16; j++) {
3687 k = color_table[j];
3688 info->palette[j].red = default_red[k];
3689 info->palette[j].green = default_grn[k];
3690 info->palette[j].blue = default_blu[k];
3691 }
3692
3693 if (Gx != GX_CHIP_ID && Gx != CX_CHIP_ID) {
3694 info->cursor = aty_init_cursor(info);
3695 if (info->cursor) {
3696 info->dispsw.cursor = atyfb_cursor;
3697 info->dispsw.set_font = atyfb_set_font;
3698 }
3699 }
3700
3701 atyfb_set_var(&var, -1, &info->fb_info);
3702
3703 if (register_framebuffer(&info->fb_info) < 0)
3704 return 0;
3705
3706 info->next = fb_list;
3707 fb_list = info;
3708
3709 printk("fb%d: %s frame buffer device on %s\n",
3710 GET_FB_IDX(info->fb_info.node), atyfb_name, name);
3711 return 1;
3712 }
3713
3714 int __init atyfb_init(void)
3715 {
3716 #if defined(CONFIG_PCI)
3717 struct pci_dev *pdev = NULL;
3718 struct fb_info_aty *info;
3719 unsigned long addr, res_start, res_size;
3720 int i;
3721 #ifdef __sparc__
3722 extern void (*prom_palette) (int);
3723 extern int con_is_present(void);
3724 struct pcidev_cookie *pcp;
3725 char prop[128];
3726 int node, len, j;
3727 u32 mem, chip_id;
3728
3729 /* Do not attach when we have a serial console. */
3730 if (!con_is_present())
3731 return -ENXIO;
3732 #else
3733 u16 tmp;
3734 #endif
3735
3736 while ((pdev = pci_find_device(PCI_VENDOR_ID_ATI, PCI_ANY_ID, pdev))) {
3737 if ((pdev->class >> 16) == PCI_BASE_CLASS_DISPLAY) {
3738 struct resource *rp;
3739
3740 for (i = sizeof(aty_features)/sizeof(*aty_features)-1; i >= 0; i--)
3741 if (pdev->device == aty_features[i].pci_id)
3742 break;
3743 if (i < 0)
3744 continue;
3745
3746 info = kmalloc(sizeof(struct fb_info_aty), GFP_ATOMIC);
3747 if (!info) {
3748 printk("atyfb_init: can't alloc fb_info_aty\n");
3749 return -ENXIO;
3750 }
3751 memset(info, 0, sizeof(struct fb_info_aty));
3752
3753 rp = &pdev->resource[0];
3754 if (rp->flags & IORESOURCE_IO)
3755 rp = &pdev->resource[1];
3756 addr = rp->start;
3757 if (!addr)
3758 continue;
3759
3760 res_start = rp->start;
3761 res_size = rp->end-rp->start+1;
3762 if (!request_mem_region(res_start, res_size, "atyfb"))
3763 continue;
3764
3765 #ifdef __sparc__
3766 /*
3767 * Map memory-mapped registers.
3768 */
3769 info->ati_regbase = addr + 0x7ffc00UL;
3770 info->ati_regbase_phys = addr + 0x7ffc00UL;
3771
3772 /*
3773 * Map in big-endian aperture.
3774 */
3775 info->frame_buffer = (unsigned long) addr + 0x800000UL;
3776 info->frame_buffer_phys = addr + 0x800000UL;
3777
3778 /*
3779 * Figure mmap addresses from PCI config space.
3780 * Split Framebuffer in big- and little-endian halfs.
3781 */
3782 for (i = 0; i < 6 && pdev->resource[i].start; i++)
3783 /* nothing */;
3784 j = i + 4;
3785
3786 info->mmap_map = kmalloc(j * sizeof(*info->mmap_map), GFP_ATOMIC);
3787 if (!info->mmap_map) {
3788 printk("atyfb_init: can't alloc mmap_map\n");
3789 kfree(info);
3790 release_mem_region(res_start, res_size);
3791 return -ENXIO;
3792 }
3793 memset(info->mmap_map, 0, j * sizeof(*info->mmap_map));
3794
3795 for (i = 0, j = 2; i < 6 && pdev->resource[i].start; i++) {
3796 struct resource *rp = &pdev->resource[i];
3797 int io, breg = PCI_BASE_ADDRESS_0 + (i << 2);
3798 unsigned long base;
3799 u32 size, pbase;
3800
3801 base = rp->start;
3802
3803 io = (rp->flags & IORESOURCE_IO);
3804
3805 size = rp->end - base + 1;
3806
3807 pci_read_config_dword(pdev, breg, &pbase);
3808
3809 if (io)
3810 size &= ~1;
3811
3812 /*
3813 * Map the framebuffer a second time, this time without
3814 * the braindead _PAGE_IE setting. This is used by the
3815 * fixed Xserver, but we need to maintain the old mapping
3816 * to stay compatible with older ones...
3817 */
3818 if (base == addr) {
3819 info->mmap_map[j].voff = (pbase + 0x10000000) & PAGE_MASK;
3820 info->mmap_map[j].poff = base & PAGE_MASK;
3821 info->mmap_map[j].size = (size + ~PAGE_MASK) & PAGE_MASK;
3822 info->mmap_map[j].prot_mask = _PAGE_CACHE;
3823 info->mmap_map[j].prot_flag = _PAGE_E;
3824 j++;
3825 }
3826
3827 /*
3828 * Here comes the old framebuffer mapping with _PAGE_IE
3829 * set for the big endian half of the framebuffer...
3830 */
3831 if (base == addr) {
3832 info->mmap_map[j].voff = (pbase + 0x800000) & PAGE_MASK;
3833 info->mmap_map[j].poff = (base+0x800000) & PAGE_MASK;
3834 info->mmap_map[j].size = 0x800000;
3835 info->mmap_map[j].prot_mask = _PAGE_CACHE;
3836 info->mmap_map[j].prot_flag = _PAGE_E|_PAGE_IE;
3837 size -= 0x800000;
3838 j++;
3839 }
3840
3841 info->mmap_map[j].voff = pbase & PAGE_MASK;
3842 info->mmap_map[j].poff = base & PAGE_MASK;
3843 info->mmap_map[j].size = (size + ~PAGE_MASK) & PAGE_MASK;
3844 info->mmap_map[j].prot_mask = _PAGE_CACHE;
3845 info->mmap_map[j].prot_flag = _PAGE_E;
3846 j++;
3847 }
3848
3849 /*
3850 * Fix PROMs idea of MEM_CNTL settings...
3851 */
3852 mem = aty_ld_le32(MEM_CNTL, info);
3853 chip_id = aty_ld_le32(CONFIG_CHIP_ID, info);
3854 if (((chip_id & CFG_CHIP_TYPE) == VT_CHIP_ID) &&
3855 !((chip_id >> 24) & 1)) {
3856 switch (mem & 0x0f) {
3857 case 3:
3858 mem = (mem & ~(0x0f)) | 2;
3859 break;
3860 case 7:
3861 mem = (mem & ~(0x0f)) | 3;
3862 break;
3863 case 9:
3864 mem = (mem & ~(0x0f)) | 4;
3865 break;
3866 case 11:
3867 mem = (mem & ~(0x0f)) | 5;
3868 break;
3869 default:
3870 break;
3871 }
3872 if ((aty_ld_le32(CONFIG_STAT0, info) & 7) >= SDRAM)
3873 mem &= ~(0x00700000);
3874 }
3875 mem &= ~(0xcf80e000); /* Turn off all undocumented bits. */
3876 aty_st_le32(MEM_CNTL, mem, info);
3877
3878 /*
3879 * If this is the console device, we will set default video
3880 * settings to what the PROM left us with.
3881 */
3882 node = prom_getchild(prom_root_node);
3883 node = prom_searchsiblings(node, "aliases");
3884 if (node) {
3885 len = prom_getproperty(node, "screen", prop, sizeof(prop));
3886 if (len > 0) {
3887 prop[len] = '\0';
3888 node = prom_finddevice(prop);
3889 } else {
3890 node = 0;
3891 }
3892 }
3893
3894 pcp = pdev->sysdata;
3895 if (node == pcp->prom_node) {
3896
3897 struct fb_var_screeninfo *var = &default_var;
3898 unsigned int N, P, Q, M, T;
3899 u32 v_total, h_total;
3900 struct crtc crtc;
3901 u8 pll_regs[16];
3902 u8 clock_cntl;
3903
3904 crtc.vxres = prom_getintdefault(node, "width", 1024);
3905 crtc.vyres = prom_getintdefault(node, "height", 768);
3906 crtc.bpp = prom_getintdefault(node, "depth", 8);
3907 crtc.xoffset = crtc.yoffset = 0;
3908 crtc.h_tot_disp = aty_ld_le32(CRTC_H_TOTAL_DISP, info);
3909 crtc.h_sync_strt_wid = aty_ld_le32(CRTC_H_SYNC_STRT_WID, info);
3910 crtc.v_tot_disp = aty_ld_le32(CRTC_V_TOTAL_DISP, info);
3911 crtc.v_sync_strt_wid = aty_ld_le32(CRTC_V_SYNC_STRT_WID, info);
3912 crtc.gen_cntl = aty_ld_le32(CRTC_GEN_CNTL, info);
3913 aty_crtc_to_var(&crtc, var);
3914
3915 h_total = var->xres + var->right_margin +
3916 var->hsync_len + var->left_margin;
3917 v_total = var->yres + var->lower_margin +
3918 var->vsync_len + var->upper_margin;
3919
3920 /*
3921 * Read the PLL to figure actual Refresh Rate.
3922 */
3923 clock_cntl = aty_ld_8(CLOCK_CNTL, info);
3924 /* printk("atyfb: CLOCK_CNTL: %02x\n", clock_cntl); */
3925 for (i = 0; i < 16; i++)
3926 pll_regs[i] = aty_ld_pll(i, info);
3927
3928 /*
3929 * PLL Reference Devider M:
3930 */
3931 M = pll_regs[2];
3932
3933 /*
3934 * PLL Feedback Devider N (Dependant on CLOCK_CNTL):
3935 */
3936 N = pll_regs[7 + (clock_cntl & 3)];
3937
3938 /*
3939 * PLL Post Devider P (Dependant on CLOCK_CNTL):
3940 */
3941 P = 1 << (pll_regs[6] >> ((clock_cntl & 3) << 1));
3942
3943 /*
3944 * PLL Devider Q:
3945 */
3946 Q = N / P;
3947
3948 /*
3949 * Target Frequency:
3950 *
3951 * T * M
3952 * Q = -------
3953 * 2 * R
3954 *
3955 * where R is XTALIN (= 14318 kHz).
3956 */
3957 T = 2 * Q * 14318 / M;
3958
3959 default_var.pixclock = 1000000000 / T;
3960 }
3961
3962 #else /* __sparc__ */
3963
3964 info->ati_regbase_phys = 0x7ff000 + addr;
3965 info->ati_regbase = (unsigned long)
3966 ioremap(info->ati_regbase_phys, 0x1000);
3967
3968 if(!info->ati_regbase) {
3969 kfree(info);
3970 release_mem_region(res_start, res_size);
3971 return -ENOMEM;
3972 }
3973
3974 info->ati_regbase_phys += 0xc00;
3975 info->ati_regbase += 0xc00;
3976
3977 /*
3978 * Enable memory-space accesses using config-space
3979 * command register.
3980 */
3981 pci_read_config_word(pdev, PCI_COMMAND, &tmp);
3982 if (!(tmp & PCI_COMMAND_MEMORY)) {
3983 tmp |= PCI_COMMAND_MEMORY;
3984 pci_write_config_word(pdev, PCI_COMMAND, tmp);
3985 }
3986
3987 #ifdef __BIG_ENDIAN
3988 /* Use the big-endian aperture */
3989 addr += 0x800000;
3990 #endif
3991
3992 /* Map in frame buffer */
3993 info->frame_buffer_phys = addr;
3994 info->frame_buffer = (unsigned long)ioremap(addr, 0x800000);
3995
3996 if(!info->frame_buffer) {
3997 kfree(info);
3998 release_mem_region(res_start, res_size);
3999 return -ENXIO;
4000 }
4001
4002 #endif /* __sparc__ */
4003
4004 if (!aty_init(info, "PCI")) {
4005 if (info->mmap_map)
4006 kfree(info->mmap_map);
4007 kfree(info);
4008 release_mem_region(res_start, res_size);
4009 return -ENXIO;
4010 }
4011
4012 #ifdef __sparc__
4013 if (!prom_palette)
4014 prom_palette = atyfb_palette;
4015
4016 /*
4017 * Add /dev/fb mmap values.
4018 */
4019 info->mmap_map[0].voff = 0x8000000000000000UL;
4020 info->mmap_map[0].poff = info->frame_buffer & PAGE_MASK;
4021 info->mmap_map[0].size = info->total_vram;
4022 info->mmap_map[0].prot_mask = _PAGE_CACHE;
4023 info->mmap_map[0].prot_flag = _PAGE_E;
4024 info->mmap_map[1].voff = info->mmap_map[0].voff + info->total_vram;
4025 info->mmap_map[1].poff = info->ati_regbase & PAGE_MASK;
4026 info->mmap_map[1].size = PAGE_SIZE;
4027 info->mmap_map[1].prot_mask = _PAGE_CACHE;
4028 info->mmap_map[1].prot_flag = _PAGE_E;
4029 #endif /* __sparc__ */
4030
4031 #ifdef CONFIG_PMAC_PBOOK
4032 if (first_display == NULL)
4033 pmu_register_sleep_notifier(&aty_sleep_notifier);
4034 info->next = first_display;
4035 first_display = info;
4036 #endif
4037
4038 #ifdef CONFIG_FB_COMPAT_XPMAC
4039 if (!console_fb_info)
4040 console_fb_info = &info->fb_info;
4041 #endif /* CONFIG_FB_COMPAT_XPMAC */
4042 }
4043 }
4044
4045 #elif defined(CONFIG_ATARI)
4046 u32 clock_r;
4047 int m64_num;
4048 struct fb_info_aty *info;
4049
4050 for (m64_num = 0; m64_num < mach64_count; m64_num++) {
4051 if (!phys_vmembase[m64_num] || !phys_size[m64_num] ||
4052 !phys_guiregbase[m64_num]) {
4053 printk(" phys_*[%d] parameters not set => returning early. \n",
4054 m64_num);
4055 continue;
4056 }
4057
4058 info = kmalloc(sizeof(struct fb_info_aty), GFP_ATOMIC);
4059 if (!info) {
4060 printk("atyfb_init: can't alloc fb_info_aty\n");
4061 return -ENOMEM;
4062 }
4063 memset(info, 0, sizeof(struct fb_info_aty));
4064
4065 /*
4066 * Map the video memory (physical address given) to somewhere in the
4067 * kernel address space.
4068 */
4069 info->frame_buffer = ioremap(phys_vmembase[m64_num], phys_size[m64_num]);
4070 info->frame_buffer_phys = info->frame_buffer; /* Fake! */
4071 info->ati_regbase = ioremap(phys_guiregbase[m64_num], 0x10000)+0xFC00ul;
4072 info->ati_regbase_phys = info->ati_regbase; /* Fake! */
4073
4074 aty_st_le32(CLOCK_CNTL, 0x12345678, info);
4075 clock_r = aty_ld_le32(CLOCK_CNTL, info);
4076
4077 switch (clock_r & 0x003F) {
4078 case 0x12:
4079 info->clk_wr_offset = 3; /* */
4080 break;
4081 case 0x34:
4082 info->clk_wr_offset = 2; /* Medusa ST-IO ISA Adapter etc. */
4083 break;
4084 case 0x16:
4085 info->clk_wr_offset = 1; /* */
4086 break;
4087 case 0x38:
4088 info->clk_wr_offset = 0; /* Panther 1 ISA Adapter (Gerald) */
4089 break;
4090 }
4091
4092 if (!aty_init(info, "ISA bus")) {
4093 kfree(info);
4094 /* This is insufficient! kernel_map has added two large chunks!! */
4095 return -ENXIO;
4096 }
4097 }
4098 #endif /* CONFIG_ATARI */
4099 return 0;
4100 }
4101
4102 #ifndef MODULE
4103 int __init atyfb_setup(char *options)
4104 {
4105 char *this_opt;
4106
4107 if (!options || !*options)
4108 return 0;
4109
4110 for (this_opt = strtok(options, ","); this_opt;
4111 this_opt = strtok(NULL, ",")) {
4112 if (!strncmp(this_opt, "font:", 5)) {
4113 char *p;
4114 int i;
4115
4116 p = this_opt + 5;
4117 for (i = 0; i < sizeof(fontname) - 1; i++)
4118 if (!*p || *p == ' ' || *p == ',')
4119 break;
4120 memcpy(fontname, this_opt + 5, i);
4121 fontname[i] = 0;
4122 } else if (!strncmp(this_opt, "noblink", 7)) {
4123 curblink = 0;
4124 } else if (!strncmp(this_opt, "noaccel", 7)) {
4125 noaccel = 1;
4126 } else if (!strncmp(this_opt, "vram:", 5))
4127 default_vram = simple_strtoul(this_opt+5, NULL, 0);
4128 else if (!strncmp(this_opt, "pll:", 4))
4129 default_pll = simple_strtoul(this_opt+4, NULL, 0);
4130 else if (!strncmp(this_opt, "mclk:", 5))
4131 default_mclk = simple_strtoul(this_opt+5, NULL, 0);
4132 #ifdef CONFIG_PPC
4133 else if (!strncmp(this_opt, "vmode:", 6)) {
4134 unsigned int vmode = simple_strtoul(this_opt+6, NULL, 0);
4135 if (vmode > 0 && vmode <= VMODE_MAX)
4136 default_vmode = vmode;
4137 } else if (!strncmp(this_opt, "cmode:", 6)) {
4138 unsigned int cmode = simple_strtoul(this_opt+6, NULL, 0);
4139 switch (cmode) {
4140 case 0:
4141 case 8:
4142 default_cmode = CMODE_8;
4143 break;
4144 case 15:
4145 case 16:
4146 default_cmode = CMODE_16;
4147 break;
4148 case 24:
4149 case 32:
4150 default_cmode = CMODE_32;
4151 break;
4152 }
4153 }
4154 #endif
4155 #ifdef CONFIG_ATARI
4156 /*
4157 * Why do we need this silly Mach64 argument?
4158 * We are already here because of mach64= so its redundant.
4159 */
4160 else if (MACH_IS_ATARI && (!strncmp(this_opt, "Mach64:", 7))) {
4161 static unsigned char m64_num;
4162 static char mach64_str[80];
4163 strncpy(mach64_str, this_opt+7, 80);
4164 if (!store_video_par(mach64_str, m64_num)) {
4165 m64_num++;
4166 mach64_count = m64_num;
4167 }
4168 }
4169 #endif
4170 else
4171 mode_option = this_opt;
4172 }
4173 return 0;
4174 }
4175 #endif /* !MODULE */
4176
4177 #ifdef CONFIG_ATARI
4178 static int __init store_video_par(char *video_str, unsigned char m64_num)
4179 {
4180 char *p;
4181 unsigned long vmembase, size, guiregbase;
4182
4183 printk("store_video_par() '%s' \n", video_str);
4184
4185 if (!(p = strtoke(video_str, ";")) || !*p)
4186 goto mach64_invalid;
4187 vmembase = simple_strtoul(p, NULL, 0);
4188 if (!(p = strtoke(NULL, ";")) || !*p)
4189 goto mach64_invalid;
4190 size = simple_strtoul(p, NULL, 0);
4191 if (!(p = strtoke(NULL, ";")) || !*p)
4192 goto mach64_invalid;
4193 guiregbase = simple_strtoul(p, NULL, 0);
4194
4195 phys_vmembase[m64_num] = vmembase;
4196 phys_size[m64_num] = size;
4197 phys_guiregbase[m64_num] = guiregbase;
4198 printk(" stored them all: $%08lX $%08lX $%08lX \n", vmembase, size,
4199 guiregbase);
4200 return 0;
4201
4202 mach64_invalid:
4203 phys_vmembase[m64_num] = 0;
4204 return -1;
4205 }
4206
4207 static char __init *strtoke(char *s, const char *ct)
4208 {
4209 static char *ssave = NULL;
4210 char *sbegin, *send;
4211
4212 sbegin = s ? s : ssave;
4213 if (!sbegin)
4214 return NULL;
4215 if (*sbegin == '\0') {
4216 ssave = NULL;
4217 return NULL;
4218 }
4219 send = strpbrk(sbegin, ct);
4220 if (send && *send != '\0')
4221 *send++ = '\0';
4222 ssave = send;
4223 return sbegin;
4224 }
4225 #endif /* CONFIG_ATARI */
4226
4227 static int atyfbcon_switch(int con, struct fb_info *fb)
4228 {
4229 struct fb_info_aty *info = (struct fb_info_aty *)fb;
4230 struct atyfb_par par;
4231
4232 /* Do we have to save the colormap? */
4233 if (fb_display[currcon].cmap.len)
4234 fb_get_cmap(&fb_display[currcon].cmap, 1, atyfb_getcolreg, fb);
4235
4236 /* Erase HW Cursor */
4237 if (info->cursor)
4238 atyfb_cursor(&fb_display[currcon], CM_ERASE,
4239 info->cursor->pos.x, info->cursor->pos.y);
4240
4241 currcon = con;
4242
4243 atyfb_decode_var(&fb_display[con].var, &par, info);
4244 atyfb_set_par(&par, info);
4245 atyfb_set_dispsw(&fb_display[con], info, par.crtc.bpp,
4246 par.accel_flags & FB_ACCELF_TEXT);
4247
4248 /* Install new colormap */
4249 do_install_cmap(con, fb);
4250
4251 /* Install hw cursor */
4252 if (info->cursor) {
4253 aty_set_cursor_color(info, cursor_pixel_map, cursor_color_map,
4254 cursor_color_map, cursor_color_map);
4255 aty_set_cursor_shape(info);
4256 }
4257 return 1;
4258 }
4259
4260 /*
4261 * Blank the display.
4262 */
4263
4264 static void atyfbcon_blank(int blank, struct fb_info *fb)
4265 {
4266 struct fb_info_aty *info = (struct fb_info_aty *)fb;
4267 u8 gen_cntl;
4268
4269 #ifdef CONFIG_PMAC_BACKLIGHT
4270 if ((_machine == _MACH_Pmac) && blank)
4271 set_backlight_enable(0);
4272 #endif /* CONFIG_PMAC_BACKLIGHT */
4273
4274 gen_cntl = aty_ld_8(CRTC_GEN_CNTL, info);
4275 if (blank > 0)
4276 switch (blank-1) {
4277 case VESA_NO_BLANKING:
4278 gen_cntl |= 0x40;
4279 break;
4280 case VESA_VSYNC_SUSPEND:
4281 gen_cntl |= 0x8;
4282 break;
4283 case VESA_HSYNC_SUSPEND:
4284 gen_cntl |= 0x4;
4285 break;
4286 case VESA_POWERDOWN:
4287 gen_cntl |= 0x4c;
4288 break;
4289 }
4290 else
4291 gen_cntl &= ~(0x4c);
4292 aty_st_8(CRTC_GEN_CNTL, gen_cntl, info);
4293
4294 #ifdef CONFIG_PMAC_BACKLIGHT
4295 if ((_machine == _MACH_Pmac) && !blank)
4296 set_backlight_enable(1);
4297 #endif /* CONFIG_PMAC_BACKLIGHT */
4298 }
4299
4300
4301 /*
4302 * Read a single color register and split it into
4303 * colors/transparent. Return != 0 for invalid regno.
4304 */
4305
4306 static int atyfb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
4307 u_int *transp, struct fb_info *fb)
4308 {
4309 struct fb_info_aty *info = (struct fb_info_aty *)fb;
4310
4311 if (regno > 255)
4312 return 1;
4313 *red = (info->palette[regno].red<<8) | info->palette[regno].red;
4314 *green = (info->palette[regno].green<<8) | info->palette[regno].green;
4315 *blue = (info->palette[regno].blue<<8) | info->palette[regno].blue;
4316 *transp = 0;
4317 return 0;
4318 }
4319
4320
4321 /*
4322 * Set a single color register. The values supplied are already
4323 * rounded down to the hardware's capabilities (according to the
4324 * entries in the var structure). Return != 0 for invalid regno.
4325 */
4326
4327 static int atyfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
4328 u_int transp, struct fb_info *fb)
4329 {
4330 struct fb_info_aty *info = (struct fb_info_aty *)fb;
4331 int i, scale;
4332
4333 if (regno > 255)
4334 return 1;
4335 red >>= 8;
4336 green >>= 8;
4337 blue >>= 8;
4338 info->palette[regno].red = red;
4339 info->palette[regno].green = green;
4340 info->palette[regno].blue = blue;
4341 i = aty_ld_8(DAC_CNTL, info) & 0xfc;
4342 if (Gx == GT_CHIP_ID || Gx == GU_CHIP_ID || Gx == GV_CHIP_ID ||
4343 Gx == GW_CHIP_ID || Gx == GZ_CHIP_ID || Gx == LG_CHIP_ID ||
4344 Gx == GB_CHIP_ID || Gx == GD_CHIP_ID || Gx == GI_CHIP_ID ||
4345 Gx == GP_CHIP_ID || Gx == GQ_CHIP_ID || Gx == LI_CHIP_ID)
4346 i |= 0x2; /*DAC_CNTL|0x2 turns off the extra brightness for gt*/
4347 aty_st_8(DAC_CNTL, i, info);
4348 aty_st_8(DAC_MASK, 0xff, info);
4349 scale = ((Gx != GX_CHIP_ID) && (Gx != CX_CHIP_ID) &&
4350 (info->current_par.crtc.bpp == 16)) ? 3 : 0;
4351 writeb(regno << scale, &info->aty_cmap_regs->windex);
4352 writeb(red, &info->aty_cmap_regs->lut);
4353 writeb(green, &info->aty_cmap_regs->lut);
4354 writeb(blue, &info->aty_cmap_regs->lut);
4355 if (regno < 16)
4356 switch (info->current_par.crtc.bpp) {
4357 #ifdef FBCON_HAS_CFB16
4358 case 16:
4359 info->fbcon_cmap.cfb16[regno] = (regno << 10) | (regno << 5) |
4360 regno;
4361 break;
4362 #endif
4363 #ifdef FBCON_HAS_CFB24
4364 case 24:
4365 info->fbcon_cmap.cfb24[regno] = (regno << 16) | (regno << 8) |
4366 regno;
4367 break;
4368 #endif
4369 #ifdef FBCON_HAS_CFB32
4370 case 32:
4371 i = (regno << 8) | regno;
4372 info->fbcon_cmap.cfb32[regno] = (i << 16) | i;
4373 break;
4374 #endif
4375 }
4376 return 0;
4377 }
4378
4379
4380 static void do_install_cmap(int con, struct fb_info *info)
4381 {
4382 if (con != currcon)
4383 return;
4384 if (fb_display[con].cmap.len)
4385 fb_set_cmap(&fb_display[con].cmap, 1, atyfb_setcolreg, info);
4386 else {
4387 int size = fb_display[con].var.bits_per_pixel == 16 ? 32 : 256;
4388 fb_set_cmap(fb_default_cmap(size), 1, atyfb_setcolreg, info);
4389 }
4390 }
4391
4392
4393 /*
4394 * Accelerated functions
4395 */
4396
4397 static inline void draw_rect(s16 x, s16 y, u16 width, u16 height,
4398 struct fb_info_aty *info)
4399 {
4400 /* perform rectangle fill */
4401 wait_for_fifo(2, info);
4402 aty_st_le32(DST_Y_X, (x << 16) | y, info);
4403 aty_st_le32(DST_HEIGHT_WIDTH, (width << 16) | height, info);
4404 info->blitter_may_be_busy = 1;
4405 }
4406
4407 static inline void aty_rectcopy(int srcx, int srcy, int dstx, int dsty,
4408 u_int width, u_int height,
4409 struct fb_info_aty *info)
4410 {
4411 u32 direction = DST_LAST_PEL;
4412 u32 pitch_value;
4413
4414 if (!width || !height)
4415 return;
4416
4417 pitch_value = info->current_par.crtc.vxres;
4418 if (info->current_par.crtc.bpp == 24) {
4419 /* In 24 bpp, the engine is in 8 bpp - this requires that all */
4420 /* horizontal coordinates and widths must be adjusted */
4421 pitch_value *= 3;
4422 srcx *= 3;
4423 dstx *= 3;
4424 width *= 3;
4425 }
4426
4427 if (srcy < dsty) {
4428 dsty += height - 1;
4429 srcy += height - 1;
4430 } else
4431 direction |= DST_Y_TOP_TO_BOTTOM;
4432
4433 if (srcx < dstx) {
4434 dstx += width - 1;
4435 srcx += width - 1;
4436 } else
4437 direction |= DST_X_LEFT_TO_RIGHT;
4438
4439 wait_for_fifo(4, info);
4440 aty_st_le32(DP_SRC, FRGD_SRC_BLIT, info);
4441 aty_st_le32(SRC_Y_X, (srcx << 16) | srcy, info);
4442 aty_st_le32(SRC_HEIGHT1_WIDTH1, (width << 16) | height, info);
4443 aty_st_le32(DST_CNTL, direction, info);
4444 draw_rect(dstx, dsty, width, height, info);
4445 }
4446
4447 static inline void aty_rectfill(int dstx, int dsty, u_int width, u_int height,
4448 u_int color, struct fb_info_aty *info)
4449 {
4450 if (!width || !height)
4451 return;
4452
4453 if (info->current_par.crtc.bpp == 24) {
4454 /* In 24 bpp, the engine is in 8 bpp - this requires that all */
4455 /* horizontal coordinates and widths must be adjusted */
4456 dstx *= 3;
4457 width *= 3;
4458 }
4459
4460 wait_for_fifo(3, info);
4461 aty_st_le32(DP_FRGD_CLR, color, info);
4462 aty_st_le32(DP_SRC, BKGD_SRC_BKGD_CLR | FRGD_SRC_FRGD_CLR | MONO_SRC_ONE,
4463 info);
4464 aty_st_le32(DST_CNTL, DST_LAST_PEL | DST_Y_TOP_TO_BOTTOM |
4465 DST_X_LEFT_TO_RIGHT, info);
4466 draw_rect(dstx, dsty, width, height, info);
4467 }
4468
4469 /*
4470 * Update the `var' structure (called by fbcon.c)
4471 */
4472
4473 static int atyfbcon_updatevar(int con, struct fb_info *fb)
4474 {
4475 struct fb_info_aty *info = (struct fb_info_aty *)fb;
4476 struct atyfb_par *par = &info->current_par;
4477 struct display *p = &fb_display[con];
4478 struct vc_data *conp = p->conp;
4479 u32 yres, yoffset, sy, height;
4480
4481 yres = ((par->crtc.v_tot_disp >> 16) & 0x7ff) + 1;
4482 yoffset = fb_display[con].var.yoffset;
4483
4484 sy = (conp->vc_rows + p->yscroll) * fontheight(p);
4485 height = yres - conp->vc_rows * fontheight(p);
4486
4487 if (height && (yoffset + yres > sy)) {
4488 u32 xres, xoffset;
4489 u32 bgx;
4490
4491 xres = (((par->crtc.h_tot_disp >> 16) & 0xff) + 1) * 8;
4492 xoffset = fb_display[con].var.xoffset;
4493
4494
4495 bgx = attr_bgcol_ec(p, conp);
4496 bgx |= (bgx << 8);
4497 bgx |= (bgx << 16);
4498
4499 if (sy + height > par->crtc.vyres) {
4500 wait_for_fifo(1, info);
4501 aty_st_le32(SC_BOTTOM, sy + height - 1, info);
4502 }
4503 aty_rectfill(xoffset, sy, xres, height, bgx, info);
4504 }
4505
4506 if (info->cursor && (yoffset + yres <= sy))
4507 atyfb_cursor(p, CM_ERASE, info->cursor->pos.x, info->cursor->pos.y);
4508
4509 info->current_par.crtc.yoffset = yoffset;
4510 set_off_pitch(&info->current_par, info);
4511 return 0;
4512 }
4513
4514 /*
4515 * Text console acceleration
4516 */
4517
4518 static void fbcon_aty_bmove(struct display *p, int sy, int sx, int dy, int dx,
4519 int height, int width)
4520 {
4521 #ifdef __sparc__
4522 struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info);
4523
4524 if (fb->mmaped && (!fb->fb_info.display_fg
4525 || fb->fb_info.display_fg->vc_num == fb->vtconsole))
4526 return;
4527 #endif
4528
4529 sx *= fontwidth(p);
4530 sy *= fontheight(p);
4531 dx *= fontwidth(p);
4532 dy *= fontheight(p);
4533 width *= fontwidth(p);
4534 height *= fontheight(p);
4535
4536 aty_rectcopy(sx, sy, dx, dy, width, height,
4537 (struct fb_info_aty *)p->fb_info);
4538 }
4539
4540 static void fbcon_aty_clear(struct vc_data *conp, struct display *p, int sy,
4541 int sx, int height, int width)
4542 {
4543 u32 bgx;
4544 #ifdef __sparc__
4545 struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info);
4546
4547 if (fb->mmaped && (!fb->fb_info.display_fg
4548 || fb->fb_info.display_fg->vc_num == fb->vtconsole))
4549 return;
4550 #endif
4551
4552 bgx = attr_bgcol_ec(p, conp);
4553 bgx |= (bgx << 8);
4554 bgx |= (bgx << 16);
4555
4556 sx *= fontwidth(p);
4557 sy *= fontheight(p);
4558 width *= fontwidth(p);
4559 height *= fontheight(p);
4560
4561 aty_rectfill(sx, sy, width, height, bgx,
4562 (struct fb_info_aty *)p->fb_info);
4563 }
4564
4565 #ifdef FBCON_HAS_CFB8
4566 static void fbcon_aty8_putc(struct vc_data *conp, struct display *p, int c,
4567 int yy, int xx)
4568 {
4569 struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info);
4570
4571 #ifdef __sparc__
4572 if (fb->mmaped && (!fb->fb_info.display_fg
4573 || fb->fb_info.display_fg->vc_num == fb->vtconsole))
4574 return;
4575 #endif
4576
4577 if (fb->blitter_may_be_busy)
4578 wait_for_idle((struct fb_info_aty *)p->fb_info);
4579 fbcon_cfb8_putc(conp, p, c, yy, xx);
4580 }
4581
4582 static void fbcon_aty8_putcs(struct vc_data *conp, struct display *p,
4583 const unsigned short *s, int count, int yy,
4584 int xx)
4585 {
4586 struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info);
4587
4588 #ifdef __sparc__
4589 if (fb->mmaped && (!fb->fb_info.display_fg
4590 || fb->fb_info.display_fg->vc_num == fb->vtconsole))
4591 return;
4592 #endif
4593
4594 if (fb->blitter_may_be_busy)
4595 wait_for_idle((struct fb_info_aty *)p->fb_info);
4596 fbcon_cfb8_putcs(conp, p, s, count, yy, xx);
4597 }
4598
4599 static void fbcon_aty8_clear_margins(struct vc_data *conp, struct display *p,
4600 int bottom_only)
4601 {
4602 struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info);
4603
4604 #ifdef __sparc__
4605 if (fb->mmaped && (!fb->fb_info.display_fg
4606 || fb->fb_info.display_fg->vc_num == fb->vtconsole))
4607 return;
4608 #endif
4609
4610 if (fb->blitter_may_be_busy)
4611 wait_for_idle((struct fb_info_aty *)p->fb_info);
4612 fbcon_cfb8_clear_margins(conp, p, bottom_only);
4613 }
4614
4615 static struct display_switch fbcon_aty8 = {
4616 setup: fbcon_cfb8_setup,
4617 bmove: fbcon_aty_bmove,
4618 clear: fbcon_aty_clear,
4619 putc: fbcon_aty8_putc,
4620 putcs: fbcon_aty8_putcs,
4621 revc: fbcon_cfb8_revc,
4622 clear_margins: fbcon_aty8_clear_margins,
4623 fontwidthmask: FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
4624 };
4625 #endif
4626
4627 #ifdef FBCON_HAS_CFB16
4628 static void fbcon_aty16_putc(struct vc_data *conp, struct display *p, int c,
4629 int yy, int xx)
4630 {
4631 struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info);
4632
4633 #ifdef __sparc__
4634 if (fb->mmaped && (!fb->fb_info.display_fg
4635 || fb->fb_info.display_fg->vc_num == fb->vtconsole))
4636 return;
4637 #endif
4638
4639 if (fb->blitter_may_be_busy)
4640 wait_for_idle((struct fb_info_aty *)p->fb_info);
4641 fbcon_cfb16_putc(conp, p, c, yy, xx);
4642 }
4643
4644 static void fbcon_aty16_putcs(struct vc_data *conp, struct display *p,
4645 const unsigned short *s, int count, int yy,
4646 int xx)
4647 {
4648 struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info);
4649
4650 #ifdef __sparc__
4651 if (fb->mmaped && (!fb->fb_info.display_fg
4652 || fb->fb_info.display_fg->vc_num == fb->vtconsole))
4653 return;
4654 #endif
4655
4656 if (fb->blitter_may_be_busy)
4657 wait_for_idle((struct fb_info_aty *)p->fb_info);
4658 fbcon_cfb16_putcs(conp, p, s, count, yy, xx);
4659 }
4660
4661 static void fbcon_aty16_clear_margins(struct vc_data *conp, struct display *p,
4662 int bottom_only)
4663 {
4664 struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info);
4665
4666 #ifdef __sparc__
4667 if (fb->mmaped && (!fb->fb_info.display_fg
4668 || fb->fb_info.display_fg->vc_num == fb->vtconsole))
4669 return;
4670 #endif
4671
4672 if (fb->blitter_may_be_busy)
4673 wait_for_idle((struct fb_info_aty *)p->fb_info);
4674 fbcon_cfb16_clear_margins(conp, p, bottom_only);
4675 }
4676
4677 static struct display_switch fbcon_aty16 = {
4678 setup: fbcon_cfb16_setup,
4679 bmove: fbcon_aty_bmove,
4680 clear: fbcon_aty_clear,
4681 putc: fbcon_aty16_putc,
4682 putcs: fbcon_aty16_putcs,
4683 revc: fbcon_cfb16_revc,
4684 clear_margins: fbcon_aty16_clear_margins,
4685 fontwidthmask: FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
4686 };
4687 #endif
4688
4689 #ifdef FBCON_HAS_CFB24
4690 static void fbcon_aty24_putc(struct vc_data *conp, struct display *p, int c,
4691 int yy, int xx)
4692 {
4693 struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info);
4694
4695 #ifdef __sparc__
4696 if (fb->mmaped && (!fb->fb_info.display_fg
4697 || fb->fb_info.display_fg->vc_num == fb->vtconsole))
4698 return;
4699 #endif
4700
4701 if (fb->blitter_may_be_busy)
4702 wait_for_idle((struct fb_info_aty *)p->fb_info);
4703 fbcon_cfb24_putc(conp, p, c, yy, xx);
4704 }
4705
4706 static void fbcon_aty24_putcs(struct vc_data *conp, struct display *p,
4707 const unsigned short *s, int count, int yy,
4708 int xx)
4709 {
4710 struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info);
4711
4712 #ifdef __sparc__
4713 if (fb->mmaped && (!fb->fb_info.display_fg
4714 || fb->fb_info.display_fg->vc_num == fb->vtconsole))
4715 return;
4716 #endif
4717
4718 if (fb->blitter_may_be_busy)
4719 wait_for_idle((struct fb_info_aty *)p->fb_info);
4720 fbcon_cfb24_putcs(conp, p, s, count, yy, xx);
4721 }
4722
4723 static void fbcon_aty24_clear_margins(struct vc_data *conp, struct display *p,
4724 int bottom_only)
4725 {
4726 struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info);
4727
4728 #ifdef __sparc__
4729 if (fb->mmaped && (!fb->fb_info.display_fg
4730 || fb->fb_info.display_fg->vc_num == fb->vtconsole))
4731 return;
4732 #endif
4733
4734 if (fb->blitter_may_be_busy)
4735 wait_for_idle((struct fb_info_aty *)p->fb_info);
4736 fbcon_cfb24_clear_margins(conp, p, bottom_only);
4737 }
4738
4739 static struct display_switch fbcon_aty24 = {
4740 setup: fbcon_cfb24_setup,
4741 bmove: fbcon_aty_bmove,
4742 clear: fbcon_aty_clear,
4743 putc: fbcon_aty24_putc,
4744 putcs: fbcon_aty24_putcs,
4745 revc: fbcon_cfb24_revc,
4746 clear_margins: fbcon_aty24_clear_margins,
4747 fontwidthmask: FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
4748 };
4749 #endif
4750
4751 #ifdef FBCON_HAS_CFB32
4752 static void fbcon_aty32_putc(struct vc_data *conp, struct display *p, int c,
4753 int yy, int xx)
4754 {
4755 struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info);
4756
4757 #ifdef __sparc__
4758 if (fb->mmaped && (!fb->fb_info.display_fg
4759 || fb->fb_info.display_fg->vc_num == fb->vtconsole))
4760 return;
4761 #endif
4762
4763 if (fb->blitter_may_be_busy)
4764 wait_for_idle((struct fb_info_aty *)p->fb_info);
4765 fbcon_cfb32_putc(conp, p, c, yy, xx);
4766 }
4767
4768 static void fbcon_aty32_putcs(struct vc_data *conp, struct display *p,
4769 const unsigned short *s, int count, int yy,
4770 int xx)
4771 {
4772 struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info);
4773
4774 #ifdef __sparc__
4775 if (fb->mmaped && (!fb->fb_info.display_fg
4776 || fb->fb_info.display_fg->vc_num == fb->vtconsole))
4777 return;
4778 #endif
4779
4780 if (fb->blitter_may_be_busy)
4781 wait_for_idle((struct fb_info_aty *)p->fb_info);
4782 fbcon_cfb32_putcs(conp, p, s, count, yy, xx);
4783 }
4784
4785 static void fbcon_aty32_clear_margins(struct vc_data *conp, struct display *p,
4786 int bottom_only)
4787 {
4788 struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info);
4789
4790 #ifdef __sparc__
4791 if (fb->mmaped && (!fb->fb_info.display_fg
4792 || fb->fb_info.display_fg->vc_num == fb->vtconsole))
4793 return;
4794 #endif
4795
4796 if (fb->blitter_may_be_busy)
4797 wait_for_idle((struct fb_info_aty *)p->fb_info);
4798 fbcon_cfb32_clear_margins(conp, p, bottom_only);
4799 }
4800
4801 static struct display_switch fbcon_aty32 = {
4802 setup: fbcon_cfb32_setup,
4803 bmove: fbcon_aty_bmove,
4804 clear: fbcon_aty_clear,
4805 putc: fbcon_aty32_putc,
4806 putcs: fbcon_aty32_putcs,
4807 revc: fbcon_cfb32_revc,
4808 clear_margins: fbcon_aty32_clear_margins,
4809 fontwidthmask: FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
4810 };
4811 #endif
4812
4813 #ifdef CONFIG_PMAC_PBOOK
4814
4815 /* Power management routines. Those are used for PowerBook sleep.
4816 *
4817 * It appears that Rage LT and Rage LT Pro have different power
4818 * management registers. There's is some confusion about which
4819 * chipID is a Rage LT or LT pro :(
4820 */
4821 static int
4822 aty_power_mgmt_LT(int sleep, struct fb_info_aty *info)
4823 {
4824 unsigned int pm;
4825 int timeout;
4826
4827 pm = aty_ld_le32(POWER_MANAGEMENT_LG, info);
4828 pm = (pm & ~PWR_MGT_MODE_MASK) | PWR_MGT_MODE_REG;
4829 aty_st_le32(POWER_MANAGEMENT_LG, pm, info);
4830 pm = aty_ld_le32(POWER_MANAGEMENT_LG, info);
4831
4832 timeout = 200000;
4833 if (sleep) {
4834 /* Sleep */
4835 pm &= ~PWR_MGT_ON;
4836 aty_st_le32(POWER_MANAGEMENT_LG, pm, info);
4837 pm = aty_ld_le32(POWER_MANAGEMENT_LG, info);
4838 udelay(10);
4839 pm &= ~(PWR_BLON | AUTO_PWR_UP);
4840 pm |= SUSPEND_NOW;
4841 aty_st_le32(POWER_MANAGEMENT_LG, pm, info);
4842 pm = aty_ld_le32(POWER_MANAGEMENT_LG, info);
4843 udelay(10);
4844 pm |= PWR_MGT_ON;
4845 aty_st_le32(POWER_MANAGEMENT_LG, pm, info);
4846 do {
4847 pm = aty_ld_le32(POWER_MANAGEMENT_LG, info);
4848 udelay(10);
4849 if ((--timeout) == 0)
4850 break;
4851 } while ((pm & PWR_MGT_STATUS_MASK) != PWR_MGT_STATUS_SUSPEND);
4852 } else {
4853 /* Wakeup */
4854 pm &= ~PWR_MGT_ON;
4855 aty_st_le32(POWER_MANAGEMENT_LG, pm, info);
4856 pm = aty_ld_le32(POWER_MANAGEMENT_LG, info);
4857 udelay(10);
4858 pm |= (PWR_BLON | AUTO_PWR_UP);
4859 pm &= ~SUSPEND_NOW;
4860 aty_st_le32(POWER_MANAGEMENT_LG, pm, info);
4861 pm = aty_ld_le32(POWER_MANAGEMENT_LG, info);
4862 udelay(10);
4863 pm |= PWR_MGT_ON;
4864 aty_st_le32(POWER_MANAGEMENT_LG, pm, info);
4865 do {
4866 pm = aty_ld_le32(POWER_MANAGEMENT_LG, info);
4867 udelay(10);
4868 if ((--timeout) == 0)
4869 break;
4870 } while ((pm & PWR_MGT_STATUS_MASK) != 0);
4871 }
4872 mdelay(500);
4873
4874 return timeout ? PBOOK_SLEEP_OK : PBOOK_SLEEP_REFUSE;
4875 }
4876
4877 static int
4878 aty_power_mgmt_LTPro(int sleep, struct fb_info_aty *info)
4879 {
4880 unsigned int pm;
4881 int timeout;
4882
4883 pm = aty_ld_lcd(LCD_POWER_MANAGEMENT, info);
4884 pm = (pm & ~PWR_MGT_MODE_MASK) | PWR_MGT_MODE_REG;
4885 aty_st_lcd(LCD_POWER_MANAGEMENT, pm, info);
4886 pm = aty_ld_lcd(LCD_POWER_MANAGEMENT, info);
4887
4888 timeout = 200;
4889 if (sleep) {
4890 /* Sleep */
4891 pm &= ~PWR_MGT_ON;
4892 aty_st_lcd(LCD_POWER_MANAGEMENT, pm, info);
4893 pm = aty_ld_lcd(LCD_POWER_MANAGEMENT, info);
4894 udelay(10);
4895 pm &= ~(PWR_BLON | AUTO_PWR_UP);
4896 pm |= SUSPEND_NOW;
4897 aty_st_lcd(LCD_POWER_MANAGEMENT, pm, info);
4898 pm = aty_ld_lcd(LCD_POWER_MANAGEMENT, info);
4899 udelay(10);
4900 pm |= PWR_MGT_ON;
4901 aty_st_lcd(LCD_POWER_MANAGEMENT, pm, info);
4902 do {
4903 pm = aty_ld_lcd(LCD_POWER_MANAGEMENT, info);
4904 udelay(1000);
4905 if ((--timeout) == 0)
4906 break;
4907 } while ((pm & PWR_MGT_STATUS_MASK) != PWR_MGT_STATUS_SUSPEND);
4908 } else {
4909 /* Wakeup */
4910 pm &= ~PWR_MGT_ON;
4911 aty_st_lcd(LCD_POWER_MANAGEMENT, pm, info);
4912 pm = aty_ld_lcd(LCD_POWER_MANAGEMENT, info);
4913 udelay(10);
4914 pm &= ~SUSPEND_NOW;
4915 pm |= (PWR_BLON | AUTO_PWR_UP);
4916 aty_st_lcd(LCD_POWER_MANAGEMENT, pm, info);
4917 pm = aty_ld_lcd(LCD_POWER_MANAGEMENT, info);
4918 udelay(10);
4919 pm |= PWR_MGT_ON;
4920 aty_st_lcd(LCD_POWER_MANAGEMENT, pm, info);
4921 do {
4922 pm = aty_ld_lcd(LCD_POWER_MANAGEMENT, info);
4923 udelay(1000);
4924 if ((--timeout) == 0)
4925 break;
4926 } while ((pm & PWR_MGT_STATUS_MASK) != 0);
4927 }
4928
4929 return timeout ? PBOOK_SLEEP_OK : PBOOK_SLEEP_REFUSE;
4930 }
4931
4932 /*
4933 * Save the contents of the frame buffer when we go to sleep,
4934 * and restore it when we wake up again.
4935 */
4936 int
4937 aty_sleep_notify(struct pmu_sleep_notifier *self, int when)
4938 {
4939 struct fb_info_aty *info;
4940 int result;
4941
4942 result = PBOOK_SLEEP_OK;
4943
4944 for (info = first_display; info != NULL; info = info->next) {
4945 struct fb_fix_screeninfo fix;
4946 int nb;
4947
4948 atyfb_get_fix(&fix, fg_console, (struct fb_info *)info);
4949 nb = fb_display[fg_console].var.yres * fix.line_length;
4950
4951 switch (when) {
4952 case PBOOK_SLEEP_REQUEST:
4953 info->save_framebuffer = vmalloc(nb);
4954 if (info->save_framebuffer == NULL)
4955 return PBOOK_SLEEP_REFUSE;
4956 break;
4957 case PBOOK_SLEEP_REJECT:
4958 if (info->save_framebuffer) {
4959 vfree(info->save_framebuffer);
4960 info->save_framebuffer = 0;
4961 }
4962 break;
4963 case PBOOK_SLEEP_NOW:
4964 if (info->blitter_may_be_busy)
4965 wait_for_idle(info);
4966 /* Stop accel engine (stop bus mastering) */
4967 if (info->current_par.accel_flags & FB_ACCELF_TEXT)
4968 reset_engine(info);
4969
4970 /* Backup fb content */
4971 if (info->save_framebuffer)
4972 memcpy_fromio(info->save_framebuffer,
4973 (void *)info->frame_buffer, nb);
4974
4975 /* Blank display and LCD */
4976 atyfbcon_blank(VESA_POWERDOWN+1, (struct fb_info *)info);
4977
4978 /* Set chip to "suspend" mode */
4979 if (Gx == LG_CHIP_ID)
4980 result = aty_power_mgmt_LT(1, info);
4981 else
4982 result = aty_power_mgmt_LTPro(1, info);
4983 break;
4984 case PBOOK_WAKE:
4985 /* Wakeup chip */
4986 if (Gx == LG_CHIP_ID)
4987 result = aty_power_mgmt_LT(0, info);
4988 else
4989 result = aty_power_mgmt_LTPro(0, info);
4990
4991 /* Restore fb content */
4992 if (info->save_framebuffer) {
4993 memcpy_toio((void *)info->frame_buffer,
4994 info->save_framebuffer, nb);
4995 vfree(info->save_framebuffer);
4996 info->save_framebuffer = 0;
4997 }
4998 /* Restore display */
4999 atyfb_set_par(&info->current_par, info);
5000 atyfbcon_blank(0, (struct fb_info *)info);
5001 break;
5002 }
5003 }
5004 return result;
5005 }
5006 #endif /* CONFIG_PMAC_PBOOK */
5007
5008 #ifdef CONFIG_PMAC_BACKLIGHT
5009 static int backlight_conv[] = {
5010 0x00, 0x3f, 0x4c, 0x59, 0x66, 0x73, 0x80, 0x8d,
5011 0x9a, 0xa7, 0xb4, 0xc1, 0xcf, 0xdc, 0xe9, 0xff
5012 };
5013
5014 static int
5015 aty_set_backlight_enable(int on, int level, void* data)
5016 {
5017 struct fb_info_aty *info = (struct fb_info_aty *)data;
5018 unsigned int reg = aty_ld_lcd(LCD_MISC_CNTL, info);
5019
5020 reg |= (BLMOD_EN | BIASMOD_EN);
5021 if (on && level > BACKLIGHT_OFF) {
5022 reg &= ~BIAS_MOD_LEVEL_MASK;
5023 reg |= (backlight_conv[level] << BIAS_MOD_LEVEL_SHIFT);
5024 } else {
5025 reg &= ~BIAS_MOD_LEVEL_MASK;
5026 reg |= (backlight_conv[0] << BIAS_MOD_LEVEL_SHIFT);
5027 }
5028 aty_st_lcd(LCD_MISC_CNTL, reg, info);
5029
5030 return 0;
5031 }
5032
5033 static int
5034 aty_set_backlight_level(int level, void* data)
5035 {
5036 return aty_set_backlight_enable(1, level, data);
5037 }
5038
5039 #endif /* CONFIG_PMAC_BACKLIGHT */
5040
5041
5042 #ifdef MODULE
5043 int __init init_module(void)
5044 {
5045 atyfb_init();
5046 return fb_list ? 0 : -ENXIO;
5047 }
5048
5049 void cleanup_module(void)
5050 {
5051 while (fb_list) {
5052 struct fb_info_aty *info = fb_list;
5053 fb_list = info->next;
5054
5055 unregister_framebuffer(&info->fb_info);
5056
5057 #ifndef __sparc__
5058 if (info->ati_regbase)
5059 iounmap((void *)info->ati_regbase);
5060 if (info->frame_buffer)
5061 iounmap((void *)info->frame_buffer);
5062 #ifdef __BIG_ENDIAN
5063 if (info->cursor && info->cursor->ram)
5064 iounmap(info->cursor->ram);
5065 #endif
5066 #endif
5067
5068 if (info->cursor) {
5069 if (info->cursor->timer)
5070 kfree(info->cursor->timer);
5071 kfree(info->cursor);
5072 }
5073 #ifdef __sparc__
5074 if (info->mmap_map)
5075 kfree(info->mmap_map);
5076 #endif
5077 kfree(info);
5078 }
5079 }
5080
5081 #endif
5082
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.