diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/video/tridentfb.c | 526 |
1 files changed, 283 insertions, 243 deletions
diff --git a/drivers/video/tridentfb.c b/drivers/video/tridentfb.c index beefab2992c0..3e8a1ef892ce 100644 --- a/drivers/video/tridentfb.c +++ b/drivers/video/tridentfb.c | |||
@@ -137,28 +137,34 @@ static int iscyber(int id) | |||
137 | 137 | ||
138 | #define CRT 0x3D0 /* CRTC registers offset for color display */ | 138 | #define CRT 0x3D0 /* CRTC registers offset for color display */ |
139 | 139 | ||
140 | #ifndef TRIDENT_MMIO | 140 | static inline void t_outb(struct tridentfb_par *p, u8 val, u16 reg) |
141 | #define TRIDENT_MMIO 1 | 141 | { |
142 | #endif | 142 | fb_writeb(val, p->io_virt + reg); |
143 | 143 | } | |
144 | #if TRIDENT_MMIO | ||
145 | #define t_outb(val, reg) writeb(val,((struct tridentfb_par *)(fb_info.par))->io_virt + reg) | ||
146 | #define t_inb(reg) readb(((struct tridentfb_par*)(fb_info.par))->io_virt + reg) | ||
147 | #else | ||
148 | #define t_outb(val, reg) outb(val, reg) | ||
149 | #define t_inb(reg) inb(reg) | ||
150 | #endif | ||
151 | 144 | ||
145 | static inline u8 t_inb(struct tridentfb_par *p, u16 reg) | ||
146 | { | ||
147 | return fb_readb(p->io_virt + reg); | ||
148 | } | ||
152 | 149 | ||
153 | static struct accel_switch { | 150 | static struct accel_switch { |
154 | void (*init_accel) (int, int); | 151 | void (*init_accel) (struct tridentfb_par *, int, int); |
155 | void (*wait_engine) (void); | 152 | void (*wait_engine) (struct tridentfb_par *); |
156 | void (*fill_rect) (u32, u32, u32, u32, u32, u32); | 153 | void (*fill_rect) |
157 | void (*copy_rect) (u32, u32, u32, u32, u32, u32); | 154 | (struct tridentfb_par *par, u32, u32, u32, u32, u32, u32); |
155 | void (*copy_rect) | ||
156 | (struct tridentfb_par *par, u32, u32, u32, u32, u32, u32); | ||
158 | } *acc; | 157 | } *acc; |
159 | 158 | ||
160 | #define writemmr(r, v) writel(v, ((struct tridentfb_par *)fb_info.par)->io_virt + r) | 159 | static inline void writemmr(struct tridentfb_par *par, u16 r, u32 v) |
161 | #define readmmr(r) readl(((struct tridentfb_par *)fb_info.par)->io_virt + r) | 160 | { |
161 | fb_writel(v, par->io_virt + r); | ||
162 | } | ||
163 | |||
164 | static inline u32 readmmr(struct tridentfb_par *par, u16 r) | ||
165 | { | ||
166 | return fb_readl(par->io_virt + r); | ||
167 | } | ||
162 | 168 | ||
163 | /* | 169 | /* |
164 | * Blade specific acceleration. | 170 | * Blade specific acceleration. |
@@ -176,7 +182,7 @@ static struct accel_switch { | |||
176 | 182 | ||
177 | #define ROP_S 0xCC | 183 | #define ROP_S 0xCC |
178 | 184 | ||
179 | static void blade_init_accel(int pitch, int bpp) | 185 | static void blade_init_accel(struct tridentfb_par *par, int pitch, int bpp) |
180 | { | 186 | { |
181 | int v1 = (pitch >> 3) << 20; | 187 | int v1 = (pitch >> 3) << 20; |
182 | int tmp = 0, v2; | 188 | int tmp = 0, v2; |
@@ -196,33 +202,35 @@ static void blade_init_accel(int pitch, int bpp) | |||
196 | break; | 202 | break; |
197 | } | 203 | } |
198 | v2 = v1 | (tmp << 29); | 204 | v2 = v1 | (tmp << 29); |
199 | writemmr(0x21C0, v2); | 205 | writemmr(par, 0x21C0, v2); |
200 | writemmr(0x21C4, v2); | 206 | writemmr(par, 0x21C4, v2); |
201 | writemmr(0x21B8, v2); | 207 | writemmr(par, 0x21B8, v2); |
202 | writemmr(0x21BC, v2); | 208 | writemmr(par, 0x21BC, v2); |
203 | writemmr(0x21D0, v1); | 209 | writemmr(par, 0x21D0, v1); |
204 | writemmr(0x21D4, v1); | 210 | writemmr(par, 0x21D4, v1); |
205 | writemmr(0x21C8, v1); | 211 | writemmr(par, 0x21C8, v1); |
206 | writemmr(0x21CC, v1); | 212 | writemmr(par, 0x21CC, v1); |
207 | writemmr(0x216C, 0); | 213 | writemmr(par, 0x216C, 0); |
208 | } | 214 | } |
209 | 215 | ||
210 | static void blade_wait_engine(void) | 216 | static void blade_wait_engine(struct tridentfb_par *par) |
211 | { | 217 | { |
212 | while (readmmr(STA) & 0xFA800000) ; | 218 | while (readmmr(par, STA) & 0xFA800000) ; |
213 | } | 219 | } |
214 | 220 | ||
215 | static void blade_fill_rect(u32 x, u32 y, u32 w, u32 h, u32 c, u32 rop) | 221 | static void blade_fill_rect(struct tridentfb_par *par, |
222 | u32 x, u32 y, u32 w, u32 h, u32 c, u32 rop) | ||
216 | { | 223 | { |
217 | writemmr(CLR, c); | 224 | writemmr(par, CLR, c); |
218 | writemmr(ROP, rop ? 0x66 : ROP_S); | 225 | writemmr(par, ROP, rop ? 0x66 : ROP_S); |
219 | writemmr(CMD, 0x20000000 | 1 << 19 | 1 << 4 | 2 << 2); | 226 | writemmr(par, CMD, 0x20000000 | 1 << 19 | 1 << 4 | 2 << 2); |
220 | 227 | ||
221 | writemmr(DR1, point(x, y)); | 228 | writemmr(par, DR1, point(x, y)); |
222 | writemmr(DR2, point(x + w - 1, y + h - 1)); | 229 | writemmr(par, DR2, point(x + w - 1, y + h - 1)); |
223 | } | 230 | } |
224 | 231 | ||
225 | static void blade_copy_rect(u32 x1, u32 y1, u32 x2, u32 y2, u32 w, u32 h) | 232 | static void blade_copy_rect(struct tridentfb_par *par, |
233 | u32 x1, u32 y1, u32 x2, u32 y2, u32 w, u32 h) | ||
226 | { | 234 | { |
227 | u32 s1, s2, d1, d2; | 235 | u32 s1, s2, d1, d2; |
228 | int direction = 2; | 236 | int direction = 2; |
@@ -234,13 +242,13 @@ static void blade_copy_rect(u32 x1, u32 y1, u32 x2, u32 y2, u32 w, u32 h) | |||
234 | if ((y1 > y2) || ((y1 == y2) && (x1 > x2))) | 242 | if ((y1 > y2) || ((y1 == y2) && (x1 > x2))) |
235 | direction = 0; | 243 | direction = 0; |
236 | 244 | ||
237 | writemmr(ROP, ROP_S); | 245 | writemmr(par, ROP, ROP_S); |
238 | writemmr(CMD, 0xE0000000 | 1 << 19 | 1 << 4 | 1 << 2 | direction); | 246 | writemmr(par, CMD, 0xE0000000 | 1 << 19 | 1 << 4 | 1 << 2 | direction); |
239 | 247 | ||
240 | writemmr(SR1, direction ? s2 : s1); | 248 | writemmr(par, SR1, direction ? s2 : s1); |
241 | writemmr(SR2, direction ? s1 : s2); | 249 | writemmr(par, SR2, direction ? s1 : s2); |
242 | writemmr(DR1, direction ? d2 : d1); | 250 | writemmr(par, DR1, direction ? d2 : d1); |
243 | writemmr(DR2, direction ? d1 : d2); | 251 | writemmr(par, DR2, direction ? d1 : d2); |
244 | } | 252 | } |
245 | 253 | ||
246 | static struct accel_switch accel_blade = { | 254 | static struct accel_switch accel_blade = { |
@@ -257,7 +265,7 @@ static struct accel_switch accel_blade = { | |||
257 | #define ROP_P 0xF0 | 265 | #define ROP_P 0xF0 |
258 | #define masked_point(x, y) ((y & 0xffff)<<16|(x & 0xffff)) | 266 | #define masked_point(x, y) ((y & 0xffff)<<16|(x & 0xffff)) |
259 | 267 | ||
260 | static void xp_init_accel(int pitch, int bpp) | 268 | static void xp_init_accel(struct tridentfb_par *par, int pitch, int bpp) |
261 | { | 269 | { |
262 | int tmp = 0, v1; | 270 | int tmp = 0, v1; |
263 | unsigned char x = 0; | 271 | unsigned char x = 0; |
@@ -293,7 +301,7 @@ static void xp_init_accel(int pitch, int bpp) | |||
293 | break; | 301 | break; |
294 | } | 302 | } |
295 | 303 | ||
296 | t_outb(x, 0x2125); | 304 | t_outb(par, x, 0x2125); |
297 | 305 | ||
298 | eng_oper = x | 0x40; | 306 | eng_oper = x | 0x40; |
299 | 307 | ||
@@ -313,12 +321,12 @@ static void xp_init_accel(int pitch, int bpp) | |||
313 | 321 | ||
314 | v1 = pitch << tmp; | 322 | v1 = pitch << tmp; |
315 | 323 | ||
316 | writemmr(0x2154, v1); | 324 | writemmr(par, 0x2154, v1); |
317 | writemmr(0x2150, v1); | 325 | writemmr(par, 0x2150, v1); |
318 | t_outb(3, 0x2126); | 326 | t_outb(par, 3, 0x2126); |
319 | } | 327 | } |
320 | 328 | ||
321 | static void xp_wait_engine(void) | 329 | static void xp_wait_engine(struct tridentfb_par *par) |
322 | { | 330 | { |
323 | int busy; | 331 | int busy; |
324 | int count, timeout; | 332 | int count, timeout; |
@@ -326,7 +334,7 @@ static void xp_wait_engine(void) | |||
326 | count = 0; | 334 | count = 0; |
327 | timeout = 0; | 335 | timeout = 0; |
328 | for (;;) { | 336 | for (;;) { |
329 | busy = t_inb(STA) & 0x80; | 337 | busy = t_inb(par, STA) & 0x80; |
330 | if (busy != 0x80) | 338 | if (busy != 0x80) |
331 | return; | 339 | return; |
332 | count++; | 340 | count++; |
@@ -336,25 +344,27 @@ static void xp_wait_engine(void) | |||
336 | timeout++; | 344 | timeout++; |
337 | if (timeout == 8) { | 345 | if (timeout == 8) { |
338 | /* Reset engine */ | 346 | /* Reset engine */ |
339 | t_outb(0x00, 0x2120); | 347 | t_outb(par, 0x00, 0x2120); |
340 | return; | 348 | return; |
341 | } | 349 | } |
342 | } | 350 | } |
343 | } | 351 | } |
344 | } | 352 | } |
345 | 353 | ||
346 | static void xp_fill_rect(u32 x, u32 y, u32 w, u32 h, u32 c, u32 rop) | 354 | static void xp_fill_rect(struct tridentfb_par *par, |
355 | u32 x, u32 y, u32 w, u32 h, u32 c, u32 rop) | ||
347 | { | 356 | { |
348 | writemmr(0x2127, ROP_P); | 357 | writemmr(par, 0x2127, ROP_P); |
349 | writemmr(0x2158, c); | 358 | writemmr(par, 0x2158, c); |
350 | writemmr(0x2128, 0x4000); | 359 | writemmr(par, 0x2128, 0x4000); |
351 | writemmr(0x2140, masked_point(h, w)); | 360 | writemmr(par, 0x2140, masked_point(h, w)); |
352 | writemmr(0x2138, masked_point(y, x)); | 361 | writemmr(par, 0x2138, masked_point(y, x)); |
353 | t_outb(0x01, 0x2124); | 362 | t_outb(par, 0x01, 0x2124); |
354 | t_outb(eng_oper, 0x2125); | 363 | t_outb(par, eng_oper, 0x2125); |
355 | } | 364 | } |
356 | 365 | ||
357 | static void xp_copy_rect(u32 x1, u32 y1, u32 x2, u32 y2, u32 w, u32 h) | 366 | static void xp_copy_rect(struct tridentfb_par *par, |
367 | u32 x1, u32 y1, u32 x2, u32 y2, u32 w, u32 h) | ||
358 | { | 368 | { |
359 | int direction; | 369 | int direction; |
360 | u32 x1_tmp, x2_tmp, y1_tmp, y2_tmp; | 370 | u32 x1_tmp, x2_tmp, y1_tmp, y2_tmp; |
@@ -379,12 +389,12 @@ static void xp_copy_rect(u32 x1, u32 y1, u32 x2, u32 y2, u32 w, u32 h) | |||
379 | y2_tmp = y2; | 389 | y2_tmp = y2; |
380 | } | 390 | } |
381 | 391 | ||
382 | writemmr(0x2128, direction); | 392 | writemmr(par, 0x2128, direction); |
383 | t_outb(ROP_S, 0x2127); | 393 | t_outb(par, ROP_S, 0x2127); |
384 | writemmr(0x213C, masked_point(y1_tmp, x1_tmp)); | 394 | writemmr(par, 0x213C, masked_point(y1_tmp, x1_tmp)); |
385 | writemmr(0x2138, masked_point(y2_tmp, x2_tmp)); | 395 | writemmr(par, 0x2138, masked_point(y2_tmp, x2_tmp)); |
386 | writemmr(0x2140, masked_point(h, w)); | 396 | writemmr(par, 0x2140, masked_point(h, w)); |
387 | t_outb(0x01, 0x2124); | 397 | t_outb(par, 0x01, 0x2124); |
388 | } | 398 | } |
389 | 399 | ||
390 | static struct accel_switch accel_xp = { | 400 | static struct accel_switch accel_xp = { |
@@ -397,7 +407,7 @@ static struct accel_switch accel_xp = { | |||
397 | /* | 407 | /* |
398 | * Image specific acceleration functions | 408 | * Image specific acceleration functions |
399 | */ | 409 | */ |
400 | static void image_init_accel(int pitch, int bpp) | 410 | static void image_init_accel(struct tridentfb_par *par, int pitch, int bpp) |
401 | { | 411 | { |
402 | int tmp = 0; | 412 | int tmp = 0; |
403 | switch (bpp) { | 413 | switch (bpp) { |
@@ -415,40 +425,42 @@ static void image_init_accel(int pitch, int bpp) | |||
415 | tmp = 2; | 425 | tmp = 2; |
416 | break; | 426 | break; |
417 | } | 427 | } |
418 | writemmr(0x2120, 0xF0000000); | 428 | writemmr(par, 0x2120, 0xF0000000); |
419 | writemmr(0x2120, 0x40000000 | tmp); | 429 | writemmr(par, 0x2120, 0x40000000 | tmp); |
420 | writemmr(0x2120, 0x80000000); | 430 | writemmr(par, 0x2120, 0x80000000); |
421 | writemmr(0x2144, 0x00000000); | 431 | writemmr(par, 0x2144, 0x00000000); |
422 | writemmr(0x2148, 0x00000000); | 432 | writemmr(par, 0x2148, 0x00000000); |
423 | writemmr(0x2150, 0x00000000); | 433 | writemmr(par, 0x2150, 0x00000000); |
424 | writemmr(0x2154, 0x00000000); | 434 | writemmr(par, 0x2154, 0x00000000); |
425 | writemmr(0x2120, 0x60000000 | (pitch << 16) | pitch); | 435 | writemmr(par, 0x2120, 0x60000000 | (pitch << 16) | pitch); |
426 | writemmr(0x216C, 0x00000000); | 436 | writemmr(par, 0x216C, 0x00000000); |
427 | writemmr(0x2170, 0x00000000); | 437 | writemmr(par, 0x2170, 0x00000000); |
428 | writemmr(0x217C, 0x00000000); | 438 | writemmr(par, 0x217C, 0x00000000); |
429 | writemmr(0x2120, 0x10000000); | 439 | writemmr(par, 0x2120, 0x10000000); |
430 | writemmr(0x2130, (2047 << 16) | 2047); | 440 | writemmr(par, 0x2130, (2047 << 16) | 2047); |
431 | } | 441 | } |
432 | 442 | ||
433 | static void image_wait_engine(void) | 443 | static void image_wait_engine(struct tridentfb_par *par) |
434 | { | 444 | { |
435 | while (readmmr(0x2164) & 0xF0000000) ; | 445 | while (readmmr(par, 0x2164) & 0xF0000000) ; |
436 | } | 446 | } |
437 | 447 | ||
438 | static void image_fill_rect(u32 x, u32 y, u32 w, u32 h, u32 c, u32 rop) | 448 | static void image_fill_rect(struct tridentfb_par *par, |
449 | u32 x, u32 y, u32 w, u32 h, u32 c, u32 rop) | ||
439 | { | 450 | { |
440 | writemmr(0x2120, 0x80000000); | 451 | writemmr(par, 0x2120, 0x80000000); |
441 | writemmr(0x2120, 0x90000000 | ROP_S); | 452 | writemmr(par, 0x2120, 0x90000000 | ROP_S); |
442 | 453 | ||
443 | writemmr(0x2144, c); | 454 | writemmr(par, 0x2144, c); |
444 | 455 | ||
445 | writemmr(DR1, point(x, y)); | 456 | writemmr(par, DR1, point(x, y)); |
446 | writemmr(DR2, point(x + w - 1, y + h - 1)); | 457 | writemmr(par, DR2, point(x + w - 1, y + h - 1)); |
447 | 458 | ||
448 | writemmr(0x2124, 0x80000000 | 3 << 22 | 1 << 10 | 1 << 9); | 459 | writemmr(par, 0x2124, 0x80000000 | 3 << 22 | 1 << 10 | 1 << 9); |
449 | } | 460 | } |
450 | 461 | ||
451 | static void image_copy_rect(u32 x1, u32 y1, u32 x2, u32 y2, u32 w, u32 h) | 462 | static void image_copy_rect(struct tridentfb_par *par, |
463 | u32 x1, u32 y1, u32 x2, u32 y2, u32 w, u32 h) | ||
452 | { | 464 | { |
453 | u32 s1, s2, d1, d2; | 465 | u32 s1, s2, d1, d2; |
454 | int direction = 2; | 466 | int direction = 2; |
@@ -460,14 +472,15 @@ static void image_copy_rect(u32 x1, u32 y1, u32 x2, u32 y2, u32 w, u32 h) | |||
460 | if ((y1 > y2) || ((y1 == y2) && (x1 > x2))) | 472 | if ((y1 > y2) || ((y1 == y2) && (x1 > x2))) |
461 | direction = 0; | 473 | direction = 0; |
462 | 474 | ||
463 | writemmr(0x2120, 0x80000000); | 475 | writemmr(par, 0x2120, 0x80000000); |
464 | writemmr(0x2120, 0x90000000 | ROP_S); | 476 | writemmr(par, 0x2120, 0x90000000 | ROP_S); |
465 | 477 | ||
466 | writemmr(SR1, direction ? s2 : s1); | 478 | writemmr(par, SR1, direction ? s2 : s1); |
467 | writemmr(SR2, direction ? s1 : s2); | 479 | writemmr(par, SR2, direction ? s1 : s2); |
468 | writemmr(DR1, direction ? d2 : d1); | 480 | writemmr(par, DR1, direction ? d2 : d1); |
469 | writemmr(DR2, direction ? d1 : d2); | 481 | writemmr(par, DR2, direction ? d1 : d2); |
470 | writemmr(0x2124, 0x80000000 | 1 << 22 | 1 << 10 | 1 << 7 | direction); | 482 | writemmr(par, 0x2124, |
483 | 0x80000000 | 1 << 22 | 1 << 10 | 1 << 7 | direction); | ||
471 | } | 484 | } |
472 | 485 | ||
473 | static struct accel_switch accel_image = { | 486 | static struct accel_switch accel_image = { |
@@ -484,6 +497,7 @@ static struct accel_switch accel_image = { | |||
484 | static void tridentfb_fillrect(struct fb_info *info, | 497 | static void tridentfb_fillrect(struct fb_info *info, |
485 | const struct fb_fillrect *fr) | 498 | const struct fb_fillrect *fr) |
486 | { | 499 | { |
500 | struct tridentfb_par *par = info->par; | ||
487 | int bpp = info->var.bits_per_pixel; | 501 | int bpp = info->var.bits_per_pixel; |
488 | int col = 0; | 502 | int col = 0; |
489 | 503 | ||
@@ -502,14 +516,18 @@ static void tridentfb_fillrect(struct fb_info *info, | |||
502 | break; | 516 | break; |
503 | } | 517 | } |
504 | 518 | ||
505 | acc->fill_rect(fr->dx, fr->dy, fr->width, fr->height, col, fr->rop); | 519 | acc->fill_rect(par, fr->dx, fr->dy, fr->width, |
506 | acc->wait_engine(); | 520 | fr->height, col, fr->rop); |
521 | acc->wait_engine(par); | ||
507 | } | 522 | } |
508 | static void tridentfb_copyarea(struct fb_info *info, | 523 | static void tridentfb_copyarea(struct fb_info *info, |
509 | const struct fb_copyarea *ca) | 524 | const struct fb_copyarea *ca) |
510 | { | 525 | { |
511 | acc->copy_rect(ca->sx, ca->sy, ca->dx, ca->dy, ca->width, ca->height); | 526 | struct tridentfb_par *par = info->par; |
512 | acc->wait_engine(); | 527 | |
528 | acc->copy_rect(par, ca->sx, ca->sy, ca->dx, ca->dy, | ||
529 | ca->width, ca->height); | ||
530 | acc->wait_engine(par); | ||
513 | } | 531 | } |
514 | #else /* !CONFIG_FB_TRIDENT_ACCEL */ | 532 | #else /* !CONFIG_FB_TRIDENT_ACCEL */ |
515 | #define tridentfb_fillrect cfb_fillrect | 533 | #define tridentfb_fillrect cfb_fillrect |
@@ -521,49 +539,51 @@ static void tridentfb_copyarea(struct fb_info *info, | |||
521 | * Hardware access functions | 539 | * Hardware access functions |
522 | */ | 540 | */ |
523 | 541 | ||
524 | static inline unsigned char read3X4(int reg) | 542 | static inline unsigned char read3X4(struct tridentfb_par *par, int reg) |
525 | { | 543 | { |
526 | struct tridentfb_par *par = (struct tridentfb_par *)fb_info.par; | ||
527 | writeb(reg, par->io_virt + CRT + 4); | 544 | writeb(reg, par->io_virt + CRT + 4); |
528 | return readb(par->io_virt + CRT + 5); | 545 | return readb(par->io_virt + CRT + 5); |
529 | } | 546 | } |
530 | 547 | ||
531 | static inline void write3X4(int reg, unsigned char val) | 548 | static inline void write3X4(struct tridentfb_par *par, int reg, |
549 | unsigned char val) | ||
532 | { | 550 | { |
533 | struct tridentfb_par *par = (struct tridentfb_par *)fb_info.par; | ||
534 | writeb(reg, par->io_virt + CRT + 4); | 551 | writeb(reg, par->io_virt + CRT + 4); |
535 | writeb(val, par->io_virt + CRT + 5); | 552 | writeb(val, par->io_virt + CRT + 5); |
536 | } | 553 | } |
537 | 554 | ||
538 | static inline unsigned char read3C4(int reg) | 555 | static inline unsigned char read3C4(struct tridentfb_par *par, int reg) |
539 | { | 556 | { |
540 | t_outb(reg, 0x3C4); | 557 | t_outb(par, reg, 0x3C4); |
541 | return t_inb(0x3C5); | 558 | return t_inb(par, 0x3C5); |
542 | } | 559 | } |
543 | 560 | ||
544 | static inline void write3C4(int reg, unsigned char val) | 561 | static inline void write3C4(struct tridentfb_par *par, int reg, |
562 | unsigned char val) | ||
545 | { | 563 | { |
546 | t_outb(reg, 0x3C4); | 564 | t_outb(par, reg, 0x3C4); |
547 | t_outb(val, 0x3C5); | 565 | t_outb(par, val, 0x3C5); |
548 | } | 566 | } |
549 | 567 | ||
550 | static inline unsigned char read3CE(int reg) | 568 | static inline unsigned char read3CE(struct tridentfb_par *par, int reg) |
551 | { | 569 | { |
552 | t_outb(reg, 0x3CE); | 570 | t_outb(par, reg, 0x3CE); |
553 | return t_inb(0x3CF); | 571 | return t_inb(par, 0x3CF); |
554 | } | 572 | } |
555 | 573 | ||
556 | static inline void writeAttr(int reg, unsigned char val) | 574 | static inline void writeAttr(struct tridentfb_par *par, int reg, |
575 | unsigned char val) | ||
557 | { | 576 | { |
558 | readb(((struct tridentfb_par *)fb_info.par)->io_virt + CRT + 0x0A); /* flip-flop to index */ | 577 | fb_readb(par->io_virt + CRT + 0x0A); /* flip-flop to index */ |
559 | t_outb(reg, 0x3C0); | 578 | t_outb(par, reg, 0x3C0); |
560 | t_outb(val, 0x3C0); | 579 | t_outb(par, val, 0x3C0); |
561 | } | 580 | } |
562 | 581 | ||
563 | static inline void write3CE(int reg, unsigned char val) | 582 | static inline void write3CE(struct tridentfb_par *par, int reg, |
583 | unsigned char val) | ||
564 | { | 584 | { |
565 | t_outb(reg, 0x3CE); | 585 | t_outb(par, reg, 0x3CE); |
566 | t_outb(val, 0x3CF); | 586 | t_outb(par, val, 0x3CF); |
567 | } | 587 | } |
568 | 588 | ||
569 | static void enable_mmio(void) | 589 | static void enable_mmio(void) |
@@ -581,32 +601,35 @@ static void enable_mmio(void) | |||
581 | outb(inb(0x3D5) | 0x01, 0x3D5); | 601 | outb(inb(0x3D5) | 0x01, 0x3D5); |
582 | } | 602 | } |
583 | 603 | ||
584 | static void disable_mmio(void) | 604 | static void disable_mmio(struct tridentfb_par *par) |
585 | { | 605 | { |
586 | /* Goto New Mode */ | 606 | /* Goto New Mode */ |
587 | t_outb(0x0B, 0x3C4); | 607 | t_outb(par, 0x0B, 0x3C4); |
588 | t_inb(0x3C5); | 608 | t_inb(par, 0x3C5); |
589 | 609 | ||
590 | /* Unprotect registers */ | 610 | /* Unprotect registers */ |
591 | t_outb(NewMode1, 0x3C4); | 611 | t_outb(par, NewMode1, 0x3C4); |
592 | t_outb(0x80, 0x3C5); | 612 | t_outb(par, 0x80, 0x3C5); |
593 | 613 | ||
594 | /* Disable MMIO */ | 614 | /* Disable MMIO */ |
595 | t_outb(PCIReg, 0x3D4); | 615 | t_outb(par, PCIReg, 0x3D4); |
596 | t_outb(t_inb(0x3D5) & ~0x01, 0x3D5); | 616 | t_outb(par, t_inb(par, 0x3D5) & ~0x01, 0x3D5); |
597 | } | 617 | } |
598 | 618 | ||
599 | #define crtc_unlock() write3X4(CRTVSyncEnd, read3X4(CRTVSyncEnd) & 0x7F) | 619 | static void crtc_unlock(struct tridentfb_par *par) |
620 | { | ||
621 | write3X4(par, CRTVSyncEnd, read3X4(par, CRTVSyncEnd) & 0x7F); | ||
622 | } | ||
600 | 623 | ||
601 | /* Return flat panel's maximum x resolution */ | 624 | /* Return flat panel's maximum x resolution */ |
602 | static int __devinit get_nativex(void) | 625 | static int __devinit get_nativex(struct tridentfb_par *par) |
603 | { | 626 | { |
604 | int x, y, tmp; | 627 | int x, y, tmp; |
605 | 628 | ||
606 | if (nativex) | 629 | if (nativex) |
607 | return nativex; | 630 | return nativex; |
608 | 631 | ||
609 | tmp = (read3CE(VertStretch) >> 4) & 3; | 632 | tmp = (read3CE(par, VertStretch) >> 4) & 3; |
610 | 633 | ||
611 | switch (tmp) { | 634 | switch (tmp) { |
612 | case 0: | 635 | case 0: |
@@ -632,44 +655,45 @@ static int __devinit get_nativex(void) | |||
632 | } | 655 | } |
633 | 656 | ||
634 | /* Set pitch */ | 657 | /* Set pitch */ |
635 | static void set_lwidth(int width) | 658 | static void set_lwidth(struct tridentfb_par *par, int width) |
636 | { | 659 | { |
637 | write3X4(Offset, width & 0xFF); | 660 | write3X4(par, Offset, width & 0xFF); |
638 | write3X4(AddColReg, | 661 | write3X4(par, AddColReg, |
639 | (read3X4(AddColReg) & 0xCF) | ((width & 0x300) >> 4)); | 662 | (read3X4(par, AddColReg) & 0xCF) | ((width & 0x300) >> 4)); |
640 | } | 663 | } |
641 | 664 | ||
642 | /* For resolutions smaller than FP resolution stretch */ | 665 | /* For resolutions smaller than FP resolution stretch */ |
643 | static void screen_stretch(void) | 666 | static void screen_stretch(struct tridentfb_par *par) |
644 | { | 667 | { |
645 | if (chip_id != CYBERBLADEXPAi1) | 668 | if (chip_id != CYBERBLADEXPAi1) |
646 | write3CE(BiosReg, 0); | 669 | write3CE(par, BiosReg, 0); |
647 | else | 670 | else |
648 | write3CE(BiosReg, 8); | 671 | write3CE(par, BiosReg, 8); |
649 | write3CE(VertStretch, (read3CE(VertStretch) & 0x7C) | 1); | 672 | write3CE(par, VertStretch, (read3CE(par, VertStretch) & 0x7C) | 1); |
650 | write3CE(HorStretch, (read3CE(HorStretch) & 0x7C) | 1); | 673 | write3CE(par, HorStretch, (read3CE(par, HorStretch) & 0x7C) | 1); |
651 | } | 674 | } |
652 | 675 | ||
653 | /* For resolutions smaller than FP resolution center */ | 676 | /* For resolutions smaller than FP resolution center */ |
654 | static void screen_center(void) | 677 | static void screen_center(struct tridentfb_par *par) |
655 | { | 678 | { |
656 | write3CE(VertStretch, (read3CE(VertStretch) & 0x7C) | 0x80); | 679 | write3CE(par, VertStretch, (read3CE(par, VertStretch) & 0x7C) | 0x80); |
657 | write3CE(HorStretch, (read3CE(HorStretch) & 0x7C) | 0x80); | 680 | write3CE(par, HorStretch, (read3CE(par, HorStretch) & 0x7C) | 0x80); |
658 | } | 681 | } |
659 | 682 | ||
660 | /* Address of first shown pixel in display memory */ | 683 | /* Address of first shown pixel in display memory */ |
661 | static void set_screen_start(int base) | 684 | static void set_screen_start(struct tridentfb_par *par, int base) |
662 | { | 685 | { |
663 | write3X4(StartAddrLow, base & 0xFF); | 686 | u8 tmp; |
664 | write3X4(StartAddrHigh, (base & 0xFF00) >> 8); | 687 | write3X4(par, StartAddrLow, base & 0xFF); |
665 | write3X4(CRTCModuleTest, | 688 | write3X4(par, StartAddrHigh, (base & 0xFF00) >> 8); |
666 | (read3X4(CRTCModuleTest) & 0xDF) | ((base & 0x10000) >> 11)); | 689 | tmp = read3X4(par, CRTCModuleTest) & 0xDF; |
667 | write3X4(CRTHiOrd, | 690 | write3X4(par, CRTCModuleTest, tmp | ((base & 0x10000) >> 11)); |
668 | (read3X4(CRTHiOrd) & 0xF8) | ((base & 0xE0000) >> 17)); | 691 | tmp = read3X4(par, CRTHiOrd) & 0xF8; |
692 | write3X4(par, CRTHiOrd, tmp | ((base & 0xE0000) >> 17)); | ||
669 | } | 693 | } |
670 | 694 | ||
671 | /* Set dotclock frequency */ | 695 | /* Set dotclock frequency */ |
672 | static void set_vclk(unsigned long freq) | 696 | static void set_vclk(struct tridentfb_par *par, unsigned long freq) |
673 | { | 697 | { |
674 | int m, n, k; | 698 | int m, n, k; |
675 | unsigned long f, fi, d, di; | 699 | unsigned long f, fi, d, di; |
@@ -690,8 +714,8 @@ static void set_vclk(unsigned long freq) | |||
690 | break; | 714 | break; |
691 | } | 715 | } |
692 | if (chip3D) { | 716 | if (chip3D) { |
693 | write3C4(ClockHigh, hi); | 717 | write3C4(par, ClockHigh, hi); |
694 | write3C4(ClockLow, lo); | 718 | write3C4(par, ClockLow, lo); |
695 | } else { | 719 | } else { |
696 | outb(lo, 0x43C8); | 720 | outb(lo, 0x43C8); |
697 | outb(hi, 0x43C9); | 721 | outb(hi, 0x43C9); |
@@ -700,9 +724,9 @@ static void set_vclk(unsigned long freq) | |||
700 | } | 724 | } |
701 | 725 | ||
702 | /* Set number of lines for flat panels*/ | 726 | /* Set number of lines for flat panels*/ |
703 | static void set_number_of_lines(int lines) | 727 | static void set_number_of_lines(struct tridentfb_par *par, int lines) |
704 | { | 728 | { |
705 | int tmp = read3CE(CyberEnhance) & 0x8F; | 729 | int tmp = read3CE(par, CyberEnhance) & 0x8F; |
706 | if (lines > 1024) | 730 | if (lines > 1024) |
707 | tmp |= 0x50; | 731 | tmp |= 0x50; |
708 | else if (lines > 768) | 732 | else if (lines > 768) |
@@ -711,24 +735,24 @@ static void set_number_of_lines(int lines) | |||
711 | tmp |= 0x20; | 735 | tmp |= 0x20; |
712 | else if (lines > 480) | 736 | else if (lines > 480) |
713 | tmp |= 0x10; | 737 | tmp |= 0x10; |
714 | write3CE(CyberEnhance, tmp); | 738 | write3CE(par, CyberEnhance, tmp); |
715 | } | 739 | } |
716 | 740 | ||
717 | /* | 741 | /* |
718 | * If we see that FP is active we assume we have one. | 742 | * If we see that FP is active we assume we have one. |
719 | * Otherwise we have a CRT display.User can override. | 743 | * Otherwise we have a CRT display.User can override. |
720 | */ | 744 | */ |
721 | static unsigned int __devinit get_displaytype(void) | 745 | static unsigned int __devinit get_displaytype(struct tridentfb_par *par) |
722 | { | 746 | { |
723 | if (fp) | 747 | if (fp) |
724 | return DISPLAY_FP; | 748 | return DISPLAY_FP; |
725 | if (crt || !chipcyber) | 749 | if (crt || !chipcyber) |
726 | return DISPLAY_CRT; | 750 | return DISPLAY_CRT; |
727 | return (read3CE(FPConfig) & 0x10) ? DISPLAY_FP : DISPLAY_CRT; | 751 | return (read3CE(par, FPConfig) & 0x10) ? DISPLAY_FP : DISPLAY_CRT; |
728 | } | 752 | } |
729 | 753 | ||
730 | /* Try detecting the video memory size */ | 754 | /* Try detecting the video memory size */ |
731 | static unsigned int __devinit get_memsize(void) | 755 | static unsigned int __devinit get_memsize(struct tridentfb_par *par) |
732 | { | 756 | { |
733 | unsigned char tmp, tmp2; | 757 | unsigned char tmp, tmp2; |
734 | unsigned int k; | 758 | unsigned int k; |
@@ -742,7 +766,7 @@ static unsigned int __devinit get_memsize(void) | |||
742 | k = 2560 * Kb; | 766 | k = 2560 * Kb; |
743 | break; | 767 | break; |
744 | default: | 768 | default: |
745 | tmp = read3X4(SPR) & 0x0F; | 769 | tmp = read3X4(par, SPR) & 0x0F; |
746 | switch (tmp) { | 770 | switch (tmp) { |
747 | 771 | ||
748 | case 0x01: | 772 | case 0x01: |
@@ -774,7 +798,7 @@ static unsigned int __devinit get_memsize(void) | |||
774 | break; | 798 | break; |
775 | case 0x0E: /* XP */ | 799 | case 0x0E: /* XP */ |
776 | 800 | ||
777 | tmp2 = read3C4(0xC1); | 801 | tmp2 = read3C4(par, 0xC1); |
778 | switch (tmp2) { | 802 | switch (tmp2) { |
779 | case 0x00: | 803 | case 0x00: |
780 | k = 20 * Mb; | 804 | k = 20 * Mb; |
@@ -862,6 +886,7 @@ static int tridentfb_check_var(struct fb_var_screeninfo *var, | |||
862 | static int tridentfb_pan_display(struct fb_var_screeninfo *var, | 886 | static int tridentfb_pan_display(struct fb_var_screeninfo *var, |
863 | struct fb_info *info) | 887 | struct fb_info *info) |
864 | { | 888 | { |
889 | struct tridentfb_par *par = info->par; | ||
865 | unsigned int offset; | 890 | unsigned int offset; |
866 | 891 | ||
867 | debug("enter\n"); | 892 | debug("enter\n"); |
@@ -869,13 +894,20 @@ static int tridentfb_pan_display(struct fb_var_screeninfo *var, | |||
869 | * var->bits_per_pixel / 32; | 894 | * var->bits_per_pixel / 32; |
870 | info->var.xoffset = var->xoffset; | 895 | info->var.xoffset = var->xoffset; |
871 | info->var.yoffset = var->yoffset; | 896 | info->var.yoffset = var->yoffset; |
872 | set_screen_start(offset); | 897 | set_screen_start(par, offset); |
873 | debug("exit\n"); | 898 | debug("exit\n"); |
874 | return 0; | 899 | return 0; |
875 | } | 900 | } |
876 | 901 | ||
877 | #define shadowmode_on() write3CE(CyberControl, read3CE(CyberControl) | 0x81) | 902 | static void shadowmode_on(struct tridentfb_par *par) |
878 | #define shadowmode_off() write3CE(CyberControl, read3CE(CyberControl) & 0x7E) | 903 | { |
904 | write3CE(par, CyberControl, read3CE(par, CyberControl) | 0x81); | ||
905 | } | ||
906 | |||
907 | static void shadowmode_off(struct tridentfb_par *par) | ||
908 | { | ||
909 | write3CE(par, CyberControl, read3CE(par, CyberControl) & 0x7E); | ||
910 | } | ||
879 | 911 | ||
880 | /* Set the hardware to the requested video mode */ | 912 | /* Set the hardware to the requested video mode */ |
881 | static int tridentfb_set_par(struct fb_info *info) | 913 | static int tridentfb_set_par(struct fb_info *info) |
@@ -905,8 +937,8 @@ static int tridentfb_set_par(struct fb_info *info) | |||
905 | vblankstart = var->yres; | 937 | vblankstart = var->yres; |
906 | vblankend = vtotal + 2; | 938 | vblankend = vtotal + 2; |
907 | 939 | ||
908 | crtc_unlock(); | 940 | crtc_unlock(par); |
909 | write3CE(CyberControl, 8); | 941 | write3CE(par, CyberControl, 8); |
910 | 942 | ||
911 | if (flatpanel && var->xres < nativex) { | 943 | if (flatpanel && var->xres < nativex) { |
912 | /* | 944 | /* |
@@ -914,35 +946,36 @@ static int tridentfb_set_par(struct fb_info *info) | |||
914 | * than requested resolution decide whether | 946 | * than requested resolution decide whether |
915 | * we stretch or center | 947 | * we stretch or center |
916 | */ | 948 | */ |
917 | t_outb(0xEB, 0x3C2); | 949 | t_outb(par, 0xEB, 0x3C2); |
918 | 950 | ||
919 | shadowmode_on(); | 951 | shadowmode_on(par); |
920 | 952 | ||
921 | if (center) | 953 | if (center) |
922 | screen_center(); | 954 | screen_center(par); |
923 | else if (stretch) | 955 | else if (stretch) |
924 | screen_stretch(); | 956 | screen_stretch(par); |
925 | 957 | ||
926 | } else { | 958 | } else { |
927 | t_outb(0x2B, 0x3C2); | 959 | t_outb(par, 0x2B, 0x3C2); |
928 | write3CE(CyberControl, 8); | 960 | write3CE(par, CyberControl, 8); |
929 | } | 961 | } |
930 | 962 | ||
931 | /* vertical timing values */ | 963 | /* vertical timing values */ |
932 | write3X4(CRTVTotal, vtotal & 0xFF); | 964 | write3X4(par, CRTVTotal, vtotal & 0xFF); |
933 | write3X4(CRTVDispEnd, vdispend & 0xFF); | 965 | write3X4(par, CRTVDispEnd, vdispend & 0xFF); |
934 | write3X4(CRTVSyncStart, vsyncstart & 0xFF); | 966 | write3X4(par, CRTVSyncStart, vsyncstart & 0xFF); |
935 | write3X4(CRTVSyncEnd, (vsyncend & 0x0F)); | 967 | write3X4(par, CRTVSyncEnd, (vsyncend & 0x0F)); |
936 | write3X4(CRTVBlankStart, vblankstart & 0xFF); | 968 | write3X4(par, CRTVBlankStart, vblankstart & 0xFF); |
937 | write3X4(CRTVBlankEnd, 0 /* p->vblankend & 0xFF */ ); | 969 | write3X4(par, CRTVBlankEnd, 0 /* p->vblankend & 0xFF */); |
938 | 970 | ||
939 | /* horizontal timing values */ | 971 | /* horizontal timing values */ |
940 | write3X4(CRTHTotal, htotal & 0xFF); | 972 | write3X4(par, CRTHTotal, htotal & 0xFF); |
941 | write3X4(CRTHDispEnd, hdispend & 0xFF); | 973 | write3X4(par, CRTHDispEnd, hdispend & 0xFF); |
942 | write3X4(CRTHSyncStart, hsyncstart & 0xFF); | 974 | write3X4(par, CRTHSyncStart, hsyncstart & 0xFF); |
943 | write3X4(CRTHSyncEnd, (hsyncend & 0x1F) | ((hblankend & 0x20) << 2)); | 975 | write3X4(par, CRTHSyncEnd, |
944 | write3X4(CRTHBlankStart, hblankstart & 0xFF); | 976 | (hsyncend & 0x1F) | ((hblankend & 0x20) << 2)); |
945 | write3X4(CRTHBlankEnd, 0 /* (p->hblankend & 0x1F) */ ); | 977 | write3X4(par, CRTHBlankStart, hblankstart & 0xFF); |
978 | write3X4(par, CRTHBlankEnd, 0 /* (p->hblankend & 0x1F) */); | ||
946 | 979 | ||
947 | /* higher bits of vertical timing values */ | 980 | /* higher bits of vertical timing values */ |
948 | tmp = 0x10; | 981 | tmp = 0x10; |
@@ -954,38 +987,40 @@ static int tridentfb_set_par(struct fb_info *info) | |||
954 | if (vtotal & 0x200) tmp |= 0x20; | 987 | if (vtotal & 0x200) tmp |= 0x20; |
955 | if (vdispend & 0x200) tmp |= 0x40; | 988 | if (vdispend & 0x200) tmp |= 0x40; |
956 | if (vsyncstart & 0x200) tmp |= 0x80; | 989 | if (vsyncstart & 0x200) tmp |= 0x80; |
957 | write3X4(CRTOverflow, tmp); | 990 | write3X4(par, CRTOverflow, tmp); |
958 | 991 | ||
959 | tmp = read3X4(CRTHiOrd) | 0x08; /* line compare bit 10 */ | 992 | tmp = read3X4(par, CRTHiOrd) | 0x08; /* line compare bit 10 */ |
960 | if (vtotal & 0x400) tmp |= 0x80; | 993 | if (vtotal & 0x400) tmp |= 0x80; |
961 | if (vblankstart & 0x400) tmp |= 0x40; | 994 | if (vblankstart & 0x400) tmp |= 0x40; |
962 | if (vsyncstart & 0x400) tmp |= 0x20; | 995 | if (vsyncstart & 0x400) tmp |= 0x20; |
963 | if (vdispend & 0x400) tmp |= 0x10; | 996 | if (vdispend & 0x400) tmp |= 0x10; |
964 | write3X4(CRTHiOrd, tmp); | 997 | write3X4(par, CRTHiOrd, tmp); |
965 | 998 | ||
966 | tmp = 0; | 999 | tmp = 0; |
967 | if (htotal & 0x800) tmp |= 0x800 >> 11; | 1000 | if (htotal & 0x800) tmp |= 0x800 >> 11; |
968 | if (hblankstart & 0x800) tmp |= 0x800 >> 7; | 1001 | if (hblankstart & 0x800) tmp |= 0x800 >> 7; |
969 | write3X4(HorizOverflow, tmp); | 1002 | write3X4(par, HorizOverflow, tmp); |
970 | 1003 | ||
971 | tmp = 0x40; | 1004 | tmp = 0x40; |
972 | if (vblankstart & 0x200) tmp |= 0x20; | 1005 | if (vblankstart & 0x200) tmp |= 0x20; |
973 | //FIXME if (info->var.vmode & FB_VMODE_DOUBLE) tmp |= 0x80; /* double scan for 200 line modes */ | 1006 | //FIXME if (info->var.vmode & FB_VMODE_DOUBLE) tmp |= 0x80; /* double scan for 200 line modes */ |
974 | write3X4(CRTMaxScanLine, tmp); | 1007 | write3X4(par, CRTMaxScanLine, tmp); |
975 | 1008 | ||
976 | write3X4(CRTLineCompare, 0xFF); | 1009 | write3X4(par, CRTLineCompare, 0xFF); |
977 | write3X4(CRTPRowScan, 0); | 1010 | write3X4(par, CRTPRowScan, 0); |
978 | write3X4(CRTModeControl, 0xC3); | 1011 | write3X4(par, CRTModeControl, 0xC3); |
979 | 1012 | ||
980 | write3X4(LinearAddReg, 0x20); /* enable linear addressing */ | 1013 | write3X4(par, LinearAddReg, 0x20); /* enable linear addressing */ |
981 | 1014 | ||
982 | tmp = (info->var.vmode & FB_VMODE_INTERLACED) ? 0x84 : 0x80; | 1015 | tmp = (info->var.vmode & FB_VMODE_INTERLACED) ? 0x84 : 0x80; |
983 | write3X4(CRTCModuleTest, tmp); /* enable access extended memory */ | 1016 | /* enable access extended memory */ |
1017 | write3X4(par, CRTCModuleTest, tmp); | ||
984 | 1018 | ||
985 | write3X4(GraphEngReg, 0x80); /* enable GE for text acceleration */ | 1019 | /* enable GE for text acceleration */ |
1020 | write3X4(par, GraphEngReg, 0x80); | ||
986 | 1021 | ||
987 | #ifdef CONFIG_FB_TRIDENT_ACCEL | 1022 | #ifdef CONFIG_FB_TRIDENT_ACCEL |
988 | acc->init_accel(info->var.xres, bpp); | 1023 | acc->init_accel(par, info->var.xres, bpp); |
989 | #endif | 1024 | #endif |
990 | 1025 | ||
991 | switch (bpp) { | 1026 | switch (bpp) { |
@@ -1003,49 +1038,52 @@ static int tridentfb_set_par(struct fb_info *info) | |||
1003 | break; | 1038 | break; |
1004 | } | 1039 | } |
1005 | 1040 | ||
1006 | write3X4(PixelBusReg, tmp); | 1041 | write3X4(par, PixelBusReg, tmp); |
1007 | 1042 | ||
1008 | tmp = 0x10; | 1043 | tmp = 0x10; |
1009 | if (chipcyber) | 1044 | if (chipcyber) |
1010 | tmp |= 0x20; | 1045 | tmp |= 0x20; |
1011 | write3X4(DRAMControl, tmp); /* both IO, linear enable */ | 1046 | write3X4(par, DRAMControl, tmp); /* both IO, linear enable */ |
1012 | 1047 | ||
1013 | write3X4(InterfaceSel, read3X4(InterfaceSel) | 0x40); | 1048 | write3X4(par, InterfaceSel, read3X4(par, InterfaceSel) | 0x40); |
1014 | write3X4(Performance, 0x92); | 1049 | write3X4(par, Performance, 0x92); |
1015 | write3X4(PCIReg, 0x07); /* MMIO & PCI read and write burst enable */ | 1050 | /* MMIO & PCI read and write burst enable */ |
1051 | write3X4(par, PCIReg, 0x07); | ||
1016 | 1052 | ||
1017 | /* convert from picoseconds to kHz */ | 1053 | /* convert from picoseconds to kHz */ |
1018 | vclk = PICOS2KHZ(info->var.pixclock); | 1054 | vclk = PICOS2KHZ(info->var.pixclock); |
1019 | if (bpp == 32) | 1055 | if (bpp == 32) |
1020 | vclk *= 2; | 1056 | vclk *= 2; |
1021 | set_vclk(vclk); | 1057 | set_vclk(par, vclk); |
1022 | 1058 | ||
1023 | write3C4(0, 3); | 1059 | write3C4(par, 0, 3); |
1024 | write3C4(1, 1); /* set char clock 8 dots wide */ | 1060 | write3C4(par, 1, 1); /* set char clock 8 dots wide */ |
1025 | write3C4(2, 0x0F); /* enable 4 maps because needed in chain4 mode */ | 1061 | /* enable 4 maps because needed in chain4 mode */ |
1026 | write3C4(3, 0); | 1062 | write3C4(par, 2, 0x0F); |
1027 | write3C4(4, 0x0E); /* memory mode enable bitmaps ?? */ | 1063 | write3C4(par, 3, 0); |
1064 | write3C4(par, 4, 0x0E); /* memory mode enable bitmaps ?? */ | ||
1028 | 1065 | ||
1029 | write3CE(MiscExtFunc, (bpp == 32) ? 0x1A : 0x12); /* divide clock by 2 if 32bpp */ | 1066 | /* divide clock by 2 if 32bpp chain4 mode display and CPU path */ |
1030 | /* chain4 mode display and CPU path */ | 1067 | write3CE(par, MiscExtFunc, (bpp == 32) ? 0x1A : 0x12); |
1031 | write3CE(0x5, 0x40); /* no CGA compat, allow 256 col */ | 1068 | write3CE(par, 0x5, 0x40); /* no CGA compat, allow 256 col */ |
1032 | write3CE(0x6, 0x05); /* graphics mode */ | 1069 | write3CE(par, 0x6, 0x05); /* graphics mode */ |
1033 | write3CE(0x7, 0x0F); /* planes? */ | 1070 | write3CE(par, 0x7, 0x0F); /* planes? */ |
1034 | 1071 | ||
1035 | if (chip_id == CYBERBLADEXPAi1) { | 1072 | if (chip_id == CYBERBLADEXPAi1) { |
1036 | /* This fixes snow-effect in 32 bpp */ | 1073 | /* This fixes snow-effect in 32 bpp */ |
1037 | write3X4(CRTHSyncStart, 0x84); | 1074 | write3X4(par, CRTHSyncStart, 0x84); |
1038 | } | 1075 | } |
1039 | 1076 | ||
1040 | writeAttr(0x10, 0x41); /* graphics mode and support 256 color modes */ | 1077 | /* graphics mode and support 256 color modes */ |
1041 | writeAttr(0x12, 0x0F); /* planes */ | 1078 | writeAttr(par, 0x10, 0x41); |
1042 | writeAttr(0x13, 0); /* horizontal pel panning */ | 1079 | writeAttr(par, 0x12, 0x0F); /* planes */ |
1080 | writeAttr(par, 0x13, 0); /* horizontal pel panning */ | ||
1043 | 1081 | ||
1044 | /* colors */ | 1082 | /* colors */ |
1045 | for (tmp = 0; tmp < 0x10; tmp++) | 1083 | for (tmp = 0; tmp < 0x10; tmp++) |
1046 | writeAttr(tmp, tmp); | 1084 | writeAttr(par, tmp, tmp); |
1047 | readb(par->io_virt + CRT + 0x0A); /* flip-flop to index */ | 1085 | fb_readb(par->io_virt + CRT + 0x0A); /* flip-flop to index */ |
1048 | t_outb(0x20, 0x3C0); /* enable attr */ | 1086 | t_outb(par, 0x20, 0x3C0); /* enable attr */ |
1049 | 1087 | ||
1050 | switch (bpp) { | 1088 | switch (bpp) { |
1051 | case 8: | 1089 | case 8: |
@@ -1063,17 +1101,17 @@ static int tridentfb_set_par(struct fb_info *info) | |||
1063 | break; | 1101 | break; |
1064 | } | 1102 | } |
1065 | 1103 | ||
1066 | t_inb(0x3C8); | 1104 | t_inb(par, 0x3C8); |
1067 | t_inb(0x3C6); | 1105 | t_inb(par, 0x3C6); |
1068 | t_inb(0x3C6); | 1106 | t_inb(par, 0x3C6); |
1069 | t_inb(0x3C6); | 1107 | t_inb(par, 0x3C6); |
1070 | t_inb(0x3C6); | 1108 | t_inb(par, 0x3C6); |
1071 | t_outb(tmp, 0x3C6); | 1109 | t_outb(par, tmp, 0x3C6); |
1072 | t_inb(0x3C8); | 1110 | t_inb(par, 0x3C8); |
1073 | 1111 | ||
1074 | if (flatpanel) | 1112 | if (flatpanel) |
1075 | set_number_of_lines(info->var.yres); | 1113 | set_number_of_lines(par, info->var.yres); |
1076 | set_lwidth(info->var.xres * bpp / (4 * 16)); | 1114 | set_lwidth(par, info->var.xres * bpp / (4 * 16)); |
1077 | info->fix.visual = (bpp == 8) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR; | 1115 | info->fix.visual = (bpp == 8) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR; |
1078 | info->fix.line_length = info->var.xres * (bpp >> 3); | 1116 | info->fix.line_length = info->var.xres * (bpp >> 3); |
1079 | info->cmap.len = (bpp == 8) ? 256 : 16; | 1117 | info->cmap.len = (bpp == 8) ? 256 : 16; |
@@ -1087,17 +1125,18 @@ static int tridentfb_setcolreg(unsigned regno, unsigned red, unsigned green, | |||
1087 | struct fb_info *info) | 1125 | struct fb_info *info) |
1088 | { | 1126 | { |
1089 | int bpp = info->var.bits_per_pixel; | 1127 | int bpp = info->var.bits_per_pixel; |
1128 | struct tridentfb_par *par = info->par; | ||
1090 | 1129 | ||
1091 | if (regno >= info->cmap.len) | 1130 | if (regno >= info->cmap.len) |
1092 | return 1; | 1131 | return 1; |
1093 | 1132 | ||
1094 | if (bpp == 8) { | 1133 | if (bpp == 8) { |
1095 | t_outb(0xFF, 0x3C6); | 1134 | t_outb(par, 0xFF, 0x3C6); |
1096 | t_outb(regno, 0x3C8); | 1135 | t_outb(par, regno, 0x3C8); |
1097 | 1136 | ||
1098 | t_outb(red >> 10, 0x3C9); | 1137 | t_outb(par, red >> 10, 0x3C9); |
1099 | t_outb(green >> 10, 0x3C9); | 1138 | t_outb(par, green >> 10, 0x3C9); |
1100 | t_outb(blue >> 10, 0x3C9); | 1139 | t_outb(par, blue >> 10, 0x3C9); |
1101 | 1140 | ||
1102 | } else if (regno < 16) { | 1141 | } else if (regno < 16) { |
1103 | if (bpp == 16) { /* RGB 565 */ | 1142 | if (bpp == 16) { /* RGB 565 */ |
@@ -1123,13 +1162,14 @@ static int tridentfb_setcolreg(unsigned regno, unsigned red, unsigned green, | |||
1123 | static int tridentfb_blank(int blank_mode, struct fb_info *info) | 1162 | static int tridentfb_blank(int blank_mode, struct fb_info *info) |
1124 | { | 1163 | { |
1125 | unsigned char PMCont, DPMSCont; | 1164 | unsigned char PMCont, DPMSCont; |
1165 | struct tridentfb_par *par = info->par; | ||
1126 | 1166 | ||
1127 | debug("enter\n"); | 1167 | debug("enter\n"); |
1128 | if (flatpanel) | 1168 | if (flatpanel) |
1129 | return 0; | 1169 | return 0; |
1130 | t_outb(0x04, 0x83C8); /* Read DPMS Control */ | 1170 | t_outb(par, 0x04, 0x83C8); /* Read DPMS Control */ |
1131 | PMCont = t_inb(0x83C6) & 0xFC; | 1171 | PMCont = t_inb(par, 0x83C6) & 0xFC; |
1132 | DPMSCont = read3CE(PowerStatus) & 0xFC; | 1172 | DPMSCont = read3CE(par, PowerStatus) & 0xFC; |
1133 | switch (blank_mode) { | 1173 | switch (blank_mode) { |
1134 | case FB_BLANK_UNBLANK: | 1174 | case FB_BLANK_UNBLANK: |
1135 | /* Screen: On, HSync: On, VSync: On */ | 1175 | /* Screen: On, HSync: On, VSync: On */ |
@@ -1155,9 +1195,9 @@ static int tridentfb_blank(int blank_mode, struct fb_info *info) | |||
1155 | break; | 1195 | break; |
1156 | } | 1196 | } |
1157 | 1197 | ||
1158 | write3CE(PowerStatus, DPMSCont); | 1198 | write3CE(par, PowerStatus, DPMSCont); |
1159 | t_outb(4, 0x83C8); | 1199 | t_outb(par, 4, 0x83C8); |
1160 | t_outb(PMCont, 0x83C6); | 1200 | t_outb(par, PMCont, 0x83C6); |
1161 | 1201 | ||
1162 | debug("exit\n"); | 1202 | debug("exit\n"); |
1163 | 1203 | ||
@@ -1265,11 +1305,11 @@ static int __devinit trident_pci_probe(struct pci_dev * dev, | |||
1265 | 1305 | ||
1266 | /* setup framebuffer memory */ | 1306 | /* setup framebuffer memory */ |
1267 | tridentfb_fix.smem_start = pci_resource_start(dev, 0); | 1307 | tridentfb_fix.smem_start = pci_resource_start(dev, 0); |
1268 | tridentfb_fix.smem_len = get_memsize(); | 1308 | tridentfb_fix.smem_len = get_memsize(&default_par); |
1269 | 1309 | ||
1270 | if (!request_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len, "tridentfb")) { | 1310 | if (!request_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len, "tridentfb")) { |
1271 | debug("request_mem_region failed!\n"); | 1311 | debug("request_mem_region failed!\n"); |
1272 | disable_mmio(); | 1312 | disable_mmio(fb_info.par); |
1273 | err = -1; | 1313 | err = -1; |
1274 | goto out_unmap1; | 1314 | goto out_unmap1; |
1275 | } | 1315 | } |
@@ -1284,10 +1324,10 @@ static int __devinit trident_pci_probe(struct pci_dev * dev, | |||
1284 | } | 1324 | } |
1285 | 1325 | ||
1286 | output("%s board found\n", pci_name(dev)); | 1326 | output("%s board found\n", pci_name(dev)); |
1287 | displaytype = get_displaytype(); | 1327 | displaytype = get_displaytype(&default_par); |
1288 | 1328 | ||
1289 | if (flatpanel) | 1329 | if (flatpanel) |
1290 | nativex = get_nativex(); | 1330 | nativex = get_nativex(&default_par); |
1291 | 1331 | ||
1292 | fb_info.fix = tridentfb_fix; | 1332 | fb_info.fix = tridentfb_fix; |
1293 | fb_info.fbops = &tridentfb_ops; | 1333 | fb_info.fbops = &tridentfb_ops; |
@@ -1330,7 +1370,7 @@ out_unmap2: | |||
1330 | if (fb_info.screen_base) | 1370 | if (fb_info.screen_base) |
1331 | iounmap(fb_info.screen_base); | 1371 | iounmap(fb_info.screen_base); |
1332 | release_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len); | 1372 | release_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len); |
1333 | disable_mmio(); | 1373 | disable_mmio(fb_info.par); |
1334 | out_unmap1: | 1374 | out_unmap1: |
1335 | if (default_par.io_virt) | 1375 | if (default_par.io_virt) |
1336 | iounmap(default_par.io_virt); | 1376 | iounmap(default_par.io_virt); |