aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/via/accel.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/via/accel.c')
-rw-r--r--drivers/video/via/accel.c137
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 */
27static 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
23static int hw_bitblt_1(void __iomem *engine, u8 op, u32 width, u32 height, 53static 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
469void viafb_wait_engine_idle(struct fb_info *info) 504void 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 }