[intel] Quirk away MSI support on 945G/GM.
[platform/upstream/libdrm.git] / linux-core / xgi_misc.c
1 /****************************************************************************
2  * Copyright (C) 2003-2006 by XGI Technology, Taiwan.
3  *
4  * All Rights Reserved.
5  *
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:
13  *
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.
17  *
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  ***************************************************************************/
26
27 #include "xgi_drv.h"
28 #include "xgi_regs.h"
29
30 #include <linux/delay.h>
31
32 /*
33  * irq functions
34  */
35 #define STALL_INTERRUPT_RESET_THRESHOLD 0xffff
36
37 static unsigned int s_invalid_begin = 0;
38
39 static bool xgi_validate_signal(struct drm_map * map)
40 {
41         if (le32_to_cpu(DRM_READ32(map, 0x2800) & 0x001c0000)) {
42                 u16 check;
43
44                 /* Check Read back status */
45                 DRM_WRITE8(map, 0x235c, 0x80);
46                 check = le16_to_cpu(DRM_READ16(map, 0x2360));
47
48                 if ((check & 0x3f) != ((check & 0x3f00) >> 8)) {
49                         return FALSE;
50                 }
51
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)) {
56                         return FALSE;
57                 }
58
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)) {
63                         return FALSE;
64                 }
65
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)) {
70                         return FALSE;
71                 }
72
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)) {
77                         return FALSE;
78                 }
79
80                 /* No pending PCIE request. GE stall. */
81         }
82
83         return TRUE;
84 }
85
86
87 static void xgi_ge_hang_reset(struct drm_map * map)
88 {
89         int time_out = 0xffff;
90
91         DRM_WRITE8(map, 0xb057, 8);
92         while (0 != le32_to_cpu(DRM_READ32(map, 0x2800) & 0xf0000000)) {
93                 while (0 != ((--time_out) & 0xfff))
94                         /* empty */ ;
95
96                 if (0 == time_out) {
97                         u8 old_3ce;
98                         u8 old_3cf;
99                         u8 old_index;
100                         u8 old_36;
101
102                         DRM_INFO("Can not reset back 0x%x!\n",
103                                  le32_to_cpu(DRM_READ32(map, 0x2800)));
104
105                         DRM_WRITE8(map, 0xb057, 0);
106
107                         /* Have to use 3x5.36 to reset. */
108                         /* Save and close dynamic gating */
109
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);
114
115                         /* Reset GE */
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);
120
121                         while (0 != ((--time_out) & 0xfff))
122                                 /* empty */ ;
123
124                         DRM_WRITE8(map, 0x3d5, old_36);
125                         DRM_WRITE8(map, 0x3d4, old_index);
126
127                         /* Restore dynamic gating */
128                         DRM_WRITE8(map, 0x3cf, old_3cf);
129                         DRM_WRITE8(map, 0x3ce, old_3ce);
130                         break;
131                 }
132         }
133
134         DRM_WRITE8(map, 0xb057, 0);
135 }
136
137
138 bool xgi_ge_irq_handler(struct xgi_info * info)
139 {
140         const u32 int_status = le32_to_cpu(DRM_READ32(info->mmio_map, 0x2810));
141         bool is_support_auto_reset = FALSE;
142
143         /* Check GE on/off */
144         if (0 == (0xffffc0f0 & int_status)) {
145                 if (0 != (0x1000 & int_status)) {
146                         /* We got GE stall interrupt.
147                          */
148                         DRM_WRITE32(info->mmio_map, 0x2810,
149                                     cpu_to_le32(int_status | 0x04000000));
150
151                         if (is_support_auto_reset) {
152                                 static cycles_t last_tick;
153                                 static unsigned continue_int_count = 0;
154
155                                 /* OE II is busy. */
156
157                                 if (!xgi_validate_signal(info->mmio_map)) {
158                                         /* Nothing but skip. */
159                                 } else if (0 == continue_int_count++) {
160                                         last_tick = get_cycles();
161                                 } else {
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;
168
169                                                 /* GE Hung up, need reset. */
170                                                 DRM_INFO("Reset GE!\n");
171
172                                                 xgi_ge_hang_reset(info->mmio_map);
173                                         }
174                                 }
175                         }
176                 } else if (0 != (0x1 & int_status)) {
177                         s_invalid_begin++;
178                         DRM_WRITE32(info->mmio_map, 0x2810,
179                                     cpu_to_le32((int_status & ~0x01) | 0x04000000));
180                 }
181
182                 return TRUE;
183         }
184
185         return FALSE;
186 }
187
188 bool xgi_crt_irq_handler(struct xgi_info * info)
189 {
190         bool ret = FALSE;
191         u8 save_3ce = DRM_READ8(info->mmio_map, 0x3ce);
192
193         /* CRT1 interrupt just happened
194          */
195         if (IN3CFB(info->mmio_map, 0x37) & 0x01) {
196                 u8 op3cf_3d;
197                 u8 op3cf_37;
198
199                 /* What happened?
200                  */
201                 op3cf_37 = IN3CFB(info->mmio_map, 0x37);
202
203                 /* Clear CRT interrupt
204                  */
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));
208                 ret = TRUE;
209         }
210         DRM_WRITE8(info->mmio_map, 0x3ce, save_3ce);
211
212         return (ret);
213 }
214
215 bool xgi_dvi_irq_handler(struct xgi_info * info)
216 {
217         bool ret = FALSE;
218         const u8 save_3ce = DRM_READ8(info->mmio_map, 0x3ce);
219
220         /* DVI interrupt just happened
221          */
222         if (IN3CFB(info->mmio_map, 0x38) & 0x20) {
223                 const u8 save_3x4 = DRM_READ8(info->mmio_map, 0x3d4);
224                 u8 op3cf_39;
225                 u8 op3cf_37;
226                 u8 op3x5_5a;
227
228                 /* What happened?
229                  */
230                 op3cf_37 = IN3CFB(info->mmio_map, 0x37);
231
232                 /* Notify BIOS that DVI plug/unplug happened
233                  */
234                 op3x5_5a = IN3X5B(info->mmio_map, 0x5a);
235                 OUT3X5B(info->mmio_map, 0x5a, op3x5_5a & 0xf7);
236
237                 DRM_WRITE8(info->mmio_map, 0x3d4, save_3x4);
238
239                 /* Clear DVI interrupt
240                  */
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));
244
245                 ret = TRUE;
246         }
247         DRM_WRITE8(info->mmio_map, 0x3ce, save_3ce);
248
249         return (ret);
250 }
251
252
253 static void dump_reg_header(unsigned regbase)
254 {
255         printk("\n=====xgi_dump_register========0x%x===============\n",
256                regbase);
257         printk("    0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f\n");
258 }
259
260
261 static void dump_indexed_reg(struct xgi_info * info, unsigned regbase)
262 {
263         unsigned i, j;
264         u8 temp;
265
266
267         dump_reg_header(regbase);
268         for (i = 0; i < 0x10; i++) {
269                 printk("%1x ", i);
270
271                 for (j = 0; j < 0x10; j++) {
272                         DRM_WRITE8(info->mmio_map, regbase - 1,
273                                    (i * 0x10) + j);
274                         temp = DRM_READ8(info->mmio_map, regbase);
275                         printk("%3x", temp);
276                 }
277                 printk("\n");
278         }
279 }
280
281
282 static void dump_reg(struct xgi_info * info, unsigned regbase, unsigned range)
283 {
284         unsigned i, j;
285
286
287         dump_reg_header(regbase);
288         for (i = 0; i < range; i++) {
289                 printk("%1x ", i);
290
291                 for (j = 0; j < 0x10; j++) {
292                         u8 temp = DRM_READ8(info->mmio_map,
293                                             regbase + (i * 0x10) + j);
294                         printk("%3x", temp);
295                 }
296                 printk("\n");
297         }
298 }
299
300
301 void xgi_dump_register(struct xgi_info * info)
302 {
303         dump_indexed_reg(info, 0x3c5);
304         dump_indexed_reg(info, 0x3d5);
305         dump_indexed_reg(info, 0x3cf);
306
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);
312 }
313
314
315 #define WHOLD_GE_STATUS             0x2800
316
317 /* Test everything except the "whole GE busy" bit, the "master engine busy"
318  * bit, and the reserved bits [26:21].
319  */
320 #define IDLE_MASK                   ~((1U<<31) | (1U<<28) | (0x3f<<21))
321
322 void xgi_waitfor_pci_idle(struct xgi_info * info)
323 {
324         unsigned int idleCount = 0;
325         u32 old_status = 0;
326         unsigned int same_count = 0;
327
328         while (idleCount < 5) {
329                 const u32 status = DRM_READ32(info->mmio_map, WHOLD_GE_STATUS)
330                         & IDLE_MASK;
331
332                 if (status == old_status) {
333                         same_count++;
334
335                         if ((same_count % 100) == 0) {
336                                 DRM_ERROR("GE status stuck at 0x%08x for %u iterations!\n",
337                                           old_status, same_count);
338                         }
339                 } else {
340                         old_status = status;
341                         same_count = 0;
342                 }
343
344                 if (status != 0) {
345                         msleep(1);
346                         idleCount = 0;
347                 } else {
348                         idleCount++;
349                 }
350         }
351 }
352
353
354 void xgi_enable_mmio(struct xgi_info * info)
355 {
356         u8 protect = 0;
357         u8 temp;
358
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);
363
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);
367
368         /* Enable MMIO */
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);
372
373         /* Protect registers */
374         OUT3C5B(info->mmio_map, 0x11, protect);
375 }
376
377
378 void xgi_disable_mmio(struct xgi_info * info)
379 {
380         u8 protect = 0;
381         u8 temp;
382
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);
387
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);
392
393         /* Protect registers */
394         OUT3C5B(info->mmio_map, 0x11, protect);
395 }
396
397
398 void xgi_enable_ge(struct xgi_info * info)
399 {
400         u8 bOld3cf2a;
401         int wait = 0;
402
403         OUT3C5B(info->mmio_map, 0x11, 0x92);
404
405         /* Save and close dynamic gating
406          */
407         bOld3cf2a = IN3CFB(info->mmio_map, XGI_MISC_CTRL);
408         OUT3CFB(info->mmio_map, XGI_MISC_CTRL, bOld3cf2a & ~EN_GEPWM);
409
410         /* Enable 2D and 3D GE
411          */
412         OUT3X5B(info->mmio_map, XGI_GE_CNTL, (GE_ENABLE | GE_ENABLE_3D));
413         wait = 10;
414         while (wait--) {
415                 DRM_READ8(info->mmio_map, 0x36);
416         }
417
418         /* Reset both 3D and 2D engine
419          */
420         OUT3X5B(info->mmio_map, XGI_GE_CNTL,
421                 (GE_ENABLE | GE_RESET | GE_ENABLE_3D));
422         wait = 10;
423         while (wait--) {
424                 DRM_READ8(info->mmio_map, 0x36);
425         }
426
427         OUT3X5B(info->mmio_map, XGI_GE_CNTL, (GE_ENABLE | GE_ENABLE_3D));
428         wait = 10;
429         while (wait--) {
430                 DRM_READ8(info->mmio_map, 0x36);
431         }
432
433         /* Enable 2D engine only
434          */
435         OUT3X5B(info->mmio_map, XGI_GE_CNTL, GE_ENABLE);
436
437         /* Enable 2D+3D engine
438          */
439         OUT3X5B(info->mmio_map, XGI_GE_CNTL, (GE_ENABLE | GE_ENABLE_3D));
440
441         /* Restore dynamic gating
442          */
443         OUT3CFB(info->mmio_map, XGI_MISC_CTRL, bOld3cf2a);
444 }
445
446
447 void xgi_disable_ge(struct xgi_info * info)
448 {
449         int wait = 0;
450
451         OUT3X5B(info->mmio_map, XGI_GE_CNTL, (GE_ENABLE | GE_ENABLE_3D));
452
453         wait = 10;
454         while (wait--) {
455                 DRM_READ8(info->mmio_map, 0x36);
456         }
457
458         /* Reset both 3D and 2D engine
459          */
460         OUT3X5B(info->mmio_map, XGI_GE_CNTL,
461                 (GE_ENABLE | GE_RESET | GE_ENABLE_3D));
462
463         wait = 10;
464         while (wait--) {
465                 DRM_READ8(info->mmio_map, 0x36);
466         }
467         OUT3X5B(info->mmio_map, XGI_GE_CNTL, (GE_ENABLE | GE_ENABLE_3D));
468
469         wait = 10;
470         while (wait--) {
471                 DRM_READ8(info->mmio_map, 0x36);
472         }
473
474         /* Disable 2D engine and 3D engine.
475          */
476         OUT3X5B(info->mmio_map, XGI_GE_CNTL, 0);
477 }