1 /*
2 (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
3 (c) Copyright 2000-2004 Convergence (integrated media) GmbH
4
5 All rights reserved.
6
7 Written by Denis Oliver Kropp <dok@directfb.org>,
8 Andreas Hundt <andi@fischlustig.de>,
9 Sven Neumann <neo@directfb.org>,
10 Ville Syrjälä <syrjala@sci.fi> and
11 Claudio Ciccani <klan@users.sf.net>.
12
13 This library is free software; you can redistribute it and/or
14 modify it under the terms of the GNU Lesser General Public
15 License as published by the Free Software Foundation; either
16 version 2 of the License, or (at your option) any later version.
17
18 This library is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 Lesser General Public License for more details.
22
23 You should have received a copy of the GNU Lesser General Public
24 License along with this library; if not, write to the
25 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
26 Boston, MA 02111-1307, USA.
27 */
28
29
30 #ifndef ___ATI128_MMIO_H__
31 #define ___ATI128_MMIO_H__
32
33 #include <dfb_types.h>
34
35 #include "ati128.h"
36
37 static inline void
ati128_out32(volatile u8 * mmioaddr,u32 reg,u32 value)38 ati128_out32(volatile u8 *mmioaddr, u32 reg, u32 value)
39 {
40 #ifdef __powerpc__
41 asm volatile("stwbrx %0,%1,%2;eieio" : : "r"(value), "b"(reg),
42 "r"(mmioaddr) : "memory");
43
44 #else
45 *((volatile u32*)(mmioaddr+reg)) = value;
46 #endif
47 }
48
49 static inline u32
ati128_in32(volatile u8 * mmioaddr,u32 reg)50 ati128_in32(volatile u8 *mmioaddr, u32 reg)
51 {
52 #ifdef __powerpc__
53 u32 value;
54
55 asm volatile("lwbrx %0,%1,%2;eieio" : "=r"(value) : "b"(reg), "r"(mmioaddr));
56
57 return value;
58 #else
59 return *((volatile u32*)(mmioaddr+reg));
60 #endif
61 }
62
ati128_waitidle(ATI128DriverData * adrv,ATI128DeviceData * adev)63 static inline void ati128_waitidle( ATI128DriverData *adrv,
64 ATI128DeviceData *adev )
65 {
66 int timeout = 1000000;
67
68 while (timeout--) {
69 if ((ati128_in32( adrv->mmio_base, GUI_STAT) & 0x00000FFF) == 64)
70 break;
71
72 adev->idle_waitcycles++;
73 }
74
75 timeout = 1000000;
76
77 while (timeout--) {
78 if ((ati128_in32( adrv->mmio_base, GUI_STAT) & (GUI_ACTIVE | ENG_3D_BUSY)) == ENGINE_IDLE)
79 break;
80
81 adev->idle_waitcycles++;
82 }
83
84 ati128_out32( adrv->mmio_base, PC_NGUI_CTLSTAT,
85 ati128_in32( adrv->mmio_base, PC_NGUI_CTLSTAT) | 0x000000ff);
86
87 timeout = 1000000;
88 while (timeout--) {
89 if ((ati128_in32( adrv->mmio_base, PC_NGUI_CTLSTAT) & PC_BUSY) != PC_BUSY)
90 break;
91
92 adev->idle_waitcycles++;
93 }
94 adev->fifo_space = 60;
95 }
96
ati128_waitfifo(ATI128DriverData * adrv,ATI128DeviceData * adev,unsigned int requested_fifo_space)97 static inline void ati128_waitfifo( ATI128DriverData *adrv,
98 ATI128DeviceData *adev,
99 unsigned int requested_fifo_space)
100 {
101 int timeout = 1000000;
102
103 adev->waitfifo_sum += requested_fifo_space;
104 adev->waitfifo_calls++;
105
106 if (adev->fifo_space < requested_fifo_space) {
107 while (timeout--) {
108 adev->fifo_waitcycles++;
109
110 adev->fifo_space = ati128_in32( adrv->mmio_base, GUI_STAT) & 0x00000FFF;
111 if (adev->fifo_space >= requested_fifo_space)
112 break;
113 }
114 }
115 else {
116 adev->fifo_cache_hits++;
117 }
118 adev->fifo_space -= requested_fifo_space;
119 }
120
121 #endif
122