This patch solves crashes and BSODs that occur when booting Win7 with
authorScott Duplichan <scott@notabs.org>
Wed, 24 Nov 2010 00:39:44 +0000 (00:39 +0000)
committerScott Duplichan <scott@notabs.org>
Wed, 24 Nov 2010 00:39:44 +0000 (00:39 +0000)
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>
git-svn-id: svn://svn.coreboot.org/coreboot/trunk@6120 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1

src/southbridge/amd/rs780/rs780.c
src/southbridge/amd/rs780/rs780.h
src/southbridge/amd/rs780/rs780_cmn.c
src/southbridge/amd/rs780/rs780_early_setup.c
src/southbridge/amd/rs780/rs780_gfx.c
src/southbridge/amd/rs780/rs780_pcie.c

index 3d23a453cd9223ff2dba514dc9308a338784a485..d8f1be3dbe74fc17a5472b0814df31624f1e9b1e 100644 (file)
@@ -133,11 +133,6 @@ static void rs780_nb_pci_table(device_t nb_dev)
        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_pci_table(device_t nb_dev)
 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 @@ static void rs780_nb_gfx_dev_table(device_t nb_dev, device_t dev)
        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 @@ static void rs780_nb_gfx_dev_table(device_t nb_dev, device_t dev)
        /* 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 @@ static void rs780_nb_gfx_dev_table(device_t nb_dev, device_t dev)
 
        /* 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 @@ void rs780_enable(device_t dev)
                                       (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 7939303fe17cf4400397426ba333a5d90fb9217b..c91a4b30228b5b05de2c5b13a8294dbe697509a9 100644 (file)
@@ -208,4 +208,9 @@ void avoid_lpc_dma_deadlock(device_t nb_dev, device_t sb_dev);
 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 8d80a061182c40650fa9f9c10f61d92985feb8d3..4bd870bbf2ee5516cb0c3b5bbc5772a9f418278b 100644 (file)
@@ -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 @@ void rs780_set_tom(device_t nb_dev)
        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 236d95fef9b1259eb14c65a9718bb49635ff1400..57a7b62427aa2ee7ee7a37e76303254fceded5d3 100644 (file)
@@ -483,9 +483,11 @@ static void rs780_por_pcicfg_init(device_t nb_dev)
        /* 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 a9801a17cd4283c6fbb95e3dda7c56d18ba190ca..c2a220cf1958c6d88dcdc7716f856a1325668901 100644 (file)
@@ -39,6 +39,8 @@ extern int is_dev3_present(void);
 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 @@ static void internal_gfx_pci_dev_init(struct device *dev)
        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 @@ static void internal_gfx_pci_dev_init(struct device *dev)
        *(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 @@ static void internal_gfx_pci_dev_init(struct device *dev)
        *(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\r
+   // reference bios does this only for RS780 rev A11\r
+   // 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 @@ static void internal_gfx_pci_dev_init(struct device *dev)
        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 @@ static void internal_gfx_pci_dev_init(struct device *dev)
 
        /* 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 @@ static void internal_gfx_pci_dev_init(struct device *dev)
 * 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 @@ static void rs780_internal_gfx_enable(device_t dev)
 #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 @@ static void rs780_internal_gfx_enable(device_t dev)
 
        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 @@ static void rs780_internal_gfx_enable(device_t dev)
        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 @@ void rs780_gfx_init(device_t nb_dev, device_t dev, u32 port)
        /* 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 c705614bf0fff2fbac1d476a83f3c5d759239dfc..9cbd83266135acd36295e78bb0edbe07aacba3b6 100644 (file)
@@ -221,6 +221,7 @@ void disable_pcie_bar3(device_t nb_dev)
        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);
 }