blob: 96d51144094aecf8471201642993122061f1d96a [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},
287 {PCI_VENDOR_ID_NVIDIA, 0x0252,
288 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
289 {PCI_VENDOR_ID_NVIDIA, 0x0313,
290 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
291 {PCI_VENDOR_ID_NVIDIA, 0x0316,
292 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
293 {PCI_VENDOR_ID_NVIDIA, 0x0317,
294 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
295 {PCI_VENDOR_ID_NVIDIA, 0x031D,
296 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
297 {PCI_VENDOR_ID_NVIDIA, 0x031E,
298 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
299 {PCI_VENDOR_ID_NVIDIA, 0x031F,
300 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
301 {PCI_VENDOR_ID_NVIDIA, 0x0329,
302 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
303 {PCI_VENDOR_ID_NVIDIA, 0x032F,
304 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
305 {PCI_VENDOR_ID_NVIDIA, 0x0345,
306 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
307 {PCI_VENDOR_ID_NVIDIA, 0x0349,
308 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
309 {PCI_VENDOR_ID_NVIDIA, 0x034B,
310 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
311 {PCI_VENDOR_ID_NVIDIA, 0x034F,
312 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
313 {PCI_VENDOR_ID_NVIDIA, 0x00c0,
314 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
315 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_GEFORCE_6800A,
316 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
317 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_GEFORCE_6800A_LE,
318 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
319 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_GEFORCE_GO_6800,
320 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
321 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_GEFORCE_GO_6800_ULTRA,
322 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
323 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_QUADRO_FX_GO1400,
324 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
325 {PCI_VENDOR_ID_NVIDIA, 0x00cd,
326 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
327 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_QUADRO_FX_1400,
328 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
329 {PCI_VENDOR_ID_NVIDIA, 0x0142,
330 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
331 {PCI_VENDOR_ID_NVIDIA, 0x0143,
332 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
333 {PCI_VENDOR_ID_NVIDIA, 0x0144,
334 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
335 {PCI_VENDOR_ID_NVIDIA, 0x0145,
336 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
337 {PCI_VENDOR_ID_NVIDIA, 0x0146,
338 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
339 {PCI_VENDOR_ID_NVIDIA, 0x0147,
340 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
341 {PCI_VENDOR_ID_NVIDIA, 0x0148,
342 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
343 {PCI_VENDOR_ID_NVIDIA, 0x0149,
344 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
345 {PCI_VENDOR_ID_NVIDIA, 0x014b,
346 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
347 {PCI_VENDOR_ID_NVIDIA, 0x14c,
348 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
349 {PCI_VENDOR_ID_NVIDIA, 0x014d,
350 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
351 {PCI_VENDOR_ID_NVIDIA, 0x0160,
352 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
353 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_6200_TURBOCACHE,
354 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
355 {PCI_VENDOR_ID_NVIDIA, 0x0162,
356 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
357 {PCI_VENDOR_ID_NVIDIA, 0x0163,
358 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
359 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_GO_6200,
360 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
361 {PCI_VENDOR_ID_NVIDIA, 0x0165,
362 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
363 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_GO_6250,
364 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
365 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_GO_6200_1,
366 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
367 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_GO_6250_1,
368 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
369 {PCI_VENDOR_ID_NVIDIA, 0x0169,
370 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
371 {PCI_VENDOR_ID_NVIDIA, 0x016b,
372 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
373 {PCI_VENDOR_ID_NVIDIA, 0x016c,
374 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
375 {PCI_VENDOR_ID_NVIDIA, 0x016d,
376 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
377 {PCI_VENDOR_ID_NVIDIA, 0x016e,
378 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
379 {PCI_VENDOR_ID_NVIDIA, 0x0210,
380 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
381 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_6800B,
382 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
383 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_6800B_LE,
384 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
385 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_6800B_GT,
386 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
Calin A. Culianu7015faa2005-11-04 20:38:04 -0500387 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_7800_GT,
388 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
389 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_7800_GTX,
390 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
391 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_GO_7800,
392 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
393 {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_GO_7800_GTX,
394 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
Linus Torvalds1da177e2005-04-16 15:20:36 -0700395 {PCI_VENDOR_ID_NVIDIA, 0x021d,
396 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
397 {PCI_VENDOR_ID_NVIDIA, 0x021e,
398 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
399 {PCI_VENDOR_ID_NVIDIA, 0x0220,
400 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
401 {PCI_VENDOR_ID_NVIDIA, 0x0221,
402 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
403 {PCI_VENDOR_ID_NVIDIA, 0x0222,
404 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
405 {PCI_VENDOR_ID_NVIDIA, 0x0228,
406 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
407 {0,} /* terminate list */
408};
409
410MODULE_DEVICE_TABLE(pci, nvidiafb_pci_tbl);
411
412/* command line data, set in nvidiafb_setup() */
413static int flatpanel __devinitdata = -1; /* Autodetect later */
414static int forceCRTC __devinitdata = -1;
415static int hwcur __devinitdata = 0;
416static int noaccel __devinitdata = 0;
417static int noscale __devinitdata = 0;
418static int paneltweak __devinitdata = 0;
Antonino A. Daplas917bb072005-05-01 08:59:22 -0700419static int vram __devinitdata = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700420#ifdef CONFIG_MTRR
421static int nomtrr __devinitdata = 0;
422#endif
423
424static char *mode_option __devinitdata = NULL;
425
426static struct fb_fix_screeninfo __devinitdata nvidiafb_fix = {
427 .type = FB_TYPE_PACKED_PIXELS,
428 .xpanstep = 8,
429 .ypanstep = 1,
430};
431
432static struct fb_var_screeninfo __devinitdata nvidiafb_default_var = {
433 .xres = 640,
434 .yres = 480,
435 .xres_virtual = 640,
436 .yres_virtual = 480,
437 .bits_per_pixel = 8,
438 .red = {0, 8, 0},
439 .green = {0, 8, 0},
440 .blue = {0, 8, 0},
441 .transp = {0, 0, 0},
442 .activate = FB_ACTIVATE_NOW,
443 .height = -1,
444 .width = -1,
445 .pixclock = 39721,
446 .left_margin = 40,
447 .right_margin = 24,
448 .upper_margin = 32,
449 .lower_margin = 11,
450 .hsync_len = 96,
451 .vsync_len = 2,
452 .vmode = FB_VMODE_NONINTERLACED
453};
454
455/*
456 * Backlight control
457 */
458#ifdef CONFIG_PMAC_BACKLIGHT
459
460static int nvidia_backlight_levels[] = {
461 0x158,
462 0x192,
463 0x1c6,
464 0x200,
465 0x234,
466 0x268,
467 0x2a2,
468 0x2d6,
469 0x310,
470 0x344,
471 0x378,
472 0x3b2,
473 0x3e6,
474 0x41a,
475 0x454,
476 0x534,
477};
478
479/* ------------------------------------------------------------------------- *
480 *
481 * Backlight operations
482 *
483 * ------------------------------------------------------------------------- */
484
485static int nvidia_set_backlight_enable(int on, int level, void *data)
486{
487 struct nvidia_par *par = (struct nvidia_par *)data;
488 u32 tmp_pcrt, tmp_pmc, fpcontrol;
489
490 tmp_pmc = NV_RD32(par->PMC, 0x10F0) & 0x0000FFFF;
491 tmp_pcrt = NV_RD32(par->PCRTC0, 0x081C) & 0xFFFFFFFC;
492 fpcontrol = NV_RD32(par->PRAMDAC, 0x0848) & 0xCFFFFFCC;
493
494 if (on && (level > BACKLIGHT_OFF)) {
495 tmp_pcrt |= 0x1;
496 tmp_pmc |= (1 << 31); // backlight bit
497 tmp_pmc |= nvidia_backlight_levels[level - 1] << 16;
498 }
499
500 if (on)
501 fpcontrol |= par->fpSyncs;
502 else
503 fpcontrol |= 0x20000022;
504
505 NV_WR32(par->PCRTC0, 0x081C, tmp_pcrt);
506 NV_WR32(par->PMC, 0x10F0, tmp_pmc);
507 NV_WR32(par->PRAMDAC, 0x848, fpcontrol);
508
509 return 0;
510}
511
512static int nvidia_set_backlight_level(int level, void *data)
513{
514 return nvidia_set_backlight_enable(1, level, data);
515}
516
517static struct backlight_controller nvidia_backlight_controller = {
518 nvidia_set_backlight_enable,
519 nvidia_set_backlight_level
520};
521
522#endif /* CONFIG_PMAC_BACKLIGHT */
523
524static void nvidiafb_load_cursor_image(struct nvidia_par *par, u8 * data8,
525 u16 bg, u16 fg, u32 w, u32 h)
526{
James Simmonsf1ab5da2005-06-21 17:17:07 -0700527 u32 *data = (u32 *) data8;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700528 int i, j, k = 0;
529 u32 b, tmp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700530
531 w = (w + 1) & ~1;
532
533 for (i = 0; i < h; i++) {
534 b = *data++;
535 reverse_order(&b);
536
537 for (j = 0; j < w / 2; j++) {
538 tmp = 0;
539#if defined (__BIG_ENDIAN)
540 tmp = (b & (1 << 31)) ? fg << 16 : bg << 16;
541 b <<= 1;
542 tmp |= (b & (1 << 31)) ? fg : bg;
543 b <<= 1;
544#else
545 tmp = (b & 1) ? fg : bg;
546 b >>= 1;
547 tmp |= (b & 1) ? fg << 16 : bg << 16;
548 b >>= 1;
549#endif
550 NV_WR32(&par->CURSOR[k++], 0, tmp);
551 }
552 k += (MAX_CURS - w) / 2;
553 }
554}
555
556static void nvidia_write_clut(struct nvidia_par *par,
557 u8 regnum, u8 red, u8 green, u8 blue)
558{
559 NVWriteDacMask(par, 0xff);
560 NVWriteDacWriteAddr(par, regnum);
561 NVWriteDacData(par, red);
562 NVWriteDacData(par, green);
563 NVWriteDacData(par, blue);
564}
565
566static void nvidia_read_clut(struct nvidia_par *par,
567 u8 regnum, u8 * red, u8 * green, u8 * blue)
568{
569 NVWriteDacMask(par, 0xff);
570 NVWriteDacReadAddr(par, regnum);
571 *red = NVReadDacData(par);
572 *green = NVReadDacData(par);
573 *blue = NVReadDacData(par);
574}
575
576static int nvidia_panel_tweak(struct nvidia_par *par,
577 struct _riva_hw_state *state)
578{
579 int tweak = 0;
580
581 if (par->paneltweak) {
582 tweak = par->paneltweak;
583 } else {
584 /* begin flat panel hacks */
585 /* This is unfortunate, but some chips need this register
586 tweaked or else you get artifacts where adjacent pixels are
587 swapped. There are no hard rules for what to set here so all
588 we can do is experiment and apply hacks. */
589
590 if(((par->Chipset & 0xffff) == 0x0328) && (state->bpp == 32)) {
591 /* At least one NV34 laptop needs this workaround. */
592 tweak = -1;
593 }
594
595 if((par->Chipset & 0xfff0) == 0x0310) {
596 tweak = 1;
597 }
598 /* end flat panel hacks */
599 }
600
601 return tweak;
602}
603
604static void nvidia_save_vga(struct nvidia_par *par,
605 struct _riva_hw_state *state)
606{
607 int i;
608
609 NVTRACE_ENTER();
610 NVLockUnlock(par, 0);
611
612 NVUnloadStateExt(par, state);
613
614 state->misc_output = NVReadMiscOut(par);
615
616 for (i = 0; i < NUM_CRT_REGS; i++)
617 state->crtc[i] = NVReadCrtc(par, i);
618
619 for (i = 0; i < NUM_ATC_REGS; i++)
620 state->attr[i] = NVReadAttr(par, i);
621
622 for (i = 0; i < NUM_GRC_REGS; i++)
623 state->gra[i] = NVReadGr(par, i);
624
625 for (i = 0; i < NUM_SEQ_REGS; i++)
626 state->seq[i] = NVReadSeq(par, i);
627 NVTRACE_LEAVE();
628}
629
Benjamin Herrenschmidt85f15032005-11-07 01:00:30 -0800630#undef DUMP_REG
631
Linus Torvalds1da177e2005-04-16 15:20:36 -0700632static void nvidia_write_regs(struct nvidia_par *par)
633{
634 struct _riva_hw_state *state = &par->ModeReg;
635 int i;
636
637 NVTRACE_ENTER();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700638
639 NVLoadStateExt(par, state);
640
641 NVWriteMiscOut(par, state->misc_output);
642
Benjamin Herrenschmidt85f15032005-11-07 01:00:30 -0800643 for (i = 1; i < NUM_SEQ_REGS; i++) {
644#ifdef DUMP_REG
645 printk(" SEQ[%02x] = %08x\n", i, state->seq[i]);
646#endif
647 NVWriteSeq(par, i, state->seq[i]);
648 }
649
650 /* Ensure CRTC registers 0-7 are unlocked by clearing bit 7 of CRTC[17] */
651 NVWriteCrtc(par, 0x11, state->crtc[0x11] & ~0x80);
652
Linus Torvalds1da177e2005-04-16 15:20:36 -0700653 for (i = 0; i < NUM_CRT_REGS; i++) {
654 switch (i) {
655 case 0x19:
656 case 0x20 ... 0x40:
657 break;
658 default:
Benjamin Herrenschmidt85f15032005-11-07 01:00:30 -0800659#ifdef DUMP_REG
660 printk("CRTC[%02x] = %08x\n", i, state->crtc[i]);
661#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700662 NVWriteCrtc(par, i, state->crtc[i]);
663 }
664 }
665
Benjamin Herrenschmidt85f15032005-11-07 01:00:30 -0800666 for (i = 0; i < NUM_GRC_REGS; i++) {
667#ifdef DUMP_REG
668 printk(" GRA[%02x] = %08x\n", i, state->gra[i]);
669#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700670 NVWriteGr(par, i, state->gra[i]);
Benjamin Herrenschmidt85f15032005-11-07 01:00:30 -0800671 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700672
Benjamin Herrenschmidt85f15032005-11-07 01:00:30 -0800673 for (i = 0; i < NUM_ATC_REGS; i++) {
674#ifdef DUMP_REG
675 printk("ATTR[%02x] = %08x\n", i, state->attr[i]);
676#endif
677 NVWriteAttr(par, i, state->attr[i]);
678 }
679
Linus Torvalds1da177e2005-04-16 15:20:36 -0700680 NVTRACE_LEAVE();
681}
682
Benjamin Herrenschmidt85f15032005-11-07 01:00:30 -0800683static void nvidia_vga_protect(struct nvidia_par *par, int on)
684{
685 unsigned char tmp;
686
687 if (on) {
688 /*
689 * Turn off screen and disable sequencer.
690 */
691 tmp = NVReadSeq(par, 0x01);
692
693 NVWriteSeq(par, 0x00, 0x01); /* Synchronous Reset */
694 NVWriteSeq(par, 0x01, tmp | 0x20); /* disable the display */
695 } else {
696 /*
697 * Reenable sequencer, then turn on screen.
698 */
699
700 tmp = NVReadSeq(par, 0x01);
701
702 NVWriteSeq(par, 0x01, tmp & ~0x20); /* reenable display */
703 NVWriteSeq(par, 0x00, 0x03); /* End Reset */
704 }
705}
706
707
708
Linus Torvalds1da177e2005-04-16 15:20:36 -0700709static int nvidia_calc_regs(struct fb_info *info)
710{
711 struct nvidia_par *par = info->par;
712 struct _riva_hw_state *state = &par->ModeReg;
Antonino A. Daplasb8c90942005-09-09 13:04:37 -0700713 int i, depth = fb_get_color_depth(&info->var, &info->fix);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700714 int h_display = info->var.xres / 8 - 1;
715 int h_start = (info->var.xres + info->var.right_margin) / 8 - 1;
716 int h_end = (info->var.xres + info->var.right_margin +
717 info->var.hsync_len) / 8 - 1;
718 int h_total = (info->var.xres + info->var.right_margin +
719 info->var.hsync_len + info->var.left_margin) / 8 - 5;
720 int h_blank_s = h_display;
721 int h_blank_e = h_total + 4;
722 int v_display = info->var.yres - 1;
723 int v_start = info->var.yres + info->var.lower_margin - 1;
724 int v_end = (info->var.yres + info->var.lower_margin +
725 info->var.vsync_len) - 1;
726 int v_total = (info->var.yres + info->var.lower_margin +
727 info->var.vsync_len + info->var.upper_margin) - 2;
728 int v_blank_s = v_display;
729 int v_blank_e = v_total + 1;
730
731 /*
732 * Set all CRTC values.
733 */
734
735 if (info->var.vmode & FB_VMODE_INTERLACED)
736 v_total |= 1;
737
738 if (par->FlatPanel == 1) {
739 v_start = v_total - 3;
740 v_end = v_total - 2;
741 v_blank_s = v_start;
742 h_start = h_total - 5;
743 h_end = h_total - 2;
744 h_blank_e = h_total + 4;
745 }
746
747 state->crtc[0x0] = Set8Bits(h_total);
748 state->crtc[0x1] = Set8Bits(h_display);
749 state->crtc[0x2] = Set8Bits(h_blank_s);
750 state->crtc[0x3] = SetBitField(h_blank_e, 4: 0, 4:0)
751 | SetBit(7);
752 state->crtc[0x4] = Set8Bits(h_start);
753 state->crtc[0x5] = SetBitField(h_blank_e, 5: 5, 7:7)
754 | SetBitField(h_end, 4: 0, 4:0);
755 state->crtc[0x6] = SetBitField(v_total, 7: 0, 7:0);
756 state->crtc[0x7] = SetBitField(v_total, 8: 8, 0:0)
757 | SetBitField(v_display, 8: 8, 1:1)
758 | SetBitField(v_start, 8: 8, 2:2)
759 | SetBitField(v_blank_s, 8: 8, 3:3)
760 | SetBit(4)
761 | SetBitField(v_total, 9: 9, 5:5)
762 | SetBitField(v_display, 9: 9, 6:6)
763 | SetBitField(v_start, 9: 9, 7:7);
764 state->crtc[0x9] = SetBitField(v_blank_s, 9: 9, 5:5)
765 | SetBit(6)
766 | ((info->var.vmode & FB_VMODE_DOUBLE) ? 0x80 : 0x00);
767 state->crtc[0x10] = Set8Bits(v_start);
768 state->crtc[0x11] = SetBitField(v_end, 3: 0, 3:0) | SetBit(5);
769 state->crtc[0x12] = Set8Bits(v_display);
770 state->crtc[0x13] = ((info->var.xres_virtual / 8) *
771 (info->var.bits_per_pixel / 8));
772 state->crtc[0x15] = Set8Bits(v_blank_s);
773 state->crtc[0x16] = Set8Bits(v_blank_e);
774
775 state->attr[0x10] = 0x01;
776
777 if (par->Television)
778 state->attr[0x11] = 0x00;
779
780 state->screen = SetBitField(h_blank_e, 6: 6, 4:4)
781 | SetBitField(v_blank_s, 10: 10, 3:3)
782 | SetBitField(v_start, 10: 10, 2:2)
783 | SetBitField(v_display, 10: 10, 1:1)
784 | SetBitField(v_total, 10: 10, 0:0);
785
786 state->horiz = SetBitField(h_total, 8: 8, 0:0)
787 | SetBitField(h_display, 8: 8, 1:1)
788 | SetBitField(h_blank_s, 8: 8, 2:2)
789 | SetBitField(h_start, 8: 8, 3:3);
790
791 state->extra = SetBitField(v_total, 11: 11, 0:0)
792 | SetBitField(v_display, 11: 11, 2:2)
793 | SetBitField(v_start, 11: 11, 4:4)
794 | SetBitField(v_blank_s, 11: 11, 6:6);
795
796 if (info->var.vmode & FB_VMODE_INTERLACED) {
797 h_total = (h_total >> 1) & ~1;
798 state->interlace = Set8Bits(h_total);
799 state->horiz |= SetBitField(h_total, 8: 8, 4:4);
800 } else {
801 state->interlace = 0xff; /* interlace off */
802 }
803
804 /*
805 * Calculate the extended registers.
806 */
807
808 if (depth < 24)
809 i = depth;
810 else
811 i = 32;
812
813 if (par->Architecture >= NV_ARCH_10)
814 par->CURSOR = (volatile u32 __iomem *)(info->screen_base +
815 par->CursorStart);
816
817 if (info->var.sync & FB_SYNC_HOR_HIGH_ACT)
818 state->misc_output &= ~0x40;
819 else
820 state->misc_output |= 0x40;
821 if (info->var.sync & FB_SYNC_VERT_HIGH_ACT)
822 state->misc_output &= ~0x80;
823 else
824 state->misc_output |= 0x80;
825
826 NVCalcStateExt(par, state, i, info->var.xres_virtual,
827 info->var.xres, info->var.yres_virtual,
828 1000000000 / info->var.pixclock, info->var.vmode);
829
830 state->scale = NV_RD32(par->PRAMDAC, 0x00000848) & 0xfff000ff;
831 if (par->FlatPanel == 1) {
832 state->pixel |= (1 << 7);
833
834 if (!par->fpScaler || (par->fpWidth <= info->var.xres)
835 || (par->fpHeight <= info->var.yres)) {
836 state->scale |= (1 << 8);
837 }
838
839 if (!par->crtcSync_read) {
840 state->crtcSync = NV_RD32(par->PRAMDAC, 0x0828);
841 par->crtcSync_read = 1;
842 }
843
844 par->PanelTweak = nvidia_panel_tweak(par, state);
845 }
846
847 state->vpll = state->pll;
848 state->vpll2 = state->pll;
849 state->vpllB = state->pllB;
850 state->vpll2B = state->pllB;
851
852 VGA_WR08(par->PCIO, 0x03D4, 0x1C);
853 state->fifo = VGA_RD08(par->PCIO, 0x03D5) & ~(1<<5);
854
855 if (par->CRTCnumber) {
856 state->head = NV_RD32(par->PCRTC0, 0x00000860) & ~0x00001000;
857 state->head2 = NV_RD32(par->PCRTC0, 0x00002860) | 0x00001000;
858 state->crtcOwner = 3;
859 state->pllsel |= 0x20000800;
860 state->vpll = NV_RD32(par->PRAMDAC0, 0x00000508);
861 if (par->twoStagePLL)
862 state->vpllB = NV_RD32(par->PRAMDAC0, 0x00000578);
863 } else if (par->twoHeads) {
864 state->head = NV_RD32(par->PCRTC0, 0x00000860) | 0x00001000;
865 state->head2 = NV_RD32(par->PCRTC0, 0x00002860) & ~0x00001000;
866 state->crtcOwner = 0;
867 state->vpll2 = NV_RD32(par->PRAMDAC0, 0x0520);
868 if (par->twoStagePLL)
869 state->vpll2B = NV_RD32(par->PRAMDAC0, 0x057C);
870 }
871
872 state->cursorConfig = 0x00000100;
873
874 if (info->var.vmode & FB_VMODE_DOUBLE)
875 state->cursorConfig |= (1 << 4);
876
877 if (par->alphaCursor) {
878 if ((par->Chipset & 0x0ff0) != 0x0110)
879 state->cursorConfig |= 0x04011000;
880 else
881 state->cursorConfig |= 0x14011000;
882 state->general |= (1 << 29);
883 } else
884 state->cursorConfig |= 0x02000000;
885
886 if (par->twoHeads) {
887 if ((par->Chipset & 0x0ff0) == 0x0110) {
888 state->dither = NV_RD32(par->PRAMDAC, 0x0528) &
889 ~0x00010000;
890 if (par->FPDither)
891 state->dither |= 0x00010000;
892 } else {
893 state->dither = NV_RD32(par->PRAMDAC, 0x083C) & ~1;
894 if (par->FPDither)
895 state->dither |= 1;
896 }
897 }
898
899 state->timingH = 0;
900 state->timingV = 0;
901 state->displayV = info->var.xres;
902
903 return 0;
904}
905
906static void nvidia_init_vga(struct fb_info *info)
907{
908 struct nvidia_par *par = info->par;
909 struct _riva_hw_state *state = &par->ModeReg;
910 int i;
911
912 for (i = 0; i < 0x10; i++)
913 state->attr[i] = i;
914 state->attr[0x10] = 0x41;
Benjamin Herrenschmidt85f15032005-11-07 01:00:30 -0800915 state->attr[0x11] = 0xff;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700916 state->attr[0x12] = 0x0f;
917 state->attr[0x13] = 0x00;
918 state->attr[0x14] = 0x00;
919
920 memset(state->crtc, 0x00, NUM_CRT_REGS);
921 state->crtc[0x0a] = 0x20;
922 state->crtc[0x17] = 0xe3;
923 state->crtc[0x18] = 0xff;
924 state->crtc[0x28] = 0x40;
925
926 memset(state->gra, 0x00, NUM_GRC_REGS);
927 state->gra[0x05] = 0x40;
928 state->gra[0x06] = 0x05;
929 state->gra[0x07] = 0x0f;
930 state->gra[0x08] = 0xff;
931
932 state->seq[0x00] = 0x03;
933 state->seq[0x01] = 0x01;
934 state->seq[0x02] = 0x0f;
935 state->seq[0x03] = 0x00;
936 state->seq[0x04] = 0x0e;
937
938 state->misc_output = 0xeb;
939}
940
941static int nvidiafb_cursor(struct fb_info *info, struct fb_cursor *cursor)
942{
943 struct nvidia_par *par = info->par;
944 u8 data[MAX_CURS * MAX_CURS / 8];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700945 int i, set = cursor->set;
James Simmonsf1ab5da2005-06-21 17:17:07 -0700946 u16 fg, bg;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700947
Antonino A. Daplas7a482422005-09-21 07:30:21 +0800948 if (cursor->image.width > MAX_CURS || cursor->image.height > MAX_CURS)
James Simmonsf1ab5da2005-06-21 17:17:07 -0700949 return -ENXIO;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700950
951 NVShowHideCursor(par, 0);
952
953 if (par->cursor_reset) {
954 set = FB_CUR_SETALL;
955 par->cursor_reset = 0;
956 }
957
958 if (set & FB_CUR_SETSIZE)
959 memset_io(par->CURSOR, 0, MAX_CURS * MAX_CURS * 2);
960
961 if (set & FB_CUR_SETPOS) {
962 u32 xx, yy, temp;
963
964 yy = cursor->image.dy - info->var.yoffset;
965 xx = cursor->image.dx - info->var.xoffset;
966 temp = xx & 0xFFFF;
967 temp |= yy << 16;
968
969 NV_WR32(par->PRAMDAC, 0x0000300, temp);
970 }
971
972 if (set & (FB_CUR_SETSHAPE | FB_CUR_SETCMAP | FB_CUR_SETIMAGE)) {
973 u32 bg_idx = cursor->image.bg_color;
974 u32 fg_idx = cursor->image.fg_color;
975 u32 s_pitch = (cursor->image.width + 7) >> 3;
976 u32 d_pitch = MAX_CURS / 8;
977 u8 *dat = (u8 *) cursor->image.data;
978 u8 *msk = (u8 *) cursor->mask;
979 u8 *src;
980
981 src = kmalloc(s_pitch * cursor->image.height, GFP_ATOMIC);
982
983 if (src) {
984 switch (cursor->rop) {
985 case ROP_XOR:
James Simmonsf1ab5da2005-06-21 17:17:07 -0700986 for (i = 0; i < s_pitch * cursor->image.height; i++)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700987 src[i] = dat[i] ^ msk[i];
988 break;
989 case ROP_COPY:
990 default:
James Simmonsf1ab5da2005-06-21 17:17:07 -0700991 for (i = 0; i < s_pitch * cursor->image.height; i++)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700992 src[i] = dat[i] & msk[i];
993 break;
994 }
995
James Simmonsf1ab5da2005-06-21 17:17:07 -0700996 fb_pad_aligned_buffer(data, d_pitch, src, s_pitch,
997 cursor->image.height);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700998
999 bg = ((info->cmap.red[bg_idx] & 0xf8) << 7) |
1000 ((info->cmap.green[bg_idx] & 0xf8) << 2) |
1001 ((info->cmap.blue[bg_idx] & 0xf8) >> 3) | 1 << 15;
1002
1003 fg = ((info->cmap.red[fg_idx] & 0xf8) << 7) |
1004 ((info->cmap.green[fg_idx] & 0xf8) << 2) |
1005 ((info->cmap.blue[fg_idx] & 0xf8) >> 3) | 1 << 15;
1006
1007 NVLockUnlock(par, 0);
1008
1009 nvidiafb_load_cursor_image(par, data, bg, fg,
1010 cursor->image.width,
1011 cursor->image.height);
1012 kfree(src);
1013 }
1014 }
1015
1016 if (cursor->enable)
1017 NVShowHideCursor(par, 1);
1018
1019 return 0;
1020}
1021
1022static int nvidiafb_set_par(struct fb_info *info)
1023{
1024 struct nvidia_par *par = info->par;
1025
1026 NVTRACE_ENTER();
1027
1028 NVLockUnlock(par, 1);
1029 if (!par->FlatPanel || (info->var.bits_per_pixel != 24) ||
1030 !par->twoHeads)
1031 par->FPDither = 0;
1032
Antonino A. Daplasb8c90942005-09-09 13:04:37 -07001033 info->fix.visual = (info->var.bits_per_pixel == 8) ?
1034 FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
1035
Linus Torvalds1da177e2005-04-16 15:20:36 -07001036 nvidia_init_vga(info);
1037 nvidia_calc_regs(info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001038
1039 NVLockUnlock(par, 0);
1040 if (par->twoHeads) {
1041 VGA_WR08(par->PCIO, 0x03D4, 0x44);
1042 VGA_WR08(par->PCIO, 0x03D5, par->ModeReg.crtcOwner);
1043 NVLockUnlock(par, 0);
1044 }
1045
Benjamin Herrenschmidt85f15032005-11-07 01:00:30 -08001046 nvidia_vga_protect(par, 1);
1047
1048 nvidia_write_regs(par);
1049
1050#if defined (__BIG_ENDIAN)
1051 /* turn on LFB swapping */
1052 {
1053 unsigned char tmp;
1054
1055 VGA_WR08(par->PCIO, 0x3d4, 0x46);
1056 tmp = VGA_RD08(par->PCIO, 0x3d5);
1057 tmp |= (1 << 7);
1058 VGA_WR08(par->PCIO, 0x3d5, tmp);
1059 }
1060#endif
1061
Linus Torvalds1da177e2005-04-16 15:20:36 -07001062 info->fix.line_length = (info->var.xres_virtual *
1063 info->var.bits_per_pixel) >> 3;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001064 if (info->var.accel_flags) {
1065 info->fbops->fb_imageblit = nvidiafb_imageblit;
1066 info->fbops->fb_fillrect = nvidiafb_fillrect;
1067 info->fbops->fb_copyarea = nvidiafb_copyarea;
1068 info->fbops->fb_sync = nvidiafb_sync;
1069 info->pixmap.scan_align = 4;
1070 info->flags &= ~FBINFO_HWACCEL_DISABLED;
1071 NVResetGraphics(info);
1072 } else {
1073 info->fbops->fb_imageblit = cfb_imageblit;
1074 info->fbops->fb_fillrect = cfb_fillrect;
1075 info->fbops->fb_copyarea = cfb_copyarea;
1076 info->fbops->fb_sync = NULL;
1077 info->pixmap.scan_align = 1;
1078 info->flags |= FBINFO_HWACCEL_DISABLED;
1079 }
1080
1081 par->cursor_reset = 1;
1082
Benjamin Herrenschmidt85f15032005-11-07 01:00:30 -08001083 nvidia_vga_protect(par, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001084
1085 NVTRACE_LEAVE();
1086 return 0;
1087}
1088
1089static int nvidiafb_setcolreg(unsigned regno, unsigned red, unsigned green,
1090 unsigned blue, unsigned transp,
1091 struct fb_info *info)
1092{
1093 struct nvidia_par *par = info->par;
1094 int i;
1095
1096 NVTRACE_ENTER();
1097 if (regno >= (1 << info->var.green.length))
1098 return -EINVAL;
1099
1100 if (info->var.grayscale) {
1101 /* gray = 0.30*R + 0.59*G + 0.11*B */
1102 red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8;
1103 }
1104
1105 if (regno < 16 && info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
1106 ((u32 *) info->pseudo_palette)[regno] =
1107 (regno << info->var.red.offset) |
1108 (regno << info->var.green.offset) |
1109 (regno << info->var.blue.offset);
1110 }
1111
1112 switch (info->var.bits_per_pixel) {
1113 case 8:
1114 /* "transparent" stuff is completely ignored. */
1115 nvidia_write_clut(par, regno, red >> 8, green >> 8, blue >> 8);
1116 break;
1117 case 16:
1118 if (info->var.green.length == 5) {
1119 for (i = 0; i < 8; i++) {
1120 nvidia_write_clut(par, regno * 8 + i, red >> 8,
1121 green >> 8, blue >> 8);
1122 }
1123 } else {
1124 u8 r, g, b;
1125
1126 if (regno < 32) {
1127 for (i = 0; i < 8; i++) {
1128 nvidia_write_clut(par, regno * 8 + i,
1129 red >> 8, green >> 8,
1130 blue >> 8);
1131 }
1132 }
1133
1134 nvidia_read_clut(par, regno * 4, &r, &g, &b);
1135
1136 for (i = 0; i < 4; i++)
1137 nvidia_write_clut(par, regno * 4 + i, r,
1138 green >> 8, b);
1139 }
1140 break;
1141 case 32:
1142 nvidia_write_clut(par, regno, red >> 8, green >> 8, blue >> 8);
1143 break;
1144 default:
1145 /* do nothing */
1146 break;
1147 }
1148
1149 NVTRACE_LEAVE();
1150 return 0;
1151}
1152
1153static int nvidiafb_check_var(struct fb_var_screeninfo *var,
1154 struct fb_info *info)
1155{
1156 struct nvidia_par *par = info->par;
1157 int memlen, vramlen, mode_valid = 0;
1158 int pitch, err = 0;
1159
1160 NVTRACE_ENTER();
1161
1162 var->transp.offset = 0;
1163 var->transp.length = 0;
1164
1165 var->xres &= ~7;
1166
1167 if (var->bits_per_pixel <= 8)
1168 var->bits_per_pixel = 8;
1169 else if (var->bits_per_pixel <= 16)
1170 var->bits_per_pixel = 16;
1171 else
1172 var->bits_per_pixel = 32;
1173
1174 switch (var->bits_per_pixel) {
1175 case 8:
1176 var->red.offset = 0;
1177 var->red.length = 8;
1178 var->green.offset = 0;
1179 var->green.length = 8;
1180 var->blue.offset = 0;
1181 var->blue.length = 8;
1182 var->transp.offset = 0;
1183 var->transp.length = 0;
1184 break;
1185 case 16:
1186 var->green.length = (var->green.length < 6) ? 5 : 6;
1187 var->red.length = 5;
1188 var->blue.length = 5;
1189 var->transp.length = 6 - var->green.length;
1190 var->blue.offset = 0;
1191 var->green.offset = 5;
1192 var->red.offset = 5 + var->green.length;
1193 var->transp.offset = (5 + var->red.offset) & 15;
1194 break;
1195 case 32: /* RGBA 8888 */
1196 var->red.offset = 16;
1197 var->red.length = 8;
1198 var->green.offset = 8;
1199 var->green.length = 8;
1200 var->blue.offset = 0;
1201 var->blue.length = 8;
1202 var->transp.length = 8;
1203 var->transp.offset = 24;
1204 break;
1205 }
1206
1207 var->red.msb_right = 0;
1208 var->green.msb_right = 0;
1209 var->blue.msb_right = 0;
1210 var->transp.msb_right = 0;
1211
1212 if (!info->monspecs.hfmax || !info->monspecs.vfmax ||
1213 !info->monspecs.dclkmax || !fb_validate_mode(var, info))
1214 mode_valid = 1;
1215
1216 /* calculate modeline if supported by monitor */
1217 if (!mode_valid && info->monspecs.gtf) {
1218 if (!fb_get_mode(FB_MAXTIMINGS, 0, var, info))
1219 mode_valid = 1;
1220 }
1221
1222 if (!mode_valid) {
1223 struct fb_videomode *mode;
1224
1225 mode = fb_find_best_mode(var, &info->modelist);
1226 if (mode) {
1227 fb_videomode_to_var(var, mode);
1228 mode_valid = 1;
1229 }
1230 }
1231
1232 if (!mode_valid && info->monspecs.modedb_len)
1233 return -EINVAL;
1234
1235 if (par->fpWidth && par->fpHeight && (par->fpWidth < var->xres ||
1236 par->fpHeight < var->yres))
1237 return -EINVAL;
1238
1239 if (var->yres_virtual < var->yres)
1240 var->yres_virtual = var->yres;
1241
1242 if (var->xres_virtual < var->xres)
1243 var->xres_virtual = var->xres;
1244
1245 var->xres_virtual = (var->xres_virtual + 63) & ~63;
1246
Antonino A. Daplas917bb072005-05-01 08:59:22 -07001247 vramlen = info->screen_size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001248 pitch = ((var->xres_virtual * var->bits_per_pixel) + 7) / 8;
1249 memlen = pitch * var->yres_virtual;
1250
1251 if (memlen > vramlen) {
1252 var->yres_virtual = vramlen / pitch;
1253
1254 if (var->yres_virtual < var->yres) {
1255 var->yres_virtual = var->yres;
1256 var->xres_virtual = vramlen / var->yres_virtual;
1257 var->xres_virtual /= var->bits_per_pixel / 8;
1258 var->xres_virtual &= ~63;
1259 pitch = (var->xres_virtual *
1260 var->bits_per_pixel + 7) / 8;
1261 memlen = pitch * var->yres;
1262
1263 if (var->xres_virtual < var->xres) {
1264 printk("nvidiafb: required video memory, "
1265 "%d bytes, for %dx%d-%d (virtual) "
1266 "is out of range\n",
1267 memlen, var->xres_virtual,
1268 var->yres_virtual, var->bits_per_pixel);
1269 err = -ENOMEM;
1270 }
1271 }
1272 }
1273
1274 if (var->accel_flags) {
1275 if (var->yres_virtual > 0x7fff)
1276 var->yres_virtual = 0x7fff;
1277 if (var->xres_virtual > 0x7fff)
1278 var->xres_virtual = 0x7fff;
1279 }
1280
1281 var->xres_virtual &= ~63;
1282
1283 NVTRACE_LEAVE();
1284
1285 return err;
1286}
1287
1288static int nvidiafb_pan_display(struct fb_var_screeninfo *var,
1289 struct fb_info *info)
1290{
1291 struct nvidia_par *par = info->par;
1292 u32 total;
1293
1294 total = info->var.yoffset * info->fix.line_length + info->var.xoffset;
1295
1296 NVSetStartAddress(par, total);
1297
1298 return 0;
1299}
1300
1301static int nvidiafb_blank(int blank, struct fb_info *info)
1302{
1303 struct nvidia_par *par = info->par;
1304 unsigned char tmp, vesa;
1305
1306 tmp = NVReadSeq(par, 0x01) & ~0x20; /* screen on/off */
1307 vesa = NVReadCrtc(par, 0x1a) & ~0xc0; /* sync on/off */
1308
1309 NVTRACE_ENTER();
1310
1311 if (blank)
1312 tmp |= 0x20;
1313
1314 switch (blank) {
1315 case FB_BLANK_UNBLANK:
1316 case FB_BLANK_NORMAL:
1317 break;
1318 case FB_BLANK_VSYNC_SUSPEND:
1319 vesa |= 0x80;
1320 break;
1321 case FB_BLANK_HSYNC_SUSPEND:
1322 vesa |= 0x40;
1323 break;
1324 case FB_BLANK_POWERDOWN:
1325 vesa |= 0xc0;
1326 break;
1327 }
1328
1329 NVWriteSeq(par, 0x01, tmp);
1330 NVWriteCrtc(par, 0x1a, vesa);
1331
1332#ifdef CONFIG_PMAC_BACKLIGHT
1333 if (par->FlatPanel && _machine == _MACH_Pmac) {
1334 set_backlight_enable(!blank);
1335 }
1336#endif
1337
1338 NVTRACE_LEAVE();
1339
1340 return 0;
1341}
1342
1343static struct fb_ops nvidia_fb_ops = {
1344 .owner = THIS_MODULE,
1345 .fb_check_var = nvidiafb_check_var,
1346 .fb_set_par = nvidiafb_set_par,
1347 .fb_setcolreg = nvidiafb_setcolreg,
1348 .fb_pan_display = nvidiafb_pan_display,
1349 .fb_blank = nvidiafb_blank,
1350 .fb_fillrect = nvidiafb_fillrect,
1351 .fb_copyarea = nvidiafb_copyarea,
1352 .fb_imageblit = nvidiafb_imageblit,
1353 .fb_cursor = nvidiafb_cursor,
1354 .fb_sync = nvidiafb_sync,
1355};
1356
1357static int __devinit nvidia_set_fbinfo(struct fb_info *info)
1358{
1359 struct fb_monspecs *specs = &info->monspecs;
1360 struct fb_videomode modedb;
1361 struct nvidia_par *par = info->par;
1362 int lpitch;
1363
1364 NVTRACE_ENTER();
1365 info->flags = FBINFO_DEFAULT
1366 | FBINFO_HWACCEL_IMAGEBLIT
1367 | FBINFO_HWACCEL_FILLRECT
1368 | FBINFO_HWACCEL_COPYAREA
1369 | FBINFO_HWACCEL_YPAN;
1370
1371 fb_videomode_to_modelist(info->monspecs.modedb,
1372 info->monspecs.modedb_len, &info->modelist);
1373 fb_var_to_videomode(&modedb, &nvidiafb_default_var);
1374
1375 if (specs->modedb != NULL) {
1376 /* get preferred timing */
1377 if (specs->misc & FB_MISC_1ST_DETAIL) {
1378 int i;
1379
1380 for (i = 0; i < specs->modedb_len; i++) {
1381 if (specs->modedb[i].flag & FB_MODE_IS_FIRST) {
1382 modedb = specs->modedb[i];
1383 break;
1384 }
1385 }
1386 } else {
1387 /* otherwise, get first mode in database */
1388 modedb = specs->modedb[0];
1389 }
1390
1391 fb_videomode_to_var(&nvidiafb_default_var, &modedb);
1392 nvidiafb_default_var.bits_per_pixel = 8;
Antonino Daplasdb6778d2005-08-08 14:22:43 +08001393 } else if (par->fpWidth && par->fpHeight) {
1394 char buf[16];
1395
1396 memset(buf, 0, 16);
Antonino A. Daplas948a95f2005-09-09 13:09:59 -07001397 snprintf(buf, 15, "%dx%dMR", par->fpWidth, par->fpHeight);
Antonino Daplasdb6778d2005-08-08 14:22:43 +08001398 fb_find_mode(&nvidiafb_default_var, info, buf, specs->modedb,
1399 specs->modedb_len, &modedb, 8);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001400 }
1401
1402 if (mode_option)
1403 fb_find_mode(&nvidiafb_default_var, info, mode_option,
1404 specs->modedb, specs->modedb_len, &modedb, 8);
1405
1406 info->var = nvidiafb_default_var;
1407 info->fix.visual = (info->var.bits_per_pixel == 8) ?
1408 FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
1409 info->pseudo_palette = par->pseudo_palette;
1410 fb_alloc_cmap(&info->cmap, 256, 0);
1411 fb_destroy_modedb(info->monspecs.modedb);
1412 info->monspecs.modedb = NULL;
1413
1414 /* maximize virtual vertical length */
1415 lpitch = info->var.xres_virtual *
1416 ((info->var.bits_per_pixel + 7) >> 3);
Antonino A. Daplas917bb072005-05-01 08:59:22 -07001417 info->var.yres_virtual = info->screen_size / lpitch;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001418
1419 info->pixmap.scan_align = 4;
1420 info->pixmap.buf_align = 4;
James Simmons58a60642005-06-21 17:17:08 -07001421 info->pixmap.access_align = 32;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001422 info->pixmap.size = 8 * 1024;
1423 info->pixmap.flags = FB_PIXMAP_SYSTEM;
1424
Antonino A. Daplas7a482422005-09-21 07:30:21 +08001425 if (!hwcur)
1426 info->fbops->fb_cursor = soft_cursor;
1427
Linus Torvalds1da177e2005-04-16 15:20:36 -07001428 info->var.accel_flags = (!noaccel);
1429
1430 switch (par->Architecture) {
1431 case NV_ARCH_04:
1432 info->fix.accel = FB_ACCEL_NV4;
1433 break;
1434 case NV_ARCH_10:
1435 info->fix.accel = FB_ACCEL_NV_10;
1436 break;
1437 case NV_ARCH_20:
1438 info->fix.accel = FB_ACCEL_NV_20;
1439 break;
1440 case NV_ARCH_30:
1441 info->fix.accel = FB_ACCEL_NV_30;
1442 break;
1443 case NV_ARCH_40:
1444 info->fix.accel = FB_ACCEL_NV_40;
1445 break;
1446 }
1447
1448 NVTRACE_LEAVE();
1449
1450 return nvidiafb_check_var(&info->var, info);
1451}
1452
1453static u32 __devinit nvidia_get_arch(struct pci_dev *pd)
1454{
1455 u32 arch = 0;
1456
1457 switch (pd->device & 0x0ff0) {
1458 case 0x0100: /* GeForce 256 */
1459 case 0x0110: /* GeForce2 MX */
1460 case 0x0150: /* GeForce2 */
1461 case 0x0170: /* GeForce4 MX */
1462 case 0x0180: /* GeForce4 MX (8x AGP) */
1463 case 0x01A0: /* nForce */
1464 case 0x01F0: /* nForce2 */
1465 arch = NV_ARCH_10;
1466 break;
1467 case 0x0200: /* GeForce3 */
1468 case 0x0250: /* GeForce4 Ti */
1469 case 0x0280: /* GeForce4 Ti (8x AGP) */
1470 arch = NV_ARCH_20;
1471 break;
1472 case 0x0300: /* GeForceFX 5800 */
1473 case 0x0310: /* GeForceFX 5600 */
1474 case 0x0320: /* GeForceFX 5200 */
1475 case 0x0330: /* GeForceFX 5900 */
1476 case 0x0340: /* GeForceFX 5700 */
1477 arch = NV_ARCH_30;
1478 break;
1479 case 0x0040:
1480 case 0x00C0:
1481 case 0x0120:
1482 case 0x0130:
1483 case 0x0140:
1484 case 0x0160:
1485 case 0x01D0:
1486 case 0x0090:
1487 case 0x0210:
1488 case 0x0220:
1489 case 0x0230:
1490 arch = NV_ARCH_40;
1491 break;
1492 case 0x0020: /* TNT, TNT2 */
1493 arch = NV_ARCH_04;
1494 break;
1495 default: /* unknown architecture */
1496 break;
1497 }
1498
1499 return arch;
1500}
1501
1502static int __devinit nvidiafb_probe(struct pci_dev *pd,
1503 const struct pci_device_id *ent)
1504{
1505 struct nvidia_par *par;
1506 struct fb_info *info;
1507 unsigned short cmd;
1508
1509
1510 NVTRACE_ENTER();
1511 assert(pd != NULL);
1512
1513 info = framebuffer_alloc(sizeof(struct nvidia_par), &pd->dev);
1514
1515 if (!info)
1516 goto err_out;
1517
1518 par = (struct nvidia_par *)info->par;
1519 par->pci_dev = pd;
1520
1521 info->pixmap.addr = kmalloc(8 * 1024, GFP_KERNEL);
1522
1523 if (info->pixmap.addr == NULL)
1524 goto err_out_kfree;
1525
1526 memset(info->pixmap.addr, 0, 8 * 1024);
1527
1528 if (pci_enable_device(pd)) {
1529 printk(KERN_ERR PFX "cannot enable PCI device\n");
1530 goto err_out_enable;
1531 }
1532
1533 if (pci_request_regions(pd, "nvidiafb")) {
1534 printk(KERN_ERR PFX "cannot request PCI regions\n");
1535 goto err_out_request;
1536 }
1537
1538 par->Architecture = nvidia_get_arch(pd);
1539
1540 par->Chipset = (pd->vendor << 16) | pd->device;
1541 printk(KERN_INFO PFX "nVidia device/chipset %X\n", par->Chipset);
1542
Linus Torvalds1da177e2005-04-16 15:20:36 -07001543 if (par->Architecture == 0) {
1544 printk(KERN_ERR PFX "unknown NV_ARCH\n");
1545 goto err_out_free_base0;
1546 }
1547
1548 sprintf(nvidiafb_fix.id, "NV%x", (pd->device & 0x0ff0) >> 4);
1549
1550 par->FlatPanel = flatpanel;
1551
1552 if (flatpanel == 1)
1553 printk(KERN_INFO PFX "flatpanel support enabled\n");
1554
1555 par->CRTCnumber = forceCRTC;
1556 par->FpScale = (!noscale);
1557 par->paneltweak = paneltweak;
1558
1559 /* enable IO and mem if not already done */
1560 pci_read_config_word(pd, PCI_COMMAND, &cmd);
1561 cmd |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
1562 pci_write_config_word(pd, PCI_COMMAND, cmd);
1563
1564 nvidiafb_fix.mmio_start = pci_resource_start(pd, 0);
1565 nvidiafb_fix.smem_start = pci_resource_start(pd, 1);
1566 nvidiafb_fix.mmio_len = pci_resource_len(pd, 0);
1567
1568 par->REGS = ioremap(nvidiafb_fix.mmio_start, nvidiafb_fix.mmio_len);
1569
1570 if (!par->REGS) {
1571 printk(KERN_ERR PFX "cannot ioremap MMIO base\n");
1572 goto err_out_free_base0;
1573 }
1574
1575 NVCommonSetup(info);
1576
1577 par->FbAddress = nvidiafb_fix.smem_start;
1578 par->FbMapSize = par->RamAmountKBytes * 1024;
Antonino A. Daplas917bb072005-05-01 08:59:22 -07001579 if (vram && vram * 1024 * 1024 < par->FbMapSize)
1580 par->FbMapSize = vram * 1024 * 1024;
1581
1582 /* Limit amount of vram to 64 MB */
1583 if (par->FbMapSize > 64 * 1024 * 1024)
1584 par->FbMapSize = 64 * 1024 * 1024;
1585
Linus Torvalds1da177e2005-04-16 15:20:36 -07001586 par->FbUsableSize = par->FbMapSize - (128 * 1024);
1587 par->ScratchBufferSize = (par->Architecture < NV_ARCH_10) ? 8 * 1024 :
1588 16 * 1024;
1589 par->ScratchBufferStart = par->FbUsableSize - par->ScratchBufferSize;
1590 info->screen_base = ioremap(nvidiafb_fix.smem_start, par->FbMapSize);
Antonino A. Daplas917bb072005-05-01 08:59:22 -07001591 info->screen_size = par->FbUsableSize;
1592 nvidiafb_fix.smem_len = par->RamAmountKBytes * 1024;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001593
1594 if (!info->screen_base) {
1595 printk(KERN_ERR PFX "cannot ioremap FB base\n");
1596 goto err_out_free_base1;
1597 }
1598
1599 par->FbStart = info->screen_base;
1600
1601#ifdef CONFIG_MTRR
1602 if (!nomtrr) {
1603 par->mtrr.vram = mtrr_add(nvidiafb_fix.smem_start,
Antonino A. Daplas917bb072005-05-01 08:59:22 -07001604 par->RamAmountKBytes * 1024,
1605 MTRR_TYPE_WRCOMB, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001606 if (par->mtrr.vram < 0) {
1607 printk(KERN_ERR PFX "unable to setup MTRR\n");
1608 } else {
1609 par->mtrr.vram_valid = 1;
1610 /* let there be speed */
1611 printk(KERN_INFO PFX "MTRR set to ON\n");
1612 }
1613 }
1614#endif /* CONFIG_MTRR */
1615
1616 info->fbops = &nvidia_fb_ops;
1617 info->fix = nvidiafb_fix;
1618
1619 if (nvidia_set_fbinfo(info) < 0) {
1620 printk(KERN_ERR PFX "error setting initial video mode\n");
1621 goto err_out_iounmap_fb;
1622 }
1623
1624 nvidia_save_vga(par, &par->SavedReg);
1625
1626 if (register_framebuffer(info) < 0) {
1627 printk(KERN_ERR PFX "error registering nVidia framebuffer\n");
1628 goto err_out_iounmap_fb;
1629 }
1630
1631 pci_set_drvdata(pd, info);
1632
1633 printk(KERN_INFO PFX
1634 "PCI nVidia %s framebuffer (%dMB @ 0x%lX)\n",
1635 info->fix.id,
1636 par->FbMapSize / (1024 * 1024), info->fix.smem_start);
1637#ifdef CONFIG_PMAC_BACKLIGHT
1638 if (par->FlatPanel && _machine == _MACH_Pmac)
1639 register_backlight_controller(&nvidia_backlight_controller,
1640 par, "mnca");
1641#endif
1642 NVTRACE_LEAVE();
1643 return 0;
1644
1645 err_out_iounmap_fb:
1646 iounmap(info->screen_base);
Antonino A. Daplas917bb072005-05-01 08:59:22 -07001647 err_out_free_base1:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001648 fb_destroy_modedb(info->monspecs.modedb);
1649 nvidia_delete_i2c_busses(par);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001650 iounmap(par->REGS);
1651 err_out_free_base0:
1652 pci_release_regions(pd);
1653 err_out_request:
1654 pci_disable_device(pd);
1655 err_out_enable:
1656 kfree(info->pixmap.addr);
1657 err_out_kfree:
1658 framebuffer_release(info);
1659 err_out:
1660 return -ENODEV;
1661}
1662
1663static void __exit nvidiafb_remove(struct pci_dev *pd)
1664{
1665 struct fb_info *info = pci_get_drvdata(pd);
1666 struct nvidia_par *par = info->par;
1667
1668 NVTRACE_ENTER();
1669 if (!info)
1670 return;
1671
1672 unregister_framebuffer(info);
1673#ifdef CONFIG_MTRR
1674 if (par->mtrr.vram_valid)
1675 mtrr_del(par->mtrr.vram, info->fix.smem_start,
1676 info->fix.smem_len);
1677#endif /* CONFIG_MTRR */
1678
1679 iounmap(info->screen_base);
1680 fb_destroy_modedb(info->monspecs.modedb);
1681 nvidia_delete_i2c_busses(par);
1682 iounmap(par->REGS);
1683 pci_release_regions(pd);
1684 pci_disable_device(pd);
1685 kfree(info->pixmap.addr);
1686 framebuffer_release(info);
1687 pci_set_drvdata(pd, NULL);
1688 NVTRACE_LEAVE();
1689}
1690
1691/* ------------------------------------------------------------------------- *
1692 *
1693 * initialization
1694 *
1695 * ------------------------------------------------------------------------- */
1696
1697#ifndef MODULE
1698static int __devinit nvidiafb_setup(char *options)
1699{
1700 char *this_opt;
1701
1702 NVTRACE_ENTER();
1703 if (!options || !*options)
1704 return 0;
1705
1706 while ((this_opt = strsep(&options, ",")) != NULL) {
1707 if (!strncmp(this_opt, "forceCRTC", 9)) {
1708 char *p;
1709
1710 p = this_opt + 9;
1711 if (!*p || !*(++p))
1712 continue;
1713 forceCRTC = *p - '0';
1714 if (forceCRTC < 0 || forceCRTC > 1)
1715 forceCRTC = -1;
1716 } else if (!strncmp(this_opt, "flatpanel", 9)) {
1717 flatpanel = 1;
1718 } else if (!strncmp(this_opt, "hwcur", 5)) {
1719 hwcur = 1;
1720 } else if (!strncmp(this_opt, "noaccel", 6)) {
1721 noaccel = 1;
1722 } else if (!strncmp(this_opt, "noscale", 7)) {
1723 noscale = 1;
1724 } else if (!strncmp(this_opt, "paneltweak:", 11)) {
1725 paneltweak = simple_strtoul(this_opt+11, NULL, 0);
Antonino A. Daplas917bb072005-05-01 08:59:22 -07001726 } else if (!strncmp(this_opt, "vram:", 5)) {
1727 vram = simple_strtoul(this_opt+5, NULL, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001728#ifdef CONFIG_MTRR
1729 } else if (!strncmp(this_opt, "nomtrr", 6)) {
1730 nomtrr = 1;
1731#endif
1732 } else
1733 mode_option = this_opt;
1734 }
1735 NVTRACE_LEAVE();
1736 return 0;
1737}
1738#endif /* !MODULE */
1739
1740static struct pci_driver nvidiafb_driver = {
1741 .name = "nvidiafb",
1742 .id_table = nvidiafb_pci_tbl,
1743 .probe = nvidiafb_probe,
1744 .remove = __exit_p(nvidiafb_remove),
1745};
1746
1747/* ------------------------------------------------------------------------- *
1748 *
1749 * modularization
1750 *
1751 * ------------------------------------------------------------------------- */
1752
1753static int __devinit nvidiafb_init(void)
1754{
1755#ifndef MODULE
1756 char *option = NULL;
1757
1758 if (fb_get_options("nvidiafb", &option))
1759 return -ENODEV;
1760 nvidiafb_setup(option);
1761#endif
1762 return pci_register_driver(&nvidiafb_driver);
1763}
1764
1765module_init(nvidiafb_init);
1766
1767#ifdef MODULE
1768static void __exit nvidiafb_exit(void)
1769{
1770 pci_unregister_driver(&nvidiafb_driver);
1771}
1772
1773module_exit(nvidiafb_exit);
1774
1775module_param(flatpanel, int, 0);
1776MODULE_PARM_DESC(flatpanel,
1777 "Enables experimental flat panel support for some chipsets. "
1778 "(0 or 1=enabled) (default=0)");
1779module_param(hwcur, int, 0);
1780MODULE_PARM_DESC(hwcur,
1781 "Enables hardware cursor implementation. (0 or 1=enabled) "
1782 "(default=0)");
1783module_param(noaccel, int, 0);
1784MODULE_PARM_DESC(noaccel,
1785 "Disables hardware acceleration. (0 or 1=disable) "
1786 "(default=0)");
1787module_param(noscale, int, 0);
1788MODULE_PARM_DESC(noscale,
1789 "Disables screen scaleing. (0 or 1=disable) "
1790 "(default=0, do scaling)");
1791module_param(paneltweak, int, 0);
1792MODULE_PARM_DESC(paneltweak,
1793 "Tweak display settings for flatpanels. "
1794 "(default=0, no tweaks)");
1795module_param(forceCRTC, int, 0);
1796MODULE_PARM_DESC(forceCRTC,
1797 "Forces usage of a particular CRTC in case autodetection "
1798 "fails. (0 or 1) (default=autodetect)");
Antonino A. Daplas917bb072005-05-01 08:59:22 -07001799module_param(vram, int, 0);
1800MODULE_PARM_DESC(vram,
1801 "amount of framebuffer memory to remap in MiB"
1802 "(default=0 - remap entire memory)");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001803#ifdef CONFIG_MTRR
1804module_param(nomtrr, bool, 0);
1805MODULE_PARM_DESC(nomtrr, "Disables MTRR support (0 or 1=disabled) "
1806 "(default=0)");
1807#endif
1808
1809MODULE_AUTHOR("Antonino Daplas");
1810MODULE_DESCRIPTION("Framebuffer driver for nVidia graphics chipset");
1811MODULE_LICENSE("GPL");
1812#endif /* MODULE */
1813