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, 6904007ebaSmrg unsigned short srcy, 7004007ebaSmrg unsigned short dstx, 7104007ebaSmrg unsigned short dsty, 7204007ebaSmrg unsigned short width, 7304007ebaSmrg unsigned short height, 7404007ebaSmrg unsigned char *data, short pitch); 75f29dbc25Smrgunsigned int GetVideoMemSize(void); 76f29dbc25Smrg 77f29dbc25Smrg/* ROUTINES added accessing hardware reg */ 78f29dbc25Smrgvoid 79f29dbc25Smrggfx_write_reg8(unsigned long offset, unsigned char value) 80f29dbc25Smrg{ 81f29dbc25Smrg WRITE_REG8(offset, value); 82f29dbc25Smrg} 83f29dbc25Smrg 84f29dbc25Smrgvoid 85f29dbc25Smrggfx_write_reg16(unsigned long offset, unsigned short value) 86f29dbc25Smrg{ 87f29dbc25Smrg WRITE_REG16(offset, value); 88f29dbc25Smrg} 89f29dbc25Smrg 90f29dbc25Smrgvoid 91f29dbc25Smrggfx_write_reg32(unsigned long offset, unsigned long value) 92f29dbc25Smrg{ 93f29dbc25Smrg WRITE_REG32(offset, value); 94f29dbc25Smrg} 9504007ebaSmrg 96f29dbc25Smrgunsigned short 97f29dbc25Smrggfx_read_reg16(unsigned long offset) 98f29dbc25Smrg{ 99f29dbc25Smrg unsigned short value; 100f29dbc25Smrg 101f29dbc25Smrg value = READ_REG16(offset); 102f29dbc25Smrg return value; 103f29dbc25Smrg} 10404007ebaSmrg 105f29dbc25Smrgunsigned long 106f29dbc25Smrggfx_read_reg32(unsigned long offset) 107f29dbc25Smrg{ 108f29dbc25Smrg unsigned long value; 109f29dbc25Smrg 110f29dbc25Smrg value = READ_REG32(offset); 111f29dbc25Smrg return value; 112f29dbc25Smrg} 113f29dbc25Smrg 114f29dbc25Smrgvoid 115f29dbc25Smrggfx_write_vid32(unsigned long offset, unsigned long value) 116f29dbc25Smrg{ 117f29dbc25Smrg WRITE_VID32(offset, value); 118f29dbc25Smrg} 11904007ebaSmrg 120f29dbc25Smrgunsigned long 121f29dbc25Smrggfx_read_vid32(unsigned long offset) 122f29dbc25Smrg{ 123f29dbc25Smrg unsigned long value; 124f29dbc25Smrg 125f29dbc25Smrg value = READ_VID32(offset); 126f29dbc25Smrg return value; 127f29dbc25Smrg} 128f29dbc25Smrg 129f29dbc25Smrg/*Addition for the VIP code */ 130f29dbc25Smrgunsigned long 131f29dbc25Smrggfx_read_vip32(unsigned long offset) 132f29dbc25Smrg{ 133f29dbc25Smrg unsigned long value; 134f29dbc25Smrg 135f29dbc25Smrg value = READ_VIP32(offset); 136f29dbc25Smrg return value; 137f29dbc25Smrg} 138f29dbc25Smrg 139f29dbc25Smrgvoid 140f29dbc25Smrggfx_write_vip32(unsigned long offset, unsigned long value) 141f29dbc25Smrg{ 142f29dbc25Smrg WRITE_VIP32(offset, value); 143f29dbc25Smrg} 144f29dbc25Smrg 145f29dbc25Smrg#define SWAP_BITS_IN_BYTES(v) \ 146f29dbc25Smrg (((0x01010101 & (v)) << 7) | ((0x02020202 & (v)) << 5) | \ 147f29dbc25Smrg ((0x04040404 & (v)) << 3) | ((0x08080808 & (v)) << 1) | \ 148f29dbc25Smrg ((0x10101010 & (v)) >> 1) | ((0x20202020 & (v)) >> 3) | \ 149f29dbc25Smrg ((0x40404040 & (v)) >> 5) | ((0x80808080 & (v)) >> 7)) 150f29dbc25Smrg 151f29dbc25Smrg#define WRITE_GPREG_STRING32_SWP(regoffset, dwords, \ 152f29dbc25Smrg counter, array, array_offset, temp) \ 153f29dbc25Smrg{ \ 154f29dbc25Smrg temp = (unsigned long)array + (array_offset); \ 155f29dbc25Smrg for (counter = 0; counter < dwords; counter++) \ 156f29dbc25Smrg WRITE_GP32 (regoffset, \ 157f29dbc25Smrg SWAP_BITS_IN_BYTES(*((unsigned long *)temp + counter))); \ 158f29dbc25Smrg} 159f29dbc25Smrg 160f29dbc25Smrgvoid 161f29dbc25Smrggfx_mono_bitmap_to_screen_blt_swp(unsigned short srcx, unsigned short srcy, 16204007ebaSmrg unsigned short dstx, unsigned short dsty, 16304007ebaSmrg unsigned short width, unsigned short height, 16404007ebaSmrg unsigned char *data, short pitch) 165f29dbc25Smrg{ 166f29dbc25Smrg unsigned long dstoffset, size, bytes; 167f29dbc25Smrg unsigned long offset, temp_offset, temp1 = 0, temp2 = 0; 168f29dbc25Smrg unsigned long i, j = 0, fifo_lines, dwords_extra, bytes_extra; 169f29dbc25Smrg unsigned long shift = 0; 170f29dbc25Smrg 17104007ebaSmrg size = (((unsigned long) width) << 16) | height; 172f29dbc25Smrg 173f29dbc25Smrg /* CALCULATE STARTING OFFSETS */ 174f29dbc25Smrg 17504007ebaSmrg offset = (unsigned long) srcy *pitch + ((unsigned long) srcx >> 3); 176f29dbc25Smrg 17704007ebaSmrg dstoffset = (unsigned long) dsty *gu2_pitch + 17804007ebaSmrg (((unsigned long) dstx) << gu2_xshift); 179f29dbc25Smrg 180f29dbc25Smrg /* CHECK IF PATTERN ORIGINS NEED TO BE SET */ 181f29dbc25Smrg 182f29dbc25Smrg if (GFXpatternFlags) { 18304007ebaSmrg /* COMBINE X AND Y PATTERN ORIGINS WITH OFFSET */ 184f29dbc25Smrg 18504007ebaSmrg dstoffset |= ((unsigned long) (dstx & 7)) << 26; 18604007ebaSmrg dstoffset |= ((unsigned long) (dsty & 7)) << 29; 187f29dbc25Smrg } 188f29dbc25Smrg 189f29dbc25Smrg bytes = ((srcx & 7) + width + 7) >> 3; 190f29dbc25Smrg fifo_lines = bytes >> 5; 191f29dbc25Smrg dwords_extra = (bytes & 0x0000001Cl) >> 2; 192f29dbc25Smrg bytes_extra = bytes & 0x00000003l; 193f29dbc25Smrg 194f29dbc25Smrg /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */ 195f29dbc25Smrg /* Put off poll for as long as possible (do most calculations first). */ 196f29dbc25Smrg /* The source offset is always 0 since we allow misaligned dword reads. */ 197f29dbc25Smrg /* Need to wait for busy instead of pending, since hardware clears */ 198f29dbc25Smrg /* the host data FIFO at the beginning of a BLT. */ 199f29dbc25Smrg 200f29dbc25Smrg GU2_WAIT_PENDING; 201f29dbc25Smrg WRITE_GP32(MGP_RASTER_MODE, gu2_rop32); 20204007ebaSmrg WRITE_GP32(MGP_SRC_OFFSET, ((unsigned long) srcx & 7) << 26); 203f29dbc25Smrg WRITE_GP32(MGP_DST_OFFSET, dstoffset); 204f29dbc25Smrg WRITE_GP32(MGP_WID_HEIGHT, size); 205f29dbc25Smrg WRITE_GP32(MGP_STRIDE, gu2_pitch); 20604007ebaSmrg WRITE_GP16(MGP_BLT_MODE, gu2_blt_mode | MGP_BM_SRC_HOST | MGP_BM_SRC_MONO); 207f29dbc25Smrg 208f29dbc25Smrg /* WAIT FOR BLT TO BE LATCHED */ 209f29dbc25Smrg 210f29dbc25Smrg GU2_WAIT_PENDING; 211f29dbc25Smrg 212f29dbc25Smrg /* WRITE ALL OF THE DATA TO THE HOST SOURCE REGISTER */ 213f29dbc25Smrg 214f29dbc25Smrg while (height--) { 21504007ebaSmrg temp_offset = offset; 216f29dbc25Smrg 21704007ebaSmrg /* WRITE ALL FULL FIFO LINES */ 218f29dbc25Smrg 21904007ebaSmrg for (i = 0; i < fifo_lines; i++) { 22004007ebaSmrg GU2_WAIT_HALF_EMPTY; 22104007ebaSmrg WRITE_GPREG_STRING32_SWP(MGP_HST_SOURCE, 8, j, data, temp_offset, 22204007ebaSmrg temp1); 22304007ebaSmrg temp_offset += 32; 22404007ebaSmrg } 225f29dbc25Smrg 22604007ebaSmrg /* WRITE ALL FULL DWORDS */ 227f29dbc25Smrg 22804007ebaSmrg GU2_WAIT_HALF_EMPTY; 22904007ebaSmrg if (dwords_extra) { 23004007ebaSmrg WRITE_GPREG_STRING32_SWP(MGP_HST_SOURCE, dwords_extra, i, data, 23104007ebaSmrg temp_offset, temp1); 23204007ebaSmrg temp_offset += (dwords_extra << 2); 23304007ebaSmrg } 234f29dbc25Smrg 23504007ebaSmrg /* WRITE REMAINING BYTES */ 236f29dbc25Smrg 23704007ebaSmrg shift = 0; 23804007ebaSmrg if (bytes_extra) 23904007ebaSmrg WRITE_GPREG_STRING8(MGP_HST_SOURCE, bytes_extra, shift, i, data, 24004007ebaSmrg temp_offset, temp1, temp2); 241f29dbc25Smrg 24204007ebaSmrg offset += pitch; 243f29dbc25Smrg } 244f29dbc25Smrg} 245f29dbc25Smrg 246f29dbc25Smrgunsigned int 247f29dbc25SmrgGetVideoMemSize(void) 248f29dbc25Smrg{ 249f29dbc25Smrg unsigned int graphicsMemBaseAddr; 250f29dbc25Smrg unsigned int totalMem = 0; 251f29dbc25Smrg int i; 252f29dbc25Smrg unsigned int graphicsMemMask, graphicsMemShift; 253f29dbc25Smrg unsigned int mcBankCfg = gfx_read_reg32(0x8408); 254f29dbc25Smrg unsigned int dimmShift = 4; 255f29dbc25Smrg 256f29dbc25Smrg /* Read graphics base address. */ 257f29dbc25Smrg 258f29dbc25Smrg graphicsMemBaseAddr = gfx_read_reg32(0x8414); 259f29dbc25Smrg 260f29dbc25Smrg graphicsMemMask = 0x7FF; 261f29dbc25Smrg graphicsMemShift = 19; 262f29dbc25Smrg 263f29dbc25Smrg /* Calculate total memory size for GXm. */ 264f29dbc25Smrg 265f29dbc25Smrg for (i = 0; i < 2; i++) { 26604007ebaSmrg if (((mcBankCfg >> dimmShift) & 0x7) != 0x7) { 26704007ebaSmrg switch ((mcBankCfg >> (dimmShift + 4)) & 0x7) { 26804007ebaSmrg case 0: 26904007ebaSmrg totalMem += 0x400000; 27004007ebaSmrg break; 27104007ebaSmrg case 1: 27204007ebaSmrg totalMem += 0x800000; 27304007ebaSmrg break; 27404007ebaSmrg case 2: 27504007ebaSmrg totalMem += 0x1000000; 27604007ebaSmrg break; 27704007ebaSmrg case 3: 27804007ebaSmrg totalMem += 0x2000000; 27904007ebaSmrg break; 28004007ebaSmrg case 4: 28104007ebaSmrg totalMem += 0x4000000; 28204007ebaSmrg break; 28304007ebaSmrg case 5: 28404007ebaSmrg totalMem += 0x8000000; 28504007ebaSmrg break; 28604007ebaSmrg case 6: 28704007ebaSmrg totalMem += 0x10000000; 28804007ebaSmrg break; 28904007ebaSmrg case 7: 29004007ebaSmrg totalMem += 0x20000000; 29104007ebaSmrg break; 29204007ebaSmrg default: 29304007ebaSmrg break; 29404007ebaSmrg } 29504007ebaSmrg } 29604007ebaSmrg dimmShift += 16; 297f29dbc25Smrg } 298f29dbc25Smrg 299f29dbc25Smrg /* Calculate graphics memory base address */ 300f29dbc25Smrg 301f29dbc25Smrg graphicsMemBaseAddr &= graphicsMemMask; 302f29dbc25Smrg graphicsMemBaseAddr <<= graphicsMemShift; 303f29dbc25Smrg 304f29dbc25Smrg return (totalMem - graphicsMemBaseAddr); 305f29dbc25Smrg} 306f29dbc25Smrg 307f29dbc25Smrg/* END OF FILE */ 308