gx_regacc.c revision f29dbc25
1/* Copyright (c) 2003-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 is the main file used to add Durango graphics support to a software 28 * project. The main reason to have a single file include the other files 29 * is that it centralizes the location of the compiler options. This file 30 * should be tuned for a specific implementation, and then modified as needed 31 * for new Durango releases. The releases.txt file indicates any updates to 32 * this main file, such as a new definition for a new hardware platform. 33 * 34 * In other words, this file should be copied from the Durango source files 35 * once when a software project starts, and then maintained as necessary. 36 * It should not be recopied with new versions of Durango unless the 37 * developer is willing to tune the file again for the specific project. 38 * */ 39 40#ifdef HAVE_CONFIG_H 41#include "config.h" 42#endif 43 44#include "gfx_rtns.h" 45#include "gfx_defs.h" 46#include "gfx_regs.h" 47 48#define GU2_WAIT_PENDING \ 49 while(READ_GP32(MGP_BLT_STATUS) & MGP_BS_BLT_PENDING) 50#define GU2_WAIT_HALF_EMPTY \ 51 while(!(READ_GP32(MGP_BLT_STATUS) & MGP_BS_HALF_EMPTY)) 52 53extern unsigned long gu2_pitch; 54extern unsigned long gu2_xshift; 55extern unsigned short GFXpatternFlags; 56extern unsigned long gu2_rop32; 57extern unsigned short gu2_blt_mode; 58 59void gfx_write_reg8(unsigned long offset, unsigned char value); 60void gfx_write_reg16(unsigned long offset, unsigned short value); 61void gfx_write_reg32(unsigned long offset, unsigned long value); 62unsigned short gfx_read_reg16(unsigned long offset); 63unsigned long gfx_read_reg32(unsigned long offset); 64void gfx_write_vid32(unsigned long offset, unsigned long value); 65unsigned long gfx_read_vid32(unsigned long offset); 66unsigned long gfx_read_vip32(unsigned long offset); 67void gfx_write_vip32(unsigned long offset, unsigned long value); 68void gfx_mono_bitmap_to_screen_blt_swp(unsigned short srcx, 69 unsigned short srcy, 70 unsigned short dstx, 71 unsigned short dsty, 72 unsigned short width, 73 unsigned short height, unsigned char *data, short pitch); 74unsigned int GetVideoMemSize(void); 75 76/* ROUTINES added accessing hardware reg */ 77void 78gfx_write_reg8(unsigned long offset, unsigned char value) 79{ 80 WRITE_REG8(offset, value); 81} 82 83void 84gfx_write_reg16(unsigned long offset, unsigned short value) 85{ 86 WRITE_REG16(offset, value); 87} 88 89void 90gfx_write_reg32(unsigned long offset, unsigned long value) 91{ 92 WRITE_REG32(offset, value); 93} 94unsigned short 95gfx_read_reg16(unsigned long offset) 96{ 97 unsigned short value; 98 99 value = READ_REG16(offset); 100 return value; 101} 102unsigned long 103gfx_read_reg32(unsigned long offset) 104{ 105 unsigned long value; 106 107 value = READ_REG32(offset); 108 return value; 109} 110 111void 112gfx_write_vid32(unsigned long offset, unsigned long value) 113{ 114 WRITE_VID32(offset, value); 115} 116unsigned long 117gfx_read_vid32(unsigned long offset) 118{ 119 unsigned long value; 120 121 value = READ_VID32(offset); 122 return value; 123} 124 125/*Addition for the VIP code */ 126unsigned long 127gfx_read_vip32(unsigned long offset) 128{ 129 unsigned long value; 130 131 value = READ_VIP32(offset); 132 return value; 133} 134 135void 136gfx_write_vip32(unsigned long offset, unsigned long value) 137{ 138 WRITE_VIP32(offset, value); 139} 140 141#define SWAP_BITS_IN_BYTES(v) \ 142 (((0x01010101 & (v)) << 7) | ((0x02020202 & (v)) << 5) | \ 143 ((0x04040404 & (v)) << 3) | ((0x08080808 & (v)) << 1) | \ 144 ((0x10101010 & (v)) >> 1) | ((0x20202020 & (v)) >> 3) | \ 145 ((0x40404040 & (v)) >> 5) | ((0x80808080 & (v)) >> 7)) 146 147#define WRITE_GPREG_STRING32_SWP(regoffset, dwords, \ 148 counter, array, array_offset, temp) \ 149{ \ 150 temp = (unsigned long)array + (array_offset); \ 151 for (counter = 0; counter < dwords; counter++) \ 152 WRITE_GP32 (regoffset, \ 153 SWAP_BITS_IN_BYTES(*((unsigned long *)temp + counter))); \ 154} 155 156void 157gfx_mono_bitmap_to_screen_blt_swp(unsigned short srcx, unsigned short srcy, 158 unsigned short dstx, unsigned short dsty, 159 unsigned short width, unsigned short height, 160 unsigned char *data, short pitch) 161{ 162 unsigned long dstoffset, size, bytes; 163 unsigned long offset, temp_offset, temp1 = 0, temp2 = 0; 164 unsigned long i, j = 0, fifo_lines, dwords_extra, bytes_extra; 165 unsigned long shift = 0; 166 167 size = (((unsigned long)width) << 16) | height; 168 169 /* CALCULATE STARTING OFFSETS */ 170 171 offset = (unsigned long)srcy *pitch + ((unsigned long)srcx >> 3); 172 173 dstoffset = (unsigned long)dsty *gu2_pitch + 174 (((unsigned long)dstx) << gu2_xshift); 175 176 /* CHECK IF PATTERN ORIGINS NEED TO BE SET */ 177 178 if (GFXpatternFlags) { 179 /* COMBINE X AND Y PATTERN ORIGINS WITH OFFSET */ 180 181 dstoffset |= ((unsigned long)(dstx & 7)) << 26; 182 dstoffset |= ((unsigned long)(dsty & 7)) << 29; 183 } 184 185 bytes = ((srcx & 7) + width + 7) >> 3; 186 fifo_lines = bytes >> 5; 187 dwords_extra = (bytes & 0x0000001Cl) >> 2; 188 bytes_extra = bytes & 0x00000003l; 189 190 /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */ 191 /* Put off poll for as long as possible (do most calculations first). */ 192 /* The source offset is always 0 since we allow misaligned dword reads. */ 193 /* Need to wait for busy instead of pending, since hardware clears */ 194 /* the host data FIFO at the beginning of a BLT. */ 195 196 GU2_WAIT_PENDING; 197 WRITE_GP32(MGP_RASTER_MODE, gu2_rop32); 198 WRITE_GP32(MGP_SRC_OFFSET, ((unsigned long)srcx & 7) << 26); 199 WRITE_GP32(MGP_DST_OFFSET, dstoffset); 200 WRITE_GP32(MGP_WID_HEIGHT, size); 201 WRITE_GP32(MGP_STRIDE, gu2_pitch); 202 WRITE_GP16(MGP_BLT_MODE, 203 gu2_blt_mode | MGP_BM_SRC_HOST | MGP_BM_SRC_MONO); 204 205 /* WAIT FOR BLT TO BE LATCHED */ 206 207 GU2_WAIT_PENDING; 208 209 /* WRITE ALL OF THE DATA TO THE HOST SOURCE REGISTER */ 210 211 while (height--) { 212 temp_offset = offset; 213 214 /* WRITE ALL FULL FIFO LINES */ 215 216 for (i = 0; i < fifo_lines; i++) { 217 GU2_WAIT_HALF_EMPTY; 218 WRITE_GPREG_STRING32_SWP(MGP_HST_SOURCE, 8, j, data, temp_offset, 219 temp1); 220 temp_offset += 32; 221 } 222 223 /* WRITE ALL FULL DWORDS */ 224 225 GU2_WAIT_HALF_EMPTY; 226 if (dwords_extra) { 227 WRITE_GPREG_STRING32_SWP(MGP_HST_SOURCE, dwords_extra, i, data, 228 temp_offset, temp1); 229 temp_offset += (dwords_extra << 2); 230 } 231 232 /* WRITE REMAINING BYTES */ 233 234 shift = 0; 235 if (bytes_extra) 236 WRITE_GPREG_STRING8(MGP_HST_SOURCE, bytes_extra, shift, i, data, 237 temp_offset, temp1, temp2); 238 239 offset += pitch; 240 } 241} 242 243unsigned int 244GetVideoMemSize(void) 245{ 246 unsigned int graphicsMemBaseAddr; 247 unsigned int totalMem = 0; 248 int i; 249 unsigned int graphicsMemMask, graphicsMemShift; 250 unsigned int mcBankCfg = gfx_read_reg32(0x8408); 251 unsigned int dimmShift = 4; 252 253 /* Read graphics base address. */ 254 255 graphicsMemBaseAddr = gfx_read_reg32(0x8414); 256 257 graphicsMemMask = 0x7FF; 258 graphicsMemShift = 19; 259 260 /* Calculate total memory size for GXm. */ 261 262 for (i = 0; i < 2; i++) { 263 if (((mcBankCfg >> dimmShift) & 0x7) != 0x7) { 264 switch ((mcBankCfg >> (dimmShift + 4)) & 0x7) { 265 case 0: 266 totalMem += 0x400000; 267 break; 268 case 1: 269 totalMem += 0x800000; 270 break; 271 case 2: 272 totalMem += 0x1000000; 273 break; 274 case 3: 275 totalMem += 0x2000000; 276 break; 277 case 4: 278 totalMem += 0x4000000; 279 break; 280 case 5: 281 totalMem += 0x8000000; 282 break; 283 case 6: 284 totalMem += 0x10000000; 285 break; 286 case 7: 287 totalMem += 0x20000000; 288 break; 289 default: 290 break; 291 } 292 } 293 dimmShift += 16; 294 } 295 296 /* Calculate graphics memory base address */ 297 298 graphicsMemBaseAddr &= graphicsMemMask; 299 graphicsMemBaseAddr <<= graphicsMemShift; 300 301 return (totalMem - graphicsMemBaseAddr); 302} 303 304/* END OF FILE */ 305