1 /****************************************************************************
2 * Copyright (C) 2003-2006 by XGI Technology, Taiwan.
6 * Permission is hereby granted, free of charge, to any person obtaining
7 * a copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation on the rights to use, copy, modify, merge,
10 * publish, distribute, sublicense, and/or sell copies of the Software,
11 * and to permit persons to whom the Software is furnished to do so,
12 * subject to the following conditions:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial
16 * portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
21 * XGI AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 * DEALINGS IN THE SOFTWARE.
25 ***************************************************************************/
30 #include <linux/delay.h>
35 #define STALL_INTERRUPT_RESET_THRESHOLD 0xffff
37 static unsigned int s_invalid_begin = 0;
39 static bool xgi_validate_signal(struct drm_map * map)
41 if (le32_to_cpu(DRM_READ32(map, 0x2800) & 0x001c0000)) {
44 /* Check Read back status */
45 DRM_WRITE8(map, 0x235c, 0x80);
46 check = le16_to_cpu(DRM_READ16(map, 0x2360));
48 if ((check & 0x3f) != ((check & 0x3f00) >> 8)) {
52 /* Check RO channel */
53 DRM_WRITE8(map, 0x235c, 0x83);
54 check = le16_to_cpu(DRM_READ16(map, 0x2360));
55 if ((check & 0x0f) != ((check & 0xf0) >> 4)) {
59 /* Check RW channel */
60 DRM_WRITE8(map, 0x235c, 0x88);
61 check = le16_to_cpu(DRM_READ16(map, 0x2360));
62 if ((check & 0x0f) != ((check & 0xf0) >> 4)) {
66 /* Check RO channel outstanding */
67 DRM_WRITE8(map, 0x235c, 0x8f);
68 check = le16_to_cpu(DRM_READ16(map, 0x2360));
69 if (0 != (check & 0x3ff)) {
73 /* Check RW channel outstanding */
74 DRM_WRITE8(map, 0x235c, 0x90);
75 check = le16_to_cpu(DRM_READ16(map, 0x2360));
76 if (0 != (check & 0x3ff)) {
80 /* No pending PCIE request. GE stall. */
87 static void xgi_ge_hang_reset(struct drm_map * map)
89 int time_out = 0xffff;
91 DRM_WRITE8(map, 0xb057, 8);
92 while (0 != le32_to_cpu(DRM_READ32(map, 0x2800) & 0xf0000000)) {
93 while (0 != ((--time_out) & 0xfff))
102 DRM_INFO("Can not reset back 0x%x!\n",
103 le32_to_cpu(DRM_READ32(map, 0x2800)));
105 DRM_WRITE8(map, 0xb057, 0);
107 /* Have to use 3x5.36 to reset. */
108 /* Save and close dynamic gating */
110 old_3ce = DRM_READ8(map, 0x3ce);
111 DRM_WRITE8(map, 0x3ce, 0x2a);
112 old_3cf = DRM_READ8(map, 0x3cf);
113 DRM_WRITE8(map, 0x3cf, old_3cf & 0xfe);
116 old_index = DRM_READ8(map, 0x3d4);
117 DRM_WRITE8(map, 0x3d4, 0x36);
118 old_36 = DRM_READ8(map, 0x3d5);
119 DRM_WRITE8(map, 0x3d5, old_36 | 0x10);
121 while (0 != ((--time_out) & 0xfff))
124 DRM_WRITE8(map, 0x3d5, old_36);
125 DRM_WRITE8(map, 0x3d4, old_index);
127 /* Restore dynamic gating */
128 DRM_WRITE8(map, 0x3cf, old_3cf);
129 DRM_WRITE8(map, 0x3ce, old_3ce);
134 DRM_WRITE8(map, 0xb057, 0);
138 bool xgi_ge_irq_handler(struct xgi_info * info)
140 const u32 int_status = le32_to_cpu(DRM_READ32(info->mmio_map, 0x2810));
141 bool is_support_auto_reset = FALSE;
143 /* Check GE on/off */
144 if (0 == (0xffffc0f0 & int_status)) {
145 if (0 != (0x1000 & int_status)) {
146 /* We got GE stall interrupt.
148 DRM_WRITE32(info->mmio_map, 0x2810,
149 cpu_to_le32(int_status | 0x04000000));
151 if (is_support_auto_reset) {
152 static cycles_t last_tick;
153 static unsigned continue_int_count = 0;
157 if (!xgi_validate_signal(info->mmio_map)) {
158 /* Nothing but skip. */
159 } else if (0 == continue_int_count++) {
160 last_tick = get_cycles();
162 const cycles_t new_tick = get_cycles();
163 if ((new_tick - last_tick) >
164 STALL_INTERRUPT_RESET_THRESHOLD) {
165 continue_int_count = 0;
166 } else if (continue_int_count >= 3) {
167 continue_int_count = 0;
169 /* GE Hung up, need reset. */
170 DRM_INFO("Reset GE!\n");
172 xgi_ge_hang_reset(info->mmio_map);
176 } else if (0 != (0x1 & int_status)) {
178 DRM_WRITE32(info->mmio_map, 0x2810,
179 cpu_to_le32((int_status & ~0x01) | 0x04000000));
188 bool xgi_crt_irq_handler(struct xgi_info * info)
191 u8 save_3ce = DRM_READ8(info->mmio_map, 0x3ce);
193 /* CRT1 interrupt just happened
195 if (IN3CFB(info->mmio_map, 0x37) & 0x01) {
201 op3cf_37 = IN3CFB(info->mmio_map, 0x37);
203 /* Clear CRT interrupt
205 op3cf_3d = IN3CFB(info->mmio_map, 0x3d);
206 OUT3CFB(info->mmio_map, 0x3d, (op3cf_3d | 0x04));
207 OUT3CFB(info->mmio_map, 0x3d, (op3cf_3d & ~0x04));
210 DRM_WRITE8(info->mmio_map, 0x3ce, save_3ce);
215 bool xgi_dvi_irq_handler(struct xgi_info * info)
218 const u8 save_3ce = DRM_READ8(info->mmio_map, 0x3ce);
220 /* DVI interrupt just happened
222 if (IN3CFB(info->mmio_map, 0x38) & 0x20) {
223 const u8 save_3x4 = DRM_READ8(info->mmio_map, 0x3d4);
230 op3cf_37 = IN3CFB(info->mmio_map, 0x37);
232 /* Notify BIOS that DVI plug/unplug happened
234 op3x5_5a = IN3X5B(info->mmio_map, 0x5a);
235 OUT3X5B(info->mmio_map, 0x5a, op3x5_5a & 0xf7);
237 DRM_WRITE8(info->mmio_map, 0x3d4, save_3x4);
239 /* Clear DVI interrupt
241 op3cf_39 = IN3CFB(info->mmio_map, 0x39);
242 OUT3C5B(info->mmio_map, 0x39, (op3cf_39 & ~0x01));
243 OUT3C5B(info->mmio_map, 0x39, (op3cf_39 | 0x01));
247 DRM_WRITE8(info->mmio_map, 0x3ce, save_3ce);
253 static void dump_reg_header(unsigned regbase)
255 printk("\n=====xgi_dump_register========0x%x===============\n",
257 printk(" 0 1 2 3 4 5 6 7 8 9 a b c d e f\n");
261 static void dump_indexed_reg(struct xgi_info * info, unsigned regbase)
267 dump_reg_header(regbase);
268 for (i = 0; i < 0x10; i++) {
271 for (j = 0; j < 0x10; j++) {
272 DRM_WRITE8(info->mmio_map, regbase - 1,
274 temp = DRM_READ8(info->mmio_map, regbase);
282 static void dump_reg(struct xgi_info * info, unsigned regbase, unsigned range)
287 dump_reg_header(regbase);
288 for (i = 0; i < range; i++) {
291 for (j = 0; j < 0x10; j++) {
292 u8 temp = DRM_READ8(info->mmio_map,
293 regbase + (i * 0x10) + j);
301 void xgi_dump_register(struct xgi_info * info)
303 dump_indexed_reg(info, 0x3c5);
304 dump_indexed_reg(info, 0x3d5);
305 dump_indexed_reg(info, 0x3cf);
307 dump_reg(info, 0xB000, 0x05);
308 dump_reg(info, 0x2200, 0x0B);
309 dump_reg(info, 0x2300, 0x07);
310 dump_reg(info, 0x2400, 0x10);
311 dump_reg(info, 0x2800, 0x10);
315 #define WHOLD_GE_STATUS 0x2800
317 /* Test everything except the "whole GE busy" bit, the "master engine busy"
318 * bit, and the reserved bits [26:21].
320 #define IDLE_MASK ~((1U<<31) | (1U<<28) | (0x3f<<21))
322 void xgi_waitfor_pci_idle(struct xgi_info * info)
324 unsigned int idleCount = 0;
326 unsigned int same_count = 0;
328 while (idleCount < 5) {
329 const u32 status = DRM_READ32(info->mmio_map, WHOLD_GE_STATUS)
332 if (status == old_status) {
335 if ((same_count % 100) == 0) {
336 DRM_ERROR("GE status stuck at 0x%08x for %u iterations!\n",
337 old_status, same_count);
354 void xgi_enable_mmio(struct xgi_info * info)
359 /* Unprotect registers */
360 DRM_WRITE8(info->mmio_map, 0x3C4, 0x11);
361 protect = DRM_READ8(info->mmio_map, 0x3C5);
362 DRM_WRITE8(info->mmio_map, 0x3C5, 0x92);
364 DRM_WRITE8(info->mmio_map, 0x3D4, 0x3A);
365 temp = DRM_READ8(info->mmio_map, 0x3D5);
366 DRM_WRITE8(info->mmio_map, 0x3D5, temp | 0x20);
369 DRM_WRITE8(info->mmio_map, 0x3D4, 0x39);
370 temp = DRM_READ8(info->mmio_map, 0x3D5);
371 DRM_WRITE8(info->mmio_map, 0x3D5, temp | 0x01);
373 /* Protect registers */
374 OUT3C5B(info->mmio_map, 0x11, protect);
378 void xgi_disable_mmio(struct xgi_info * info)
383 /* Unprotect registers */
384 DRM_WRITE8(info->mmio_map, 0x3C4, 0x11);
385 protect = DRM_READ8(info->mmio_map, 0x3C5);
386 DRM_WRITE8(info->mmio_map, 0x3C5, 0x92);
388 /* Disable MMIO access */
389 DRM_WRITE8(info->mmio_map, 0x3D4, 0x39);
390 temp = DRM_READ8(info->mmio_map, 0x3D5);
391 DRM_WRITE8(info->mmio_map, 0x3D5, temp & 0xFE);
393 /* Protect registers */
394 OUT3C5B(info->mmio_map, 0x11, protect);
398 void xgi_enable_ge(struct xgi_info * info)
403 OUT3C5B(info->mmio_map, 0x11, 0x92);
405 /* Save and close dynamic gating
407 bOld3cf2a = IN3CFB(info->mmio_map, XGI_MISC_CTRL);
408 OUT3CFB(info->mmio_map, XGI_MISC_CTRL, bOld3cf2a & ~EN_GEPWM);
410 /* Enable 2D and 3D GE
412 OUT3X5B(info->mmio_map, XGI_GE_CNTL, (GE_ENABLE | GE_ENABLE_3D));
415 DRM_READ8(info->mmio_map, 0x36);
418 /* Reset both 3D and 2D engine
420 OUT3X5B(info->mmio_map, XGI_GE_CNTL,
421 (GE_ENABLE | GE_RESET | GE_ENABLE_3D));
424 DRM_READ8(info->mmio_map, 0x36);
427 OUT3X5B(info->mmio_map, XGI_GE_CNTL, (GE_ENABLE | GE_ENABLE_3D));
430 DRM_READ8(info->mmio_map, 0x36);
433 /* Enable 2D engine only
435 OUT3X5B(info->mmio_map, XGI_GE_CNTL, GE_ENABLE);
437 /* Enable 2D+3D engine
439 OUT3X5B(info->mmio_map, XGI_GE_CNTL, (GE_ENABLE | GE_ENABLE_3D));
441 /* Restore dynamic gating
443 OUT3CFB(info->mmio_map, XGI_MISC_CTRL, bOld3cf2a);
447 void xgi_disable_ge(struct xgi_info * info)
451 OUT3X5B(info->mmio_map, XGI_GE_CNTL, (GE_ENABLE | GE_ENABLE_3D));
455 DRM_READ8(info->mmio_map, 0x36);
458 /* Reset both 3D and 2D engine
460 OUT3X5B(info->mmio_map, XGI_GE_CNTL,
461 (GE_ENABLE | GE_RESET | GE_ENABLE_3D));
465 DRM_READ8(info->mmio_map, 0x36);
467 OUT3X5B(info->mmio_map, XGI_GE_CNTL, (GE_ENABLE | GE_ENABLE_3D));
471 DRM_READ8(info->mmio_map, 0x36);
474 /* Disable 2D engine and 3D engine.
476 OUT3X5B(info->mmio_map, XGI_GE_CNTL, 0);