blob: dbcb8962e57dd790e9bf9e0dafc2363e805e7007 [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;
Antonino A. Daplasade91852006-01-09 20:53:39 -0800431static int bpp __devinitdata = 8;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700432#ifdef CONFIG_MTRR
433static int nomtrr __devinitdata = 0;
434#endif
435
436static char *mode_option __devinitdata = NULL;
437
438static struct fb_fix_screeninfo __devinitdata nvidiafb_fix = {
439 .type = FB_TYPE_PACKED_PIXELS,
440 .xpanstep = 8,
441 .ypanstep = 1,
442};
443
444static struct fb_var_screeninfo __devinitdata nvidiafb_default_var = {
445 .xres = 640,
446 .yres = 480,
447 .xres_virtual = 640,
448 .yres_virtual = 480,
449 .bits_per_pixel = 8,
450 .red = {0, 8, 0},
451 .green = {0, 8, 0},
452 .blue = {0, 8, 0},
453 .transp = {0, 0, 0},
454 .activate = FB_ACTIVATE_NOW,
455 .height = -1,
456 .width = -1,
457 .pixclock = 39721,
458 .left_margin = 40,
459 .right_margin = 24,
460 .upper_margin = 32,
461 .lower_margin = 11,
462 .hsync_len = 96,
463 .vsync_len = 2,
464 .vmode = FB_VMODE_NONINTERLACED
465};
466
467/*
468 * Backlight control
469 */
470#ifdef CONFIG_PMAC_BACKLIGHT
471
472static int nvidia_backlight_levels[] = {
473 0x158,
474 0x192,
475 0x1c6,
476 0x200,
477 0x234,
478 0x268,
479 0x2a2,
480 0x2d6,
481 0x310,
482 0x344,
483 0x378,
484 0x3b2,
485 0x3e6,
486 0x41a,
487 0x454,
488 0x534,
489};
490
491/* ------------------------------------------------------------------------- *
492 *
493 * Backlight operations
494 *
495 * ------------------------------------------------------------------------- */
496
497static int nvidia_set_backlight_enable(int on, int level, void *data)
498{
Antonino A. Daplasc439e342006-01-09 20:53:02 -0800499 struct nvidia_par *par = data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700500 u32 tmp_pcrt, tmp_pmc, fpcontrol;
501
502 tmp_pmc = NV_RD32(par->PMC, 0x10F0) & 0x0000FFFF;
503 tmp_pcrt = NV_RD32(par->PCRTC0, 0x081C) & 0xFFFFFFFC;
504 fpcontrol = NV_RD32(par->PRAMDAC, 0x0848) & 0xCFFFFFCC;
505
506 if (on && (level > BACKLIGHT_OFF)) {
507 tmp_pcrt |= 0x1;
508 tmp_pmc |= (1 << 31); // backlight bit
509 tmp_pmc |= nvidia_backlight_levels[level - 1] << 16;
510 }
511
512 if (on)
513 fpcontrol |= par->fpSyncs;
514 else
515 fpcontrol |= 0x20000022;
516
517 NV_WR32(par->PCRTC0, 0x081C, tmp_pcrt);
518 NV_WR32(par->PMC, 0x10F0, tmp_pmc);
519 NV_WR32(par->PRAMDAC, 0x848, fpcontrol);
520
521 return 0;
522}
523
524static int nvidia_set_backlight_level(int level, void *data)
525{
526 return nvidia_set_backlight_enable(1, level, data);
527}
528
529static struct backlight_controller nvidia_backlight_controller = {
530 nvidia_set_backlight_enable,
531 nvidia_set_backlight_level
532};
533
534#endif /* CONFIG_PMAC_BACKLIGHT */
535
536static void nvidiafb_load_cursor_image(struct nvidia_par *par, u8 * data8,
537 u16 bg, u16 fg, u32 w, u32 h)
538{
James Simmonsf1ab5da2005-06-21 17:17:07 -0700539 u32 *data = (u32 *) data8;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700540 int i, j, k = 0;
541 u32 b, tmp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700542
543 w = (w + 1) & ~1;
544
545 for (i = 0; i < h; i++) {
546 b = *data++;
547 reverse_order(&b);
548
549 for (j = 0; j < w / 2; j++) {
550 tmp = 0;
551#if defined (__BIG_ENDIAN)
552 tmp = (b & (1 << 31)) ? fg << 16 : bg << 16;
553 b <<= 1;
554 tmp |= (b & (1 << 31)) ? fg : bg;
555 b <<= 1;
556#else
557 tmp = (b & 1) ? fg : bg;
558 b >>= 1;
559 tmp |= (b & 1) ? fg << 16 : bg << 16;
560 b >>= 1;
561#endif
562 NV_WR32(&par->CURSOR[k++], 0, tmp);
563 }
564 k += (MAX_CURS - w) / 2;
565 }
566}
567
568static void nvidia_write_clut(struct nvidia_par *par,
569 u8 regnum, u8 red, u8 green, u8 blue)
570{
571 NVWriteDacMask(par, 0xff);
572 NVWriteDacWriteAddr(par, regnum);
573 NVWriteDacData(par, red);
574 NVWriteDacData(par, green);
575 NVWriteDacData(par, blue);
576}
577
578static void nvidia_read_clut(struct nvidia_par *par,
579 u8 regnum, u8 * red, u8 * green, u8 * blue)
580{
581 NVWriteDacMask(par, 0xff);
582 NVWriteDacReadAddr(par, regnum);
583 *red = NVReadDacData(par);
584 *green = NVReadDacData(par);
585 *blue = NVReadDacData(par);
586}
587
588static int nvidia_panel_tweak(struct nvidia_par *par,
589 struct _riva_hw_state *state)
590{
591 int tweak = 0;
592
593 if (par->paneltweak) {
594 tweak = par->paneltweak;
595 } else {
596 /* begin flat panel hacks */
597 /* This is unfortunate, but some chips need this register
598 tweaked or else you get artifacts where adjacent pixels are
599 swapped. There are no hard rules for what to set here so all
600 we can do is experiment and apply hacks. */
601
602 if(((par->Chipset & 0xffff) == 0x0328) && (state->bpp == 32)) {
603 /* At least one NV34 laptop needs this workaround. */
604 tweak = -1;
605 }
606
607 if((par->Chipset & 0xfff0) == 0x0310) {
608 tweak = 1;
609 }
610 /* end flat panel hacks */
611 }
612
613 return tweak;
614}
615
616static void nvidia_save_vga(struct nvidia_par *par,
617 struct _riva_hw_state *state)
618{
619 int i;
620
621 NVTRACE_ENTER();
622 NVLockUnlock(par, 0);
623
624 NVUnloadStateExt(par, state);
625
626 state->misc_output = NVReadMiscOut(par);
627
628 for (i = 0; i < NUM_CRT_REGS; i++)
629 state->crtc[i] = NVReadCrtc(par, i);
630
631 for (i = 0; i < NUM_ATC_REGS; i++)
632 state->attr[i] = NVReadAttr(par, i);
633
634 for (i = 0; i < NUM_GRC_REGS; i++)
635 state->gra[i] = NVReadGr(par, i);
636
637 for (i = 0; i < NUM_SEQ_REGS; i++)
638 state->seq[i] = NVReadSeq(par, i);
639 NVTRACE_LEAVE();
640}
641
Benjamin Herrenschmidt85f15032005-11-07 01:00:30 -0800642#undef DUMP_REG
643
Linus Torvalds1da177e2005-04-16 15:20:36 -0700644static void nvidia_write_regs(struct nvidia_par *par)
645{
646 struct _riva_hw_state *state = &par->ModeReg;
647 int i;
648
649 NVTRACE_ENTER();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700650
651 NVLoadStateExt(par, state);
652
653 NVWriteMiscOut(par, state->misc_output);
654
Benjamin Herrenschmidt85f15032005-11-07 01:00:30 -0800655 for (i = 1; i < NUM_SEQ_REGS; i++) {
656#ifdef DUMP_REG
657 printk(" SEQ[%02x] = %08x\n", i, state->seq[i]);
658#endif
659 NVWriteSeq(par, i, state->seq[i]);
660 }
661
662 /* Ensure CRTC registers 0-7 are unlocked by clearing bit 7 of CRTC[17] */
663 NVWriteCrtc(par, 0x11, state->crtc[0x11] & ~0x80);
664
Linus Torvalds1da177e2005-04-16 15:20:36 -0700665 for (i = 0; i < NUM_CRT_REGS; i++) {
666 switch (i) {
667 case 0x19:
668 case 0x20 ... 0x40:
669 break;
670 default:
Benjamin Herrenschmidt85f15032005-11-07 01:00:30 -0800671#ifdef DUMP_REG
672 printk("CRTC[%02x] = %08x\n", i, state->crtc[i]);
673#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700674 NVWriteCrtc(par, i, state->crtc[i]);
675 }
676 }
677
Benjamin Herrenschmidt85f15032005-11-07 01:00:30 -0800678 for (i = 0; i < NUM_GRC_REGS; i++) {
679#ifdef DUMP_REG
680 printk(" GRA[%02x] = %08x\n", i, state->gra[i]);
681#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700682 NVWriteGr(par, i, state->gra[i]);
Benjamin Herrenschmidt85f15032005-11-07 01:00:30 -0800683 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700684
Benjamin Herrenschmidt85f15032005-11-07 01:00:30 -0800685 for (i = 0; i < NUM_ATC_REGS; i++) {
686#ifdef DUMP_REG
687 printk("ATTR[%02x] = %08x\n", i, state->attr[i]);
688#endif
689 NVWriteAttr(par, i, state->attr[i]);
690 }
691
Linus Torvalds1da177e2005-04-16 15:20:36 -0700692 NVTRACE_LEAVE();
693}
694
Benjamin Herrenschmidt85f15032005-11-07 01:00:30 -0800695static void nvidia_vga_protect(struct nvidia_par *par, int on)
696{
697 unsigned char tmp;
698
699 if (on) {
700 /*
701 * Turn off screen and disable sequencer.
702 */
703 tmp = NVReadSeq(par, 0x01);
704
705 NVWriteSeq(par, 0x00, 0x01); /* Synchronous Reset */
706 NVWriteSeq(par, 0x01, tmp | 0x20); /* disable the display */
707 } else {
708 /*
709 * Reenable sequencer, then turn on screen.
710 */
711
712 tmp = NVReadSeq(par, 0x01);
713
714 NVWriteSeq(par, 0x01, tmp & ~0x20); /* reenable display */
715 NVWriteSeq(par, 0x00, 0x03); /* End Reset */
716 }
717}
718
719
720
Linus Torvalds1da177e2005-04-16 15:20:36 -0700721static int nvidia_calc_regs(struct fb_info *info)
722{
723 struct nvidia_par *par = info->par;
724 struct _riva_hw_state *state = &par->ModeReg;
Antonino A. Daplasb8c90942005-09-09 13:04:37 -0700725 int i, depth = fb_get_color_depth(&info->var, &info->fix);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700726 int h_display = info->var.xres / 8 - 1;
727 int h_start = (info->var.xres + info->var.right_margin) / 8 - 1;
728 int h_end = (info->var.xres + info->var.right_margin +
729 info->var.hsync_len) / 8 - 1;
730 int h_total = (info->var.xres + info->var.right_margin +
731 info->var.hsync_len + info->var.left_margin) / 8 - 5;
732 int h_blank_s = h_display;
733 int h_blank_e = h_total + 4;
734 int v_display = info->var.yres - 1;
735 int v_start = info->var.yres + info->var.lower_margin - 1;
736 int v_end = (info->var.yres + info->var.lower_margin +
737 info->var.vsync_len) - 1;
738 int v_total = (info->var.yres + info->var.lower_margin +
739 info->var.vsync_len + info->var.upper_margin) - 2;
740 int v_blank_s = v_display;
741 int v_blank_e = v_total + 1;
742
743 /*
744 * Set all CRTC values.
745 */
746
747 if (info->var.vmode & FB_VMODE_INTERLACED)
748 v_total |= 1;
749
750 if (par->FlatPanel == 1) {
751 v_start = v_total - 3;
752 v_end = v_total - 2;
753 v_blank_s = v_start;
754 h_start = h_total - 5;
755 h_end = h_total - 2;
756 h_blank_e = h_total + 4;
757 }
758
759 state->crtc[0x0] = Set8Bits(h_total);
760 state->crtc[0x1] = Set8Bits(h_display);
761 state->crtc[0x2] = Set8Bits(h_blank_s);
762 state->crtc[0x3] = SetBitField(h_blank_e, 4: 0, 4:0)
763 | SetBit(7);
764 state->crtc[0x4] = Set8Bits(h_start);
765 state->crtc[0x5] = SetBitField(h_blank_e, 5: 5, 7:7)
766 | SetBitField(h_end, 4: 0, 4:0);
767 state->crtc[0x6] = SetBitField(v_total, 7: 0, 7:0);
768 state->crtc[0x7] = SetBitField(v_total, 8: 8, 0:0)
769 | SetBitField(v_display, 8: 8, 1:1)
770 | SetBitField(v_start, 8: 8, 2:2)
771 | SetBitField(v_blank_s, 8: 8, 3:3)
772 | SetBit(4)
773 | SetBitField(v_total, 9: 9, 5:5)
774 | SetBitField(v_display, 9: 9, 6:6)
775 | SetBitField(v_start, 9: 9, 7:7);
776 state->crtc[0x9] = SetBitField(v_blank_s, 9: 9, 5:5)
777 | SetBit(6)
778 | ((info->var.vmode & FB_VMODE_DOUBLE) ? 0x80 : 0x00);
779 state->crtc[0x10] = Set8Bits(v_start);
780 state->crtc[0x11] = SetBitField(v_end, 3: 0, 3:0) | SetBit(5);
781 state->crtc[0x12] = Set8Bits(v_display);
782 state->crtc[0x13] = ((info->var.xres_virtual / 8) *
783 (info->var.bits_per_pixel / 8));
784 state->crtc[0x15] = Set8Bits(v_blank_s);
785 state->crtc[0x16] = Set8Bits(v_blank_e);
786
787 state->attr[0x10] = 0x01;
788
789 if (par->Television)
790 state->attr[0x11] = 0x00;
791
792 state->screen = SetBitField(h_blank_e, 6: 6, 4:4)
793 | SetBitField(v_blank_s, 10: 10, 3:3)
794 | SetBitField(v_start, 10: 10, 2:2)
795 | SetBitField(v_display, 10: 10, 1:1)
796 | SetBitField(v_total, 10: 10, 0:0);
797
798 state->horiz = SetBitField(h_total, 8: 8, 0:0)
799 | SetBitField(h_display, 8: 8, 1:1)
800 | SetBitField(h_blank_s, 8: 8, 2:2)
801 | SetBitField(h_start, 8: 8, 3:3);
802
803 state->extra = SetBitField(v_total, 11: 11, 0:0)
804 | SetBitField(v_display, 11: 11, 2:2)
805 | SetBitField(v_start, 11: 11, 4:4)
806 | SetBitField(v_blank_s, 11: 11, 6:6);
807
808 if (info->var.vmode & FB_VMODE_INTERLACED) {
809 h_total = (h_total >> 1) & ~1;
810 state->interlace = Set8Bits(h_total);
811 state->horiz |= SetBitField(h_total, 8: 8, 4:4);
812 } else {
813 state->interlace = 0xff; /* interlace off */
814 }
815
816 /*
817 * Calculate the extended registers.
818 */
819
820 if (depth < 24)
821 i = depth;
822 else
823 i = 32;
824
825 if (par->Architecture >= NV_ARCH_10)
826 par->CURSOR = (volatile u32 __iomem *)(info->screen_base +
827 par->CursorStart);
828
829 if (info->var.sync & FB_SYNC_HOR_HIGH_ACT)
830 state->misc_output &= ~0x40;
831 else
832 state->misc_output |= 0x40;
833 if (info->var.sync & FB_SYNC_VERT_HIGH_ACT)
834 state->misc_output &= ~0x80;
835 else
836 state->misc_output |= 0x80;
837
838 NVCalcStateExt(par, state, i, info->var.xres_virtual,
839 info->var.xres, info->var.yres_virtual,
840 1000000000 / info->var.pixclock, info->var.vmode);
841
842 state->scale = NV_RD32(par->PRAMDAC, 0x00000848) & 0xfff000ff;
843 if (par->FlatPanel == 1) {
844 state->pixel |= (1 << 7);
845
846 if (!par->fpScaler || (par->fpWidth <= info->var.xres)
847 || (par->fpHeight <= info->var.yres)) {
848 state->scale |= (1 << 8);
849 }
850
851 if (!par->crtcSync_read) {
852 state->crtcSync = NV_RD32(par->PRAMDAC, 0x0828);
853 par->crtcSync_read = 1;
854 }
855
856 par->PanelTweak = nvidia_panel_tweak(par, state);
857 }
858
859 state->vpll = state->pll;
860 state->vpll2 = state->pll;
861 state->vpllB = state->pllB;
862 state->vpll2B = state->pllB;
863
864 VGA_WR08(par->PCIO, 0x03D4, 0x1C);
865 state->fifo = VGA_RD08(par->PCIO, 0x03D5) & ~(1<<5);
866
867 if (par->CRTCnumber) {
868 state->head = NV_RD32(par->PCRTC0, 0x00000860) & ~0x00001000;
869 state->head2 = NV_RD32(par->PCRTC0, 0x00002860) | 0x00001000;
870 state->crtcOwner = 3;
871 state->pllsel |= 0x20000800;
872 state->vpll = NV_RD32(par->PRAMDAC0, 0x00000508);
873 if (par->twoStagePLL)
874 state->vpllB = NV_RD32(par->PRAMDAC0, 0x00000578);
875 } else if (par->twoHeads) {
876 state->head = NV_RD32(par->PCRTC0, 0x00000860) | 0x00001000;
877 state->head2 = NV_RD32(par->PCRTC0, 0x00002860) & ~0x00001000;
878 state->crtcOwner = 0;
879 state->vpll2 = NV_RD32(par->PRAMDAC0, 0x0520);
880 if (par->twoStagePLL)
881 state->vpll2B = NV_RD32(par->PRAMDAC0, 0x057C);
882 }
883
884 state->cursorConfig = 0x00000100;
885
886 if (info->var.vmode & FB_VMODE_DOUBLE)
887 state->cursorConfig |= (1 << 4);
888
889 if (par->alphaCursor) {
890 if ((par->Chipset & 0x0ff0) != 0x0110)
891 state->cursorConfig |= 0x04011000;
892 else
893 state->cursorConfig |= 0x14011000;
894 state->general |= (1 << 29);
895 } else
896 state->cursorConfig |= 0x02000000;
897
898 if (par->twoHeads) {
899 if ((par->Chipset & 0x0ff0) == 0x0110) {
900 state->dither = NV_RD32(par->PRAMDAC, 0x0528) &
901 ~0x00010000;
902 if (par->FPDither)
903 state->dither |= 0x00010000;
904 } else {
905 state->dither = NV_RD32(par->PRAMDAC, 0x083C) & ~1;
906 if (par->FPDither)
907 state->dither |= 1;
908 }
909 }
910
911 state->timingH = 0;
912 state->timingV = 0;
913 state->displayV = info->var.xres;
914
915 return 0;
916}
917
918static void nvidia_init_vga(struct fb_info *info)
919{
920 struct nvidia_par *par = info->par;
921 struct _riva_hw_state *state = &par->ModeReg;
922 int i;
923
924 for (i = 0; i < 0x10; i++)
925 state->attr[i] = i;
926 state->attr[0x10] = 0x41;
Benjamin Herrenschmidt85f15032005-11-07 01:00:30 -0800927 state->attr[0x11] = 0xff;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700928 state->attr[0x12] = 0x0f;
929 state->attr[0x13] = 0x00;
930 state->attr[0x14] = 0x00;
931
932 memset(state->crtc, 0x00, NUM_CRT_REGS);
933 state->crtc[0x0a] = 0x20;
934 state->crtc[0x17] = 0xe3;
935 state->crtc[0x18] = 0xff;
936 state->crtc[0x28] = 0x40;
937
938 memset(state->gra, 0x00, NUM_GRC_REGS);
939 state->gra[0x05] = 0x40;
940 state->gra[0x06] = 0x05;
941 state->gra[0x07] = 0x0f;
942 state->gra[0x08] = 0xff;
943
944 state->seq[0x00] = 0x03;
945 state->seq[0x01] = 0x01;
946 state->seq[0x02] = 0x0f;
947 state->seq[0x03] = 0x00;
948 state->seq[0x04] = 0x0e;
949
950 state->misc_output = 0xeb;
951}
952
953static int nvidiafb_cursor(struct fb_info *info, struct fb_cursor *cursor)
954{
955 struct nvidia_par *par = info->par;
956 u8 data[MAX_CURS * MAX_CURS / 8];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700957 int i, set = cursor->set;
James Simmonsf1ab5da2005-06-21 17:17:07 -0700958 u16 fg, bg;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700959
Antonino A. Daplas7a482422005-09-21 07:30:21 +0800960 if (cursor->image.width > MAX_CURS || cursor->image.height > MAX_CURS)
James Simmonsf1ab5da2005-06-21 17:17:07 -0700961 return -ENXIO;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700962
963 NVShowHideCursor(par, 0);
964
965 if (par->cursor_reset) {
966 set = FB_CUR_SETALL;
967 par->cursor_reset = 0;
968 }
969
970 if (set & FB_CUR_SETSIZE)
971 memset_io(par->CURSOR, 0, MAX_CURS * MAX_CURS * 2);
972
973 if (set & FB_CUR_SETPOS) {
974 u32 xx, yy, temp;
975
976 yy = cursor->image.dy - info->var.yoffset;
977 xx = cursor->image.dx - info->var.xoffset;
978 temp = xx & 0xFFFF;
979 temp |= yy << 16;
980
981 NV_WR32(par->PRAMDAC, 0x0000300, temp);
982 }
983
984 if (set & (FB_CUR_SETSHAPE | FB_CUR_SETCMAP | FB_CUR_SETIMAGE)) {
985 u32 bg_idx = cursor->image.bg_color;
986 u32 fg_idx = cursor->image.fg_color;
987 u32 s_pitch = (cursor->image.width + 7) >> 3;
988 u32 d_pitch = MAX_CURS / 8;
989 u8 *dat = (u8 *) cursor->image.data;
990 u8 *msk = (u8 *) cursor->mask;
991 u8 *src;
992
993 src = kmalloc(s_pitch * cursor->image.height, GFP_ATOMIC);
994
995 if (src) {
996 switch (cursor->rop) {
997 case ROP_XOR:
James Simmonsf1ab5da2005-06-21 17:17:07 -0700998 for (i = 0; i < s_pitch * cursor->image.height; i++)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700999 src[i] = dat[i] ^ msk[i];
1000 break;
1001 case ROP_COPY:
1002 default:
James Simmonsf1ab5da2005-06-21 17:17:07 -07001003 for (i = 0; i < s_pitch * cursor->image.height; i++)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001004 src[i] = dat[i] & msk[i];
1005 break;
1006 }
1007
James Simmonsf1ab5da2005-06-21 17:17:07 -07001008 fb_pad_aligned_buffer(data, d_pitch, src, s_pitch,
1009 cursor->image.height);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001010
1011 bg = ((info->cmap.red[bg_idx] & 0xf8) << 7) |
1012 ((info->cmap.green[bg_idx] & 0xf8) << 2) |
1013 ((info->cmap.blue[bg_idx] & 0xf8) >> 3) | 1 << 15;
1014
1015 fg = ((info->cmap.red[fg_idx] & 0xf8) << 7) |
1016 ((info->cmap.green[fg_idx] & 0xf8) << 2) |
1017 ((info->cmap.blue[fg_idx] & 0xf8) >> 3) | 1 << 15;
1018
1019 NVLockUnlock(par, 0);
1020
1021 nvidiafb_load_cursor_image(par, data, bg, fg,
1022 cursor->image.width,
1023 cursor->image.height);
1024 kfree(src);
1025 }
1026 }
1027
1028 if (cursor->enable)
1029 NVShowHideCursor(par, 1);
1030
1031 return 0;
1032}
1033
1034static int nvidiafb_set_par(struct fb_info *info)
1035{
1036 struct nvidia_par *par = info->par;
1037
1038 NVTRACE_ENTER();
1039
1040 NVLockUnlock(par, 1);
Benjamin Herrenschmidtb8c49ef2005-11-07 01:00:32 -08001041 if (!par->FlatPanel || !par->twoHeads)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001042 par->FPDither = 0;
1043
Benjamin Herrenschmidtb8c49ef2005-11-07 01:00:32 -08001044 if (par->FPDither < 0) {
1045 if ((par->Chipset & 0x0ff0) == 0x0110)
1046 par->FPDither = !!(NV_RD32(par->PRAMDAC, 0x0528)
1047 & 0x00010000);
1048 else
1049 par->FPDither = !!(NV_RD32(par->PRAMDAC, 0x083C) & 1);
1050 printk(KERN_INFO PFX "Flat panel dithering %s\n",
1051 par->FPDither ? "enabled" : "disabled");
1052 }
1053
Antonino A. Daplasb8c90942005-09-09 13:04:37 -07001054 info->fix.visual = (info->var.bits_per_pixel == 8) ?
1055 FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
1056
Linus Torvalds1da177e2005-04-16 15:20:36 -07001057 nvidia_init_vga(info);
1058 nvidia_calc_regs(info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001059
1060 NVLockUnlock(par, 0);
1061 if (par->twoHeads) {
1062 VGA_WR08(par->PCIO, 0x03D4, 0x44);
1063 VGA_WR08(par->PCIO, 0x03D5, par->ModeReg.crtcOwner);
1064 NVLockUnlock(par, 0);
1065 }
1066
Benjamin Herrenschmidt85f15032005-11-07 01:00:30 -08001067 nvidia_vga_protect(par, 1);
1068
1069 nvidia_write_regs(par);
1070
1071#if defined (__BIG_ENDIAN)
1072 /* turn on LFB swapping */
1073 {
1074 unsigned char tmp;
1075
1076 VGA_WR08(par->PCIO, 0x3d4, 0x46);
1077 tmp = VGA_RD08(par->PCIO, 0x3d5);
1078 tmp |= (1 << 7);
1079 VGA_WR08(par->PCIO, 0x3d5, tmp);
1080 }
1081#endif
1082
Linus Torvalds1da177e2005-04-16 15:20:36 -07001083 info->fix.line_length = (info->var.xres_virtual *
1084 info->var.bits_per_pixel) >> 3;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001085 if (info->var.accel_flags) {
1086 info->fbops->fb_imageblit = nvidiafb_imageblit;
1087 info->fbops->fb_fillrect = nvidiafb_fillrect;
1088 info->fbops->fb_copyarea = nvidiafb_copyarea;
1089 info->fbops->fb_sync = nvidiafb_sync;
1090 info->pixmap.scan_align = 4;
1091 info->flags &= ~FBINFO_HWACCEL_DISABLED;
1092 NVResetGraphics(info);
1093 } else {
1094 info->fbops->fb_imageblit = cfb_imageblit;
1095 info->fbops->fb_fillrect = cfb_fillrect;
1096 info->fbops->fb_copyarea = cfb_copyarea;
1097 info->fbops->fb_sync = NULL;
1098 info->pixmap.scan_align = 1;
1099 info->flags |= FBINFO_HWACCEL_DISABLED;
1100 }
1101
1102 par->cursor_reset = 1;
1103
Benjamin Herrenschmidt85f15032005-11-07 01:00:30 -08001104 nvidia_vga_protect(par, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001105
1106 NVTRACE_LEAVE();
1107 return 0;
1108}
1109
1110static int nvidiafb_setcolreg(unsigned regno, unsigned red, unsigned green,
1111 unsigned blue, unsigned transp,
1112 struct fb_info *info)
1113{
1114 struct nvidia_par *par = info->par;
1115 int i;
1116
1117 NVTRACE_ENTER();
1118 if (regno >= (1 << info->var.green.length))
1119 return -EINVAL;
1120
1121 if (info->var.grayscale) {
1122 /* gray = 0.30*R + 0.59*G + 0.11*B */
1123 red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8;
1124 }
1125
1126 if (regno < 16 && info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
1127 ((u32 *) info->pseudo_palette)[regno] =
1128 (regno << info->var.red.offset) |
1129 (regno << info->var.green.offset) |
1130 (regno << info->var.blue.offset);
1131 }
1132
1133 switch (info->var.bits_per_pixel) {
1134 case 8:
1135 /* "transparent" stuff is completely ignored. */
1136 nvidia_write_clut(par, regno, red >> 8, green >> 8, blue >> 8);
1137 break;
1138 case 16:
1139 if (info->var.green.length == 5) {
1140 for (i = 0; i < 8; i++) {
1141 nvidia_write_clut(par, regno * 8 + i, red >> 8,
1142 green >> 8, blue >> 8);
1143 }
1144 } else {
1145 u8 r, g, b;
1146
1147 if (regno < 32) {
1148 for (i = 0; i < 8; i++) {
1149 nvidia_write_clut(par, regno * 8 + i,
1150 red >> 8, green >> 8,
1151 blue >> 8);
1152 }
1153 }
1154
1155 nvidia_read_clut(par, regno * 4, &r, &g, &b);
1156
1157 for (i = 0; i < 4; i++)
1158 nvidia_write_clut(par, regno * 4 + i, r,
1159 green >> 8, b);
1160 }
1161 break;
1162 case 32:
1163 nvidia_write_clut(par, regno, red >> 8, green >> 8, blue >> 8);
1164 break;
1165 default:
1166 /* do nothing */
1167 break;
1168 }
1169
1170 NVTRACE_LEAVE();
1171 return 0;
1172}
1173
1174static int nvidiafb_check_var(struct fb_var_screeninfo *var,
1175 struct fb_info *info)
1176{
1177 struct nvidia_par *par = info->par;
1178 int memlen, vramlen, mode_valid = 0;
1179 int pitch, err = 0;
1180
1181 NVTRACE_ENTER();
1182
1183 var->transp.offset = 0;
1184 var->transp.length = 0;
1185
1186 var->xres &= ~7;
1187
1188 if (var->bits_per_pixel <= 8)
1189 var->bits_per_pixel = 8;
1190 else if (var->bits_per_pixel <= 16)
1191 var->bits_per_pixel = 16;
1192 else
1193 var->bits_per_pixel = 32;
1194
1195 switch (var->bits_per_pixel) {
1196 case 8:
1197 var->red.offset = 0;
1198 var->red.length = 8;
1199 var->green.offset = 0;
1200 var->green.length = 8;
1201 var->blue.offset = 0;
1202 var->blue.length = 8;
1203 var->transp.offset = 0;
1204 var->transp.length = 0;
1205 break;
1206 case 16:
1207 var->green.length = (var->green.length < 6) ? 5 : 6;
1208 var->red.length = 5;
1209 var->blue.length = 5;
1210 var->transp.length = 6 - var->green.length;
1211 var->blue.offset = 0;
1212 var->green.offset = 5;
1213 var->red.offset = 5 + var->green.length;
1214 var->transp.offset = (5 + var->red.offset) & 15;
1215 break;
1216 case 32: /* RGBA 8888 */
1217 var->red.offset = 16;
1218 var->red.length = 8;
1219 var->green.offset = 8;
1220 var->green.length = 8;
1221 var->blue.offset = 0;
1222 var->blue.length = 8;
1223 var->transp.length = 8;
1224 var->transp.offset = 24;
1225 break;
1226 }
1227
1228 var->red.msb_right = 0;
1229 var->green.msb_right = 0;
1230 var->blue.msb_right = 0;
1231 var->transp.msb_right = 0;
1232
1233 if (!info->monspecs.hfmax || !info->monspecs.vfmax ||
1234 !info->monspecs.dclkmax || !fb_validate_mode(var, info))
1235 mode_valid = 1;
1236
1237 /* calculate modeline if supported by monitor */
1238 if (!mode_valid && info->monspecs.gtf) {
1239 if (!fb_get_mode(FB_MAXTIMINGS, 0, var, info))
1240 mode_valid = 1;
1241 }
1242
1243 if (!mode_valid) {
1244 struct fb_videomode *mode;
1245
1246 mode = fb_find_best_mode(var, &info->modelist);
1247 if (mode) {
1248 fb_videomode_to_var(var, mode);
1249 mode_valid = 1;
1250 }
1251 }
1252
1253 if (!mode_valid && info->monspecs.modedb_len)
1254 return -EINVAL;
1255
1256 if (par->fpWidth && par->fpHeight && (par->fpWidth < var->xres ||
1257 par->fpHeight < var->yres))
1258 return -EINVAL;
1259
1260 if (var->yres_virtual < var->yres)
1261 var->yres_virtual = var->yres;
1262
1263 if (var->xres_virtual < var->xres)
1264 var->xres_virtual = var->xres;
1265
1266 var->xres_virtual = (var->xres_virtual + 63) & ~63;
1267
Antonino A. Daplas917bb072005-05-01 08:59:22 -07001268 vramlen = info->screen_size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001269 pitch = ((var->xres_virtual * var->bits_per_pixel) + 7) / 8;
1270 memlen = pitch * var->yres_virtual;
1271
1272 if (memlen > vramlen) {
1273 var->yres_virtual = vramlen / pitch;
1274
1275 if (var->yres_virtual < var->yres) {
1276 var->yres_virtual = var->yres;
1277 var->xres_virtual = vramlen / var->yres_virtual;
1278 var->xres_virtual /= var->bits_per_pixel / 8;
1279 var->xres_virtual &= ~63;
1280 pitch = (var->xres_virtual *
1281 var->bits_per_pixel + 7) / 8;
1282 memlen = pitch * var->yres;
1283
1284 if (var->xres_virtual < var->xres) {
1285 printk("nvidiafb: required video memory, "
1286 "%d bytes, for %dx%d-%d (virtual) "
1287 "is out of range\n",
1288 memlen, var->xres_virtual,
1289 var->yres_virtual, var->bits_per_pixel);
1290 err = -ENOMEM;
1291 }
1292 }
1293 }
1294
1295 if (var->accel_flags) {
1296 if (var->yres_virtual > 0x7fff)
1297 var->yres_virtual = 0x7fff;
1298 if (var->xres_virtual > 0x7fff)
1299 var->xres_virtual = 0x7fff;
1300 }
1301
1302 var->xres_virtual &= ~63;
1303
1304 NVTRACE_LEAVE();
1305
1306 return err;
1307}
1308
1309static int nvidiafb_pan_display(struct fb_var_screeninfo *var,
1310 struct fb_info *info)
1311{
1312 struct nvidia_par *par = info->par;
1313 u32 total;
1314
Antonino A. Daplas3c8d61b2005-11-13 16:06:34 -08001315 total = var->yoffset * info->fix.line_length + var->xoffset;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001316
1317 NVSetStartAddress(par, total);
1318
1319 return 0;
1320}
1321
1322static int nvidiafb_blank(int blank, struct fb_info *info)
1323{
1324 struct nvidia_par *par = info->par;
1325 unsigned char tmp, vesa;
1326
1327 tmp = NVReadSeq(par, 0x01) & ~0x20; /* screen on/off */
1328 vesa = NVReadCrtc(par, 0x1a) & ~0xc0; /* sync on/off */
1329
1330 NVTRACE_ENTER();
1331
1332 if (blank)
1333 tmp |= 0x20;
1334
1335 switch (blank) {
1336 case FB_BLANK_UNBLANK:
1337 case FB_BLANK_NORMAL:
1338 break;
1339 case FB_BLANK_VSYNC_SUSPEND:
1340 vesa |= 0x80;
1341 break;
1342 case FB_BLANK_HSYNC_SUSPEND:
1343 vesa |= 0x40;
1344 break;
1345 case FB_BLANK_POWERDOWN:
1346 vesa |= 0xc0;
1347 break;
1348 }
1349
1350 NVWriteSeq(par, 0x01, tmp);
1351 NVWriteCrtc(par, 0x1a, vesa);
1352
1353#ifdef CONFIG_PMAC_BACKLIGHT
1354 if (par->FlatPanel && _machine == _MACH_Pmac) {
1355 set_backlight_enable(!blank);
1356 }
1357#endif
1358
1359 NVTRACE_LEAVE();
1360
1361 return 0;
1362}
1363
1364static struct fb_ops nvidia_fb_ops = {
1365 .owner = THIS_MODULE,
1366 .fb_check_var = nvidiafb_check_var,
1367 .fb_set_par = nvidiafb_set_par,
1368 .fb_setcolreg = nvidiafb_setcolreg,
1369 .fb_pan_display = nvidiafb_pan_display,
1370 .fb_blank = nvidiafb_blank,
1371 .fb_fillrect = nvidiafb_fillrect,
1372 .fb_copyarea = nvidiafb_copyarea,
1373 .fb_imageblit = nvidiafb_imageblit,
1374 .fb_cursor = nvidiafb_cursor,
1375 .fb_sync = nvidiafb_sync,
1376};
1377
1378static int __devinit nvidia_set_fbinfo(struct fb_info *info)
1379{
1380 struct fb_monspecs *specs = &info->monspecs;
1381 struct fb_videomode modedb;
1382 struct nvidia_par *par = info->par;
1383 int lpitch;
1384
1385 NVTRACE_ENTER();
1386 info->flags = FBINFO_DEFAULT
1387 | FBINFO_HWACCEL_IMAGEBLIT
1388 | FBINFO_HWACCEL_FILLRECT
1389 | FBINFO_HWACCEL_COPYAREA
1390 | FBINFO_HWACCEL_YPAN;
1391
1392 fb_videomode_to_modelist(info->monspecs.modedb,
1393 info->monspecs.modedb_len, &info->modelist);
1394 fb_var_to_videomode(&modedb, &nvidiafb_default_var);
1395
Antonino A. Daplasade91852006-01-09 20:53:39 -08001396 switch (bpp) {
1397 case 0 ... 8:
1398 bpp = 8;
1399 break;
1400 case 9 ... 16:
1401 bpp = 16;
1402 break;
1403 default:
1404 bpp = 32;
1405 break;
1406 }
1407
Linus Torvalds1da177e2005-04-16 15:20:36 -07001408 if (specs->modedb != NULL) {
Antonino A. Daplas5ee1ef92005-11-07 01:00:55 -08001409 struct fb_videomode *modedb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001410
Antonino A. Daplas5ee1ef92005-11-07 01:00:55 -08001411 modedb = fb_find_best_display(specs, &info->modelist);
1412 fb_videomode_to_var(&nvidiafb_default_var, modedb);
Antonino A. Daplasade91852006-01-09 20:53:39 -08001413 nvidiafb_default_var.bits_per_pixel = bpp;
Antonino Daplasdb6778d2005-08-08 14:22:43 +08001414 } else if (par->fpWidth && par->fpHeight) {
1415 char buf[16];
1416
1417 memset(buf, 0, 16);
Antonino A. Daplas948a95f2005-09-09 13:09:59 -07001418 snprintf(buf, 15, "%dx%dMR", par->fpWidth, par->fpHeight);
Antonino Daplasdb6778d2005-08-08 14:22:43 +08001419 fb_find_mode(&nvidiafb_default_var, info, buf, specs->modedb,
Antonino A. Daplasade91852006-01-09 20:53:39 -08001420 specs->modedb_len, &modedb, bpp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001421 }
1422
1423 if (mode_option)
1424 fb_find_mode(&nvidiafb_default_var, info, mode_option,
Antonino A. Daplasade91852006-01-09 20:53:39 -08001425 specs->modedb, specs->modedb_len, &modedb, bpp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001426
1427 info->var = nvidiafb_default_var;
1428 info->fix.visual = (info->var.bits_per_pixel == 8) ?
1429 FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
1430 info->pseudo_palette = par->pseudo_palette;
1431 fb_alloc_cmap(&info->cmap, 256, 0);
1432 fb_destroy_modedb(info->monspecs.modedb);
1433 info->monspecs.modedb = NULL;
1434
1435 /* maximize virtual vertical length */
1436 lpitch = info->var.xres_virtual *
1437 ((info->var.bits_per_pixel + 7) >> 3);
Antonino A. Daplas917bb072005-05-01 08:59:22 -07001438 info->var.yres_virtual = info->screen_size / lpitch;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001439
1440 info->pixmap.scan_align = 4;
1441 info->pixmap.buf_align = 4;
James Simmons58a60642005-06-21 17:17:08 -07001442 info->pixmap.access_align = 32;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001443 info->pixmap.size = 8 * 1024;
1444 info->pixmap.flags = FB_PIXMAP_SYSTEM;
1445
Antonino A. Daplas7a482422005-09-21 07:30:21 +08001446 if (!hwcur)
Antonino A. Daplasc465e052005-11-07 01:00:35 -08001447 info->fbops->fb_cursor = NULL;
Antonino A. Daplas7a482422005-09-21 07:30:21 +08001448
Linus Torvalds1da177e2005-04-16 15:20:36 -07001449 info->var.accel_flags = (!noaccel);
1450
1451 switch (par->Architecture) {
1452 case NV_ARCH_04:
1453 info->fix.accel = FB_ACCEL_NV4;
1454 break;
1455 case NV_ARCH_10:
1456 info->fix.accel = FB_ACCEL_NV_10;
1457 break;
1458 case NV_ARCH_20:
1459 info->fix.accel = FB_ACCEL_NV_20;
1460 break;
1461 case NV_ARCH_30:
1462 info->fix.accel = FB_ACCEL_NV_30;
1463 break;
1464 case NV_ARCH_40:
1465 info->fix.accel = FB_ACCEL_NV_40;
1466 break;
1467 }
1468
1469 NVTRACE_LEAVE();
1470
1471 return nvidiafb_check_var(&info->var, info);
1472}
1473
Antonino A. Daplasc549dc62006-01-09 20:53:33 -08001474static u32 __devinit nvidia_get_chipset(struct fb_info *info)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001475{
Antonino A. Daplasc549dc62006-01-09 20:53:33 -08001476 struct nvidia_par *par = info->par;
1477 u32 id = (par->pci_dev->vendor << 16) | par->pci_dev->device;
1478
1479 printk("nvidiafb: PCI id - %x\n", id);
1480 if ((id & 0xfff0) == 0x00f0) {
1481 /* pci-e */
1482 printk("nvidiafb: PCI-E card\n");
1483 id = NV_RD32(par->REGS, 0x1800);
1484
1485 if ((id & 0x0000ffff) == 0x000010DE)
1486 id = 0x10DE0000 | (id >> 16);
1487 else if ((id & 0xffff0000) == 0xDE100000) /* wrong endian */
1488 id = 0x10DE0000 | ((id << 8) & 0x0000ff00) |
1489 ((id >> 8) & 0x000000ff);
1490 }
1491
1492 printk("nvidiafb: Actual id - %x\n", id);
1493 return id;
1494}
1495
1496static u32 __devinit nvidia_get_arch(struct fb_info *info)
1497{
1498 struct nvidia_par *par = info->par;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001499 u32 arch = 0;
1500
Antonino A. Daplasc549dc62006-01-09 20:53:33 -08001501 switch (par->Chipset & 0x0ff0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001502 case 0x0100: /* GeForce 256 */
1503 case 0x0110: /* GeForce2 MX */
1504 case 0x0150: /* GeForce2 */
1505 case 0x0170: /* GeForce4 MX */
1506 case 0x0180: /* GeForce4 MX (8x AGP) */
1507 case 0x01A0: /* nForce */
1508 case 0x01F0: /* nForce2 */
1509 arch = NV_ARCH_10;
1510 break;
1511 case 0x0200: /* GeForce3 */
1512 case 0x0250: /* GeForce4 Ti */
1513 case 0x0280: /* GeForce4 Ti (8x AGP) */
1514 arch = NV_ARCH_20;
1515 break;
1516 case 0x0300: /* GeForceFX 5800 */
1517 case 0x0310: /* GeForceFX 5600 */
1518 case 0x0320: /* GeForceFX 5200 */
1519 case 0x0330: /* GeForceFX 5900 */
1520 case 0x0340: /* GeForceFX 5700 */
1521 arch = NV_ARCH_30;
1522 break;
1523 case 0x0040:
1524 case 0x00C0:
1525 case 0x0120:
1526 case 0x0130:
1527 case 0x0140:
1528 case 0x0160:
1529 case 0x01D0:
1530 case 0x0090:
1531 case 0x0210:
1532 case 0x0220:
1533 case 0x0230:
Benjamin Herrenschmidt0137ecf2006-01-09 20:51:27 -08001534 case 0x0290:
1535 case 0x0390:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001536 arch = NV_ARCH_40;
1537 break;
1538 case 0x0020: /* TNT, TNT2 */
1539 arch = NV_ARCH_04;
1540 break;
1541 default: /* unknown architecture */
1542 break;
1543 }
1544
1545 return arch;
1546}
1547
1548static int __devinit nvidiafb_probe(struct pci_dev *pd,
1549 const struct pci_device_id *ent)
1550{
1551 struct nvidia_par *par;
1552 struct fb_info *info;
1553 unsigned short cmd;
1554
1555
1556 NVTRACE_ENTER();
1557 assert(pd != NULL);
1558
1559 info = framebuffer_alloc(sizeof(struct nvidia_par), &pd->dev);
1560
1561 if (!info)
1562 goto err_out;
1563
Antonino A. Daplasc439e342006-01-09 20:53:02 -08001564 par = info->par;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001565 par->pci_dev = pd;
1566
1567 info->pixmap.addr = kmalloc(8 * 1024, GFP_KERNEL);
1568
1569 if (info->pixmap.addr == NULL)
1570 goto err_out_kfree;
1571
1572 memset(info->pixmap.addr, 0, 8 * 1024);
1573
1574 if (pci_enable_device(pd)) {
1575 printk(KERN_ERR PFX "cannot enable PCI device\n");
1576 goto err_out_enable;
1577 }
1578
1579 if (pci_request_regions(pd, "nvidiafb")) {
1580 printk(KERN_ERR PFX "cannot request PCI regions\n");
1581 goto err_out_request;
1582 }
1583
Linus Torvalds1da177e2005-04-16 15:20:36 -07001584 par->FlatPanel = flatpanel;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001585 if (flatpanel == 1)
1586 printk(KERN_INFO PFX "flatpanel support enabled\n");
Benjamin Herrenschmidtb8c49ef2005-11-07 01:00:32 -08001587 par->FPDither = fpdither;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001588
1589 par->CRTCnumber = forceCRTC;
1590 par->FpScale = (!noscale);
1591 par->paneltweak = paneltweak;
1592
1593 /* enable IO and mem if not already done */
1594 pci_read_config_word(pd, PCI_COMMAND, &cmd);
1595 cmd |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
1596 pci_write_config_word(pd, PCI_COMMAND, cmd);
1597
1598 nvidiafb_fix.mmio_start = pci_resource_start(pd, 0);
1599 nvidiafb_fix.smem_start = pci_resource_start(pd, 1);
1600 nvidiafb_fix.mmio_len = pci_resource_len(pd, 0);
1601
1602 par->REGS = ioremap(nvidiafb_fix.mmio_start, nvidiafb_fix.mmio_len);
1603
1604 if (!par->REGS) {
1605 printk(KERN_ERR PFX "cannot ioremap MMIO base\n");
1606 goto err_out_free_base0;
1607 }
1608
Antonino A. Daplasc549dc62006-01-09 20:53:33 -08001609 par->Chipset = nvidia_get_chipset(info);
1610 printk(KERN_INFO PFX "nVidia device/chipset %X\n", par->Chipset);
1611 par->Architecture = nvidia_get_arch(info);
1612
1613 if (par->Architecture == 0) {
1614 printk(KERN_ERR PFX "unknown NV_ARCH\n");
1615 goto err_out_arch;
1616 }
1617
1618 sprintf(nvidiafb_fix.id, "NV%x", (pd->device & 0x0ff0) >> 4);
1619
Antonino A. Daplas918799a2006-01-09 20:53:40 -08001620 if (NVCommonSetup(info))
1621 goto err_out_arch;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001622
1623 par->FbAddress = nvidiafb_fix.smem_start;
1624 par->FbMapSize = par->RamAmountKBytes * 1024;
Antonino A. Daplas917bb072005-05-01 08:59:22 -07001625 if (vram && vram * 1024 * 1024 < par->FbMapSize)
1626 par->FbMapSize = vram * 1024 * 1024;
1627
1628 /* Limit amount of vram to 64 MB */
1629 if (par->FbMapSize > 64 * 1024 * 1024)
1630 par->FbMapSize = 64 * 1024 * 1024;
1631
Benjamin Herrenschmidt0137ecf2006-01-09 20:51:27 -08001632 if(par->Architecture >= NV_ARCH_40)
1633 par->FbUsableSize = par->FbMapSize - (560 * 1024);
1634 else
1635 par->FbUsableSize = par->FbMapSize - (128 * 1024);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001636 par->ScratchBufferSize = (par->Architecture < NV_ARCH_10) ? 8 * 1024 :
1637 16 * 1024;
1638 par->ScratchBufferStart = par->FbUsableSize - par->ScratchBufferSize;
Benjamin Herrenschmidt0137ecf2006-01-09 20:51:27 -08001639 par->CursorStart = par->FbUsableSize + (32 * 1024);
1640
Linus Torvalds1da177e2005-04-16 15:20:36 -07001641 info->screen_base = ioremap(nvidiafb_fix.smem_start, par->FbMapSize);
Antonino A. Daplas917bb072005-05-01 08:59:22 -07001642 info->screen_size = par->FbUsableSize;
1643 nvidiafb_fix.smem_len = par->RamAmountKBytes * 1024;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001644
1645 if (!info->screen_base) {
1646 printk(KERN_ERR PFX "cannot ioremap FB base\n");
1647 goto err_out_free_base1;
1648 }
1649
1650 par->FbStart = info->screen_base;
1651
1652#ifdef CONFIG_MTRR
1653 if (!nomtrr) {
1654 par->mtrr.vram = mtrr_add(nvidiafb_fix.smem_start,
Antonino A. Daplas917bb072005-05-01 08:59:22 -07001655 par->RamAmountKBytes * 1024,
1656 MTRR_TYPE_WRCOMB, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001657 if (par->mtrr.vram < 0) {
1658 printk(KERN_ERR PFX "unable to setup MTRR\n");
1659 } else {
1660 par->mtrr.vram_valid = 1;
1661 /* let there be speed */
1662 printk(KERN_INFO PFX "MTRR set to ON\n");
1663 }
1664 }
1665#endif /* CONFIG_MTRR */
1666
1667 info->fbops = &nvidia_fb_ops;
1668 info->fix = nvidiafb_fix;
1669
1670 if (nvidia_set_fbinfo(info) < 0) {
1671 printk(KERN_ERR PFX "error setting initial video mode\n");
1672 goto err_out_iounmap_fb;
1673 }
1674
1675 nvidia_save_vga(par, &par->SavedReg);
1676
1677 if (register_framebuffer(info) < 0) {
1678 printk(KERN_ERR PFX "error registering nVidia framebuffer\n");
1679 goto err_out_iounmap_fb;
1680 }
1681
1682 pci_set_drvdata(pd, info);
1683
1684 printk(KERN_INFO PFX
1685 "PCI nVidia %s framebuffer (%dMB @ 0x%lX)\n",
1686 info->fix.id,
1687 par->FbMapSize / (1024 * 1024), info->fix.smem_start);
1688#ifdef CONFIG_PMAC_BACKLIGHT
1689 if (par->FlatPanel && _machine == _MACH_Pmac)
1690 register_backlight_controller(&nvidia_backlight_controller,
1691 par, "mnca");
1692#endif
1693 NVTRACE_LEAVE();
1694 return 0;
1695
Antonino A. Daplasc549dc62006-01-09 20:53:33 -08001696err_out_iounmap_fb:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001697 iounmap(info->screen_base);
Antonino A. Daplasc549dc62006-01-09 20:53:33 -08001698err_out_free_base1:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001699 fb_destroy_modedb(info->monspecs.modedb);
1700 nvidia_delete_i2c_busses(par);
Antonino A. Daplasc549dc62006-01-09 20:53:33 -08001701err_out_arch:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001702 iounmap(par->REGS);
Antonino A. Daplasc549dc62006-01-09 20:53:33 -08001703err_out_free_base0:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001704 pci_release_regions(pd);
Antonino A. Daplasc549dc62006-01-09 20:53:33 -08001705err_out_request:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001706 pci_disable_device(pd);
Antonino A. Daplasc549dc62006-01-09 20:53:33 -08001707err_out_enable:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001708 kfree(info->pixmap.addr);
Antonino A. Daplasc549dc62006-01-09 20:53:33 -08001709err_out_kfree:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001710 framebuffer_release(info);
Antonino A. Daplasc549dc62006-01-09 20:53:33 -08001711err_out:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001712 return -ENODEV;
1713}
1714
1715static void __exit nvidiafb_remove(struct pci_dev *pd)
1716{
1717 struct fb_info *info = pci_get_drvdata(pd);
1718 struct nvidia_par *par = info->par;
1719
1720 NVTRACE_ENTER();
1721 if (!info)
1722 return;
1723
1724 unregister_framebuffer(info);
1725#ifdef CONFIG_MTRR
1726 if (par->mtrr.vram_valid)
1727 mtrr_del(par->mtrr.vram, info->fix.smem_start,
1728 info->fix.smem_len);
1729#endif /* CONFIG_MTRR */
1730
1731 iounmap(info->screen_base);
1732 fb_destroy_modedb(info->monspecs.modedb);
1733 nvidia_delete_i2c_busses(par);
1734 iounmap(par->REGS);
1735 pci_release_regions(pd);
1736 pci_disable_device(pd);
1737 kfree(info->pixmap.addr);
1738 framebuffer_release(info);
1739 pci_set_drvdata(pd, NULL);
1740 NVTRACE_LEAVE();
1741}
1742
1743/* ------------------------------------------------------------------------- *
1744 *
1745 * initialization
1746 *
1747 * ------------------------------------------------------------------------- */
1748
1749#ifndef MODULE
1750static int __devinit nvidiafb_setup(char *options)
1751{
1752 char *this_opt;
1753
1754 NVTRACE_ENTER();
1755 if (!options || !*options)
1756 return 0;
1757
1758 while ((this_opt = strsep(&options, ",")) != NULL) {
1759 if (!strncmp(this_opt, "forceCRTC", 9)) {
1760 char *p;
1761
1762 p = this_opt + 9;
1763 if (!*p || !*(++p))
1764 continue;
1765 forceCRTC = *p - '0';
1766 if (forceCRTC < 0 || forceCRTC > 1)
1767 forceCRTC = -1;
1768 } else if (!strncmp(this_opt, "flatpanel", 9)) {
1769 flatpanel = 1;
1770 } else if (!strncmp(this_opt, "hwcur", 5)) {
1771 hwcur = 1;
1772 } else if (!strncmp(this_opt, "noaccel", 6)) {
1773 noaccel = 1;
1774 } else if (!strncmp(this_opt, "noscale", 7)) {
1775 noscale = 1;
1776 } else if (!strncmp(this_opt, "paneltweak:", 11)) {
1777 paneltweak = simple_strtoul(this_opt+11, NULL, 0);
Antonino A. Daplas917bb072005-05-01 08:59:22 -07001778 } else if (!strncmp(this_opt, "vram:", 5)) {
1779 vram = simple_strtoul(this_opt+5, NULL, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001780#ifdef CONFIG_MTRR
1781 } else if (!strncmp(this_opt, "nomtrr", 6)) {
1782 nomtrr = 1;
1783#endif
Benjamin Herrenschmidtb8c49ef2005-11-07 01:00:32 -08001784 } else if (!strncmp(this_opt, "fpdither:", 9)) {
1785 fpdither = simple_strtol(this_opt+9, NULL, 0);
Antonino A. Daplasade91852006-01-09 20:53:39 -08001786 } else if (!strncmp(this_opt, "bpp:", 4)) {
1787 bpp = simple_strtoul(this_opt+4, NULL, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001788 } else
1789 mode_option = this_opt;
1790 }
1791 NVTRACE_LEAVE();
1792 return 0;
1793}
1794#endif /* !MODULE */
1795
1796static struct pci_driver nvidiafb_driver = {
1797 .name = "nvidiafb",
1798 .id_table = nvidiafb_pci_tbl,
1799 .probe = nvidiafb_probe,
1800 .remove = __exit_p(nvidiafb_remove),
1801};
1802
1803/* ------------------------------------------------------------------------- *
1804 *
1805 * modularization
1806 *
1807 * ------------------------------------------------------------------------- */
1808
1809static int __devinit nvidiafb_init(void)
1810{
1811#ifndef MODULE
1812 char *option = NULL;
1813
1814 if (fb_get_options("nvidiafb", &option))
1815 return -ENODEV;
1816 nvidiafb_setup(option);
1817#endif
1818 return pci_register_driver(&nvidiafb_driver);
1819}
1820
1821module_init(nvidiafb_init);
1822
1823#ifdef MODULE
1824static void __exit nvidiafb_exit(void)
1825{
1826 pci_unregister_driver(&nvidiafb_driver);
1827}
1828
1829module_exit(nvidiafb_exit);
1830
1831module_param(flatpanel, int, 0);
1832MODULE_PARM_DESC(flatpanel,
1833 "Enables experimental flat panel support for some chipsets. "
Benjamin Herrenschmidtb8c49ef2005-11-07 01:00:32 -08001834 "(0=disabled, 1=enabled, -1=autodetect) (default=-1)");
1835module_param(fpdither, int, 0);
1836MODULE_PARM_DESC(fpdither,
1837 "Enables dithering of flat panel for 6 bits panels. "
1838 "(0=disabled, 1=enabled, -1=autodetect) (default=-1)");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001839module_param(hwcur, int, 0);
1840MODULE_PARM_DESC(hwcur,
1841 "Enables hardware cursor implementation. (0 or 1=enabled) "
1842 "(default=0)");
1843module_param(noaccel, int, 0);
1844MODULE_PARM_DESC(noaccel,
1845 "Disables hardware acceleration. (0 or 1=disable) "
1846 "(default=0)");
1847module_param(noscale, int, 0);
1848MODULE_PARM_DESC(noscale,
1849 "Disables screen scaleing. (0 or 1=disable) "
1850 "(default=0, do scaling)");
1851module_param(paneltweak, int, 0);
1852MODULE_PARM_DESC(paneltweak,
1853 "Tweak display settings for flatpanels. "
1854 "(default=0, no tweaks)");
1855module_param(forceCRTC, int, 0);
1856MODULE_PARM_DESC(forceCRTC,
1857 "Forces usage of a particular CRTC in case autodetection "
1858 "fails. (0 or 1) (default=autodetect)");
Antonino A. Daplas917bb072005-05-01 08:59:22 -07001859module_param(vram, int, 0);
1860MODULE_PARM_DESC(vram,
1861 "amount of framebuffer memory to remap in MiB"
1862 "(default=0 - remap entire memory)");
Antonino A. Daplasc439e342006-01-09 20:53:02 -08001863module_param(mode_option, charp, 0);
1864MODULE_PARM_DESC(mode_option, "Specify initial video mode");
Antonino A. Daplasade91852006-01-09 20:53:39 -08001865module_param(bpp, int, 0);
1866MODULE_PARM_DESC(bpp, "pixel width in bits"
1867 "(default=8)");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001868#ifdef CONFIG_MTRR
1869module_param(nomtrr, bool, 0);
1870MODULE_PARM_DESC(nomtrr, "Disables MTRR support (0 or 1=disabled) "
1871 "(default=0)");
1872#endif
1873
1874MODULE_AUTHOR("Antonino Daplas");
1875MODULE_DESCRIPTION("Framebuffer driver for nVidia graphics chipset");
1876MODULE_LICENSE("GPL");
1877#endif /* MODULE */
1878