1/* Copyright (c) 2005 Advanced Micro Devices, Inc. 2 * 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: 9 * 10 * The above copyright notice and this permission notice shall be included in 11 * all copies or substantial portions of the Software. 12 * 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 19 * IN THE SOFTWARE. 20 * 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. 24 * */ 25 26/* 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. 32 * */ 33 34/* ACCESS TO THE CPU REGISTERS */ 35 36#define WRITE_REG8(offset, value) \ 37 (*(volatile unsigned char *)(gfx_virt_regptr + (offset))) = (value) 38 39#define WRITE_REG16(offset, value) \ 40 (*(volatile unsigned short *)(gfx_virt_regptr + (offset))) = (value) 41 42#define WRITE_REG32(offset, value) \ 43 (*(volatile unsigned long *)(gfx_virt_regptr + (offset))) = (value) 44 45#define READ_REG16(offset) \ 46 (*(volatile unsigned short *)(gfx_virt_regptr + (offset))) 47 48#define READ_REG32(offset) \ 49 (*(volatile unsigned long *)(gfx_virt_regptr + (offset))) 50 51/* ACCESS TO THE ACCELERATOR REGISTERS (REDCLOUD ONLY) */ 52 53#define WRITE_GP8(offset, value) \ 54 (*(volatile unsigned char *)(gfx_virt_gpptr + (offset))) = (value) 55 56#define WRITE_GP16(offset, value) \ 57 (*(volatile unsigned short *)(gfx_virt_gpptr + (offset))) = (value) 58 59#define WRITE_GP32(offset, value) \ 60 (*(volatile unsigned long *)(gfx_virt_gpptr + (offset))) = (value) 61 62#define READ_GP16(offset) \ 63 (*(volatile unsigned short *)(gfx_virt_gpptr + (offset))) 64 65#define READ_GP32(offset) \ 66 (*(volatile unsigned long *)(gfx_virt_gpptr + (offset))) 67 68/* ACCESS TO THE FRAME BUFFER */ 69 70#define WRITE_FB32(offset, value) \ 71 (*(volatile unsigned long *)(gfx_virt_fbptr + (offset))) = (value) 72 73#define WRITE_FB16(offset, value) \ 74 (*(volatile unsigned short *)(gfx_virt_fbptr + (offset))) = (value) 75 76#define WRITE_FB8(offset, value) \ 77 (*(volatile unsigned char *)(gfx_virt_fbptr + (offset))) = (value) 78 79/* ACCESS TO THE VIDEO HARDWARE */ 80 81#define READ_VID32(offset) \ 82 (*(volatile unsigned long *)(gfx_virt_vidptr + (offset))) 83 84#define WRITE_VID32(offset, value) \ 85 (*(volatile unsigned long *)(gfx_virt_vidptr + (offset))) = (value) 86 87/* ACCESS TO THE VIP HARDWARE */ 88 89#define READ_VIP32(offset) \ 90 (*(volatile unsigned long *)(gfx_virt_vipptr + (offset))) 91 92#define WRITE_VIP32(offset, value) \ 93 (*(volatile unsigned long *)(gfx_virt_vipptr + (offset))) = (value) 94 95/* ACCESS TO THE SCRATCHPAD RAM */ 96 97#define WRITE_SCRATCH32(offset, value) \ 98 (*(volatile unsigned long *)(gfx_virt_spptr + (offset))) = (value) 99 100#define WRITE_SCRATCH16(offset, value) \ 101 (*(volatile unsigned short *)(gfx_virt_spptr + (offset))) = (value) 102 103#define WRITE_SCRATCH8(offset, value) \ 104 (*(volatile unsigned char *)(gfx_virt_spptr + (offset))) = (value) 105 106#define READ_SCRATCH16(offset) \ 107 (*(volatile unsigned short *)(gfx_virt_spptr + (offset))) 108 109#define READ_SCRATCH32(offset) \ 110 (*(volatile unsigned long *)(gfx_virt_spptr + (offset))) 111 112/* ACCESS TO MSRS */ 113 114void gfx_msr_asm_write(unsigned short msrReg, unsigned long msrAddr, 115 unsigned long *ptrHigh, unsigned long *ptrLow); 116void gfx_msr_asm_read(unsigned short msrReg, unsigned long msrAddr, 117 unsigned long *ptrHigh, unsigned long *ptrLow); 118 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 ) 122 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 ) 126 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. 131 * */ 132 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. 138 * 139 * Arguments: 140 * scratch_base - offset into the GX base for the first BLT buffer byte. 141 ****************************************************************************/ 142 143#define SET_SCRATCH_BASE(scratch_base) \ 144 { gfx_gx1_scratch_base = (unsigned long)gfx_virt_spptr + scratch_base; } 145 146#ifdef GFX_OPTIMIZE_ASSEMBLY 147 148/***************************************************************************** 149 * Macro: WRITE_SCRATCH_STRING 150 * Purpose: Write multiple bytes to the scratchpad buffer 151 * 152 * Arguments: 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 159 * character. 160 ****************************************************************************/ 161 162#define WRITE_SCRATCH_STRING(dwords, bytes, array, array_offset) \ 163{ \ 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 } \ 169 _asm { rep movsd } \ 170 _asm { mov ecx, bytes } \ 171 _asm { rep movsb } \ 172} 173 174/***************************************************************************** 175 * Macro: WRITE_FRAME_BUFFER_STRING32 176 * Purpose: Write multiple dwords to the Frame buffer 177 * 178 * Arguments: 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 185 * character. 186 ****************************************************************************/ 187 188#define WRITE_FRAME_BUFFER_STRING32(fboffset, bytes, array, array_offset) \ 189{ \ 190 _asm { mov ecx, bytes } \ 191 _asm { shr ecx, 2 } \ 192 _asm { cld } \ 193 _asm { mov edi, gfx_virt_fbptr } \ 194 _asm { add edi, fboffset } \ 195 _asm { mov esi, array } \ 196 _asm { add esi, array_offset } \ 197 _asm { rep movsd } \ 198} 199 200#else 201 202/***************************************************************************** 203 * Macro: WRITE_SCRATCH_STRING 204 * Purpose: Write multiple bytes to the scratchpad buffer 205 * 206 * Arguments: 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 213 * character. 214 ****************************************************************************/ 215 216#define WRITE_SCRATCH_STRING(dword_bytes, bytes_extra, array, array_offset) \ 217{ \ 218 unsigned long i, j; \ 219 unsigned long aroffset = (unsigned long)array + (array_offset); \ 220 \ 221 /* WRITE DWORDS */ \ 222 \ 223 for (i = 0; i < dword_bytes; i += 4) \ 224 *((volatile unsigned long *)(gfx_gx1_scratch_base + i)) = \ 225 *((unsigned long *)(aroffset + i)); \ 226 \ 227 /* WRITE BYTES */ \ 228 \ 229 j = i + bytes_extra; \ 230 while (i < j) { \ 231 *((volatile unsigned char *)(gfx_gx1_scratch_base + i)) = \ 232 *((unsigned char *)(aroffset + i)); \ 233 i++; \ 234 } \ 235} 236 237/***************************************************************************** 238 * Macro: WRITE_FRAME_BUFFER_STRING32 239 * Purpose: Write multiple dwords to the Frame buffer 240 * 241 * Arguments: 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 248 * character. 249 ****************************************************************************/ 250 251#define WRITE_FRAME_BUFFER_STRING32(fboffset, bytes, array, array_offset) \ 252{ \ 253 unsigned long i; \ 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))); \ 257} 258 259#endif 260 261/***************************************************************************** 262 * Macro: WRITE_FRAME_BUFFER_STRING8 263 * Purpose: Write multiple bytes to the frame buffer 264 * 265 * Arguments: 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 271 * character. 272 ****************************************************************************/ 273 274#define WRITE_FRAME_BUFFER_STRING8(fboffset, bytes, array, array_offset) \ 275{ \ 276 unsigned long i; \ 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))); \ 280} 281 282/***************************************************************************** 283 * Macro: WRITE_GPREG_STRING32 284 * Purpose: Write multiple dwords to one GP register. 285 * 286 * Arguments: 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 294 * character. 295 * temp - name of a temporary variable that can be used for 296 * calculations. 297 * This argument is also used for C-only macros. 298 ****************************************************************************/ 299 300#define WRITE_GPREG_STRING32(regoffset, dwords, counter, array, \ 301 array_offset, temp) \ 302{ \ 303 temp = (unsigned long)array + (array_offset); \ 304 for (counter = 0; counter < dwords; counter++) \ 305 WRITE_GP32 (regoffset, *((unsigned long *)temp + counter)); \ 306} 307 308/***************************************************************************** 309 * Macro: WRITE_GPREG_STRING8 310 * Purpose: Write 4 or less bytes to one GP register. 311 * 312 * Arguments: 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 318 * count. 319 * This variable holds the initial shift value into the 320 * GP register. 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 325 * character. 326 * temp1 - name of a temporary variable that can be used for 327 * calculations. 328 * This argument is also used for C-only macros. 329 * temp2 - name of a temporary variable that can be used for 330 * calculations. 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) \ 335{ \ 336 if (bytes) { \ 337 temp1 = (unsigned long)array + (array_offset); \ 338 temp2 = 0; \ 339 for (counter = 0; counter < bytes; counter++) { \ 340 temp2 |= ((unsigned long)(*((unsigned char *)(temp1 + \ 341 counter)))) << shift; \ 342 shift += 8; \ 343 } \ 344 WRITE_GP32 (regoffset, temp2); \ 345 } \ 346} 347 348/* END OF FILE */ 349