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