52 #include <linux/module.h>
54 #include <linux/kernel.h>
55 #include <linux/errno.h>
56 #include <linux/string.h>
58 #include <linux/slab.h>
64 #include <linux/pci.h>
67 #include <linux/wait.h>
69 #include <linux/reboot.h>
80 #include <asm/machdep.h>
82 #include "../macmodes.h"
86 #include <asm/oplib.h>
91 #include <linux/adb.h>
92 #include <linux/pmu.h>
94 #ifdef CONFIG_BOOTX_TEXT
95 #include <asm/btext.h>
97 #ifdef CONFIG_PMAC_BACKLIGHT
113 #define GUI_RESERVE (1 * PAGE_SIZE)
116 #define FAIL(msg) do { \
117 if (!(var->activate & FB_ACTIVATE_TEST)) \
118 printk(KERN_CRIT "atyfb: " msg "\n"); \
121 #define FAIL_MAX(msg, x, _max_) do { \
123 if (!(var->activate & FB_ACTIVATE_TEST)) \
124 printk(KERN_CRIT "atyfb: " msg " %x(%x)\n", x, _max_); \
129 #define DPRINTK(fmt, args...) printk(KERN_DEBUG "atyfb: " fmt, ## args)
131 #define DPRINTK(fmt, args...)
134 #define PRINTKI(fmt, args...) printk(KERN_INFO "atyfb: " fmt, ## args)
135 #define PRINTKE(fmt, args...) printk(KERN_ERR "atyfb: " fmt, ## args)
137 #if defined(CONFIG_PM) || defined(CONFIG_PMAC_BACKLIGHT) || \
138 defined (CONFIG_FB_ATY_GENERIC_LCD) || defined(CONFIG_FB_ATY_BACKLIGHT)
139 static const u32 lt_lcd_regs[] = {
182 #ifdef CONFIG_FB_ATY_GENERIC_LCD
189 static void ATIReduceRatio(
int *Numerator,
int *Denominator)
191 int Multiplier, Divider, Remainder;
193 Multiplier = *Numerator;
194 Divider = *Denominator;
196 while ((Remainder = Multiplier % Divider)) {
197 Multiplier = Divider;
201 *Numerator /= Divider;
202 *Denominator /= Divider;
238 static int atyfb_blank(
int blank,
struct fb_info *
info);
254 static int aty_var_to_crtc(
const struct fb_info *
info,
257 static int aty_crtc_to_var(
const struct crtc *
crtc,
261 static int read_aty_sense(
const struct atyfb_par *par);
265 static struct fb_info *reboot_info;
273 640, 480, 640, 480, 0, 0, 8, 0,
274 {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
275 0, 0, -1, -1, 0, 39722, 48, 16, 33, 10, 96, 2,
281 NULL, 60, 640, 480, 39721, 40, 24, 32, 11, 96, 2,
285 static struct fb_ops atyfb_ops = {
287 .fb_open = atyfb_open,
288 .fb_release = atyfb_release,
289 .fb_check_var = atyfb_check_var,
290 .fb_set_par = atyfb_set_par,
291 .fb_setcolreg = atyfb_setcolreg,
292 .fb_pan_display = atyfb_pan_display,
293 .fb_blank = atyfb_blank,
294 .fb_ioctl = atyfb_ioctl,
299 .fb_mmap = atyfb_mmap,
301 .fb_sync = atyfb_sync,
312 static int comp_sync __devinitdata = -1;
315 #ifdef CONFIG_PMAC_BACKLIGHT
316 static int backlight __devinitdata = 1;
318 static int backlight __devinitdata = 0;
332 static unsigned int mach64_count __devinitdata = 0;
333 static unsigned long phys_vmembase[
FB_MAX] __devinitdata = { 0, };
334 static unsigned long phys_size[
FB_MAX] __devinitdata = { 0, };
335 static unsigned long phys_guiregbase[
FB_MAX] __devinitdata = { 0, };
339 #define ATI_CHIP_88800GX (M64F_GX)
340 #define ATI_CHIP_88800CX (M64F_GX)
342 #define ATI_CHIP_264CT (M64F_CT | M64F_INTEGRATED | M64F_CT_BUS | M64F_MAGIC_FIFO)
343 #define ATI_CHIP_264ET (M64F_CT | M64F_INTEGRATED | M64F_CT_BUS | M64F_MAGIC_FIFO)
345 #define ATI_CHIP_264VT (M64F_VT | M64F_INTEGRATED | M64F_VT_BUS | M64F_MAGIC_FIFO)
346 #define ATI_CHIP_264GT (M64F_GT | M64F_INTEGRATED | M64F_MAGIC_FIFO | M64F_EXTRA_BRIGHT)
348 #define ATI_CHIP_264VTB (M64F_VT | M64F_INTEGRATED | M64F_VT_BUS | M64F_GTB_DSP)
349 #define ATI_CHIP_264VT3 (M64F_VT | M64F_INTEGRATED | M64F_VT_BUS | M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL)
350 #define ATI_CHIP_264VT4 (M64F_VT | M64F_INTEGRATED | M64F_GTB_DSP)
353 #define ATI_CHIP_264LT (M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP)
356 #define ATI_MODERN_SET (M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP | M64F_EXTRA_BRIGHT)
358 #define ATI_CHIP_264GTB (ATI_MODERN_SET | M64F_SDRAM_MAGIC_PLL)
360 #define ATI_CHIP_264LTG (ATI_MODERN_SET | M64F_SDRAM_MAGIC_PLL)
362 #define ATI_CHIP_264GT2C (ATI_MODERN_SET | M64F_SDRAM_MAGIC_PLL | M64F_HW_TRIPLE)
363 #define ATI_CHIP_264GTPRO (ATI_MODERN_SET | M64F_SDRAM_MAGIC_PLL | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D)
364 #define ATI_CHIP_264LTPRO (ATI_MODERN_SET | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D)
366 #define ATI_CHIP_264XL (ATI_MODERN_SET | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D | M64F_XL_DLL | M64F_MFB_FORCE_4 | M64F_XL_MEM)
367 #define ATI_CHIP_MOBILITY (ATI_MODERN_SET | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D | M64F_XL_DLL | M64F_MFB_FORCE_4 | M64F_XL_MEM | M64F_MOBIL_BUS)
374 } aty_chips[] __devinitdata = {
375 #ifdef CONFIG_FB_ATY_GX
381 #ifdef CONFIG_FB_ATY_CT
407 {
PCI_CHIP_MACH64GQ,
"3D RAGE PRO (Mach64 GQ, PQFP, PCI, limited 3D)", 230, 100, 100, 125,
ATI_CHIP_264GTPRO },
437 for (i =
ARRAY_SIZE(aty_chips) - 1; i >= 0; i--)
438 if (par->
pci_id == aty_chips[i].pci_id)
444 name = aty_chips[
i].name;
456 #ifdef CONFIG_FB_ATY_GX
466 #ifdef CONFIG_FB_ATY_CT
468 switch (rev & 0x07) {
470 switch (rev & 0xc0) {
472 name =
"ATI264VT (A3) (Mach64 VT)";
480 name =
"ATI264VT2 (A4) (Mach64 VT)";
490 name =
"ATI264VT3 (B1) (Mach64 VT)";
498 name =
"ATI264VT3 (B2) (Mach64 VT)";
508 switch (rev & 0x07) {
510 name =
"3D RAGE II (Mach64 GT)";
518 name =
"3D RAGE II+ (Mach64 GT)";
530 PRINTKI(
"%s [0x%04x rev 0x%02x]\n", name, type, rev);
534 static char ram_dram[] __devinitdata =
"DRAM";
535 static char ram_resv[] __devinitdata =
"RESV";
536 #ifdef CONFIG_FB_ATY_GX
537 static char ram_vram[] __devinitdata =
"VRAM";
539 #ifdef CONFIG_FB_ATY_CT
540 static char ram_edo[] __devinitdata =
"EDO";
541 static char ram_sdram[] __devinitdata =
"SDRAM (1:1)";
542 static char ram_sgram[] __devinitdata =
"SGRAM (1:1)";
543 static char ram_sdram32[] __devinitdata =
"SDRAM (2:1) (32-bit)";
544 static char ram_wram[] __devinitdata =
"WRAM";
545 static char ram_off[] __devinitdata =
"OFF";
549 #ifdef CONFIG_FB_ATY_GX
550 static char *aty_gx_ram[8] __devinitdata = {
551 ram_dram, ram_vram, ram_vram, ram_dram,
552 ram_dram, ram_vram, ram_vram, ram_resv
556 #ifdef CONFIG_FB_ATY_CT
557 static char *aty_ct_ram[8] __devinitdata = {
558 ram_off, ram_dram, ram_edo, ram_edo,
559 ram_sdram, ram_sgram, ram_wram, ram_resv
561 static char *aty_xl_ram[8] __devinitdata = {
562 ram_off, ram_dram, ram_edo, ram_edo,
563 ram_sdram, ram_sgram, ram_sdram32, ram_resv
571 #ifdef CONFIG_FB_ATY_GENERIC_LCD
573 par->
pll.
ct.xres = 0;
574 if (par->lcd_table != 0) {
576 if (lcd_on_off &
LCD_ON) {
578 pixclock = par->lcd_pixclock;
585 #if defined(CONFIG_PPC)
600 sense = ((i & 0x3000) >> 3) | (i & 0x100);
606 sense |= ((i & 0x1000) >> 7) | ((i & 0x100) >> 4);
613 sense |= ((i & 0x2000) >> 10) | ((i & 0x100) >> 6);
634 #ifdef CONFIG_FB_ATY_GENERIC_LCD
635 if (par->lcd_table != 0) {
640 crtc->lcd_config_panel = aty_ld_lcd(
CNFG_PANEL, par);
663 #ifdef CONFIG_FB_ATY_GENERIC_LCD
664 if (par->lcd_table != 0) {
679 static void aty_set_crtc(
const struct atyfb_par *par,
const struct crtc *crtc)
681 #ifdef CONFIG_FB_ATY_GENERIC_LCD
682 if (par->lcd_table != 0) {
688 aty_st_lcd(
CNFG_PANEL, crtc->lcd_config_panel, par);
704 DPRINTK(
"set primary CRT to %ix%i %c%c composite %c\n",
705 ((((crtc->
h_tot_disp >> 16) & 0xff) + 1) << 3),
732 #ifdef CONFIG_FB_ATY_GENERIC_LCD
734 if (par->lcd_table != 0) {
739 DPRINTK(
"set shadow CRT to %ix%i %c%c\n",
740 ((((crtc->shadow_h_tot_disp >> 16) & 0xff) + 1) << 3),
741 (((crtc->shadow_v_tot_disp >> 16) & 0x7ff) + 1),
742 (crtc->shadow_h_sync_strt_wid & 0x200000) ?
'N' :
'P',
743 (crtc->shadow_v_sync_strt_wid & 0x200000) ?
'N' :
'P');
745 DPRINTK(
"SHADOW CRTC_H_TOTAL_DISP: %x\n",
746 crtc->shadow_h_tot_disp);
747 DPRINTK(
"SHADOW CRTC_H_SYNC_STRT_WID: %x\n",
748 crtc->shadow_h_sync_strt_wid);
749 DPRINTK(
"SHADOW CRTC_V_TOTAL_DISP: %x\n",
750 crtc->shadow_v_tot_disp);
751 DPRINTK(
"SHADOW CRTC_V_SYNC_STRT_WID: %x\n",
752 crtc->shadow_v_sync_strt_wid);
760 DPRINTK(
"LCD_GEN_CNTL: %x\n", crtc->lcd_gen_cntl);
761 DPRINTK(
"HORZ_STRETCHING: %x\n", crtc->horz_stretching);
762 DPRINTK(
"VERT_STRETCHING: %x\n", crtc->vert_stretching);
764 DPRINTK(
"EXT_VERT_STRETCH: %x\n", crtc->ext_vert_stretch);
780 u32 line_length = vxres * bpp / 8;
784 line_length = (line_length + 63) & ~63;
789 static int aty_var_to_crtc(
const struct fb_info *
info,
794 u32 xres, yres, vxres, vyres, xoffset, yoffset, bpp;
796 u32 h_total, h_disp, h_sync_strt, h_sync_end, h_sync_dly, h_sync_wid, h_sync_pol;
797 u32 v_total, v_disp, v_sync_strt, v_sync_end, v_sync_wid, v_sync_pol, c_sync;
798 u32 pix_width, dp_pix_width, dp_chain_mask;
802 xres = (var->
xres + 7) & ~7;
806 xoffset = (var->
xoffset + 7) & ~7;
810 bpp = (var->
green.length == 5) ? 15 : 16;
815 if (vxres < xres + xoffset)
816 vxres = xres + xoffset;
819 if (vyres < yres + yoffset)
820 vyres = yres + yoffset;
829 }
else if (bpp <= 15) {
835 }
else if (bpp <= 16) {
841 }
else if (bpp <= 24 &&
M64_HAS(INTEGRATED)) {
847 }
else if (bpp <= 32) {
856 line_length = calc_line_length(par, vxres, bpp);
858 if (vyres * line_length > info->
fix.smem_len)
859 FAIL(
"not enough video RAM");
864 if ((xres > 1600) || (yres > 1200)) {
865 FAIL(
"MACH64 chips are designed for max 1600x1200\n"
866 "select another resolution.");
869 h_sync_end = h_sync_strt + var->
hsync_len;
871 h_total = h_sync_end + h_sync_dly + var->
left_margin;
874 v_sync_end = v_sync_strt + var->
vsync_len;
877 #ifdef CONFIG_FB_ATY_GENERIC_LCD
878 if (par->lcd_table != 0) {
881 crtc->lcd_index = lcd_index &
890 crtc->lcd_config_panel = aty_ld_lcd(
CNFG_PANEL, par) | 0x4000;
893 crtc->lcd_gen_cntl &=
899 if ((crtc->lcd_gen_cntl &
LCD_ON) &&
900 ((xres > par->lcd_width) || (yres > par->lcd_height))) {
908 if (crtc->lcd_gen_cntl &
CRT_ON) {
910 PRINTKI(
"Disable LCD panel, because video mode does not fit.\n");
911 crtc->lcd_gen_cntl &= ~
LCD_ON;
915 PRINTKE(
"Video mode exceeds size of LCD panel.\nConnect this computer to a conventional monitor if you really need this mode.\n");
921 if ((par->lcd_table != 0) && (crtc->lcd_gen_cntl &
LCD_ON)) {
938 if (yres < par->lcd_height) {
939 VScan = par->lcd_height / yres;
946 h_sync_strt = h_disp + par->lcd_right_margin;
947 h_sync_end = h_sync_strt + par->lcd_hsync_len;
948 h_sync_dly = par->lcd_hsync_dly;
949 h_total = h_disp + par->lcd_hblank_len;
951 v_sync_strt = v_disp + par->lcd_lower_margin / VScan;
952 v_sync_end = v_sync_strt + par->lcd_vsync_len / VScan;
953 v_total = v_disp + par->lcd_vblank_len / VScan;
957 h_disp = (h_disp >> 3) - 1;
958 h_sync_strt = (h_sync_strt >> 3) - 1;
959 h_sync_end = (h_sync_end >> 3) - 1;
960 h_total = (h_total >> 3) - 1;
961 h_sync_wid = h_sync_end - h_sync_strt;
963 FAIL_MAX(
"h_disp too large", h_disp, 0xff);
964 FAIL_MAX(
"h_sync_strt too large", h_sync_strt, 0x1ff);
966 if (h_sync_wid > 0x1f)
968 FAIL_MAX(
"h_total too large", h_total, 0x1ff);
978 #ifdef CONFIG_FB_ATY_GENERIC_LCD
979 if ((par->lcd_table != 0) && (crtc->lcd_gen_cntl &
LCD_ON))
980 vdisplay = par->lcd_height;
987 v_sync_wid = v_sync_end - v_sync_strt;
989 FAIL_MAX(
"v_disp too large", v_disp, 0x7ff);
990 FAIL_MAX(
"v_sync_stsrt too large", v_sync_strt, 0x7ff);
992 if (v_sync_wid > 0x1f)
994 FAIL_MAX(
"v_total too large", v_total, 0x7ff);
1000 crtc->
vyres = vyres;
1005 ((yoffset * line_length + xoffset * bpp / 8) / 8) |
1006 ((line_length /
bpp) << 22);
1011 ((h_sync_strt & 0x100) << 4) | (h_sync_wid << 16) |
1022 if (vmode & FB_VMODE_DOUBLE)
1027 #ifdef CONFIG_FB_ATY_GENERIC_LCD
1028 if (par->lcd_table != 0) {
1030 if (vmode & FB_VMODE_DOUBLE)
1049 if (xres < par->lcd_width && crtc->lcd_gen_cntl &
LCD_ON) {
1065 int HDisplay = xres & ~7;
1066 int nStretch = par->lcd_width / HDisplay;
1067 int Remainder = par->lcd_width % HDisplay;
1069 if ((!Remainder && ((nStretch > 2))) ||
1070 (((HDisplay * 16) / par->lcd_width) < 7)) {
1071 static const char StretchLoops[] = { 10, 12, 13, 15, 16 };
1072 int horz_stretch_loop = -1, BestRemainder;
1073 int Numerator = HDisplay, Denominator = par->lcd_width;
1075 ATIReduceRatio(&Numerator, &Denominator);
1077 BestRemainder = (Numerator * 16) / Denominator;
1078 while (--Index >= 0) {
1079 Remainder = ((Denominator - Numerator) * StretchLoops[Index]) %
1081 if (Remainder < BestRemainder) {
1082 horz_stretch_loop = Index;
1083 if (!(BestRemainder = Remainder))
1088 if ((horz_stretch_loop >= 0) && !BestRemainder) {
1089 int horz_stretch_ratio = 0, Accumulator = 0;
1090 int reuse_previous = 1;
1092 Index = StretchLoops[horz_stretch_loop];
1094 while (--Index >= 0) {
1095 if (Accumulator > 0)
1096 horz_stretch_ratio |= reuse_previous;
1098 Accumulator += Denominator;
1099 Accumulator -= Numerator;
1100 reuse_previous <<= 1;
1115 if (vdisplay < par->lcd_height && crtc->lcd_gen_cntl &
LCD_ON) {
1120 xres <= (
M64_HAS(MOBIL_BUS) ? 1024 : 800))
1127 crtc->vert_stretching = 0;
1147 static int aty_crtc_to_var(
const struct crtc *crtc,
1151 u32 h_total, h_disp, h_sync_strt, h_sync_dly, h_sync_wid, h_sync_pol;
1152 u32 v_total, v_disp, v_sync_strt, v_sync_wid, v_sync_pol, c_sync;
1174 xres = (h_disp + 1) * 8;
1176 left = (h_total - h_sync_strt - h_sync_wid) * 8 - h_sync_dly;
1177 right = (h_sync_strt - h_disp) * 8 + h_sync_dly;
1178 hslen = h_sync_wid * 8;
1179 upper = v_total - v_sync_strt - v_sync_wid;
1180 lower = v_sync_strt - v_disp;
1186 switch (pix_width) {
1190 var->
red.offset = 0;
1191 var->
red.length = 8;
1192 var->
green.offset = 0;
1193 var->
green.length = 8;
1194 var->
blue.offset = 0;
1195 var->
blue.length = 8;
1202 var->
red.offset = 0;
1203 var->
red.length = 8;
1204 var->
green.offset = 0;
1205 var->
green.length = 8;
1206 var->
blue.offset = 0;
1207 var->
blue.length = 8;
1213 var->
red.offset = 10;
1214 var->
red.length = 5;
1215 var->
green.offset = 5;
1216 var->
green.length = 5;
1217 var->
blue.offset = 0;
1218 var->
blue.length = 5;
1224 var->
red.offset = 11;
1225 var->
red.length = 5;
1226 var->
green.offset = 5;
1227 var->
green.length = 6;
1228 var->
blue.offset = 0;
1229 var->
blue.length = 5;
1235 var->
red.offset = 16;
1236 var->
red.length = 8;
1237 var->
green.offset = 8;
1238 var->
green.length = 8;
1239 var->
blue.offset = 0;
1240 var->
blue.length = 8;
1246 var->
red.offset = 16;
1247 var->
red.length = 8;
1248 var->
green.offset = 8;
1249 var->
green.length = 8;
1250 var->
blue.offset = 0;
1251 var->
blue.length = 8;
1256 PRINTKE(
"Invalid pixel width\n");
1296 static int atyfb_set_par(
struct fb_info *info)
1309 err = aty_var_to_crtc(info, var, &par->
crtc);
1313 pixclock = atyfb_get_pixclock(var, par);
1315 if (pixclock == 0) {
1316 PRINTKE(
"Invalid pixclock\n");
1319 err = par->
pll_ops->var_to_pll(info, pixclock,
1328 info->
fbops->fb_sync = atyfb_sync;
1338 aty_set_crtc(par, &par->
crtc);
1345 pixclock_in_ps = par->
pll_ops->pll_to_var(info, &par->
pll);
1349 if (0 == pixclock_in_ps) {
1350 PRINTKE(
"ALERT ops->pll_to_var get 0\n");
1351 pixclock_in_ps = pixclock;
1355 if (!aty_crtc_to_var(&par->
crtc, &
debug)) {
1356 u32 hSync, vRefresh;
1357 u32 h_disp, h_sync_strt, h_sync_end, h_total;
1358 u32 v_disp, v_sync_strt, v_sync_end, v_total;
1360 h_disp =
debug.xres;
1361 h_sync_strt = h_disp +
debug.right_margin;
1362 h_sync_end = h_sync_strt +
debug.hsync_len;
1363 h_total = h_sync_end +
debug.left_margin;
1364 v_disp =
debug.yres;
1365 v_sync_strt = v_disp +
debug.lower_margin;
1366 v_sync_end = v_sync_strt +
debug.vsync_len;
1367 v_total = v_sync_end +
debug.upper_margin;
1369 hSync = 1000000000 / (pixclock_in_ps * h_total);
1370 vRefresh = (hSync * 1000) / v_total;
1377 DPRINTK(
" Set Visible Mode to %ix%i-%i\n",
1379 DPRINTK(
" Virtual resolution %ix%i, "
1380 "pixclock_in_ps %i (calculated %i)\n",
1382 pixclock, pixclock_in_ps);
1383 DPRINTK(
" Dot clock: %i MHz\n",
1384 1000000 / pixclock_in_ps);
1385 DPRINTK(
" Horizontal sync: %i kHz\n", hSync);
1386 DPRINTK(
" Vertical refresh: %i Hz\n", vRefresh);
1387 DPRINTK(
" x style: %i.%03i %i %i %i %i %i %i %i %i\n",
1388 1000000 / pixclock_in_ps, 1000000 % pixclock_in_ps,
1389 h_disp, h_sync_strt, h_sync_end, h_total,
1390 v_disp, v_sync_strt, v_sync_end, v_total);
1391 DPRINTK(
" fb style: %i %i %i %i %i %i %i %i %i\n",
1435 }
else if (
M64_HAS(MOBIL_BUS)) {
1458 #ifdef CONFIG_BOOTX_TEXT
1460 (((par->
crtc.h_tot_disp >> 16) & 0xff) + 1) * 8,
1461 ((par->
crtc.v_tot_disp >> 16) & 0x7ff) + 1,
1477 printk(
"debug atyfb: Mach64 non-shadow register values:");
1478 for (i = 0; i < 256; i = i+4) {
1480 printk(
"\ndebug atyfb: 0x%04X: ", base + i);
1485 #ifdef CONFIG_FB_ATY_CT
1488 printk(
"debug atyfb: Mach64 PLL register values:");
1489 for (i = 0; i < 64; i++) {
1491 printk(
"\ndebug atyfb: 0x%02X: ", base + i);
1499 #ifdef CONFIG_FB_ATY_GENERIC_LCD
1500 if (par->lcd_table != 0) {
1503 printk(
"debug atyfb: LCD register values:");
1508 printk(
"\ndebug atyfb: 0x%04X: ",
1510 printk(
" %08X", aty_ld_lcd(i, par));
1513 for (i = 0; i < 64; i++) {
1515 printk(
"\ndebug atyfb: 0x%02X: ",
1517 printk(
" %08X", aty_ld_lcd(i, par));
1538 err = aty_var_to_crtc(info, var, &crtc);
1542 pixclock = atyfb_get_pixclock(var, par);
1544 if (pixclock == 0) {
1546 PRINTKE(
"Invalid pixclock\n");
1549 err = par->
pll_ops->var_to_pll(info, pixclock,
1558 info->
var.accel_flags = 0;
1560 aty_crtc_to_var(&crtc, var);
1565 static void set_off_pitch(
struct atyfb_par *par,
const struct fb_info *info)
1567 u32 xoffset = info->
var.xoffset;
1568 u32 yoffset = info->
var.yoffset;
1569 u32 line_length = info->
fix.line_length;
1570 u32 bpp = info->
var.bits_per_pixel;
1572 par->
crtc.off_pitch =
1573 ((yoffset * line_length + xoffset * bpp / 8) / 8) |
1574 ((line_length /
bpp) << 22);
1582 static int atyfb_open(
struct fb_info *info,
int user)
1610 if (par->
vblank.pan_display) {
1611 par->
vblank.pan_display = 0;
1623 static int aty_enable_irq(
struct atyfb_par *par,
int reenable)
1639 }
else if (reenable) {
1643 printk(
"atyfb: someone disabled IRQ [%08x]\n",
1647 CRTC_VBLANK_INT_EN, par);
1655 static int aty_disable_irq(
struct atyfb_par *par)
1660 if (par->
vblank.pan_display) {
1661 par->
vblank.pan_display = 0;
1675 static int atyfb_release(
struct fb_info *info,
int user)
1693 was_mmaped = par->mmaped;
1711 if (var.yres == var.yres_virtual) {
1714 ((videoram * 8) / var.bits_per_pixel) /
1716 if (var.yres_virtual < var.yres)
1717 var.yres_virtual = var.yres;
1721 aty_disable_irq(par);
1736 u32 xres, yres, xoffset, yoffset;
1738 xres = (((par->
crtc.h_tot_disp >> 16) & 0xff) + 1) * 8;
1739 yres = ((par->
crtc.v_tot_disp >> 16) & 0x7ff) + 1;
1742 xoffset = (var->
xoffset + 7) & ~7;
1744 if (xoffset + xres > par->
crtc.vxres ||
1745 yoffset + yres > par->
crtc.vyres)
1747 info->
var.xoffset = xoffset;
1748 info->
var.yoffset = yoffset;
1752 set_off_pitch(par, info);
1754 par->
vblank.pan_display = 1;
1756 par->
vblank.pan_display = 0;
1763 static int aty_waitforvblank(
struct atyfb_par *par,
u32 crtc)
1777 ret = aty_enable_irq(par, 0);
1787 aty_enable_irq(par, 1);
1796 #define ATYIO_CLKR 0x41545900
1797 #define ATYIO_CLKW 0x41545901
1808 u32 dsp_xclks_per_row;
1809 u32 dsp_loop_latency;
1815 #define ATYIO_FEATR 0x41545902
1816 #define ATYIO_FEATW 0x41545903
1830 fbtyp.fb_width = par->
crtc.vxres;
1831 fbtyp.fb_height = par->
crtc.vyres;
1832 fbtyp.fb_depth = info->
var.bits_per_pixel;
1833 fbtyp.fb_cmsize = info->
cmap.len;
1834 fbtyp.fb_size = info->
fix.smem_len;
1848 return aty_waitforvblank(par, crtc);
1852 #if defined(DEBUG) && defined(CONFIG_FB_ATY_CT)
1857 u32 dsp_config = pll->
ct.dsp_config;
1858 u32 dsp_on_off = pll->
ct.dsp_on_off;
1860 clk.pll_ref_div = pll->
ct.pll_ref_div;
1861 clk.mclk_fb_div = pll->
ct.mclk_fb_div;
1862 clk.mclk_post_div = pll->
ct.mclk_post_div_real;
1863 clk.mclk_fb_mult = pll->
ct.mclk_fb_mult;
1864 clk.xclk_post_div = pll->
ct.xclk_post_div_real;
1865 clk.vclk_fb_div = pll->
ct.vclk_fb_div;
1866 clk.vclk_post_div = pll->
ct.vclk_post_div_real;
1867 clk.dsp_xclks_per_row = dsp_config & 0x3fff;
1868 clk.dsp_loop_latency = (dsp_config >> 16) & 0xf;
1869 clk.dsp_precision = (dsp_config >> 20) & 7;
1870 clk.dsp_off = dsp_on_off & 0x7ff;
1871 clk.dsp_on = (dsp_on_off >> 16) & 0x7ff;
1886 pll->
ct.pll_ref_div =
clk.pll_ref_div;
1887 pll->
ct.mclk_fb_div =
clk.mclk_fb_div;
1888 pll->
ct.mclk_post_div_real =
clk.mclk_post_div;
1889 pll->
ct.mclk_fb_mult =
clk.mclk_fb_mult;
1890 pll->
ct.xclk_post_div_real =
clk.xclk_post_div;
1891 pll->
ct.vclk_fb_div =
clk.vclk_fb_div;
1892 pll->
ct.vclk_post_div_real =
clk.vclk_post_div;
1893 pll->
ct.dsp_config = (
clk.dsp_xclks_per_row & 0x3fff) |
1894 ((
clk.dsp_loop_latency & 0xf) << 16) |
1895 ((
clk.dsp_precision & 7) << 20);
1896 pll->
ct.dsp_on_off = (
clk.dsp_off & 0x7ff) |
1897 ((
clk.dsp_on & 0x7ff) << 16);
1918 static int atyfb_sync(
struct fb_info *info)
1931 unsigned int size,
page, map_size = 0;
1932 unsigned long map_offset = 0;
1947 if (((vma->
vm_pgoff == 0) && (size == info->
fix.smem_len)) ||
1949 off += 0x8000000000000000
UL;
1956 for (i = 0; par->mmap_map[
i].size; i++) {
1957 unsigned long start = par->mmap_map[
i].voff;
1958 unsigned long end = start + par->mmap_map[
i].size;
1966 map_size = par->mmap_map[
i].size - (offset -
start);
1967 map_offset = par->mmap_map[
i].poff + (offset -
start);
1974 if (page + map_size > size)
1975 map_size = size -
page;
1981 map_offset >> PAGE_SHIFT, map_size, vma->
vm_page_prot))
1998 #if defined(CONFIG_PM) && defined(CONFIG_PCI)
2000 #ifdef CONFIG_PPC_PMAC
2003 static int aty_power_mgmt(
int sleep,
struct atyfb_par *par)
2030 if ((--timeout) == 0)
2049 if ((--timeout) == 0)
2055 return timeout ? 0 : -
EIO;
2061 struct fb_info *info = pci_get_drvdata(pdev);
2064 if (state.
event == pdev->
dev.power.power_state.event)
2088 #ifdef CONFIG_PPC_PMAC
2090 if (machine_is(powermac) && aty_power_mgmt(1, par)) {
2104 pdev->
dev.power.power_state =
state;
2109 static void aty_resume_chip(
struct fb_info *info)
2123 static int atyfb_pci_resume(
struct pci_dev *pdev)
2125 struct fb_info *info = pci_get_drvdata(pdev);
2139 #ifdef CONFIG_PPC_PMAC
2140 if (machine_is(powermac) &&
2142 aty_power_mgmt(0, par);
2145 aty_resume_chip(info);
2150 atyfb_set_par(info);
2169 #ifdef CONFIG_FB_ATY_BACKLIGHT
2170 #define MAX_LEVEL 0xFF
2172 static int aty_bl_get_level_brightness(
struct atyfb_par *par,
int level)
2174 struct fb_info *info = pci_get_drvdata(par->
pdev);
2191 struct atyfb_par *par = bl_get_data(bd);
2199 level = bd->
props.brightness;
2216 return bd->
props.brightness;
2221 .update_status = aty_bl_update_status,
2224 static void aty_bl_init(
struct atyfb_par *par)
2227 struct fb_info *info = pci_get_drvdata(par->
pdev);
2231 #ifdef CONFIG_PMAC_BACKLIGHT
2240 props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
2244 info->bl_dev =
NULL;
2254 bd->
props.brightness = bd->
props.max_brightness;
2256 backlight_update_status(bd);
2258 printk(
"aty: Backlight initialized (%s)\n", name);
2270 printk(
"aty: Backlight unloaded\n");
2278 const int ragepro_tbl[] = {
2279 44, 50, 55, 66, 75, 80, 100
2281 const int ragexl_tbl[] = {
2282 50, 66, 75, 83, 90, 95, 100, 105,
2283 110, 115, 120, 125, 133, 143, 166
2285 const int *refresh_tbl;
2289 refresh_tbl = ragexl_tbl;
2292 refresh_tbl = ragepro_tbl;
2296 for (i = 0; i <
size; i++) {
2297 if (xclk < refresh_tbl[i])
2309 #if defined(__i386__) && defined(CONFIG_FB_ATY_GENERIC_LCD)
2320 (par->lcd_right_margin + par->lcd_hsync_dly +
2321 par->lcd_hsync_len);
2322 var->
hsync_len = par->lcd_hsync_len + par->lcd_hsync_dly;
2326 (par->lcd_lower_margin + par->lcd_vsync_len);
2340 int gtb_memsize, has_var = 0;
2347 #ifdef CONFIG_FB_ATY_GX
2350 u8 dac_type, dac_subtype, clk_type;
2352 par->
bus_type = (stat0 >> 0) & 0x07;
2353 par->
ram_type = (stat0 >> 3) & 0x07;
2354 ramname = aty_gx_ram[par->
ram_type];
2359 dac_type = (stat0 >> 9) & 0x07;
2360 if (dac_type == 0x07)
2369 switch (dac_subtype) {
2384 PRINTKI(
"aty_init: DAC type not implemented yet!\n");
2410 PRINTKI(
"aty_init: CLK type not implemented yet!");
2416 #ifdef CONFIG_FB_ATY_CT
2423 ramname = aty_xl_ram[par->
ram_type];
2425 ramname = aty_ct_ram[par->
ram_type];
2434 #ifdef CONFIG_PPC_PMAC
2453 aty_calc_mem_refresh(par, par->
pll_limits.xclk);
2461 #ifdef CONFIG_FB_ATY_CT
2467 diff1 = 510 * 14 / pll_ref_div - par->
pll_limits.pll_max;
2468 diff2 = 510 * 29 / pll_ref_div - par->
pll_limits.pll_max;
2473 if (diff2 < diff1) {
2487 gtb_memsize =
M64_HAS(GTB_DSP);
2492 info->
fix.smem_len = 0x80000;
2495 info->
fix.smem_len = 0x100000;
2498 info->
fix.smem_len = 0x200000;
2501 info->
fix.smem_len = 0x400000;
2504 info->
fix.smem_len = 0x600000;
2507 info->
fix.smem_len = 0x800000;
2510 info->
fix.smem_len = 0x80000;
2514 info->
fix.smem_len = 0x80000;
2517 info->
fix.smem_len = 0x100000;
2520 info->
fix.smem_len = 0x200000;
2523 info->
fix.smem_len = 0x400000;
2526 info->
fix.smem_len = 0x600000;
2529 info->
fix.smem_len = 0x800000;
2532 info->
fix.smem_len = 0x80000;
2535 if (
M64_HAS(MAGIC_VRAM_SIZE)) {
2537 info->
fix.smem_len += 0x400000;
2541 info->
fix.smem_len = vram * 1024;
2543 if (info->
fix.smem_len <= 0x80000)
2545 else if (info->
fix.smem_len <= 0x100000)
2547 else if (info->
fix.smem_len <= 0x200000)
2549 else if (info->
fix.smem_len <= 0x400000)
2551 else if (info->
fix.smem_len <= 0x600000)
2563 info->
fix.mmio_len = 0x400;
2566 info->
fix.mmio_len = 0x400;
2569 info->
fix.mmio_start -= 0x400;
2570 info->
fix.mmio_len = 0x800;
2573 info->
fix.mmio_start -= 0x400;
2574 info->
fix.mmio_len = 0x800;
2578 PRINTKI(
"%d%c %s, %s MHz XTAL, %d MHz PLL, %d Mhz MCLK, %d MHz XCLK\n",
2579 info->
fix.smem_len == 0x80000 ? 512 : (info->
fix.smem_len>>20),
2580 info->
fix.smem_len == 0x80000 ?
'K' :
'M', ramname,
xtal,
2584 #if defined(DEBUG) && defined(CONFIG_FB_ATY_CT)
2587 printk(
"debug atyfb: BUS_CNTL DAC_CNTL MEM_CNTL "
2588 "EXT_MEM_CNTL CRTC_GEN_CNTL DSP_CONFIG "
2589 "DSP_ON_OFF CLOCK_CNTL\n"
2590 "debug atyfb: %08x %08x %08x "
2602 for (i = 0; i < 40; i++)
2617 (info->
fix.smem_len == 0x800000 ||
2631 par->mtrr_aper = -1;
2637 if (par->mtrr_aper >= 0 && !par->
aux_start) {
2642 if (par->mtrr_reg < 0) {
2644 par->mtrr_aper = -1;
2650 info->
fbops = &atyfb_ops;
2658 #ifdef CONFIG_PMAC_BACKLIGHT
2668 if (
M64_HAS(MOBIL_BUS) && backlight) {
2669 #ifdef CONFIG_FB_ATY_BACKLIGHT
2674 memset(&var, 0,
sizeof(var));
2676 if (machine_is(powermac)) {
2697 sense = read_aty_sense(par);
2698 PRINTKI(
"monitor sense=%x, mode %d\n",
2701 if (default_vmode <= 0 || default_vmode >
VMODE_MAX)
2703 if (default_cmode < CMODE_8 || default_cmode >
CMODE_32)
2713 #if defined(__i386__) && defined(CONFIG_FB_ATY_GENERIC_LCD)
2714 if (!atyfb_get_timings_from_lcd(par, &var))
2729 if (comp_sync != -1) {
2743 ret = atyfb_check_var(&var, info);
2745 PRINTKE(
"can't set default video mode\n");
2749 #ifdef CONFIG_FB_ATY_CT
2750 if (!noaccel &&
M64_HAS(INTEGRATED))
2767 PRINTKI(
"fb%d: %s frame buffer device on %s\n",
2777 if (par->mtrr_reg >= 0) {
2781 if (par->mtrr_aper >= 0) {
2783 par->mtrr_aper = -1;
2789 #if defined(CONFIG_ATARI) && !defined(MODULE)
2790 static int __devinit store_video_par(
char *video_str,
unsigned char m64_num)
2793 unsigned long vmembase,
size, guiregbase;
2795 PRINTKI(
"store_video_par() '%s' \n", video_str);
2797 if (!(p =
strsep(&video_str,
";")) || !*p)
2798 goto mach64_invalid;
2800 if (!(p =
strsep(&video_str,
";")) || !*p)
2801 goto mach64_invalid;
2803 if (!(p =
strsep(&video_str,
";")) || !*p)
2804 goto mach64_invalid;
2807 phys_vmembase[m64_num] = vmembase;
2808 phys_size[m64_num] =
size;
2809 phys_guiregbase[m64_num] = guiregbase;
2810 PRINTKI(
"stored them all: $%08lX $%08lX $%08lX \n", vmembase, size,
2815 phys_vmembase[m64_num] = 0;
2824 static int atyfb_blank(
int blank,
struct fb_info *info)
2832 #ifdef CONFIG_FB_ATY_GENERIC_LCD
2842 gen_cntl &= ~0x400004c;
2847 gen_cntl |= 0x4000040;
2850 gen_cntl |= 0x4000048;
2853 gen_cntl |= 0x4000044;
2856 gen_cntl |= 0x400004c;
2861 #ifdef CONFIG_FB_ATY_GENERIC_LCD
2898 depth = (info->
var.green.length == 5) ? 15 : 16;
2904 (
depth == 16 && regno > 63) ||
2905 (
depth == 15 && regno > 31))
2919 pal[regno] = (regno << 10) | (regno << 5) | regno;
2922 pal[regno] = (regno << 11) | (regno << 5) | regno;
2925 pal[regno] = (regno << 16) | (regno << 8) | regno;
2928 i = (regno << 8) | regno;
2929 pal[regno] = (i << 16) | i;
2943 aty_st_pal(regno << 3, red,
2944 par->
palette[regno << 1].green,
2946 red = par->
palette[regno >> 1].red;
2947 blue = par->
palette[regno >> 1].blue;
2949 }
else if (
depth == 15) {
2951 for (i = 0; i < 8; i++)
2952 aty_st_pal(regno + i, red, green, blue, par);
2955 aty_st_pal(regno, red, green, blue, par);
2977 info->
fix.mmio_start = addr + 0x7ffc00
UL;
2983 info->
fix.smem_start = addr + 0x800000
UL;
2989 for (i = 0; i < 6 && pdev->
resource[
i].start; i++)
2993 par->mmap_map = kcalloc(j,
sizeof(*par->mmap_map),
GFP_ATOMIC);
2994 if (!par->mmap_map) {
2995 PRINTKE(
"atyfb_setup_sparc() can't alloc mmap_map\n");
2999 for (i = 0, j = 2; i < 6 && pdev->
resource[
i].start; i++) {
3009 size = rp->
end - base + 1;
3011 pci_read_config_dword(pdev, breg, &pbase);
3023 par->mmap_map[
j].voff = (pbase + 0x10000000) &
PAGE_MASK;
3025 par->mmap_map[
j].size = (size + ~PAGE_MASK) & PAGE_MASK;
3027 par->mmap_map[
j].prot_flag =
_PAGE_E;
3036 par->mmap_map[
j].voff = (pbase + 0x800000) &
PAGE_MASK;
3037 par->mmap_map[
j].poff = (base + 0x800000) &
PAGE_MASK;
3038 par->mmap_map[
j].size = 0x800000;
3047 par->mmap_map[
j].size = (size + ~PAGE_MASK) & PAGE_MASK;
3049 par->mmap_map[
j].prot_flag =
_PAGE_E;
3053 ret = correct_chipset(par);
3063 if (((chip_id & CFG_CHIP_TYPE) ==
VT_CHIP_ID) && !((chip_id >> 24) & 1)) {
3064 switch (mem & 0x0f) {
3066 mem = (mem & ~(0x0f)) | 2;
3069 mem = (mem & ~(0x0f)) | 3;
3072 mem = (mem & ~(0x0f)) | 4;
3075 mem = (mem & ~(0x0f)) | 5;
3081 mem &= ~(0x00700000);
3083 mem &= ~(0xcf80e000);
3087 dp = pci_device_to_OF_node(pdev);
3090 unsigned int N,
P,
Q,
M,
T,
R;
3091 u32 v_total, h_total;
3105 aty_crtc_to_var(&crtc, var);
3115 for (i = 0; i < 16; i++)
3126 N = pll_regs[7 + (clock_cntl & 3)];
3131 P = 1 << (pll_regs[6] >> ((clock_cntl & 3) << 1));
3163 #ifdef CONFIG_FB_ATY_GENERIC_LCD
3178 driv_inf_tab = bios_base + *((
u16 *)(bios_base+0x78));
3181 sig = *(
u32 *)driv_inf_tab;
3182 if ((sig == 0x54504c24) ||
3183 (sig == 0x544d5224) ||
3184 (sig == 0x54435824) ||
3185 (sig == 0x544c5824)) {
3186 PRINTKI(
"BIOS contains driver information table.\n");
3187 lcd_ofs = *(
u16 *)(driv_inf_tab + 10);
3190 par->lcd_table = bios_base + lcd_ofs;
3193 if (par->lcd_table != 0) {
3196 char refresh_rates_buf[100];
3197 int id, tech,
f,
i,
m, default_refresh_rate;
3205 u8 lcd_refresh_rates[16] = { 50, 56, 60, 67, 70, 72, 75, 76, 85,
3206 90, 100, 120, 140, 150, 160, 200 };
3212 id = *(
u8 *)par->lcd_table;
3213 strncpy(model, (
char *)par->lcd_table+1, 24);
3216 width = par->lcd_width = *(
u16 *)(par->lcd_table+25);
3217 height = par->lcd_height = *(
u16 *)(par->lcd_table+27);
3218 panel_type = *(
u16 *)(par->lcd_table+29);
3220 txtcolour =
"colour";
3222 txtcolour =
"monochrome";
3224 txtdual =
"dual (split) ";
3227 tech = (panel_type >> 2) & 63;
3230 txtmonitor =
"passive matrix";
3233 txtmonitor =
"active matrix";
3236 txtmonitor =
"active addressed STN";
3242 txtmonitor =
"plasma";
3245 txtmonitor =
"unknown";
3247 format = *(
u32 *)(par->lcd_table+57);
3248 if (tech == 0 || tech == 2) {
3249 switch (format & 7) {
3251 txtformat =
"12 bit interface";
3254 txtformat =
"16 bit interface";
3257 txtformat =
"24 bit interface";
3260 txtformat =
"unknown format";
3263 switch (format & 7) {
3265 txtformat =
"8 colours";
3268 txtformat =
"512 colours";
3271 txtformat =
"4096 colours";
3274 txtformat =
"262144 colours (LT mode)";
3277 txtformat =
"16777216 colours";
3280 txtformat =
"262144 colours (FDPI-2 mode)";
3283 txtformat =
"unknown format";
3286 PRINTKI(
"%s%s %s monitor detected: %s\n",
3287 txtdual, txtcolour, txtmonitor, model);
3288 PRINTKI(
" id=%d, %dx%d pixels, %s\n",
3289 id, width, height, txtformat);
3290 refresh_rates_buf[0] = 0;
3291 refresh_rates = *(
u16 *)(par->lcd_table+62);
3294 for (i = 0; i < 16; i++) {
3295 if (refresh_rates & m) {
3298 lcd_refresh_rates[i]);
3302 lcd_refresh_rates[i]);
3304 strcat(refresh_rates_buf, strbuf);
3308 default_refresh_rate = (*(
u8 *)(par->lcd_table+61) & 0xf0) >> 4;
3309 PRINTKI(
" supports refresh rates [%s], default %d Hz\n",
3310 refresh_rates_buf, lcd_refresh_rates[default_refresh_rate]);
3311 par->lcd_refreshrate = lcd_refresh_rates[default_refresh_rate];
3324 lcdmodeptr = (
u16 *)(par->lcd_table + 64);
3325 while (*lcdmodeptr != 0) {
3327 u16 mwidth, mheight, lcd_hsync_start, lcd_vsync_start;
3328 modeptr = bios_base + *lcdmodeptr;
3330 mwidth = *((
u16 *)(modeptr+0));
3331 mheight = *((
u16 *)(modeptr+2));
3333 if (mwidth == width && mheight == height) {
3334 par->lcd_pixclock = 100000000 / *((
u16 *)(modeptr+9));
3335 par->lcd_htotal = *((
u16 *)(modeptr+17)) & 511;
3336 par->lcd_hdisp = *((
u16 *)(modeptr+19)) & 511;
3337 lcd_hsync_start = *((
u16 *)(modeptr+21)) & 511;
3338 par->lcd_hsync_dly = (*((
u16 *)(modeptr+21)) >> 9) & 7;
3339 par->lcd_hsync_len = *((
u8 *)(modeptr+23)) & 63;
3341 par->lcd_vtotal = *((
u16 *)(modeptr+24)) & 2047;
3342 par->lcd_vdisp = *((
u16 *)(modeptr+26)) & 2047;
3343 lcd_vsync_start = *((
u16 *)(modeptr+28)) & 2047;
3344 par->lcd_vsync_len = (*((
u16 *)(modeptr+28)) >> 11) & 31;
3346 par->lcd_htotal = (par->lcd_htotal + 1) * 8;
3347 par->lcd_hdisp = (par->lcd_hdisp + 1) * 8;
3348 lcd_hsync_start = (lcd_hsync_start + 1) * 8;
3349 par->lcd_hsync_len = par->lcd_hsync_len * 8;
3355 par->lcd_right_margin = lcd_hsync_start - par->lcd_hdisp;
3356 par->lcd_lower_margin = lcd_vsync_start - par->lcd_vdisp;
3357 par->lcd_hblank_len = par->lcd_htotal - par->lcd_hdisp;
3358 par->lcd_vblank_len = par->lcd_vtotal - par->lcd_vdisp;
3364 if (*lcdmodeptr == 0) {
3365 PRINTKE(
"LCD monitor CRTC parameters not found!!!\n");
3368 PRINTKI(
" LCD CRTC parameters: %d.%d %d %d %d %d %d %d %d %d\n",
3369 1000000 / par->lcd_pixclock, 1000000 % par->lcd_pixclock,
3371 par->lcd_hdisp + par->lcd_right_margin,
3372 par->lcd_hdisp + par->lcd_right_margin
3373 + par->lcd_hsync_dly + par->lcd_hsync_len,
3376 par->lcd_vdisp + par->lcd_lower_margin,
3377 par->lcd_vdisp + par->lcd_lower_margin + par->lcd_vsync_len,
3379 PRINTKI(
" : %d %d %d %d %d %d %d %d %d\n",
3381 par->lcd_hblank_len - (par->lcd_right_margin +
3382 par->lcd_hsync_dly + par->lcd_hsync_len),
3384 par->lcd_right_margin,
3386 par->lcd_vblank_len - (par->lcd_lower_margin + par->lcd_vsync_len),
3388 par->lcd_lower_margin,
3389 par->lcd_vsync_len);
3397 u32 bios_base, rom_addr;
3401 bios_base = (
unsigned long)
ioremap(rom_addr, 0x10000);
3404 if (*((
u16 *)bios_base) == 0xaa55) {
3407 u16 rom_table_offset, freq_table_offset;
3408 PLL_BLOCK_MACH64 pll_block;
3410 PRINTKI(
"Mach64 BIOS is located at %x, mapped at %x.\n", rom_addr, bios_base);
3413 bios_ptr = (
u8*)bios_base;
3414 rom_table_offset = (
u16)(bios_ptr[0x48] | (bios_ptr[0x49] << 8));
3415 freq_table_offset = bios_ptr[rom_table_offset + 16] | (bios_ptr[rom_table_offset + 17] << 8);
3416 memcpy(&pll_block, bios_ptr + freq_table_offset,
sizeof(PLL_BLOCK_MACH64));
3418 PRINTKI(
"BIOS frequency table:\n");
3419 PRINTKI(
"PCLK_min_freq %d, PCLK_max_freq %d, ref_freq %d, ref_divider %d\n",
3420 pll_block.PCLK_min_freq, pll_block.PCLK_max_freq,
3421 pll_block.ref_freq, pll_block.ref_divider);
3422 PRINTKI(
"MCLK_pwd %d, MCLK_max_freq %d, XCLK_max_freq %d, SCLK_freq %d\n",
3423 pll_block.MCLK_pwd, pll_block.MCLK_max_freq,
3424 pll_block.XCLK_max_freq, pll_block.SCLK_freq);
3426 par->
pll_limits.pll_min = pll_block.PCLK_min_freq/100;
3427 par->
pll_limits.pll_max = pll_block.PCLK_max_freq/100;
3428 par->
pll_limits.ref_clk = pll_block.ref_freq/100;
3429 par->
pll_limits.ref_div = pll_block.ref_divider;
3430 par->
pll_limits.sclk = pll_block.SCLK_freq/100;
3431 par->
pll_limits.mclk = pll_block.MCLK_max_freq/100;
3432 par->
pll_limits.mclk_pm = pll_block.MCLK_pwd/100;
3433 par->
pll_limits.xclk = pll_block.XCLK_max_freq/100;
3434 #ifdef CONFIG_FB_ATY_GENERIC_LCD
3435 aty_init_lcd(par, bios_base);
3439 PRINTKE(
"no BIOS frequency table found, use parameters\n");
3454 unsigned long raddr;
3458 raddr = addr + 0x7ff000
UL;
3463 par->
aux_size = resource_size(rrp);
3465 PRINTKI(
"using auxiliary register aperture\n");
3473 info->
fix.mmio_start += par->
aux_start ? 0x400 : 0xc00;
3495 goto atyfb_setup_generic_fail;
3498 ret = correct_chipset(par);
3500 goto atyfb_setup_generic_fail;
3502 ret = init_from_bios(par);
3504 goto atyfb_setup_generic_fail;
3516 atyfb_setup_generic_fail:
3539 PRINTKE(
"Cannot enable PCI device\n");
3552 res_start = rp->
start;
3553 res_size = resource_size(rp);
3560 PRINTKE(
"atyfb_pci_probe() can't alloc fb_info\n");
3564 info->
fix = atyfb_fix;
3574 rc = atyfb_setup_sparc(pdev, info, addr);
3576 rc = atyfb_setup_generic(pdev, info, addr);
3579 goto err_release_mem;
3581 pci_set_drvdata(pdev, info);
3584 rc = aty_init(info);
3586 goto err_release_io;
3592 par->mmap_map[0].voff = 0x8000000000000000
UL;
3594 par->mmap_map[0].size = info->
fix.smem_len;
3595 par->mmap_map[0].prot_mask = _PAGE_CACHE;
3596 par->mmap_map[0].prot_flag = _PAGE_E;
3597 par->mmap_map[1].voff = par->mmap_map[0].voff + info->
fix.smem_len;
3601 par->mmap_map[1].prot_flag =
_PAGE_E;
3613 kfree(par->mmap_map);
3634 static int __init atyfb_atari_probe(
void)
3642 for (m64_num = 0; m64_num < mach64_count; m64_num++) {
3643 if (!phys_vmembase[m64_num] || !phys_size[m64_num] ||
3644 !phys_guiregbase[m64_num]) {
3645 PRINTKI(
"phys_*[%d] parameters not set => "
3646 "returning early. \n", m64_num);
3652 PRINTKE(
"atyfb_atari_probe() can't alloc fb_info\n");
3657 info->
fix = atyfb_fix;
3659 par->
irq = (
unsigned int) -1;
3674 switch (clock_r & 0x003F) {
3701 if (correct_chipset(par) || aty_init(info)) {
3710 return num_found ? 0 : -
ENXIO;
3727 #ifdef CONFIG_FB_ATY_BACKLIGHT
3729 aty_bl_exit(info->bl_dev);
3733 if (par->mtrr_reg >= 0) {
3737 if (par->mtrr_aper >= 0) {
3739 par->mtrr_aper = -1;
3753 kfree(par->mmap_map);
3767 struct fb_info *info = pci_get_drvdata(pdev);
3770 if (reboot_info == info)
3778 #ifdef CONFIG_FB_ATY_GX
3783 #ifdef CONFIG_FB_ATY_CT
3835 .id_table = atyfb_pci_tbl,
3836 .probe = atyfb_pci_probe,
3839 .suspend = atyfb_pci_suspend,
3840 .resume = atyfb_pci_resume,
3851 if (!options || !*options)
3854 while ((this_opt =
strsep(&options,
",")) !=
NULL) {
3855 if (!
strncmp(this_opt,
"noaccel", 7)) {
3858 }
else if (!
strncmp(this_opt,
"nomtrr", 6)) {
3861 }
else if (!
strncmp(this_opt,
"vram:", 5))
3863 else if (!
strncmp(this_opt,
"pll:", 4))
3865 else if (!
strncmp(this_opt,
"mclk:", 5))
3867 else if (!
strncmp(this_opt,
"xclk:", 5))
3869 else if (!
strncmp(this_opt,
"comp_sync:", 10))
3871 else if (!
strncmp(this_opt,
"backlight:", 10))
3874 else if (!
strncmp(this_opt,
"vmode:", 6)) {
3875 unsigned int vmode =
3877 if (vmode > 0 && vmode <= VMODE_MAX)
3878 default_vmode = vmode;
3879 }
else if (!
strncmp(this_opt,
"cmode:", 6)) {
3880 unsigned int cmode =
3904 && (!
strncmp(this_opt,
"Mach64:", 7))) {
3905 static unsigned char m64_num;
3906 static char mach64_str[80];
3907 strlcpy(mach64_str, this_opt + 7,
sizeof(mach64_str));
3908 if (!store_video_par(mach64_str, m64_num)) {
3910 mach64_count = m64_num;
3937 par = reboot_info->
par;
3947 unlock_fb_info(reboot_info);
3955 .notifier_call = atyfb_reboot_notify,
3960 .ident =
"HP OmniBook 500",
3971 static int __init atyfb_init(
void)
3973 int err1 = 1, err2 = 1;
3979 atyfb_setup(option);
3983 err1 = pci_register_driver(&atyfb_driver);
3986 err2 = atyfb_atari_probe();
3998 static void __exit atyfb_exit(
void)
4024 MODULE_PARM_DESC(comp_sync,
"Set composite sync signal to low (0) or high (1)");
4026 MODULE_PARM_DESC(mode,
"Specify resolution as \"<xres>x<yres>[-<bpp>][@<refresh>]\" ");