Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    2) /* $Id: aty128fb.c,v 1.1.1.1.36.1 1999/12/11 09:03:05 Exp $
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3)  *  linux/drivers/video/aty128fb.c -- Frame buffer device for ATI Rage128
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  *  Copyright (C) 1999-2003, Brad Douglas <brad@neruo.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)  *  Copyright (C) 1999, Anthony Tong <atong@uiuc.edu>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8)  *                Ani Joshi / Jeff Garzik
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9)  *                      - Code cleanup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11)  *                Michel Danzer <michdaen@iiic.ethz.ch>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12)  *                      - 15/16 bit cleanup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13)  *                      - fix panning
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15)  *                Benjamin Herrenschmidt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16)  *                      - pmac-specific PM stuff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17)  *			- various fixes & cleanups
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19)  *                Andreas Hundt <andi@convergence.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20)  *                      - FB_ACTIVATE fixes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22)  *		  Paul Mackerras <paulus@samba.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23)  *			- Convert to new framebuffer API,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24)  *			  fix colormap setting at 16 bits/pixel (565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26)  *		  Paul Mundt 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27)  *		  	- PCI hotplug
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29)  *		  Jon Smirl <jonsmirl@yahoo.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30)  * 			- PCI ID update
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31)  * 			- replace ROM BIOS search
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33)  *  Based off of Geert's atyfb.c and vfb.c.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35)  *  TODO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36)  *		- monitor sensing (DDC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37)  *              - virtual display
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38)  *		- other platform support (only ppc/x86 supported)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39)  *		- hardware cursor support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41)  *    Please cc: your patches to brad@neruo.com.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45)  * A special note of gratitude to ATI's devrel for providing documentation,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46)  * example code and hardware. Thanks Nitya.	-atong and brad
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) #include <linux/moduleparam.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) #include <linux/vmalloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) #include <linux/fb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) #include <linux/ioport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) #include <linux/console.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) #include <linux/backlight.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) #include <asm/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) #ifdef CONFIG_PPC_PMAC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) #include <asm/machdep.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) #include <asm/pmac_feature.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) #include <asm/prom.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) #include "../macmodes.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) #ifdef CONFIG_PMAC_BACKLIGHT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) #include <asm/backlight.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) #ifdef CONFIG_BOOTX_TEXT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) #include <asm/btext.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) #endif /* CONFIG_BOOTX_TEXT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) #include <video/aty128.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) /* Debug flag */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) #undef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) #define DBG(fmt, args...) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) 	printk(KERN_DEBUG "aty128fb: %s " fmt, __func__, ##args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) #define DBG(fmt, args...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) #ifndef CONFIG_PPC_PMAC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) /* default mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) static const struct fb_var_screeninfo default_var = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) 	/* 640x480, 60 Hz, Non-Interlaced (25.175 MHz dotclock) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) 	640, 480, 640, 480, 0, 0, 8, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) 	{0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) 	0, 0, -1, -1, 0, 39722, 48, 16, 33, 10, 96, 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) 	0, FB_VMODE_NONINTERLACED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) #else /* CONFIG_PPC_PMAC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) /* default to 1024x768 at 75Hz on PPC - this will work
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107)  * on the iMac, the usual 640x480 @ 60Hz doesn't. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) static const struct fb_var_screeninfo default_var = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) 	/* 1024x768, 75 Hz, Non-Interlaced (78.75 MHz dotclock) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) 	1024, 768, 1024, 768, 0, 0, 8, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) 	{0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) 	0, 0, -1, -1, 0, 12699, 160, 32, 28, 1, 96, 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) 	FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) 	FB_VMODE_NONINTERLACED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) #endif /* CONFIG_PPC_PMAC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) /* default modedb mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) /* 640x480, 60 Hz, Non-Interlaced (25.172 MHz dotclock) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) static const struct fb_videomode defaultmode = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) 	.refresh =	60,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) 	.xres =		640,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) 	.yres =		480,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) 	.pixclock =	39722,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) 	.left_margin =	48,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) 	.right_margin =	16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) 	.upper_margin =	33,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) 	.lower_margin =	10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) 	.hsync_len =	96,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) 	.vsync_len =	2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) 	.sync =		0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) 	.vmode =	FB_VMODE_NONINTERLACED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) /* Chip generations */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) 	rage_128,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) 	rage_128_pci,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) 	rage_128_pro,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) 	rage_128_pro_pci,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) 	rage_M3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) 	rage_M3_pci,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) 	rage_M4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) 	rage_128_ultra,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) /* Must match above enum */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) static char * const r128_family[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) 	"AGP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 	"PCI",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) 	"PRO AGP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) 	"PRO PCI",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) 	"M3 AGP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) 	"M3 PCI",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) 	"M4 AGP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) 	"Ultra AGP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160)  * PCI driver prototypes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) static int aty128_probe(struct pci_dev *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163)                                const struct pci_device_id *ent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) static void aty128_remove(struct pci_dev *pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) static int aty128_pci_suspend_late(struct device *dev, pm_message_t state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) static int __maybe_unused aty128_pci_suspend(struct device *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) static int __maybe_unused aty128_pci_hibernate(struct device *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) static int __maybe_unused aty128_pci_freeze(struct device *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) static int __maybe_unused aty128_pci_resume(struct device *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) static int aty128_do_resume(struct pci_dev *pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) static const struct dev_pm_ops aty128_pci_pm_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) 	.suspend	= aty128_pci_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 	.resume		= aty128_pci_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) 	.freeze		= aty128_pci_freeze,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) 	.thaw		= aty128_pci_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) 	.poweroff	= aty128_pci_hibernate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) 	.restore	= aty128_pci_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) /* supported Rage128 chipsets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) static const struct pci_device_id aty128_pci_tbl[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_LE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_M3_pci },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_LF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_M3 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_MF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_M4 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_ML,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_M4 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro_pci },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PJ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro_pci },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PQ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro_pci },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PU,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PV,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_RE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pci },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_RF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_RG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_RK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pci },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_RL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_SE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_SF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pci },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_SG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_SH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_SK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_SL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_SM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_SN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_TF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_ultra },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_TL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_ultra },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_TR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_ultra },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_TS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_ultra },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_TT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_ultra },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_TU,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_ultra },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 	{ 0, }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) MODULE_DEVICE_TABLE(pci, aty128_pci_tbl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) static struct pci_driver aty128fb_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 	.name		= "aty128fb",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) 	.id_table	= aty128_pci_tbl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) 	.probe		= aty128_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 	.remove		= aty128_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 	.driver.pm	= &aty128_pci_pm_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) /* packed BIOS settings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) #ifndef CONFIG_PPC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) typedef struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) 	u8 clock_chip_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) 	u8 struct_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) 	u8 accelerator_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 	u8 VGA_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 	u16 VGA_table_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 	u16 POST_table_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 	u16 XCLK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 	u16 MCLK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 	u8 num_PLL_blocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) 	u8 size_PLL_blocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 	u16 PCLK_ref_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) 	u16 PCLK_ref_divider;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 	u32 PCLK_min_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) 	u32 PCLK_max_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 	u16 MCLK_ref_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 	u16 MCLK_ref_divider;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 	u32 MCLK_min_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 	u32 MCLK_max_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 	u16 XCLK_ref_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 	u16 XCLK_ref_divider;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) 	u32 XCLK_min_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) 	u32 XCLK_max_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) } __attribute__ ((packed)) PLL_BLOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) #endif /* !CONFIG_PPC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) /* onboard memory information */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) struct aty128_meminfo {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 	u8 ML;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) 	u8 MB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 	u8 Trcd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 	u8 Trp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 	u8 Twr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 	u8 CL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 	u8 Tr2w;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 	u8 LoopLatency;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 	u8 DspOn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 	u8 Rloop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 	const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) /* various memory configurations */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) static const struct aty128_meminfo sdr_128 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 	.ML = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 	.MB = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 	.Trcd = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 	.Trp = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 	.Twr = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 	.CL = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 	.Tr2w = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 	.LoopLatency = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) 	.DspOn = 30,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 	.Rloop = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 	.name = "128-bit SDR SGRAM (1:1)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) static const struct aty128_meminfo sdr_sgram = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 	.ML = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 	.MB = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 	.Trcd = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 	.Trp = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 	.Twr = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) 	.CL = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 	.Tr2w = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 	.LoopLatency = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) 	.DspOn = 24,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 	.Rloop = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 	.name = "64-bit SDR SGRAM (2:1)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) static const struct aty128_meminfo ddr_sgram = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 	.ML = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) 	.MB = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) 	.Trcd = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 	.Trp = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 	.Twr = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) 	.CL = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 	.Tr2w = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 	.LoopLatency = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 	.DspOn = 31,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 	.Rloop = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 	.name = "64-bit DDR SGRAM",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) static const struct fb_fix_screeninfo aty128fb_fix = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 	.id		= "ATY Rage128",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 	.type		= FB_TYPE_PACKED_PIXELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 	.visual		= FB_VISUAL_PSEUDOCOLOR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) 	.xpanstep	= 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) 	.ypanstep	= 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) 	.mmio_len	= 0x2000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) 	.accel		= FB_ACCEL_ATI_RAGE128,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) static char *mode_option = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) #ifdef CONFIG_PPC_PMAC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) static int default_vmode = VMODE_1024_768_60;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) static int default_cmode = CMODE_8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) static int default_crt_on = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) static int default_lcd_on = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) static bool mtrr = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) #ifdef CONFIG_FB_ATY128_BACKLIGHT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) static int backlight = IS_BUILTIN(CONFIG_PMAC_BACKLIGHT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) /* PLL constants */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) struct aty128_constants {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 	u32 ref_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 	u32 ppll_min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 	u32 ppll_max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 	u32 ref_divider;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 	u32 xclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 	u32 fifo_width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 	u32 fifo_depth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) struct aty128_crtc {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 	u32 gen_cntl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 	u32 h_total, h_sync_strt_wid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 	u32 v_total, v_sync_strt_wid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 	u32 pitch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 	u32 offset, offset_cntl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 	u32 xoffset, yoffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 	u32 vxres, vyres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 	u32 depth, bpp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) struct aty128_pll {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) 	u32 post_divider;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 	u32 feedback_divider;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) 	u32 vclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) struct aty128_ddafifo {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) 	u32 dda_config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) 	u32 dda_on_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) /* register values for a specific mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) struct aty128fb_par {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 	struct aty128_crtc crtc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 	struct aty128_pll pll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 	struct aty128_ddafifo fifo_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 	u32 accel_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 	struct aty128_constants constants;  /* PLL and others      */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 	void __iomem *regbase;              /* remapped mmio       */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 	u32 vram_size;                      /* onboard video ram   */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 	int chip_gen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 	const struct aty128_meminfo *mem;   /* onboard mem info    */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 	int wc_cookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 	int blitter_may_be_busy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 	int fifo_slots;                 /* free slots in FIFO (64 max) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 	int crt_on, lcd_on;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 	struct pci_dev *pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 	struct fb_info *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 	int	asleep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 	int	lock_blank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 	u8	red[32];		/* see aty128fb_setcolreg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 	u8	green[64];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) 	u8	blue[32];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 	u32	pseudo_palette[16];	/* used for TRUECOLOR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) #define round_div(n, d) ((n+(d/2))/d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) static int aty128fb_check_var(struct fb_var_screeninfo *var,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 			      struct fb_info *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) static int aty128fb_set_par(struct fb_info *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) static int aty128fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 			      u_int transp, struct fb_info *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) static int aty128fb_pan_display(struct fb_var_screeninfo *var,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 			   struct fb_info *fb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) static int aty128fb_blank(int blank, struct fb_info *fb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) static int aty128fb_ioctl(struct fb_info *info, u_int cmd, unsigned long arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) static int aty128fb_sync(struct fb_info *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475)     /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476)      *  Internal routines
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477)      */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) static int aty128_encode_var(struct fb_var_screeninfo *var,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480)                              const struct aty128fb_par *par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) static int aty128_decode_var(struct fb_var_screeninfo *var,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482)                              struct aty128fb_par *par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) static void aty128_timings(struct aty128fb_par *par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) static void aty128_init_engine(struct aty128fb_par *par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) static void aty128_reset_engine(const struct aty128fb_par *par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) static void aty128_flush_pixel_cache(const struct aty128fb_par *par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) static void do_wait_for_fifo(u16 entries, struct aty128fb_par *par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) static void wait_for_fifo(u16 entries, struct aty128fb_par *par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) static void wait_for_idle(struct aty128fb_par *par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) static u32 depth_to_dst(u32 depth);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) #ifdef CONFIG_FB_ATY128_BACKLIGHT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) static void aty128_bl_set_power(struct fb_info *info, int power);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) #define BIOS_IN8(v)  	(readb(bios + (v)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) #define BIOS_IN16(v) 	(readb(bios + (v)) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 			  (readb(bios + (v) + 1) << 8))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) #define BIOS_IN32(v) 	(readb(bios + (v)) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 			  (readb(bios + (v) + 1) << 8) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 			  (readb(bios + (v) + 2) << 16) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) 			  (readb(bios + (v) + 3) << 24))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) static const struct fb_ops aty128fb_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 	.owner		= THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) 	.fb_check_var	= aty128fb_check_var,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) 	.fb_set_par	= aty128fb_set_par,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 	.fb_setcolreg	= aty128fb_setcolreg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) 	.fb_pan_display = aty128fb_pan_display,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) 	.fb_blank	= aty128fb_blank,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 	.fb_ioctl	= aty128fb_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) 	.fb_sync	= aty128fb_sync,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 	.fb_fillrect	= cfb_fillrect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 	.fb_copyarea	= cfb_copyarea,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 	.fb_imageblit	= cfb_imageblit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519)     /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520)      * Functions to read from/write to the mmio registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521)      *	- endian conversions may possibly be avoided by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522)      *    using the other register aperture. TODO.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523)      */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) static inline u32 _aty_ld_le32(volatile unsigned int regindex, 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) 			       const struct aty128fb_par *par)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) 	return readl (par->regbase + regindex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) static inline void _aty_st_le32(volatile unsigned int regindex, u32 val, 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 				const struct aty128fb_par *par)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 	writel (val, par->regbase + regindex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) static inline u8 _aty_ld_8(unsigned int regindex,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 			   const struct aty128fb_par *par)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 	return readb (par->regbase + regindex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) static inline void _aty_st_8(unsigned int regindex, u8 val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 			     const struct aty128fb_par *par)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 	writeb (val, par->regbase + regindex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) #define aty_ld_le32(regindex)		_aty_ld_le32(regindex, par)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) #define aty_st_le32(regindex, val)	_aty_st_le32(regindex, val, par)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) #define aty_ld_8(regindex)		_aty_ld_8(regindex, par)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) #define aty_st_8(regindex, val)		_aty_st_8(regindex, val, par)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553)     /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554)      * Functions to read from/write to the pll registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555)      */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) #define aty_ld_pll(pll_index)		_aty_ld_pll(pll_index, par)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) #define aty_st_pll(pll_index, val)	_aty_st_pll(pll_index, val, par)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) static u32 _aty_ld_pll(unsigned int pll_index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) 		       const struct aty128fb_par *par)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) {       
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 	aty_st_8(CLOCK_CNTL_INDEX, pll_index & 0x3F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 	return aty_ld_le32(CLOCK_CNTL_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568)     
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) static void _aty_st_pll(unsigned int pll_index, u32 val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 			const struct aty128fb_par *par)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 	aty_st_8(CLOCK_CNTL_INDEX, (pll_index & 0x3F) | PLL_WR_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) 	aty_st_le32(CLOCK_CNTL_DATA, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) /* return true when the PLL has completed an atomic update */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) static int aty_pll_readupdate(const struct aty128fb_par *par)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) 	return !(aty_ld_pll(PPLL_REF_DIV) & PPLL_ATOMIC_UPDATE_R);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) static void aty_pll_wait_readupdate(const struct aty128fb_par *par)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 	unsigned long timeout = jiffies + HZ/100; // should be more than enough
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 	int reset = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 	while (time_before(jiffies, timeout))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 		if (aty_pll_readupdate(par)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 			reset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 	if (reset)	/* reset engine?? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 		printk(KERN_DEBUG "aty128fb: PLL write timeout!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) /* tell PLL to update */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) static void aty_pll_writeupdate(const struct aty128fb_par *par)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 	aty_pll_wait_readupdate(par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 	aty_st_pll(PPLL_REF_DIV,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 		   aty_ld_pll(PPLL_REF_DIV) | PPLL_ATOMIC_UPDATE_W);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) /* write to the scratch register to test r/w functionality */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) static int register_test(const struct aty128fb_par *par)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) 	u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 	int flag = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 	val = aty_ld_le32(BIOS_0_SCRATCH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) 	aty_st_le32(BIOS_0_SCRATCH, 0x55555555);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 	if (aty_ld_le32(BIOS_0_SCRATCH) == 0x55555555) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) 		aty_st_le32(BIOS_0_SCRATCH, 0xAAAAAAAA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 		if (aty_ld_le32(BIOS_0_SCRATCH) == 0xAAAAAAAA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 			flag = 1; 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 	aty_st_le32(BIOS_0_SCRATCH, val);	// restore value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 	return flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632)  * Accelerator engine functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) static void do_wait_for_fifo(u16 entries, struct aty128fb_par *par)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 	for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 		for (i = 0; i < 2000000; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 			par->fifo_slots = aty_ld_le32(GUI_STAT) & 0x0fff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 			if (par->fifo_slots >= entries)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 				return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 		aty128_reset_engine(par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) static void wait_for_idle(struct aty128fb_par *par)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 	do_wait_for_fifo(64, par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 	for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 		for (i = 0; i < 2000000; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 			if (!(aty_ld_le32(GUI_STAT) & (1 << 31))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 				aty128_flush_pixel_cache(par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 				par->blitter_may_be_busy = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 				return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 		aty128_reset_engine(par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) static void wait_for_fifo(u16 entries, struct aty128fb_par *par)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 	if (par->fifo_slots < entries)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 		do_wait_for_fifo(64, par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 	par->fifo_slots -= entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) static void aty128_flush_pixel_cache(const struct aty128fb_par *par)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 	u32 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 	tmp = aty_ld_le32(PC_NGUI_CTLSTAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 	tmp &= ~(0x00ff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 	tmp |= 0x00ff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) 	aty_st_le32(PC_NGUI_CTLSTAT, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 	for (i = 0; i < 2000000; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 		if (!(aty_ld_le32(PC_NGUI_CTLSTAT) & PC_BUSY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) static void aty128_reset_engine(const struct aty128fb_par *par)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 	u32 gen_reset_cntl, clock_cntl_index, mclk_cntl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 	aty128_flush_pixel_cache(par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 	clock_cntl_index = aty_ld_le32(CLOCK_CNTL_INDEX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 	mclk_cntl = aty_ld_pll(MCLK_CNTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 	aty_st_pll(MCLK_CNTL, mclk_cntl | 0x00030000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 	gen_reset_cntl = aty_ld_le32(GEN_RESET_CNTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 	aty_st_le32(GEN_RESET_CNTL, gen_reset_cntl | SOFT_RESET_GUI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 	aty_ld_le32(GEN_RESET_CNTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 	aty_st_le32(GEN_RESET_CNTL, gen_reset_cntl & ~(SOFT_RESET_GUI));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 	aty_ld_le32(GEN_RESET_CNTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 	aty_st_pll(MCLK_CNTL, mclk_cntl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 	aty_st_le32(CLOCK_CNTL_INDEX, clock_cntl_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 	aty_st_le32(GEN_RESET_CNTL, gen_reset_cntl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 	/* use old pio mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) 	aty_st_le32(PM4_BUFFER_CNTL, PM4_BUFFER_CNTL_NONPM4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) 	DBG("engine reset");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) static void aty128_init_engine(struct aty128fb_par *par)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 	u32 pitch_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 	wait_for_idle(par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 	/* 3D scaler not spoken here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 	wait_for_fifo(1, par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 	aty_st_le32(SCALE_3D_CNTL, 0x00000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 	aty128_reset_engine(par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 	pitch_value = par->crtc.pitch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 	if (par->crtc.bpp == 24) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 		pitch_value = pitch_value * 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 	wait_for_fifo(4, par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 	/* setup engine offset registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 	aty_st_le32(DEFAULT_OFFSET, 0x00000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 	/* setup engine pitch registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 	aty_st_le32(DEFAULT_PITCH, pitch_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 	/* set the default scissor register to max dimensions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 	aty_st_le32(DEFAULT_SC_BOTTOM_RIGHT, (0x1FFF << 16) | 0x1FFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 	/* set the drawing controls registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 	aty_st_le32(DP_GUI_MASTER_CNTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 		    GMC_SRC_PITCH_OFFSET_DEFAULT		|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 		    GMC_DST_PITCH_OFFSET_DEFAULT		|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 		    GMC_SRC_CLIP_DEFAULT			|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 		    GMC_DST_CLIP_DEFAULT			|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 		    GMC_BRUSH_SOLIDCOLOR			|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 		    (depth_to_dst(par->crtc.depth) << 8)	|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 		    GMC_SRC_DSTCOLOR			|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 		    GMC_BYTE_ORDER_MSB_TO_LSB		|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 		    GMC_DP_CONVERSION_TEMP_6500		|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 		    ROP3_PATCOPY				|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 		    GMC_DP_SRC_RECT				|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 		    GMC_3D_FCN_EN_CLR			|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 		    GMC_DST_CLR_CMP_FCN_CLEAR		|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 		    GMC_AUX_CLIP_CLEAR			|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 		    GMC_WRITE_MASK_SET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 	wait_for_fifo(8, par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 	/* clear the line drawing registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 	aty_st_le32(DST_BRES_ERR, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 	aty_st_le32(DST_BRES_INC, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 	aty_st_le32(DST_BRES_DEC, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 	/* set brush color registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 	aty_st_le32(DP_BRUSH_FRGD_CLR, 0xFFFFFFFF); /* white */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 	aty_st_le32(DP_BRUSH_BKGD_CLR, 0x00000000); /* black */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 	/* set source color registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 	aty_st_le32(DP_SRC_FRGD_CLR, 0xFFFFFFFF);   /* white */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 	aty_st_le32(DP_SRC_BKGD_CLR, 0x00000000);   /* black */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 	/* default write mask */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 	aty_st_le32(DP_WRITE_MASK, 0xFFFFFFFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 	/* Wait for all the writes to be completed before returning */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 	wait_for_idle(par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) /* convert depth values to their register representation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) static u32 depth_to_dst(u32 depth)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 	if (depth <= 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 		return DST_8BPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 	else if (depth <= 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 		return DST_15BPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 	else if (depth == 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 		return DST_16BPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 	else if (depth <= 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 		return DST_24BPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 	else if (depth <= 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 		return DST_32BPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 	return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805)  * PLL informations retreival
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) #ifndef __sparc__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) static void __iomem *aty128_map_ROM(const struct aty128fb_par *par,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 				    struct pci_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 	u16 dptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 	u8 rom_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 	void __iomem *bios;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 	size_t rom_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818)     	/* Fix from ATI for problem with Rage128 hardware not leaving ROM enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819)     	unsigned int temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 	temp = aty_ld_le32(RAGE128_MPP_TB_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 	temp &= 0x00ffffffu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) 	temp |= 0x04 << 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 	aty_st_le32(RAGE128_MPP_TB_CONFIG, temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 	temp = aty_ld_le32(RAGE128_MPP_TB_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 	bios = pci_map_rom(dev, &rom_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 	if (!bios) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 		printk(KERN_ERR "aty128fb: ROM failed to map\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 	/* Very simple test to make sure it appeared */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 	if (BIOS_IN16(0) != 0xaa55) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 		printk(KERN_DEBUG "aty128fb: Invalid ROM signature %x should "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 			" be 0xaa55\n", BIOS_IN16(0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 		goto failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 	/* Look for the PCI data to check the ROM type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 	dptr = BIOS_IN16(0x18);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 	/* Check the PCI data signature. If it's wrong, we still assume a normal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 	 * x86 ROM for now, until I've verified this works everywhere.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 	 * The goal here is more to phase out Open Firmware images.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 	 * Currently, we only look at the first PCI data, we could iteratre and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 	 * deal with them all, and we should use fb_bios_start relative to start
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 	 * of image and not relative start of ROM, but so far, I never found a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 	 * dual-image ATI card.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 	 * typedef struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 	 * 	u32	signature;	+ 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 	 * 	u16	vendor;		+ 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 	 * 	u16	device;		+ 0x06
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 	 * 	u16	reserved_1;	+ 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 	 * 	u16	dlen;		+ 0x0a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 	 * 	u8	drevision;	+ 0x0c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 	 * 	u8	class_hi;	+ 0x0d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 	 * 	u16	class_lo;	+ 0x0e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 	 * 	u16	ilen;		+ 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 	 * 	u16	irevision;	+ 0x12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 	 * 	u8	type;		+ 0x14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 	 * 	u8	indicator;	+ 0x15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 	 * 	u16	reserved_2;	+ 0x16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 	 * } pci_data_t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 	if (BIOS_IN32(dptr) !=  (('R' << 24) | ('I' << 16) | ('C' << 8) | 'P')) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 		printk(KERN_WARNING "aty128fb: PCI DATA signature in ROM incorrect: %08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 		       BIOS_IN32(dptr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 		goto anyway;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 	rom_type = BIOS_IN8(dptr + 0x14);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 	switch(rom_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 	case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 		printk(KERN_INFO "aty128fb: Found Intel x86 BIOS ROM Image\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 	case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 		printk(KERN_INFO "aty128fb: Found Open Firmware ROM Image\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 		goto failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 	case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 		printk(KERN_INFO "aty128fb: Found HP PA-RISC ROM Image\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 		goto failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 		printk(KERN_INFO "aty128fb: Found unknown type %d ROM Image\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 		       rom_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 		goto failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889)  anyway:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 	return bios;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892)  failed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 	pci_unmap_rom(dev, bios);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) static void aty128_get_pllinfo(struct aty128fb_par *par,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 			       unsigned char __iomem *bios)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 	unsigned int bios_hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 	unsigned int bios_pll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 	bios_hdr = BIOS_IN16(0x48);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 	bios_pll = BIOS_IN16(bios_hdr + 0x30);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 	par->constants.ppll_max = BIOS_IN32(bios_pll + 0x16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 	par->constants.ppll_min = BIOS_IN32(bios_pll + 0x12);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 	par->constants.xclk = BIOS_IN16(bios_pll + 0x08);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 	par->constants.ref_divider = BIOS_IN16(bios_pll + 0x10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 	par->constants.ref_clk = BIOS_IN16(bios_pll + 0x0e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 	DBG("ppll_max %d ppll_min %d xclk %d ref_divider %d ref clock %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 			par->constants.ppll_max, par->constants.ppll_min,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 			par->constants.xclk, par->constants.ref_divider,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 			par->constants.ref_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) }           
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) #ifdef CONFIG_X86
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) static void __iomem *aty128_find_mem_vbios(struct aty128fb_par *par)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 	/* I simplified this code as we used to miss the signatures in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 	 * a lot of case. It's now closer to XFree, we just don't check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 	 * for signatures at all... Something better will have to be done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 	 * if we end up having conflicts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927)         u32  segstart;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928)         unsigned char __iomem *rom_base = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929)                                                 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930)         for (segstart=0x000c0000; segstart<0x000f0000; segstart+=0x00001000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931)                 rom_base = ioremap(segstart, 0x10000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 		if (rom_base == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 			return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 		if (readb(rom_base) == 0x55 && readb(rom_base + 1) == 0xaa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 	                break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936)                 iounmap(rom_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 		rom_base = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 	return rom_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) #endif /* ndef(__sparc__) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) /* fill in known card constants if pll_block is not available */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) static void aty128_timings(struct aty128fb_par *par)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) #ifdef CONFIG_PPC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 	/* instead of a table lookup, assume OF has properly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 	 * setup the PLL registers and use their values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 	 * to set the XCLK values and reference divider values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 	u32 x_mpll_ref_fb_div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 	u32 xclk_cntl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 	u32 Nx, M;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 	unsigned PostDivSet[] = { 0, 1, 2, 4, 8, 3, 6, 12 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 	if (!par->constants.ref_clk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 		par->constants.ref_clk = 2950;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) #ifdef CONFIG_PPC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 	x_mpll_ref_fb_div = aty_ld_pll(X_MPLL_REF_FB_DIV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 	xclk_cntl = aty_ld_pll(XCLK_CNTL) & 0x7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 	Nx = (x_mpll_ref_fb_div & 0x00ff00) >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 	M  = x_mpll_ref_fb_div & 0x0000ff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 	par->constants.xclk = round_div((2 * Nx * par->constants.ref_clk),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 					(M * PostDivSet[xclk_cntl]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 	par->constants.ref_divider =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) 		aty_ld_pll(PPLL_REF_DIV) & PPLL_REF_DIV_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 	if (!par->constants.ref_divider) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 		par->constants.ref_divider = 0x3b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 		aty_st_pll(X_MPLL_REF_FB_DIV, 0x004c4c1e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 		aty_pll_writeupdate(par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 	aty_st_pll(PPLL_REF_DIV, par->constants.ref_divider);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 	aty_pll_writeupdate(par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 	/* from documentation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 	if (!par->constants.ppll_min)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 		par->constants.ppll_min = 12500;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 	if (!par->constants.ppll_max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 		par->constants.ppll_max = 25000;    /* 23000 on some cards? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 	if (!par->constants.xclk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 		par->constants.xclk = 0x1d4d;	     /* same as mclk */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 	par->constants.fifo_width = 128;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 	par->constants.fifo_depth = 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 	switch (aty_ld_le32(MEM_CNTL) & 0x3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 	case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 		par->mem = &sdr_128;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 	case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 		par->mem = &sdr_sgram;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) 	case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) 		par->mem = &ddr_sgram;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 		par->mem = &sdr_sgram;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012)  * CRTC programming
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) /* Program the CRTC registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) static void aty128_set_crtc(const struct aty128_crtc *crtc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 			    const struct aty128fb_par *par)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 	aty_st_le32(CRTC_GEN_CNTL, crtc->gen_cntl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 	aty_st_le32(CRTC_H_TOTAL_DISP, crtc->h_total);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 	aty_st_le32(CRTC_H_SYNC_STRT_WID, crtc->h_sync_strt_wid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 	aty_st_le32(CRTC_V_TOTAL_DISP, crtc->v_total);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 	aty_st_le32(CRTC_V_SYNC_STRT_WID, crtc->v_sync_strt_wid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) 	aty_st_le32(CRTC_PITCH, crtc->pitch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 	aty_st_le32(CRTC_OFFSET, crtc->offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 	aty_st_le32(CRTC_OFFSET_CNTL, crtc->offset_cntl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 	/* Disable ATOMIC updating.  Is this the right place? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 	aty_st_pll(PPLL_CNTL, aty_ld_pll(PPLL_CNTL) & ~(0x00030000));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) static int aty128_var_to_crtc(const struct fb_var_screeninfo *var,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 			      struct aty128_crtc *crtc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 			      const struct aty128fb_par *par)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 	u32 xres, yres, vxres, vyres, xoffset, yoffset, bpp, dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 	u32 left, right, upper, lower, hslen, vslen, sync, vmode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 	u32 h_total, h_disp, h_sync_strt, h_sync_wid, h_sync_pol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 	u32 v_total, v_disp, v_sync_strt, v_sync_wid, v_sync_pol, c_sync;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 	u32 depth, bytpp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 	u8 mode_bytpp[7] = { 0, 0, 1, 2, 2, 3, 4 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 	/* input */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 	xres = var->xres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 	yres = var->yres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 	vxres   = var->xres_virtual;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 	vyres   = var->yres_virtual;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 	xoffset = var->xoffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 	yoffset = var->yoffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 	bpp   = var->bits_per_pixel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 	left  = var->left_margin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 	right = var->right_margin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) 	upper = var->upper_margin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 	lower = var->lower_margin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 	hslen = var->hsync_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) 	vslen = var->vsync_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 	sync  = var->sync;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 	vmode = var->vmode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 	if (bpp != 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 		depth = bpp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 		depth = (var->green.length == 6) ? 16 : 15;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 	/* check for mode eligibility
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 	 * accept only non interlaced modes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 	if ((vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 	/* convert (and round up) and validate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 	xres = (xres + 7) & ~7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 	xoffset = (xoffset + 7) & ~7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 	if (vxres < xres + xoffset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 		vxres = xres + xoffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 	if (vyres < yres + yoffset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 		vyres = yres + yoffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 	/* convert depth into ATI register depth */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 	dst = depth_to_dst(depth);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) 	if (dst == -EINVAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 		printk(KERN_ERR "aty128fb: Invalid depth or RGBA\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 	/* convert register depth to bytes per pixel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 	bytpp = mode_bytpp[dst];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) 	/* make sure there is enough video ram for the mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) 	if ((u32)(vxres * vyres * bytpp) > par->vram_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) 		printk(KERN_ERR "aty128fb: Not enough memory for mode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 	h_disp = (xres >> 3) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 	h_total = (((xres + right + hslen + left) >> 3) - 1) & 0xFFFFL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) 	v_disp = yres - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 	v_total = (yres + upper + vslen + lower - 1) & 0xFFFFL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 	/* check to make sure h_total and v_total are in range */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 	if (((h_total >> 3) - 1) > 0x1ff || (v_total - 1) > 0x7FF) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 		printk(KERN_ERR "aty128fb: invalid width ranges\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) 	h_sync_wid = (hslen + 7) >> 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) 	if (h_sync_wid == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 		h_sync_wid = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 	else if (h_sync_wid > 0x3f)        /* 0x3f = max hwidth */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) 		h_sync_wid = 0x3f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 	h_sync_strt = (h_disp << 3) + right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 	v_sync_wid = vslen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 	if (v_sync_wid == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 		v_sync_wid = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 	else if (v_sync_wid > 0x1f)        /* 0x1f = max vwidth */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 		v_sync_wid = 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122)     
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 	v_sync_strt = v_disp + lower;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 	h_sync_pol = sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) 	v_sync_pol = sync & FB_SYNC_VERT_HIGH_ACT ? 0 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127)     
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) 	c_sync = sync & FB_SYNC_COMP_HIGH_ACT ? (1 << 4) : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) 	crtc->gen_cntl = 0x3000000L | c_sync | (dst << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) 	crtc->h_total = h_total | (h_disp << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) 	crtc->v_total = v_total | (v_disp << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) 	crtc->h_sync_strt_wid = h_sync_strt | (h_sync_wid << 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) 	        (h_sync_pol << 23);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) 	crtc->v_sync_strt_wid = v_sync_strt | (v_sync_wid << 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138)                 (v_sync_pol << 23);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) 	crtc->pitch = vxres >> 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) 	crtc->offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) 	if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) 		crtc->offset_cntl = 0x00010000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) 		crtc->offset_cntl = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) 	crtc->vxres = vxres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) 	crtc->vyres = vyres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) 	crtc->xoffset = xoffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) 	crtc->yoffset = yoffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) 	crtc->depth = depth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) 	crtc->bpp = bpp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) static int aty128_pix_width_to_var(int pix_width, struct fb_var_screeninfo *var)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) 	/* fill in pixel info */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) 	var->red.msb_right = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) 	var->green.msb_right = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) 	var->blue.offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) 	var->blue.msb_right = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) 	var->transp.offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) 	var->transp.length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) 	var->transp.msb_right = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) 	switch (pix_width) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) 	case CRTC_PIX_WIDTH_8BPP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) 		var->bits_per_pixel = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) 		var->red.offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) 		var->red.length = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) 		var->green.offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) 		var->green.length = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) 		var->blue.length = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) 	case CRTC_PIX_WIDTH_15BPP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) 		var->bits_per_pixel = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) 		var->red.offset = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) 		var->red.length = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) 		var->green.offset = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) 		var->green.length = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) 		var->blue.length = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) 	case CRTC_PIX_WIDTH_16BPP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) 		var->bits_per_pixel = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) 		var->red.offset = 11;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) 		var->red.length = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) 		var->green.offset = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) 		var->green.length = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) 		var->blue.length = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) 	case CRTC_PIX_WIDTH_24BPP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) 		var->bits_per_pixel = 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) 		var->red.offset = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) 		var->red.length = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) 		var->green.offset = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) 		var->green.length = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) 		var->blue.length = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) 	case CRTC_PIX_WIDTH_32BPP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) 		var->bits_per_pixel = 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) 		var->red.offset = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) 		var->red.length = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) 		var->green.offset = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) 		var->green.length = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) 		var->blue.length = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) 		var->transp.offset = 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) 		var->transp.length = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) 		printk(KERN_ERR "aty128fb: Invalid pixel width\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) static int aty128_crtc_to_var(const struct aty128_crtc *crtc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) 			      struct fb_var_screeninfo *var)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) 	u32 xres, yres, left, right, upper, lower, hslen, vslen, sync;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) 	u32 h_total, h_disp, h_sync_strt, h_sync_dly, h_sync_wid, h_sync_pol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) 	u32 v_total, v_disp, v_sync_strt, v_sync_wid, v_sync_pol, c_sync;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) 	u32 pix_width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) 	/* fun with masking */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) 	h_total     = crtc->h_total & 0x1ff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) 	h_disp      = (crtc->h_total >> 16) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) 	h_sync_strt = (crtc->h_sync_strt_wid >> 3) & 0x1ff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) 	h_sync_dly  = crtc->h_sync_strt_wid & 0x7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) 	h_sync_wid  = (crtc->h_sync_strt_wid >> 16) & 0x3f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) 	h_sync_pol  = (crtc->h_sync_strt_wid >> 23) & 0x1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) 	v_total     = crtc->v_total & 0x7ff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) 	v_disp      = (crtc->v_total >> 16) & 0x7ff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) 	v_sync_strt = crtc->v_sync_strt_wid & 0x7ff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) 	v_sync_wid  = (crtc->v_sync_strt_wid >> 16) & 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) 	v_sync_pol  = (crtc->v_sync_strt_wid >> 23) & 0x1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) 	c_sync      = crtc->gen_cntl & CRTC_CSYNC_EN ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) 	pix_width   = crtc->gen_cntl & CRTC_PIX_WIDTH_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) 	/* do conversions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) 	xres  = (h_disp + 1) << 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) 	yres  = v_disp + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) 	left  = ((h_total - h_sync_strt - h_sync_wid) << 3) - h_sync_dly;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) 	right = ((h_sync_strt - h_disp) << 3) + h_sync_dly;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) 	hslen = h_sync_wid << 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) 	upper = v_total - v_sync_strt - v_sync_wid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) 	lower = v_sync_strt - v_disp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) 	vslen = v_sync_wid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) 	sync  = (h_sync_pol ? 0 : FB_SYNC_HOR_HIGH_ACT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) 		(v_sync_pol ? 0 : FB_SYNC_VERT_HIGH_ACT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) 		(c_sync ? FB_SYNC_COMP_HIGH_ACT : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) 	aty128_pix_width_to_var(pix_width, var);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) 	var->xres = xres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) 	var->yres = yres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) 	var->xres_virtual = crtc->vxres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) 	var->yres_virtual = crtc->vyres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) 	var->xoffset = crtc->xoffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) 	var->yoffset = crtc->yoffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) 	var->left_margin  = left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) 	var->right_margin = right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) 	var->upper_margin = upper;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) 	var->lower_margin = lower;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) 	var->hsync_len = hslen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) 	var->vsync_len = vslen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) 	var->sync  = sync;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) 	var->vmode = FB_VMODE_NONINTERLACED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) static void aty128_set_crt_enable(struct aty128fb_par *par, int on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) 	if (on) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) 		aty_st_le32(CRTC_EXT_CNTL, aty_ld_le32(CRTC_EXT_CNTL) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) 			    CRT_CRTC_ON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) 		aty_st_le32(DAC_CNTL, (aty_ld_le32(DAC_CNTL) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) 			    DAC_PALETTE2_SNOOP_EN));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) 		aty_st_le32(CRTC_EXT_CNTL, aty_ld_le32(CRTC_EXT_CNTL) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) 			    ~CRT_CRTC_ON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) static void aty128_set_lcd_enable(struct aty128fb_par *par, int on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) 	u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) #ifdef CONFIG_FB_ATY128_BACKLIGHT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) 	struct fb_info *info = pci_get_drvdata(par->pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) 	if (on) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) 		reg = aty_ld_le32(LVDS_GEN_CNTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) 		reg |= LVDS_ON | LVDS_EN | LVDS_BLON | LVDS_DIGION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) 		reg &= ~LVDS_DISPLAY_DIS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) 		aty_st_le32(LVDS_GEN_CNTL, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) #ifdef CONFIG_FB_ATY128_BACKLIGHT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) 		aty128_bl_set_power(info, FB_BLANK_UNBLANK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) #endif	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) #ifdef CONFIG_FB_ATY128_BACKLIGHT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) 		aty128_bl_set_power(info, FB_BLANK_POWERDOWN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) #endif	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) 		reg = aty_ld_le32(LVDS_GEN_CNTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) 		reg |= LVDS_DISPLAY_DIS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) 		aty_st_le32(LVDS_GEN_CNTL, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) 		mdelay(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) 		reg &= ~(LVDS_ON /*| LVDS_EN*/);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) 		aty_st_le32(LVDS_GEN_CNTL, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) static void aty128_set_pll(struct aty128_pll *pll,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) 			   const struct aty128fb_par *par)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) 	u32 div3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) 	unsigned char post_conv[] =	/* register values for post dividers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325)         { 2, 0, 1, 4, 2, 2, 6, 2, 3, 2, 2, 2, 7 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) 	/* select PPLL_DIV_3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) 	aty_st_le32(CLOCK_CNTL_INDEX, aty_ld_le32(CLOCK_CNTL_INDEX) | (3 << 8));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) 	/* reset PLL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) 	aty_st_pll(PPLL_CNTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) 		   aty_ld_pll(PPLL_CNTL) | PPLL_RESET | PPLL_ATOMIC_UPDATE_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) 	/* write the reference divider */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) 	aty_pll_wait_readupdate(par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) 	aty_st_pll(PPLL_REF_DIV, par->constants.ref_divider & 0x3ff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) 	aty_pll_writeupdate(par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) 	div3 = aty_ld_pll(PPLL_DIV_3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) 	div3 &= ~PPLL_FB3_DIV_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) 	div3 |= pll->feedback_divider;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) 	div3 &= ~PPLL_POST3_DIV_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) 	div3 |= post_conv[pll->post_divider] << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) 	/* write feedback and post dividers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) 	aty_pll_wait_readupdate(par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) 	aty_st_pll(PPLL_DIV_3, div3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) 	aty_pll_writeupdate(par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) 	aty_pll_wait_readupdate(par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) 	aty_st_pll(HTOTAL_CNTL, 0);	/* no horiz crtc adjustment */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) 	aty_pll_writeupdate(par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) 	/* clear the reset, just in case */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) 	aty_st_pll(PPLL_CNTL, aty_ld_pll(PPLL_CNTL) & ~PPLL_RESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) static int aty128_var_to_pll(u32 period_in_ps, struct aty128_pll *pll,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) 			     const struct aty128fb_par *par)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) 	const struct aty128_constants c = par->constants;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) 	unsigned char post_dividers[] = {1,2,4,8,3,6,12};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) 	u32 output_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) 	u32 vclk;        /* in .01 MHz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) 	int i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) 	u32 n, d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) 	vclk = 100000000 / period_in_ps;	/* convert units to 10 kHz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) 	/* adjust pixel clock if necessary */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) 	if (vclk > c.ppll_max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) 		vclk = c.ppll_max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) 	if (vclk * 12 < c.ppll_min)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) 		vclk = c.ppll_min/12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) 	/* now, find an acceptable divider */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) 	for (i = 0; i < ARRAY_SIZE(post_dividers); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) 		output_freq = post_dividers[i] * vclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) 		if (output_freq >= c.ppll_min && output_freq <= c.ppll_max) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) 			pll->post_divider = post_dividers[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) 	if (i == ARRAY_SIZE(post_dividers))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) 	/* calculate feedback divider */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) 	n = c.ref_divider * output_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) 	d = c.ref_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) 	pll->feedback_divider = round_div(n, d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) 	pll->vclk = vclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) 	DBG("post %d feedback %d vlck %d output %d ref_divider %d "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) 	    "vclk_per: %d\n", pll->post_divider,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) 	    pll->feedback_divider, vclk, output_freq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) 	    c.ref_divider, period_in_ps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) static int aty128_pll_to_var(const struct aty128_pll *pll,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) 			     struct fb_var_screeninfo *var)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) 	var->pixclock = 100000000 / pll->vclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) static void aty128_set_fifo(const struct aty128_ddafifo *dsp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) 			    const struct aty128fb_par *par)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) 	aty_st_le32(DDA_CONFIG, dsp->dda_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) 	aty_st_le32(DDA_ON_OFF, dsp->dda_on_off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) static int aty128_ddafifo(struct aty128_ddafifo *dsp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) 			  const struct aty128_pll *pll,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) 			  u32 depth,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) 			  const struct aty128fb_par *par)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) 	const struct aty128_meminfo *m = par->mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) 	u32 xclk = par->constants.xclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) 	u32 fifo_width = par->constants.fifo_width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) 	u32 fifo_depth = par->constants.fifo_depth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) 	s32 x, b, p, ron, roff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) 	u32 n, d, bpp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) 	/* round up to multiple of 8 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) 	bpp = (depth+7) & ~7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) 	n = xclk * fifo_width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) 	d = pll->vclk * bpp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) 	x = round_div(n, d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) 	ron = 4 * m->MB +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) 		3 * ((m->Trcd - 2 > 0) ? m->Trcd - 2 : 0) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) 		2 * m->Trp +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) 		m->Twr +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) 		m->CL +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) 		m->Tr2w +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) 		x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) 	DBG("x %x\n", x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) 	b = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) 	while (x) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) 		x >>= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) 		b++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) 	p = b + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) 	ron <<= (11 - p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) 	n <<= (11 - p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) 	x = round_div(n, d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) 	roff = x * (fifo_depth - 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) 	if ((ron + m->Rloop) >= roff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) 		printk(KERN_ERR "aty128fb: Mode out of range!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) 	DBG("p: %x rloop: %x x: %x ron: %x roff: %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) 	    p, m->Rloop, x, ron, roff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) 	dsp->dda_config = p << 16 | m->Rloop << 20 | x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) 	dsp->dda_on_off = ron << 16 | roff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480)  * This actually sets the video mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) static int aty128fb_set_par(struct fb_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) { 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) 	struct aty128fb_par *par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) 	u32 config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) 	if ((err = aty128_decode_var(&info->var, par)) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) 	if (par->blitter_may_be_busy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) 		wait_for_idle(par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) 	/* clear all registers that may interfere with mode setting */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) 	aty_st_le32(OVR_CLR, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) 	aty_st_le32(OVR_WID_LEFT_RIGHT, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) 	aty_st_le32(OVR_WID_TOP_BOTTOM, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) 	aty_st_le32(OV0_SCALE_CNTL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) 	aty_st_le32(MPP_TB_CONFIG, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) 	aty_st_le32(MPP_GP_CONFIG, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) 	aty_st_le32(SUBPIC_CNTL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) 	aty_st_le32(VIPH_CONTROL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) 	aty_st_le32(I2C_CNTL_1, 0);         /* turn off i2c */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) 	aty_st_le32(GEN_INT_CNTL, 0);	/* turn off interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) 	aty_st_le32(CAP0_TRIG_CNTL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) 	aty_st_le32(CAP1_TRIG_CNTL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) 	aty_st_8(CRTC_EXT_CNTL + 1, 4);	/* turn video off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) 	aty128_set_crtc(&par->crtc, par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) 	aty128_set_pll(&par->pll, par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) 	aty128_set_fifo(&par->fifo_reg, par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) 	config = aty_ld_le32(CNFG_CNTL) & ~3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) #if defined(__BIG_ENDIAN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) 	if (par->crtc.bpp == 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) 		config |= 2;	/* make aperture do 32 bit swapping */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) 	else if (par->crtc.bpp == 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) 		config |= 1;	/* make aperture do 16 bit swapping */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) 	aty_st_le32(CNFG_CNTL, config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) 	aty_st_8(CRTC_EXT_CNTL + 1, 0);	/* turn the video back on */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) 	info->fix.line_length = (par->crtc.vxres * par->crtc.bpp) >> 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) 	info->fix.visual = par->crtc.bpp == 8 ? FB_VISUAL_PSEUDOCOLOR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) 		: FB_VISUAL_DIRECTCOLOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) 	if (par->chip_gen == rage_M3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) 		aty128_set_crt_enable(par, par->crt_on);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) 		aty128_set_lcd_enable(par, par->lcd_on);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) 	if (par->accel_flags & FB_ACCELF_TEXT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) 		aty128_init_engine(par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) #ifdef CONFIG_BOOTX_TEXT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) 	btext_update_display(info->fix.smem_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) 			     (((par->crtc.h_total>>16) & 0xff)+1)*8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) 			     ((par->crtc.v_total>>16) & 0x7ff)+1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) 			     par->crtc.bpp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) 			     par->crtc.vxres*par->crtc.bpp/8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) #endif /* CONFIG_BOOTX_TEXT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549)  *  encode/decode the User Defined Part of the Display
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) static int aty128_decode_var(struct fb_var_screeninfo *var,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) 			     struct aty128fb_par *par)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) 	struct aty128_crtc crtc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) 	struct aty128_pll pll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) 	struct aty128_ddafifo fifo_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) 	if ((err = aty128_var_to_crtc(var, &crtc, par)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) 	if ((err = aty128_var_to_pll(var->pixclock, &pll, par)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) 	if ((err = aty128_ddafifo(&fifo_reg, &pll, crtc.depth, par)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) 	par->crtc = crtc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) 	par->pll = pll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) 	par->fifo_reg = fifo_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) 	par->accel_flags = var->accel_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) static int aty128_encode_var(struct fb_var_screeninfo *var,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) 			     const struct aty128fb_par *par)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) 	if ((err = aty128_crtc_to_var(&par->crtc, var)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) 	if ((err = aty128_pll_to_var(&par->pll, var)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) 	var->nonstd = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) 	var->activate = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) 	var->height = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) 	var->width = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) 	var->accel_flags = par->accel_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) }           
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) static int aty128fb_check_var(struct fb_var_screeninfo *var,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) 			      struct fb_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) 	struct aty128fb_par par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) 	par = *(struct aty128fb_par *)info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) 	if ((err = aty128_decode_var(var, &par)) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) 	aty128_encode_var(var, &par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615)  *  Pan or Wrap the Display
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) static int aty128fb_pan_display(struct fb_var_screeninfo *var,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) 				struct fb_info *fb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) 	struct aty128fb_par *par = fb->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) 	u32 xoffset, yoffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) 	u32 offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) 	u32 xres, yres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) 	xres = (((par->crtc.h_total >> 16) & 0xff) + 1) << 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) 	yres = ((par->crtc.v_total >> 16) & 0x7ff) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) 	xoffset = (var->xoffset +7) & ~7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) 	yoffset = var->yoffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) 	if (xoffset+xres > par->crtc.vxres || yoffset+yres > par->crtc.vyres)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) 	par->crtc.xoffset = xoffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) 	par->crtc.yoffset = yoffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) 	offset = ((yoffset * par->crtc.vxres + xoffset) * (par->crtc.bpp >> 3))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) 									  & ~7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) 	if (par->crtc.bpp == 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) 		offset += 8 * (offset % 3); /* Must be multiple of 8 and 3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) 	aty_st_le32(CRTC_OFFSET, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650)  *  Helper function to store a single palette register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) static void aty128_st_pal(u_int regno, u_int red, u_int green, u_int blue,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) 			  struct aty128fb_par *par)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) 	if (par->chip_gen == rage_M3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) 		aty_st_le32(DAC_CNTL, aty_ld_le32(DAC_CNTL) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) 			    ~DAC_PALETTE_ACCESS_CNTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) 	aty_st_8(PALETTE_INDEX, regno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) 	aty_st_le32(PALETTE_DATA, (red<<16)|(green<<8)|blue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) static int aty128fb_sync(struct fb_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) 	struct aty128fb_par *par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) 	if (par->blitter_may_be_busy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) 		wait_for_idle(par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) #ifndef MODULE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) static int aty128fb_setup(char *options)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) 	char *this_opt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) 	if (!options || !*options)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) 	while ((this_opt = strsep(&options, ",")) != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) 		if (!strncmp(this_opt, "lcd:", 4)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) 			default_lcd_on = simple_strtoul(this_opt+4, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) 		} else if (!strncmp(this_opt, "crt:", 4)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) 			default_crt_on = simple_strtoul(this_opt+4, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) 		} else if (!strncmp(this_opt, "backlight:", 10)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) #ifdef CONFIG_FB_ATY128_BACKLIGHT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) 			backlight = simple_strtoul(this_opt+10, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) 		if(!strncmp(this_opt, "nomtrr", 6)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) 			mtrr = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) #ifdef CONFIG_PPC_PMAC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) 		/* vmode and cmode deprecated */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) 		if (!strncmp(this_opt, "vmode:", 6)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) 			unsigned int vmode = simple_strtoul(this_opt+6, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) 			if (vmode > 0 && vmode <= VMODE_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) 				default_vmode = vmode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) 		} else if (!strncmp(this_opt, "cmode:", 6)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) 			unsigned int cmode = simple_strtoul(this_opt+6, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) 			switch (cmode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) 			case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) 			case 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) 				default_cmode = CMODE_8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) 			case 15:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) 			case 16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) 				default_cmode = CMODE_16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) 			case 24:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) 			case 32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) 				default_cmode = CMODE_32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) #endif /* CONFIG_PPC_PMAC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) 		mode_option = this_opt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) #endif  /*  MODULE  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) /* Backlight */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) #ifdef CONFIG_FB_ATY128_BACKLIGHT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) #define MAX_LEVEL 0xFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) static int aty128_bl_get_level_brightness(struct aty128fb_par *par,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) 		int level)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) 	struct fb_info *info = pci_get_drvdata(par->pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) 	int atylevel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) 	/* Get and convert the value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) 	/* No locking of bl_curve since we read a single value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) 	atylevel = MAX_LEVEL -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) 		(info->bl_curve[level] * FB_BACKLIGHT_MAX / MAX_LEVEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) 	if (atylevel < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) 		atylevel = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) 	else if (atylevel > MAX_LEVEL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) 		atylevel = MAX_LEVEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) 	return atylevel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) /* We turn off the LCD completely instead of just dimming the backlight.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754)  * This provides greater power saving and the display is useless without
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755)  * backlight anyway
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) #define BACKLIGHT_LVDS_OFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) /* That one prevents proper CRT output with LCD off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) #undef BACKLIGHT_DAC_OFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) static int aty128_bl_update_status(struct backlight_device *bd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) 	struct aty128fb_par *par = bl_get_data(bd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) 	unsigned int reg = aty_ld_le32(LVDS_GEN_CNTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) 	int level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) 	if (bd->props.power != FB_BLANK_UNBLANK ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) 	    bd->props.fb_blank != FB_BLANK_UNBLANK ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) 	    !par->lcd_on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) 		level = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) 		level = bd->props.brightness;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) 	reg |= LVDS_BL_MOD_EN | LVDS_BLON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) 	if (level > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) 		reg |= LVDS_DIGION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) 		if (!(reg & LVDS_ON)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) 			reg &= ~LVDS_BLON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) 			aty_st_le32(LVDS_GEN_CNTL, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) 			aty_ld_le32(LVDS_GEN_CNTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) 			mdelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) 			reg |= LVDS_BLON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) 			aty_st_le32(LVDS_GEN_CNTL, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) 		reg &= ~LVDS_BL_MOD_LEVEL_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) 		reg |= (aty128_bl_get_level_brightness(par, level) <<
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) 			LVDS_BL_MOD_LEVEL_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) #ifdef BACKLIGHT_LVDS_OFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) 		reg |= LVDS_ON | LVDS_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) 		reg &= ~LVDS_DISPLAY_DIS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) 		aty_st_le32(LVDS_GEN_CNTL, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) #ifdef BACKLIGHT_DAC_OFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) 		aty_st_le32(DAC_CNTL, aty_ld_le32(DAC_CNTL) & (~DAC_PDWN));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) 		reg &= ~LVDS_BL_MOD_LEVEL_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) 		reg |= (aty128_bl_get_level_brightness(par, 0) <<
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) 			LVDS_BL_MOD_LEVEL_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) #ifdef BACKLIGHT_LVDS_OFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) 		reg |= LVDS_DISPLAY_DIS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) 		aty_st_le32(LVDS_GEN_CNTL, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) 		aty_ld_le32(LVDS_GEN_CNTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) 		udelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) 		reg &= ~(LVDS_ON | LVDS_EN | LVDS_BLON | LVDS_DIGION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) 		aty_st_le32(LVDS_GEN_CNTL, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) #ifdef BACKLIGHT_DAC_OFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) 		aty_st_le32(DAC_CNTL, aty_ld_le32(DAC_CNTL) | DAC_PDWN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) static const struct backlight_ops aty128_bl_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) 	.update_status	= aty128_bl_update_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) static void aty128_bl_set_power(struct fb_info *info, int power)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) 	if (info->bl_dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) 		info->bl_dev->props.power = power;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) 		backlight_update_status(info->bl_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) static void aty128_bl_init(struct aty128fb_par *par)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) 	struct backlight_properties props;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) 	struct fb_info *info = pci_get_drvdata(par->pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) 	struct backlight_device *bd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) 	char name[12];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) 	/* Could be extended to Rage128Pro LVDS output too */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) 	if (par->chip_gen != rage_M3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) #ifdef CONFIG_PMAC_BACKLIGHT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) 	if (!pmac_has_backlight_type("ati"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) 	snprintf(name, sizeof(name), "aty128bl%d", info->node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) 	memset(&props, 0, sizeof(struct backlight_properties));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) 	props.type = BACKLIGHT_RAW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) 	props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) 	bd = backlight_device_register(name, info->dev, par, &aty128_bl_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) 				       &props);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) 	if (IS_ERR(bd)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) 		info->bl_dev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) 		printk(KERN_WARNING "aty128: Backlight registration failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) 	info->bl_dev = bd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) 	fb_bl_default_curve(info, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) 		 63 * FB_BACKLIGHT_MAX / MAX_LEVEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) 		219 * FB_BACKLIGHT_MAX / MAX_LEVEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) 	bd->props.brightness = bd->props.max_brightness;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) 	bd->props.power = FB_BLANK_UNBLANK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) 	backlight_update_status(bd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) 	printk("aty128: Backlight initialized (%s)\n", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) static void aty128_bl_exit(struct backlight_device *bd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) 	backlight_device_unregister(bd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) 	printk("aty128: Backlight unloaded\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) #endif /* CONFIG_FB_ATY128_BACKLIGHT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882)  *  Initialisation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) #ifdef CONFIG_PPC_PMAC__disabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) static void aty128_early_resume(void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888)         struct aty128fb_par *par = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) 	if (!console_trylock())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) 	pci_restore_state(par->pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) 	aty128_do_resume(par->pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) 	console_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) #endif /* CONFIG_PPC_PMAC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) static int aty128_init(struct pci_dev *pdev, const struct pci_device_id *ent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) 	struct fb_info *info = pci_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) 	struct aty128fb_par *par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) 	struct fb_var_screeninfo var;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) 	char video_card[50];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) 	u8 chip_rev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) 	u32 dac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) 	/* Get the chip revision */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) 	chip_rev = (aty_ld_le32(CNFG_CNTL) >> 16) & 0x1F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) 	strcpy(video_card, "Rage128 XX ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) 	video_card[8] = ent->device >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) 	video_card[9] = ent->device & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) 	/* range check to make sure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) 	if (ent->driver_data < ARRAY_SIZE(r128_family))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) 		strlcat(video_card, r128_family[ent->driver_data],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) 			sizeof(video_card));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) 	printk(KERN_INFO "aty128fb: %s [chip rev 0x%x] ", video_card, chip_rev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) 	if (par->vram_size % (1024 * 1024) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) 		printk("%dM %s\n", par->vram_size / (1024*1024), par->mem->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) 		printk("%dk %s\n", par->vram_size / 1024, par->mem->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) 	par->chip_gen = ent->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) 	/* fill in info */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) 	info->fbops = &aty128fb_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) 	info->flags = FBINFO_FLAG_DEFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) 	par->lcd_on = default_lcd_on;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) 	par->crt_on = default_crt_on;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) 	var = default_var;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) #ifdef CONFIG_PPC_PMAC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) 	if (machine_is(powermac)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) 		/* Indicate sleep capability */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) 		if (par->chip_gen == rage_M3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) 			pmac_call_feature(PMAC_FTR_DEVICE_CAN_WAKE, NULL, 0, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) #if 0 /* Disable the early video resume hack for now as it's causing problems,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942)        * among others we now rely on the PCI core restoring the config space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943)        * for us, which isn't the case with that hack, and that code path causes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944)        * various things to be called with interrupts off while they shouldn't.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945)        * I'm leaving the code in as it can be useful for debugging purposes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946)        */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) 			pmac_set_early_video_resume(aty128_early_resume, par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) 		/* Find default mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) 		if (mode_option) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) 			if (!mac_find_mode(&var, info, mode_option, 8))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) 				var = default_var;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) 			if (default_vmode <= 0 || default_vmode > VMODE_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) 				default_vmode = VMODE_1024_768_60;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) 			/* iMacs need that resolution
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) 			 * PowerMac2,1 first r128 iMacs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) 			 * PowerMac2,2 summer 2000 iMacs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) 			 * PowerMac4,1 january 2001 iMacs "flower power"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) 			if (of_machine_is_compatible("PowerMac2,1") ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) 			    of_machine_is_compatible("PowerMac2,2") ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) 			    of_machine_is_compatible("PowerMac4,1"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) 				default_vmode = VMODE_1024_768_75;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) 			/* iBook SE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) 			if (of_machine_is_compatible("PowerBook2,2"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) 				default_vmode = VMODE_800_600_60;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) 			/* PowerBook Firewire (Pismo), iBook Dual USB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) 			if (of_machine_is_compatible("PowerBook3,1") ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) 			    of_machine_is_compatible("PowerBook4,1"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) 				default_vmode = VMODE_1024_768_60;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) 			/* PowerBook Titanium */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) 			if (of_machine_is_compatible("PowerBook3,2"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) 				default_vmode = VMODE_1152_768_60;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) 	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) 			if (default_cmode > 16) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) 				default_cmode = CMODE_32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) 			else if (default_cmode > 8) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) 				default_cmode = CMODE_16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) 			else 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) 				default_cmode = CMODE_8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) 			if (mac_vmode_to_var(default_vmode, default_cmode, &var))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) 				var = default_var;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) #endif /* CONFIG_PPC_PMAC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) 		if (mode_option)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) 			if (fb_find_mode(&var, info, mode_option, NULL, 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) 					 0, &defaultmode, 8) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) 				var = default_var;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) 	var.accel_flags &= ~FB_ACCELF_TEXT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) //	var.accel_flags |= FB_ACCELF_TEXT;/* FIXME Will add accel later */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) 	if (aty128fb_check_var(&var, info)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) 		printk(KERN_ERR "aty128fb: Cannot set default mode.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) 	/* setup the DAC the way we like it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) 	dac = aty_ld_le32(DAC_CNTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) 	dac |= (DAC_8BIT_EN | DAC_RANGE_CNTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) 	dac |= DAC_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) 	if (par->chip_gen == rage_M3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) 		dac |= DAC_PALETTE2_SNOOP_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) 	aty_st_le32(DAC_CNTL, dac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) 	/* turn off bus mastering, just in case */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) 	aty_st_le32(BUS_CNTL, aty_ld_le32(BUS_CNTL) | BUS_MASTER_DIS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) 	info->var = var;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) 	fb_alloc_cmap(&info->cmap, 256, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) 	var.activate = FB_ACTIVATE_NOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) 	aty128_init_engine(par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) 	par->pdev = pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) 	par->asleep = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) 	par->lock_blank = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) #ifdef CONFIG_FB_ATY128_BACKLIGHT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) 	if (backlight)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) 		aty128_bl_init(par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) 	if (register_framebuffer(info) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) 	fb_info(info, "%s frame buffer device on %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) 		info->fix.id, video_card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) 	return 1;	/* success! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) #ifdef CONFIG_PCI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) /* register a card    ++ajoshi */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) static int aty128_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) 	unsigned long fb_addr, reg_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) 	struct aty128fb_par *par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) 	struct fb_info *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) #ifndef __sparc__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) 	void __iomem *bios = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) 	/* Enable device in PCI config */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) 	if ((err = pci_enable_device(pdev))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) 		printk(KERN_ERR "aty128fb: Cannot enable PCI device: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) 				err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) 	fb_addr = pci_resource_start(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) 	if (!request_mem_region(fb_addr, pci_resource_len(pdev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) 				"aty128fb FB")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) 		printk(KERN_ERR "aty128fb: cannot reserve frame "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) 				"buffer memory\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) 	reg_addr = pci_resource_start(pdev, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) 	if (!request_mem_region(reg_addr, pci_resource_len(pdev, 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) 				"aty128fb MMIO")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) 		printk(KERN_ERR "aty128fb: cannot reserve MMIO region\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) 		goto err_free_fb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) 	/* We have the resources. Now virtualize them */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) 	info = framebuffer_alloc(sizeof(struct aty128fb_par), &pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) 	if (!info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) 		goto err_free_mmio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) 	par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) 	info->pseudo_palette = par->pseudo_palette;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) 	/* Virtualize mmio region */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) 	info->fix.mmio_start = reg_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) 	par->regbase = pci_ioremap_bar(pdev, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) 	if (!par->regbase)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) 		goto err_free_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) 	/* Grab memory size from the card */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) 	// How does this relate to the resource length from the PCI hardware?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) 	par->vram_size = aty_ld_le32(CNFG_MEMSIZE) & 0x03FFFFFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) 	/* Virtualize the framebuffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) 	info->screen_base = ioremap_wc(fb_addr, par->vram_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) 	if (!info->screen_base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) 		goto err_unmap_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) 	/* Set up info->fix */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) 	info->fix = aty128fb_fix;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) 	info->fix.smem_start = fb_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) 	info->fix.smem_len = par->vram_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) 	info->fix.mmio_start = reg_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) 	/* If we can't test scratch registers, something is seriously wrong */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) 	if (!register_test(par)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) 		printk(KERN_ERR "aty128fb: Can't write to video register!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) 		goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) #ifndef __sparc__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) 	bios = aty128_map_ROM(par, pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) #ifdef CONFIG_X86
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) 	if (bios == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) 		bios = aty128_find_mem_vbios(par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) 	if (bios == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) 		printk(KERN_INFO "aty128fb: BIOS not located, guessing timings.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) 		printk(KERN_INFO "aty128fb: Rage128 BIOS located\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) 		aty128_get_pllinfo(par, bios);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) 		pci_unmap_rom(pdev, bios);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) #endif /* __sparc__ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) 	aty128_timings(par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) 	pci_set_drvdata(pdev, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) 	if (!aty128_init(pdev, ent))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) 		goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) 	if (mtrr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) 		par->wc_cookie = arch_phys_wc_add(info->fix.smem_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) 						  par->vram_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) err_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) 	iounmap(info->screen_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) err_unmap_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) 	iounmap(par->regbase);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) err_free_info:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) 	framebuffer_release(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) err_free_mmio:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) 	release_mem_region(pci_resource_start(pdev, 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) 			pci_resource_len(pdev, 2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) err_free_fb:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) 	release_mem_region(pci_resource_start(pdev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) 			pci_resource_len(pdev, 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) 	return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) static void aty128_remove(struct pci_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) 	struct fb_info *info = pci_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) 	struct aty128fb_par *par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) 	if (!info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) 	par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) 	unregister_framebuffer(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) #ifdef CONFIG_FB_ATY128_BACKLIGHT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) 	aty128_bl_exit(info->bl_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) 	arch_phys_wc_del(par->wc_cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) 	iounmap(par->regbase);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) 	iounmap(info->screen_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) 	release_mem_region(pci_resource_start(pdev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) 			   pci_resource_len(pdev, 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) 	release_mem_region(pci_resource_start(pdev, 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) 			   pci_resource_len(pdev, 2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) 	framebuffer_release(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) #endif /* CONFIG_PCI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186)     /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187)      *  Blank the display.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188)      */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) static int aty128fb_blank(int blank, struct fb_info *fb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) 	struct aty128fb_par *par = fb->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) 	u8 state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) 	if (par->lock_blank || par->asleep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) 	switch (blank) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) 	case FB_BLANK_NORMAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) 		state = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) 	case FB_BLANK_VSYNC_SUSPEND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) 		state = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) 	case FB_BLANK_HSYNC_SUSPEND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) 		state = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) 	case FB_BLANK_POWERDOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) 		state = 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) 	case FB_BLANK_UNBLANK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) 		state = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) 	aty_st_8(CRTC_EXT_CNTL+1, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) 	if (par->chip_gen == rage_M3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) 		aty128_set_crt_enable(par, par->crt_on && !blank);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) 		aty128_set_lcd_enable(par, par->lcd_on && !blank);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226)  *  Set a single color register. The values supplied are already
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227)  *  rounded down to the hardware's capabilities (according to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228)  *  entries in the var structure). Return != 0 for invalid regno.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) static int aty128fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) 			      u_int transp, struct fb_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) 	struct aty128fb_par *par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) 	if (regno > 255
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) 	    || (par->crtc.depth == 16 && regno > 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) 	    || (par->crtc.depth == 15 && regno > 31))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) 	red >>= 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) 	green >>= 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) 	blue >>= 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) 	if (regno < 16) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) 		int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) 		u32 *pal = info->pseudo_palette;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) 		switch (par->crtc.depth) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) 		case 15:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) 			pal[regno] = (regno << 10) | (regno << 5) | regno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) 		case 16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) 			pal[regno] = (regno << 11) | (regno << 6) | regno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) 		case 24:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) 			pal[regno] = (regno << 16) | (regno << 8) | regno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) 		case 32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) 			i = (regno << 8) | regno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) 			pal[regno] = (i << 16) | i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) 	if (par->crtc.depth == 16 && regno > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) 		 * With the 5-6-5 split of bits for RGB at 16 bits/pixel, we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) 		 * have 32 slots for R and B values but 64 slots for G values.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) 		 * Thus the R and B values go in one slot but the G value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) 		 * goes in a different slot, and we have to avoid disturbing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) 		 * the other fields in the slots we touch.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) 		par->green[regno] = green;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) 		if (regno < 32) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) 			par->red[regno] = red;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) 			par->blue[regno] = blue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) 			aty128_st_pal(regno * 8, red, par->green[regno*2],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) 				      blue, par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) 		red = par->red[regno/2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) 		blue = par->blue[regno/2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) 		regno <<= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) 	} else if (par->crtc.bpp == 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) 		regno <<= 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) 	aty128_st_pal(regno, red, green, blue, par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) #define ATY_MIRROR_LCD_ON	0x00000001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) #define ATY_MIRROR_CRT_ON	0x00000002
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) /* out param: u32*	backlight value: 0 to 15 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) #define FBIO_ATY128_GET_MIRROR	_IOR('@', 1, __u32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) /* in param: u32*	backlight value: 0 to 15 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) #define FBIO_ATY128_SET_MIRROR	_IOW('@', 2, __u32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) static int aty128fb_ioctl(struct fb_info *info, u_int cmd, u_long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) 	struct aty128fb_par *par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) 	u32 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303)     
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) 	switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) 	case FBIO_ATY128_SET_MIRROR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) 		if (par->chip_gen != rage_M3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) 		rc = get_user(value, (__u32 __user *)arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) 		if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) 			return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) 		par->lcd_on = (value & 0x01) != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) 		par->crt_on = (value & 0x02) != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) 		if (!par->crt_on && !par->lcd_on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) 			par->lcd_on = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) 		aty128_set_crt_enable(par, par->crt_on);	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) 		aty128_set_lcd_enable(par, par->lcd_on);	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) 	case FBIO_ATY128_GET_MIRROR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) 		if (par->chip_gen != rage_M3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) 		value = (par->crt_on << 1) | par->lcd_on;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) 		return put_user(value, (__u32 __user *)arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) 	return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) static void aty128_set_suspend(struct aty128fb_par *par, int suspend)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) 	u32	pmgt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) 	if (!par->pdev->pm_cap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) 		
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) 	/* Set the chip into the appropriate suspend mode (we use D2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) 	 * D3 would require a complete re-initialisation of the chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) 	 * including PCI config registers, clocks, AGP configuration, ...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) 	 * For resume, the core will have already brought us back to D0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) 	if (suspend) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) 		/* Make sure CRTC2 is reset. Remove that the day we decide to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) 		 * actually use CRTC2 and replace it with real code for disabling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) 		 * the CRTC2 output during sleep
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) 		aty_st_le32(CRTC2_GEN_CNTL, aty_ld_le32(CRTC2_GEN_CNTL) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) 			~(CRTC2_EN));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) 		/* Set the power management mode to be PCI based */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) 		/* Use this magic value for now */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) 		pmgt = 0x0c005407;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) 		aty_st_pll(POWER_MANAGEMENT, pmgt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) 		(void)aty_ld_pll(POWER_MANAGEMENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) 		aty_st_le32(BUS_CNTL1, 0x00000010);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) 		aty_st_le32(MEM_POWER_MISC, 0x0c830000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) 		msleep(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) static int aty128_pci_suspend_late(struct device *dev, pm_message_t state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) 	struct pci_dev *pdev = to_pci_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) 	struct fb_info *info = pci_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) 	struct aty128fb_par *par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) 	/* We don't do anything but D2, for now we return 0, but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) 	 * we may want to change that. How do we know if the BIOS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) 	 * can properly take care of D3 ? Also, with swsusp, we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) 	 * know we'll be rebooted, ...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) #ifndef CONFIG_PPC_PMAC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) 	/* HACK ALERT ! Once I find a proper way to say to each driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) 	 * individually what will happen with it's PCI slot, I'll change
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) 	 * that. On laptops, the AGP slot is just unclocked, so D2 is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) 	 * expected, while on desktops, the card is powered off
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) #endif /* CONFIG_PPC_PMAC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) 	 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) 	if (state.event == pdev->dev.power.power_state.event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) 	printk(KERN_DEBUG "aty128fb: suspending...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) 	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) 	console_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) 	fb_set_suspend(info, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) 	/* Make sure engine is reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) 	wait_for_idle(par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) 	aty128_reset_engine(par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) 	wait_for_idle(par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) 	/* Blank display and LCD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) 	aty128fb_blank(FB_BLANK_POWERDOWN, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) 	/* Sleep */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) 	par->asleep = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) 	par->lock_blank = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) #ifdef CONFIG_PPC_PMAC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) 	/* On powermac, we have hooks to properly suspend/resume AGP now,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) 	 * use them here. We'll ultimately need some generic support here,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) 	 * but the generic code isn't quite ready for that yet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) 	pmac_suspend_agp_for_card(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) #endif /* CONFIG_PPC_PMAC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) 	/* We need a way to make sure the fbdev layer will _not_ touch the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) 	 * framebuffer before we put the chip to suspend state. On 2.4, I
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) 	 * used dummy fb ops, 2.5 need proper support for this at the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) 	 * fbdev level
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) 	if (state.event != PM_EVENT_ON)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) 		aty128_set_suspend(par, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) 	console_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) 	pdev->dev.power.power_state = state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) static int __maybe_unused aty128_pci_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) 	return aty128_pci_suspend_late(dev, PMSG_SUSPEND);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) static int __maybe_unused aty128_pci_hibernate(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) 	return aty128_pci_suspend_late(dev, PMSG_HIBERNATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) static int __maybe_unused aty128_pci_freeze(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) 	return aty128_pci_suspend_late(dev, PMSG_FREEZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) static int aty128_do_resume(struct pci_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) 	struct fb_info *info = pci_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) 	struct aty128fb_par *par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) 	if (pdev->dev.power.power_state.event == PM_EVENT_ON)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) 	/* PCI state will have been restored by the core, so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) 	 * we should be in D0 now with our config space fully
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) 	 * restored
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) 	/* Wakeup chip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) 	aty128_set_suspend(par, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) 	par->asleep = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) 	/* Restore display & engine */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) 	aty128_reset_engine(par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) 	wait_for_idle(par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) 	aty128fb_set_par(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) 	fb_pan_display(info, &info->var);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) 	fb_set_cmap(&info->cmap, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) 	/* Refresh */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) 	fb_set_suspend(info, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) 	/* Unblank */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) 	par->lock_blank = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) 	aty128fb_blank(0, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) #ifdef CONFIG_PPC_PMAC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) 	/* On powermac, we have hooks to properly suspend/resume AGP now,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) 	 * use them here. We'll ultimately need some generic support here,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) 	 * but the generic code isn't quite ready for that yet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) 	pmac_resume_agp_for_card(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) #endif /* CONFIG_PPC_PMAC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) 	pdev->dev.power.power_state = PMSG_ON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) 	printk(KERN_DEBUG "aty128fb: resumed !\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) static int __maybe_unused aty128_pci_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) 	console_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) 	rc = aty128_do_resume(to_pci_dev(dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) 	console_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) static int aty128fb_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) #ifndef MODULE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) 	char *option = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) 	if (fb_get_options("aty128fb", &option))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) 	aty128fb_setup(option);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) 	return pci_register_driver(&aty128fb_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) static void __exit aty128fb_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) 	pci_unregister_driver(&aty128fb_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) module_init(aty128fb_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) module_exit(aty128fb_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) MODULE_AUTHOR("(c)1999-2003 Brad Douglas <brad@neruo.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) MODULE_DESCRIPTION("FBDev driver for ATI Rage128 / Pro cards");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) module_param(mode_option, charp, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) MODULE_PARM_DESC(mode_option, "Specify resolution as \"<xres>x<yres>[-<bpp>][@<refresh>]\" ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) module_param_named(nomtrr, mtrr, invbool, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) MODULE_PARM_DESC(nomtrr, "bool: Disable MTRR support (0 or 1=disabled) (default=0)");