Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

viafb: fix hardware acceleration for suspend & resume

This patch splits the acceleration initialization in two parts:
The first is only called during probe and is used to allocate
resources. The second part is also called on resume to reinitalize
the 2D engine. This should fix all acceleration issues after resume
most notable an "invisible" cursor and as we do nothing special it is
reasonable to assume that it works on all supported IGPs.

Signed-off-by: Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
Acked-by: Jonathan Corbet <corbet@lwn.net>
Cc: Joseph Chan <JosephChan@via.com.tw>

+31 -19
+26 -17
drivers/video/via/accel.c
··· 315 315 return 0; 316 316 } 317 317 318 - int viafb_init_engine(struct fb_info *info) 318 + int viafb_setup_engine(struct fb_info *info) 319 319 { 320 320 struct viafb_par *viapar = info->par; 321 321 void __iomem *engine; 322 - int highest_reg, i; 323 - u32 vq_start_addr, vq_end_addr, vq_start_low, vq_end_low, vq_high, 324 - vq_len, chip_name = viapar->shared->chip_info.gfx_chip_name; 322 + u32 chip_name = viapar->shared->chip_info.gfx_chip_name; 325 323 326 324 engine = viapar->shared->vdev->engine_mmio; 327 325 if (!engine) { ··· 327 329 "hardware acceleration disabled\n"); 328 330 return -ENOMEM; 329 331 } 330 - 331 - /* Initialize registers to reset the 2D engine */ 332 - switch (viapar->shared->chip_info.twod_engine) { 333 - case VIA_2D_ENG_M1: 334 - highest_reg = 0x5c; 335 - break; 336 - default: 337 - highest_reg = 0x40; 338 - break; 339 - } 340 - for (i = 0; i <= highest_reg; i += 4) 341 - writel(0x0, engine + i); 342 332 343 333 switch (chip_name) { 344 334 case UNICHROME_CLE266: ··· 372 386 viapar->fbmem_used += viapar->shared->vdev->camera_fbmem_size; 373 387 viapar->shared->vdev->camera_fbmem_offset = viapar->fbmem_free; 374 388 #endif 389 + 390 + viafb_reset_engine(viapar); 391 + return 0; 392 + } 393 + 394 + void viafb_reset_engine(struct viafb_par *viapar) 395 + { 396 + void __iomem *engine = viapar->shared->vdev->engine_mmio; 397 + int highest_reg, i; 398 + u32 vq_start_addr, vq_end_addr, vq_start_low, vq_end_low, vq_high, 399 + vq_len, chip_name = viapar->shared->chip_info.gfx_chip_name; 400 + 401 + /* Initialize registers to reset the 2D engine */ 402 + switch (viapar->shared->chip_info.twod_engine) { 403 + case VIA_2D_ENG_M1: 404 + highest_reg = 0x5c; 405 + break; 406 + default: 407 + highest_reg = 0x40; 408 + break; 409 + } 410 + for (i = 0; i <= highest_reg; i += 4) 411 + writel(0x0, engine + i); 375 412 376 413 /* Init AGP and VQ regs */ 377 414 switch (chip_name) { ··· 483 474 writel(0x0, engine + VIA_REG_CURSOR_ORG); 484 475 writel(0x0, engine + VIA_REG_CURSOR_BG); 485 476 writel(0x0, engine + VIA_REG_CURSOR_FG); 486 - return 0; 477 + return; 487 478 } 488 479 489 480 void viafb_show_hw_cursor(struct fb_info *info, int Status)
+2 -1
drivers/video/via/accel.h
··· 203 203 #define VIA_BITBLT_MONO 2 204 204 #define VIA_BITBLT_FILL 3 205 205 206 - int viafb_init_engine(struct fb_info *info); 206 + int viafb_setup_engine(struct fb_info *info); 207 + void viafb_reset_engine(struct viafb_par *viapar); 207 208 void viafb_show_hw_cursor(struct fb_info *info, int Status); 208 209 void viafb_wait_engine_idle(struct fb_info *info); 209 210
+3 -1
drivers/video/via/viafbdev.c
··· 1695 1695 if (pci_enable_device(pdev)) 1696 1696 goto fail; 1697 1697 pci_set_master(pdev); 1698 + if (viaparinfo->shared->vdev->engine_mmio) 1699 + viafb_reset_engine(viaparinfo); 1698 1700 viafb_set_par(viafbinfo); 1699 1701 if (viafb_dual_fb) 1700 1702 viafb_set_par(viafbinfo1); ··· 1768 1766 viafbinfo->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN; 1769 1767 1770 1768 viafbinfo->pseudo_palette = pseudo_pal; 1771 - if (viafb_accel && !viafb_init_engine(viafbinfo)) { 1769 + if (viafb_accel && !viafb_setup_engine(viafbinfo)) { 1772 1770 viafbinfo->flags |= FBINFO_HWACCEL_COPYAREA | 1773 1771 FBINFO_HWACCEL_FILLRECT | FBINFO_HWACCEL_IMAGEBLIT; 1774 1772 default_var.accel_flags = FB_ACCELF_TEXT;