1f29dbc25Smrg/* Copyright (c) 2005 Advanced Micro Devices, Inc.
2f29dbc25Smrg *
3f29dbc25Smrg * Permission is hereby granted, free of charge, to any person obtaining a copy
4f29dbc25Smrg * of this software and associated documentation files (the "Software"), to
5f29dbc25Smrg * deal in the Software without restriction, including without limitation the
6f29dbc25Smrg * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7f29dbc25Smrg * sell copies of the Software, and to permit persons to whom the Software is
8f29dbc25Smrg * furnished to do so, subject to the following conditions:
9f29dbc25Smrg *
10f29dbc25Smrg * The above copyright notice and this permission notice shall be included in
11f29dbc25Smrg * all copies or substantial portions of the Software.
12f29dbc25Smrg *
13f29dbc25Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14f29dbc25Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15f29dbc25Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16f29dbc25Smrg * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17f29dbc25Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18f29dbc25Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
19f29dbc25Smrg * IN THE SOFTWARE.
20f29dbc25Smrg *
21f29dbc25Smrg * Neither the name of the Advanced Micro Devices, Inc. nor the names of its
22f29dbc25Smrg * contributors may be used to endorse or promote products derived from this
23f29dbc25Smrg * software without specific prior written permission.
24f29dbc25Smrg * */
25f29dbc25Smrg
26f29dbc25Smrg/*
27f29dbc25Smrg * This header file contains the macros used to access the hardware.  These
28f29dbc25Smrg * macros assume that 32-bit access is possible, which is true for most
29f29dbc25Smrg * applications.  Projects using 16-bit compilers (the Windows98 display
30f29dbc25Smrg * driver) and special purpose applications (such as Darwin) need to define
31f29dbc25Smrg * their own versions of these macros, which typically call a subroutine.
32f29dbc25Smrg * */
33f29dbc25Smrg
34f29dbc25Smrg/* ACCESS TO THE CPU REGISTERS */
35f29dbc25Smrg
36f29dbc25Smrg#define WRITE_REG8(offset, value) 			\
37f29dbc25Smrg	(*(volatile unsigned char *)(gfx_virt_regptr + (offset))) = (value)
38f29dbc25Smrg
39f29dbc25Smrg#define WRITE_REG16(offset, value) 			\
40f29dbc25Smrg	(*(volatile unsigned short *)(gfx_virt_regptr + (offset))) = (value)
41f29dbc25Smrg
42f29dbc25Smrg#define WRITE_REG32(offset, value) 			\
43f29dbc25Smrg	(*(volatile unsigned long *)(gfx_virt_regptr + (offset))) = (value)
44f29dbc25Smrg
45f29dbc25Smrg#define READ_REG16(offset) 					\
46f29dbc25Smrg    (*(volatile unsigned short *)(gfx_virt_regptr + (offset)))
47f29dbc25Smrg
48f29dbc25Smrg#define READ_REG32(offset) 					\
49f29dbc25Smrg    (*(volatile unsigned long *)(gfx_virt_regptr + (offset)))
50f29dbc25Smrg
51f29dbc25Smrg/* ACCESS TO THE ACCELERATOR REGISTERS (REDCLOUD ONLY) */
52f29dbc25Smrg
53f29dbc25Smrg#define WRITE_GP8(offset, value) 			\
54f29dbc25Smrg	(*(volatile unsigned char *)(gfx_virt_gpptr + (offset))) = (value)
55f29dbc25Smrg
56f29dbc25Smrg#define WRITE_GP16(offset, value) 			\
57f29dbc25Smrg	(*(volatile unsigned short *)(gfx_virt_gpptr + (offset))) = (value)
58f29dbc25Smrg
59f29dbc25Smrg#define WRITE_GP32(offset, value) 			\
60f29dbc25Smrg	(*(volatile unsigned long *)(gfx_virt_gpptr + (offset))) = (value)
61f29dbc25Smrg
62f29dbc25Smrg#define READ_GP16(offset) 					\
63f29dbc25Smrg    (*(volatile unsigned short *)(gfx_virt_gpptr + (offset)))
64f29dbc25Smrg
65f29dbc25Smrg#define READ_GP32(offset) 					\
66f29dbc25Smrg    (*(volatile unsigned long *)(gfx_virt_gpptr + (offset)))
67f29dbc25Smrg
68f29dbc25Smrg/* ACCESS TO THE FRAME BUFFER */
69f29dbc25Smrg
70f29dbc25Smrg#define WRITE_FB32(offset, value) 			\
71f29dbc25Smrg	(*(volatile unsigned long *)(gfx_virt_fbptr + (offset))) = (value)
72f29dbc25Smrg
73f29dbc25Smrg#define WRITE_FB16(offset, value) 			\
74f29dbc25Smrg	(*(volatile unsigned short *)(gfx_virt_fbptr + (offset))) = (value)
75f29dbc25Smrg
76f29dbc25Smrg#define WRITE_FB8(offset, value) 			\
77f29dbc25Smrg	(*(volatile unsigned char *)(gfx_virt_fbptr + (offset))) = (value)
78f29dbc25Smrg
79f29dbc25Smrg/* ACCESS TO THE VIDEO HARDWARE */
80f29dbc25Smrg
81f29dbc25Smrg#define READ_VID32(offset) 					\
82f29dbc25Smrg	(*(volatile unsigned long *)(gfx_virt_vidptr + (offset)))
83f29dbc25Smrg
84f29dbc25Smrg#define WRITE_VID32(offset, value) 			\
85f29dbc25Smrg	(*(volatile unsigned long *)(gfx_virt_vidptr + (offset))) = (value)
86f29dbc25Smrg
87f29dbc25Smrg/* ACCESS TO THE VIP HARDWARE */
88f29dbc25Smrg
89f29dbc25Smrg#define READ_VIP32(offset) 					\
90f29dbc25Smrg	(*(volatile unsigned long *)(gfx_virt_vipptr + (offset)))
91f29dbc25Smrg
92f29dbc25Smrg#define WRITE_VIP32(offset, value)			\
93f29dbc25Smrg	(*(volatile unsigned long *)(gfx_virt_vipptr + (offset))) = (value)
94f29dbc25Smrg
95f29dbc25Smrg/* ACCESS TO THE SCRATCHPAD RAM */
96f29dbc25Smrg
97f29dbc25Smrg#define WRITE_SCRATCH32(offset, value)		\
98f29dbc25Smrg	(*(volatile unsigned long *)(gfx_virt_spptr + (offset))) = (value)
99f29dbc25Smrg
100f29dbc25Smrg#define WRITE_SCRATCH16(offset, value) 		\
101f29dbc25Smrg	(*(volatile unsigned short *)(gfx_virt_spptr + (offset))) = (value)
102f29dbc25Smrg
103f29dbc25Smrg#define WRITE_SCRATCH8(offset, value) 		\
104f29dbc25Smrg	(*(volatile unsigned char *)(gfx_virt_spptr + (offset))) = (value)
105f29dbc25Smrg
106f29dbc25Smrg#define READ_SCRATCH16(offset) 				\
107f29dbc25Smrg    (*(volatile unsigned short *)(gfx_virt_spptr + (offset)))
108f29dbc25Smrg
109f29dbc25Smrg#define READ_SCRATCH32(offset) \
110f29dbc25Smrg    (*(volatile unsigned long *)(gfx_virt_spptr + (offset)))
111f29dbc25Smrg
112f29dbc25Smrg/* ACCESS TO MSRS */
113f29dbc25Smrg
114f29dbc25Smrgvoid gfx_msr_asm_write(unsigned short msrReg, unsigned long msrAddr,
11504007ebaSmrg                       unsigned long *ptrHigh, unsigned long *ptrLow);
116f29dbc25Smrgvoid gfx_msr_asm_read(unsigned short msrReg, unsigned long msrAddr,
11704007ebaSmrg                      unsigned long *ptrHigh, unsigned long *ptrLow);
118f29dbc25Smrg
119f29dbc25Smrg#define MSR_READ( MBD_MSR_CAP, address, valueHigh_ptr, valueLow_ptr ) 	\
120f29dbc25Smrg	gfx_msr_asm_read( ((unsigned short)(MBD_MSR_CAP)), address, 		\
121f29dbc25Smrg					valueHigh_ptr, valueLow_ptr )
122f29dbc25Smrg
123f29dbc25Smrg#define MSR_WRITE( MBD_MSR_CAP, address, valueHigh_ptr, valueLow_ptr ) 	\
124f29dbc25Smrg	gfx_msr_asm_write( ((unsigned short)(MBD_MSR_CAP)), address, 		\
125f29dbc25Smrg					valueHigh_ptr, valueLow_ptr )
126f29dbc25Smrg
127f29dbc25Smrg/* OPTIMIZATION MACROS */
128f29dbc25Smrg/* The following macros have been added to allow more complete optimization of
129f29dbc25Smrg * the bitmap-to-screen routines in Durango.  These routines also allow
130f29dbc25Smrg * Durango to run properly within a 16-bit environment.
131f29dbc25Smrg * */
132f29dbc25Smrg
133f29dbc25Smrg/*****************************************************************************
134f29dbc25Smrg * Macro:	SET_SCRATCH_BASE
135f29dbc25Smrg * Purpose: Record the base address of the BLT buffers. The
136f29dbc25Smrg * 			WRITE_SCRATCH_STRINGxx macros assume that this address is used
137f29dbc25Smrg * 			as the base for all writes.
138f29dbc25Smrg *
139f29dbc25Smrg * Arguments:
140f29dbc25Smrg *    scratch_base -   offset into the GX base for the first BLT buffer byte.
141f29dbc25Smrg ****************************************************************************/
142f29dbc25Smrg
143f29dbc25Smrg#define SET_SCRATCH_BASE(scratch_base) \
144f29dbc25Smrg	{ gfx_gx1_scratch_base = (unsigned long)gfx_virt_spptr + scratch_base; }
145f29dbc25Smrg
146f29dbc25Smrg#ifdef GFX_OPTIMIZE_ASSEMBLY
147f29dbc25Smrg
148f29dbc25Smrg/*****************************************************************************
149f29dbc25Smrg * Macro:   WRITE_SCRATCH_STRING
150f29dbc25Smrg * Purpose: Write multiple bytes to the scratchpad buffer
151f29dbc25Smrg *
152f29dbc25Smrg * Arguments:
153f29dbc25Smrg *    dword_bytes  -   	number of bytes to transfer.  This number will always.
154f29dbc25Smrg *                     	be a multiple of 4.  It cannot be modified within the
155f29dbc25Smrg *                     	macro (ex. bytes -= 4)
156f29dbc25Smrg *    bytes_extra  -   	number of non-DWORD aligned bytes
157f29dbc25Smrg *    array        -   	pointer to an array of unsigned characters.
158f29dbc25Smrg *    array_offset -   	offset into the array from which to pull the first
159f29dbc25Smrg *    					character.
160f29dbc25Smrg ****************************************************************************/
161f29dbc25Smrg
162f29dbc25Smrg#define WRITE_SCRATCH_STRING(dwords, bytes, array, array_offset)	\
163f29dbc25Smrg{                                                                   \
164f29dbc25Smrg	_asm { mov edi, gfx_gx1_scratch_base }                          \
165f29dbc25Smrg	_asm { mov esi, array }                                         \
166f29dbc25Smrg	_asm { add esi, array_offset }                                  \
167f29dbc25Smrg	_asm { mov ecx, dwords }                                        \
168f29dbc25Smrg	_asm { shr ecx, 2 }                                             \
169f29dbc25Smrg	_asm { rep movsd }                                              \
170f29dbc25Smrg	_asm { mov ecx, bytes }                                         \
171f29dbc25Smrg	_asm { rep movsb }                                              \
172f29dbc25Smrg}
173f29dbc25Smrg
174f29dbc25Smrg/*****************************************************************************
175f29dbc25Smrg * Macro:   WRITE_FRAME_BUFFER_STRING32
176f29dbc25Smrg * Purpose: Write multiple dwords to the Frame buffer
177f29dbc25Smrg *
178f29dbc25Smrg * Arguments:
179f29dbc25Smrg *    fboffset     -   	offset to the beginning frame buffer location.
180f29dbc25Smrg *    bytes        -   	number of bytes to transfer.  This number will always.
181f29dbc25Smrg *                     	be a multiple of 4.  It cannot be modified within the
182f29dbc25Smrg *                     	macro (ex. bytes -= 4)
183f29dbc25Smrg *    array        -   	pointer to an array of unsigned characters.
184f29dbc25Smrg *    array_offset -   	offset into the array from which to pull the first
185f29dbc25Smrg *    					character.
186f29dbc25Smrg ****************************************************************************/
187f29dbc25Smrg
188f29dbc25Smrg#define WRITE_FRAME_BUFFER_STRING32(fboffset, bytes, array, array_offset)	\
189f29dbc25Smrg{                                                                           \
190f29dbc25Smrg	_asm { mov ecx, bytes }                                                 \
191f29dbc25Smrg	_asm { shr ecx, 2 }                                                     \
192f29dbc25Smrg	_asm { cld }                                                            \
193f29dbc25Smrg	_asm { mov edi, gfx_virt_fbptr }                                        \
194f29dbc25Smrg	_asm { add edi, fboffset }                                              \
195f29dbc25Smrg	_asm { mov esi, array }                                                 \
196f29dbc25Smrg	_asm { add esi, array_offset }                                          \
197f29dbc25Smrg    _asm { rep movsd }                                                      \
198f29dbc25Smrg}
199f29dbc25Smrg
200f29dbc25Smrg#else
201f29dbc25Smrg
202f29dbc25Smrg/*****************************************************************************
203f29dbc25Smrg * Macro:   WRITE_SCRATCH_STRING
204f29dbc25Smrg * Purpose: Write multiple bytes to the scratchpad buffer
205f29dbc25Smrg *
206f29dbc25Smrg * Arguments:
207f29dbc25Smrg *    dword_bytes  -   	number of bytes to transfer.  This number will always.
208f29dbc25Smrg *                     	be a multiple of 4.  It cannot be modified within the
209f29dbc25Smrg *                     	macro (ex. bytes -= 4)
210f29dbc25Smrg *    bytes_extra  -   	number of non-DWORD aligned bytes
211f29dbc25Smrg *    array        -   	pointer to an array of unsigned characters.
212f29dbc25Smrg *    array_offset -   	offset into the array from which to pull the first
213f29dbc25Smrg *    					character.
214f29dbc25Smrg ****************************************************************************/
215f29dbc25Smrg
216f29dbc25Smrg#define WRITE_SCRATCH_STRING(dword_bytes, bytes_extra, array, array_offset)	\
217f29dbc25Smrg{                                                                           \
218f29dbc25Smrg	unsigned long i, j;                                                     \
219f29dbc25Smrg	unsigned long aroffset = (unsigned long)array + (array_offset);         \
220f29dbc25Smrg	                                                                        \
221f29dbc25Smrg	/* WRITE DWORDS */                                                      \
222f29dbc25Smrg	                                                                        \
223f29dbc25Smrg	for (i = 0; i < dword_bytes; i += 4)                                    \
224f29dbc25Smrg		*((volatile unsigned long *)(gfx_gx1_scratch_base + i)) = 			\
225f29dbc25Smrg			*((unsigned long *)(aroffset + i));								\
226f29dbc25Smrg	                                                                        \
227f29dbc25Smrg	/* WRITE BYTES */                                                       \
228f29dbc25Smrg	                                                                        \
229f29dbc25Smrg	j = i + bytes_extra;	                                                \
230f29dbc25Smrg	while (i < j) {	                                                        \
231f29dbc25Smrg		*((volatile unsigned char *)(gfx_gx1_scratch_base + i)) = 			\
232f29dbc25Smrg			*((unsigned char *)(aroffset + i));								\
233f29dbc25Smrg		i++;	                                                            \
234f29dbc25Smrg	}	                                                                    \
235f29dbc25Smrg}
236f29dbc25Smrg
237f29dbc25Smrg/*****************************************************************************
238f29dbc25Smrg * Macro:   WRITE_FRAME_BUFFER_STRING32
239f29dbc25Smrg * Purpose: Write multiple dwords to the Frame buffer
240f29dbc25Smrg *
241f29dbc25Smrg * Arguments:
242f29dbc25Smrg *    fboffset     -   	offset to the beginning frame buffer location.
243f29dbc25Smrg *    bytes        -   	number of bytes to transfer.  This number will always.
244f29dbc25Smrg *                     	be a multiple of 4.  It cannot be modified within the
245f29dbc25Smrg *                     	macro (ex. bytes -= 4)
246f29dbc25Smrg *    array        -   	pointer to an array of unsigned characters.
247f29dbc25Smrg *    array_offset -   	offset into the array from which to pull the first
248f29dbc25Smrg *    					character.
249f29dbc25Smrg ****************************************************************************/
250f29dbc25Smrg
251f29dbc25Smrg#define WRITE_FRAME_BUFFER_STRING32(fboffset, bytes, array, array_offset)	\
252f29dbc25Smrg{                                                                           \
253f29dbc25Smrg	unsigned long i;                                                        \
254f29dbc25Smrg	unsigned long aroffset = (unsigned long)array + (array_offset);         \
255f29dbc25Smrg	for (i = 0; i < bytes; i += 4)                                          \
256f29dbc25Smrg		WRITE_FB32 ((fboffset) + i, *((unsigned long *)(aroffset + i)));    \
257f29dbc25Smrg}
258f29dbc25Smrg
259f29dbc25Smrg#endif
260f29dbc25Smrg
261f29dbc25Smrg/*****************************************************************************
262f29dbc25Smrg * Macro:   WRITE_FRAME_BUFFER_STRING8
263f29dbc25Smrg * Purpose: Write multiple bytes to the frame buffer
264f29dbc25Smrg *
265f29dbc25Smrg * Arguments:
266f29dbc25Smrg *    spoffset     -   	offset to the beginning frame buffer location.
267f29dbc25Smrg *    bytes        -   	number of bytes to transfer.  This number cannot be
268f29dbc25Smrg *    					modified within the macro (ex. bytes -= 4)
269f29dbc25Smrg *    array        -  	pointer to an array of unsigned characters.
270f29dbc25Smrg *    array_offset -   	offset into the array from which to pull the first
271f29dbc25Smrg *    					character.
272f29dbc25Smrg ****************************************************************************/
273f29dbc25Smrg
274f29dbc25Smrg#define WRITE_FRAME_BUFFER_STRING8(fboffset, bytes, array, array_offset)	\
275f29dbc25Smrg{                                                                           \
276f29dbc25Smrg	unsigned long i;                                                        \
277f29dbc25Smrg	unsigned long aroffset = (unsigned long)array + (array_offset);         \
278f29dbc25Smrg	for (i = 0; i < bytes; i++)                                             \
279f29dbc25Smrg		WRITE_FB8 ((fboffset) + i, *((unsigned char *)(aroffset + i)));     \
280f29dbc25Smrg}
281f29dbc25Smrg
282f29dbc25Smrg/*****************************************************************************
283f29dbc25Smrg * Macro:   WRITE_GPREG_STRING32
284f29dbc25Smrg * Purpose: Write multiple dwords to one GP register.
285f29dbc25Smrg *
286f29dbc25Smrg * Arguments:
287f29dbc25Smrg *    regoffset    -   	Offset of the GP register to be written.
288f29dbc25Smrg *    dwords       -   	number of dwords to transfer.  It cannot be modified
289f29dbc25Smrg *    					within the macro (ex. dwords--)
290f29dbc25Smrg *    counter      -   	name of a counter variable that can be used in a loop.
291f29dbc25Smrg *    			  		This is used to optimize macros written in C.
292f29dbc25Smrg *    array        -   	pointer to an array of unsigned characters.
293f29dbc25Smrg *    array_offset -   	offset into the array from which to pull the first
294f29dbc25Smrg *    					character.
295f29dbc25Smrg *    temp         -   	name of a temporary variable that can be used for
296f29dbc25Smrg *    					calculations.
297f29dbc25Smrg *                     	This argument is also used for C-only macros.
298f29dbc25Smrg ****************************************************************************/
299f29dbc25Smrg
300f29dbc25Smrg#define WRITE_GPREG_STRING32(regoffset, dwords, counter, array, 		\
301f29dbc25Smrg				array_offset, temp)           							\
302f29dbc25Smrg{                                                                       \
303f29dbc25Smrg	temp = (unsigned long)array + (array_offset);                       \
304f29dbc25Smrg	for (counter = 0; counter < dwords; counter++)                      \
305f29dbc25Smrg		WRITE_GP32 (regoffset, *((unsigned long *)temp + counter));     \
306f29dbc25Smrg}
307f29dbc25Smrg
308f29dbc25Smrg/*****************************************************************************
309f29dbc25Smrg * Macro:   WRITE_GPREG_STRING8
310f29dbc25Smrg * Purpose: Write 4 or less bytes to one GP register.
311f29dbc25Smrg *
312f29dbc25Smrg * Arguments:
313f29dbc25Smrg *    regoffset    -   	Offset of the GP register to be written.
314f29dbc25Smrg *    bytes        -   	number of bytes to transfer.  This number will always.
315f29dbc25Smrg *                     	be less than 4.  It cannot be modified within the
316f29dbc25Smrg *                     	macro (ex. bytes--)
317f29dbc25Smrg *    shift        -   	name of a shift variable that can be used as a shift
318f29dbc25Smrg *    					count.
319f29dbc25Smrg *                     	This variable holds the initial shift value into the
320f29dbc25Smrg *                     	GP register.
321f29dbc25Smrg *    counter      -   	name of a counter variable that can be used in a loop.
322f29dbc25Smrg *      				This is used to optimize macros written in C.
323f29dbc25Smrg *    array        -   	pointer to an array of unsigned characters.
324f29dbc25Smrg *    array_offset -   	offset into the array from which to pull the first
325f29dbc25Smrg *    					character.
326f29dbc25Smrg *    temp1        -   	name of a temporary variable that can be used for
327f29dbc25Smrg *    					calculations.
328f29dbc25Smrg *                     	This argument is also used for C-only macros.
329f29dbc25Smrg *    temp2        -   	name of a temporary variable that can be used for
330f29dbc25Smrg *    					calculations.
331f29dbc25Smrg *                     	This argument is also used for C-only macros.
332f29dbc25Smrg ****************************************************************************/
333f29dbc25Smrg#define WRITE_GPREG_STRING8(regoffset, bytes, shift, counter, array,	\
334f29dbc25Smrg				array_offset, temp1, temp2)           					\
335f29dbc25Smrg{                                                                       \
336f29dbc25Smrg	if (bytes) { 	                                                   	\
337f29dbc25Smrg		temp1 = (unsigned long)array + (array_offset);                  \
338f29dbc25Smrg		temp2 = 0;                                                      \
339f29dbc25Smrg		for (counter = 0; counter < bytes; counter++) {                 \
340f29dbc25Smrg			temp2 |= ((unsigned long)(*((unsigned char *)(temp1 + 		\
341f29dbc25Smrg											counter)))) << shift;     	\
342f29dbc25Smrg			shift += 8;                                                 \
343f29dbc25Smrg		}                                                               \
344f29dbc25Smrg		WRITE_GP32 (regoffset, temp2);                                  \
345f29dbc25Smrg	}                                                                   \
346f29dbc25Smrg}
347f29dbc25Smrg
348f29dbc25Smrg/* END OF FILE */
349