^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * linux/drivers/video/nvidia/nvidia.c - nVidia fb driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright 2004 Antonino Daplas <adaplas@pol.net>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * This file is subject to the terms and conditions of the GNU General Public
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * License. See the file COPYING in the main directory of this archive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/fb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/console.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/backlight.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #ifdef CONFIG_BOOTX_TEXT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <asm/btext.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include "nv_local.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include "nv_type.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include "nv_proto.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include "nv_dma.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #ifdef CONFIG_FB_NVIDIA_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define NVTRACE printk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define NVTRACE if (0) printk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define NVTRACE_ENTER(...) NVTRACE("%s START\n", __func__)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define NVTRACE_LEAVE(...) NVTRACE("%s END\n", __func__)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #ifdef CONFIG_FB_NVIDIA_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define assert(expr) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) if (!(expr)) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) printk( "Assertion failed! %s,%s,%s,line=%d\n",\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #expr,__FILE__,__func__,__LINE__); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) BUG(); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define assert(expr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define PFX "nvidiafb: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) /* HW cursor parameters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define MAX_CURS 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) static const struct pci_device_id nvidiafb_pci_tbl[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) {PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) PCI_BASE_CLASS_DISPLAY << 16, 0xff0000, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) { 0, }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) MODULE_DEVICE_TABLE(pci, nvidiafb_pci_tbl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) /* command line data, set in nvidiafb_setup() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) static int flatpanel = -1; /* Autodetect later */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) static int fpdither = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) static int forceCRTC = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) static int hwcur = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) static int noaccel = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) static int noscale = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) static int paneltweak = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) static int vram = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) static int bpp = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) static int reverse_i2c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) static bool nomtrr = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) static int backlight = IS_BUILTIN(CONFIG_PMAC_BACKLIGHT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) static char *mode_option = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) static struct fb_fix_screeninfo nvidiafb_fix = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) .type = FB_TYPE_PACKED_PIXELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) .xpanstep = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) .ypanstep = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) static struct fb_var_screeninfo nvidiafb_default_var = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) .xres = 640,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) .yres = 480,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) .xres_virtual = 640,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) .yres_virtual = 480,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) .bits_per_pixel = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) .red = {0, 8, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) .green = {0, 8, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) .blue = {0, 8, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) .transp = {0, 0, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) .activate = FB_ACTIVATE_NOW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) .height = -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) .width = -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) .pixclock = 39721,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) .left_margin = 40,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) .right_margin = 24,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) .upper_margin = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) .lower_margin = 11,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) .hsync_len = 96,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) .vsync_len = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) .vmode = FB_VMODE_NONINTERLACED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) static void nvidiafb_load_cursor_image(struct nvidia_par *par, u8 * data8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) u16 bg, u16 fg, u32 w, u32 h)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) u32 *data = (u32 *) data8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) int i, j, k = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) u32 b, tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) w = (w + 1) & ~1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) for (i = 0; i < h; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) b = *data++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) reverse_order(&b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) for (j = 0; j < w / 2; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) tmp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) #if defined (__BIG_ENDIAN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) tmp = (b & (1 << 31)) ? fg << 16 : bg << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) b <<= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) tmp |= (b & (1 << 31)) ? fg : bg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) b <<= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) tmp = (b & 1) ? fg : bg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) b >>= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) tmp |= (b & 1) ? fg << 16 : bg << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) b >>= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) NV_WR32(&par->CURSOR[k++], 0, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) k += (MAX_CURS - w) / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) static void nvidia_write_clut(struct nvidia_par *par,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) u8 regnum, u8 red, u8 green, u8 blue)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) NVWriteDacMask(par, 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) NVWriteDacWriteAddr(par, regnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) NVWriteDacData(par, red);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) NVWriteDacData(par, green);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) NVWriteDacData(par, blue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) static void nvidia_read_clut(struct nvidia_par *par,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) u8 regnum, u8 * red, u8 * green, u8 * blue)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) NVWriteDacMask(par, 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) NVWriteDacReadAddr(par, regnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) *red = NVReadDacData(par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) *green = NVReadDacData(par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) *blue = NVReadDacData(par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) static int nvidia_panel_tweak(struct nvidia_par *par,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) struct _riva_hw_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) int tweak = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) if (par->paneltweak) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) tweak = par->paneltweak;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) /* Begin flat panel hacks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) * This is unfortunate, but some chips need this register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) * tweaked or else you get artifacts where adjacent pixels are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) * swapped. There are no hard rules for what to set here so all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) * we can do is experiment and apply hacks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) if (((par->Chipset & 0xffff) == 0x0328) && (state->bpp == 32)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) /* At least one NV34 laptop needs this workaround. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) tweak = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) if ((par->Chipset & 0xfff0) == 0x0310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) tweak = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) /* end flat panel hacks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) return tweak;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) static void nvidia_screen_off(struct nvidia_par *par, int on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) unsigned char tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) if (on) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) * Turn off screen and disable sequencer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) tmp = NVReadSeq(par, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) NVWriteSeq(par, 0x00, 0x01); /* Synchronous Reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) NVWriteSeq(par, 0x01, tmp | 0x20); /* disable the display */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) * Reenable sequencer, then turn on screen.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) tmp = NVReadSeq(par, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) NVWriteSeq(par, 0x01, tmp & ~0x20); /* reenable display */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) NVWriteSeq(par, 0x00, 0x03); /* End Reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) static void nvidia_save_vga(struct nvidia_par *par,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) struct _riva_hw_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) NVTRACE_ENTER();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) NVLockUnlock(par, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) NVUnloadStateExt(par, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) state->misc_output = NVReadMiscOut(par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) for (i = 0; i < NUM_CRT_REGS; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) state->crtc[i] = NVReadCrtc(par, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) for (i = 0; i < NUM_ATC_REGS; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) state->attr[i] = NVReadAttr(par, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) for (i = 0; i < NUM_GRC_REGS; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) state->gra[i] = NVReadGr(par, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) for (i = 0; i < NUM_SEQ_REGS; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) state->seq[i] = NVReadSeq(par, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) NVTRACE_LEAVE();
^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) #undef DUMP_REG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) static void nvidia_write_regs(struct nvidia_par *par,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) struct _riva_hw_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) NVTRACE_ENTER();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) NVLoadStateExt(par, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) NVWriteMiscOut(par, state->misc_output);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) for (i = 1; i < NUM_SEQ_REGS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) #ifdef DUMP_REG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) printk(" SEQ[%02x] = %08x\n", i, state->seq[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) NVWriteSeq(par, i, state->seq[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) /* Ensure CRTC registers 0-7 are unlocked by clearing bit 7 of CRTC[17] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) NVWriteCrtc(par, 0x11, state->crtc[0x11] & ~0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) for (i = 0; i < NUM_CRT_REGS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) switch (i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) case 0x19:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) case 0x20 ... 0x40:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) #ifdef DUMP_REG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) printk("CRTC[%02x] = %08x\n", i, state->crtc[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) NVWriteCrtc(par, i, state->crtc[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) for (i = 0; i < NUM_GRC_REGS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) #ifdef DUMP_REG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) printk(" GRA[%02x] = %08x\n", i, state->gra[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) NVWriteGr(par, i, state->gra[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) for (i = 0; i < NUM_ATC_REGS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) #ifdef DUMP_REG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) printk("ATTR[%02x] = %08x\n", i, state->attr[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) NVWriteAttr(par, i, state->attr[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) NVTRACE_LEAVE();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) static int nvidia_calc_regs(struct fb_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) struct nvidia_par *par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) struct _riva_hw_state *state = &par->ModeReg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) int i, depth = fb_get_color_depth(&info->var, &info->fix);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) int h_display = info->var.xres / 8 - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) int h_start = (info->var.xres + info->var.right_margin) / 8 - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) int h_end = (info->var.xres + info->var.right_margin +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) info->var.hsync_len) / 8 - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) int h_total = (info->var.xres + info->var.right_margin +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) info->var.hsync_len + info->var.left_margin) / 8 - 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) int h_blank_s = h_display;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) int h_blank_e = h_total + 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) int v_display = info->var.yres - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) int v_start = info->var.yres + info->var.lower_margin - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) int v_end = (info->var.yres + info->var.lower_margin +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) info->var.vsync_len) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) int v_total = (info->var.yres + info->var.lower_margin +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) info->var.vsync_len + info->var.upper_margin) - 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) int v_blank_s = v_display;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) int v_blank_e = v_total + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) * Set all CRTC values.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) if (info->var.vmode & FB_VMODE_INTERLACED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) v_total |= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) if (par->FlatPanel == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) v_start = v_total - 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) v_end = v_total - 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) v_blank_s = v_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) h_start = h_total - 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) h_end = h_total - 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) h_blank_e = h_total + 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) state->crtc[0x0] = Set8Bits(h_total);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) state->crtc[0x1] = Set8Bits(h_display);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) state->crtc[0x2] = Set8Bits(h_blank_s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) state->crtc[0x3] = SetBitField(h_blank_e, 4: 0, 4:0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) | SetBit(7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) state->crtc[0x4] = Set8Bits(h_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) state->crtc[0x5] = SetBitField(h_blank_e, 5: 5, 7:7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) | SetBitField(h_end, 4: 0, 4:0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) state->crtc[0x6] = SetBitField(v_total, 7: 0, 7:0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) state->crtc[0x7] = SetBitField(v_total, 8: 8, 0:0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) | SetBitField(v_display, 8: 8, 1:1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) | SetBitField(v_start, 8: 8, 2:2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) | SetBitField(v_blank_s, 8: 8, 3:3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) | SetBit(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) | SetBitField(v_total, 9: 9, 5:5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) | SetBitField(v_display, 9: 9, 6:6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) | SetBitField(v_start, 9: 9, 7:7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) state->crtc[0x9] = SetBitField(v_blank_s, 9: 9, 5:5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) | SetBit(6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) | ((info->var.vmode & FB_VMODE_DOUBLE) ? 0x80 : 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) state->crtc[0x10] = Set8Bits(v_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) state->crtc[0x11] = SetBitField(v_end, 3: 0, 3:0) | SetBit(5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) state->crtc[0x12] = Set8Bits(v_display);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) state->crtc[0x13] = ((info->var.xres_virtual / 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) (info->var.bits_per_pixel / 8));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) state->crtc[0x15] = Set8Bits(v_blank_s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) state->crtc[0x16] = Set8Bits(v_blank_e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) state->attr[0x10] = 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) if (par->Television)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) state->attr[0x11] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) state->screen = SetBitField(h_blank_e, 6: 6, 4:4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) | SetBitField(v_blank_s, 10: 10, 3:3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) | SetBitField(v_start, 10: 10, 2:2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) | SetBitField(v_display, 10: 10, 1:1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) | SetBitField(v_total, 10: 10, 0:0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) state->horiz = SetBitField(h_total, 8: 8, 0:0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) | SetBitField(h_display, 8: 8, 1:1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) | SetBitField(h_blank_s, 8: 8, 2:2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) | SetBitField(h_start, 8: 8, 3:3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) state->extra = SetBitField(v_total, 11: 11, 0:0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) | SetBitField(v_display, 11: 11, 2:2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) | SetBitField(v_start, 11: 11, 4:4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) | SetBitField(v_blank_s, 11: 11, 6:6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) if (info->var.vmode & FB_VMODE_INTERLACED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) h_total = (h_total >> 1) & ~1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) state->interlace = Set8Bits(h_total);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) state->horiz |= SetBitField(h_total, 8: 8, 4:4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) state->interlace = 0xff; /* interlace off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) * Calculate the extended registers.
^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) if (depth < 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) i = depth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) i = 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) if (par->Architecture >= NV_ARCH_10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) par->CURSOR = (volatile u32 __iomem *)(info->screen_base +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) par->CursorStart);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) if (info->var.sync & FB_SYNC_HOR_HIGH_ACT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) state->misc_output &= ~0x40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) state->misc_output |= 0x40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) if (info->var.sync & FB_SYNC_VERT_HIGH_ACT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) state->misc_output &= ~0x80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) state->misc_output |= 0x80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) NVCalcStateExt(par, state, i, info->var.xres_virtual,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) info->var.xres, info->var.yres_virtual,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 1000000000 / info->var.pixclock, info->var.vmode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) state->scale = NV_RD32(par->PRAMDAC, 0x00000848) & 0xfff000ff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) if (par->FlatPanel == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) state->pixel |= (1 << 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) if (!par->fpScaler || (par->fpWidth <= info->var.xres)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) || (par->fpHeight <= info->var.yres)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) state->scale |= (1 << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) if (!par->crtcSync_read) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) state->crtcSync = NV_RD32(par->PRAMDAC, 0x0828);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) par->crtcSync_read = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) par->PanelTweak = nvidia_panel_tweak(par, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) state->vpll = state->pll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) state->vpll2 = state->pll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) state->vpllB = state->pllB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) state->vpll2B = state->pllB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) VGA_WR08(par->PCIO, 0x03D4, 0x1C);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) state->fifo = VGA_RD08(par->PCIO, 0x03D5) & ~(1<<5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) if (par->CRTCnumber) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) state->head = NV_RD32(par->PCRTC0, 0x00000860) & ~0x00001000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) state->head2 = NV_RD32(par->PCRTC0, 0x00002860) | 0x00001000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) state->crtcOwner = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) state->pllsel |= 0x20000800;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) state->vpll = NV_RD32(par->PRAMDAC0, 0x00000508);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) if (par->twoStagePLL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) state->vpllB = NV_RD32(par->PRAMDAC0, 0x00000578);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) } else if (par->twoHeads) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) state->head = NV_RD32(par->PCRTC0, 0x00000860) | 0x00001000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) state->head2 = NV_RD32(par->PCRTC0, 0x00002860) & ~0x00001000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) state->crtcOwner = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) state->vpll2 = NV_RD32(par->PRAMDAC0, 0x0520);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) if (par->twoStagePLL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) state->vpll2B = NV_RD32(par->PRAMDAC0, 0x057C);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) state->cursorConfig = 0x00000100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) if (info->var.vmode & FB_VMODE_DOUBLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) state->cursorConfig |= (1 << 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) if (par->alphaCursor) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) if ((par->Chipset & 0x0ff0) != 0x0110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) state->cursorConfig |= 0x04011000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) state->cursorConfig |= 0x14011000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) state->general |= (1 << 29);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) state->cursorConfig |= 0x02000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) if (par->twoHeads) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) if ((par->Chipset & 0x0ff0) == 0x0110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) state->dither = NV_RD32(par->PRAMDAC, 0x0528) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) ~0x00010000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) if (par->FPDither)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) state->dither |= 0x00010000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) state->dither = NV_RD32(par->PRAMDAC, 0x083C) & ~1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) if (par->FPDither)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) state->dither |= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) state->timingH = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) state->timingV = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) state->displayV = info->var.xres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) static void nvidia_init_vga(struct fb_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) struct nvidia_par *par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) struct _riva_hw_state *state = &par->ModeReg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) for (i = 0; i < 0x10; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) state->attr[i] = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) state->attr[0x10] = 0x41;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) state->attr[0x11] = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) state->attr[0x12] = 0x0f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) state->attr[0x13] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) state->attr[0x14] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) memset(state->crtc, 0x00, NUM_CRT_REGS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) state->crtc[0x0a] = 0x20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) state->crtc[0x17] = 0xe3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) state->crtc[0x18] = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) state->crtc[0x28] = 0x40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) memset(state->gra, 0x00, NUM_GRC_REGS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) state->gra[0x05] = 0x40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) state->gra[0x06] = 0x05;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) state->gra[0x07] = 0x0f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) state->gra[0x08] = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) state->seq[0x00] = 0x03;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) state->seq[0x01] = 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) state->seq[0x02] = 0x0f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) state->seq[0x03] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) state->seq[0x04] = 0x0e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) state->misc_output = 0xeb;
^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) static int nvidiafb_cursor(struct fb_info *info, struct fb_cursor *cursor)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) struct nvidia_par *par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) u8 data[MAX_CURS * MAX_CURS / 8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) int i, set = cursor->set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) u16 fg, bg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) if (cursor->image.width > MAX_CURS || cursor->image.height > MAX_CURS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) NVShowHideCursor(par, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) if (par->cursor_reset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) set = FB_CUR_SETALL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) par->cursor_reset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) if (set & FB_CUR_SETSIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) memset_io(par->CURSOR, 0, MAX_CURS * MAX_CURS * 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) if (set & FB_CUR_SETPOS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) u32 xx, yy, temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) yy = cursor->image.dy - info->var.yoffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) xx = cursor->image.dx - info->var.xoffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) temp = xx & 0xFFFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) temp |= yy << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) NV_WR32(par->PRAMDAC, 0x0000300, temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) if (set & (FB_CUR_SETSHAPE | FB_CUR_SETCMAP | FB_CUR_SETIMAGE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) u32 bg_idx = cursor->image.bg_color;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) u32 fg_idx = cursor->image.fg_color;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) u32 s_pitch = (cursor->image.width + 7) >> 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) u32 d_pitch = MAX_CURS / 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) u8 *dat = (u8 *) cursor->image.data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) u8 *msk = (u8 *) cursor->mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) u8 *src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) src = kmalloc_array(s_pitch, cursor->image.height, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) if (src) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) switch (cursor->rop) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) case ROP_XOR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) for (i = 0; i < s_pitch * cursor->image.height; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) src[i] = dat[i] ^ msk[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) case ROP_COPY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) for (i = 0; i < s_pitch * cursor->image.height; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) src[i] = dat[i] & msk[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) fb_pad_aligned_buffer(data, d_pitch, src, s_pitch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) cursor->image.height);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) bg = ((info->cmap.red[bg_idx] & 0xf8) << 7) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) ((info->cmap.green[bg_idx] & 0xf8) << 2) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) ((info->cmap.blue[bg_idx] & 0xf8) >> 3) | 1 << 15;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) fg = ((info->cmap.red[fg_idx] & 0xf8) << 7) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) ((info->cmap.green[fg_idx] & 0xf8) << 2) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) ((info->cmap.blue[fg_idx] & 0xf8) >> 3) | 1 << 15;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) NVLockUnlock(par, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) nvidiafb_load_cursor_image(par, data, bg, fg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) cursor->image.width,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) cursor->image.height);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) kfree(src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) if (cursor->enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) NVShowHideCursor(par, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) static struct fb_ops nvidia_fb_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) static int nvidiafb_set_par(struct fb_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) struct nvidia_par *par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) NVTRACE_ENTER();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) NVLockUnlock(par, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) if (!par->FlatPanel || !par->twoHeads)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) par->FPDither = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) if (par->FPDither < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) if ((par->Chipset & 0x0ff0) == 0x0110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) par->FPDither = !!(NV_RD32(par->PRAMDAC, 0x0528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) & 0x00010000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) par->FPDither = !!(NV_RD32(par->PRAMDAC, 0x083C) & 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) printk(KERN_INFO PFX "Flat panel dithering %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) par->FPDither ? "enabled" : "disabled");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) info->fix.visual = (info->var.bits_per_pixel == 8) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) nvidia_init_vga(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) nvidia_calc_regs(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) NVLockUnlock(par, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) if (par->twoHeads) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) VGA_WR08(par->PCIO, 0x03D4, 0x44);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) VGA_WR08(par->PCIO, 0x03D5, par->ModeReg.crtcOwner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) NVLockUnlock(par, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) nvidia_screen_off(par, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) nvidia_write_regs(par, &par->ModeReg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) NVSetStartAddress(par, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) #if defined (__BIG_ENDIAN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) /* turn on LFB swapping */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) unsigned char tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) VGA_WR08(par->PCIO, 0x3d4, 0x46);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) tmp = VGA_RD08(par->PCIO, 0x3d5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) tmp |= (1 << 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) VGA_WR08(par->PCIO, 0x3d5, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) info->fix.line_length = (info->var.xres_virtual *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) info->var.bits_per_pixel) >> 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) if (info->var.accel_flags) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) nvidia_fb_ops.fb_imageblit = nvidiafb_imageblit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) nvidia_fb_ops.fb_fillrect = nvidiafb_fillrect;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) nvidia_fb_ops.fb_copyarea = nvidiafb_copyarea;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) nvidia_fb_ops.fb_sync = nvidiafb_sync;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) info->pixmap.scan_align = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) info->flags &= ~FBINFO_HWACCEL_DISABLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) info->flags |= FBINFO_READS_FAST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) NVResetGraphics(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) nvidia_fb_ops.fb_imageblit = cfb_imageblit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) nvidia_fb_ops.fb_fillrect = cfb_fillrect;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) nvidia_fb_ops.fb_copyarea = cfb_copyarea;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) nvidia_fb_ops.fb_sync = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) info->pixmap.scan_align = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) info->flags |= FBINFO_HWACCEL_DISABLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) info->flags &= ~FBINFO_READS_FAST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) par->cursor_reset = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) nvidia_screen_off(par, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) #ifdef CONFIG_BOOTX_TEXT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) /* Update debug text engine */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) btext_update_display(info->fix.smem_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) info->var.xres, info->var.yres,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) info->var.bits_per_pixel, info->fix.line_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) NVLockUnlock(par, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) NVTRACE_LEAVE();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) static int nvidiafb_setcolreg(unsigned regno, unsigned red, unsigned green,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) unsigned blue, unsigned transp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) struct fb_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) struct nvidia_par *par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) NVTRACE_ENTER();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) if (regno >= (1 << info->var.green.length))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) if (info->var.grayscale) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) /* gray = 0.30*R + 0.59*G + 0.11*B */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) if (regno < 16 && info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) ((u32 *) info->pseudo_palette)[regno] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) (regno << info->var.red.offset) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) (regno << info->var.green.offset) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) (regno << info->var.blue.offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) switch (info->var.bits_per_pixel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) case 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) /* "transparent" stuff is completely ignored. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) nvidia_write_clut(par, regno, red >> 8, green >> 8, blue >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) case 16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) if (info->var.green.length == 5) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) for (i = 0; i < 8; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) nvidia_write_clut(par, regno * 8 + i, red >> 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) green >> 8, blue >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) u8 r, g, b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) if (regno < 32) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) for (i = 0; i < 8; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) nvidia_write_clut(par, regno * 8 + i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) red >> 8, green >> 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) blue >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) nvidia_read_clut(par, regno * 4, &r, &g, &b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) for (i = 0; i < 4; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) nvidia_write_clut(par, regno * 4 + i, r,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) green >> 8, b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) case 32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) nvidia_write_clut(par, regno, red >> 8, green >> 8, blue >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) /* do nothing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) NVTRACE_LEAVE();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) static int nvidiafb_check_var(struct fb_var_screeninfo *var,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) struct fb_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) struct nvidia_par *par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) int memlen, vramlen, mode_valid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) int pitch, err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) NVTRACE_ENTER();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) var->transp.offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) var->transp.length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) var->xres &= ~7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) if (var->bits_per_pixel <= 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) var->bits_per_pixel = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) else if (var->bits_per_pixel <= 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) var->bits_per_pixel = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) var->bits_per_pixel = 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) switch (var->bits_per_pixel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) case 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) var->red.offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) var->red.length = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) var->green.offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) var->green.length = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) var->blue.offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) var->blue.length = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) var->transp.offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) var->transp.length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) case 16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) var->green.length = (var->green.length < 6) ? 5 : 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) var->red.length = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) var->blue.length = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) var->transp.length = 6 - var->green.length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) var->blue.offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) var->green.offset = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) var->red.offset = 5 + var->green.length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) var->transp.offset = (5 + var->red.offset) & 15;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) case 32: /* RGBA 8888 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) var->red.offset = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) var->red.length = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) var->green.offset = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) var->green.length = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) var->blue.offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) var->blue.length = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) var->transp.length = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) var->transp.offset = 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) var->red.msb_right = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) var->green.msb_right = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) var->blue.msb_right = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) var->transp.msb_right = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) if (!info->monspecs.hfmax || !info->monspecs.vfmax ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) !info->monspecs.dclkmax || !fb_validate_mode(var, info))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) mode_valid = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) /* calculate modeline if supported by monitor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) if (!mode_valid && info->monspecs.gtf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) if (!fb_get_mode(FB_MAXTIMINGS, 0, var, info))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) mode_valid = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) if (!mode_valid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) const struct fb_videomode *mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) mode = fb_find_best_mode(var, &info->modelist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) if (mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) fb_videomode_to_var(var, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) mode_valid = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) if (!mode_valid && info->monspecs.modedb_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) * If we're on a flat panel, check if the mode is outside of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) * panel dimensions. If so, cap it and try for the next best mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) * before bailing out.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) if (par->fpWidth && par->fpHeight && (par->fpWidth < var->xres ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) par->fpHeight < var->yres)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) const struct fb_videomode *mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) var->xres = par->fpWidth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) var->yres = par->fpHeight;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) mode = fb_find_best_mode(var, &info->modelist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) if (!mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) printk(KERN_ERR PFX "mode out of range of flat "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) "panel dimensions\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) fb_videomode_to_var(var, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) if (var->yres_virtual < var->yres)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) var->yres_virtual = var->yres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) if (var->xres_virtual < var->xres)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) var->xres_virtual = var->xres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) var->xres_virtual = (var->xres_virtual + 63) & ~63;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) vramlen = info->screen_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) pitch = ((var->xres_virtual * var->bits_per_pixel) + 7) / 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) memlen = pitch * var->yres_virtual;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) if (memlen > vramlen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) var->yres_virtual = vramlen / pitch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) if (var->yres_virtual < var->yres) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) var->yres_virtual = var->yres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) var->xres_virtual = vramlen / var->yres_virtual;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) var->xres_virtual /= var->bits_per_pixel / 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) var->xres_virtual &= ~63;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) pitch = (var->xres_virtual *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) var->bits_per_pixel + 7) / 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) memlen = pitch * var->yres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) if (var->xres_virtual < var->xres) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) printk("nvidiafb: required video memory, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) "%d bytes, for %dx%d-%d (virtual) "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) "is out of range\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) memlen, var->xres_virtual,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) var->yres_virtual, var->bits_per_pixel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) if (var->accel_flags) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) if (var->yres_virtual > 0x7fff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) var->yres_virtual = 0x7fff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) if (var->xres_virtual > 0x7fff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) var->xres_virtual = 0x7fff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) var->xres_virtual &= ~63;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) NVTRACE_LEAVE();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) static int nvidiafb_pan_display(struct fb_var_screeninfo *var,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) struct fb_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) struct nvidia_par *par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) u32 total;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) total = var->yoffset * info->fix.line_length + var->xoffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) NVSetStartAddress(par, total);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) static int nvidiafb_blank(int blank, struct fb_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) struct nvidia_par *par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) unsigned char tmp, vesa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) tmp = NVReadSeq(par, 0x01) & ~0x20; /* screen on/off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) vesa = NVReadCrtc(par, 0x1a) & ~0xc0; /* sync on/off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) NVTRACE_ENTER();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) if (blank)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) tmp |= 0x20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) switch (blank) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) case FB_BLANK_UNBLANK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) case FB_BLANK_NORMAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) case FB_BLANK_VSYNC_SUSPEND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) vesa |= 0x80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) case FB_BLANK_HSYNC_SUSPEND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) vesa |= 0x40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) case FB_BLANK_POWERDOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) vesa |= 0xc0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) NVWriteSeq(par, 0x01, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) NVWriteCrtc(par, 0x1a, vesa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) NVTRACE_LEAVE();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) * Because the VGA registers are not mapped linearly in its MMIO space,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) * restrict VGA register saving and restore to x86 only, where legacy VGA IO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) * access is legal. Consequently, we must also check if the device is the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) * primary display.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) #ifdef CONFIG_X86
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) static void save_vga_x86(struct nvidia_par *par)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) struct resource *res= &par->pci_dev->resource[PCI_ROM_RESOURCE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) if (res && res->flags & IORESOURCE_ROM_SHADOW) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) memset(&par->vgastate, 0, sizeof(par->vgastate));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) par->vgastate.flags = VGA_SAVE_MODE | VGA_SAVE_FONTS |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) VGA_SAVE_CMAP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) save_vga(&par->vgastate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) static void restore_vga_x86(struct nvidia_par *par)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) struct resource *res= &par->pci_dev->resource[PCI_ROM_RESOURCE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) if (res && res->flags & IORESOURCE_ROM_SHADOW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) restore_vga(&par->vgastate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) #define save_vga_x86(x) do {} while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) #define restore_vga_x86(x) do {} while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) #endif /* X86 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) static int nvidiafb_open(struct fb_info *info, int user)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) struct nvidia_par *par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) if (!par->open_count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) save_vga_x86(par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) nvidia_save_vga(par, &par->initial_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) par->open_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) static int nvidiafb_release(struct fb_info *info, int user)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) struct nvidia_par *par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) if (!par->open_count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) if (par->open_count == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) nvidia_write_regs(par, &par->initial_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) restore_vga_x86(par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) par->open_count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) static struct fb_ops nvidia_fb_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) .fb_open = nvidiafb_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) .fb_release = nvidiafb_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) .fb_check_var = nvidiafb_check_var,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) .fb_set_par = nvidiafb_set_par,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) .fb_setcolreg = nvidiafb_setcolreg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) .fb_pan_display = nvidiafb_pan_display,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) .fb_blank = nvidiafb_blank,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) .fb_fillrect = nvidiafb_fillrect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) .fb_copyarea = nvidiafb_copyarea,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) .fb_imageblit = nvidiafb_imageblit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) .fb_cursor = nvidiafb_cursor,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) .fb_sync = nvidiafb_sync,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) static int nvidiafb_suspend_late(struct device *dev, pm_message_t mesg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) struct fb_info *info = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) struct nvidia_par *par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) if (mesg.event == PM_EVENT_PRETHAW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) mesg.event = PM_EVENT_FREEZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) console_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) par->pm_state = mesg.event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) if (mesg.event & PM_EVENT_SLEEP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) fb_set_suspend(info, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) nvidiafb_blank(FB_BLANK_POWERDOWN, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) nvidia_write_regs(par, &par->SavedReg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) dev->power.power_state = mesg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) console_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) static int __maybe_unused nvidiafb_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) return nvidiafb_suspend_late(dev, PMSG_SUSPEND);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) static int __maybe_unused nvidiafb_hibernate(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) return nvidiafb_suspend_late(dev, PMSG_HIBERNATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) static int __maybe_unused nvidiafb_freeze(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) return nvidiafb_suspend_late(dev, PMSG_FREEZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) static int __maybe_unused nvidiafb_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) struct fb_info *info = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) struct nvidia_par *par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) console_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) par->pm_state = PM_EVENT_ON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) nvidiafb_set_par(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) fb_set_suspend (info, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) nvidiafb_blank(FB_BLANK_UNBLANK, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) console_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) static const struct dev_pm_ops nvidiafb_pm_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) .suspend = nvidiafb_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) .resume = nvidiafb_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) .freeze = nvidiafb_freeze,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) .thaw = nvidiafb_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) .poweroff = nvidiafb_hibernate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) .restore = nvidiafb_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) #endif /* CONFIG_PM_SLEEP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) static int nvidia_set_fbinfo(struct fb_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) struct fb_monspecs *specs = &info->monspecs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) struct fb_videomode modedb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) struct nvidia_par *par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) int lpitch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) NVTRACE_ENTER();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) info->flags = FBINFO_DEFAULT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) | FBINFO_HWACCEL_IMAGEBLIT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) | FBINFO_HWACCEL_FILLRECT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) | FBINFO_HWACCEL_COPYAREA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) | FBINFO_HWACCEL_YPAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) fb_videomode_to_modelist(info->monspecs.modedb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) info->monspecs.modedb_len, &info->modelist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) fb_var_to_videomode(&modedb, &nvidiafb_default_var);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) switch (bpp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) case 0 ... 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) bpp = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) case 9 ... 16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) bpp = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) bpp = 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) if (specs->modedb != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) const struct fb_videomode *mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) mode = fb_find_best_display(specs, &info->modelist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) fb_videomode_to_var(&nvidiafb_default_var, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) nvidiafb_default_var.bits_per_pixel = bpp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) } else if (par->fpWidth && par->fpHeight) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) char buf[16];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) memset(buf, 0, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) snprintf(buf, 15, "%dx%dMR", par->fpWidth, par->fpHeight);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) fb_find_mode(&nvidiafb_default_var, info, buf, specs->modedb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) specs->modedb_len, &modedb, bpp);
^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) if (mode_option)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) fb_find_mode(&nvidiafb_default_var, info, mode_option,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) specs->modedb, specs->modedb_len, &modedb, bpp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) info->var = nvidiafb_default_var;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) info->fix.visual = (info->var.bits_per_pixel == 8) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) info->pseudo_palette = par->pseudo_palette;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) fb_alloc_cmap(&info->cmap, 256, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) fb_destroy_modedb(info->monspecs.modedb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) info->monspecs.modedb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) /* maximize virtual vertical length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) lpitch = info->var.xres_virtual *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) ((info->var.bits_per_pixel + 7) >> 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) info->var.yres_virtual = info->screen_size / lpitch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) info->pixmap.scan_align = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) info->pixmap.buf_align = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) info->pixmap.access_align = 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) info->pixmap.size = 8 * 1024;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) info->pixmap.flags = FB_PIXMAP_SYSTEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) if (!hwcur)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) nvidia_fb_ops.fb_cursor = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) info->var.accel_flags = (!noaccel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) switch (par->Architecture) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) case NV_ARCH_04:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) info->fix.accel = FB_ACCEL_NV4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) case NV_ARCH_10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) info->fix.accel = FB_ACCEL_NV_10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) case NV_ARCH_20:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) info->fix.accel = FB_ACCEL_NV_20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) case NV_ARCH_30:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) info->fix.accel = FB_ACCEL_NV_30;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) case NV_ARCH_40:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) info->fix.accel = FB_ACCEL_NV_40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) NVTRACE_LEAVE();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) return nvidiafb_check_var(&info->var, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) static u32 nvidia_get_chipset(struct fb_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) struct nvidia_par *par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) u32 id = (par->pci_dev->vendor << 16) | par->pci_dev->device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) printk(KERN_INFO PFX "Device ID: %x \n", id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) if ((id & 0xfff0) == 0x00f0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) (id & 0xfff0) == 0x02e0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) /* pci-e */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) id = NV_RD32(par->REGS, 0x1800);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) if ((id & 0x0000ffff) == 0x000010DE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) id = 0x10DE0000 | (id >> 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) else if ((id & 0xffff0000) == 0xDE100000) /* wrong endian */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) id = 0x10DE0000 | ((id << 8) & 0x0000ff00) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) ((id >> 8) & 0x000000ff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) printk(KERN_INFO PFX "Subsystem ID: %x \n", id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) return id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) static u32 nvidia_get_arch(struct fb_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) struct nvidia_par *par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) u32 arch = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) switch (par->Chipset & 0x0ff0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) case 0x0100: /* GeForce 256 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) case 0x0110: /* GeForce2 MX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) case 0x0150: /* GeForce2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) case 0x0170: /* GeForce4 MX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) case 0x0180: /* GeForce4 MX (8x AGP) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) case 0x01A0: /* nForce */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) case 0x01F0: /* nForce2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) arch = NV_ARCH_10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) case 0x0200: /* GeForce3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) case 0x0250: /* GeForce4 Ti */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) case 0x0280: /* GeForce4 Ti (8x AGP) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) arch = NV_ARCH_20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) case 0x0300: /* GeForceFX 5800 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) case 0x0310: /* GeForceFX 5600 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) case 0x0320: /* GeForceFX 5200 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) case 0x0330: /* GeForceFX 5900 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) case 0x0340: /* GeForceFX 5700 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) arch = NV_ARCH_30;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) case 0x0040: /* GeForce 6800 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) case 0x00C0: /* GeForce 6800 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) case 0x0120: /* GeForce 6800 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) case 0x0140: /* GeForce 6600 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) case 0x0160: /* GeForce 6200 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) case 0x01D0: /* GeForce 7200, 7300, 7400 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) case 0x0090: /* GeForce 7800 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) case 0x0210: /* GeForce 6800 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) case 0x0220: /* GeForce 6200 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) case 0x0240: /* GeForce 6100 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) case 0x0290: /* GeForce 7900 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) case 0x0390: /* GeForce 7600 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) case 0x03D0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) arch = NV_ARCH_40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) case 0x0020: /* TNT, TNT2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) arch = NV_ARCH_04;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) default: /* unknown architecture */
^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) return arch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) static int nvidiafb_probe(struct pci_dev *pd, const struct pci_device_id *ent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) struct nvidia_par *par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) struct fb_info *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) unsigned short cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) NVTRACE_ENTER();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) assert(pd != NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) info = framebuffer_alloc(sizeof(struct nvidia_par), &pd->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) if (!info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) par->pci_dev = pd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) info->pixmap.addr = kzalloc(8 * 1024, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) if (info->pixmap.addr == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) goto err_out_kfree;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) if (pci_enable_device(pd)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) printk(KERN_ERR PFX "cannot enable PCI device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) goto err_out_enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) if (pci_request_regions(pd, "nvidiafb")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) printk(KERN_ERR PFX "cannot request PCI regions\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) goto err_out_enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) par->FlatPanel = flatpanel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) if (flatpanel == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) printk(KERN_INFO PFX "flatpanel support enabled\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) par->FPDither = fpdither;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) par->CRTCnumber = forceCRTC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) par->FpScale = (!noscale);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) par->paneltweak = paneltweak;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) par->reverse_i2c = reverse_i2c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) /* enable IO and mem if not already done */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) pci_read_config_word(pd, PCI_COMMAND, &cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) cmd |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) pci_write_config_word(pd, PCI_COMMAND, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) nvidiafb_fix.mmio_start = pci_resource_start(pd, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) nvidiafb_fix.smem_start = pci_resource_start(pd, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) nvidiafb_fix.mmio_len = pci_resource_len(pd, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) par->REGS = ioremap(nvidiafb_fix.mmio_start, nvidiafb_fix.mmio_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) if (!par->REGS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) printk(KERN_ERR PFX "cannot ioremap MMIO base\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) goto err_out_free_base0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) par->Chipset = nvidia_get_chipset(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) par->Architecture = nvidia_get_arch(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) if (par->Architecture == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) printk(KERN_ERR PFX "unknown NV_ARCH\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) goto err_out_arch;
^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) sprintf(nvidiafb_fix.id, "NV%x", (pd->device & 0x0ff0) >> 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) if (NVCommonSetup(info))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) goto err_out_arch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) par->FbAddress = nvidiafb_fix.smem_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) par->FbMapSize = par->RamAmountKBytes * 1024;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) if (vram && vram * 1024 * 1024 < par->FbMapSize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) par->FbMapSize = vram * 1024 * 1024;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) /* Limit amount of vram to 64 MB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) if (par->FbMapSize > 64 * 1024 * 1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) par->FbMapSize = 64 * 1024 * 1024;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) if(par->Architecture >= NV_ARCH_40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) par->FbUsableSize = par->FbMapSize - (560 * 1024);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) par->FbUsableSize = par->FbMapSize - (128 * 1024);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) par->ScratchBufferSize = (par->Architecture < NV_ARCH_10) ? 8 * 1024 :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) 16 * 1024;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) par->ScratchBufferStart = par->FbUsableSize - par->ScratchBufferSize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) par->CursorStart = par->FbUsableSize + (32 * 1024);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) info->screen_base = ioremap_wc(nvidiafb_fix.smem_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) par->FbMapSize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) info->screen_size = par->FbUsableSize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) nvidiafb_fix.smem_len = par->RamAmountKBytes * 1024;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) if (!info->screen_base) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) printk(KERN_ERR PFX "cannot ioremap FB base\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) goto err_out_free_base1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) par->FbStart = info->screen_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) if (!nomtrr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) par->wc_cookie = arch_phys_wc_add(nvidiafb_fix.smem_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) par->RamAmountKBytes * 1024);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) info->fbops = &nvidia_fb_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) info->fix = nvidiafb_fix;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) if (nvidia_set_fbinfo(info) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) printk(KERN_ERR PFX "error setting initial video mode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) goto err_out_iounmap_fb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) nvidia_save_vga(par, &par->SavedReg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) pci_set_drvdata(pd, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) if (backlight)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) nvidia_bl_init(par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) if (register_framebuffer(info) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) printk(KERN_ERR PFX "error registering nVidia framebuffer\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) goto err_out_iounmap_fb;
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) printk(KERN_INFO PFX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) "PCI nVidia %s framebuffer (%dMB @ 0x%lX)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) info->fix.id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) par->FbMapSize / (1024 * 1024), info->fix.smem_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) NVTRACE_LEAVE();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) err_out_iounmap_fb:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) iounmap(info->screen_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) err_out_free_base1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) fb_destroy_modedb(info->monspecs.modedb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) nvidia_delete_i2c_busses(par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) err_out_arch:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) iounmap(par->REGS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) err_out_free_base0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) pci_release_regions(pd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) err_out_enable:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) kfree(info->pixmap.addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) err_out_kfree:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) framebuffer_release(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) err_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) static void nvidiafb_remove(struct pci_dev *pd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) struct fb_info *info = pci_get_drvdata(pd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) struct nvidia_par *par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) NVTRACE_ENTER();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) unregister_framebuffer(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) nvidia_bl_exit(par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) arch_phys_wc_del(par->wc_cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) iounmap(info->screen_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) fb_destroy_modedb(info->monspecs.modedb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) nvidia_delete_i2c_busses(par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) iounmap(par->REGS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) pci_release_regions(pd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) kfree(info->pixmap.addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) framebuffer_release(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) NVTRACE_LEAVE();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) /* ------------------------------------------------------------------------- *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) * initialization
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) * ------------------------------------------------------------------------- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) #ifndef MODULE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) static int nvidiafb_setup(char *options)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) char *this_opt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) NVTRACE_ENTER();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) if (!options || !*options)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) while ((this_opt = strsep(&options, ",")) != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) if (!strncmp(this_opt, "forceCRTC", 9)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) char *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) p = this_opt + 9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) if (!*p || !*(++p))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) forceCRTC = *p - '0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) if (forceCRTC < 0 || forceCRTC > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) forceCRTC = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) } else if (!strncmp(this_opt, "flatpanel", 9)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) flatpanel = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) } else if (!strncmp(this_opt, "hwcur", 5)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) hwcur = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) } else if (!strncmp(this_opt, "noaccel", 6)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) noaccel = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) } else if (!strncmp(this_opt, "noscale", 7)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) noscale = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) } else if (!strncmp(this_opt, "reverse_i2c", 11)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) reverse_i2c = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) } else if (!strncmp(this_opt, "paneltweak:", 11)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) paneltweak = simple_strtoul(this_opt+11, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) } else if (!strncmp(this_opt, "vram:", 5)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) vram = simple_strtoul(this_opt+5, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) } else if (!strncmp(this_opt, "backlight:", 10)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) backlight = simple_strtoul(this_opt+10, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) } else if (!strncmp(this_opt, "nomtrr", 6)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) nomtrr = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) } else if (!strncmp(this_opt, "fpdither:", 9)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) fpdither = simple_strtol(this_opt+9, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) } else if (!strncmp(this_opt, "bpp:", 4)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) bpp = simple_strtoul(this_opt+4, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) mode_option = this_opt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) NVTRACE_LEAVE();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) #endif /* !MODULE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) static struct pci_driver nvidiafb_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) .name = "nvidiafb",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) .id_table = nvidiafb_pci_tbl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) .probe = nvidiafb_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) .driver.pm = &nvidiafb_pm_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) .remove = nvidiafb_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) /* ------------------------------------------------------------------------- *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) * modularization
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) * ------------------------------------------------------------------------- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) static int nvidiafb_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) #ifndef MODULE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) char *option = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) if (fb_get_options("nvidiafb", &option))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) nvidiafb_setup(option);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) return pci_register_driver(&nvidiafb_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) module_init(nvidiafb_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) static void __exit nvidiafb_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) pci_unregister_driver(&nvidiafb_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) module_exit(nvidiafb_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) module_param(flatpanel, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) MODULE_PARM_DESC(flatpanel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) "Enables experimental flat panel support for some chipsets. "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) "(0=disabled, 1=enabled, -1=autodetect) (default=-1)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) module_param(fpdither, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) MODULE_PARM_DESC(fpdither,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) "Enables dithering of flat panel for 6 bits panels. "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) "(0=disabled, 1=enabled, -1=autodetect) (default=-1)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) module_param(hwcur, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) MODULE_PARM_DESC(hwcur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) "Enables hardware cursor implementation. (0 or 1=enabled) "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) "(default=0)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) module_param(noaccel, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) MODULE_PARM_DESC(noaccel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) "Disables hardware acceleration. (0 or 1=disable) "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) "(default=0)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) module_param(noscale, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) MODULE_PARM_DESC(noscale,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) "Disables screen scaling. (0 or 1=disable) "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) "(default=0, do scaling)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) module_param(paneltweak, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) MODULE_PARM_DESC(paneltweak,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) "Tweak display settings for flatpanels. "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) "(default=0, no tweaks)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) module_param(forceCRTC, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) MODULE_PARM_DESC(forceCRTC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) "Forces usage of a particular CRTC in case autodetection "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) "fails. (0 or 1) (default=autodetect)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) module_param(vram, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) MODULE_PARM_DESC(vram,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) "amount of framebuffer memory to remap in MiB"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) "(default=0 - remap entire memory)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) module_param(mode_option, charp, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) MODULE_PARM_DESC(mode_option, "Specify initial video mode");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) module_param(bpp, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) MODULE_PARM_DESC(bpp, "pixel width in bits"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) "(default=8)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) module_param(reverse_i2c, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) MODULE_PARM_DESC(reverse_i2c, "reverse port assignment of the i2c bus");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) module_param(nomtrr, bool, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) MODULE_PARM_DESC(nomtrr, "Disables MTRR support (0 or 1=disabled) "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) "(default=0)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) MODULE_AUTHOR("Antonino Daplas");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) MODULE_DESCRIPTION("Framebuffer driver for nVidia graphics chipset");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) MODULE_LICENSE("GPL");