aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/via/accel.c
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 /drivers/video/via/accel.c
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>
Diffstat (limited to 'drivers/video/via/accel.c')
-rw-r--r--drivers/video/via/accel.c268
1 files changed, 106 insertions, 162 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}