1
/* Copyright (c) 2005 Advanced Micro Devices, Inc.
3
* Permission is hereby granted, free of charge, to any person obtaining a copy
4
* of this software and associated documentation files (the "Software"), to
5
* deal in the Software without restriction, including without limitation the
6
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7
* sell copies of the Software, and to permit persons to whom the Software is
8
* furnished to do so, subject to the following conditions:
10
* The above copyright notice and this permission notice shall be included in
11
* all copies or substantial portions of the Software.
13
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21
* Neither the name of the Advanced Micro Devices, Inc. nor the names of its
22
* contributors may be used to endorse or promote products derived from this
23
* software without specific prior written permission.
27
* This header file contains the macros used to access the hardware. These
28
* macros assume that 32-bit access is possible, which is true for most
29
* applications. Projects using 16-bit compilers (the Windows98 display
30
* driver) and special purpose applications (such as Darwin) need to define
31
* their own versions of these macros, which typically call a subroutine.
34
/* ACCESS TO THE CPU REGISTERS */
36
#define WRITE_REG8(offset, value) \
37
(*(volatile unsigned char *)(gfx_virt_regptr + (offset))) = (value)
39
#define WRITE_REG16(offset, value) \
40
(*(volatile unsigned short *)(gfx_virt_regptr + (offset))) = (value)
42
#define WRITE_REG32(offset, value) \
43
(*(volatile unsigned long *)(gfx_virt_regptr + (offset))) = (value)
45
#define READ_REG16(offset) \
46
(*(volatile unsigned short *)(gfx_virt_regptr + (offset)))
48
#define READ_REG32(offset) \
49
(*(volatile unsigned long *)(gfx_virt_regptr + (offset)))
51
/* ACCESS TO THE ACCELERATOR REGISTERS (REDCLOUD ONLY) */
53
#define WRITE_GP8(offset, value) \
54
(*(volatile unsigned char *)(gfx_virt_gpptr + (offset))) = (value)
56
#define WRITE_GP16(offset, value) \
57
(*(volatile unsigned short *)(gfx_virt_gpptr + (offset))) = (value)
59
#define WRITE_GP32(offset, value) \
60
(*(volatile unsigned long *)(gfx_virt_gpptr + (offset))) = (value)
62
#define READ_GP16(offset) \
63
(*(volatile unsigned short *)(gfx_virt_gpptr + (offset)))
65
#define READ_GP32(offset) \
66
(*(volatile unsigned long *)(gfx_virt_gpptr + (offset)))
68
/* ACCESS TO THE FRAME BUFFER */
70
#define WRITE_FB32(offset, value) \
71
(*(volatile unsigned long *)(gfx_virt_fbptr + (offset))) = (value)
73
#define WRITE_FB16(offset, value) \
74
(*(volatile unsigned short *)(gfx_virt_fbptr + (offset))) = (value)
76
#define WRITE_FB8(offset, value) \
77
(*(volatile unsigned char *)(gfx_virt_fbptr + (offset))) = (value)
79
/* ACCESS TO THE VIDEO HARDWARE */
81
#define READ_VID32(offset) \
82
(*(volatile unsigned long *)(gfx_virt_vidptr + (offset)))
84
#define WRITE_VID32(offset, value) \
85
(*(volatile unsigned long *)(gfx_virt_vidptr + (offset))) = (value)
87
/* ACCESS TO THE VIP HARDWARE */
89
#define READ_VIP32(offset) \
90
(*(volatile unsigned long *)(gfx_virt_vipptr + (offset)))
92
#define WRITE_VIP32(offset, value) \
93
(*(volatile unsigned long *)(gfx_virt_vipptr + (offset))) = (value)
95
/* ACCESS TO THE SCRATCHPAD RAM */
97
#define WRITE_SCRATCH32(offset, value) \
98
(*(volatile unsigned long *)(gfx_virt_spptr + (offset))) = (value)
100
#define WRITE_SCRATCH16(offset, value) \
101
(*(volatile unsigned short *)(gfx_virt_spptr + (offset))) = (value)
103
#define WRITE_SCRATCH8(offset, value) \
104
(*(volatile unsigned char *)(gfx_virt_spptr + (offset))) = (value)
106
#define READ_SCRATCH16(offset) \
107
(*(volatile unsigned short *)(gfx_virt_spptr + (offset)))
109
#define READ_SCRATCH32(offset) \
110
(*(volatile unsigned long *)(gfx_virt_spptr + (offset)))
114
void gfx_msr_asm_write(unsigned short msrReg, unsigned long msrAddr,
115
unsigned long *ptrHigh, unsigned long *ptrLow);
116
void gfx_msr_asm_read(unsigned short msrReg, unsigned long msrAddr,
117
unsigned long *ptrHigh, unsigned long *ptrLow);
119
#define MSR_READ( MBD_MSR_CAP, address, valueHigh_ptr, valueLow_ptr ) \
120
gfx_msr_asm_read( ((unsigned short)(MBD_MSR_CAP)), address, \
121
valueHigh_ptr, valueLow_ptr )
123
#define MSR_WRITE( MBD_MSR_CAP, address, valueHigh_ptr, valueLow_ptr ) \
124
gfx_msr_asm_write( ((unsigned short)(MBD_MSR_CAP)), address, \
125
valueHigh_ptr, valueLow_ptr )
127
/* OPTIMIZATION MACROS */
128
/* The following macros have been added to allow more complete optimization of
129
* the bitmap-to-screen routines in Durango. These routines also allow
130
* Durango to run properly within a 16-bit environment.
133
/*****************************************************************************
134
* Macro: SET_SCRATCH_BASE
135
* Purpose: Record the base address of the BLT buffers. The
136
* WRITE_SCRATCH_STRINGxx macros assume that this address is used
137
* as the base for all writes.
140
* scratch_base - offset into the GX base for the first BLT buffer byte.
141
****************************************************************************/
143
#define SET_SCRATCH_BASE(scratch_base) \
144
{ gfx_gx1_scratch_base = (unsigned long)gfx_virt_spptr + scratch_base; }
146
#ifdef GFX_OPTIMIZE_ASSEMBLY
148
/*****************************************************************************
149
* Macro: WRITE_SCRATCH_STRING
150
* Purpose: Write multiple bytes to the scratchpad buffer
153
* dword_bytes - number of bytes to transfer. This number will always.
154
* be a multiple of 4. It cannot be modified within the
155
* macro (ex. bytes -= 4)
156
* bytes_extra - number of non-DWORD aligned bytes
157
* array - pointer to an array of unsigned characters.
158
* array_offset - offset into the array from which to pull the first
160
****************************************************************************/
162
#define WRITE_SCRATCH_STRING(dwords, bytes, array, array_offset) \
164
_asm { mov edi, gfx_gx1_scratch_base } \
165
_asm { mov esi, array } \
166
_asm { add esi, array_offset } \
167
_asm { mov ecx, dwords } \
168
_asm { shr ecx, 2 } \
170
_asm { mov ecx, bytes } \
174
/*****************************************************************************
175
* Macro: WRITE_FRAME_BUFFER_STRING32
176
* Purpose: Write multiple dwords to the Frame buffer
179
* fboffset - offset to the beginning frame buffer location.
180
* bytes - number of bytes to transfer. This number will always.
181
* be a multiple of 4. It cannot be modified within the
182
* macro (ex. bytes -= 4)
183
* array - pointer to an array of unsigned characters.
184
* array_offset - offset into the array from which to pull the first
186
****************************************************************************/
188
#define WRITE_FRAME_BUFFER_STRING32(fboffset, bytes, array, array_offset) \
190
_asm { mov ecx, bytes } \
191
_asm { shr ecx, 2 } \
193
_asm { mov edi, gfx_virt_fbptr } \
194
_asm { add edi, fboffset } \
195
_asm { mov esi, array } \
196
_asm { add esi, array_offset } \
202
/*****************************************************************************
203
* Macro: WRITE_SCRATCH_STRING
204
* Purpose: Write multiple bytes to the scratchpad buffer
207
* dword_bytes - number of bytes to transfer. This number will always.
208
* be a multiple of 4. It cannot be modified within the
209
* macro (ex. bytes -= 4)
210
* bytes_extra - number of non-DWORD aligned bytes
211
* array - pointer to an array of unsigned characters.
212
* array_offset - offset into the array from which to pull the first
214
****************************************************************************/
216
#define WRITE_SCRATCH_STRING(dword_bytes, bytes_extra, array, array_offset) \
218
unsigned long i, j; \
219
unsigned long aroffset = (unsigned long)array + (array_offset); \
223
for (i = 0; i < dword_bytes; i += 4) \
224
*((volatile unsigned long *)(gfx_gx1_scratch_base + i)) = \
225
*((unsigned long *)(aroffset + i)); \
229
j = i + bytes_extra; \
231
*((volatile unsigned char *)(gfx_gx1_scratch_base + i)) = \
232
*((unsigned char *)(aroffset + i)); \
237
/*****************************************************************************
238
* Macro: WRITE_FRAME_BUFFER_STRING32
239
* Purpose: Write multiple dwords to the Frame buffer
242
* fboffset - offset to the beginning frame buffer location.
243
* bytes - number of bytes to transfer. This number will always.
244
* be a multiple of 4. It cannot be modified within the
245
* macro (ex. bytes -= 4)
246
* array - pointer to an array of unsigned characters.
247
* array_offset - offset into the array from which to pull the first
249
****************************************************************************/
251
#define WRITE_FRAME_BUFFER_STRING32(fboffset, bytes, array, array_offset) \
254
unsigned long aroffset = (unsigned long)array + (array_offset); \
255
for (i = 0; i < bytes; i += 4) \
256
WRITE_FB32 ((fboffset) + i, *((unsigned long *)(aroffset + i))); \
261
/*****************************************************************************
262
* Macro: WRITE_FRAME_BUFFER_STRING8
263
* Purpose: Write multiple bytes to the frame buffer
266
* spoffset - offset to the beginning frame buffer location.
267
* bytes - number of bytes to transfer. This number cannot be
268
* modified within the macro (ex. bytes -= 4)
269
* array - pointer to an array of unsigned characters.
270
* array_offset - offset into the array from which to pull the first
272
****************************************************************************/
274
#define WRITE_FRAME_BUFFER_STRING8(fboffset, bytes, array, array_offset) \
277
unsigned long aroffset = (unsigned long)array + (array_offset); \
278
for (i = 0; i < bytes; i++) \
279
WRITE_FB8 ((fboffset) + i, *((unsigned char *)(aroffset + i))); \
282
/*****************************************************************************
283
* Macro: WRITE_GPREG_STRING32
284
* Purpose: Write multiple dwords to one GP register.
287
* regoffset - Offset of the GP register to be written.
288
* dwords - number of dwords to transfer. It cannot be modified
289
* within the macro (ex. dwords--)
290
* counter - name of a counter variable that can be used in a loop.
291
* This is used to optimize macros written in C.
292
* array - pointer to an array of unsigned characters.
293
* array_offset - offset into the array from which to pull the first
295
* temp - name of a temporary variable that can be used for
297
* This argument is also used for C-only macros.
298
****************************************************************************/
300
#define WRITE_GPREG_STRING32(regoffset, dwords, counter, array, \
301
array_offset, temp) \
303
temp = (unsigned long)array + (array_offset); \
304
for (counter = 0; counter < dwords; counter++) \
305
WRITE_GP32 (regoffset, *((unsigned long *)temp + counter)); \
308
/*****************************************************************************
309
* Macro: WRITE_GPREG_STRING8
310
* Purpose: Write 4 or less bytes to one GP register.
313
* regoffset - Offset of the GP register to be written.
314
* bytes - number of bytes to transfer. This number will always.
315
* be less than 4. It cannot be modified within the
316
* macro (ex. bytes--)
317
* shift - name of a shift variable that can be used as a shift
319
* This variable holds the initial shift value into the
321
* counter - name of a counter variable that can be used in a loop.
322
* This is used to optimize macros written in C.
323
* array - pointer to an array of unsigned characters.
324
* array_offset - offset into the array from which to pull the first
326
* temp1 - name of a temporary variable that can be used for
328
* This argument is also used for C-only macros.
329
* temp2 - name of a temporary variable that can be used for
331
* This argument is also used for C-only macros.
332
****************************************************************************/
333
#define WRITE_GPREG_STRING8(regoffset, bytes, shift, counter, array, \
334
array_offset, temp1, temp2) \
337
temp1 = (unsigned long)array + (array_offset); \
339
for (counter = 0; counter < bytes; counter++) { \
340
temp2 |= ((unsigned long)(*((unsigned char *)(temp1 + \
341
counter)))) << shift; \
344
WRITE_GP32 (regoffset, temp2); \