(Re-submitting with correction to GFX debug bar setup procedure needed
for use with AMD family 0Fh processor).
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(a)notabs.org>
Index: src/southbridge/amd/rs780/rs780.c
===================================================================
--- src/southbridge/amd/rs780/rs780.c (revision 6011)
+++ src/southbridge/amd/rs780/rs780.c (working copy)
@@ -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));
Index: src/southbridge/amd/rs780/rs780.h
===================================================================
--- src/southbridge/amd/rs780/rs780.h (revision 6011)
+++ src/southbridge/amd/rs780/rs780.h (working copy)
@@ -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 */
Index: src/southbridge/amd/rs780/rs780_cmn.c
===================================================================
--- src/southbridge/amd/rs780/rs780_cmn.c (revision 6011)
+++ src/southbridge/amd/rs780/rs780_cmn.c (working copy)
@@ -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)
@@ -223,7 +224,7 @@
pci_write_config32(k8_f1, 0xbc, 0);
pci_write_config32(k8_f1, 0xb0, 0);
pci_write_config32(k8_f1, 0xb4, 0);
- }
+ }
}
void PcieReleasePortTraining(device_t nb_dev, device_t dev, u32 port)
@@ -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;
+}
Index: src/southbridge/amd/rs780/rs780_early_setup.c
===================================================================
--- src/southbridge/amd/rs780/rs780_early_setup.c (revision 6011)
+++ src/southbridge/amd/rs780/rs780_early_setup.c (working copy)
@@ -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)
Index: src/southbridge/amd/rs780/rs780_gfx.c
===================================================================
--- src/southbridge/amd/rs780/rs780_gfx.c (revision 6011)
+++ src/southbridge/amd/rs780/rs780_gfx.c (working copy)
@@ -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 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 u8 ht_width_lookup [] = {8, 16, 0, 0, 2, 4, 0, 0};
+ static u16 memclk_lookup_fam0F [] = {100, 0, 133, 0, 0, 166, 0, 200};
+ static 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,26 @@
*(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
+ *(GpuF0MMReg + 0x2000/4) = 0x00000010;
+ *(GpuF0MMReg + 0x2408/4) = 1 << 9;
+ *(GpuF0MMReg + 0x2000/4) = 0x00000011;
+
/* GFX_InitFBAccess finished. */
+#if (CONFIG_GFXUMA == 1) /* for UMA mode. */
/* 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);
+ 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 +431,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;
- /* UMA Channel Number: 1 or 2. */
- vgainfo.ucUMAChannelNumber = 2;
- vgainfo.ucDockingPinBit = 0; //?
- vgainfo.ucDockingPinPolarity = 0; //?
- vgainfo.ulDockingPinCFGInfo = 0; //?
- vgainfo.ulCPUCapInfo = 3; /* K8. */
+ vgainfo.ulBootUpEngineClock = 500 * 100; // setup option on reference BIOS, 500 is default
- /* page 5-19 on BDG. */
- vgainfo.usNumberOfCyclesInPeriod = 0x8019;
- vgainfo.usMaxNBVoltage = 0x1a;
- vgainfo.usMinNBVoltage = 0;
- vgainfo.usBootUpNBVoltage = 0x1a;
+ // 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;
+ }
- /* 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);
+ /* UMA Channel Number: 1 or 2. */
+ 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 +543,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 +641,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 +693,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,24 +704,40 @@
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);
+ 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);
+ 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);
+ }
- 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);
+ 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, 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);
+ 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. */
/* The UMA starts at 0xC0000000 of internal RS780 address space
@@ -672,7 +746,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 +1090,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. */
Index: src/southbridge/amd/rs780/rs780_pcie.c
===================================================================
--- src/southbridge/amd/rs780/rs780_pcie.c (revision 6011)
+++ src/southbridge/amd/rs780/rs780_pcie.c (working copy)
@@ -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);
}