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