45c54bfe99bb86f68b94be7dc73879d50b78d74d
[deliverable/linux.git] / drivers / video / via / accel.c
1 /*
2 * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
4
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public
7 * License as published by the Free Software Foundation;
8 * either version 2, or (at your option) any later version.
9
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
12 * the implied warranty of MERCHANTABILITY or FITNESS FOR
13 * A PARTICULAR PURPOSE.See the GNU General Public License
14 * for more details.
15
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc.,
19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */
21 #include "global.h"
22
23 void viafb_init_accel(void)
24 {
25 viaparinfo->fbmem_free -= CURSOR_SIZE;
26 viaparinfo->cursor_start = viaparinfo->fbmem_free;
27 viaparinfo->fbmem_used += CURSOR_SIZE;
28
29 /* Reverse 8*1024 memory space for cursor image */
30 viaparinfo->fbmem_free -= (CURSOR_SIZE + VQ_SIZE);
31 viaparinfo->VQ_start = viaparinfo->fbmem_free;
32 viaparinfo->VQ_end = viaparinfo->VQ_start + VQ_SIZE - 1;
33 viaparinfo->fbmem_used += (CURSOR_SIZE + VQ_SIZE); }
34
35 void viafb_init_2d_engine(void)
36 {
37 u32 dwVQStartAddr, dwVQEndAddr;
38 u32 dwVQLen, dwVQStartL, dwVQEndL, dwVQStartEndH;
39
40 /* init 2D engine regs to reset 2D engine */
41 writel(0x0, viaparinfo->io_virt + VIA_REG_GEMODE);
42 writel(0x0, viaparinfo->io_virt + VIA_REG_SRCPOS);
43 writel(0x0, viaparinfo->io_virt + VIA_REG_DSTPOS);
44 writel(0x0, viaparinfo->io_virt + VIA_REG_DIMENSION);
45 writel(0x0, viaparinfo->io_virt + VIA_REG_PATADDR);
46 writel(0x0, viaparinfo->io_virt + VIA_REG_FGCOLOR);
47 writel(0x0, viaparinfo->io_virt + VIA_REG_BGCOLOR);
48 writel(0x0, viaparinfo->io_virt + VIA_REG_CLIPTL);
49 writel(0x0, viaparinfo->io_virt + VIA_REG_CLIPBR);
50 writel(0x0, viaparinfo->io_virt + VIA_REG_OFFSET);
51 writel(0x0, viaparinfo->io_virt + VIA_REG_KEYCONTROL);
52 writel(0x0, viaparinfo->io_virt + VIA_REG_SRCBASE);
53 writel(0x0, viaparinfo->io_virt + VIA_REG_DSTBASE);
54 writel(0x0, viaparinfo->io_virt + VIA_REG_PITCH);
55 writel(0x0, viaparinfo->io_virt + VIA_REG_MONOPAT1);
56
57 /* Init AGP and VQ regs */
58 switch (viaparinfo->chip_info->gfx_chip_name) {
59 case UNICHROME_K8M890:
60 case UNICHROME_P4M900:
61 writel(0x00100000, viaparinfo->io_virt + VIA_REG_CR_TRANSET);
62 writel(0x680A0000, viaparinfo->io_virt + VIA_REG_CR_TRANSPACE);
63 writel(0x02000000, viaparinfo->io_virt + VIA_REG_CR_TRANSPACE);
64 break;
65
66 default:
67 writel(0x00100000, viaparinfo->io_virt + VIA_REG_TRANSET);
68 writel(0x00000000, viaparinfo->io_virt + VIA_REG_TRANSPACE);
69 writel(0x00333004, viaparinfo->io_virt + VIA_REG_TRANSPACE);
70 writel(0x60000000, viaparinfo->io_virt + VIA_REG_TRANSPACE);
71 writel(0x61000000, viaparinfo->io_virt + VIA_REG_TRANSPACE);
72 writel(0x62000000, viaparinfo->io_virt + VIA_REG_TRANSPACE);
73 writel(0x63000000, viaparinfo->io_virt + VIA_REG_TRANSPACE);
74 writel(0x64000000, viaparinfo->io_virt + VIA_REG_TRANSPACE);
75 writel(0x7D000000, viaparinfo->io_virt + VIA_REG_TRANSPACE);
76
77 writel(0xFE020000, viaparinfo->io_virt + VIA_REG_TRANSET);
78 writel(0x00000000, viaparinfo->io_virt + VIA_REG_TRANSPACE);
79 break;
80 }
81 if (viaparinfo->VQ_start != 0) {
82 /* Enable VQ */
83 dwVQStartAddr = viaparinfo->VQ_start;
84 dwVQEndAddr = viaparinfo->VQ_end;
85
86 dwVQStartL = 0x50000000 | (dwVQStartAddr & 0xFFFFFF);
87 dwVQEndL = 0x51000000 | (dwVQEndAddr & 0xFFFFFF);
88 dwVQStartEndH = 0x52000000 |
89 ((dwVQStartAddr & 0xFF000000) >> 24) |
90 ((dwVQEndAddr & 0xFF000000) >> 16);
91 dwVQLen = 0x53000000 | (VQ_SIZE >> 3);
92 switch (viaparinfo->chip_info->gfx_chip_name) {
93 case UNICHROME_K8M890:
94 case UNICHROME_P4M900:
95 dwVQStartL |= 0x20000000;
96 dwVQEndL |= 0x20000000;
97 dwVQStartEndH |= 0x20000000;
98 dwVQLen |= 0x20000000;
99 break;
100 default:
101 break;
102 }
103
104 switch (viaparinfo->chip_info->gfx_chip_name) {
105 case UNICHROME_K8M890:
106 case UNICHROME_P4M900:
107 writel(0x00100000,
108 viaparinfo->io_virt + VIA_REG_CR_TRANSET);
109 writel(dwVQStartEndH,
110 viaparinfo->io_virt + VIA_REG_CR_TRANSPACE);
111 writel(dwVQStartL,
112 viaparinfo->io_virt + VIA_REG_CR_TRANSPACE);
113 writel(dwVQEndL,
114 viaparinfo->io_virt + VIA_REG_CR_TRANSPACE);
115 writel(dwVQLen,
116 viaparinfo->io_virt + VIA_REG_CR_TRANSPACE);
117 writel(0x74301001,
118 viaparinfo->io_virt + VIA_REG_CR_TRANSPACE);
119 writel(0x00000000,
120 viaparinfo->io_virt + VIA_REG_CR_TRANSPACE);
121 break;
122 default:
123 writel(0x00FE0000,
124 viaparinfo->io_virt + VIA_REG_TRANSET);
125 writel(0x080003FE,
126 viaparinfo->io_virt + VIA_REG_TRANSPACE);
127 writel(0x0A00027C,
128 viaparinfo->io_virt + VIA_REG_TRANSPACE);
129 writel(0x0B000260,
130 viaparinfo->io_virt + VIA_REG_TRANSPACE);
131 writel(0x0C000274,
132 viaparinfo->io_virt + VIA_REG_TRANSPACE);
133 writel(0x0D000264,
134 viaparinfo->io_virt + VIA_REG_TRANSPACE);
135 writel(0x0E000000,
136 viaparinfo->io_virt + VIA_REG_TRANSPACE);
137 writel(0x0F000020,
138 viaparinfo->io_virt + VIA_REG_TRANSPACE);
139 writel(0x1000027E,
140 viaparinfo->io_virt + VIA_REG_TRANSPACE);
141 writel(0x110002FE,
142 viaparinfo->io_virt + VIA_REG_TRANSPACE);
143 writel(0x200F0060,
144 viaparinfo->io_virt + VIA_REG_TRANSPACE);
145
146 writel(0x00000006,
147 viaparinfo->io_virt + VIA_REG_TRANSPACE);
148 writel(0x40008C0F,
149 viaparinfo->io_virt + VIA_REG_TRANSPACE);
150 writel(0x44000000,
151 viaparinfo->io_virt + VIA_REG_TRANSPACE);
152 writel(0x45080C04,
153 viaparinfo->io_virt + VIA_REG_TRANSPACE);
154 writel(0x46800408,
155 viaparinfo->io_virt + VIA_REG_TRANSPACE);
156
157 writel(dwVQStartEndH,
158 viaparinfo->io_virt + VIA_REG_TRANSPACE);
159 writel(dwVQStartL,
160 viaparinfo->io_virt + VIA_REG_TRANSPACE);
161 writel(dwVQEndL,
162 viaparinfo->io_virt + VIA_REG_TRANSPACE);
163 writel(dwVQLen,
164 viaparinfo->io_virt + VIA_REG_TRANSPACE);
165 break;
166 }
167 } else {
168 /* Disable VQ */
169 switch (viaparinfo->chip_info->gfx_chip_name) {
170 case UNICHROME_K8M890:
171 case UNICHROME_P4M900:
172 writel(0x00100000,
173 viaparinfo->io_virt + VIA_REG_CR_TRANSET);
174 writel(0x74301000,
175 viaparinfo->io_virt + VIA_REG_CR_TRANSPACE);
176 break;
177 default:
178 writel(0x00FE0000,
179 viaparinfo->io_virt + VIA_REG_TRANSET);
180 writel(0x00000004,
181 viaparinfo->io_virt + VIA_REG_TRANSPACE);
182 writel(0x40008C0F,
183 viaparinfo->io_virt + VIA_REG_TRANSPACE);
184 writel(0x44000000,
185 viaparinfo->io_virt + VIA_REG_TRANSPACE);
186 writel(0x45080C04,
187 viaparinfo->io_virt + VIA_REG_TRANSPACE);
188 writel(0x46800408,
189 viaparinfo->io_virt + VIA_REG_TRANSPACE);
190 break;
191 }
192 }
193
194 viafb_set_2d_color_depth(viaparinfo->bpp);
195
196 writel(0x0, viaparinfo->io_virt + VIA_REG_SRCBASE);
197 writel(0x0, viaparinfo->io_virt + VIA_REG_DSTBASE);
198
199 writel(VIA_PITCH_ENABLE |
200 (((viaparinfo->hres *
201 viaparinfo->bpp >> 3) >> 3) | (((viaparinfo->hres *
202 viaparinfo->
203 bpp >> 3) >> 3) << 16)),
204 viaparinfo->io_virt + VIA_REG_PITCH);
205 }
206
207 void viafb_set_2d_color_depth(int bpp)
208 {
209 u32 dwGEMode;
210
211 dwGEMode = readl(viaparinfo->io_virt + 0x04) & 0xFFFFFCFF;
212
213 switch (bpp) {
214 case 16:
215 dwGEMode |= VIA_GEM_16bpp;
216 break;
217 case 32:
218 dwGEMode |= VIA_GEM_32bpp;
219 break;
220 default:
221 dwGEMode |= VIA_GEM_8bpp;
222 break;
223 }
224
225 /* Set BPP and Pitch */
226 writel(dwGEMode, viaparinfo->io_virt + VIA_REG_GEMODE);
227 }
228
229 void viafb_hw_cursor_init(void)
230 {
231 /* Set Cursor Image Base Address */
232 writel(viaparinfo->cursor_start,
233 viaparinfo->io_virt + VIA_REG_CURSOR_MODE);
234 writel(0x0, viaparinfo->io_virt + VIA_REG_CURSOR_POS);
235 writel(0x0, viaparinfo->io_virt + VIA_REG_CURSOR_ORG);
236 writel(0x0, viaparinfo->io_virt + VIA_REG_CURSOR_BG);
237 writel(0x0, viaparinfo->io_virt + VIA_REG_CURSOR_FG);
238 }
239
240 void viafb_show_hw_cursor(struct fb_info *info, int Status)
241 {
242 u32 temp;
243 u32 iga_path = ((struct viafb_par *)(info->par))->iga_path;
244
245 temp = readl(viaparinfo->io_virt + VIA_REG_CURSOR_MODE);
246 switch (Status) {
247 case HW_Cursor_ON:
248 temp |= 0x1;
249 break;
250 case HW_Cursor_OFF:
251 temp &= 0xFFFFFFFE;
252 break;
253 }
254 switch (iga_path) {
255 case IGA2:
256 temp |= 0x80000000;
257 break;
258 case IGA1:
259 default:
260 temp &= 0x7FFFFFFF;
261 }
262 writel(temp, viaparinfo->io_virt + VIA_REG_CURSOR_MODE);
263 }
264
265 int viafb_wait_engine_idle(void)
266 {
267 int loop = 0;
268
269 while (!(readl(viaparinfo->io_virt + VIA_REG_STATUS) &
270 VIA_VR_QUEUE_BUSY) && (loop < MAXLOOP)) {
271 loop++;
272 cpu_relax();
273 }
274
275 while ((readl(viaparinfo->io_virt + VIA_REG_STATUS) &
276 (VIA_CMD_RGTR_BUSY | VIA_2D_ENG_BUSY | VIA_3D_ENG_BUSY)) &&
277 (loop < MAXLOOP)) {
278 loop++;
279 cpu_relax();
280 }
281
282 return loop >= MAXLOOP;
283 }
This page took 0.036202 seconds and 5 git commands to generate.