aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFlorian Tobias Schandinat <FlorianSchandinat@gmx.de>2009-09-22 19:47:31 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-09-23 10:39:53 -0400
commit31de59d5e1cd6968ea9d1a19cceefb7a037e46bf (patch)
treef9a081a1c850cfc931af25c6d40fb3b55efb24b5
parent2d6e8851f608bd0c811f2df83eeff4ad8631e723 (diff)
viafb: hardware acceleration initialization cleanup
The main motivation of this patch was to merge the three initialization functions in one and clean it up. However as some changes in other code areas where needed to do it right some small other changes were made. Changes to viafb_par: io_virt renamed as engine_mmio and moved to shared VQ_start renamed as vq_vram_addr and moved to shared VQ_end removed as it is easily recalculatable vq_vram_addr is not strictly needed but keep it to track where we allocated video memory. The memory allocated for the virtual queue was shrunk to VQ_SIZE as VQ_SIZE+CURSOR_SIZE looked like a bug to me. But to be honest I don't have the faintest idea what virtual queues are for in the graphic hardware and whether the driver needs them in any way. I only know that they aren't directly accessed by the driver and so the only potential current use would be as hardware internal buffers. For now keep them to avoid regressions and only remove the double cursor allocation. The most changes were caused by renames and the mentioned structure changes so the chance of regressions is pretty low. The meaning of viafb_accel changed slightly as previously it was changed back and forth in the code and allowed to enable the hardware acceleration by software if previously disabled. The new behaviour is that viafb_accel=0 always prevents hardware acceleration. With viafb_accel!=0 the acceleration can be freely choosen by set_var. This means viafb_accel is a diagnostic tool and if someone has to use viafb_accel=0 the driver needs to be fixed. As this is mostly a code cleanup no regressions beside the slightly change of viafb_accel is expected. Signed-off-by: Florian Tobias Schandinat <FlorianSchandinat@gmx.de> Cc: Scott Fang <ScottFang@viatech.com.cn> Cc: Joseph Chan <JosephChan@via.com.tw> Cc: Harald Welte <laforge@gnumonks.org> Cc: Jonathan Corbet <corbet@lwn.net> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--drivers/video/via/accel.c268
-rw-r--r--drivers/video/via/accel.h8
-rw-r--r--drivers/video/via/global.c1
-rw-r--r--drivers/video/via/hw.h1
-rw-r--r--drivers/video/via/viafbdev.c80
-rw-r--r--drivers/video/via/viafbdev.h7
6 files changed, 148 insertions, 217 deletions
diff --git a/drivers/video/via/accel.c b/drivers/video/via/accel.c
index 503f9d8e5bd0..42ab4b425679 100644
--- a/drivers/video/via/accel.c
+++ b/drivers/video/via/accel.c
@@ -308,9 +308,22 @@ static int hw_bitblt_2(void __iomem *engine, u8 op, u32 width, u32 height,
308 return 0; 308 return 0;
309} 309}
310 310
311void viafb_init_accel(struct viafb_shared *shared) 311int viafb_init_engine(struct fb_info *info)
312{ 312{
313 switch (shared->chip_info.gfx_chip_name) { 313 struct viafb_par *viapar = info->par;
314 void __iomem *engine;
315 u32 vq_start_addr, vq_end_addr, vq_start_low, vq_end_low, vq_high,
316 vq_len, chip_name = viapar->shared->chip_info.gfx_chip_name;
317
318 engine = ioremap_nocache(info->fix.mmio_start, info->fix.mmio_len);
319 viapar->shared->engine_mmio = engine;
320 if (!engine) {
321 printk(KERN_WARNING "viafb_init_accel: ioremap failed, "
322 "hardware acceleration disabled\n");
323 return -ENOMEM;
324 }
325
326 switch (chip_name) {
314 case UNICHROME_CLE266: 327 case UNICHROME_CLE266:
315 case UNICHROME_K400: 328 case UNICHROME_K400:
316 case UNICHROME_K800: 329 case UNICHROME_K800:
@@ -321,186 +334,115 @@ void viafb_init_accel(struct viafb_shared *shared)
321 case UNICHROME_K8M890: 334 case UNICHROME_K8M890:
322 case UNICHROME_P4M890: 335 case UNICHROME_P4M890:
323 case UNICHROME_P4M900: 336 case UNICHROME_P4M900:
324 shared->hw_bitblt = hw_bitblt_1; 337 viapar->shared->hw_bitblt = hw_bitblt_1;
325 break; 338 break;
326 case UNICHROME_VX800: 339 case UNICHROME_VX800:
327 shared->hw_bitblt = hw_bitblt_2; 340 viapar->shared->hw_bitblt = hw_bitblt_2;
328 break; 341 break;
329 default: 342 default:
330 shared->hw_bitblt = NULL; 343 viapar->shared->hw_bitblt = NULL;
331 } 344 }
332 345
333 viaparinfo->fbmem_free -= CURSOR_SIZE; 346 viapar->fbmem_free -= CURSOR_SIZE;
334 shared->cursor_vram_addr = viaparinfo->fbmem_free; 347 viapar->shared->cursor_vram_addr = viapar->fbmem_free;
335 viaparinfo->fbmem_used += CURSOR_SIZE; 348 viapar->fbmem_used += CURSOR_SIZE;
336 349
337 /* Reverse 8*1024 memory space for cursor image */ 350 viapar->fbmem_free -= VQ_SIZE;
338 viaparinfo->fbmem_free -= (CURSOR_SIZE + VQ_SIZE); 351 viapar->shared->vq_vram_addr = viapar->fbmem_free;
339 viaparinfo->VQ_start = viaparinfo->fbmem_free; 352 viapar->fbmem_used += VQ_SIZE;
340 viaparinfo->VQ_end = viaparinfo->VQ_start + VQ_SIZE - 1;
341 viaparinfo->fbmem_used += (CURSOR_SIZE + VQ_SIZE);
342}
343
344void viafb_init_2d_engine(void)
345{
346 u32 dwVQStartAddr, dwVQEndAddr;
347 u32 dwVQLen, dwVQStartL, dwVQEndL, dwVQStartEndH;
348 353
349 /* Init AGP and VQ regs */ 354 /* Init AGP and VQ regs */
350 switch (viaparinfo->chip_info->gfx_chip_name) { 355 switch (chip_name) {
351 case UNICHROME_K8M890: 356 case UNICHROME_K8M890:
352 case UNICHROME_P4M900: 357 case UNICHROME_P4M900:
353 writel(0x00100000, viaparinfo->io_virt + VIA_REG_CR_TRANSET); 358 writel(0x00100000, engine + VIA_REG_CR_TRANSET);
354 writel(0x680A0000, viaparinfo->io_virt + VIA_REG_CR_TRANSPACE); 359 writel(0x680A0000, engine + VIA_REG_CR_TRANSPACE);
355 writel(0x02000000, viaparinfo->io_virt + VIA_REG_CR_TRANSPACE); 360 writel(0x02000000, engine + VIA_REG_CR_TRANSPACE);
356 break; 361 break;
357 362
358 default: 363 default:
359 writel(0x00100000, viaparinfo->io_virt + VIA_REG_TRANSET); 364 writel(0x00100000, engine + VIA_REG_TRANSET);
360 writel(0x00000000, viaparinfo->io_virt + VIA_REG_TRANSPACE); 365 writel(0x00000000, engine + VIA_REG_TRANSPACE);
361 writel(0x00333004, viaparinfo->io_virt + VIA_REG_TRANSPACE); 366 writel(0x00333004, engine + VIA_REG_TRANSPACE);
362 writel(0x60000000, viaparinfo->io_virt + VIA_REG_TRANSPACE); 367 writel(0x60000000, engine + VIA_REG_TRANSPACE);
363 writel(0x61000000, viaparinfo->io_virt + VIA_REG_TRANSPACE); 368 writel(0x61000000, engine + VIA_REG_TRANSPACE);
364 writel(0x62000000, viaparinfo->io_virt + VIA_REG_TRANSPACE); 369 writel(0x62000000, engine + VIA_REG_TRANSPACE);
365 writel(0x63000000, viaparinfo->io_virt + VIA_REG_TRANSPACE); 370 writel(0x63000000, engine + VIA_REG_TRANSPACE);
366 writel(0x64000000, viaparinfo->io_virt + VIA_REG_TRANSPACE); 371 writel(0x64000000, engine + VIA_REG_TRANSPACE);
367 writel(0x7D000000, viaparinfo->io_virt + VIA_REG_TRANSPACE); 372 writel(0x7D000000, engine + VIA_REG_TRANSPACE);
368 373
369 writel(0xFE020000, viaparinfo->io_virt + VIA_REG_TRANSET); 374 writel(0xFE020000, engine + VIA_REG_TRANSET);
370 writel(0x00000000, viaparinfo->io_virt + VIA_REG_TRANSPACE); 375 writel(0x00000000, engine + VIA_REG_TRANSPACE);
371 break; 376 break;
372 } 377 }
373 if (viaparinfo->VQ_start != 0) {
374 /* Enable VQ */
375 dwVQStartAddr = viaparinfo->VQ_start;
376 dwVQEndAddr = viaparinfo->VQ_end;
377
378 dwVQStartL = 0x50000000 | (dwVQStartAddr & 0xFFFFFF);
379 dwVQEndL = 0x51000000 | (dwVQEndAddr & 0xFFFFFF);
380 dwVQStartEndH = 0x52000000 |
381 ((dwVQStartAddr & 0xFF000000) >> 24) |
382 ((dwVQEndAddr & 0xFF000000) >> 16);
383 dwVQLen = 0x53000000 | (VQ_SIZE >> 3);
384 switch (viaparinfo->chip_info->gfx_chip_name) {
385 case UNICHROME_K8M890:
386 case UNICHROME_P4M900:
387 dwVQStartL |= 0x20000000;
388 dwVQEndL |= 0x20000000;
389 dwVQStartEndH |= 0x20000000;
390 dwVQLen |= 0x20000000;
391 break;
392 default:
393 break;
394 }
395 378
396 switch (viaparinfo->chip_info->gfx_chip_name) { 379 /* Enable VQ */
397 case UNICHROME_K8M890: 380 vq_start_addr = viapar->shared->vq_vram_addr;
398 case UNICHROME_P4M900: 381 vq_end_addr = viapar->shared->vq_vram_addr + VQ_SIZE - 1;
399 writel(0x00100000, 382
400 viaparinfo->io_virt + VIA_REG_CR_TRANSET); 383 vq_start_low = 0x50000000 | (vq_start_addr & 0xFFFFFF);
401 writel(dwVQStartEndH, 384 vq_end_low = 0x51000000 | (vq_end_addr & 0xFFFFFF);
402 viaparinfo->io_virt + VIA_REG_CR_TRANSPACE); 385 vq_high = 0x52000000 | ((vq_start_addr & 0xFF000000) >> 24) |
403 writel(dwVQStartL, 386 ((vq_end_addr & 0xFF000000) >> 16);
404 viaparinfo->io_virt + VIA_REG_CR_TRANSPACE); 387 vq_len = 0x53000000 | (VQ_SIZE >> 3);
405 writel(dwVQEndL, 388
406 viaparinfo->io_virt + VIA_REG_CR_TRANSPACE); 389 switch (chip_name) {
407 writel(dwVQLen, 390 case UNICHROME_K8M890:
408 viaparinfo->io_virt + VIA_REG_CR_TRANSPACE); 391 case UNICHROME_P4M900:
409 writel(0x74301001, 392 vq_start_low |= 0x20000000;
410 viaparinfo->io_virt + VIA_REG_CR_TRANSPACE); 393 vq_end_low |= 0x20000000;
411 writel(0x00000000, 394 vq_high |= 0x20000000;
412 viaparinfo->io_virt + VIA_REG_CR_TRANSPACE); 395 vq_len |= 0x20000000;
413 break; 396
414 default: 397 writel(0x00100000, engine + VIA_REG_CR_TRANSET);
415 writel(0x00FE0000, 398 writel(vq_high, engine + VIA_REG_CR_TRANSPACE);
416 viaparinfo->io_virt + VIA_REG_TRANSET); 399 writel(vq_start_low, engine + VIA_REG_CR_TRANSPACE);
417 writel(0x080003FE, 400 writel(vq_end_low, engine + VIA_REG_CR_TRANSPACE);
418 viaparinfo->io_virt + VIA_REG_TRANSPACE); 401 writel(vq_len, engine + VIA_REG_CR_TRANSPACE);
419 writel(0x0A00027C, 402 writel(0x74301001, engine + VIA_REG_CR_TRANSPACE);
420 viaparinfo->io_virt + VIA_REG_TRANSPACE); 403 writel(0x00000000, engine + VIA_REG_CR_TRANSPACE);
421 writel(0x0B000260, 404 break;
422 viaparinfo->io_virt + VIA_REG_TRANSPACE); 405 default:
423 writel(0x0C000274, 406 writel(0x00FE0000, engine + VIA_REG_TRANSET);
424 viaparinfo->io_virt + VIA_REG_TRANSPACE); 407 writel(0x080003FE, engine + VIA_REG_TRANSPACE);
425 writel(0x0D000264, 408 writel(0x0A00027C, engine + VIA_REG_TRANSPACE);
426 viaparinfo->io_virt + VIA_REG_TRANSPACE); 409 writel(0x0B000260, engine + VIA_REG_TRANSPACE);
427 writel(0x0E000000, 410 writel(0x0C000274, engine + VIA_REG_TRANSPACE);
428 viaparinfo->io_virt + VIA_REG_TRANSPACE); 411 writel(0x0D000264, engine + VIA_REG_TRANSPACE);
429 writel(0x0F000020, 412 writel(0x0E000000, engine + VIA_REG_TRANSPACE);
430 viaparinfo->io_virt + VIA_REG_TRANSPACE); 413 writel(0x0F000020, engine + VIA_REG_TRANSPACE);
431 writel(0x1000027E, 414 writel(0x1000027E, engine + VIA_REG_TRANSPACE);
432 viaparinfo->io_virt + VIA_REG_TRANSPACE); 415 writel(0x110002FE, engine + VIA_REG_TRANSPACE);
433 writel(0x110002FE, 416 writel(0x200F0060, engine + VIA_REG_TRANSPACE);
434 viaparinfo->io_virt + VIA_REG_TRANSPACE); 417
435 writel(0x200F0060, 418 writel(0x00000006, engine + VIA_REG_TRANSPACE);
436 viaparinfo->io_virt + VIA_REG_TRANSPACE); 419 writel(0x40008C0F, engine + VIA_REG_TRANSPACE);
437 420 writel(0x44000000, engine + VIA_REG_TRANSPACE);
438 writel(0x00000006, 421 writel(0x45080C04, engine + VIA_REG_TRANSPACE);
439 viaparinfo->io_virt + VIA_REG_TRANSPACE); 422 writel(0x46800408, engine + VIA_REG_TRANSPACE);
440 writel(0x40008C0F, 423
441 viaparinfo->io_virt + VIA_REG_TRANSPACE); 424 writel(vq_high, engine + VIA_REG_TRANSPACE);
442 writel(0x44000000, 425 writel(vq_start_low, engine + VIA_REG_TRANSPACE);
443 viaparinfo->io_virt + VIA_REG_TRANSPACE); 426 writel(vq_end_low, engine + VIA_REG_TRANSPACE);
444 writel(0x45080C04, 427 writel(vq_len, engine + VIA_REG_TRANSPACE);
445 viaparinfo->io_virt + VIA_REG_TRANSPACE); 428 break;
446 writel(0x46800408,
447 viaparinfo->io_virt + VIA_REG_TRANSPACE);
448
449 writel(dwVQStartEndH,
450 viaparinfo->io_virt + VIA_REG_TRANSPACE);
451 writel(dwVQStartL,
452 viaparinfo->io_virt + VIA_REG_TRANSPACE);
453 writel(dwVQEndL,
454 viaparinfo->io_virt + VIA_REG_TRANSPACE);
455 writel(dwVQLen,
456 viaparinfo->io_virt + VIA_REG_TRANSPACE);
457 break;
458 }
459 } else {
460 /* Disable VQ */
461 switch (viaparinfo->chip_info->gfx_chip_name) {
462 case UNICHROME_K8M890:
463 case UNICHROME_P4M900:
464 writel(0x00100000,
465 viaparinfo->io_virt + VIA_REG_CR_TRANSET);
466 writel(0x74301000,
467 viaparinfo->io_virt + VIA_REG_CR_TRANSPACE);
468 break;
469 default:
470 writel(0x00FE0000,
471 viaparinfo->io_virt + VIA_REG_TRANSET);
472 writel(0x00000004,
473 viaparinfo->io_virt + VIA_REG_TRANSPACE);
474 writel(0x40008C0F,
475 viaparinfo->io_virt + VIA_REG_TRANSPACE);
476 writel(0x44000000,
477 viaparinfo->io_virt + VIA_REG_TRANSPACE);
478 writel(0x45080C04,
479 viaparinfo->io_virt + VIA_REG_TRANSPACE);
480 writel(0x46800408,
481 viaparinfo->io_virt + VIA_REG_TRANSPACE);
482 break;
483 }
484 } 429 }
485}
486 430
487void viafb_hw_cursor_init(void)
488{
489 /* Set Cursor Image Base Address */ 431 /* Set Cursor Image Base Address */
490 writel(viaparinfo->shared->cursor_vram_addr, 432 writel(viapar->shared->cursor_vram_addr, engine + VIA_REG_CURSOR_MODE);
491 viaparinfo->io_virt + VIA_REG_CURSOR_MODE); 433 writel(0x0, engine + VIA_REG_CURSOR_POS);
492 writel(0x0, viaparinfo->io_virt + VIA_REG_CURSOR_POS); 434 writel(0x0, engine + VIA_REG_CURSOR_ORG);
493 writel(0x0, viaparinfo->io_virt + VIA_REG_CURSOR_ORG); 435 writel(0x0, engine + VIA_REG_CURSOR_BG);
494 writel(0x0, viaparinfo->io_virt + VIA_REG_CURSOR_BG); 436 writel(0x0, engine + VIA_REG_CURSOR_FG);
495 writel(0x0, viaparinfo->io_virt + VIA_REG_CURSOR_FG); 437 return 0;
496} 438}
497 439
498void viafb_show_hw_cursor(struct fb_info *info, int Status) 440void viafb_show_hw_cursor(struct fb_info *info, int Status)
499{ 441{
500 u32 temp; 442 struct viafb_par *viapar = info->par;
501 u32 iga_path = ((struct viafb_par *)(info->par))->iga_path; 443 u32 temp, iga_path = viapar->iga_path;
502 444
503 temp = readl(viaparinfo->io_virt + VIA_REG_CURSOR_MODE); 445 temp = readl(viapar->shared->engine_mmio + VIA_REG_CURSOR_MODE);
504 switch (Status) { 446 switch (Status) {
505 case HW_Cursor_ON: 447 case HW_Cursor_ON:
506 temp |= 0x1; 448 temp |= 0x1;
@@ -517,25 +459,27 @@ void viafb_show_hw_cursor(struct fb_info *info, int Status)
517 default: 459 default:
518 temp &= 0x7FFFFFFF; 460 temp &= 0x7FFFFFFF;
519 } 461 }
520 writel(temp, viaparinfo->io_virt + VIA_REG_CURSOR_MODE); 462 writel(temp, viapar->shared->engine_mmio + VIA_REG_CURSOR_MODE);
521} 463}
522 464
523int viafb_wait_engine_idle(void) 465void viafb_wait_engine_idle(struct fb_info *info)
524{ 466{
467 struct viafb_par *viapar = info->par;
525 int loop = 0; 468 int loop = 0;
526 469
527 while (!(readl(viaparinfo->io_virt + VIA_REG_STATUS) & 470 while (!(readl(viapar->shared->engine_mmio + VIA_REG_STATUS) &
528 VIA_VR_QUEUE_BUSY) && (loop < MAXLOOP)) { 471 VIA_VR_QUEUE_BUSY) && (loop < MAXLOOP)) {
529 loop++; 472 loop++;
530 cpu_relax(); 473 cpu_relax();
531 } 474 }
532 475
533 while ((readl(viaparinfo->io_virt + VIA_REG_STATUS) & 476 while ((readl(viapar->shared->engine_mmio + VIA_REG_STATUS) &
534 (VIA_CMD_RGTR_BUSY | VIA_2D_ENG_BUSY | VIA_3D_ENG_BUSY)) && 477 (VIA_CMD_RGTR_BUSY | VIA_2D_ENG_BUSY | VIA_3D_ENG_BUSY)) &&
535 (loop < MAXLOOP)) { 478 (loop < MAXLOOP)) {
536 loop++; 479 loop++;
537 cpu_relax(); 480 cpu_relax();
538 } 481 }
539 482
540 return loop >= MAXLOOP; 483 if (loop >= MAXLOOP)
484 printk(KERN_ERR "viafb_wait_engine_idle: not syncing\n");
541} 485}
diff --git a/drivers/video/via/accel.h b/drivers/video/via/accel.h
index 4d93eba4f3eb..615c84ad0f01 100644
--- a/drivers/video/via/accel.h
+++ b/drivers/video/via/accel.h
@@ -163,10 +163,8 @@
163#define VIA_BITBLT_MONO 2 163#define VIA_BITBLT_MONO 2
164#define VIA_BITBLT_FILL 3 164#define VIA_BITBLT_FILL 3
165 165
166void viafb_init_accel(struct viafb_shared *shared); 166int viafb_init_engine(struct fb_info *info);
167void viafb_init_2d_engine(void); 167void viafb_show_hw_cursor(struct fb_info *info, int Status);
168void viafb_hw_cursor_init(void); 168void viafb_wait_engine_idle(struct fb_info *info);
169void viafb_show_hw_cursor(struct fb_info *info, int Status); int
170viafb_wait_engine_idle(void); void viafb_set_2d_color_depth(int bpp);
171 169
172#endif /* __ACCEL_H__ */ 170#endif /* __ACCEL_H__ */
diff --git a/drivers/video/via/global.c b/drivers/video/via/global.c
index 33e7c45b2b78..b675cdbb03ad 100644
--- a/drivers/video/via/global.c
+++ b/drivers/video/via/global.c
@@ -32,7 +32,6 @@ int viafb_lcd_dsp_method = LCD_EXPANDSION;
32int viafb_lcd_mode = LCD_OPENLDI; 32int viafb_lcd_mode = LCD_OPENLDI;
33int viafb_bpp = 32; 33int viafb_bpp = 32;
34int viafb_bpp1 = 32; 34int viafb_bpp1 = 32;
35int viafb_accel = 1;
36int viafb_CRT_ON = 1; 35int viafb_CRT_ON = 1;
37int viafb_DVI_ON; 36int viafb_DVI_ON;
38int viafb_LCD_ON ; 37int viafb_LCD_ON ;
diff --git a/drivers/video/via/hw.h b/drivers/video/via/hw.h
index 817033d2d3be..7302b403e453 100644
--- a/drivers/video/via/hw.h
+++ b/drivers/video/via/hw.h
@@ -855,7 +855,6 @@ extern int viafb_dual_fb;
855extern int viafb_LCD2_ON; 855extern int viafb_LCD2_ON;
856extern int viafb_LCD_ON; 856extern int viafb_LCD_ON;
857extern int viafb_DVI_ON; 857extern int viafb_DVI_ON;
858extern int viafb_accel;
859extern int viafb_hotplug; 858extern int viafb_hotplug;
860 859
861void viafb_write_reg_mask(u8 index, int io_port, u8 data, u8 mask); 860void viafb_write_reg_mask(u8 index, int io_port, u8 data, u8 mask);
diff --git a/drivers/video/via/viafbdev.c b/drivers/video/via/viafbdev.c
index e9c9f0ec842a..8e43759a0b8d 100644
--- a/drivers/video/via/viafbdev.c
+++ b/drivers/video/via/viafbdev.c
@@ -33,6 +33,8 @@ static u32 pseudo_pal[17];
33static char *viafb_mode = "640x480"; 33static char *viafb_mode = "640x480";
34static char *viafb_mode1 = "640x480"; 34static char *viafb_mode1 = "640x480";
35 35
36static int viafb_accel = 1;
37
36/* Added for specifying active devices.*/ 38/* Added for specifying active devices.*/
37char *viafb_active_dev = ""; 39char *viafb_active_dev = "";
38 40
@@ -140,6 +142,9 @@ static int viafb_check_var(struct fb_var_screeninfo *var,
140 142
141 /* Adjust var according to our driver's own table */ 143 /* Adjust var according to our driver's own table */
142 viafb_fill_var_timing_info(var, viafb_refresh, vmode_index); 144 viafb_fill_var_timing_info(var, viafb_refresh, vmode_index);
145 if (info->var.accel_flags & FB_ACCELF_TEXT &&
146 !ppar->shared->engine_mmio)
147 info->var.accel_flags = 0;
143 148
144 return 0; 149 return 0;
145} 150}
@@ -177,8 +182,10 @@ static int viafb_set_par(struct fb_info *info)
177 182
178 viafb_update_fix(info); 183 viafb_update_fix(info);
179 viafb_bpp = info->var.bits_per_pixel; 184 viafb_bpp = info->var.bits_per_pixel;
180 /* Update viafb_accel, it is necessary to our 2D accelerate */ 185 if (info->var.accel_flags & FB_ACCELF_TEXT)
181 viafb_accel = info->var.accel_flags; 186 info->flags &= ~FBINFO_HWACCEL_DISABLED;
187 else
188 info->flags |= FBINFO_HWACCEL_DISABLED;
182 } 189 }
183 190
184 return 0; 191 return 0;
@@ -764,10 +771,11 @@ static void viafb_fillrect(struct fb_info *info,
764 const struct fb_fillrect *rect) 771 const struct fb_fillrect *rect)
765{ 772{
766 struct viafb_par *viapar = info->par; 773 struct viafb_par *viapar = info->par;
774 struct viafb_shared *shared = viapar->shared;
767 u32 fg_color; 775 u32 fg_color;
768 u8 rop; 776 u8 rop;
769 777
770 if (!viapar->shared->hw_bitblt) { 778 if (info->flags & FBINFO_HWACCEL_DISABLED || !shared->hw_bitblt) {
771 cfb_fillrect(info, rect); 779 cfb_fillrect(info, rect);
772 return; 780 return;
773 } 781 }
@@ -786,7 +794,7 @@ static void viafb_fillrect(struct fb_info *info,
786 rop = 0xF0; 794 rop = 0xF0;
787 795
788 DEBUG_MSG(KERN_DEBUG "viafb 2D engine: fillrect\n"); 796 DEBUG_MSG(KERN_DEBUG "viafb 2D engine: fillrect\n");
789 if (viapar->shared->hw_bitblt(viapar->io_virt, VIA_BITBLT_FILL, 797 if (shared->hw_bitblt(shared->engine_mmio, VIA_BITBLT_FILL,
790 rect->width, rect->height, info->var.bits_per_pixel, 798 rect->width, rect->height, info->var.bits_per_pixel,
791 viapar->vram_addr, info->fix.line_length, rect->dx, rect->dy, 799 viapar->vram_addr, info->fix.line_length, rect->dx, rect->dy,
792 NULL, 0, 0, 0, 0, fg_color, 0, rop)) 800 NULL, 0, 0, 0, 0, fg_color, 0, rop))
@@ -797,8 +805,9 @@ static void viafb_copyarea(struct fb_info *info,
797 const struct fb_copyarea *area) 805 const struct fb_copyarea *area)
798{ 806{
799 struct viafb_par *viapar = info->par; 807 struct viafb_par *viapar = info->par;
808 struct viafb_shared *shared = viapar->shared;
800 809
801 if (!viapar->shared->hw_bitblt) { 810 if (info->flags & FBINFO_HWACCEL_DISABLED || !shared->hw_bitblt) {
802 cfb_copyarea(info, area); 811 cfb_copyarea(info, area);
803 return; 812 return;
804 } 813 }
@@ -807,7 +816,7 @@ static void viafb_copyarea(struct fb_info *info,
807 return; 816 return;
808 817
809 DEBUG_MSG(KERN_DEBUG "viafb 2D engine: copyarea\n"); 818 DEBUG_MSG(KERN_DEBUG "viafb 2D engine: copyarea\n");
810 if (viapar->shared->hw_bitblt(viapar->io_virt, VIA_BITBLT_COLOR, 819 if (shared->hw_bitblt(shared->engine_mmio, VIA_BITBLT_COLOR,
811 area->width, area->height, info->var.bits_per_pixel, 820 area->width, area->height, info->var.bits_per_pixel,
812 viapar->vram_addr, info->fix.line_length, area->dx, area->dy, 821 viapar->vram_addr, info->fix.line_length, area->dx, area->dy,
813 NULL, viapar->vram_addr, info->fix.line_length, 822 NULL, viapar->vram_addr, info->fix.line_length,
@@ -819,10 +828,11 @@ static void viafb_imageblit(struct fb_info *info,
819 const struct fb_image *image) 828 const struct fb_image *image)
820{ 829{
821 struct viafb_par *viapar = info->par; 830 struct viafb_par *viapar = info->par;
831 struct viafb_shared *shared = viapar->shared;
822 u32 fg_color = 0, bg_color = 0; 832 u32 fg_color = 0, bg_color = 0;
823 u8 op; 833 u8 op;
824 834
825 if (!viapar->shared->hw_bitblt || 835 if (info->flags & FBINFO_HWACCEL_DISABLED || !shared->hw_bitblt ||
826 (image->depth != 1 && image->depth != viapar->depth)) { 836 (image->depth != 1 && image->depth != viapar->depth)) {
827 cfb_imageblit(info, image); 837 cfb_imageblit(info, image);
828 return; 838 return;
@@ -843,7 +853,7 @@ static void viafb_imageblit(struct fb_info *info,
843 op = VIA_BITBLT_COLOR; 853 op = VIA_BITBLT_COLOR;
844 854
845 DEBUG_MSG(KERN_DEBUG "viafb 2D engine: imageblit\n"); 855 DEBUG_MSG(KERN_DEBUG "viafb 2D engine: imageblit\n");
846 if (viapar->shared->hw_bitblt(viapar->io_virt, op, 856 if (shared->hw_bitblt(shared->engine_mmio, op,
847 image->width, image->height, info->var.bits_per_pixel, 857 image->width, image->height, info->var.bits_per_pixel,
848 viapar->vram_addr, info->fix.line_length, image->dx, image->dy, 858 viapar->vram_addr, info->fix.line_length, image->dx, image->dy,
849 (u32 *)image->data, 0, 0, 0, 0, fg_color, bg_color, 0)) 859 (u32 *)image->data, 0, 0, 0, 0, fg_color, bg_color, 0))
@@ -853,6 +863,7 @@ static void viafb_imageblit(struct fb_info *info,
853static int viafb_cursor(struct fb_info *info, struct fb_cursor *cursor) 863static int viafb_cursor(struct fb_info *info, struct fb_cursor *cursor)
854{ 864{
855 struct viafb_par *viapar = info->par; 865 struct viafb_par *viapar = info->par;
866 void __iomem *engine = viapar->shared->engine_mmio;
856 u32 temp, xx, yy, bg_color = 0, fg_color = 0, 867 u32 temp, xx, yy, bg_color = 0, fg_color = 0,
857 chip_name = viapar->shared->chip_info.gfx_chip_name; 868 chip_name = viapar->shared->chip_info.gfx_chip_name;
858 int i, j = 0, cur_size = 64; 869 int i, j = 0, cur_size = 64;
@@ -867,7 +878,7 @@ static int viafb_cursor(struct fb_info *info, struct fb_cursor *cursor)
867 878
868 if (cursor->set & FB_CUR_SETHOT) { 879 if (cursor->set & FB_CUR_SETHOT) {
869 temp = (cursor->hot.x << 16) + cursor->hot.y; 880 temp = (cursor->hot.x << 16) + cursor->hot.y;
870 writel(temp, viapar->io_virt + VIA_REG_CURSOR_ORG); 881 writel(temp, engine + VIA_REG_CURSOR_ORG);
871 } 882 }
872 883
873 if (cursor->set & FB_CUR_SETPOS) { 884 if (cursor->set & FB_CUR_SETPOS) {
@@ -875,7 +886,7 @@ static int viafb_cursor(struct fb_info *info, struct fb_cursor *cursor)
875 xx = cursor->image.dx - info->var.xoffset; 886 xx = cursor->image.dx - info->var.xoffset;
876 temp = yy & 0xFFFF; 887 temp = yy & 0xFFFF;
877 temp |= (xx << 16); 888 temp |= (xx << 16);
878 writel(temp, viapar->io_virt + VIA_REG_CURSOR_POS); 889 writel(temp, engine + VIA_REG_CURSOR_POS);
879 } 890 }
880 891
881 if (cursor->image.width <= 32 && cursor->image.height <= 32) 892 if (cursor->image.width <= 32 && cursor->image.height <= 32)
@@ -889,13 +900,13 @@ static int viafb_cursor(struct fb_info *info, struct fb_cursor *cursor)
889 } 900 }
890 901
891 if (cursor->set & FB_CUR_SETSIZE) { 902 if (cursor->set & FB_CUR_SETSIZE) {
892 temp = readl(viapar->io_virt + VIA_REG_CURSOR_MODE); 903 temp = readl(engine + VIA_REG_CURSOR_MODE);
893 if (cur_size == 32) 904 if (cur_size == 32)
894 temp |= 0x2; 905 temp |= 0x2;
895 else 906 else
896 temp &= ~0x2; 907 temp &= ~0x2;
897 908
898 writel(temp, viapar->io_virt + VIA_REG_CURSOR_MODE); 909 writel(temp, engine + VIA_REG_CURSOR_MODE);
899 } 910 }
900 911
901 if (cursor->set & FB_CUR_SETCMAP) { 912 if (cursor->set & FB_CUR_SETCMAP) {
@@ -922,8 +933,8 @@ static int viafb_cursor(struct fb_info *info, struct fb_cursor *cursor)
922 ((info->cmap.blue[bg_color] & 0xFF00) >> 8); 933 ((info->cmap.blue[bg_color] & 0xFF00) >> 8);
923 } 934 }
924 935
925 writel(bg_color, viapar->io_virt + VIA_REG_CURSOR_BG); 936 writel(bg_color, engine + VIA_REG_CURSOR_BG);
926 writel(fg_color, viapar->io_virt + VIA_REG_CURSOR_FG); 937 writel(fg_color, engine + VIA_REG_CURSOR_FG);
927 } 938 }
928 939
929 if (cursor->set & FB_CUR_SETSHAPE) { 940 if (cursor->set & FB_CUR_SETSHAPE) {
@@ -996,8 +1007,8 @@ static int viafb_cursor(struct fb_info *info, struct fb_cursor *cursor)
996 1007
997static int viafb_sync(struct fb_info *info) 1008static int viafb_sync(struct fb_info *info)
998{ 1009{
999 if (viafb_accel) 1010 if (!(info->flags & FBINFO_HWACCEL_DISABLED))
1000 viafb_wait_engine_idle(); 1011 viafb_wait_engine_idle(info);
1001 return 0; 1012 return 0;
1002} 1013}
1003 1014
@@ -1867,22 +1878,18 @@ static int __devinit via_pci_probe(void)
1867 1878
1868 viafb_get_mmio_info(&viafbinfo->fix.mmio_start, 1879 viafb_get_mmio_info(&viafbinfo->fix.mmio_start,
1869 &viafbinfo->fix.mmio_len); 1880 &viafbinfo->fix.mmio_len);
1870 viaparinfo->io_virt = ioremap_nocache(viafbinfo->fix.mmio_start,
1871 viafbinfo->fix.mmio_len);
1872 if (!viaparinfo->io_virt) {
1873 printk(KERN_WARNING "ioremap failed: hardware acceleration disabled\n");
1874 viafb_accel = 0;
1875 }
1876
1877 viafbinfo->node = 0; 1881 viafbinfo->node = 0;
1878 viafbinfo->fbops = &viafb_ops; 1882 viafbinfo->fbops = &viafb_ops;
1879 viafbinfo->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN; 1883 viafbinfo->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN;
1880 1884
1881 viafbinfo->pseudo_palette = pseudo_pal; 1885 viafbinfo->pseudo_palette = pseudo_pal;
1882 if (viafb_accel) { 1886 if (viafb_accel && !viafb_init_engine(viafbinfo)) {
1883 viafb_init_accel(viaparinfo->shared); 1887 viafbinfo->flags |= FBINFO_HWACCEL_COPYAREA |
1884 viafb_init_2d_engine(); 1888 FBINFO_HWACCEL_FILLRECT | FBINFO_HWACCEL_IMAGEBLIT;
1885 viafb_hw_cursor_init(); 1889 default_var.accel_flags = FB_ACCELF_TEXT;
1890 } else {
1891 viafbinfo->flags |= FBINFO_HWACCEL_DISABLED;
1892 default_var.accel_flags = 0;
1886 } 1893 }
1887 1894
1888 if (viafb_second_size && (viafb_second_size < 8)) { 1895 if (viafb_second_size && (viafb_second_size < 8)) {
@@ -1963,15 +1970,6 @@ static int __devinit via_pci_probe(void)
1963 default_var.lower_margin = 4; 1970 default_var.lower_margin = 4;
1964 default_var.hsync_len = default_var.left_margin; 1971 default_var.hsync_len = default_var.left_margin;
1965 default_var.vsync_len = 4; 1972 default_var.vsync_len = 4;
1966 default_var.accel_flags = 0;
1967
1968 if (viafb_accel) {
1969 viafbinfo->flags |=
1970 (FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT |
1971 FBINFO_HWACCEL_IMAGEBLIT);
1972 default_var.accel_flags |= FB_ACCELF_TEXT;
1973 } else
1974 viafbinfo->flags |= FBINFO_HWACCEL_DISABLED;
1975 1973
1976 if (viafb_dual_fb) { 1974 if (viafb_dual_fb) {
1977 viafbinfo1 = framebuffer_alloc(viafb_par_length, NULL); 1975 viafbinfo1 = framebuffer_alloc(viafb_par_length, NULL);
@@ -1994,12 +1992,6 @@ static int __devinit via_pci_probe(void)
1994 viaparinfo1->fbmem_used; 1992 viaparinfo1->fbmem_used;
1995 viaparinfo->fbmem_free = viaparinfo->memsize; 1993 viaparinfo->fbmem_free = viaparinfo->memsize;
1996 viaparinfo->fbmem_used = 0; 1994 viaparinfo->fbmem_used = 0;
1997 if (viafb_accel) {
1998 viaparinfo1->VQ_start = viaparinfo->VQ_start -
1999 viafb_second_offset;
2000 viaparinfo1->VQ_end = viaparinfo->VQ_end -
2001 viafb_second_offset;
2002 }
2003 1995
2004 viaparinfo->iga_path = IGA1; 1996 viaparinfo->iga_path = IGA1;
2005 viaparinfo1->iga_path = IGA2; 1997 viaparinfo1->iga_path = IGA2;
@@ -2073,7 +2065,7 @@ static void __devexit via_pci_remove(void)
2073 if (viafb_dual_fb) 2065 if (viafb_dual_fb)
2074 unregister_framebuffer(viafbinfo1); 2066 unregister_framebuffer(viafbinfo1);
2075 iounmap((void *)viafbinfo->screen_base); 2067 iounmap((void *)viafbinfo->screen_base);
2076 iounmap(viaparinfo->io_virt); 2068 iounmap(viaparinfo->shared->engine_mmio);
2077 2069
2078 viafb_delete_i2c_buss(viaparinfo); 2070 viafb_delete_i2c_buss(viaparinfo);
2079 2071
@@ -2235,7 +2227,7 @@ MODULE_PARM_DESC(viafb_SAMM_ON,
2235 2227
2236module_param(viafb_accel, int, 0); 2228module_param(viafb_accel, int, 0);
2237MODULE_PARM_DESC(viafb_accel, 2229MODULE_PARM_DESC(viafb_accel,
2238 "Set 2D Hardware Acceleration.(Default = OFF)"); 2230 "Set 2D Hardware Acceleration: 0 = OFF, 1 = ON (default)");
2239 2231
2240module_param(viafb_active_dev, charp, 0); 2232module_param(viafb_active_dev, charp, 0);
2241MODULE_PARM_DESC(viafb_active_dev, "Specify active devices."); 2233MODULE_PARM_DESC(viafb_active_dev, "Specify active devices.");
diff --git a/drivers/video/via/viafbdev.h b/drivers/video/via/viafbdev.h
index 159619bc80b1..0c94d2441922 100644
--- a/drivers/video/via/viafbdev.h
+++ b/drivers/video/via/viafbdev.h
@@ -51,7 +51,9 @@ struct viafb_shared {
51 struct chip_information chip_info; 51 struct chip_information chip_info;
52 52
53 /* hardware acceleration stuff */ 53 /* hardware acceleration stuff */
54 void __iomem *engine_mmio;
54 u32 cursor_vram_addr; 55 u32 cursor_vram_addr;
56 u32 vq_vram_addr; /* virtual queue address in video ram */
55 int (*hw_bitblt)(void __iomem *engine, u8 op, u32 width, u32 height, 57 int (*hw_bitblt)(void __iomem *engine, u8 op, u32 width, u32 height,
56 u8 dst_bpp, u32 dst_addr, u32 dst_pitch, u32 dst_x, u32 dst_y, 58 u8 dst_bpp, u32 dst_addr, u32 dst_pitch, u32 dst_x, u32 dst_y,
57 u32 *src_mem, u32 src_addr, u32 src_pitch, u32 src_x, u32 src_y, 59 u32 *src_mem, u32 src_addr, u32 src_pitch, u32 src_x, u32 src_y,
@@ -61,13 +63,11 @@ struct viafb_shared {
61struct viafb_par { 63struct viafb_par {
62 u8 depth; 64 u8 depth;
63 u32 vram_addr; 65 u32 vram_addr;
64 void __iomem *io_virt; /*iospace virtual memory address */ 66
65 unsigned int fbmem; /*framebuffer physical memory address */ 67 unsigned int fbmem; /*framebuffer physical memory address */
66 unsigned int memsize; /*size of fbmem */ 68 unsigned int memsize; /*size of fbmem */
67 u32 fbmem_free; /* Free FB memory */ 69 u32 fbmem_free; /* Free FB memory */
68 u32 fbmem_used; /* Use FB memory size */ 70 u32 fbmem_used; /* Use FB memory size */
69 u32 VQ_start; /* Virtual Queue Start Address */
70 u32 VQ_end; /* Virtual Queue End Address */
71 u32 iga_path; 71 u32 iga_path;
72 72
73 struct viafb_shared *shared; 73 struct viafb_shared *shared;
@@ -90,7 +90,6 @@ extern int viafb_dual_fb;
90extern int viafb_LCD2_ON; 90extern int viafb_LCD2_ON;
91extern int viafb_LCD_ON; 91extern int viafb_LCD_ON;
92extern int viafb_DVI_ON; 92extern int viafb_DVI_ON;
93extern int viafb_accel;
94extern int viafb_hotplug; 93extern int viafb_hotplug;
95extern int viafb_memsize; 94extern int viafb_memsize;
96 95