| /* |
| * This file is part of the coreboot project. |
| * |
| * Copyright (C) 2009 One Laptop per Child, Association, Inc. |
| * |
| * This program is free software; you can redistribute it and/or modify |
| * it under the terms of the GNU General Public License as published by |
| * the Free Software Foundation; version 2 of the License. |
| * |
| * This program is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| * GNU General Public License for more details. |
| * |
| * You should have received a copy of the GNU General Public License |
| * along with this program; if not, write to the Free Software |
| * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
| */ |
| |
| #include "pci_rawops.h" |
| |
| typedef struct __UMA_RAM_tag { |
| u16 DramSize; |
| u8 D0F3Val; |
| u8 D1F0Val; |
| u8 VgaPortVal; |
| } UMARAM; |
| #define UMARAM_512M 7 |
| #define UMARAM_256M 6 |
| #define UMARAM_128M 5 |
| #define UMARAM_64M 4 |
| #define UMARAM_32M 3 |
| #define UMARAM_16M 2 |
| #define UMARAM_8M 1 |
| #define UMARAM_0M 0 |
| |
| #define FB_512M 0 |
| #define FB_256M 0x40 |
| #define FB_128M 0x60 |
| #define FB_64M 0x70 |
| #define FB_32M 0x78 |
| #define FB_16M 0x7c |
| #define FB_8M 0x7E |
| #define FB_4M 0x7F |
| |
| #define VGA_PORT_512M 0x00 |
| #define VGA_PORT_256M 0x80 |
| #define VGA_PORT_128M 0xC0 |
| #define VGA_PORT_64M 0xE0 |
| #define VGA_PORT_32M 0xF0 |
| #define VGA_PORT_16M 0xF8 |
| |
| #define VIACONFIG_VGA_PCI_10 0xf8000008 |
| #define VIACONFIG_VGA_PCI_14 0xfc000000 |
| |
| static const UMARAM UMARamArr[] = { |
| {0, UMARAM_0M, FB_4M, 0xFE}, |
| {8, UMARAM_8M, FB_8M, 0xFC}, |
| {16, UMARAM_16M, FB_16M, VGA_PORT_16M}, |
| {32, UMARAM_32M, FB_32M, VGA_PORT_32M}, |
| {64, UMARAM_64M, FB_64M, VGA_PORT_64M}, |
| {128, UMARAM_128M, FB_128M, VGA_PORT_128M}, |
| {256, UMARAM_256M, FB_256M, VGA_PORT_256M}, |
| {512, UMARAM_512M, FB_512M, VGA_PORT_512M}, |
| {0xffff, 0xff, 0xff, 0xFF} |
| }; |
| |
| void SetUMARam(void) |
| { |
| #if 1 |
| u8 ramregs[] = { 0x43, 0x42, 0x41, 0x40 }; |
| device_t vga_dev = PCI_DEV(0, 1, 0), d0f0_dev = PCI_DEV(0, 0, 0); |
| u8 ByteVal, temp; |
| const UMARAM *pUMARamTable; |
| u16 UmaSize; |
| u8 SLD0F3Val, SLD1F0Val, VgaPortVal; |
| u32 RamSize, SLBase, Tmp; |
| u8 i; |
| PRINT_DEBUG_MEM("Entering vx800 SetUMARam.\n"); |
| SLD0F3Val = 0; |
| SLD1F0Val = 0; |
| VgaPortVal = 0; |
| |
| ByteVal = pci_read_config8(MEMCTRL, 0xa1); |
| ByteVal |= 0x80; |
| pci_write_config8(MEMCTRL, 0xa1, ByteVal); |
| |
| //set VGA Timer |
| pci_write_config8(MEMCTRL, 0xa2, 0xee); |
| |
| //set agp misc |
| //GFX Data Delay to Sync with Clock |
| pci_write_config8(MEMCTRL, 0xa4, 0x01); |
| |
| //page register life timer |
| pci_write_config8(MEMCTRL, 0xa6, 0x76); |
| |
| //GMINT and GFX relatate |
| //note Bit 3 VGA Enable |
| pci_write_config8(MEMCTRL, 0xa7, 0x8c); |
| // ByteVal = 0x4c; |
| |
| //GMINT Misc.1 |
| //pci_write_config8(MEMCTRL, 0xb0, 0x80); |
| |
| //pci_write_config8(MEMCTRL, 0xb1, 0xaa); |
| |
| //AGPCINT MISC |
| //pci_write_config8(MEMCTRL, 0xb2, 0x82); |
| //ByteVal = 0x8A; |
| |
| //GMINT MISC.2 |
| //disable read pass write |
| pci_write_config8(MEMCTRL, 0xb3, 0x9A); |
| |
| //EPLL Register |
| //pci_write_config8(MEMCTRL, 0xb4, 0x04); |
| |
| //enable CHA and CHB merge mode |
| pci_write_config8(MEMCTRL, 0xde, 0x06); |
| |
| //if can get the value from setup interface, so get the value |
| //else use the default value |
| UmaSize = CONFIG_VIDEO_MB; |
| |
| for (pUMARamTable = UMARamArr; pUMARamTable->DramSize != 0xffff; |
| pUMARamTable++) { |
| if (UmaSize == pUMARamTable->DramSize) { |
| SLD0F3Val = pUMARamTable->D0F3Val; |
| SLD1F0Val = pUMARamTable->D1F0Val; |
| VgaPortVal = pUMARamTable->VgaPortVal; |
| } |
| } |
| //set SL size |
| //Fill in Fun3_RXA1[6:4] with the Frame Buffer size for the Integrated Graphic Device. |
| ByteVal = pci_read_config8(MEMCTRL, 0xa1); |
| ByteVal = (ByteVal & 0x8f) | (SLD0F3Val << 4); |
| pci_write_config8(MEMCTRL, 0xa1, ByteVal); |
| |
| // vga_dev = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VX855_VGA, 0); |
| |
| //RxB2 may be for S.L. and RxB1 may be for L. L. |
| // It is different from Spec. |
| ByteVal = SLD1F0Val; |
| pci_write_config8(vga_dev, 0xb2, ByteVal); |
| |
| //set M1 size |
| //ByteVal=pci_read_config8(MEMCTRL, 0xa3); |
| //ByteVal = 0x02; |
| //pci_write_config8(MEMCTRL, 0xa3, ByteVal); |
| |
| PRINT_DEBUG_MEM("UMA setting - 3\n"); |
| |
| //Enable p2p IO/mem |
| ByteVal = 0x07; |
| pci_write_config8(vga_dev, 0x04, ByteVal); |
| |
| //must set SL and MMIO base, or else when enable GFX memory space, system will hang |
| //set S.L base |
| Tmp = pci_read_config32(vga_dev, 0x10); |
| Tmp = 0xfffffff8; |
| pci_write_config32(vga_dev, 0x10, Tmp); |
| Tmp = pci_read_config32(vga_dev, 0x10); |
| Tmp = VIACONFIG_VGA_PCI_10; |
| pci_write_config32(vga_dev, 0x10, Tmp); |
| |
| //set MMIO base |
| Tmp = pci_read_config32(vga_dev, 0x14); |
| Tmp = 0xfffffffC; |
| pci_write_config32(vga_dev, 0x14, Tmp); |
| Tmp = pci_read_config32(vga_dev, 0x14); |
| Tmp = VIACONFIG_VGA_PCI_14; |
| pci_write_config32(vga_dev, 0x14, Tmp); |
| |
| //enable direct cpu frame buffer access |
| i = pci_rawread_config8(PCI_RAWDEV(0, 0, 3), 0xa1); |
| i = (i & 0xf0) | (VIACONFIG_VGA_PCI_10 >> 28); |
| pci_rawwrite_config8(PCI_RAWDEV(0, 0, 3), 0xa1, i); |
| pci_rawwrite_config8(PCI_RAWDEV(0, 0, 3), 0xa0, 0x01); |
| |
| //enable GFx memory space access control for S.L and mmio |
| ByteVal = pci_read_config8(d0f0_dev, 0xD4); |
| ByteVal |= 0x03; |
| //ByteVal |= 0x01; |
| pci_write_config8(d0f0_dev, 0xD4, ByteVal); |
| |
| //enable Base VGA 16 Bits Decode |
| ByteVal = pci_read_config8(d0f0_dev, 0xfe); |
| ByteVal |= 0x10; |
| pci_write_config8(d0f0_dev, 0xfe, ByteVal); |
| |
| //disable CHB L.L |
| //set VGA memory selection |
| ByteVal = pci_read_config8(vga_dev, 0xb0); |
| ByteVal &= 0xF8; |
| //ByteVal |= 0x01; |
| ByteVal |= 0x03; |
| pci_write_config8(vga_dev, 0xb0, ByteVal); |
| |
| //set LL size |
| |
| //enable memory access to SL,MMIO,LL and IO to 3B0~3BB,3C0 ~3DF |
| //ByteVal = 0x03; |
| //pci_write_config8(d0f0_dev, 0xc0, ByteVal); |
| |
| //Turn on Graphic chip IO port port access |
| ByteVal = inb(0x03C3); |
| ByteVal |= 0x01; |
| outb(ByteVal, 0x03C3); |
| |
| //Turn off Graphic chip Register protection |
| outb(0x10, 0x03C4); |
| |
| ByteVal = inb(0x03C5); |
| ByteVal |= 0x01; |
| outb(ByteVal, 0x03C5); |
| |
| //set VGA memory Frequence |
| //direct IO port 0x3DX to vga io space 0x3C2[0] |
| ByteVal = inb(0x03CC); |
| ByteVal |= 0x03; |
| outb(ByteVal, 0x03C2); |
| // ByteVal=inb(0x03C2); |
| // ByteVal |= 0x01; |
| // outb(ByteVal,0x03C2); |
| |
| #if 1 //bios porting guide has no this two defination: 3d on 3d4/3d5 and 39 on 3c4/3c5 |
| //set frequence 0x3D5.3d[7:4] |
| outb(0x3d, 0x03d4); |
| |
| temp = pci_read_config8(MEMCTRL, 0x90); |
| temp = (u8) (temp & 0x07); |
| ByteVal = inb(0x03d5); |
| switch (temp) { |
| case 0: //DIMMFREQ_200: |
| ByteVal = (u8) ((ByteVal & 0x0F) | 0x30); |
| break; |
| case 1: //DIMMFREQ_266: |
| ByteVal = (u8) ((ByteVal & 0x0F) | 0x40); |
| break; |
| case 3: //DIMMFREQ_400: |
| ByteVal = (u8) ((ByteVal & 0x0F) | 0x60); |
| break; |
| case 4: //DIMMFREQ_533: |
| ByteVal = (u8) ((ByteVal & 0x0F) | 0x70); |
| break; |
| case 5: //DIMMFREQ_667: |
| ByteVal = (u8) ((ByteVal & 0x0F) | 0x80); |
| break; |
| case 6: //DIMMFREQ_800: |
| ByteVal = (u8) ((ByteVal & 0x0F) | 0x90); |
| break; |
| default: |
| ByteVal = (u8) ((ByteVal & 0x0F) | 0x70); |
| break; |
| } |
| outb(ByteVal, 0x03d5); |
| |
| // Set frame buffer size |
| outb(0x39, 0x03c4); |
| outb(1 << SLD0F3Val, 0x03c5); |
| |
| #endif |
| // Set S.L. size in GFX's register |
| outb(0x68, 0x03c4); |
| outb(VgaPortVal, 0x03c5); |
| |
| // ECLK Selection (00:166Mhz, 01:185Mhz, 10:250Mhz, 11:275Mhz) |
| // set 3C5.5A[0]=1, address maps to secondary resgiters |
| outb(0x5a, 0x03c4); |
| ByteVal = inb(0x03c5); |
| ByteVal |= 0x01; |
| outb(ByteVal, 0x03c5); |
| |
| // Set 3D5.4C[7:6] (00:166Mhz, 01:185Mhz, 10:250Mhz, 11:275Mhz) |
| outb(0x4c, 0x03d4); |
| ByteVal = inb(0x03d5); |
| ByteVal = (ByteVal & 0x3F) | 0x80; |
| outb(ByteVal, 0x03d5); |
| |
| // set 3C5.5A[0]=0, address maps to first resgiters |
| outb(0x5a, 0x03c4); |
| ByteVal = inb(0x03c5); |
| ByteVal &= 0xFE; |
| outb(ByteVal, 0x03c5); |
| |
| // Set S.L. Address in System Memory |
| //calculate dram size |
| for (RamSize = 0, i = 0; i < ARRAY_SIZE(ramregs); i++) { |
| RamSize = pci_read_config8(MEMCTRL, ramregs[i]); |
| if (RamSize != 0) |
| break; |
| } |
| //calculate SL Base Address |
| SLBase = (RamSize << 26) - (UmaSize << 20); |
| |
| outb(0x6D, 0x03c4); |
| //SL Base[28:21] |
| outb((u8) ((SLBase >> 21) & 0xFF), 0x03c5); |
| |
| outb(0x6e, 0x03c4); |
| //SL Base[36:29] |
| outb((u8) ((SLBase >> 29) & 0xFF), 0x03c5); |
| |
| outb(0x6f, 0x03c4); |
| outb(0x00, 0x03c5); |
| |
| // Set SVID high byte |
| outb(0x36, 0x03c4); |
| outb(0x11, 0x03c5); |
| |
| // Set SVID Low byte |
| outb(0x35, 0x03c4); |
| outb(0x06, 0x03c5); |
| |
| // Set SID high byte |
| outb(0x38, 0x03c4); |
| outb(0x51, 0x03c5); |
| |
| // Set SID Low byte |
| outb(0x37, 0x03c4); |
| outb(0x22, 0x03c5); |
| |
| //start : For enable snapshot mode control |
| // program 3C5 for SNAPSHOT Mode control, set RxF3h=1Ah |
| outb(0xf3, 0x03c4); |
| ByteVal = inb(0x03c5); |
| ByteVal = (ByteVal & 0xE5) | 0x1A; |
| outb(ByteVal, 0x03c5); |
| |
| outb(0xf3, 0x03d4); |
| ByteVal = inb(0x03d5); |
| ByteVal = (ByteVal & 0xE5) | 0x1A; |
| outb(ByteVal, 0x03d5); |
| |
| #if 0 |
| u8 table3c43c5[0x70] = { |
| 0x03, 0x01, 0x0F, 0x00, 0x06, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x01, 0x78, 0x00, 0x00, 0x00, 0xBE, 0x20, 0x7F, |
| 0x60, 0x7F, 0x08, 0x31, 0xCC, 0x00, 0x01, 0x00, |
| 0x00, 0x18, 0x10, 0x00, 0x00, 0x00, 0x3D, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x04, 0xF3, 0xFF, 0xFC, |
| 0xF8, 0x0C, 0x00, 0x00, 0x40, 0x06, 0x11, 0x22, |
| 0x51, 0x10, 0x00, 0x01, 0x19, 0x0C, 0x00, 0xFF, |
| 0x38, 0x40, 0x30, 0xFF, 0x70, 0x8C, 0x85, 0x9D, |
| 0x80, 0x05, 0x54, 0x90, 0x03, 0x30, 0x00, 0x5F, |
| 0x1F, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, |
| 0x06, 0xDF, 0x00, 0x20, 0x20, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x40, 0x20, 0x00, 0x20, 0x20, |
| 0xE0, 0x20, 0xD0, 0x3F, 0x00, 0xE0, 0x00, 0x00 |
| }; |
| u8 table3d43d5[0x88] = { |
| 0x7F, 0x63, 0x63, 0x83, 0x69, 0x19, 0x72, 0xE0, |
| 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x58, 0x9C, 0x57, 0x90, 0x00, 0x57, 0x73, 0xE3, |
| 0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x0C, 0x00, 0x11, 0x06, 0x00, 0x20, 0x01, 0x34, |
| 0xEE, 0x74, 0x01, 0x01, 0x08, 0x84, 0x00, 0x00, |
| 0x00, 0xF3, 0x40, 0x90, 0x00, 0x00, 0x00, 0x01, |
| 0x00, 0x12, 0x00, 0x02, 0x00, 0x00, 0x10, 0x00, |
| 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, |
| 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x9D, 0x9D, 0x10, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x9D, 0x9D, 0x9D, |
| 0x9D, 0x9D, 0x9D, 0x9D, 0x00, 0x9D, 0x1D, 0x00, |
| 0x00, 0x00, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, |
| 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, |
| }; |
| |
| u8 table3c0space[0xc0] = { |
| 0x11, 0x00, 0x10, 0x01, 0x26, 0x3D, 0xFF, 0x00, |
| 0x10, 0x3F, 0x00, 0x00, 0x2F, 0x00, 0x22, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, |
| 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, |
| 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x50, 0xFF, |
| 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, |
| 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, |
| 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, |
| 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, |
| 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, |
| 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, |
| 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, |
| 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, |
| 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, |
| 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, |
| 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, |
| 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, |
| 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, |
| 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, |
| 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, |
| 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, |
| 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, |
| }; |
| |
| //for(i=0;i<0xc0;i++) |
| for (i = 0; i < 0x40; i++) |
| { |
| outb(table3c0space[i], 0x03c0 + i); |
| } |
| |
| for (i = 0; i < 0x70; i++) { |
| outb(i, 0x03c4); |
| outb(table3c43c5[i], 0x03c5); |
| } |
| for (i = 0; i < 0x88; i++) { |
| outb(i, 0x03d4); |
| outb(table3d43d5[i], 0x03d5); |
| } |
| |
| outb(0x92, 0x03d4); |
| outb(0x80, 0x03d5); |
| |
| outb(0xa3, 0x03d4); |
| outb(0x00, 0x03d5); |
| |
| outb(0xe8, 0x03d4); |
| outb(0x40, 0x03d5); |
| #endif |
| |
| // 3d4 3d freq |
| // IO Port / Index: 3X5.3D |
| // Scratch Pad Register 4 |
| // outb(0x39,0x03c4); |
| // outb(1 << SLD0F3Val ,0x03c5); |
| // |
| #endif |
| |
| } |