blob: 099d64af37be7830c4ad503c7e7af80eb35555ce [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * linux/drivers/video/nvidia/nvidia.c - nVidia fb driver
3 *
4 * Copyright 2004 Antonino Daplas <adaplas@pol.net>
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file COPYING in the main directory of this archive
8 * for more details.
9 *
10 */
11
12#include <linux/config.h>
13#include <linux/module.h>
14#include <linux/kernel.h>
15#include <linux/errno.h>
16#include <linux/string.h>
17#include <linux/mm.h>
18#include <linux/tty.h>
19#include <linux/slab.h>
20#include <linux/delay.h>
21#include <linux/fb.h>
22#include <linux/init.h>
23#include <linux/pci.h>
24#ifdef CONFIG_MTRR
25#include <asm/mtrr.h>
26#endif
27#ifdef CONFIG_PPC_OF
28#include <asm/prom.h>
29#include <asm/pci-bridge.h>
30#endif
31#ifdef CONFIG_PMAC_BACKLIGHT
32#include <asm/backlight.h>
33#endif
34
35#include "nv_local.h"
36#include "nv_type.h"
37#include "nv_proto.h"
38#include "nv_dma.h"
39
40#ifndef CONFIG_PCI /* sanity check */
41#error This driver requires PCI support.
42#endif
43
44#undef CONFIG_FB_NVIDIA_DEBUG
45#ifdef CONFIG_FB_NVIDIA_DEBUG
46#define NVTRACE printk
47#else
48#define NVTRACE if (0) printk
49#endif
50
51#define NVTRACE_ENTER(...) NVTRACE("%s START\n", __FUNCTION__)
52#define NVTRACE_LEAVE(...) NVTRACE("%s END\n", __FUNCTION__)
53
54#ifdef CONFIG_FB_NVIDIA_DEBUG
55#define assert(expr) \
56 if (!(expr)) { \
57 printk( "Assertion failed! %s,%s,%s,line=%d\n",\
58 #expr,__FILE__,__FUNCTION__,__LINE__); \
59 BUG(); \
60 }
61#else
62#define assert(expr)
63#endif
64
65#define PFX "nvidiafb: "
66
67/* HW cursor parameters */
68#define MAX_CURS 32
69
70static struct pci_device_id nvidiafb_pci_tbl[] = {
71 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_TNT,
72 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
73 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_TNT2,
74 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
75 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_UTNT2,
76 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
77 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_TNT_UNKNOWN,
78 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
79 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_VTNT2,
80 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
81 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_UVTNT2,
82 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
83 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_ITNT2,
84 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
85 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_SDR,
86 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
87 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_DDR,
88 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
89 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO,
90 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
91 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_MX,
92 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
93 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_MX2,
94 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
95 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_GO,
96 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
97 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO2_MXR,
98 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
99 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_GTS,
100 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
101 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_GTS2,
102 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
103 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_ULTRA,
104 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
105 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO2_PRO,
106 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
107 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_460,
108 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
109 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_440,
110 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
111 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_420,
112 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
113 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_440_SE,
114 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
115 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_440_GO,
116 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
117 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_420_GO,
118 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
119 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_460_GO,
120 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
121 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_420_GO_M32,
122 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
123 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_500XGL,
124 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
125 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_440_GO_M64,
126 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
127 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_200,
128 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
129 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_550XGL,
130 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
131 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_500_GOGL,
132 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
133 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_410_GO_M16,
134 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
135 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_440_8X,
136 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
137 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_440SE_8X,
138 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
139 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_420_8X,
140 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
141 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_448_GO,
142 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
143 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_488_GO,
144 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
145 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_580_XGL,
146 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
147 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_MAC,
148 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
149 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_280_NVS,
150 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
151 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_380_XGL,
152 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
153 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_IGEFORCE2,
154 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
155 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE3,
156 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
157 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE3_1,
158 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
159 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE3_2,
160 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
161 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO_DDC,
162 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
163 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4600,
164 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
165 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4400,
166 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
167 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4200,
168 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
169 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_900XGL,
170 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
171 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_750XGL,
172 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
173 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_700XGL,
174 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
175 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800,
176 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
177 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800_8X,
178 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
179 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800SE,
180 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
181 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_4200_GO,
182 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
183 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_980_XGL,
184 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
185 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_780_XGL,
186 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
187 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_700_GOGL,
188 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
189 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5800_ULTRA,
190 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
191 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5800,
192 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
193 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO_FX_2000,
194 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
195 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO_FX_1000,
196 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
197 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5600_ULTRA,
198 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
199 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5600,
200 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
201 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5600SE,
202 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
203 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO5600,
204 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
205 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO5650,
206 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
207 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO_FX_GO700,
208 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
209 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5200,
210 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
211 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5200_ULTRA,
212 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
213 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5200_1,
214 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
215 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5200SE,
216 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
217 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO5200,
218 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
219 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO5250,
220 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
221 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO5250_32,
222 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
223 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO_5200,
224 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
225 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO_NVS_280_PCI,
226 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
227 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO_FX_500,
228 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
229 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO5300,
230 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
231 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO5100,
232 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
233 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5900_ULTRA,
234 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
235 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5900,
236 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
237 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5900XT,
238 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
239 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5950_ULTRA,
240 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
241 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO_FX_3000,
242 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
243 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5700_ULTRA,
244 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
245 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5700,
246 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
247 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5700LE,
248 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
249 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5700VE,
250 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
251 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO5700_1,
252 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
253 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO5700_2,
254 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
255 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO_FX_GO1000,
256 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
257 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO_FX_1100,
258 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
259 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5500,
260 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
261 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5100,
262 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
263 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO_FX_700,
264 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
265 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5900ZT,
266 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
267 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_6800_ULTRA,
268 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
269 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_6800,
270 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
271 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_6800_LE,
272 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
273 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_6800_GT,
274 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
275 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO_FX_4000,
276 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
277 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_6600_GT,
278 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
279 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_6600,
280 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
281 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_6610_XL,
282 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
283 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO_FX_540,
284 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
285 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_6200,
286 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
Antonino A. Daplasc549dc62006-01-09 20:53:33 -0800287 {PCI_VENDOR_ID_NVIDIA, PCIE_DEVICE_ID_NVIDIA_GEFORCE_6800_ALT1,
288 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
289 {PCI_VENDOR_ID_NVIDIA, PCIE_DEVICE_ID_NVIDIA_GEFORCE_6600_ALT1,
290 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
291 {PCI_VENDOR_ID_NVIDIA, PCIE_DEVICE_ID_NVIDIA_GEFORCE_6600_ALT2,
292 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
293 {PCI_VENDOR_ID_NVIDIA, PCIE_DEVICE_ID_NVIDIA_GEFORCE_6200_ALT1,
294 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
295 {PCI_VENDOR_ID_NVIDIA, PCIE_DEVICE_ID_NVIDIA_GEFORCE_6800_GT,
296 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
Linus Torvalds1da177e2005-04-16 15:20:36 -0700297 {PCI_VENDOR_ID_NVIDIA, 0x0252,
298 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
299 {PCI_VENDOR_ID_NVIDIA, 0x0313,
300 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
301 {PCI_VENDOR_ID_NVIDIA, 0x0316,
302 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
303 {PCI_VENDOR_ID_NVIDIA, 0x0317,
304 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
305 {PCI_VENDOR_ID_NVIDIA, 0x031D,
306 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
307 {PCI_VENDOR_ID_NVIDIA, 0x031E,
308 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
309 {PCI_VENDOR_ID_NVIDIA, 0x031F,
310 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
311 {PCI_VENDOR_ID_NVIDIA, 0x0329,
312 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
313 {PCI_VENDOR_ID_NVIDIA, 0x032F,
314 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
315 {PCI_VENDOR_ID_NVIDIA, 0x0345,
316 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
317 {PCI_VENDOR_ID_NVIDIA, 0x0349,
318 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
319 {PCI_VENDOR_ID_NVIDIA, 0x034B,
320 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
321 {PCI_VENDOR_ID_NVIDIA, 0x034F,
322 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
323 {PCI_VENDOR_ID_NVIDIA, 0x00c0,
324 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
325 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_GEFORCE_6800A,
326 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
327 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_GEFORCE_6800A_LE,
328 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
329 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_GEFORCE_GO_6800,
330 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
331 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_GEFORCE_GO_6800_ULTRA,
332 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
333 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_QUADRO_FX_GO1400,
334 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
335 {PCI_VENDOR_ID_NVIDIA, 0x00cd,
336 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
337 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_QUADRO_FX_1400,
338 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
339 {PCI_VENDOR_ID_NVIDIA, 0x0142,
340 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
341 {PCI_VENDOR_ID_NVIDIA, 0x0143,
342 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
343 {PCI_VENDOR_ID_NVIDIA, 0x0144,
344 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
345 {PCI_VENDOR_ID_NVIDIA, 0x0145,
346 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
347 {PCI_VENDOR_ID_NVIDIA, 0x0146,
348 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
349 {PCI_VENDOR_ID_NVIDIA, 0x0147,
350 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
351 {PCI_VENDOR_ID_NVIDIA, 0x0148,
352 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
353 {PCI_VENDOR_ID_NVIDIA, 0x0149,
354 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
355 {PCI_VENDOR_ID_NVIDIA, 0x014b,
356 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
357 {PCI_VENDOR_ID_NVIDIA, 0x14c,
358 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
359 {PCI_VENDOR_ID_NVIDIA, 0x014d,
360 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
361 {PCI_VENDOR_ID_NVIDIA, 0x0160,
362 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
363 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_6200_TURBOCACHE,
364 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
365 {PCI_VENDOR_ID_NVIDIA, 0x0162,
366 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
367 {PCI_VENDOR_ID_NVIDIA, 0x0163,
368 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
369 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_GO_6200,
370 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
371 {PCI_VENDOR_ID_NVIDIA, 0x0165,
372 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
373 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_GO_6250,
374 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
375 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_GO_6200_1,
376 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
377 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_GO_6250_1,
378 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
379 {PCI_VENDOR_ID_NVIDIA, 0x0169,
380 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
381 {PCI_VENDOR_ID_NVIDIA, 0x016b,
382 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
383 {PCI_VENDOR_ID_NVIDIA, 0x016c,
384 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
385 {PCI_VENDOR_ID_NVIDIA, 0x016d,
386 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
387 {PCI_VENDOR_ID_NVIDIA, 0x016e,
388 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
389 {PCI_VENDOR_ID_NVIDIA, 0x0210,
390 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
391 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_6800B,
392 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
393 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_6800B_LE,
394 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
395 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_6800B_GT,
396 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
Calin A. Culianu7015faa2005-11-04 20:38:04 -0500397 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_7800_GT,
398 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
399 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_7800_GTX,
400 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
401 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_GO_7800,
402 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
403 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_GO_7800_GTX,
404 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
Linus Torvalds1da177e2005-04-16 15:20:36 -0700405 {PCI_VENDOR_ID_NVIDIA, 0x021d,
406 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
407 {PCI_VENDOR_ID_NVIDIA, 0x021e,
408 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
409 {PCI_VENDOR_ID_NVIDIA, 0x0220,
410 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
411 {PCI_VENDOR_ID_NVIDIA, 0x0221,
412 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
413 {PCI_VENDOR_ID_NVIDIA, 0x0222,
414 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
415 {PCI_VENDOR_ID_NVIDIA, 0x0228,
416 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
417 {0,} /* terminate list */
418};
419
420MODULE_DEVICE_TABLE(pci, nvidiafb_pci_tbl);
421
422/* command line data, set in nvidiafb_setup() */
423static int flatpanel __devinitdata = -1; /* Autodetect later */
Benjamin Herrenschmidtb8c49ef2005-11-07 01:00:32 -0800424static int fpdither __devinitdata = -1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700425static int forceCRTC __devinitdata = -1;
426static int hwcur __devinitdata = 0;
427static int noaccel __devinitdata = 0;
428static int noscale __devinitdata = 0;
429static int paneltweak __devinitdata = 0;
Antonino A. Daplas917bb072005-05-01 08:59:22 -0700430static int vram __devinitdata = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700431#ifdef CONFIG_MTRR
432static int nomtrr __devinitdata = 0;
433#endif
434
435static char *mode_option __devinitdata = NULL;
436
437static struct fb_fix_screeninfo __devinitdata nvidiafb_fix = {
438 .type = FB_TYPE_PACKED_PIXELS,
439 .xpanstep = 8,
440 .ypanstep = 1,
441};
442
443static struct fb_var_screeninfo __devinitdata nvidiafb_default_var = {
444 .xres = 640,
445 .yres = 480,
446 .xres_virtual = 640,
447 .yres_virtual = 480,
448 .bits_per_pixel = 8,
449 .red = {0, 8, 0},
450 .green = {0, 8, 0},
451 .blue = {0, 8, 0},
452 .transp = {0, 0, 0},
453 .activate = FB_ACTIVATE_NOW,
454 .height = -1,
455 .width = -1,
456 .pixclock = 39721,
457 .left_margin = 40,
458 .right_margin = 24,
459 .upper_margin = 32,
460 .lower_margin = 11,
461 .hsync_len = 96,
462 .vsync_len = 2,
463 .vmode = FB_VMODE_NONINTERLACED
464};
465
466/*
467 * Backlight control
468 */
469#ifdef CONFIG_PMAC_BACKLIGHT
470
471static int nvidia_backlight_levels[] = {
472 0x158,
473 0x192,
474 0x1c6,
475 0x200,
476 0x234,
477 0x268,
478 0x2a2,
479 0x2d6,
480 0x310,
481 0x344,
482 0x378,
483 0x3b2,
484 0x3e6,
485 0x41a,
486 0x454,
487 0x534,
488};
489
490/* ------------------------------------------------------------------------- *
491 *
492 * Backlight operations
493 *
494 * ------------------------------------------------------------------------- */
495
496static int nvidia_set_backlight_enable(int on, int level, void *data)
497{
Antonino A. Daplasc439e342006-01-09 20:53:02 -0800498 struct nvidia_par *par = data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700499 u32 tmp_pcrt, tmp_pmc, fpcontrol;
500
501 tmp_pmc = NV_RD32(par->PMC, 0x10F0) & 0x0000FFFF;
502 tmp_pcrt = NV_RD32(par->PCRTC0, 0x081C) & 0xFFFFFFFC;
503 fpcontrol = NV_RD32(par->PRAMDAC, 0x0848) & 0xCFFFFFCC;
504
505 if (on && (level > BACKLIGHT_OFF)) {
506 tmp_pcrt |= 0x1;
507 tmp_pmc |= (1 << 31); // backlight bit
508 tmp_pmc |= nvidia_backlight_levels[level - 1] << 16;
509 }
510
511 if (on)
512 fpcontrol |= par->fpSyncs;
513 else
514 fpcontrol |= 0x20000022;
515
516 NV_WR32(par->PCRTC0, 0x081C, tmp_pcrt);
517 NV_WR32(par->PMC, 0x10F0, tmp_pmc);
518 NV_WR32(par->PRAMDAC, 0x848, fpcontrol);
519
520 return 0;
521}
522
523static int nvidia_set_backlight_level(int level, void *data)
524{
525 return nvidia_set_backlight_enable(1, level, data);
526}
527
528static struct backlight_controller nvidia_backlight_controller = {
529 nvidia_set_backlight_enable,
530 nvidia_set_backlight_level
531};
532
533#endif /* CONFIG_PMAC_BACKLIGHT */
534
535static void nvidiafb_load_cursor_image(struct nvidia_par *par, u8 * data8,
536 u16 bg, u16 fg, u32 w, u32 h)
537{
James Simmonsf1ab5da2005-06-21 17:17:07 -0700538 u32 *data = (u32 *) data8;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700539 int i, j, k = 0;
540 u32 b, tmp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700541
542 w = (w + 1) & ~1;
543
544 for (i = 0; i < h; i++) {
545 b = *data++;
546 reverse_order(&b);
547
548 for (j = 0; j < w / 2; j++) {
549 tmp = 0;
550#if defined (__BIG_ENDIAN)
551 tmp = (b & (1 << 31)) ? fg << 16 : bg << 16;
552 b <<= 1;
553 tmp |= (b & (1 << 31)) ? fg : bg;
554 b <<= 1;
555#else
556 tmp = (b & 1) ? fg : bg;
557 b >>= 1;
558 tmp |= (b & 1) ? fg << 16 : bg << 16;
559 b >>= 1;
560#endif
561 NV_WR32(&par->CURSOR[k++], 0, tmp);
562 }
563 k += (MAX_CURS - w) / 2;
564 }
565}
566
567static void nvidia_write_clut(struct nvidia_par *par,
568 u8 regnum, u8 red, u8 green, u8 blue)
569{
570 NVWriteDacMask(par, 0xff);
571 NVWriteDacWriteAddr(par, regnum);
572 NVWriteDacData(par, red);
573 NVWriteDacData(par, green);
574 NVWriteDacData(par, blue);
575}
576
577static void nvidia_read_clut(struct nvidia_par *par,
578 u8 regnum, u8 * red, u8 * green, u8 * blue)
579{
580 NVWriteDacMask(par, 0xff);
581 NVWriteDacReadAddr(par, regnum);
582 *red = NVReadDacData(par);
583 *green = NVReadDacData(par);
584 *blue = NVReadDacData(par);
585}
586
587static int nvidia_panel_tweak(struct nvidia_par *par,
588 struct _riva_hw_state *state)
589{
590 int tweak = 0;
591
592 if (par->paneltweak) {
593 tweak = par->paneltweak;
594 } else {
595 /* begin flat panel hacks */
596 /* This is unfortunate, but some chips need this register
597 tweaked or else you get artifacts where adjacent pixels are
598 swapped. There are no hard rules for what to set here so all
599 we can do is experiment and apply hacks. */
600
601 if(((par->Chipset & 0xffff) == 0x0328) && (state->bpp == 32)) {
602 /* At least one NV34 laptop needs this workaround. */
603 tweak = -1;
604 }
605
606 if((par->Chipset & 0xfff0) == 0x0310) {
607 tweak = 1;
608 }
609 /* end flat panel hacks */
610 }
611
612 return tweak;
613}
614
615static void nvidia_save_vga(struct nvidia_par *par,
616 struct _riva_hw_state *state)
617{
618 int i;
619
620 NVTRACE_ENTER();
621 NVLockUnlock(par, 0);
622
623 NVUnloadStateExt(par, state);
624
625 state->misc_output = NVReadMiscOut(par);
626
627 for (i = 0; i < NUM_CRT_REGS; i++)
628 state->crtc[i] = NVReadCrtc(par, i);
629
630 for (i = 0; i < NUM_ATC_REGS; i++)
631 state->attr[i] = NVReadAttr(par, i);
632
633 for (i = 0; i < NUM_GRC_REGS; i++)
634 state->gra[i] = NVReadGr(par, i);
635
636 for (i = 0; i < NUM_SEQ_REGS; i++)
637 state->seq[i] = NVReadSeq(par, i);
638 NVTRACE_LEAVE();
639}
640
Benjamin Herrenschmidt85f15032005-11-07 01:00:30 -0800641#undef DUMP_REG
642
Linus Torvalds1da177e2005-04-16 15:20:36 -0700643static void nvidia_write_regs(struct nvidia_par *par)
644{
645 struct _riva_hw_state *state = &par->ModeReg;
646 int i;
647
648 NVTRACE_ENTER();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700649
650 NVLoadStateExt(par, state);
651
652 NVWriteMiscOut(par, state->misc_output);
653
Benjamin Herrenschmidt85f15032005-11-07 01:00:30 -0800654 for (i = 1; i < NUM_SEQ_REGS; i++) {
655#ifdef DUMP_REG
656 printk(" SEQ[%02x] = %08x\n", i, state->seq[i]);
657#endif
658 NVWriteSeq(par, i, state->seq[i]);
659 }
660
661 /* Ensure CRTC registers 0-7 are unlocked by clearing bit 7 of CRTC[17] */
662 NVWriteCrtc(par, 0x11, state->crtc[0x11] & ~0x80);
663
Linus Torvalds1da177e2005-04-16 15:20:36 -0700664 for (i = 0; i < NUM_CRT_REGS; i++) {
665 switch (i) {
666 case 0x19:
667 case 0x20 ... 0x40:
668 break;
669 default:
Benjamin Herrenschmidt85f15032005-11-07 01:00:30 -0800670#ifdef DUMP_REG
671 printk("CRTC[%02x] = %08x\n", i, state->crtc[i]);
672#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700673 NVWriteCrtc(par, i, state->crtc[i]);
674 }
675 }
676
Benjamin Herrenschmidt85f15032005-11-07 01:00:30 -0800677 for (i = 0; i < NUM_GRC_REGS; i++) {
678#ifdef DUMP_REG
679 printk(" GRA[%02x] = %08x\n", i, state->gra[i]);
680#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700681 NVWriteGr(par, i, state->gra[i]);
Benjamin Herrenschmidt85f15032005-11-07 01:00:30 -0800682 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700683
Benjamin Herrenschmidt85f15032005-11-07 01:00:30 -0800684 for (i = 0; i < NUM_ATC_REGS; i++) {
685#ifdef DUMP_REG
686 printk("ATTR[%02x] = %08x\n", i, state->attr[i]);
687#endif
688 NVWriteAttr(par, i, state->attr[i]);
689 }
690
Linus Torvalds1da177e2005-04-16 15:20:36 -0700691 NVTRACE_LEAVE();
692}
693
Benjamin Herrenschmidt85f15032005-11-07 01:00:30 -0800694static void nvidia_vga_protect(struct nvidia_par *par, int on)
695{
696 unsigned char tmp;
697
698 if (on) {
699 /*
700 * Turn off screen and disable sequencer.
701 */
702 tmp = NVReadSeq(par, 0x01);
703
704 NVWriteSeq(par, 0x00, 0x01); /* Synchronous Reset */
705 NVWriteSeq(par, 0x01, tmp | 0x20); /* disable the display */
706 } else {
707 /*
708 * Reenable sequencer, then turn on screen.
709 */
710
711 tmp = NVReadSeq(par, 0x01);
712
713 NVWriteSeq(par, 0x01, tmp & ~0x20); /* reenable display */
714 NVWriteSeq(par, 0x00, 0x03); /* End Reset */
715 }
716}
717
718
719
Linus Torvalds1da177e2005-04-16 15:20:36 -0700720static int nvidia_calc_regs(struct fb_info *info)
721{
722 struct nvidia_par *par = info->par;
723 struct _riva_hw_state *state = &par->ModeReg;
Antonino A. Daplasb8c90942005-09-09 13:04:37 -0700724 int i, depth = fb_get_color_depth(&info->var, &info->fix);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700725 int h_display = info->var.xres / 8 - 1;
726 int h_start = (info->var.xres + info->var.right_margin) / 8 - 1;
727 int h_end = (info->var.xres + info->var.right_margin +
728 info->var.hsync_len) / 8 - 1;
729 int h_total = (info->var.xres + info->var.right_margin +
730 info->var.hsync_len + info->var.left_margin) / 8 - 5;
731 int h_blank_s = h_display;
732 int h_blank_e = h_total + 4;
733 int v_display = info->var.yres - 1;
734 int v_start = info->var.yres + info->var.lower_margin - 1;
735 int v_end = (info->var.yres + info->var.lower_margin +
736 info->var.vsync_len) - 1;
737 int v_total = (info->var.yres + info->var.lower_margin +
738 info->var.vsync_len + info->var.upper_margin) - 2;
739 int v_blank_s = v_display;
740 int v_blank_e = v_total + 1;
741
742 /*
743 * Set all CRTC values.
744 */
745
746 if (info->var.vmode & FB_VMODE_INTERLACED)
747 v_total |= 1;
748
749 if (par->FlatPanel == 1) {
750 v_start = v_total - 3;
751 v_end = v_total - 2;
752 v_blank_s = v_start;
753 h_start = h_total - 5;
754 h_end = h_total - 2;
755 h_blank_e = h_total + 4;
756 }
757
758 state->crtc[0x0] = Set8Bits(h_total);
759 state->crtc[0x1] = Set8Bits(h_display);
760 state->crtc[0x2] = Set8Bits(h_blank_s);
761 state->crtc[0x3] = SetBitField(h_blank_e, 4: 0, 4:0)
762 | SetBit(7);
763 state->crtc[0x4] = Set8Bits(h_start);
764 state->crtc[0x5] = SetBitField(h_blank_e, 5: 5, 7:7)
765 | SetBitField(h_end, 4: 0, 4:0);
766 state->crtc[0x6] = SetBitField(v_total, 7: 0, 7:0);
767 state->crtc[0x7] = SetBitField(v_total, 8: 8, 0:0)
768 | SetBitField(v_display, 8: 8, 1:1)
769 | SetBitField(v_start, 8: 8, 2:2)
770 | SetBitField(v_blank_s, 8: 8, 3:3)
771 | SetBit(4)
772 | SetBitField(v_total, 9: 9, 5:5)
773 | SetBitField(v_display, 9: 9, 6:6)
774 | SetBitField(v_start, 9: 9, 7:7);
775 state->crtc[0x9] = SetBitField(v_blank_s, 9: 9, 5:5)
776 | SetBit(6)
777 | ((info->var.vmode & FB_VMODE_DOUBLE) ? 0x80 : 0x00);
778 state->crtc[0x10] = Set8Bits(v_start);
779 state->crtc[0x11] = SetBitField(v_end, 3: 0, 3:0) | SetBit(5);
780 state->crtc[0x12] = Set8Bits(v_display);
781 state->crtc[0x13] = ((info->var.xres_virtual / 8) *
782 (info->var.bits_per_pixel / 8));
783 state->crtc[0x15] = Set8Bits(v_blank_s);
784 state->crtc[0x16] = Set8Bits(v_blank_e);
785
786 state->attr[0x10] = 0x01;
787
788 if (par->Television)
789 state->attr[0x11] = 0x00;
790
791 state->screen = SetBitField(h_blank_e, 6: 6, 4:4)
792 | SetBitField(v_blank_s, 10: 10, 3:3)
793 | SetBitField(v_start, 10: 10, 2:2)
794 | SetBitField(v_display, 10: 10, 1:1)
795 | SetBitField(v_total, 10: 10, 0:0);
796
797 state->horiz = SetBitField(h_total, 8: 8, 0:0)
798 | SetBitField(h_display, 8: 8, 1:1)
799 | SetBitField(h_blank_s, 8: 8, 2:2)
800 | SetBitField(h_start, 8: 8, 3:3);
801
802 state->extra = SetBitField(v_total, 11: 11, 0:0)
803 | SetBitField(v_display, 11: 11, 2:2)
804 | SetBitField(v_start, 11: 11, 4:4)
805 | SetBitField(v_blank_s, 11: 11, 6:6);
806
807 if (info->var.vmode & FB_VMODE_INTERLACED) {
808 h_total = (h_total >> 1) & ~1;
809 state->interlace = Set8Bits(h_total);
810 state->horiz |= SetBitField(h_total, 8: 8, 4:4);
811 } else {
812 state->interlace = 0xff; /* interlace off */
813 }
814
815 /*
816 * Calculate the extended registers.
817 */
818
819 if (depth < 24)
820 i = depth;
821 else
822 i = 32;
823
824 if (par->Architecture >= NV_ARCH_10)
825 par->CURSOR = (volatile u32 __iomem *)(info->screen_base +
826 par->CursorStart);
827
828 if (info->var.sync & FB_SYNC_HOR_HIGH_ACT)
829 state->misc_output &= ~0x40;
830 else
831 state->misc_output |= 0x40;
832 if (info->var.sync & FB_SYNC_VERT_HIGH_ACT)
833 state->misc_output &= ~0x80;
834 else
835 state->misc_output |= 0x80;
836
837 NVCalcStateExt(par, state, i, info->var.xres_virtual,
838 info->var.xres, info->var.yres_virtual,
839 1000000000 / info->var.pixclock, info->var.vmode);
840
841 state->scale = NV_RD32(par->PRAMDAC, 0x00000848) & 0xfff000ff;
842 if (par->FlatPanel == 1) {
843 state->pixel |= (1 << 7);
844
845 if (!par->fpScaler || (par->fpWidth <= info->var.xres)
846 || (par->fpHeight <= info->var.yres)) {
847 state->scale |= (1 << 8);
848 }
849
850 if (!par->crtcSync_read) {
851 state->crtcSync = NV_RD32(par->PRAMDAC, 0x0828);
852 par->crtcSync_read = 1;
853 }
854
855 par->PanelTweak = nvidia_panel_tweak(par, state);
856 }
857
858 state->vpll = state->pll;
859 state->vpll2 = state->pll;
860 state->vpllB = state->pllB;
861 state->vpll2B = state->pllB;
862
863 VGA_WR08(par->PCIO, 0x03D4, 0x1C);
864 state->fifo = VGA_RD08(par->PCIO, 0x03D5) & ~(1<<5);
865
866 if (par->CRTCnumber) {
867 state->head = NV_RD32(par->PCRTC0, 0x00000860) & ~0x00001000;
868 state->head2 = NV_RD32(par->PCRTC0, 0x00002860) | 0x00001000;
869 state->crtcOwner = 3;
870 state->pllsel |= 0x20000800;
871 state->vpll = NV_RD32(par->PRAMDAC0, 0x00000508);
872 if (par->twoStagePLL)
873 state->vpllB = NV_RD32(par->PRAMDAC0, 0x00000578);
874 } else if (par->twoHeads) {
875 state->head = NV_RD32(par->PCRTC0, 0x00000860) | 0x00001000;
876 state->head2 = NV_RD32(par->PCRTC0, 0x00002860) & ~0x00001000;
877 state->crtcOwner = 0;
878 state->vpll2 = NV_RD32(par->PRAMDAC0, 0x0520);
879 if (par->twoStagePLL)
880 state->vpll2B = NV_RD32(par->PRAMDAC0, 0x057C);
881 }
882
883 state->cursorConfig = 0x00000100;
884
885 if (info->var.vmode & FB_VMODE_DOUBLE)
886 state->cursorConfig |= (1 << 4);
887
888 if (par->alphaCursor) {
889 if ((par->Chipset & 0x0ff0) != 0x0110)
890 state->cursorConfig |= 0x04011000;
891 else
892 state->cursorConfig |= 0x14011000;
893 state->general |= (1 << 29);
894 } else
895 state->cursorConfig |= 0x02000000;
896
897 if (par->twoHeads) {
898 if ((par->Chipset & 0x0ff0) == 0x0110) {
899 state->dither = NV_RD32(par->PRAMDAC, 0x0528) &
900 ~0x00010000;
901 if (par->FPDither)
902 state->dither |= 0x00010000;
903 } else {
904 state->dither = NV_RD32(par->PRAMDAC, 0x083C) & ~1;
905 if (par->FPDither)
906 state->dither |= 1;
907 }
908 }
909
910 state->timingH = 0;
911 state->timingV = 0;
912 state->displayV = info->var.xres;
913
914 return 0;
915}
916
917static void nvidia_init_vga(struct fb_info *info)
918{
919 struct nvidia_par *par = info->par;
920 struct _riva_hw_state *state = &par->ModeReg;
921 int i;
922
923 for (i = 0; i < 0x10; i++)
924 state->attr[i] = i;
925 state->attr[0x10] = 0x41;
Benjamin Herrenschmidt85f15032005-11-07 01:00:30 -0800926 state->attr[0x11] = 0xff;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700927 state->attr[0x12] = 0x0f;
928 state->attr[0x13] = 0x00;
929 state->attr[0x14] = 0x00;
930
931 memset(state->crtc, 0x00, NUM_CRT_REGS);
932 state->crtc[0x0a] = 0x20;
933 state->crtc[0x17] = 0xe3;
934 state->crtc[0x18] = 0xff;
935 state->crtc[0x28] = 0x40;
936
937 memset(state->gra, 0x00, NUM_GRC_REGS);
938 state->gra[0x05] = 0x40;
939 state->gra[0x06] = 0x05;
940 state->gra[0x07] = 0x0f;
941 state->gra[0x08] = 0xff;
942
943 state->seq[0x00] = 0x03;
944 state->seq[0x01] = 0x01;
945 state->seq[0x02] = 0x0f;
946 state->seq[0x03] = 0x00;
947 state->seq[0x04] = 0x0e;
948
949 state->misc_output = 0xeb;
950}
951
952static int nvidiafb_cursor(struct fb_info *info, struct fb_cursor *cursor)
953{
954 struct nvidia_par *par = info->par;
955 u8 data[MAX_CURS * MAX_CURS / 8];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700956 int i, set = cursor->set;
James Simmonsf1ab5da2005-06-21 17:17:07 -0700957 u16 fg, bg;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700958
Antonino A. Daplas7a482422005-09-21 07:30:21 +0800959 if (cursor->image.width > MAX_CURS || cursor->image.height > MAX_CURS)
James Simmonsf1ab5da2005-06-21 17:17:07 -0700960 return -ENXIO;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700961
962 NVShowHideCursor(par, 0);
963
964 if (par->cursor_reset) {
965 set = FB_CUR_SETALL;
966 par->cursor_reset = 0;
967 }
968
969 if (set & FB_CUR_SETSIZE)
970 memset_io(par->CURSOR, 0, MAX_CURS * MAX_CURS * 2);
971
972 if (set & FB_CUR_SETPOS) {
973 u32 xx, yy, temp;
974
975 yy = cursor->image.dy - info->var.yoffset;
976 xx = cursor->image.dx - info->var.xoffset;
977 temp = xx & 0xFFFF;
978 temp |= yy << 16;
979
980 NV_WR32(par->PRAMDAC, 0x0000300, temp);
981 }
982
983 if (set & (FB_CUR_SETSHAPE | FB_CUR_SETCMAP | FB_CUR_SETIMAGE)) {
984 u32 bg_idx = cursor->image.bg_color;
985 u32 fg_idx = cursor->image.fg_color;
986 u32 s_pitch = (cursor->image.width + 7) >> 3;
987 u32 d_pitch = MAX_CURS / 8;
988 u8 *dat = (u8 *) cursor->image.data;
989 u8 *msk = (u8 *) cursor->mask;
990 u8 *src;
991
992 src = kmalloc(s_pitch * cursor->image.height, GFP_ATOMIC);
993
994 if (src) {
995 switch (cursor->rop) {
996 case ROP_XOR:
James Simmonsf1ab5da2005-06-21 17:17:07 -0700997 for (i = 0; i < s_pitch * cursor->image.height; i++)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700998 src[i] = dat[i] ^ msk[i];
999 break;
1000 case ROP_COPY:
1001 default:
James Simmonsf1ab5da2005-06-21 17:17:07 -07001002 for (i = 0; i < s_pitch * cursor->image.height; i++)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001003 src[i] = dat[i] & msk[i];
1004 break;
1005 }
1006
James Simmonsf1ab5da2005-06-21 17:17:07 -07001007 fb_pad_aligned_buffer(data, d_pitch, src, s_pitch,
1008 cursor->image.height);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001009
1010 bg = ((info->cmap.red[bg_idx] & 0xf8) << 7) |
1011 ((info->cmap.green[bg_idx] & 0xf8) << 2) |
1012 ((info->cmap.blue[bg_idx] & 0xf8) >> 3) | 1 << 15;
1013
1014 fg = ((info->cmap.red[fg_idx] & 0xf8) << 7) |
1015 ((info->cmap.green[fg_idx] & 0xf8) << 2) |
1016 ((info->cmap.blue[fg_idx] & 0xf8) >> 3) | 1 << 15;
1017
1018 NVLockUnlock(par, 0);
1019
1020 nvidiafb_load_cursor_image(par, data, bg, fg,
1021 cursor->image.width,
1022 cursor->image.height);
1023 kfree(src);
1024 }
1025 }
1026
1027 if (cursor->enable)
1028 NVShowHideCursor(par, 1);
1029
1030 return 0;
1031}
1032
1033static int nvidiafb_set_par(struct fb_info *info)
1034{
1035 struct nvidia_par *par = info->par;
1036
1037 NVTRACE_ENTER();
1038
1039 NVLockUnlock(par, 1);
Benjamin Herrenschmidtb8c49ef2005-11-07 01:00:32 -08001040 if (!par->FlatPanel || !par->twoHeads)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001041 par->FPDither = 0;
1042
Benjamin Herrenschmidtb8c49ef2005-11-07 01:00:32 -08001043 if (par->FPDither < 0) {
1044 if ((par->Chipset & 0x0ff0) == 0x0110)
1045 par->FPDither = !!(NV_RD32(par->PRAMDAC, 0x0528)
1046 & 0x00010000);
1047 else
1048 par->FPDither = !!(NV_RD32(par->PRAMDAC, 0x083C) & 1);
1049 printk(KERN_INFO PFX "Flat panel dithering %s\n",
1050 par->FPDither ? "enabled" : "disabled");
1051 }
1052
Antonino A. Daplasb8c90942005-09-09 13:04:37 -07001053 info->fix.visual = (info->var.bits_per_pixel == 8) ?
1054 FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
1055
Linus Torvalds1da177e2005-04-16 15:20:36 -07001056 nvidia_init_vga(info);
1057 nvidia_calc_regs(info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001058
1059 NVLockUnlock(par, 0);
1060 if (par->twoHeads) {
1061 VGA_WR08(par->PCIO, 0x03D4, 0x44);
1062 VGA_WR08(par->PCIO, 0x03D5, par->ModeReg.crtcOwner);
1063 NVLockUnlock(par, 0);
1064 }
1065
Benjamin Herrenschmidt85f15032005-11-07 01:00:30 -08001066 nvidia_vga_protect(par, 1);
1067
1068 nvidia_write_regs(par);
1069
1070#if defined (__BIG_ENDIAN)
1071 /* turn on LFB swapping */
1072 {
1073 unsigned char tmp;
1074
1075 VGA_WR08(par->PCIO, 0x3d4, 0x46);
1076 tmp = VGA_RD08(par->PCIO, 0x3d5);
1077 tmp |= (1 << 7);
1078 VGA_WR08(par->PCIO, 0x3d5, tmp);
1079 }
1080#endif
1081
Linus Torvalds1da177e2005-04-16 15:20:36 -07001082 info->fix.line_length = (info->var.xres_virtual *
1083 info->var.bits_per_pixel) >> 3;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001084 if (info->var.accel_flags) {
1085 info->fbops->fb_imageblit = nvidiafb_imageblit;
1086 info->fbops->fb_fillrect = nvidiafb_fillrect;
1087 info->fbops->fb_copyarea = nvidiafb_copyarea;
1088 info->fbops->fb_sync = nvidiafb_sync;
1089 info->pixmap.scan_align = 4;
1090 info->flags &= ~FBINFO_HWACCEL_DISABLED;
1091 NVResetGraphics(info);
1092 } else {
1093 info->fbops->fb_imageblit = cfb_imageblit;
1094 info->fbops->fb_fillrect = cfb_fillrect;
1095 info->fbops->fb_copyarea = cfb_copyarea;
1096 info->fbops->fb_sync = NULL;
1097 info->pixmap.scan_align = 1;
1098 info->flags |= FBINFO_HWACCEL_DISABLED;
1099 }
1100
1101 par->cursor_reset = 1;
1102
Benjamin Herrenschmidt85f15032005-11-07 01:00:30 -08001103 nvidia_vga_protect(par, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001104
1105 NVTRACE_LEAVE();
1106 return 0;
1107}
1108
1109static int nvidiafb_setcolreg(unsigned regno, unsigned red, unsigned green,
1110 unsigned blue, unsigned transp,
1111 struct fb_info *info)
1112{
1113 struct nvidia_par *par = info->par;
1114 int i;
1115
1116 NVTRACE_ENTER();
1117 if (regno >= (1 << info->var.green.length))
1118 return -EINVAL;
1119
1120 if (info->var.grayscale) {
1121 /* gray = 0.30*R + 0.59*G + 0.11*B */
1122 red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8;
1123 }
1124
1125 if (regno < 16 && info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
1126 ((u32 *) info->pseudo_palette)[regno] =
1127 (regno << info->var.red.offset) |
1128 (regno << info->var.green.offset) |
1129 (regno << info->var.blue.offset);
1130 }
1131
1132 switch (info->var.bits_per_pixel) {
1133 case 8:
1134 /* "transparent" stuff is completely ignored. */
1135 nvidia_write_clut(par, regno, red >> 8, green >> 8, blue >> 8);
1136 break;
1137 case 16:
1138 if (info->var.green.length == 5) {
1139 for (i = 0; i < 8; i++) {
1140 nvidia_write_clut(par, regno * 8 + i, red >> 8,
1141 green >> 8, blue >> 8);
1142 }
1143 } else {
1144 u8 r, g, b;
1145
1146 if (regno < 32) {
1147 for (i = 0; i < 8; i++) {
1148 nvidia_write_clut(par, regno * 8 + i,
1149 red >> 8, green >> 8,
1150 blue >> 8);
1151 }
1152 }
1153
1154 nvidia_read_clut(par, regno * 4, &r, &g, &b);
1155
1156 for (i = 0; i < 4; i++)
1157 nvidia_write_clut(par, regno * 4 + i, r,
1158 green >> 8, b);
1159 }
1160 break;
1161 case 32:
1162 nvidia_write_clut(par, regno, red >> 8, green >> 8, blue >> 8);
1163 break;
1164 default:
1165 /* do nothing */
1166 break;
1167 }
1168
1169 NVTRACE_LEAVE();
1170 return 0;
1171}
1172
1173static int nvidiafb_check_var(struct fb_var_screeninfo *var,
1174 struct fb_info *info)
1175{
1176 struct nvidia_par *par = info->par;
1177 int memlen, vramlen, mode_valid = 0;
1178 int pitch, err = 0;
1179
1180 NVTRACE_ENTER();
1181
1182 var->transp.offset = 0;
1183 var->transp.length = 0;
1184
1185 var->xres &= ~7;
1186
1187 if (var->bits_per_pixel <= 8)
1188 var->bits_per_pixel = 8;
1189 else if (var->bits_per_pixel <= 16)
1190 var->bits_per_pixel = 16;
1191 else
1192 var->bits_per_pixel = 32;
1193
1194 switch (var->bits_per_pixel) {
1195 case 8:
1196 var->red.offset = 0;
1197 var->red.length = 8;
1198 var->green.offset = 0;
1199 var->green.length = 8;
1200 var->blue.offset = 0;
1201 var->blue.length = 8;
1202 var->transp.offset = 0;
1203 var->transp.length = 0;
1204 break;
1205 case 16:
1206 var->green.length = (var->green.length < 6) ? 5 : 6;
1207 var->red.length = 5;
1208 var->blue.length = 5;
1209 var->transp.length = 6 - var->green.length;
1210 var->blue.offset = 0;
1211 var->green.offset = 5;
1212 var->red.offset = 5 + var->green.length;
1213 var->transp.offset = (5 + var->red.offset) & 15;
1214 break;
1215 case 32: /* RGBA 8888 */
1216 var->red.offset = 16;
1217 var->red.length = 8;
1218 var->green.offset = 8;
1219 var->green.length = 8;
1220 var->blue.offset = 0;
1221 var->blue.length = 8;
1222 var->transp.length = 8;
1223 var->transp.offset = 24;
1224 break;
1225 }
1226
1227 var->red.msb_right = 0;
1228 var->green.msb_right = 0;
1229 var->blue.msb_right = 0;
1230 var->transp.msb_right = 0;
1231
1232 if (!info->monspecs.hfmax || !info->monspecs.vfmax ||
1233 !info->monspecs.dclkmax || !fb_validate_mode(var, info))
1234 mode_valid = 1;
1235
1236 /* calculate modeline if supported by monitor */
1237 if (!mode_valid && info->monspecs.gtf) {
1238 if (!fb_get_mode(FB_MAXTIMINGS, 0, var, info))
1239 mode_valid = 1;
1240 }
1241
1242 if (!mode_valid) {
1243 struct fb_videomode *mode;
1244
1245 mode = fb_find_best_mode(var, &info->modelist);
1246 if (mode) {
1247 fb_videomode_to_var(var, mode);
1248 mode_valid = 1;
1249 }
1250 }
1251
1252 if (!mode_valid && info->monspecs.modedb_len)
1253 return -EINVAL;
1254
1255 if (par->fpWidth && par->fpHeight && (par->fpWidth < var->xres ||
1256 par->fpHeight < var->yres))
1257 return -EINVAL;
1258
1259 if (var->yres_virtual < var->yres)
1260 var->yres_virtual = var->yres;
1261
1262 if (var->xres_virtual < var->xres)
1263 var->xres_virtual = var->xres;
1264
1265 var->xres_virtual = (var->xres_virtual + 63) & ~63;
1266
Antonino A. Daplas917bb072005-05-01 08:59:22 -07001267 vramlen = info->screen_size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001268 pitch = ((var->xres_virtual * var->bits_per_pixel) + 7) / 8;
1269 memlen = pitch * var->yres_virtual;
1270
1271 if (memlen > vramlen) {
1272 var->yres_virtual = vramlen / pitch;
1273
1274 if (var->yres_virtual < var->yres) {
1275 var->yres_virtual = var->yres;
1276 var->xres_virtual = vramlen / var->yres_virtual;
1277 var->xres_virtual /= var->bits_per_pixel / 8;
1278 var->xres_virtual &= ~63;
1279 pitch = (var->xres_virtual *
1280 var->bits_per_pixel + 7) / 8;
1281 memlen = pitch * var->yres;
1282
1283 if (var->xres_virtual < var->xres) {
1284 printk("nvidiafb: required video memory, "
1285 "%d bytes, for %dx%d-%d (virtual) "
1286 "is out of range\n",
1287 memlen, var->xres_virtual,
1288 var->yres_virtual, var->bits_per_pixel);
1289 err = -ENOMEM;
1290 }
1291 }
1292 }
1293
1294 if (var->accel_flags) {
1295 if (var->yres_virtual > 0x7fff)
1296 var->yres_virtual = 0x7fff;
1297 if (var->xres_virtual > 0x7fff)
1298 var->xres_virtual = 0x7fff;
1299 }
1300
1301 var->xres_virtual &= ~63;
1302
1303 NVTRACE_LEAVE();
1304
1305 return err;
1306}
1307
1308static int nvidiafb_pan_display(struct fb_var_screeninfo *var,
1309 struct fb_info *info)
1310{
1311 struct nvidia_par *par = info->par;
1312 u32 total;
1313
Antonino A. Daplas3c8d61b2005-11-13 16:06:34 -08001314 total = var->yoffset * info->fix.line_length + var->xoffset;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001315
1316 NVSetStartAddress(par, total);
1317
1318 return 0;
1319}
1320
1321static int nvidiafb_blank(int blank, struct fb_info *info)
1322{
1323 struct nvidia_par *par = info->par;
1324 unsigned char tmp, vesa;
1325
1326 tmp = NVReadSeq(par, 0x01) & ~0x20; /* screen on/off */
1327 vesa = NVReadCrtc(par, 0x1a) & ~0xc0; /* sync on/off */
1328
1329 NVTRACE_ENTER();
1330
1331 if (blank)
1332 tmp |= 0x20;
1333
1334 switch (blank) {
1335 case FB_BLANK_UNBLANK:
1336 case FB_BLANK_NORMAL:
1337 break;
1338 case FB_BLANK_VSYNC_SUSPEND:
1339 vesa |= 0x80;
1340 break;
1341 case FB_BLANK_HSYNC_SUSPEND:
1342 vesa |= 0x40;
1343 break;
1344 case FB_BLANK_POWERDOWN:
1345 vesa |= 0xc0;
1346 break;
1347 }
1348
1349 NVWriteSeq(par, 0x01, tmp);
1350 NVWriteCrtc(par, 0x1a, vesa);
1351
1352#ifdef CONFIG_PMAC_BACKLIGHT
1353 if (par->FlatPanel && _machine == _MACH_Pmac) {
1354 set_backlight_enable(!blank);
1355 }
1356#endif
1357
1358 NVTRACE_LEAVE();
1359
1360 return 0;
1361}
1362
1363static struct fb_ops nvidia_fb_ops = {
1364 .owner = THIS_MODULE,
1365 .fb_check_var = nvidiafb_check_var,
1366 .fb_set_par = nvidiafb_set_par,
1367 .fb_setcolreg = nvidiafb_setcolreg,
1368 .fb_pan_display = nvidiafb_pan_display,
1369 .fb_blank = nvidiafb_blank,
1370 .fb_fillrect = nvidiafb_fillrect,
1371 .fb_copyarea = nvidiafb_copyarea,
1372 .fb_imageblit = nvidiafb_imageblit,
1373 .fb_cursor = nvidiafb_cursor,
1374 .fb_sync = nvidiafb_sync,
1375};
1376
1377static int __devinit nvidia_set_fbinfo(struct fb_info *info)
1378{
1379 struct fb_monspecs *specs = &info->monspecs;
1380 struct fb_videomode modedb;
1381 struct nvidia_par *par = info->par;
1382 int lpitch;
1383
1384 NVTRACE_ENTER();
1385 info->flags = FBINFO_DEFAULT
1386 | FBINFO_HWACCEL_IMAGEBLIT
1387 | FBINFO_HWACCEL_FILLRECT
1388 | FBINFO_HWACCEL_COPYAREA
1389 | FBINFO_HWACCEL_YPAN;
1390
1391 fb_videomode_to_modelist(info->monspecs.modedb,
1392 info->monspecs.modedb_len, &info->modelist);
1393 fb_var_to_videomode(&modedb, &nvidiafb_default_var);
1394
1395 if (specs->modedb != NULL) {
Antonino A. Daplas5ee1ef92005-11-07 01:00:55 -08001396 struct fb_videomode *modedb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001397
Antonino A. Daplas5ee1ef92005-11-07 01:00:55 -08001398 modedb = fb_find_best_display(specs, &info->modelist);
1399 fb_videomode_to_var(&nvidiafb_default_var, modedb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001400 nvidiafb_default_var.bits_per_pixel = 8;
Antonino Daplasdb6778d2005-08-08 14:22:43 +08001401 } else if (par->fpWidth && par->fpHeight) {
1402 char buf[16];
1403
1404 memset(buf, 0, 16);
Antonino A. Daplas948a95f2005-09-09 13:09:59 -07001405 snprintf(buf, 15, "%dx%dMR", par->fpWidth, par->fpHeight);
Antonino Daplasdb6778d2005-08-08 14:22:43 +08001406 fb_find_mode(&nvidiafb_default_var, info, buf, specs->modedb,
1407 specs->modedb_len, &modedb, 8);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001408 }
1409
1410 if (mode_option)
1411 fb_find_mode(&nvidiafb_default_var, info, mode_option,
1412 specs->modedb, specs->modedb_len, &modedb, 8);
1413
1414 info->var = nvidiafb_default_var;
1415 info->fix.visual = (info->var.bits_per_pixel == 8) ?
1416 FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
1417 info->pseudo_palette = par->pseudo_palette;
1418 fb_alloc_cmap(&info->cmap, 256, 0);
1419 fb_destroy_modedb(info->monspecs.modedb);
1420 info->monspecs.modedb = NULL;
1421
1422 /* maximize virtual vertical length */
1423 lpitch = info->var.xres_virtual *
1424 ((info->var.bits_per_pixel + 7) >> 3);
Antonino A. Daplas917bb072005-05-01 08:59:22 -07001425 info->var.yres_virtual = info->screen_size / lpitch;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001426
1427 info->pixmap.scan_align = 4;
1428 info->pixmap.buf_align = 4;
James Simmons58a60642005-06-21 17:17:08 -07001429 info->pixmap.access_align = 32;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001430 info->pixmap.size = 8 * 1024;
1431 info->pixmap.flags = FB_PIXMAP_SYSTEM;
1432
Antonino A. Daplas7a482422005-09-21 07:30:21 +08001433 if (!hwcur)
Antonino A. Daplasc465e052005-11-07 01:00:35 -08001434 info->fbops->fb_cursor = NULL;
Antonino A. Daplas7a482422005-09-21 07:30:21 +08001435
Linus Torvalds1da177e2005-04-16 15:20:36 -07001436 info->var.accel_flags = (!noaccel);
1437
1438 switch (par->Architecture) {
1439 case NV_ARCH_04:
1440 info->fix.accel = FB_ACCEL_NV4;
1441 break;
1442 case NV_ARCH_10:
1443 info->fix.accel = FB_ACCEL_NV_10;
1444 break;
1445 case NV_ARCH_20:
1446 info->fix.accel = FB_ACCEL_NV_20;
1447 break;
1448 case NV_ARCH_30:
1449 info->fix.accel = FB_ACCEL_NV_30;
1450 break;
1451 case NV_ARCH_40:
1452 info->fix.accel = FB_ACCEL_NV_40;
1453 break;
1454 }
1455
1456 NVTRACE_LEAVE();
1457
1458 return nvidiafb_check_var(&info->var, info);
1459}
1460
Antonino A. Daplasc549dc62006-01-09 20:53:33 -08001461static u32 __devinit nvidia_get_chipset(struct fb_info *info)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001462{
Antonino A. Daplasc549dc62006-01-09 20:53:33 -08001463 struct nvidia_par *par = info->par;
1464 u32 id = (par->pci_dev->vendor << 16) | par->pci_dev->device;
1465
1466 printk("nvidiafb: PCI id - %x\n", id);
1467 if ((id & 0xfff0) == 0x00f0) {
1468 /* pci-e */
1469 printk("nvidiafb: PCI-E card\n");
1470 id = NV_RD32(par->REGS, 0x1800);
1471
1472 if ((id & 0x0000ffff) == 0x000010DE)
1473 id = 0x10DE0000 | (id >> 16);
1474 else if ((id & 0xffff0000) == 0xDE100000) /* wrong endian */
1475 id = 0x10DE0000 | ((id << 8) & 0x0000ff00) |
1476 ((id >> 8) & 0x000000ff);
1477 }
1478
1479 printk("nvidiafb: Actual id - %x\n", id);
1480 return id;
1481}
1482
1483static u32 __devinit nvidia_get_arch(struct fb_info *info)
1484{
1485 struct nvidia_par *par = info->par;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001486 u32 arch = 0;
1487
Antonino A. Daplasc549dc62006-01-09 20:53:33 -08001488 switch (par->Chipset & 0x0ff0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001489 case 0x0100: /* GeForce 256 */
1490 case 0x0110: /* GeForce2 MX */
1491 case 0x0150: /* GeForce2 */
1492 case 0x0170: /* GeForce4 MX */
1493 case 0x0180: /* GeForce4 MX (8x AGP) */
1494 case 0x01A0: /* nForce */
1495 case 0x01F0: /* nForce2 */
1496 arch = NV_ARCH_10;
1497 break;
1498 case 0x0200: /* GeForce3 */
1499 case 0x0250: /* GeForce4 Ti */
1500 case 0x0280: /* GeForce4 Ti (8x AGP) */
1501 arch = NV_ARCH_20;
1502 break;
1503 case 0x0300: /* GeForceFX 5800 */
1504 case 0x0310: /* GeForceFX 5600 */
1505 case 0x0320: /* GeForceFX 5200 */
1506 case 0x0330: /* GeForceFX 5900 */
1507 case 0x0340: /* GeForceFX 5700 */
1508 arch = NV_ARCH_30;
1509 break;
1510 case 0x0040:
1511 case 0x00C0:
1512 case 0x0120:
1513 case 0x0130:
1514 case 0x0140:
1515 case 0x0160:
1516 case 0x01D0:
1517 case 0x0090:
1518 case 0x0210:
1519 case 0x0220:
1520 case 0x0230:
Benjamin Herrenschmidt0137ecf2006-01-09 20:51:27 -08001521 case 0x0290:
1522 case 0x0390:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001523 arch = NV_ARCH_40;
1524 break;
1525 case 0x0020: /* TNT, TNT2 */
1526 arch = NV_ARCH_04;
1527 break;
1528 default: /* unknown architecture */
1529 break;
1530 }
1531
1532 return arch;
1533}
1534
1535static int __devinit nvidiafb_probe(struct pci_dev *pd,
1536 const struct pci_device_id *ent)
1537{
1538 struct nvidia_par *par;
1539 struct fb_info *info;
1540 unsigned short cmd;
1541
1542
1543 NVTRACE_ENTER();
1544 assert(pd != NULL);
1545
1546 info = framebuffer_alloc(sizeof(struct nvidia_par), &pd->dev);
1547
1548 if (!info)
1549 goto err_out;
1550
Antonino A. Daplasc439e342006-01-09 20:53:02 -08001551 par = info->par;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001552 par->pci_dev = pd;
1553
1554 info->pixmap.addr = kmalloc(8 * 1024, GFP_KERNEL);
1555
1556 if (info->pixmap.addr == NULL)
1557 goto err_out_kfree;
1558
1559 memset(info->pixmap.addr, 0, 8 * 1024);
1560
1561 if (pci_enable_device(pd)) {
1562 printk(KERN_ERR PFX "cannot enable PCI device\n");
1563 goto err_out_enable;
1564 }
1565
1566 if (pci_request_regions(pd, "nvidiafb")) {
1567 printk(KERN_ERR PFX "cannot request PCI regions\n");
1568 goto err_out_request;
1569 }
1570
Linus Torvalds1da177e2005-04-16 15:20:36 -07001571 par->FlatPanel = flatpanel;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001572 if (flatpanel == 1)
1573 printk(KERN_INFO PFX "flatpanel support enabled\n");
Benjamin Herrenschmidtb8c49ef2005-11-07 01:00:32 -08001574 par->FPDither = fpdither;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001575
1576 par->CRTCnumber = forceCRTC;
1577 par->FpScale = (!noscale);
1578 par->paneltweak = paneltweak;
1579
1580 /* enable IO and mem if not already done */
1581 pci_read_config_word(pd, PCI_COMMAND, &cmd);
1582 cmd |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
1583 pci_write_config_word(pd, PCI_COMMAND, cmd);
1584
1585 nvidiafb_fix.mmio_start = pci_resource_start(pd, 0);
1586 nvidiafb_fix.smem_start = pci_resource_start(pd, 1);
1587 nvidiafb_fix.mmio_len = pci_resource_len(pd, 0);
1588
1589 par->REGS = ioremap(nvidiafb_fix.mmio_start, nvidiafb_fix.mmio_len);
1590
1591 if (!par->REGS) {
1592 printk(KERN_ERR PFX "cannot ioremap MMIO base\n");
1593 goto err_out_free_base0;
1594 }
1595
Antonino A. Daplasc549dc62006-01-09 20:53:33 -08001596 par->Chipset = nvidia_get_chipset(info);
1597 printk(KERN_INFO PFX "nVidia device/chipset %X\n", par->Chipset);
1598 par->Architecture = nvidia_get_arch(info);
1599
1600 if (par->Architecture == 0) {
1601 printk(KERN_ERR PFX "unknown NV_ARCH\n");
1602 goto err_out_arch;
1603 }
1604
1605 sprintf(nvidiafb_fix.id, "NV%x", (pd->device & 0x0ff0) >> 4);
1606
Linus Torvalds1da177e2005-04-16 15:20:36 -07001607 NVCommonSetup(info);
1608
1609 par->FbAddress = nvidiafb_fix.smem_start;
1610 par->FbMapSize = par->RamAmountKBytes * 1024;
Antonino A. Daplas917bb072005-05-01 08:59:22 -07001611 if (vram && vram * 1024 * 1024 < par->FbMapSize)
1612 par->FbMapSize = vram * 1024 * 1024;
1613
1614 /* Limit amount of vram to 64 MB */
1615 if (par->FbMapSize > 64 * 1024 * 1024)
1616 par->FbMapSize = 64 * 1024 * 1024;
1617
Benjamin Herrenschmidt0137ecf2006-01-09 20:51:27 -08001618 if(par->Architecture >= NV_ARCH_40)
1619 par->FbUsableSize = par->FbMapSize - (560 * 1024);
1620 else
1621 par->FbUsableSize = par->FbMapSize - (128 * 1024);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001622 par->ScratchBufferSize = (par->Architecture < NV_ARCH_10) ? 8 * 1024 :
1623 16 * 1024;
1624 par->ScratchBufferStart = par->FbUsableSize - par->ScratchBufferSize;
Benjamin Herrenschmidt0137ecf2006-01-09 20:51:27 -08001625 par->CursorStart = par->FbUsableSize + (32 * 1024);
1626
Linus Torvalds1da177e2005-04-16 15:20:36 -07001627 info->screen_base = ioremap(nvidiafb_fix.smem_start, par->FbMapSize);
Antonino A. Daplas917bb072005-05-01 08:59:22 -07001628 info->screen_size = par->FbUsableSize;
1629 nvidiafb_fix.smem_len = par->RamAmountKBytes * 1024;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001630
1631 if (!info->screen_base) {
1632 printk(KERN_ERR PFX "cannot ioremap FB base\n");
1633 goto err_out_free_base1;
1634 }
1635
1636 par->FbStart = info->screen_base;
1637
1638#ifdef CONFIG_MTRR
1639 if (!nomtrr) {
1640 par->mtrr.vram = mtrr_add(nvidiafb_fix.smem_start,
Antonino A. Daplas917bb072005-05-01 08:59:22 -07001641 par->RamAmountKBytes * 1024,
1642 MTRR_TYPE_WRCOMB, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001643 if (par->mtrr.vram < 0) {
1644 printk(KERN_ERR PFX "unable to setup MTRR\n");
1645 } else {
1646 par->mtrr.vram_valid = 1;
1647 /* let there be speed */
1648 printk(KERN_INFO PFX "MTRR set to ON\n");
1649 }
1650 }
1651#endif /* CONFIG_MTRR */
1652
1653 info->fbops = &nvidia_fb_ops;
1654 info->fix = nvidiafb_fix;
1655
1656 if (nvidia_set_fbinfo(info) < 0) {
1657 printk(KERN_ERR PFX "error setting initial video mode\n");
1658 goto err_out_iounmap_fb;
1659 }
1660
1661 nvidia_save_vga(par, &par->SavedReg);
1662
1663 if (register_framebuffer(info) < 0) {
1664 printk(KERN_ERR PFX "error registering nVidia framebuffer\n");
1665 goto err_out_iounmap_fb;
1666 }
1667
1668 pci_set_drvdata(pd, info);
1669
1670 printk(KERN_INFO PFX
1671 "PCI nVidia %s framebuffer (%dMB @ 0x%lX)\n",
1672 info->fix.id,
1673 par->FbMapSize / (1024 * 1024), info->fix.smem_start);
1674#ifdef CONFIG_PMAC_BACKLIGHT
1675 if (par->FlatPanel && _machine == _MACH_Pmac)
1676 register_backlight_controller(&nvidia_backlight_controller,
1677 par, "mnca");
1678#endif
1679 NVTRACE_LEAVE();
1680 return 0;
1681
Antonino A. Daplasc549dc62006-01-09 20:53:33 -08001682err_out_iounmap_fb:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001683 iounmap(info->screen_base);
Antonino A. Daplasc549dc62006-01-09 20:53:33 -08001684err_out_free_base1:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001685 fb_destroy_modedb(info->monspecs.modedb);
1686 nvidia_delete_i2c_busses(par);
Antonino A. Daplasc549dc62006-01-09 20:53:33 -08001687err_out_arch:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001688 iounmap(par->REGS);
Antonino A. Daplasc549dc62006-01-09 20:53:33 -08001689err_out_free_base0:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001690 pci_release_regions(pd);
Antonino A. Daplasc549dc62006-01-09 20:53:33 -08001691err_out_request:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001692 pci_disable_device(pd);
Antonino A. Daplasc549dc62006-01-09 20:53:33 -08001693err_out_enable:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001694 kfree(info->pixmap.addr);
Antonino A. Daplasc549dc62006-01-09 20:53:33 -08001695err_out_kfree:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001696 framebuffer_release(info);
Antonino A. Daplasc549dc62006-01-09 20:53:33 -08001697err_out:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001698 return -ENODEV;
1699}
1700
1701static void __exit nvidiafb_remove(struct pci_dev *pd)
1702{
1703 struct fb_info *info = pci_get_drvdata(pd);
1704 struct nvidia_par *par = info->par;
1705
1706 NVTRACE_ENTER();
1707 if (!info)
1708 return;
1709
1710 unregister_framebuffer(info);
1711#ifdef CONFIG_MTRR
1712 if (par->mtrr.vram_valid)
1713 mtrr_del(par->mtrr.vram, info->fix.smem_start,
1714 info->fix.smem_len);
1715#endif /* CONFIG_MTRR */
1716
1717 iounmap(info->screen_base);
1718 fb_destroy_modedb(info->monspecs.modedb);
1719 nvidia_delete_i2c_busses(par);
1720 iounmap(par->REGS);
1721 pci_release_regions(pd);
1722 pci_disable_device(pd);
1723 kfree(info->pixmap.addr);
1724 framebuffer_release(info);
1725 pci_set_drvdata(pd, NULL);
1726 NVTRACE_LEAVE();
1727}
1728
1729/* ------------------------------------------------------------------------- *
1730 *
1731 * initialization
1732 *
1733 * ------------------------------------------------------------------------- */
1734
1735#ifndef MODULE
1736static int __devinit nvidiafb_setup(char *options)
1737{
1738 char *this_opt;
1739
1740 NVTRACE_ENTER();
1741 if (!options || !*options)
1742 return 0;
1743
1744 while ((this_opt = strsep(&options, ",")) != NULL) {
1745 if (!strncmp(this_opt, "forceCRTC", 9)) {
1746 char *p;
1747
1748 p = this_opt + 9;
1749 if (!*p || !*(++p))
1750 continue;
1751 forceCRTC = *p - '0';
1752 if (forceCRTC < 0 || forceCRTC > 1)
1753 forceCRTC = -1;
1754 } else if (!strncmp(this_opt, "flatpanel", 9)) {
1755 flatpanel = 1;
1756 } else if (!strncmp(this_opt, "hwcur", 5)) {
1757 hwcur = 1;
1758 } else if (!strncmp(this_opt, "noaccel", 6)) {
1759 noaccel = 1;
1760 } else if (!strncmp(this_opt, "noscale", 7)) {
1761 noscale = 1;
1762 } else if (!strncmp(this_opt, "paneltweak:", 11)) {
1763 paneltweak = simple_strtoul(this_opt+11, NULL, 0);
Antonino A. Daplas917bb072005-05-01 08:59:22 -07001764 } else if (!strncmp(this_opt, "vram:", 5)) {
1765 vram = simple_strtoul(this_opt+5, NULL, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001766#ifdef CONFIG_MTRR
1767 } else if (!strncmp(this_opt, "nomtrr", 6)) {
1768 nomtrr = 1;
1769#endif
Benjamin Herrenschmidtb8c49ef2005-11-07 01:00:32 -08001770 } else if (!strncmp(this_opt, "fpdither:", 9)) {
1771 fpdither = simple_strtol(this_opt+9, NULL, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001772 } else
1773 mode_option = this_opt;
1774 }
1775 NVTRACE_LEAVE();
1776 return 0;
1777}
1778#endif /* !MODULE */
1779
1780static struct pci_driver nvidiafb_driver = {
1781 .name = "nvidiafb",
1782 .id_table = nvidiafb_pci_tbl,
1783 .probe = nvidiafb_probe,
1784 .remove = __exit_p(nvidiafb_remove),
1785};
1786
1787/* ------------------------------------------------------------------------- *
1788 *
1789 * modularization
1790 *
1791 * ------------------------------------------------------------------------- */
1792
1793static int __devinit nvidiafb_init(void)
1794{
1795#ifndef MODULE
1796 char *option = NULL;
1797
1798 if (fb_get_options("nvidiafb", &option))
1799 return -ENODEV;
1800 nvidiafb_setup(option);
1801#endif
1802 return pci_register_driver(&nvidiafb_driver);
1803}
1804
1805module_init(nvidiafb_init);
1806
1807#ifdef MODULE
1808static void __exit nvidiafb_exit(void)
1809{
1810 pci_unregister_driver(&nvidiafb_driver);
1811}
1812
1813module_exit(nvidiafb_exit);
1814
1815module_param(flatpanel, int, 0);
1816MODULE_PARM_DESC(flatpanel,
1817 "Enables experimental flat panel support for some chipsets. "
Benjamin Herrenschmidtb8c49ef2005-11-07 01:00:32 -08001818 "(0=disabled, 1=enabled, -1=autodetect) (default=-1)");
1819module_param(fpdither, int, 0);
1820MODULE_PARM_DESC(fpdither,
1821 "Enables dithering of flat panel for 6 bits panels. "
1822 "(0=disabled, 1=enabled, -1=autodetect) (default=-1)");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001823module_param(hwcur, int, 0);
1824MODULE_PARM_DESC(hwcur,
1825 "Enables hardware cursor implementation. (0 or 1=enabled) "
1826 "(default=0)");
1827module_param(noaccel, int, 0);
1828MODULE_PARM_DESC(noaccel,
1829 "Disables hardware acceleration. (0 or 1=disable) "
1830 "(default=0)");
1831module_param(noscale, int, 0);
1832MODULE_PARM_DESC(noscale,
1833 "Disables screen scaleing. (0 or 1=disable) "
1834 "(default=0, do scaling)");
1835module_param(paneltweak, int, 0);
1836MODULE_PARM_DESC(paneltweak,
1837 "Tweak display settings for flatpanels. "
1838 "(default=0, no tweaks)");
1839module_param(forceCRTC, int, 0);
1840MODULE_PARM_DESC(forceCRTC,
1841 "Forces usage of a particular CRTC in case autodetection "
1842 "fails. (0 or 1) (default=autodetect)");
Antonino A. Daplas917bb072005-05-01 08:59:22 -07001843module_param(vram, int, 0);
1844MODULE_PARM_DESC(vram,
1845 "amount of framebuffer memory to remap in MiB"
1846 "(default=0 - remap entire memory)");
Antonino A. Daplasc439e342006-01-09 20:53:02 -08001847module_param(mode_option, charp, 0);
1848MODULE_PARM_DESC(mode_option, "Specify initial video mode");
1849
Linus Torvalds1da177e2005-04-16 15:20:36 -07001850#ifdef CONFIG_MTRR
1851module_param(nomtrr, bool, 0);
1852MODULE_PARM_DESC(nomtrr, "Disables MTRR support (0 or 1=disabled) "
1853 "(default=0)");
1854#endif
1855
1856MODULE_AUTHOR("Antonino Daplas");
1857MODULE_DESCRIPTION("Framebuffer driver for nVidia graphics chipset");
1858MODULE_LICENSE("GPL");
1859#endif /* MODULE */
1860