accel.c revision c3e25673843153ea75fda79a47cf12f10a25ca37
1801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan/*
2801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
3801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
4801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan
5801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan * This program is free software; you can redistribute it and/or
6801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan * modify it under the terms of the GNU General Public
7801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan * License as published by the Free Software Foundation;
8801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan * either version 2, or (at your option) any later version.
9801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan
10801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan * This program is distributed in the hope that it will be useful,
11801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
12801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan * the implied warranty of MERCHANTABILITY or FITNESS FOR
13801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan * A PARTICULAR PURPOSE.See the GNU General Public License
14801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan * for more details.
15801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan
16801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan * You should have received a copy of the GNU General Public License
17801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan * along with this program; if not, write to the Free Software
18801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan * Foundation, Inc.,
19801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan */
21801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan#include "global.h"
22801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan
23c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinatstatic int hw_bitblt_1(void __iomem *engine, u8 op, u32 width, u32 height,
24c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	u8 dst_bpp, u32 dst_addr, u32 dst_pitch, u32 dst_x, u32 dst_y,
25c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	u32 *src_mem, u32 src_addr, u32 src_pitch, u32 src_x, u32 src_y,
26c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	u32 fg_color, u32 bg_color, u8 fill_rop)
27801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan{
28c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	u32 ge_cmd = 0, tmp, i;
29c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat
30c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	if (!op || op > 3) {
31c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		printk(KERN_WARNING "hw_bitblt_1: Invalid operation: %d\n", op);
32c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		return -EINVAL;
33c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	}
34c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat
35c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	if (op != VIA_BITBLT_FILL && !src_mem && src_addr == dst_addr) {
36c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		if (src_x < dst_x) {
37c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat			ge_cmd |= 0x00008000;
38c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat			src_x += width - 1;
39c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat			dst_x += width - 1;
40c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		}
41c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		if (src_y < dst_y) {
42c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat			ge_cmd |= 0x00004000;
43c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat			src_y += height - 1;
44c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat			dst_y += height - 1;
45c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		}
46c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	}
47c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat
48c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	if (op == VIA_BITBLT_FILL) {
49c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		switch (fill_rop) {
50c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		case 0x00: /* blackness */
51c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		case 0x5A: /* pattern inversion */
52c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		case 0xF0: /* pattern copy */
53c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		case 0xFF: /* whiteness */
54c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat			break;
55c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		default:
56c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat			printk(KERN_WARNING "hw_bitblt_1: Invalid fill rop: "
57c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat				"%u\n", fill_rop);
58c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat			return -EINVAL;
59c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		}
60c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	}
61c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat
62c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	switch (dst_bpp) {
63c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	case 8:
64c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		tmp = 0x00000000;
65c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		break;
66c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	case 16:
67c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		tmp = 0x00000100;
68c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		break;
69c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	case 32:
70c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		tmp = 0x00000300;
71c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		break;
72c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	default:
73c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		printk(KERN_WARNING "hw_bitblt_1: Unsupported bpp %d\n",
74c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat			dst_bpp);
75c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		return -EINVAL;
76c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	}
77c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	writel(tmp, engine + 0x04);
78c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat
79c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	if (op != VIA_BITBLT_FILL) {
80c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		if (src_x & (op == VIA_BITBLT_MONO ? 0xFFFF8000 : 0xFFFFF000)
81c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat			|| src_y & 0xFFFFF000) {
82c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat			printk(KERN_WARNING "hw_bitblt_1: Unsupported source "
83c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat				"x/y %d %d\n", src_x, src_y);
84c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat			return -EINVAL;
85c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		}
86c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		tmp = src_x | (src_y << 16);
87c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		writel(tmp, engine + 0x08);
88c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	}
89c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat
90c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	if (dst_x & 0xFFFFF000 || dst_y & 0xFFFFF000) {
91c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		printk(KERN_WARNING "hw_bitblt_1: Unsupported destination x/y "
92c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat			"%d %d\n", dst_x, dst_y);
93c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		return -EINVAL;
94c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	}
95c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	tmp = dst_x | (dst_y << 16);
96c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	writel(tmp, engine + 0x0C);
97c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat
98c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	if ((width - 1) & 0xFFFFF000 || (height - 1) & 0xFFFFF000) {
99c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		printk(KERN_WARNING "hw_bitblt_1: Unsupported width/height "
100c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat			"%d %d\n", width, height);
101c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		return -EINVAL;
102c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	}
103c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	tmp = (width - 1) | ((height - 1) << 16);
104c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	writel(tmp, engine + 0x10);
105c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat
106c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	if (op != VIA_BITBLT_COLOR)
107c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		writel(fg_color, engine + 0x18);
108c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat
109c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	if (op == VIA_BITBLT_MONO)
110c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		writel(bg_color, engine + 0x1C);
111c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat
112c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	if (op != VIA_BITBLT_FILL) {
113c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		tmp = src_mem ? 0 : src_addr;
114c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		if (dst_addr & 0xE0000007) {
115c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat			printk(KERN_WARNING "hw_bitblt_1: Unsupported source "
116c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat				"address %X\n", tmp);
117c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat			return -EINVAL;
118c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		}
119c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		tmp >>= 3;
120c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		writel(tmp, engine + 0x30);
121c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	}
122c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat
123c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	if (dst_addr & 0xE0000007) {
124c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		printk(KERN_WARNING "hw_bitblt_1: Unsupported destination "
125c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat			"address %X\n", dst_addr);
126c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		return -EINVAL;
127c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	}
128c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	tmp = dst_addr >> 3;
129c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	writel(tmp, engine + 0x34);
130c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat
131c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	if (op == VIA_BITBLT_FILL)
132c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		tmp = 0;
133c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	else
134c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		tmp = src_pitch;
135c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	if (tmp & 0xFFFFC007 || dst_pitch & 0xFFFFC007) {
136c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		printk(KERN_WARNING "hw_bitblt_1: Unsupported pitch %X %X\n",
137c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat			tmp, dst_pitch);
138c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		return -EINVAL;
139c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	}
140c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	tmp = (tmp >> 3) | (dst_pitch << (16 - 3));
141c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	writel(tmp, engine + 0x38);
142c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat
143c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	if (op == VIA_BITBLT_FILL)
144c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		ge_cmd |= fill_rop << 24 | 0x00002000 | 0x00000001;
145c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	else {
146c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		ge_cmd |= 0xCC000000; /* ROP=SRCCOPY */
147c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		if (src_mem)
148c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat			ge_cmd |= 0x00000040;
149c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		if (op == VIA_BITBLT_MONO)
150c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat			ge_cmd |= 0x00000002 | 0x00000100 | 0x00020000;
151c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		else
152c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat			ge_cmd |= 0x00000001;
153c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	}
154c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	writel(ge_cmd, engine);
155c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat
156c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	if (op == VIA_BITBLT_FILL || !src_mem)
157c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		return 0;
158c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat
159c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	tmp = (width * height * (op == VIA_BITBLT_MONO ? 1 : (dst_bpp >> 3)) +
160c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		3) >> 2;
161c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat
162c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	for (i = 0; i < tmp; i++)
163c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		writel(src_mem[i], engine + VIA_MMIO_BLTBASE);
164c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat
165c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	return 0;
166c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat}
167c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat
168c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinatstatic int hw_bitblt_2(void __iomem *engine, u8 op, u32 width, u32 height,
169c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	u8 dst_bpp, u32 dst_addr, u32 dst_pitch, u32 dst_x, u32 dst_y,
170c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	u32 *src_mem, u32 src_addr, u32 src_pitch, u32 src_x, u32 src_y,
171c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	u32 fg_color, u32 bg_color, u8 fill_rop)
172c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat{
173c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	u32 ge_cmd = 0, tmp, i;
174c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat
175c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	if (!op || op > 3) {
176c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		printk(KERN_WARNING "hw_bitblt_2: Invalid operation: %d\n", op);
177c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		return -EINVAL;
178c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	}
179c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat
180c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	if (op != VIA_BITBLT_FILL && !src_mem && src_addr == dst_addr) {
181c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		if (src_x < dst_x) {
182c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat			ge_cmd |= 0x00008000;
183c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat			src_x += width - 1;
184c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat			dst_x += width - 1;
185c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		}
186c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		if (src_y < dst_y) {
187c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat			ge_cmd |= 0x00004000;
188c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat			src_y += height - 1;
189c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat			dst_y += height - 1;
190c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		}
191c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	}
192c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat
193c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	if (op == VIA_BITBLT_FILL) {
194c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		switch (fill_rop) {
195c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		case 0x00: /* blackness */
196c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		case 0x5A: /* pattern inversion */
197c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		case 0xF0: /* pattern copy */
198c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		case 0xFF: /* whiteness */
199c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat			break;
200c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		default:
201c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat			printk(KERN_WARNING "hw_bitblt_2: Invalid fill rop: "
202c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat				"%u\n", fill_rop);
203c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat			return -EINVAL;
204c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		}
205c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	}
206c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat
207c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	switch (dst_bpp) {
208c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	case 8:
209c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		tmp = 0x00000000;
210c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		break;
211c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	case 16:
212c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		tmp = 0x00000100;
213c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		break;
214c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	case 32:
215c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		tmp = 0x00000300;
216c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		break;
217c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	default:
218c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		printk(KERN_WARNING "hw_bitblt_2: Unsupported bpp %d\n",
219c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat			dst_bpp);
220c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		return -EINVAL;
221c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	}
222c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	writel(tmp, engine + 0x04);
223c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat
224c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	if (op == VIA_BITBLT_FILL)
225c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		tmp = 0;
226c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	else
227c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		tmp = src_pitch;
228c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	if (tmp & 0xFFFFC007 || dst_pitch & 0xFFFFC007) {
229c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		printk(KERN_WARNING "hw_bitblt_2: Unsupported pitch %X %X\n",
230c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat			tmp, dst_pitch);
231c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		return -EINVAL;
232c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	}
233c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	tmp = (tmp >> 3) | (dst_pitch << (16 - 3));
234c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	writel(tmp, engine + 0x08);
235c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat
236c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	if ((width - 1) & 0xFFFFF000 || (height - 1) & 0xFFFFF000) {
237c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		printk(KERN_WARNING "hw_bitblt_2: Unsupported width/height "
238c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat			"%d %d\n", width, height);
239c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		return -EINVAL;
240c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	}
241c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	tmp = (width - 1) | ((height - 1) << 16);
242c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	writel(tmp, engine + 0x0C);
243c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat
244c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	if (dst_x & 0xFFFFF000 || dst_y & 0xFFFFF000) {
245c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		printk(KERN_WARNING "hw_bitblt_2: Unsupported destination x/y "
246c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat			"%d %d\n", dst_x, dst_y);
247c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		return -EINVAL;
248c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	}
249c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	tmp = dst_x | (dst_y << 16);
250c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	writel(tmp, engine + 0x10);
251c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat
252c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	if (dst_addr & 0xE0000007) {
253c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		printk(KERN_WARNING "hw_bitblt_2: Unsupported destination "
254c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat			"address %X\n", dst_addr);
255c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		return -EINVAL;
256c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	}
257c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	tmp = dst_addr >> 3;
258c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	writel(tmp, engine + 0x14);
259c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat
260c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	if (op != VIA_BITBLT_FILL) {
261c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		if (src_x & (op == VIA_BITBLT_MONO ? 0xFFFF8000 : 0xFFFFF000)
262c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat			|| src_y & 0xFFFFF000) {
263c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat			printk(KERN_WARNING "hw_bitblt_2: Unsupported source "
264c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat				"x/y %d %d\n", src_x, src_y);
265c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat			return -EINVAL;
266c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		}
267c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		tmp = src_x | (src_y << 16);
268c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		writel(tmp, engine + 0x18);
269c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat
270c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		tmp = src_mem ? 0 : src_addr;
271c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		if (dst_addr & 0xE0000007) {
272c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat			printk(KERN_WARNING "hw_bitblt_2: Unsupported source "
273c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat				"address %X\n", tmp);
274c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat			return -EINVAL;
275c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		}
276c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		tmp >>= 3;
277c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		writel(tmp, engine + 0x1C);
278c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	}
279c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat
280c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	if (op != VIA_BITBLT_COLOR)
281c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		writel(fg_color, engine + 0x4C);
282c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat
283c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	if (op == VIA_BITBLT_MONO)
284c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		writel(bg_color, engine + 0x50);
285c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat
286c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	if (op == VIA_BITBLT_FILL)
287c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		ge_cmd |= fill_rop << 24 | 0x00002000 | 0x00000001;
288c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	else {
289c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		ge_cmd |= 0xCC000000; /* ROP=SRCCOPY */
290c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		if (src_mem)
291c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat			ge_cmd |= 0x00000040;
292c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		if (op == VIA_BITBLT_MONO)
293c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat			ge_cmd |= 0x00000002 | 0x00000100 | 0x00020000;
294c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		else
295c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat			ge_cmd |= 0x00000001;
296c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	}
297c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	writel(ge_cmd, engine);
298c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat
299c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	if (op == VIA_BITBLT_FILL || !src_mem)
300c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		return 0;
301c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat
302c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	tmp = (width * height * (op == VIA_BITBLT_MONO ? 1 : (dst_bpp >> 3)) +
303c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		3) >> 2;
304c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat
305c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	for (i = 0; i < tmp; i++)
306c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		writel(src_mem[i], engine + VIA_MMIO_BLTBASE);
307c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat
308c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	return 0;
309c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat}
310c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat
311c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinatvoid viafb_init_accel(struct viafb_shared *shared)
312c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat{
313c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	switch (shared->chip_info.gfx_chip_name) {
314c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	case UNICHROME_CLE266:
315c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	case UNICHROME_K400:
316c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	case UNICHROME_K800:
317c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	case UNICHROME_PM800:
318c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	case UNICHROME_CN700:
319c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	case UNICHROME_CX700:
320c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	case UNICHROME_CN750:
321c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	case UNICHROME_K8M890:
322c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	case UNICHROME_P4M890:
323c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	case UNICHROME_P4M900:
324c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		shared->hw_bitblt = hw_bitblt_1;
325c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		break;
326c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	case UNICHROME_VX800:
327c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		shared->hw_bitblt = hw_bitblt_2;
328c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		break;
329c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	default:
330c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat		shared->hw_bitblt = NULL;
331c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	}
332c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat
333801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan	viaparinfo->fbmem_free -= CURSOR_SIZE;
334801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan	viaparinfo->cursor_start = viaparinfo->fbmem_free;
335801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan	viaparinfo->fbmem_used += CURSOR_SIZE;
336801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan
337801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan	/* Reverse 8*1024 memory space for cursor image */
338801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan	viaparinfo->fbmem_free -= (CURSOR_SIZE + VQ_SIZE);
339801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan	viaparinfo->VQ_start = viaparinfo->fbmem_free;
340801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan	viaparinfo->VQ_end = viaparinfo->VQ_start + VQ_SIZE - 1;
341c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	viaparinfo->fbmem_used += (CURSOR_SIZE + VQ_SIZE);
342c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat}
343801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan
344801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chanvoid viafb_init_2d_engine(void)
345801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan{
346c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat	u32 dwVQStartAddr, dwVQEndAddr;
347801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan	u32 dwVQLen, dwVQStartL, dwVQEndL, dwVQStartEndH;
348801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan
349801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan	/* Init AGP and VQ regs */
350801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan	switch (viaparinfo->chip_info->gfx_chip_name) {
351801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan	case UNICHROME_K8M890:
352801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan	case UNICHROME_P4M900:
353801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan		writel(0x00100000, viaparinfo->io_virt + VIA_REG_CR_TRANSET);
354801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan		writel(0x680A0000, viaparinfo->io_virt + VIA_REG_CR_TRANSPACE);
355801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan		writel(0x02000000, viaparinfo->io_virt + VIA_REG_CR_TRANSPACE);
356801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan		break;
357801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan
358801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan	default:
359801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan		writel(0x00100000, viaparinfo->io_virt + VIA_REG_TRANSET);
360801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan		writel(0x00000000, viaparinfo->io_virt + VIA_REG_TRANSPACE);
361801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan		writel(0x00333004, viaparinfo->io_virt + VIA_REG_TRANSPACE);
362801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan		writel(0x60000000, viaparinfo->io_virt + VIA_REG_TRANSPACE);
363801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan		writel(0x61000000, viaparinfo->io_virt + VIA_REG_TRANSPACE);
364801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan		writel(0x62000000, viaparinfo->io_virt + VIA_REG_TRANSPACE);
365801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan		writel(0x63000000, viaparinfo->io_virt + VIA_REG_TRANSPACE);
366801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan		writel(0x64000000, viaparinfo->io_virt + VIA_REG_TRANSPACE);
367801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan		writel(0x7D000000, viaparinfo->io_virt + VIA_REG_TRANSPACE);
368801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan
369801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan		writel(0xFE020000, viaparinfo->io_virt + VIA_REG_TRANSET);
370801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan		writel(0x00000000, viaparinfo->io_virt + VIA_REG_TRANSPACE);
371801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan		break;
372801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan	}
373801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan	if (viaparinfo->VQ_start != 0) {
374801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan		/* Enable VQ */
375801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan		dwVQStartAddr = viaparinfo->VQ_start;
376801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan		dwVQEndAddr = viaparinfo->VQ_end;
377801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan
378801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan		dwVQStartL = 0x50000000 | (dwVQStartAddr & 0xFFFFFF);
379801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan		dwVQEndL = 0x51000000 | (dwVQEndAddr & 0xFFFFFF);
380801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan		dwVQStartEndH = 0x52000000 |
381801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan			((dwVQStartAddr & 0xFF000000) >> 24) |
382801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan			((dwVQEndAddr & 0xFF000000) >> 16);
383801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan		dwVQLen = 0x53000000 | (VQ_SIZE >> 3);
384801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan		switch (viaparinfo->chip_info->gfx_chip_name) {
385801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan		case UNICHROME_K8M890:
386801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan		case UNICHROME_P4M900:
387801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan			dwVQStartL |= 0x20000000;
388801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan			dwVQEndL |= 0x20000000;
389801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan			dwVQStartEndH |= 0x20000000;
390801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan			dwVQLen |= 0x20000000;
391801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan			break;
392801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan		default:
393801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan			break;
394801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan		}
395801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan
396801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan		switch (viaparinfo->chip_info->gfx_chip_name) {
397801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan		case UNICHROME_K8M890:
398801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan		case UNICHROME_P4M900:
399801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan			writel(0x00100000,
400801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan				viaparinfo->io_virt + VIA_REG_CR_TRANSET);
401801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan			writel(dwVQStartEndH,
402801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan				viaparinfo->io_virt + VIA_REG_CR_TRANSPACE);
403801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan			writel(dwVQStartL,
404801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan				viaparinfo->io_virt + VIA_REG_CR_TRANSPACE);
405801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan			writel(dwVQEndL,
406801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan				viaparinfo->io_virt + VIA_REG_CR_TRANSPACE);
407801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan			writel(dwVQLen,
408801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan				viaparinfo->io_virt + VIA_REG_CR_TRANSPACE);
409801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan			writel(0x74301001,
410801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan				viaparinfo->io_virt + VIA_REG_CR_TRANSPACE);
411801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan			writel(0x00000000,
412801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan				viaparinfo->io_virt + VIA_REG_CR_TRANSPACE);
413801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan			break;
414801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan		default:
415801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan			writel(0x00FE0000,
416801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan				viaparinfo->io_virt + VIA_REG_TRANSET);
417801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan			writel(0x080003FE,
418801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan				viaparinfo->io_virt + VIA_REG_TRANSPACE);
419801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan			writel(0x0A00027C,
420801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan				viaparinfo->io_virt + VIA_REG_TRANSPACE);
421801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan			writel(0x0B000260,
422801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan				viaparinfo->io_virt + VIA_REG_TRANSPACE);
423801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan			writel(0x0C000274,
424801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan				viaparinfo->io_virt + VIA_REG_TRANSPACE);
425801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan			writel(0x0D000264,
426801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan				viaparinfo->io_virt + VIA_REG_TRANSPACE);
427801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan			writel(0x0E000000,
428801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan				viaparinfo->io_virt + VIA_REG_TRANSPACE);
429801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan			writel(0x0F000020,
430801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan				viaparinfo->io_virt + VIA_REG_TRANSPACE);
431801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan			writel(0x1000027E,
432801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan				viaparinfo->io_virt + VIA_REG_TRANSPACE);
433801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan			writel(0x110002FE,
434801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan				viaparinfo->io_virt + VIA_REG_TRANSPACE);
435801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan			writel(0x200F0060,
436801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan				viaparinfo->io_virt + VIA_REG_TRANSPACE);
437801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan
438801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan			writel(0x00000006,
439801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan				viaparinfo->io_virt + VIA_REG_TRANSPACE);
440801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan			writel(0x40008C0F,
441801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan				viaparinfo->io_virt + VIA_REG_TRANSPACE);
442801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan			writel(0x44000000,
443801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan				viaparinfo->io_virt + VIA_REG_TRANSPACE);
444801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan			writel(0x45080C04,
445801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan				viaparinfo->io_virt + VIA_REG_TRANSPACE);
446801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan			writel(0x46800408,
447801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan				viaparinfo->io_virt + VIA_REG_TRANSPACE);
448801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan
449801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan			writel(dwVQStartEndH,
450801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan				viaparinfo->io_virt + VIA_REG_TRANSPACE);
451801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan			writel(dwVQStartL,
452801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan				viaparinfo->io_virt + VIA_REG_TRANSPACE);
453801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan			writel(dwVQEndL,
454801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan				viaparinfo->io_virt + VIA_REG_TRANSPACE);
455801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan			writel(dwVQLen,
456801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan				viaparinfo->io_virt + VIA_REG_TRANSPACE);
457801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan			break;
458801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan		}
459801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan	} else {
460801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan		/* Disable VQ */
461801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan		switch (viaparinfo->chip_info->gfx_chip_name) {
462801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan		case UNICHROME_K8M890:
463801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan		case UNICHROME_P4M900:
464801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan			writel(0x00100000,
465801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan				viaparinfo->io_virt + VIA_REG_CR_TRANSET);
466801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan			writel(0x74301000,
467801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan				viaparinfo->io_virt + VIA_REG_CR_TRANSPACE);
468801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan			break;
469801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan		default:
470801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan			writel(0x00FE0000,
471801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan				viaparinfo->io_virt + VIA_REG_TRANSET);
472801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan			writel(0x00000004,
473801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan				viaparinfo->io_virt + VIA_REG_TRANSPACE);
474801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan			writel(0x40008C0F,
475801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan				viaparinfo->io_virt + VIA_REG_TRANSPACE);
476801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan			writel(0x44000000,
477801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan				viaparinfo->io_virt + VIA_REG_TRANSPACE);
478801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan			writel(0x45080C04,
479801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan				viaparinfo->io_virt + VIA_REG_TRANSPACE);
480801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan			writel(0x46800408,
481801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan				viaparinfo->io_virt + VIA_REG_TRANSPACE);
482801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan			break;
483801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan		}
484801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan	}
485801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan}
486801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan
487801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chanvoid viafb_hw_cursor_init(void)
488801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan{
489801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan	/* Set Cursor Image Base Address */
490801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan	writel(viaparinfo->cursor_start,
491801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan		viaparinfo->io_virt + VIA_REG_CURSOR_MODE);
492801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan	writel(0x0, viaparinfo->io_virt + VIA_REG_CURSOR_POS);
493801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan	writel(0x0, viaparinfo->io_virt + VIA_REG_CURSOR_ORG);
494801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan	writel(0x0, viaparinfo->io_virt + VIA_REG_CURSOR_BG);
495801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan	writel(0x0, viaparinfo->io_virt + VIA_REG_CURSOR_FG);
496801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan}
497801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan
498801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chanvoid viafb_show_hw_cursor(struct fb_info *info, int Status)
499801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan{
500801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan	u32 temp;
501801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan	u32 iga_path = ((struct viafb_par *)(info->par))->iga_path;
502801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan
503801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan	temp = readl(viaparinfo->io_virt + VIA_REG_CURSOR_MODE);
504801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan	switch (Status) {
505801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan	case HW_Cursor_ON:
506801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan		temp |= 0x1;
507801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan		break;
508801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan	case HW_Cursor_OFF:
509801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan		temp &= 0xFFFFFFFE;
510801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan		break;
511801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan	}
512801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan	switch (iga_path) {
513801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan	case IGA2:
514801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan		temp |= 0x80000000;
515801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan		break;
516801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan	case IGA1:
517801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan	default:
518801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan		temp &= 0x7FFFFFFF;
519801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan	}
520801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan	writel(temp, viaparinfo->io_virt + VIA_REG_CURSOR_MODE);
521801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan}
522801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan
523801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chanint viafb_wait_engine_idle(void)
524801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan{
525801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan	int loop = 0;
526801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan
527801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan	while (!(readl(viaparinfo->io_virt + VIA_REG_STATUS) &
5282bd8c47597b2522795f5eb2e61c22dcfec5dfa6aRoel Kluin			VIA_VR_QUEUE_BUSY) && (loop < MAXLOOP)) {
5292bd8c47597b2522795f5eb2e61c22dcfec5dfa6aRoel Kluin		loop++;
530801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan		cpu_relax();
5312bd8c47597b2522795f5eb2e61c22dcfec5dfa6aRoel Kluin	}
532801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan
533801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan	while ((readl(viaparinfo->io_virt + VIA_REG_STATUS) &
534801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan		    (VIA_CMD_RGTR_BUSY | VIA_2D_ENG_BUSY | VIA_3D_ENG_BUSY)) &&
5352bd8c47597b2522795f5eb2e61c22dcfec5dfa6aRoel Kluin		    (loop < MAXLOOP)) {
5362bd8c47597b2522795f5eb2e61c22dcfec5dfa6aRoel Kluin		loop++;
537801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan		cpu_relax();
5382bd8c47597b2522795f5eb2e61c22dcfec5dfa6aRoel Kluin	}
539801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan
540801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan	return loop >= MAXLOOP;
541801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan}
542