diff options
Diffstat (limited to 'drivers/video/via/accel.c')
-rw-r--r-- | drivers/video/via/accel.c | 137 |
1 files changed, 91 insertions, 46 deletions
diff --git a/drivers/video/via/accel.c b/drivers/video/via/accel.c index d5077dfa9e00..e44893ea590d 100644 --- a/drivers/video/via/accel.c +++ b/drivers/video/via/accel.c | |||
@@ -18,14 +18,45 @@ | |||
18 | * Foundation, Inc., | 18 | * Foundation, Inc., |
19 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | 19 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
20 | */ | 20 | */ |
21 | #include <linux/via-core.h> | ||
21 | #include "global.h" | 22 | #include "global.h" |
22 | 23 | ||
24 | /* | ||
25 | * Figure out an appropriate bytes-per-pixel setting. | ||
26 | */ | ||
27 | static int viafb_set_bpp(void __iomem *engine, u8 bpp) | ||
28 | { | ||
29 | u32 gemode; | ||
30 | |||
31 | /* Preserve the reserved bits */ | ||
32 | /* Lowest 2 bits to zero gives us no rotation */ | ||
33 | gemode = readl(engine + VIA_REG_GEMODE) & 0xfffffcfc; | ||
34 | switch (bpp) { | ||
35 | case 8: | ||
36 | gemode |= VIA_GEM_8bpp; | ||
37 | break; | ||
38 | case 16: | ||
39 | gemode |= VIA_GEM_16bpp; | ||
40 | break; | ||
41 | case 32: | ||
42 | gemode |= VIA_GEM_32bpp; | ||
43 | break; | ||
44 | default: | ||
45 | printk(KERN_WARNING "viafb_set_bpp: Unsupported bpp %d\n", bpp); | ||
46 | return -EINVAL; | ||
47 | } | ||
48 | writel(gemode, engine + VIA_REG_GEMODE); | ||
49 | return 0; | ||
50 | } | ||
51 | |||
52 | |||
23 | static int hw_bitblt_1(void __iomem *engine, u8 op, u32 width, u32 height, | 53 | static int hw_bitblt_1(void __iomem *engine, u8 op, u32 width, u32 height, |
24 | u8 dst_bpp, u32 dst_addr, u32 dst_pitch, u32 dst_x, u32 dst_y, | 54 | u8 dst_bpp, u32 dst_addr, u32 dst_pitch, u32 dst_x, u32 dst_y, |
25 | u32 *src_mem, u32 src_addr, u32 src_pitch, u32 src_x, u32 src_y, | 55 | u32 *src_mem, u32 src_addr, u32 src_pitch, u32 src_x, u32 src_y, |
26 | u32 fg_color, u32 bg_color, u8 fill_rop) | 56 | u32 fg_color, u32 bg_color, u8 fill_rop) |
27 | { | 57 | { |
28 | u32 ge_cmd = 0, tmp, i; | 58 | u32 ge_cmd = 0, tmp, i; |
59 | int ret; | ||
29 | 60 | ||
30 | if (!op || op > 3) { | 61 | if (!op || op > 3) { |
31 | printk(KERN_WARNING "hw_bitblt_1: Invalid operation: %d\n", op); | 62 | printk(KERN_WARNING "hw_bitblt_1: Invalid operation: %d\n", op); |
@@ -59,22 +90,9 @@ static int hw_bitblt_1(void __iomem *engine, u8 op, u32 width, u32 height, | |||
59 | } | 90 | } |
60 | } | 91 | } |
61 | 92 | ||
62 | switch (dst_bpp) { | 93 | ret = viafb_set_bpp(engine, dst_bpp); |
63 | case 8: | 94 | if (ret) |
64 | tmp = 0x00000000; | 95 | return ret; |
65 | break; | ||
66 | case 16: | ||
67 | tmp = 0x00000100; | ||
68 | break; | ||
69 | case 32: | ||
70 | tmp = 0x00000300; | ||
71 | break; | ||
72 | default: | ||
73 | printk(KERN_WARNING "hw_bitblt_1: Unsupported bpp %d\n", | ||
74 | dst_bpp); | ||
75 | return -EINVAL; | ||
76 | } | ||
77 | writel(tmp, engine + 0x04); | ||
78 | 96 | ||
79 | if (op != VIA_BITBLT_FILL) { | 97 | if (op != VIA_BITBLT_FILL) { |
80 | if (src_x & (op == VIA_BITBLT_MONO ? 0xFFFF8000 : 0xFFFFF000) | 98 | if (src_x & (op == VIA_BITBLT_MONO ? 0xFFFF8000 : 0xFFFFF000) |
@@ -171,6 +189,7 @@ static int hw_bitblt_2(void __iomem *engine, u8 op, u32 width, u32 height, | |||
171 | u32 fg_color, u32 bg_color, u8 fill_rop) | 189 | u32 fg_color, u32 bg_color, u8 fill_rop) |
172 | { | 190 | { |
173 | u32 ge_cmd = 0, tmp, i; | 191 | u32 ge_cmd = 0, tmp, i; |
192 | int ret; | ||
174 | 193 | ||
175 | if (!op || op > 3) { | 194 | if (!op || op > 3) { |
176 | printk(KERN_WARNING "hw_bitblt_2: Invalid operation: %d\n", op); | 195 | printk(KERN_WARNING "hw_bitblt_2: Invalid operation: %d\n", op); |
@@ -204,22 +223,9 @@ static int hw_bitblt_2(void __iomem *engine, u8 op, u32 width, u32 height, | |||
204 | } | 223 | } |
205 | } | 224 | } |
206 | 225 | ||
207 | switch (dst_bpp) { | 226 | ret = viafb_set_bpp(engine, dst_bpp); |
208 | case 8: | 227 | if (ret) |
209 | tmp = 0x00000000; | 228 | return ret; |
210 | break; | ||
211 | case 16: | ||
212 | tmp = 0x00000100; | ||
213 | break; | ||
214 | case 32: | ||
215 | tmp = 0x00000300; | ||
216 | break; | ||
217 | default: | ||
218 | printk(KERN_WARNING "hw_bitblt_2: Unsupported bpp %d\n", | ||
219 | dst_bpp); | ||
220 | return -EINVAL; | ||
221 | } | ||
222 | writel(tmp, engine + 0x04); | ||
223 | 229 | ||
224 | if (op == VIA_BITBLT_FILL) | 230 | if (op == VIA_BITBLT_FILL) |
225 | tmp = 0; | 231 | tmp = 0; |
@@ -312,17 +318,29 @@ int viafb_init_engine(struct fb_info *info) | |||
312 | { | 318 | { |
313 | struct viafb_par *viapar = info->par; | 319 | struct viafb_par *viapar = info->par; |
314 | void __iomem *engine; | 320 | void __iomem *engine; |
321 | int highest_reg, i; | ||
315 | u32 vq_start_addr, vq_end_addr, vq_start_low, vq_end_low, vq_high, | 322 | 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; | 323 | vq_len, chip_name = viapar->shared->chip_info.gfx_chip_name; |
317 | 324 | ||
318 | engine = ioremap_nocache(info->fix.mmio_start, info->fix.mmio_len); | 325 | engine = viapar->shared->vdev->engine_mmio; |
319 | viapar->shared->engine_mmio = engine; | ||
320 | if (!engine) { | 326 | if (!engine) { |
321 | printk(KERN_WARNING "viafb_init_accel: ioremap failed, " | 327 | printk(KERN_WARNING "viafb_init_accel: ioremap failed, " |
322 | "hardware acceleration disabled\n"); | 328 | "hardware acceleration disabled\n"); |
323 | return -ENOMEM; | 329 | return -ENOMEM; |
324 | } | 330 | } |
325 | 331 | ||
332 | /* Initialize registers to reset the 2D engine */ | ||
333 | switch (viapar->shared->chip_info.twod_engine) { | ||
334 | case VIA_2D_ENG_M1: | ||
335 | highest_reg = 0x5c; | ||
336 | break; | ||
337 | default: | ||
338 | highest_reg = 0x40; | ||
339 | break; | ||
340 | } | ||
341 | for (i = 0; i <= highest_reg; i += 4) | ||
342 | writel(0x0, engine + i); | ||
343 | |||
326 | switch (chip_name) { | 344 | switch (chip_name) { |
327 | case UNICHROME_CLE266: | 345 | case UNICHROME_CLE266: |
328 | case UNICHROME_K400: | 346 | case UNICHROME_K400: |
@@ -352,13 +370,28 @@ int viafb_init_engine(struct fb_info *info) | |||
352 | viapar->shared->vq_vram_addr = viapar->fbmem_free; | 370 | viapar->shared->vq_vram_addr = viapar->fbmem_free; |
353 | viapar->fbmem_used += VQ_SIZE; | 371 | viapar->fbmem_used += VQ_SIZE; |
354 | 372 | ||
355 | /* Init 2D engine reg to reset 2D engine */ | 373 | #if defined(CONFIG_FB_VIA_CAMERA) || defined(CONFIG_FB_VIA_CAMERA_MODULE) |
356 | writel(0x0, engine + VIA_REG_KEYCONTROL); | 374 | /* |
375 | * Set aside a chunk of framebuffer memory for the camera | ||
376 | * driver. Someday this driver probably needs a proper allocator | ||
377 | * for fbmem; for now, we just have to do this before the | ||
378 | * framebuffer initializes itself. | ||
379 | * | ||
380 | * As for the size: the engine can handle three frames, | ||
381 | * 16 bits deep, up to VGA resolution. | ||
382 | */ | ||
383 | viapar->shared->vdev->camera_fbmem_size = 3*VGA_HEIGHT*VGA_WIDTH*2; | ||
384 | viapar->fbmem_free -= viapar->shared->vdev->camera_fbmem_size; | ||
385 | viapar->fbmem_used += viapar->shared->vdev->camera_fbmem_size; | ||
386 | viapar->shared->vdev->camera_fbmem_offset = viapar->fbmem_free; | ||
387 | #endif | ||
357 | 388 | ||
358 | /* Init AGP and VQ regs */ | 389 | /* Init AGP and VQ regs */ |
359 | switch (chip_name) { | 390 | switch (chip_name) { |
360 | case UNICHROME_K8M890: | 391 | case UNICHROME_K8M890: |
361 | case UNICHROME_P4M900: | 392 | case UNICHROME_P4M900: |
393 | case UNICHROME_VX800: | ||
394 | case UNICHROME_VX855: | ||
362 | writel(0x00100000, engine + VIA_REG_CR_TRANSET); | 395 | writel(0x00100000, engine + VIA_REG_CR_TRANSET); |
363 | writel(0x680A0000, engine + VIA_REG_CR_TRANSPACE); | 396 | writel(0x680A0000, engine + VIA_REG_CR_TRANSPACE); |
364 | writel(0x02000000, engine + VIA_REG_CR_TRANSPACE); | 397 | writel(0x02000000, engine + VIA_REG_CR_TRANSPACE); |
@@ -393,6 +426,8 @@ int viafb_init_engine(struct fb_info *info) | |||
393 | switch (chip_name) { | 426 | switch (chip_name) { |
394 | case UNICHROME_K8M890: | 427 | case UNICHROME_K8M890: |
395 | case UNICHROME_P4M900: | 428 | case UNICHROME_P4M900: |
429 | case UNICHROME_VX800: | ||
430 | case UNICHROME_VX855: | ||
396 | vq_start_low |= 0x20000000; | 431 | vq_start_low |= 0x20000000; |
397 | vq_end_low |= 0x20000000; | 432 | vq_end_low |= 0x20000000; |
398 | vq_high |= 0x20000000; | 433 | vq_high |= 0x20000000; |
@@ -446,7 +481,7 @@ void viafb_show_hw_cursor(struct fb_info *info, int Status) | |||
446 | struct viafb_par *viapar = info->par; | 481 | struct viafb_par *viapar = info->par; |
447 | u32 temp, iga_path = viapar->iga_path; | 482 | u32 temp, iga_path = viapar->iga_path; |
448 | 483 | ||
449 | temp = readl(viapar->shared->engine_mmio + VIA_REG_CURSOR_MODE); | 484 | temp = readl(viapar->shared->vdev->engine_mmio + VIA_REG_CURSOR_MODE); |
450 | switch (Status) { | 485 | switch (Status) { |
451 | case HW_Cursor_ON: | 486 | case HW_Cursor_ON: |
452 | temp |= 0x1; | 487 | temp |= 0x1; |
@@ -463,23 +498,33 @@ void viafb_show_hw_cursor(struct fb_info *info, int Status) | |||
463 | default: | 498 | default: |
464 | temp &= 0x7FFFFFFF; | 499 | temp &= 0x7FFFFFFF; |
465 | } | 500 | } |
466 | writel(temp, viapar->shared->engine_mmio + VIA_REG_CURSOR_MODE); | 501 | writel(temp, viapar->shared->vdev->engine_mmio + VIA_REG_CURSOR_MODE); |
467 | } | 502 | } |
468 | 503 | ||
469 | void viafb_wait_engine_idle(struct fb_info *info) | 504 | void viafb_wait_engine_idle(struct fb_info *info) |
470 | { | 505 | { |
471 | struct viafb_par *viapar = info->par; | 506 | struct viafb_par *viapar = info->par; |
472 | int loop = 0; | 507 | int loop = 0; |
473 | 508 | u32 mask; | |
474 | while (!(readl(viapar->shared->engine_mmio + VIA_REG_STATUS) & | 509 | void __iomem *engine = viapar->shared->vdev->engine_mmio; |
475 | VIA_VR_QUEUE_BUSY) && (loop < MAXLOOP)) { | 510 | |
476 | loop++; | 511 | switch (viapar->shared->chip_info.twod_engine) { |
477 | cpu_relax(); | 512 | case VIA_2D_ENG_H5: |
513 | case VIA_2D_ENG_M1: | ||
514 | mask = VIA_CMD_RGTR_BUSY_M1 | VIA_2D_ENG_BUSY_M1 | | ||
515 | VIA_3D_ENG_BUSY_M1; | ||
516 | break; | ||
517 | default: | ||
518 | while (!(readl(engine + VIA_REG_STATUS) & | ||
519 | VIA_VR_QUEUE_BUSY) && (loop < MAXLOOP)) { | ||
520 | loop++; | ||
521 | cpu_relax(); | ||
522 | } | ||
523 | mask = VIA_CMD_RGTR_BUSY | VIA_2D_ENG_BUSY | VIA_3D_ENG_BUSY; | ||
524 | break; | ||
478 | } | 525 | } |
479 | 526 | ||
480 | while ((readl(viapar->shared->engine_mmio + VIA_REG_STATUS) & | 527 | while ((readl(engine + VIA_REG_STATUS) & mask) && (loop < MAXLOOP)) { |
481 | (VIA_CMD_RGTR_BUSY | VIA_2D_ENG_BUSY | VIA_3D_ENG_BUSY)) && | ||
482 | (loop < MAXLOOP)) { | ||
483 | loop++; | 528 | loop++; |
484 | cpu_relax(); | 529 | cpu_relax(); |
485 | } | 530 | } |