Author: sduplichan Date: Wed Nov 24 01:39:44 2010 New Revision: 6120 URL: https://tracker.coreboot.org/trac/coreboot/changeset/6120
Log: This patch solves crashes and BSODs that occur when booting Win7 with AMD RS780 uma graphics. Tested with frame buffer sizes 64m through 1GB by running dxdiag and Windows media player at 1600x1200 true color. Additional changes needed to boot Win7 on Mahogany_fam10 will follow.
-- Enable and program the debug bar as required by the ATI graphics driver. First, make the debug bar writable and allow resource allocation code to program it. Once programmed, enable its operation. -- Disable the family 10h processor mmconf while the RS780 mmconf is in use. -- Make strap programming more closely follow the reference BIOS. -- Disable PCIe bar 3 after using it. -- UMA size is no longer hardcoded. -- Disable write combining for all steppings to eliminate stability problem. -- Correct task file data. -- Improve the accuracy of the Atom table that passes information to the driver.
Signed-off-by: Scott Duplichan scott@notabs.org Acked-by: Rudolf Marek r.marek@assembler.cz
Modified: trunk/src/southbridge/amd/rs780/rs780.c trunk/src/southbridge/amd/rs780/rs780.h trunk/src/southbridge/amd/rs780/rs780_cmn.c trunk/src/southbridge/amd/rs780/rs780_early_setup.c trunk/src/southbridge/amd/rs780/rs780_gfx.c trunk/src/southbridge/amd/rs780/rs780_pcie.c
Modified: trunk/src/southbridge/amd/rs780/rs780.c ============================================================================== --- trunk/src/southbridge/amd/rs780/rs780.c Tue Nov 23 08:30:50 2010 (r6119) +++ trunk/src/southbridge/amd/rs780/rs780.c Wed Nov 24 01:39:44 2010 (r6120) @@ -133,11 +133,6 @@ temp32 = pci_read_config32(nb_dev, 0x4c); printk(BIOS_DEBUG, "NB_PCI_REG4C = %x.\n", temp32);
- /* disable GFX debug. */ - temp8 = pci_read_config8(nb_dev, 0x8d); - temp8 &= ~(1<<1); - pci_write_config8(nb_dev, 0x8d, temp8); - /* set temporary NB TOM to 0x40000000. */ rs780_set_tom(nb_dev);
@@ -194,14 +189,24 @@ static void rs780_nb_gfx_dev_table(device_t nb_dev, device_t dev) { /* NB_InitGFXStraps */ - u32 MMIOBase, apc04, apc18, apc24; + u32 MMIOBase, apc04, apc18, apc24, romstrap2; + msr_t pcie_mmio_save; volatile u32 * strap;
+ // disable processor pcie mmio, if enabled + if (is_family10h()) { + msr_t temp; + pcie_mmio_save = temp = rdmsr (0xc0010058); + temp.lo &= ~1; + wrmsr (0xc0010058, temp); + } + /* Get PCIe configuration space. */ MMIOBase = pci_read_config32(nb_dev, 0x1c) & 0xfffffff0; /* Temporarily disable PCIe configuration space. */ set_htiu_enable_bits(nb_dev, 0x32, 1<<28, 0);
+ // 1E: NB_BIF_SPARE set_nbmisc_enable_bits(nb_dev, 0x1e, 0xffffffff, 1<<1 | 1<<4 | 1<<6 | 1<<7); /* Set a temporary Bus number. */ apc18 = pci_read_config32(dev, 0x18); @@ -214,18 +219,27 @@ pci_write_config8(dev, 0x04, 0x02);
/* Program Straps. */ - strap = (volatile u32 *)(MMIOBase + 0x15020); + romstrap2 = 1 << 26; // enables audio function #if (CONFIG_GFXUMA == 1) - *strap = 1<<7; /* the format of BIF_MEM_AP_SIZE. 001->256MB? */ -#else - *strap = 0; /* 128M SP memory, 000 -> 128MB */ + extern uint64_t uma_memory_size; + // bits 7-9: aperture size + // 0-7: 128mb, 256mb, 64mb, 32mb, 512mb, 1g, 2g, 4g + if (uma_memory_size == 0x02000000) romstrap2 |= 3 << 7; + if (uma_memory_size == 0x04000000) romstrap2 |= 2 << 7; + if (uma_memory_size == 0x08000000) romstrap2 |= 0 << 7; + if (uma_memory_size == 0x10000000) romstrap2 |= 1 << 7; + if (uma_memory_size == 0x20000000) romstrap2 |= 4 << 7; + if (uma_memory_size == 0x40000000) romstrap2 |= 5 << 7; + if (uma_memory_size == 0x80000000) romstrap2 |= 6 << 7; #endif + strap = (volatile u32 *)(MMIOBase + 0x15020); + *strap = romstrap2; strap = (volatile u32 *)(MMIOBase + 0x15000); *strap = 0x2c006300; strap = (volatile u32 *)(MMIOBase + 0x15010); *strap = 0x03015330; - //strap = (volatile u32 *)(MMIOBase + 0x15020); - //*strap |= 0x00000040; /* Disable HDA device. */ + strap = (volatile u32 *)(MMIOBase + 0x15020); + *strap = romstrap2 | 0x00000040; strap = (volatile u32 *)(MMIOBase + 0x15030); *strap = 0x00001002; strap = (volatile u32 *)(MMIOBase + 0x15040); @@ -240,8 +254,9 @@ /* BIF switches into normal functional mode. */ set_nbmisc_enable_bits(nb_dev, 0x1e, 1<<4 | 1<<5, 1<<5);
- /* NB Revision is A12. */ - set_nbmisc_enable_bits(nb_dev, 0x1e, 1<<9, 1<<9); + /* NB Revision is A12 or newer */ + if (get_nb_rev(nb_dev) >= REV_RS780_A12) + set_nbmisc_enable_bits(nb_dev, 0x1e, 1<<9, 1<<9);
/* Restore APC04, APC18, APC24. */ pci_write_config32(dev, 0x04, apc04); @@ -250,6 +265,11 @@
/* Enable PCIe configuration space. */ set_htiu_enable_bits(nb_dev, 0x32, 0, 1<<28); + + // restore processor pcie mmio + if (is_family10h()) + wrmsr (0xc0010058, pcie_mmio_save); + printk(BIOS_INFO, "GC is accessible from now on.\n"); }
@@ -332,18 +352,17 @@ (dev->enabled ? 1 : 0) << 6); if (dev->enabled) rs780_gpp_sb_init(nb_dev, dev, dev_ind); - disable_pcie_bar3(nb_dev); break; case 9: /* bus 0, dev 9,10, GPP */ case 10: printk(BIOS_INFO, "Bus-0, Dev-9, 10, Fun-0. enable=%d\n", dev->enabled); - enable_pcie_bar3(nb_dev); /* PCIEMiscInit */ set_nbmisc_enable_bits(nb_dev, 0x0c, 1 << (7 + dev_ind), (dev->enabled ? 0 : 1) << (7 + dev_ind)); if (dev->enabled) rs780_gpp_sb_init(nb_dev, dev, dev_ind); - /* Dont call disable_pcie_bar3(nb_dev) here, otherwise the screen will crash. */ + + if (dev_ind == 10) disable_pcie_bar3(nb_dev); break; default: printk(BIOS_DEBUG, "unknown dev: %s\n", dev_path(dev));
Modified: trunk/src/southbridge/amd/rs780/rs780.h ============================================================================== --- trunk/src/southbridge/amd/rs780/rs780.h Tue Nov 23 08:30:50 2010 (r6119) +++ trunk/src/southbridge/amd/rs780/rs780.h Wed Nov 24 01:39:44 2010 (r6120) @@ -208,4 +208,9 @@ void config_gpp_core(device_t nb_dev, device_t sb_dev); void PcieReleasePortTraining(device_t nb_dev, device_t dev, u32 port); u8 PcieTrainPort(device_t nb_dev, device_t dev, u32 port); +u32 extractbit(u32 data, int bit_number); +u32 extractbits(u32 source, int lsb, int msb); +int cpuidFamily(void); +int is_family0Fh(void); +int is_family10h(void); #endif /* RS780_H */
Modified: trunk/src/southbridge/amd/rs780/rs780_cmn.c ============================================================================== --- trunk/src/southbridge/amd/rs780/rs780_cmn.c Tue Nov 23 08:30:50 2010 (r6119) +++ trunk/src/southbridge/amd/rs780/rs780_cmn.c Wed Nov 24 01:39:44 2010 (r6120) @@ -29,6 +29,7 @@ #include <cpu/amd/mtrr.h> #include <boot/coreboot_tables.h> #include <delay.h> +#include <cpu/cpu.h> #include "rs780.h"
static u32 nb_read_index(device_t dev, u32 index_reg, u32 index) @@ -361,3 +362,42 @@ pci_write_config32(nb_dev, 0x90, uma_memory_base); //nbmc_write_index(nb_dev, 0x1e, uma_memory_base); } + +// extract single bit +u32 extractbit(u32 data, int bit_number) +{ + return (data >> bit_number) & 1; +} + +// extract bit field +u32 extractbits(u32 source, int lsb, int msb) +{ + int field_width = msb - lsb + 1; + u32 mask = 0xFFFFFFFF >> (32 - field_width); + return (source >> lsb) & mask; +} + +// return AMD cpuid family +int cpuidFamily(void) +{ + u32 baseFamily, extendedFamily, fms; + + fms = cpuid_eax (1); + baseFamily = extractbits (fms, 8, 11); + extendedFamily = extractbits (fms, 20, 27); + return baseFamily + extendedFamily; +} + + +// return non-zero for AMD family 0Fh processor found +int is_family0Fh(void) +{ + return cpuidFamily() == 0x0F; +} + + +// return non-zero for AMD family 10h processor found +int is_family10h(void) +{ + return cpuidFamily() == 0x10; +}
Modified: trunk/src/southbridge/amd/rs780/rs780_early_setup.c ============================================================================== --- trunk/src/southbridge/amd/rs780/rs780_early_setup.c Tue Nov 23 08:30:50 2010 (r6119) +++ trunk/src/southbridge/amd/rs780/rs780_early_setup.c Wed Nov 24 01:39:44 2010 (r6120) @@ -483,9 +483,11 @@ /* Reg94h[31:29] = 0x7 Enables HT transmitter de-emphasis */ set_nbcfg_enable_bits_8(nb_dev, 0x97, (u8)(~0x1F), 0xE0);
- /*Reg8Ch[10:9] = 0x3 Enables Gfx Debug BAR, - * force this BAR as mem type in rs780_gfx.c */ - set_nbcfg_enable_bits_8(nb_dev, 0x8D, (u8)(~0xFF), 0x03); + /* Reg8Ch[9] enables Gfx Debug BAR programming + * Reg8Ch[10] enables Gfx Debug BAR operation + * Enable programming of the debug bar now, but enable + * operation only after it has been programmed */ + set_nbcfg_enable_bits_8(nb_dev, 0x8D, (u8)(~0xFF), 0x02); }
static void rs780_por_mc_index_init(device_t nb_dev)
Modified: trunk/src/southbridge/amd/rs780/rs780_gfx.c ============================================================================== --- trunk/src/southbridge/amd/rs780/rs780_gfx.c Tue Nov 23 08:30:50 2010 (r6119) +++ trunk/src/southbridge/amd/rs780/rs780_gfx.c Wed Nov 24 01:39:44 2010 (r6120) @@ -39,6 +39,8 @@ void set_pcie_reset(void); void set_pcie_dereset(void);
+extern uint64_t uma_memory_base, uma_memory_size; + /* Trust the original resource allocation. Don't do it again. */ #undef DONT_TRUST_RESOURCE_ALLOCATION //#define DONT_TRUST_RESOURCE_ALLOCATION @@ -304,11 +306,15 @@ volatile u32 * pointer; int i; u16 command; - u32 value, sblk; + u32 value; u16 deviceid, vendorid; device_t nb_dev = dev_find_slot(0, 0); device_t k8_f2 = dev_find_slot(0, PCI_DEVFN(0x18, 2)); device_t k8_f0 = dev_find_slot(0, PCI_DEVFN(0x18, 0)); + static const u8 ht_freq_lookup [] = {2, 0, 4, 0, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 0, 0, 28, 30, 32}; + static const u8 ht_width_lookup [] = {8, 16, 0, 0, 2, 4, 0, 0}; + static const u16 memclk_lookup_fam0F [] = {100, 0, 133, 0, 0, 166, 0, 200}; + static const u16 memclk_lookup_fam10 [] = {200, 266, 333, 400, 533, 667, 800, 800};
/* We definetely will use this in future. Just leave it here. */ /*struct southbridge_amd_rs780_config *cfg = @@ -339,6 +345,8 @@ *(GpuF0MMReg + 0x2180/4) = ((value&0xff00)>>8)|((value&0xff000000)>>8); *(GpuF0MMReg + 0x2c04/4) = ((value&0xff00)<<8); *(GpuF0MMReg + 0x5428/4) = ((value&0xffff0000)+0x10000)-((value&0xffff)<<16); + *(GpuF0MMReg + 0xF774/4) = 0xffffffff; + *(GpuF0MMReg + 0xF770/4) = 0x00000001; *(GpuF0MMReg + 0x2000/4) = 0x00000011; *(GpuF0MMReg + 0x200c/4) = 0x00000020; *(GpuF0MMReg + 0x2010/4) = 0x10204810; @@ -352,21 +360,28 @@ *(GpuF0MMReg + 0x7de4/4) |= (1<<3) | (1<<4); /* Force allow LDT_STOP Cool'n'Quiet workaround. */ *(GpuF0MMReg + 0x655c/4) |= 1<<4; + + // disable write combining, needed for stability + // reference bios does this only for RS780 rev A11 + // need to figure out why we need it for all revs + *(GpuF0MMReg + 0x2000/4) = 0x00000010; + *(GpuF0MMReg + 0x2408/4) = 1 << 9; + *(GpuF0MMReg + 0x2000/4) = 0x00000011; + /* GFX_InitFBAccess finished. */
- /* GFX_StartMC. */ #if (CONFIG_GFXUMA == 1) /* for UMA mode. */ - /* MC_INIT_COMPLETE. */ - set_nbmc_enable_bits(nb_dev, 0x2, 0, 1<<31); - /* MC_STARTUP, MC_POWERED_UP and MC_VMODE.*/ - set_nbmc_enable_bits(nb_dev, 0x1, 1<<18, 1|1<<2); - - set_nbmc_enable_bits(nb_dev, 0xb1, 0, 1<<6); - set_nbmc_enable_bits(nb_dev, 0xc3, 0, 1); - nbmc_write_index(nb_dev, 0x07, 0x18); - nbmc_write_index(nb_dev, 0x06, 0x00000102); - nbmc_write_index(nb_dev, 0x09, 0x40000008); - set_nbmc_enable_bits(nb_dev, 0x6, 0, 1<<31); + /* GFX_StartMC. */ + set_nbmc_enable_bits(nb_dev, 0x02, 0x00000000, 0x80000000); + set_nbmc_enable_bits(nb_dev, 0x01, 0x00000000, 0x00000001); + set_nbmc_enable_bits(nb_dev, 0x01, 0x00000000, 0x00000004); + set_nbmc_enable_bits(nb_dev, 0x01, 0x00040000, 0x00000000); + set_nbmc_enable_bits(nb_dev, 0xB1, 0xFFFF0000, 0x00000040); + set_nbmc_enable_bits(nb_dev, 0xC3, 0x00000000, 0x00000001); + set_nbmc_enable_bits(nb_dev, 0x07, 0xFFFFFFFF, 0x00000018); + set_nbmc_enable_bits(nb_dev, 0x06, 0xFFFFFFFF, 0x00000102); + set_nbmc_enable_bits(nb_dev, 0x09, 0xFFFFFFFF, 0x40000008); + set_nbmc_enable_bits(nb_dev, 0x06, 0x00000000, 0x80000000); /* GFX_StartMC finished. */ #else /* for SP mode. */ @@ -418,77 +433,110 @@ vgainfo.sHeader.ucTableContentRevision = 2;
#if (CONFIG_GFXUMA == 0) /* SP mode. */ + // Side port support is incomplete, do not use it + // These parameters must match the motherboard vgainfo.ulBootUpSidePortClock = 667*100; - vgainfo.ucMemoryType = 3; + vgainfo.ucMemoryType = 3; // 3=ddr3 sp mem, 2=ddr2 sp mem vgainfo.ulMinSidePortClock = 333*100; #endif
- vgainfo.ulBootUpEngineClock = 500 * 100; /* set boot up GFX engine clock. */ - vgainfo.ulReserved1[0] = 0; vgainfo.ulReserved1[1] = 0; - value = pci_read_config32(k8_f2, 0x94); - printk(BIOS_DEBUG, "MEMCLK = %x\n", value&0x7); - vgainfo.ulBootUpUMAClock = 333 * 100; /* set boot up UMA memory clock. */ - vgainfo.ulBootUpSidePortClock = 0; /* disable SP. */ - vgainfo.ulMinSidePortClock = 0; /* disable SP. */ - for(i=0; i<6; i++) - vgainfo.ulReserved2[i] = 0; - vgainfo.ulSystemConfig = 0; - //vgainfo.ulSystemConfig |= 1<<1 | 1<<3 | 1<<4 | 1<<5 | 1<<6 | 1<<7 | 1; - vgainfo.ulBootUpReqDisplayVector = 0; //? - vgainfo.ulOtherDisplayMisc = 0; //? - vgainfo.ulDDISlot1Config = 0x000c0011; //0; //VGA - //vgainfo.ulDDISlot1Config = 0x000c00FF; //0; //HDMI - vgainfo.ulDDISlot2Config = 0x00130022; //0; //? - vgainfo.ucMemoryType = 2; + vgainfo.ulBootUpEngineClock = 500 * 100; // setup option on reference BIOS, 500 is default + + // find the DDR memory frequency + if (is_family10h()) { + value = pci_read_config32(k8_f2, 0x94); // read channel 0 DRAM Configuration High Register + if (extractbit(value, 14)) // if channel 0 disabled, channel 1 must have memory + value = pci_read_config32(k8_f2, 0x194);// read channel 1 DRAM Configuration High Register + vgainfo.ulBootUpUMAClock = memclk_lookup_fam10 [extractbits (value, 0, 2)] * 100; + } + if (is_family0Fh()) { + value = pci_read_config32(k8_f2, 0x94); + vgainfo.ulBootUpUMAClock = memclk_lookup_fam0F [extractbits (value, 20, 22)] * 100; + } + /* UMA Channel Number: 1 or 2. */ - vgainfo.ucUMAChannelNumber = 2; - vgainfo.ucDockingPinBit = 0; //? - vgainfo.ucDockingPinPolarity = 0; //? - vgainfo.ulDockingPinCFGInfo = 0; //? - vgainfo.ulCPUCapInfo = 3; /* K8. */ - - /* page 5-19 on BDG. */ - vgainfo.usNumberOfCyclesInPeriod = 0x8019; - vgainfo.usMaxNBVoltage = 0x1a; - vgainfo.usMinNBVoltage = 0; - vgainfo.usBootUpNBVoltage = 0x1a; - - /* Get SBLink value (HyperTransport I/O Hub Link ID). */ - value = pci_read_config32(k8_f0, 0x64); - sblk = (value >> 8) & 0x3; - printk(BIOS_DEBUG, "SBLINK = %d.\n", sblk); + vgainfo.ucUMAChannelNumber = 1; + if (is_family0Fh()) { + value = pci_read_config32(k8_f2, 0x90); + if (extractbit(value, 11)) // 128-bit mode + vgainfo.ucUMAChannelNumber = 2; + } + if (is_family10h()) { + u32 dch0 = pci_read_config32(k8_f2, 0x94); + u32 dch1 = pci_read_config32(k8_f2, 0x194); + if (extractbit(dch0, 14) == 0 && extractbit(dch1, 14) == 0) { // both channels enabled + value = pci_read_config32(k8_f2, 0x110); + if (extractbit(value, 4)) // ganged mode + vgainfo.ucUMAChannelNumber = 2; + } + } + + // processor type + if (is_family0Fh()) + vgainfo.ulCPUCapInfo = 3; + if (is_family10h()) + vgainfo.ulCPUCapInfo = 2;
/* HT speed */ - value = pci_read_config32(nb_dev, 0xd0); - printk(BIOS_DEBUG, "NB HT speed = %x.\n", value); - value = pci_read_config32(k8_f0, 0x88 + (sblk * 0x20)); - printk(BIOS_DEBUG, "CPU HT speed = %x.\n", value); - vgainfo.ulHTLinkFreq = 100 * 100; /* set HT speed. */ + value = pci_read_config8(nb_dev, 0xd1); + value = ht_freq_lookup [value] * 100; // HT link frequency in MHz + vgainfo.ulHTLinkFreq = value * 100; // HT frequency in units of 100 MHz + vgainfo.ulHighVoltageHTLinkFreq = vgainfo.ulHTLinkFreq; + vgainfo.ulLowVoltageHTLinkFreq = vgainfo.ulHTLinkFreq; + + if (value <= 1800) + vgainfo.ulLowVoltageHTLinkFreq = vgainfo.ulHTLinkFreq; + else { + int sblink, cpuLnkFreqCap, nbLnkFreqCap; + value = pci_read_config32(k8_f0, 0x64); + sblink = extractbits(value, 8, 10); + cpuLnkFreqCap = pci_read_config16(k8_f0, 0x8a + sblink * 0x20); + nbLnkFreqCap = pci_read_config16(nb_dev, 0xd2); + if (cpuLnkFreqCap & nbLnkFreqCap & (1 << 10)) // if both 1800 MHz capable + vgainfo.ulLowVoltageHTLinkFreq = 1800*100; + }
/* HT width. */ - value = pci_read_config32(nb_dev, 0xc8); - printk(BIOS_DEBUG, "HT width = %x.\n", value); - vgainfo.usMinHTLinkWidth = 16; - vgainfo.usMaxHTLinkWidth = 16; - vgainfo.usUMASyncStartDelay = 322; - vgainfo.usUMADataReturnTime = 86; - vgainfo.usLinkStatusZeroTime = 0x00c8; //0; //? - vgainfo.usReserved = 0; - vgainfo.ulHighVoltageHTLinkFreq = 100 * 100; - vgainfo.ulLowVoltageHTLinkFreq = 100 * 100; - vgainfo.usMaxUpStreamHTLinkWidth = 16; - vgainfo.usMaxDownStreamHTLinkWidth = 16; - vgainfo.usMinUpStreamHTLinkWidth = 16; - vgainfo.usMinDownStreamHTLinkWidth = 16; - for(i=0; i<97; i++) - vgainfo.ulReserved3[i] = 0; + value = pci_read_config8(nb_dev, 0xcb); + vgainfo.usMinDownStreamHTLinkWidth = + vgainfo.usMaxDownStreamHTLinkWidth = + vgainfo.usMinUpStreamHTLinkWidth = + vgainfo.usMaxUpStreamHTLinkWidth = + vgainfo.usMinHTLinkWidth = + vgainfo.usMaxHTLinkWidth = ht_width_lookup [extractbits(value, 0, 2)]; + + if (is_family0Fh()) { + vgainfo.usUMASyncStartDelay = 322; + vgainfo.usUMADataReturnTime = 286; + } + + if (is_family10h()) { + static u16 t0mult_lookup [] = {10, 50, 200, 2000}; + int t0time, t0scale; + value = pci_read_config32(k8_f0, 0x16c); + t0time = extractbits(value, 0, 3); + t0scale = extractbits(value, 4, 5); + vgainfo.usLinkStatusZeroTime = t0mult_lookup [t0scale] * t0time; + vgainfo.usUMASyncStartDelay = 100; + if (vgainfo.ulHTLinkFreq < 1000 * 100) { // less than 1000 MHz + vgainfo.usUMADataReturnTime = 300; + vgainfo.usLinkStatusZeroTime = 6 * 100; // 6us for GH in HT1 mode + } + else { + int lssel; + value = pci_read_config32(nb_dev, 0xac); + lssel = extractbits (value, 7, 8); + vgainfo.usUMADataReturnTime = 1300; + if (lssel == 0) vgainfo.usUMADataReturnTime = 150; + } + }
/* Transfer the Table to VBIOS. */ pointer = (u32 *)&vgainfo; for(i=0; i<sizeof(ATOM_INTEGRATED_SYSTEM_INFO_V2); i+=4) { #if (CONFIG_GFXUMA == 1) - *GpuF0MMReg = 0x80000000 + 0x10000000 - 512 + i; + *GpuF0MMReg = 0x80000000 + uma_memory_size - 512 + i; #else *GpuF0MMReg = 0x80000000 + 0x8000000 - 512 + i; #endif @@ -497,11 +545,22 @@
/* GFX_InitLate. */ { - u8 temp8; - temp8 = pci_read_config8(dev, 0x4); - //temp8 &= ~1; /* CIM clears this bit. Strangely, I can'd. */ - temp8 |= 1<<1|1<<2; - pci_write_config8(dev, 0x4, temp8); + u32 temp; + temp = pci_read_config8(dev, 0x4); + //temp &= ~1; /* CIM clears this bit. Strangely, I can'd. */ + temp |= 1<<1|1<<2; + pci_write_config8(dev, 0x4, temp); + + // if the GFX debug bar is writable, then it has + // been programmed and can be safely enabled now + temp = pci_read_config32(nb_dev, 0x8c); + + // if bits 1 (intgfx_enable) and 9 (gfx_debug_bar_enable) + // then enable gfx debug bar (set gxf_debug_decode_enable) + if (temp & 0x202) + temp |= (1 << 10); + pci_write_config32(nb_dev, 0x8c, temp); + }
#ifdef DONT_TRUST_RESOURCE_ALLOCATION @@ -584,7 +643,6 @@ * Set registers in RS780 and CPU to enable the internal GFX. * Please refer to CIM source code and BKDG. */ -extern uint64_t uma_memory_base, uma_memory_size;
static void rs780_internal_gfx_enable(device_t dev) { @@ -637,7 +695,9 @@ #if (CONFIG_GFXUMA == 1) /* GFX_InitUMA. */ /* Copy CPU DDR Controller to NB MC. */ + device_t k8_f1 = dev_find_slot(0, PCI_DEVFN(0x18, 1)); device_t k8_f2 = dev_find_slot(0, PCI_DEVFN(0x18, 2)); + device_t k8_f4 = dev_find_slot(0, PCI_DEVFN(0x18, 4)); for (i = 0; i < 12; i++) { l_dword = pci_read_config32(k8_f2, 0x40 + i * 4); @@ -646,23 +706,39 @@
l_dword = pci_read_config32(k8_f2, 0x80); nbmc_write_index(nb_dev, 0x3c, l_dword); - l_dword = pci_read_config32(k8_f2, 0x94); - if(l_dword & (1<<22)) - set_nbmc_enable_bits(nb_dev, 0x3c, 0, 1<<16); - else - set_nbmc_enable_bits(nb_dev, 0x3c, 1<<16, 0); - - if(l_dword & (1<<8)) - set_nbmc_enable_bits(nb_dev, 0x3c, 0, 1<<17); - else - set_nbmc_enable_bits(nb_dev, 0x3c, 1<<17, 0); - + set_nbmc_enable_bits(nb_dev, 0x3c, 0, !!(l_dword & (1<<22))<<16); + set_nbmc_enable_bits(nb_dev, 0x3c, 0, !!(l_dword & (1<< 8))<<17); l_dword = pci_read_config32(k8_f2, 0x90); - if(l_dword & (1<<10)) - set_nbmc_enable_bits(nb_dev, 0x3c, 0, 1<<18); - else - set_nbmc_enable_bits(nb_dev, 0x3c, 1<<18, 0); + set_nbmc_enable_bits(nb_dev, 0x3c, 0, !!(l_dword & (1<<10))<<18); + if (is_family10h()) + { + for (i = 0; i < 12; i++) + { + l_dword = pci_read_config32(k8_f2, 0x140 + i * 4); + nbmc_write_index(nb_dev, 0x3d + i, l_dword); + } + + l_dword = pci_read_config32(k8_f2, 0x180); + nbmc_write_index(nb_dev, 0x49, l_dword); + l_dword = pci_read_config32(k8_f2, 0x194); + set_nbmc_enable_bits(nb_dev, 0x49, 0, !!(l_dword & (1<<22))<<16); + set_nbmc_enable_bits(nb_dev, 0x49, 0, !!(l_dword & (1<< 8))<<17); + l_dword = pci_read_config32(k8_f2, 0x190); + set_nbmc_enable_bits(nb_dev, 0x49, 0, !!(l_dword & (1<<10))<<18); + + l_dword = pci_read_config32(k8_f2, 0x110); + nbmc_write_index(nb_dev, 0x4a, l_dword); + l_dword = pci_read_config32(k8_f2, 0x114); + nbmc_write_index(nb_dev, 0x4b, l_dword); + l_dword = pci_read_config32(k8_f4, 0x44); + set_nbmc_enable_bits(nb_dev, 0x4a, 0, !!(l_dword & (1<<22))<<24); + l_dword = pci_read_config32(k8_f1, 0x40); + nbmc_write_index(nb_dev, 0x4c, l_dword); + l_dword = pci_read_config32(k8_f1, 0xf0); + nbmc_write_index(nb_dev, 0x4d, l_dword); + } +
/* Set UMA in the 780 side. */ /* UMA start address, size. */ @@ -672,7 +748,7 @@ nbmc_write_index(nb_dev, 0x10, ((uma_memory_size - 1 + 0xC0000000) & (~0xffff)) | 0xc000); nbmc_write_index(nb_dev, 0x11, uma_memory_base); nbmc_write_index(nb_dev, 0x12, 0); - nbmc_write_index(nb_dev, 0xf0, 256); + nbmc_write_index(nb_dev, 0xf0, uma_memory_size >> 20); /* GFX_InitUMA finished. */ #else /* GFX_InitSP. */ @@ -1016,7 +1092,7 @@ /* 5.9.1.1. Disables the GFX REFCLK transmitter so that the GFX * REFCLK PAD can be driven by an external source. */ /* 5.9.1.2. Enables GFX REFCLK receiver to receive the REFCLK from an external source. */ - set_nbmisc_enable_bits(nb_dev, 0x38, 1 << 29 | 1 << 28, 0 << 29 | 1 << 28); + set_nbmisc_enable_bits(nb_dev, 0x38, 1 << 29 | 1 << 28 | 1 << 26, 1 << 28);
/* 5.9.1.3 Selects the GFX REFCLK to be the source for PLL A. */ /* 5.9.1.4 Selects the GFX REFCLK to be the source for PLL B. */
Modified: trunk/src/southbridge/amd/rs780/rs780_pcie.c ============================================================================== --- trunk/src/southbridge/amd/rs780/rs780_pcie.c Tue Nov 23 08:30:50 2010 (r6119) +++ trunk/src/southbridge/amd/rs780/rs780_pcie.c Wed Nov 24 01:39:44 2010 (r6120) @@ -221,6 +221,7 @@ printk(BIOS_DEBUG, "disable_pcie_bar3()\n"); pci_write_config32(nb_dev, 0x1C, 0); /* clear BAR3 address */ set_nbcfg_enable_bits(nb_dev, 0x7C, 1 << 30, 0 << 30); /* Disable writes to the BAR3. */ + set_htiu_enable_bits(nb_dev, 0x32, 1 << 28, 0); /* disable bar3 decode */ ProgK8TempMmioBase(0, EXT_CONF_BASE_ADDRESS, TEMP_MMIO_BASE_ADDRESS); }