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