^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * linux/drivers/video/riva/fbdev.c - nVidia RIVA 128/TNT/TNT2 fb driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Maintained by Ani Joshi <ajoshi@shell.unixbox.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright 1999-2000 Jeff Garzik
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Contributors:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Ani Joshi: Lots of debugging and cleanup work, really helped
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * get the driver going
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * Ferenc Bakonyi: Bug fixes, cleanup, modularization
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * Jindrich Makovicka: Accel code help, hw cursor, mtrr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * Paul Richards: Bug fixes, updates
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * Initial template from skeletonfb.c, created 28 Dec 1997 by Geert Uytterhoeven
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * Includes riva_hw.c from nVidia, see copyright below.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * KGI code provided the basis for state storage, init, and mode switching.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * This file is subject to the terms and conditions of the GNU General Public
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * License. See the file COPYING in the main directory of this archive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * Known bugs and issues:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * restoring text mode fails
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * doublescan modes are broken
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <linux/fb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #include <linux/backlight.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include <linux/bitrev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #ifdef CONFIG_PMAC_BACKLIGHT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #include <asm/machdep.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #include <asm/backlight.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #include "rivafb.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #include "nvreg.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) /* version number of this driver */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define RIVAFB_VERSION "0.9.5b"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) /* ------------------------------------------------------------------------- *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * various helpful macros and constants
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * ------------------------------------------------------------------------- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #ifdef CONFIG_FB_RIVA_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define NVTRACE printk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define NVTRACE if(0) printk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define NVTRACE_ENTER(...) NVTRACE("%s START\n", __func__)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define NVTRACE_LEAVE(...) NVTRACE("%s END\n", __func__)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #ifdef CONFIG_FB_RIVA_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define assert(expr) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) if(!(expr)) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) printk( "Assertion failed! %s,%s,%s,line=%d\n",\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #expr,__FILE__,__func__,__LINE__); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) BUG(); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define assert(expr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define PFX "rivafb: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) /* macro that allows you to set overflow bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define SetBitField(value,from,to) SetBF(to,GetBF(value,from))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define SetBit(n) (1<<(n))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define Set8Bits(value) ((value)&0xff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) /* HW cursor parameters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define MAX_CURS 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) /* ------------------------------------------------------------------------- *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) * prototypes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) * ------------------------------------------------------------------------- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) static int rivafb_blank(int blank, struct fb_info *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) /* ------------------------------------------------------------------------- *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) * card identification
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) * ------------------------------------------------------------------------- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) static const struct pci_device_id rivafb_pci_tbl[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) { PCI_VENDOR_ID_NVIDIA_SGS, PCI_DEVICE_ID_NVIDIA_SGS_RIVA128,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_TNT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_TNT2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_UTNT2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_VTNT2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_UVTNT2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_ITNT2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_SDR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_DDR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_MX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_MX2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_GO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO2_MXR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_GTS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_GTS2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_ULTRA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO2_PRO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_460,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_440,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) // NF2/IGP version, GeForce 4 MX, NV18
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) { PCI_VENDOR_ID_NVIDIA, 0x01f0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_420,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_440_GO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_420_GO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_420_GO_M32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_500XGL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_440_GO_M64,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_200,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_550XGL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_500_GOGL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_IGEFORCE2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE3_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE3_2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO_DDC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4600,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4400,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4200,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_900XGL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_750XGL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_700XGL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO_5200,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) { 0, } /* terminate list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) MODULE_DEVICE_TABLE(pci, rivafb_pci_tbl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) /* ------------------------------------------------------------------------- *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) * global variables
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) * ------------------------------------------------------------------------- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) /* command line data, set in rivafb_setup() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) static int flatpanel = -1; /* Autodetect later */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) static int forceCRTC = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) static bool noaccel = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) static bool nomtrr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) static int backlight = IS_BUILTIN(CONFIG_PMAC_BACKLIGHT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) static char *mode_option = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) static bool strictmode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) static struct fb_fix_screeninfo rivafb_fix = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) .type = FB_TYPE_PACKED_PIXELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) .xpanstep = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) .ypanstep = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) static struct fb_var_screeninfo rivafb_default_var = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) .xres = 640,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) .yres = 480,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) .xres_virtual = 640,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) .yres_virtual = 480,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) .bits_per_pixel = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) .red = {0, 8, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) .green = {0, 8, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) .blue = {0, 8, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) .transp = {0, 0, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) .activate = FB_ACTIVATE_NOW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) .height = -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) .width = -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) .pixclock = 39721,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) .left_margin = 40,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) .right_margin = 24,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) .upper_margin = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) .lower_margin = 11,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) .hsync_len = 96,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) .vsync_len = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) .vmode = FB_VMODE_NONINTERLACED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) /* from GGI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) static const struct riva_regs reg_template = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* ATTR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 0x41, 0x01, 0x0F, 0x00, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* CRT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE3, /* 0x10 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 0x00, /* 0x40 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) {0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, /* GRA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 0xFF},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) {0x03, 0x01, 0x0F, 0x00, 0x0E}, /* SEQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 0xEB /* MISC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) * Backlight control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) #ifdef CONFIG_FB_RIVA_BACKLIGHT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) /* We do not have any information about which values are allowed, thus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) * we used safe values.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) #define MIN_LEVEL 0x158
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) #define MAX_LEVEL 0x534
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) #define LEVEL_STEP ((MAX_LEVEL - MIN_LEVEL) / FB_BACKLIGHT_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) static int riva_bl_get_level_brightness(struct riva_par *par,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) int level)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) struct fb_info *info = pci_get_drvdata(par->pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) int nlevel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) /* Get and convert the value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) /* No locking on bl_curve since accessing a single value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) nlevel = MIN_LEVEL + info->bl_curve[level] * LEVEL_STEP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) if (nlevel < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) nlevel = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) else if (nlevel < MIN_LEVEL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) nlevel = MIN_LEVEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) else if (nlevel > MAX_LEVEL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) nlevel = MAX_LEVEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) return nlevel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) static int riva_bl_update_status(struct backlight_device *bd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) struct riva_par *par = bl_get_data(bd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) U032 tmp_pcrt, tmp_pmc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) int level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) if (bd->props.power != FB_BLANK_UNBLANK ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) bd->props.fb_blank != FB_BLANK_UNBLANK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) level = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) level = bd->props.brightness;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) tmp_pmc = NV_RD32(par->riva.PMC, 0x10F0) & 0x0000FFFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) tmp_pcrt = NV_RD32(par->riva.PCRTC0, 0x081C) & 0xFFFFFFFC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) if(level > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) tmp_pcrt |= 0x1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) tmp_pmc |= (1 << 31); /* backlight bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) tmp_pmc |= riva_bl_get_level_brightness(par, level) << 16; /* level */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) NV_WR32(par->riva.PCRTC0, 0x081C, tmp_pcrt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) NV_WR32(par->riva.PMC, 0x10F0, tmp_pmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) static const struct backlight_ops riva_bl_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) .update_status = riva_bl_update_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) static void riva_bl_init(struct riva_par *par)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) struct backlight_properties props;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) struct fb_info *info = pci_get_drvdata(par->pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) struct backlight_device *bd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) char name[12];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) if (!par->FlatPanel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) #ifdef CONFIG_PMAC_BACKLIGHT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) if (!machine_is(powermac) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) !pmac_has_backlight_type("mnca"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) snprintf(name, sizeof(name), "rivabl%d", info->node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) memset(&props, 0, sizeof(struct backlight_properties));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) props.type = BACKLIGHT_RAW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) bd = backlight_device_register(name, info->dev, par, &riva_bl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) &props);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) if (IS_ERR(bd)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) info->bl_dev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) printk(KERN_WARNING "riva: Backlight registration failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) info->bl_dev = bd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) fb_bl_default_curve(info, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) MIN_LEVEL * FB_BACKLIGHT_MAX / MAX_LEVEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) FB_BACKLIGHT_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) bd->props.brightness = bd->props.max_brightness;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) bd->props.power = FB_BLANK_UNBLANK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) backlight_update_status(bd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) printk("riva: Backlight initialized (%s)\n", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) static void riva_bl_exit(struct fb_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) struct backlight_device *bd = info->bl_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) backlight_device_unregister(bd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) printk("riva: Backlight unloaded\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) static inline void riva_bl_init(struct riva_par *par) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) static inline void riva_bl_exit(struct fb_info *info) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) #endif /* CONFIG_FB_RIVA_BACKLIGHT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) /* ------------------------------------------------------------------------- *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) * MMIO access macros
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) * ------------------------------------------------------------------------- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) static inline void CRTCout(struct riva_par *par, unsigned char index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) unsigned char val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) VGA_WR08(par->riva.PCIO, 0x3d4, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) VGA_WR08(par->riva.PCIO, 0x3d5, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) static inline unsigned char CRTCin(struct riva_par *par,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) unsigned char index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) VGA_WR08(par->riva.PCIO, 0x3d4, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) return (VGA_RD08(par->riva.PCIO, 0x3d5));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) static inline void GRAout(struct riva_par *par, unsigned char index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) unsigned char val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) VGA_WR08(par->riva.PVIO, 0x3ce, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) VGA_WR08(par->riva.PVIO, 0x3cf, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) static inline unsigned char GRAin(struct riva_par *par,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) unsigned char index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) VGA_WR08(par->riva.PVIO, 0x3ce, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) return (VGA_RD08(par->riva.PVIO, 0x3cf));
^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) static inline void SEQout(struct riva_par *par, unsigned char index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) unsigned char val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) VGA_WR08(par->riva.PVIO, 0x3c4, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) VGA_WR08(par->riva.PVIO, 0x3c5, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) static inline unsigned char SEQin(struct riva_par *par,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) unsigned char index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) VGA_WR08(par->riva.PVIO, 0x3c4, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) return (VGA_RD08(par->riva.PVIO, 0x3c5));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) static inline void ATTRout(struct riva_par *par, unsigned char index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) unsigned char val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) VGA_WR08(par->riva.PCIO, 0x3c0, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) VGA_WR08(par->riva.PCIO, 0x3c0, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) static inline unsigned char ATTRin(struct riva_par *par,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) unsigned char index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) VGA_WR08(par->riva.PCIO, 0x3c0, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) return (VGA_RD08(par->riva.PCIO, 0x3c1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) static inline void MISCout(struct riva_par *par, unsigned char val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) VGA_WR08(par->riva.PVIO, 0x3c2, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) static inline unsigned char MISCin(struct riva_par *par)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) return (VGA_RD08(par->riva.PVIO, 0x3cc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) static inline void reverse_order(u32 *l)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) u8 *a = (u8 *)l;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) a[0] = bitrev8(a[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) a[1] = bitrev8(a[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) a[2] = bitrev8(a[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) a[3] = bitrev8(a[3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^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) * cursor stuff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) * ------------------------------------------------------------------------- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) * rivafb_load_cursor_image - load cursor image to hardware
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) * @data: address to monochrome bitmap (1 = foreground color, 0 = background)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) * @par: pointer to private data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) * @w: width of cursor image in pixels
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) * @h: height of cursor image in scanlines
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) * @bg: background color (ARGB1555) - alpha bit determines opacity
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) * @fg: foreground color (ARGB1555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) * DESCRIPTiON:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) * Loads cursor image based on a monochrome source and mask bitmap. The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) * image bits determines the color of the pixel, 0 for background, 1 for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) * foreground. Only the affected region (as determined by @w and @h
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) * parameters) will be updated.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) * CALLED FROM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) * rivafb_cursor()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) static void rivafb_load_cursor_image(struct riva_par *par, u8 *data8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) u16 bg, u16 fg, u32 w, u32 h)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) int i, j, k = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) u32 b, tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) u32 *data = (u32 *)data8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) bg = le16_to_cpu(bg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) fg = le16_to_cpu(fg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) w = (w + 1) & ~1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) for (i = 0; i < h; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) b = *data++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) reverse_order(&b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) for (j = 0; j < w/2; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) tmp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) #if defined (__BIG_ENDIAN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) tmp = (b & (1 << 31)) ? fg << 16 : bg << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) b <<= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) tmp |= (b & (1 << 31)) ? fg : bg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) b <<= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) tmp = (b & 1) ? fg : bg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) b >>= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) tmp |= (b & 1) ? fg << 16 : bg << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) b >>= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) writel(tmp, &par->riva.CURSOR[k++]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) k += (MAX_CURS - w)/2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)
^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) * general utility functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) * ------------------------------------------------------------------------- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) * riva_wclut - set CLUT entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) * @chip: pointer to RIVA_HW_INST object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) * @regnum: register number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) * @red: red component
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) * @green: green component
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) * @blue: blue component
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) * DESCRIPTION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) * Sets color register @regnum.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) * CALLED FROM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) * rivafb_setcolreg()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) static void riva_wclut(RIVA_HW_INST *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) unsigned char regnum, unsigned char red,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) unsigned char green, unsigned char blue)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) VGA_WR08(chip->PDIO, 0x3c8, regnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) VGA_WR08(chip->PDIO, 0x3c9, red);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) VGA_WR08(chip->PDIO, 0x3c9, green);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) VGA_WR08(chip->PDIO, 0x3c9, blue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) }
^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) * riva_rclut - read fromCLUT register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) * @chip: pointer to RIVA_HW_INST object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) * @regnum: register number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) * @red: red component
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) * @green: green component
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) * @blue: blue component
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) * DESCRIPTION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) * Reads red, green, and blue from color register @regnum.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) * CALLED FROM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) * rivafb_setcolreg()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) static void riva_rclut(RIVA_HW_INST *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) unsigned char regnum, unsigned char *red,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) unsigned char *green, unsigned char *blue)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) VGA_WR08(chip->PDIO, 0x3c7, regnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) *red = VGA_RD08(chip->PDIO, 0x3c9);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) *green = VGA_RD08(chip->PDIO, 0x3c9);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) *blue = VGA_RD08(chip->PDIO, 0x3c9);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) * riva_save_state - saves current chip state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) * @par: pointer to riva_par object containing info for current riva board
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) * @regs: pointer to riva_regs object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) * DESCRIPTION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) * Saves current chip state to @regs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) * CALLED FROM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) * rivafb_probe()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) /* from GGI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) static void riva_save_state(struct riva_par *par, struct riva_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) NVTRACE_ENTER();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) par->riva.LockUnlock(&par->riva, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) par->riva.UnloadStateExt(&par->riva, ®s->ext);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) regs->misc_output = MISCin(par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) for (i = 0; i < NUM_CRT_REGS; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) regs->crtc[i] = CRTCin(par, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) for (i = 0; i < NUM_ATC_REGS; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) regs->attr[i] = ATTRin(par, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) for (i = 0; i < NUM_GRC_REGS; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) regs->gra[i] = GRAin(par, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) for (i = 0; i < NUM_SEQ_REGS; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) regs->seq[i] = SEQin(par, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) NVTRACE_LEAVE();
^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) * riva_load_state - loads current chip state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) * @par: pointer to riva_par object containing info for current riva board
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) * @regs: pointer to riva_regs object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) * DESCRIPTION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) * Loads chip state from @regs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) * CALLED FROM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) * riva_load_video_mode()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) * rivafb_probe()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) * rivafb_remove()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) /* from GGI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) static void riva_load_state(struct riva_par *par, struct riva_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) RIVA_HW_STATE *state = ®s->ext;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) NVTRACE_ENTER();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) CRTCout(par, 0x11, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) par->riva.LockUnlock(&par->riva, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) par->riva.LoadStateExt(&par->riva, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) MISCout(par, regs->misc_output);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) for (i = 0; i < NUM_CRT_REGS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) switch (i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) case 0x19:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) case 0x20 ... 0x40:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) CRTCout(par, i, regs->crtc[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) }
^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) for (i = 0; i < NUM_ATC_REGS; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) ATTRout(par, i, regs->attr[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) for (i = 0; i < NUM_GRC_REGS; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) GRAout(par, i, regs->gra[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) for (i = 0; i < NUM_SEQ_REGS; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) SEQout(par, i, regs->seq[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) NVTRACE_LEAVE();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) * riva_load_video_mode - calculate timings
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) * @info: pointer to fb_info object containing info for current riva board
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) * DESCRIPTION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) * Calculate some timings and then send em off to riva_load_state().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) * CALLED FROM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) * rivafb_set_par()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) static int riva_load_video_mode(struct fb_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) int bpp, width, hDisplaySize, hDisplay, hStart,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) hEnd, hTotal, height, vDisplay, vStart, vEnd, vTotal, dotClock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) int hBlankStart, hBlankEnd, vBlankStart, vBlankEnd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) struct riva_par *par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) struct riva_regs newmode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) NVTRACE_ENTER();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) /* time to calculate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) rivafb_blank(FB_BLANK_NORMAL, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) bpp = info->var.bits_per_pixel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) if (bpp == 16 && info->var.green.length == 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) bpp = 15;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) width = info->var.xres_virtual;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) hDisplaySize = info->var.xres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) hDisplay = (hDisplaySize / 8) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) hStart = (hDisplaySize + info->var.right_margin) / 8 - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) hEnd = (hDisplaySize + info->var.right_margin +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) info->var.hsync_len) / 8 - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) hTotal = (hDisplaySize + info->var.right_margin +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) info->var.hsync_len + info->var.left_margin) / 8 - 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) hBlankStart = hDisplay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) hBlankEnd = hTotal + 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) height = info->var.yres_virtual;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) vDisplay = info->var.yres - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) vStart = info->var.yres + info->var.lower_margin - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) vEnd = info->var.yres + info->var.lower_margin +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) info->var.vsync_len - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) vTotal = info->var.yres + info->var.lower_margin +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) info->var.vsync_len + info->var.upper_margin + 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) vBlankStart = vDisplay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) vBlankEnd = vTotal + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) dotClock = 1000000000 / info->var.pixclock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) memcpy(&newmode, ®_template, sizeof(struct riva_regs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) if ((info->var.vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) vTotal |= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) if (par->FlatPanel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) vStart = vTotal - 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) vEnd = vTotal - 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) vBlankStart = vStart;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) hStart = hTotal - 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) hEnd = hTotal - 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) hBlankEnd = hTotal + 4;
^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) newmode.crtc[0x0] = Set8Bits (hTotal);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) newmode.crtc[0x1] = Set8Bits (hDisplay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) newmode.crtc[0x2] = Set8Bits (hBlankStart);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) newmode.crtc[0x3] = SetBitField (hBlankEnd, 4: 0, 4:0) | SetBit (7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) newmode.crtc[0x4] = Set8Bits (hStart);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) newmode.crtc[0x5] = SetBitField (hBlankEnd, 5: 5, 7:7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) | SetBitField (hEnd, 4: 0, 4:0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) newmode.crtc[0x6] = SetBitField (vTotal, 7: 0, 7:0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) newmode.crtc[0x7] = SetBitField (vTotal, 8: 8, 0:0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) | SetBitField (vDisplay, 8: 8, 1:1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) | SetBitField (vStart, 8: 8, 2:2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) | SetBitField (vBlankStart, 8: 8, 3:3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) | SetBit (4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) | SetBitField (vTotal, 9: 9, 5:5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) | SetBitField (vDisplay, 9: 9, 6:6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) | SetBitField (vStart, 9: 9, 7:7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) newmode.crtc[0x9] = SetBitField (vBlankStart, 9: 9, 5:5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) | SetBit (6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) newmode.crtc[0x10] = Set8Bits (vStart);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) newmode.crtc[0x11] = SetBitField (vEnd, 3: 0, 3:0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) | SetBit (5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) newmode.crtc[0x12] = Set8Bits (vDisplay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) newmode.crtc[0x13] = (width / 8) * ((bpp + 1) / 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) newmode.crtc[0x15] = Set8Bits (vBlankStart);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) newmode.crtc[0x16] = Set8Bits (vBlankEnd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) newmode.ext.screen = SetBitField(hBlankEnd,6:6,4:4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) | SetBitField(vBlankStart,10:10,3:3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) | SetBitField(vStart,10:10,2:2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) | SetBitField(vDisplay,10:10,1:1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) | SetBitField(vTotal,10:10,0:0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) newmode.ext.horiz = SetBitField(hTotal,8:8,0:0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) | SetBitField(hDisplay,8:8,1:1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) | SetBitField(hBlankStart,8:8,2:2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) | SetBitField(hStart,8:8,3:3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) newmode.ext.extra = SetBitField(vTotal,11:11,0:0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) | SetBitField(vDisplay,11:11,2:2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) | SetBitField(vStart,11:11,4:4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) | SetBitField(vBlankStart,11:11,6:6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) if ((info->var.vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) int tmp = (hTotal >> 1) & ~1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) newmode.ext.interlace = Set8Bits(tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) newmode.ext.horiz |= SetBitField(tmp, 8:8,4:4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) newmode.ext.interlace = 0xff; /* interlace off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) if (par->riva.Architecture >= NV_ARCH_10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) par->riva.CURSOR = (U032 __iomem *)(info->screen_base + par->riva.CursorStart);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) if (info->var.sync & FB_SYNC_HOR_HIGH_ACT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) newmode.misc_output &= ~0x40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) newmode.misc_output |= 0x40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) if (info->var.sync & FB_SYNC_VERT_HIGH_ACT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) newmode.misc_output &= ~0x80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) newmode.misc_output |= 0x80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) rc = CalcStateExt(&par->riva, &newmode.ext, par->pdev, bpp, width,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) hDisplaySize, height, dotClock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) newmode.ext.scale = NV_RD32(par->riva.PRAMDAC, 0x00000848) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) 0xfff000ff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) if (par->FlatPanel == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) newmode.ext.pixel |= (1 << 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) newmode.ext.scale |= (1 << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) if (par->SecondCRTC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) newmode.ext.head = NV_RD32(par->riva.PCRTC0, 0x00000860) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) ~0x00001000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) newmode.ext.head2 = NV_RD32(par->riva.PCRTC0, 0x00002860) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) 0x00001000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) newmode.ext.crtcOwner = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) newmode.ext.pllsel |= 0x20000800;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) newmode.ext.vpll2 = newmode.ext.vpll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) } else if (par->riva.twoHeads) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) newmode.ext.head = NV_RD32(par->riva.PCRTC0, 0x00000860) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) 0x00001000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) newmode.ext.head2 = NV_RD32(par->riva.PCRTC0, 0x00002860) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) ~0x00001000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) newmode.ext.crtcOwner = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) newmode.ext.vpll2 = NV_RD32(par->riva.PRAMDAC0, 0x00000520);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) if (par->FlatPanel == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) newmode.ext.pixel |= (1 << 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) newmode.ext.scale |= (1 << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) newmode.ext.cursorConfig = 0x02000100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) par->current_state = newmode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) riva_load_state(par, &par->current_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) par->riva.LockUnlock(&par->riva, 0); /* important for HW cursor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) rivafb_blank(FB_BLANK_UNBLANK, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) NVTRACE_LEAVE();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) static void riva_update_var(struct fb_var_screeninfo *var,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) const struct fb_videomode *modedb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) NVTRACE_ENTER();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) var->xres = var->xres_virtual = modedb->xres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) var->yres = modedb->yres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) if (var->yres_virtual < var->yres)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) var->yres_virtual = var->yres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) var->xoffset = var->yoffset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) var->pixclock = modedb->pixclock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) var->left_margin = modedb->left_margin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) var->right_margin = modedb->right_margin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) var->upper_margin = modedb->upper_margin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) var->lower_margin = modedb->lower_margin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) var->hsync_len = modedb->hsync_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) var->vsync_len = modedb->vsync_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) var->sync = modedb->sync;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) var->vmode = modedb->vmode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) NVTRACE_LEAVE();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) * rivafb_do_maximize -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) * @info: pointer to fb_info object containing info for current riva board
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) * @var:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) * @nom:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) * @den:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) * DESCRIPTION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) * .
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) * RETURNS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) * -EINVAL on failure, 0 on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) * CALLED FROM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) * rivafb_check_var()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) static int rivafb_do_maximize(struct fb_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) struct fb_var_screeninfo *var,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) int nom, int den)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) static struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) int xres, yres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) } modes[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) {1600, 1280},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) {1280, 1024},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) {1024, 768},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) {800, 600},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) {640, 480},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) {-1, -1}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) NVTRACE_ENTER();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) /* use highest possible virtual resolution */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) if (var->xres_virtual == -1 && var->yres_virtual == -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) printk(KERN_WARNING PFX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) "using maximum available virtual resolution\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) for (i = 0; modes[i].xres != -1; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) if (modes[i].xres * nom / den * modes[i].yres <
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) info->fix.smem_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) if (modes[i].xres == -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) printk(KERN_ERR PFX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) "could not find a virtual resolution that fits into video memory!!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) NVTRACE("EXIT - EINVAL error\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) var->xres_virtual = modes[i].xres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) var->yres_virtual = modes[i].yres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) printk(KERN_INFO PFX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) "virtual resolution set to maximum of %dx%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) var->xres_virtual, var->yres_virtual);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) } else if (var->xres_virtual == -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) var->xres_virtual = (info->fix.smem_len * den /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) (nom * var->yres_virtual)) & ~15;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) printk(KERN_WARNING PFX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) "setting virtual X resolution to %d\n", var->xres_virtual);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) } else if (var->yres_virtual == -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) var->xres_virtual = (var->xres_virtual + 15) & ~15;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) var->yres_virtual = info->fix.smem_len * den /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) (nom * var->xres_virtual);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) printk(KERN_WARNING PFX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) "setting virtual Y resolution to %d\n", var->yres_virtual);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) var->xres_virtual = (var->xres_virtual + 15) & ~15;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) if (var->xres_virtual * nom / den * var->yres_virtual > info->fix.smem_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) printk(KERN_ERR PFX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) "mode %dx%dx%d rejected...resolution too high to fit into video memory!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) var->xres, var->yres, var->bits_per_pixel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) NVTRACE("EXIT - EINVAL error\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) return -EINVAL;
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) if (var->xres_virtual * nom / den >= 8192) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) printk(KERN_WARNING PFX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) "virtual X resolution (%d) is too high, lowering to %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) var->xres_virtual, 8192 * den / nom - 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) var->xres_virtual = 8192 * den / nom - 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) if (var->xres_virtual < var->xres) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) printk(KERN_ERR PFX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) "virtual X resolution (%d) is smaller than real\n", var->xres_virtual);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) if (var->yres_virtual < var->yres) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) printk(KERN_ERR PFX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) "virtual Y resolution (%d) is smaller than real\n", var->yres_virtual);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) if (var->yres_virtual > 0x7fff/nom)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) var->yres_virtual = 0x7fff/nom;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) if (var->xres_virtual > 0x7fff/nom)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) var->xres_virtual = 0x7fff/nom;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) NVTRACE_LEAVE();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) riva_set_pattern(struct riva_par *par, int clr0, int clr1, int pat0, int pat1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) RIVA_FIFO_FREE(par->riva, Patt, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) NV_WR32(&par->riva.Patt->Color0, 0, clr0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) NV_WR32(&par->riva.Patt->Color1, 0, clr1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) NV_WR32(par->riva.Patt->Monochrome, 0, pat0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) NV_WR32(par->riva.Patt->Monochrome, 4, pat1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) /* acceleration routines */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) static inline void wait_for_idle(struct riva_par *par)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) while (par->riva.Busy(&par->riva));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) * Set ROP. Translate X rop into ROP3. Internal routine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) riva_set_rop_solid(struct riva_par *par, int rop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) riva_set_pattern(par, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) RIVA_FIFO_FREE(par->riva, Rop, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) NV_WR32(&par->riva.Rop->Rop3, 0, rop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) static void riva_setup_accel(struct fb_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) struct riva_par *par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) RIVA_FIFO_FREE(par->riva, Clip, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) NV_WR32(&par->riva.Clip->TopLeft, 0, 0x0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) NV_WR32(&par->riva.Clip->WidthHeight, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) (info->var.xres_virtual & 0xffff) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) (info->var.yres_virtual << 16));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) riva_set_rop_solid(par, 0xcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) wait_for_idle(par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) * riva_get_cmap_len - query current color map length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) * @var: standard kernel fb changeable data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) * DESCRIPTION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) * Get current color map length.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) * RETURNS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) * Length of color map
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) * CALLED FROM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) * rivafb_setcolreg()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) static int riva_get_cmap_len(const struct fb_var_screeninfo *var)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) int rc = 256; /* reasonable default */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) switch (var->green.length) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) case 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) rc = 256; /* 256 entries (2^8), 8 bpp and RGB8888 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) case 5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) rc = 32; /* 32 entries (2^5), 16 bpp, RGB555 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) case 6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) rc = 64; /* 64 entries (2^6), 16 bpp, RGB565 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) /* should not occur */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) /* ------------------------------------------------------------------------- *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) * framebuffer operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) * ------------------------------------------------------------------------- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) static int rivafb_open(struct fb_info *info, int user)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) struct riva_par *par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) NVTRACE_ENTER();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) mutex_lock(&par->open_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) if (!par->ref_count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) #ifdef CONFIG_X86
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) memset(&par->state, 0, sizeof(struct vgastate));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) par->state.flags = VGA_SAVE_MODE | VGA_SAVE_FONTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) /* save the DAC for Riva128 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) if (par->riva.Architecture == NV_ARCH_03)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) par->state.flags |= VGA_SAVE_CMAP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) save_vga(&par->state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) /* vgaHWunlock() + riva unlock (0x7F) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) CRTCout(par, 0x11, 0xFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) par->riva.LockUnlock(&par->riva, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) riva_save_state(par, &par->initial_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) par->ref_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) mutex_unlock(&par->open_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) NVTRACE_LEAVE();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) static int rivafb_release(struct fb_info *info, int user)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) struct riva_par *par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) NVTRACE_ENTER();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) mutex_lock(&par->open_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) if (!par->ref_count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) mutex_unlock(&par->open_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) if (par->ref_count == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) par->riva.LockUnlock(&par->riva, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) par->riva.LoadStateExt(&par->riva, &par->initial_state.ext);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) riva_load_state(par, &par->initial_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) #ifdef CONFIG_X86
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) restore_vga(&par->state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) par->riva.LockUnlock(&par->riva, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) par->ref_count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) mutex_unlock(&par->open_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) NVTRACE_LEAVE();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) static int rivafb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) const struct fb_videomode *mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) struct riva_par *par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) int nom, den; /* translating from pixels->bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) int mode_valid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) NVTRACE_ENTER();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) if (!var->pixclock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) switch (var->bits_per_pixel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) case 1 ... 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) var->red.offset = var->green.offset = var->blue.offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) var->red.length = var->green.length = var->blue.length = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) var->bits_per_pixel = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) nom = den = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) case 9 ... 15:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) var->green.length = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) case 16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) var->bits_per_pixel = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) /* The Riva128 supports RGB555 only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) if (par->riva.Architecture == NV_ARCH_03)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) var->green.length = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) if (var->green.length == 5) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) /* 0rrrrrgg gggbbbbb */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) var->red.offset = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) var->green.offset = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) var->blue.offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) var->red.length = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) var->green.length = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) var->blue.length = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) /* rrrrrggg gggbbbbb */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) var->red.offset = 11;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) var->green.offset = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) var->blue.offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) var->red.length = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) var->green.length = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) var->blue.length = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) nom = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) den = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) case 17 ... 32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) var->red.length = var->green.length = var->blue.length = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) var->bits_per_pixel = 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) var->red.offset = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) var->green.offset = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) var->blue.offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) nom = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) den = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) printk(KERN_ERR PFX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) "mode %dx%dx%d rejected...color depth not supported.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) var->xres, var->yres, var->bits_per_pixel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) NVTRACE("EXIT, returning -EINVAL\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) if (!strictmode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) if (!info->monspecs.vfmax || !info->monspecs.hfmax ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) !info->monspecs.dclkmax || !fb_validate_mode(var, info))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) mode_valid = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) /* calculate modeline if supported by monitor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) if (!mode_valid && info->monspecs.gtf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) if (!fb_get_mode(FB_MAXTIMINGS, 0, var, info))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) mode_valid = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) if (!mode_valid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) mode = fb_find_best_mode(var, &info->modelist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) if (mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) riva_update_var(var, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) mode_valid = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) if (!mode_valid && info->monspecs.modedb_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) if (var->xres_virtual < var->xres)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) var->xres_virtual = var->xres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) if (var->yres_virtual <= var->yres)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) var->yres_virtual = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) if (rivafb_do_maximize(info, var, nom, den) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) /* truncate xoffset and yoffset to maximum if too high */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) if (var->xoffset > var->xres_virtual - var->xres)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) var->xoffset = var->xres_virtual - var->xres - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) if (var->yoffset > var->yres_virtual - var->yres)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) var->yoffset = var->yres_virtual - var->yres - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) var->red.msb_right =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) var->green.msb_right =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) var->blue.msb_right =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) var->transp.offset = var->transp.length = var->transp.msb_right = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) NVTRACE_LEAVE();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) static int rivafb_set_par(struct fb_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) struct riva_par *par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) NVTRACE_ENTER();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) /* vgaHWunlock() + riva unlock (0x7F) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) CRTCout(par, 0x11, 0xFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) par->riva.LockUnlock(&par->riva, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) rc = riva_load_video_mode(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) if(!(info->flags & FBINFO_HWACCEL_DISABLED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) riva_setup_accel(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) par->cursor_reset = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) info->fix.line_length = (info->var.xres_virtual * (info->var.bits_per_pixel >> 3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) info->fix.visual = (info->var.bits_per_pixel == 8) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) if (info->flags & FBINFO_HWACCEL_DISABLED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) info->pixmap.scan_align = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) info->pixmap.scan_align = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) NVTRACE_LEAVE();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) * rivafb_pan_display
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) * @var: standard kernel fb changeable data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) * @con: TODO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) * @info: pointer to fb_info object containing info for current riva board
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) * DESCRIPTION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) * Pan (or wrap, depending on the `vmode' field) the display using the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) * `xoffset' and `yoffset' fields of the `var' structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) * If the values don't fit, return -EINVAL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) * This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) static int rivafb_pan_display(struct fb_var_screeninfo *var,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) struct fb_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) struct riva_par *par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) unsigned int base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) NVTRACE_ENTER();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) base = var->yoffset * info->fix.line_length + var->xoffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) par->riva.SetStartAddress(&par->riva, base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) NVTRACE_LEAVE();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) static int rivafb_blank(int blank, struct fb_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) struct riva_par *par= info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) unsigned char tmp, vesa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) tmp = SEQin(par, 0x01) & ~0x20; /* screen on/off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) vesa = CRTCin(par, 0x1a) & ~0xc0; /* sync on/off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) NVTRACE_ENTER();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) if (blank)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) tmp |= 0x20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) switch (blank) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) case FB_BLANK_UNBLANK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) case FB_BLANK_NORMAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) case FB_BLANK_VSYNC_SUSPEND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) vesa |= 0x80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) case FB_BLANK_HSYNC_SUSPEND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) vesa |= 0x40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) case FB_BLANK_POWERDOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) vesa |= 0xc0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) SEQout(par, 0x01, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) CRTCout(par, 0x1a, vesa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) NVTRACE_LEAVE();
^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) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) * rivafb_setcolreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) * @regno: register index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) * @red: red component
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) * @green: green component
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) * @blue: blue component
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) * @transp: transparency
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) * @info: pointer to fb_info object containing info for current riva board
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) * DESCRIPTION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) * Set a single color register. The values supplied have a 16 bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) * magnitude.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) * RETURNS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) * Return != 0 for invalid regno.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) * CALLED FROM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) * fbcmap.c:fb_set_cmap()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) static int rivafb_setcolreg(unsigned regno, unsigned red, unsigned green,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) unsigned blue, unsigned transp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) struct fb_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) struct riva_par *par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) RIVA_HW_INST *chip = &par->riva;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) if (regno >= riva_get_cmap_len(&info->var))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) if (info->var.grayscale) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) /* gray = 0.30*R + 0.59*G + 0.11*B */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) red = green = blue =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) (red * 77 + green * 151 + blue * 28) >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) if (regno < 16 && info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) ((u32 *) info->pseudo_palette)[regno] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) (regno << info->var.red.offset) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) (regno << info->var.green.offset) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) (regno << info->var.blue.offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) * The Riva128 2D engine requires color information in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) * TrueColor format even if framebuffer is in DirectColor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) if (par->riva.Architecture == NV_ARCH_03) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) switch (info->var.bits_per_pixel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) case 16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) par->palette[regno] = ((red & 0xf800) >> 1) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) ((green & 0xf800) >> 6) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) ((blue & 0xf800) >> 11);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) case 32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) par->palette[regno] = ((red & 0xff00) << 8) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) ((green & 0xff00)) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) ((blue & 0xff00) >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) switch (info->var.bits_per_pixel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) case 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) /* "transparent" stuff is completely ignored. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) riva_wclut(chip, regno, red >> 8, green >> 8, blue >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) case 16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) if (info->var.green.length == 5) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) for (i = 0; i < 8; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) riva_wclut(chip, regno*8+i, red >> 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) green >> 8, blue >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) u8 r, g, b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) if (regno < 32) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) for (i = 0; i < 8; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) riva_wclut(chip, regno*8+i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) red >> 8, green >> 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) blue >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) riva_rclut(chip, regno*4, &r, &g, &b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) for (i = 0; i < 4; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) riva_wclut(chip, regno*4+i, r,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) green >> 8, b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) case 32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) riva_wclut(chip, regno, red >> 8, green >> 8, blue >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) /* do nothing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) * rivafb_fillrect - hardware accelerated color fill function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) * @info: pointer to fb_info structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) * @rect: pointer to fb_fillrect structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) * DESCRIPTION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) * This function fills up a region of framebuffer memory with a solid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) * color with a choice of two different ROP's, copy or invert.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) * CALLED FROM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) * framebuffer hook
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) static void rivafb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) struct riva_par *par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) u_int color, rop = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) if ((info->flags & FBINFO_HWACCEL_DISABLED)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) cfb_fillrect(info, rect);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) if (info->var.bits_per_pixel == 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) color = rect->color;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) if (par->riva.Architecture != NV_ARCH_03)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) color = ((u32 *)info->pseudo_palette)[rect->color];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) color = par->palette[rect->color];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) switch (rect->rop) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) case ROP_XOR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) rop = 0x66;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) case ROP_COPY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) rop = 0xCC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) riva_set_rop_solid(par, rop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) RIVA_FIFO_FREE(par->riva, Bitmap, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) NV_WR32(&par->riva.Bitmap->Color1A, 0, color);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) RIVA_FIFO_FREE(par->riva, Bitmap, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) NV_WR32(&par->riva.Bitmap->UnclippedRectangle[0].TopLeft, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) (rect->dx << 16) | rect->dy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) mb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) NV_WR32(&par->riva.Bitmap->UnclippedRectangle[0].WidthHeight, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) (rect->width << 16) | rect->height);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) mb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) riva_set_rop_solid(par, 0xcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) * rivafb_copyarea - hardware accelerated blit function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) * @info: pointer to fb_info structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) * @region: pointer to fb_copyarea structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) * DESCRIPTION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) * This copies an area of pixels from one location to another
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) * CALLED FROM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) * framebuffer hook
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) static void rivafb_copyarea(struct fb_info *info, const struct fb_copyarea *region)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) struct riva_par *par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) if ((info->flags & FBINFO_HWACCEL_DISABLED)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) cfb_copyarea(info, region);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) RIVA_FIFO_FREE(par->riva, Blt, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) NV_WR32(&par->riva.Blt->TopLeftSrc, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) (region->sy << 16) | region->sx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) NV_WR32(&par->riva.Blt->TopLeftDst, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) (region->dy << 16) | region->dx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) mb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) NV_WR32(&par->riva.Blt->WidthHeight, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) (region->height << 16) | region->width);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) mb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) static inline void convert_bgcolor_16(u32 *col)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) *col = ((*col & 0x0000F800) << 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) | ((*col & 0x00007E0) << 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) | ((*col & 0x0000001F) << 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) | 0xFF000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) mb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) * rivafb_imageblit: hardware accelerated color expand function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) * @info: pointer to fb_info structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) * @image: pointer to fb_image structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) * DESCRIPTION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) * If the source is a monochrome bitmap, the function fills up a a region
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) * of framebuffer memory with pixels whose color is determined by the bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) * setting of the bitmap, 1 - foreground, 0 - background.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) * If the source is not a monochrome bitmap, color expansion is not done.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) * In this case, it is channeled to a software function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) * CALLED FROM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) * framebuffer hook
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) static void rivafb_imageblit(struct fb_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) const struct fb_image *image)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) struct riva_par *par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) u32 fgx = 0, bgx = 0, width, tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) u8 *cdat = (u8 *) image->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) volatile u32 __iomem *d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) int i, size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) if ((info->flags & FBINFO_HWACCEL_DISABLED) || image->depth != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) cfb_imageblit(info, image);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) switch (info->var.bits_per_pixel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) case 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) fgx = image->fg_color;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) bgx = image->bg_color;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) case 16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) case 32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) if (par->riva.Architecture != NV_ARCH_03) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) fgx = ((u32 *)info->pseudo_palette)[image->fg_color];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) bgx = ((u32 *)info->pseudo_palette)[image->bg_color];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) fgx = par->palette[image->fg_color];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) bgx = par->palette[image->bg_color];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) if (info->var.green.length == 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) convert_bgcolor_16(&bgx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) RIVA_FIFO_FREE(par->riva, Bitmap, 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) NV_WR32(&par->riva.Bitmap->ClipE.TopLeft, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) (image->dy << 16) | (image->dx & 0xFFFF));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) NV_WR32(&par->riva.Bitmap->ClipE.BottomRight, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) (((image->dy + image->height) << 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) ((image->dx + image->width) & 0xffff)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) NV_WR32(&par->riva.Bitmap->Color0E, 0, bgx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) NV_WR32(&par->riva.Bitmap->Color1E, 0, fgx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) NV_WR32(&par->riva.Bitmap->WidthHeightInE, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) (image->height << 16) | ((image->width + 31) & ~31));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) NV_WR32(&par->riva.Bitmap->WidthHeightOutE, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) (image->height << 16) | ((image->width + 31) & ~31));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) NV_WR32(&par->riva.Bitmap->PointE, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) (image->dy << 16) | (image->dx & 0xFFFF));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) d = &par->riva.Bitmap->MonochromeData01E;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) width = (image->width + 31)/32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) size = width * image->height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) while (size >= 16) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) RIVA_FIFO_FREE(par->riva, Bitmap, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) for (i = 0; i < 16; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) tmp = *((u32 *)cdat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) cdat = (u8 *)((u32 *)cdat + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) reverse_order(&tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) NV_WR32(d, i*4, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) size -= 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) if (size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) RIVA_FIFO_FREE(par->riva, Bitmap, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) for (i = 0; i < size; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) tmp = *((u32 *) cdat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) cdat = (u8 *)((u32 *)cdat + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) reverse_order(&tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) NV_WR32(d, i*4, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) * rivafb_cursor - hardware cursor function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) * @info: pointer to info structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) * @cursor: pointer to fbcursor structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) * DESCRIPTION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) * A cursor function that supports displaying a cursor image via hardware.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) * Within the kernel, copy and invert rops are supported. If exported
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) * to user space, only the copy rop will be supported.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) * CALLED FROM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) * framebuffer hook
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) static int rivafb_cursor(struct fb_info *info, struct fb_cursor *cursor)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) struct riva_par *par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) u8 data[MAX_CURS * MAX_CURS/8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) int i, set = cursor->set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) u16 fg, bg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) if (cursor->image.width > MAX_CURS || cursor->image.height > MAX_CURS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) par->riva.ShowHideCursor(&par->riva, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) if (par->cursor_reset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) set = FB_CUR_SETALL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) par->cursor_reset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) if (set & FB_CUR_SETSIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) memset_io(par->riva.CURSOR, 0, MAX_CURS * MAX_CURS * 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) if (set & FB_CUR_SETPOS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) u32 xx, yy, temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) yy = cursor->image.dy - info->var.yoffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) xx = cursor->image.dx - info->var.xoffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) temp = xx & 0xFFFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) temp |= yy << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) NV_WR32(par->riva.PRAMDAC, 0x0000300, temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) if (set & (FB_CUR_SETSHAPE | FB_CUR_SETCMAP | FB_CUR_SETIMAGE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) u32 bg_idx = cursor->image.bg_color;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) u32 fg_idx = cursor->image.fg_color;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) u32 s_pitch = (cursor->image.width+7) >> 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) u32 d_pitch = MAX_CURS/8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) u8 *dat = (u8 *) cursor->image.data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) u8 *msk = (u8 *) cursor->mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) u8 *src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) src = kmalloc_array(s_pitch, cursor->image.height, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) if (src) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) switch (cursor->rop) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) case ROP_XOR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) for (i = 0; i < s_pitch * cursor->image.height; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) src[i] = dat[i] ^ msk[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) case ROP_COPY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) for (i = 0; i < s_pitch * cursor->image.height; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) src[i] = dat[i] & msk[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) fb_pad_aligned_buffer(data, d_pitch, src, s_pitch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) cursor->image.height);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) bg = ((info->cmap.red[bg_idx] & 0xf8) << 7) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) ((info->cmap.green[bg_idx] & 0xf8) << 2) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) ((info->cmap.blue[bg_idx] & 0xf8) >> 3) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) 1 << 15;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) fg = ((info->cmap.red[fg_idx] & 0xf8) << 7) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) ((info->cmap.green[fg_idx] & 0xf8) << 2) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) ((info->cmap.blue[fg_idx] & 0xf8) >> 3) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) 1 << 15;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) par->riva.LockUnlock(&par->riva, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) rivafb_load_cursor_image(par, data, bg, fg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) cursor->image.width,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) cursor->image.height);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) kfree(src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) if (cursor->enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) par->riva.ShowHideCursor(&par->riva, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) return 0;
^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) static int rivafb_sync(struct fb_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) struct riva_par *par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) wait_for_idle(par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) /* ------------------------------------------------------------------------- *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) * initialization helper functions
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) /* kernel interface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) static const struct fb_ops riva_fb_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) .fb_open = rivafb_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) .fb_release = rivafb_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) .fb_check_var = rivafb_check_var,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) .fb_set_par = rivafb_set_par,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) .fb_setcolreg = rivafb_setcolreg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) .fb_pan_display = rivafb_pan_display,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) .fb_blank = rivafb_blank,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) .fb_fillrect = rivafb_fillrect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) .fb_copyarea = rivafb_copyarea,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) .fb_imageblit = rivafb_imageblit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) .fb_cursor = rivafb_cursor,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) .fb_sync = rivafb_sync,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) static int riva_set_fbinfo(struct fb_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) unsigned int cmap_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) struct riva_par *par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) NVTRACE_ENTER();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) info->flags = FBINFO_DEFAULT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) | FBINFO_HWACCEL_XPAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) | FBINFO_HWACCEL_YPAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) | FBINFO_HWACCEL_COPYAREA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) | FBINFO_HWACCEL_FILLRECT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) | FBINFO_HWACCEL_IMAGEBLIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) /* Accel seems to not work properly on NV30 yet...*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) if ((par->riva.Architecture == NV_ARCH_30) || noaccel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) printk(KERN_DEBUG PFX "disabling acceleration\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) info->flags |= FBINFO_HWACCEL_DISABLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) info->var = rivafb_default_var;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) info->fix.visual = (info->var.bits_per_pixel == 8) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) info->pseudo_palette = par->pseudo_palette;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) cmap_len = riva_get_cmap_len(&info->var);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) fb_alloc_cmap(&info->cmap, cmap_len, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) info->pixmap.size = 8 * 1024;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) info->pixmap.buf_align = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) info->pixmap.access_align = 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) info->pixmap.flags = FB_PIXMAP_SYSTEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) info->var.yres_virtual = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) NVTRACE_LEAVE();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) return (rivafb_check_var(&info->var, info));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) static int riva_get_EDID_OF(struct fb_info *info, struct pci_dev *pd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) struct riva_par *par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) struct device_node *dp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) const unsigned char *pedid = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) const unsigned char *disptype = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) static char *propnames[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) "DFP,EDID", "LCD,EDID", "EDID", "EDID1", "EDID,B", "EDID,A", NULL };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) NVTRACE_ENTER();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) dp = pci_device_to_OF_node(pd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) for (; dp != NULL; dp = dp->child) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) disptype = of_get_property(dp, "display-type", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) if (disptype == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) if (strncmp(disptype, "LCD", 3) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) for (i = 0; propnames[i] != NULL; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) pedid = of_get_property(dp, propnames[i], NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) if (pedid != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) par->EDID = (unsigned char *)pedid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) NVTRACE("LCD found.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) NVTRACE_LEAVE();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) #if defined(CONFIG_FB_RIVA_I2C)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) static int riva_get_EDID_i2c(struct fb_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) struct riva_par *par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) struct fb_var_screeninfo var;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) NVTRACE_ENTER();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) par->riva.LockUnlock(&par->riva, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) riva_create_i2c_busses(par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) for (i = 0; i < 3; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) if (!par->chan[i].par)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) riva_probe_i2c_connector(par, i, &par->EDID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) if (par->EDID && !fb_parse_edid(par->EDID, &var)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) printk(PFX "Found EDID Block from BUS %i\n", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) NVTRACE_LEAVE();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) return (par->EDID) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) #endif /* CONFIG_FB_RIVA_I2C */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) static void riva_update_default_var(struct fb_var_screeninfo *var,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) struct fb_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) struct fb_monspecs *specs = &info->monspecs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) struct fb_videomode modedb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) NVTRACE_ENTER();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) /* respect mode options */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) if (mode_option) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) fb_find_mode(var, info, mode_option,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) specs->modedb, specs->modedb_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) NULL, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) } else if (specs->modedb != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) /* get first mode in database as fallback */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) modedb = specs->modedb[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) /* get preferred timing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) if (info->monspecs.misc & FB_MISC_1ST_DETAIL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) for (i = 0; i < specs->modedb_len; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) if (specs->modedb[i].flag & FB_MODE_IS_FIRST) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) modedb = specs->modedb[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) var->bits_per_pixel = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) riva_update_var(var, &modedb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) NVTRACE_LEAVE();
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) static void riva_get_EDID(struct fb_info *info, struct pci_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) NVTRACE_ENTER();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) if (riva_get_EDID_OF(info, pdev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) NVTRACE_LEAVE();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) if (IS_ENABLED(CONFIG_OF))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) printk(PFX "could not retrieve EDID from OF\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) #if defined(CONFIG_FB_RIVA_I2C)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) if (!riva_get_EDID_i2c(info))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) printk(PFX "could not retrieve EDID from DDC/I2C\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) NVTRACE_LEAVE();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) static void riva_get_edidinfo(struct fb_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) struct fb_var_screeninfo *var = &rivafb_default_var;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) struct riva_par *par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) fb_edid_to_monspecs(par->EDID, &info->monspecs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) fb_videomode_to_modelist(info->monspecs.modedb, info->monspecs.modedb_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) &info->modelist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) riva_update_default_var(var, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) /* if user specified flatpanel, we respect that */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) if (info->monspecs.input & FB_DISP_DDI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) par->FlatPanel = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) /* ------------------------------------------------------------------------- *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) * PCI bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) * ------------------------------------------------------------------------- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) static u32 riva_get_arch(struct pci_dev *pd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) u32 arch = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) switch (pd->device & 0x0ff0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) case 0x0100: /* GeForce 256 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) case 0x0110: /* GeForce2 MX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) case 0x0150: /* GeForce2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) case 0x0170: /* GeForce4 MX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) case 0x0180: /* GeForce4 MX (8x AGP) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) case 0x01A0: /* nForce */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) case 0x01F0: /* nForce2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) arch = NV_ARCH_10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) case 0x0200: /* GeForce3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) case 0x0250: /* GeForce4 Ti */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) case 0x0280: /* GeForce4 Ti (8x AGP) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) arch = NV_ARCH_20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) case 0x0300: /* GeForceFX 5800 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) case 0x0310: /* GeForceFX 5600 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) case 0x0320: /* GeForceFX 5200 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) case 0x0330: /* GeForceFX 5900 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) case 0x0340: /* GeForceFX 5700 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) arch = NV_ARCH_30;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) case 0x0020: /* TNT, TNT2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) arch = NV_ARCH_04;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) case 0x0010: /* Riva128 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) arch = NV_ARCH_03;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) default: /* unknown architecture */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) return arch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) static int rivafb_probe(struct pci_dev *pd, const struct pci_device_id *ent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) struct riva_par *default_par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) struct fb_info *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) NVTRACE_ENTER();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) assert(pd != NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) info = framebuffer_alloc(sizeof(struct riva_par), &pd->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) if (!info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) goto err_ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) default_par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) default_par->pdev = pd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) info->pixmap.addr = kzalloc(8 * 1024, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) if (info->pixmap.addr == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) goto err_framebuffer_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) ret = pci_enable_device(pd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) printk(KERN_ERR PFX "cannot enable PCI device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) goto err_free_pixmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) ret = pci_request_regions(pd, "rivafb");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) printk(KERN_ERR PFX "cannot request PCI regions\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) goto err_disable_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) mutex_init(&default_par->open_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) default_par->riva.Architecture = riva_get_arch(pd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) default_par->Chipset = (pd->vendor << 16) | pd->device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) printk(KERN_INFO PFX "nVidia device/chipset %X\n",default_par->Chipset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) if(default_par->riva.Architecture == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) printk(KERN_ERR PFX "unknown NV_ARCH\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) ret=-ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) goto err_release_region;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) if(default_par->riva.Architecture == NV_ARCH_10 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) default_par->riva.Architecture == NV_ARCH_20 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) default_par->riva.Architecture == NV_ARCH_30) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) sprintf(rivafb_fix.id, "NV%x", (pd->device & 0x0ff0) >> 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) sprintf(rivafb_fix.id, "NV%x", default_par->riva.Architecture);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) default_par->FlatPanel = flatpanel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) if (flatpanel == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) printk(KERN_INFO PFX "flatpanel support enabled\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) default_par->forceCRTC = forceCRTC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) rivafb_fix.mmio_len = pci_resource_len(pd, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) rivafb_fix.smem_len = pci_resource_len(pd, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) /* enable IO and mem if not already done */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) unsigned short cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) pci_read_config_word(pd, PCI_COMMAND, &cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) cmd |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) pci_write_config_word(pd, PCI_COMMAND, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) rivafb_fix.mmio_start = pci_resource_start(pd, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) rivafb_fix.smem_start = pci_resource_start(pd, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) default_par->ctrl_base = ioremap(rivafb_fix.mmio_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) rivafb_fix.mmio_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) if (!default_par->ctrl_base) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) printk(KERN_ERR PFX "cannot ioremap MMIO base\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) goto err_release_region;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) switch (default_par->riva.Architecture) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) case NV_ARCH_03:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) /* Riva128's PRAMIN is in the "framebuffer" space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) * Since these cards were never made with more than 8 megabytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) * we can safely allocate this separately.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) default_par->riva.PRAMIN = ioremap(rivafb_fix.smem_start + 0x00C00000, 0x00008000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) if (!default_par->riva.PRAMIN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) printk(KERN_ERR PFX "cannot ioremap PRAMIN region\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) goto err_iounmap_ctrl_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) case NV_ARCH_04:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) case NV_ARCH_10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) case NV_ARCH_20:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) case NV_ARCH_30:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) default_par->riva.PCRTC0 =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) (u32 __iomem *)(default_par->ctrl_base + 0x00600000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) default_par->riva.PRAMIN =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) (u32 __iomem *)(default_par->ctrl_base + 0x00710000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) riva_common_setup(default_par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) if (default_par->riva.Architecture == NV_ARCH_03) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) default_par->riva.PCRTC = default_par->riva.PCRTC0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) = default_par->riva.PGRAPH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) rivafb_fix.smem_len = riva_get_memlen(default_par) * 1024;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) default_par->dclk_max = riva_get_maxdclk(default_par) * 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) info->screen_base = ioremap_wc(rivafb_fix.smem_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) rivafb_fix.smem_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) if (!info->screen_base) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) printk(KERN_ERR PFX "cannot ioremap FB base\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) goto err_iounmap_pramin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) if (!nomtrr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) default_par->wc_cookie =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) arch_phys_wc_add(rivafb_fix.smem_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) rivafb_fix.smem_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) info->fbops = &riva_fb_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) info->fix = rivafb_fix;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) riva_get_EDID(info, pd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) riva_get_edidinfo(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) ret=riva_set_fbinfo(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) printk(KERN_ERR PFX "error setting initial video mode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) goto err_iounmap_screen_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) fb_destroy_modedb(info->monspecs.modedb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) info->monspecs.modedb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) pci_set_drvdata(pd, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) if (backlight)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) riva_bl_init(info->par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) ret = register_framebuffer(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) printk(KERN_ERR PFX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) "error registering riva framebuffer\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) goto err_iounmap_screen_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) printk(KERN_INFO PFX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) "PCI nVidia %s framebuffer ver %s (%dMB @ 0x%lX)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) info->fix.id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) RIVAFB_VERSION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) info->fix.smem_len / (1024 * 1024),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) info->fix.smem_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) NVTRACE_LEAVE();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) err_iounmap_screen_base:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) #ifdef CONFIG_FB_RIVA_I2C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) riva_delete_i2c_busses(info->par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) iounmap(info->screen_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) err_iounmap_pramin:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) if (default_par->riva.Architecture == NV_ARCH_03)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) iounmap(default_par->riva.PRAMIN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) err_iounmap_ctrl_base:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) iounmap(default_par->ctrl_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) err_release_region:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) pci_release_regions(pd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) err_disable_device:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) err_free_pixmap:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) kfree(info->pixmap.addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) err_framebuffer_release:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) framebuffer_release(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) err_ret:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) static void rivafb_remove(struct pci_dev *pd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) struct fb_info *info = pci_get_drvdata(pd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) struct riva_par *par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) NVTRACE_ENTER();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) #ifdef CONFIG_FB_RIVA_I2C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) riva_delete_i2c_busses(par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) kfree(par->EDID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) unregister_framebuffer(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) riva_bl_exit(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) arch_phys_wc_del(par->wc_cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) iounmap(par->ctrl_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) iounmap(info->screen_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) if (par->riva.Architecture == NV_ARCH_03)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) iounmap(par->riva.PRAMIN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) pci_release_regions(pd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) kfree(info->pixmap.addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) framebuffer_release(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) NVTRACE_LEAVE();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) /* ------------------------------------------------------------------------- *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) * initialization
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) * ------------------------------------------------------------------------- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) #ifndef MODULE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) static int rivafb_setup(char *options)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) char *this_opt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) NVTRACE_ENTER();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) if (!options || !*options)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) while ((this_opt = strsep(&options, ",")) != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) if (!strncmp(this_opt, "forceCRTC", 9)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) char *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) p = this_opt + 9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) if (!*p || !*(++p)) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) forceCRTC = *p - '0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) if (forceCRTC < 0 || forceCRTC > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) forceCRTC = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) } else if (!strncmp(this_opt, "flatpanel", 9)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) flatpanel = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) } else if (!strncmp(this_opt, "backlight:", 10)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) backlight = simple_strtoul(this_opt+10, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) } else if (!strncmp(this_opt, "nomtrr", 6)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) nomtrr = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) } else if (!strncmp(this_opt, "strictmode", 10)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) strictmode = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) } else if (!strncmp(this_opt, "noaccel", 7)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) noaccel = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) mode_option = this_opt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) NVTRACE_LEAVE();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) #endif /* !MODULE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) static struct pci_driver rivafb_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) .name = "rivafb",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) .id_table = rivafb_pci_tbl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) .probe = rivafb_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) .remove = rivafb_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153)
^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) * modularization
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) * ------------------------------------------------------------------------- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) static int rivafb_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) #ifndef MODULE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) char *option = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) if (fb_get_options("rivafb", &option))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) rivafb_setup(option);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) return pci_register_driver(&rivafb_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) module_init(rivafb_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) static void __exit rivafb_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) pci_unregister_driver(&rivafb_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) module_exit(rivafb_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) module_param(noaccel, bool, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) MODULE_PARM_DESC(noaccel, "bool: disable acceleration");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) module_param(flatpanel, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) MODULE_PARM_DESC(flatpanel, "Enables experimental flat panel support for some chipsets. (0 or 1=enabled) (default=0)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) module_param(forceCRTC, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) MODULE_PARM_DESC(forceCRTC, "Forces usage of a particular CRTC in case autodetection fails. (0 or 1) (default=autodetect)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) module_param(nomtrr, bool, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) MODULE_PARM_DESC(nomtrr, "Disables MTRR support (0 or 1=disabled) (default=0)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) module_param(strictmode, bool, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) MODULE_PARM_DESC(strictmode, "Only use video modes from EDID");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) MODULE_AUTHOR("Ani Joshi, maintainer");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) MODULE_DESCRIPTION("Framebuffer driver for nVidia Riva 128, TNT, TNT2, and the GeForce series");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) MODULE_LICENSE("GPL");