remove trailing whitespace
[coreboot.git] / src / northbridge / amd / amdk8 / misc_control.c
index fe797aa580e03ae6ed9d9d2ea18e99e217fb996d..7ba2b90406b8462b32030f2842fbadf29d4eaf9b 100644 (file)
@@ -1,10 +1,10 @@
 /* Turn off machine check triggers when reading
- * pci space where there are no devices.
- * This is necessary when scaning the bus for
+ * PCI space where there are no devices.
+ * This is necessary when scanning the bus for
  * devices which is done by the kernel
  *
  * written in 2003 by Eric Biederman
- * 
+ *
  *  - Athlon64 workarounds by Stefan Reinauer
  *  - "reset once" logic by Yinghai Lu
  */
 #include <device/pci.h>
 #include <device/pci_ids.h>
 #include <device/pci_ops.h>
-#include "./cpu_rev.c"
+#include <reset.h>
+#include <pc80/mc146818rtc.h>
+#include <bitops.h>
+#include <cpu/amd/model_fxx_rev.h>
+
+#include "amdk8.h"
+
+/**
+ * @brief Read resources for AGP aperture
+ *
+ * @param
+ *
+ * There is only one AGP aperture resource needed. The resource is added to
+ * the northbridge of BSP.
+ *
+ * The same trick can be used to augment legacy VGA resources which can
+ * be detect by generic PCI resource allocator for VGA devices.
+ * BAD: it is more tricky than I think, the resource allocation code is
+ * implemented in a way to NOT DOING legacy VGA resource allocation on
+ * purpose :-(.
+ */
+static void mcf3_read_resources(device_t dev)
+{
+       struct resource *resource;
+       unsigned char iommu;
+       /* Read the generic PCI resources */
+       pci_dev_read_resources(dev);
+
+       /* If we are not the first processor don't allocate the GART aperture */
+       if (dev->path.pci.devfn != PCI_DEVFN(0x18, 3)) {
+               return;
+       }
+
+       iommu = 1;
+       if( get_option(&iommu, "iommu") < 0 )
+       {
+               iommu = CONFIG_IOMMU;
+       }
+
+       if (iommu) {
+               /* Add a GART aperture resource */
+               resource = new_resource(dev, 0x94);
+               resource->size = CONFIG_AGP_APERTURE_SIZE;
+               resource->align = log2(resource->size);
+               resource->gran  = log2(resource->size);
+               resource->limit = 0xffffffff; /* 4G */
+               resource->flags = IORESOURCE_MEM;
+       }
+}
+
+static void set_agp_aperture(device_t dev)
+{
+       struct resource *resource;
+
+       resource = probe_resource(dev, 0x94);
+       if (resource) {
+               device_t pdev;
+               uint32_t gart_base, gart_acr;
+
+               /* Remember this resource has been stored */
+               resource->flags |= IORESOURCE_STORED;
+
+               /* Find the size of the GART aperture */
+               gart_acr = (0<<6)|(0<<5)|(0<<4)|((resource->gran - 25) << 1)|(0<<0);
+
+               /* Get the base address */
+               gart_base = ((resource->base) >> 25) & 0x00007fff;
+
+               /* Update the other northbridges */
+               pdev = 0;
+               while((pdev = dev_find_device(PCI_VENDOR_ID_AMD, 0x1103, pdev))) {
+                       /* Store the GART size but don't enable it */
+                       pci_write_config32(pdev, 0x90, gart_acr);
+
+                       /* Store the GART base address */
+                       pci_write_config32(pdev, 0x94, gart_base);
+
+                       /* Don't set the GART Table base address */
+                       pci_write_config32(pdev, 0x98, 0);
+
+                       /* Report the resource has been stored... */
+                       report_resource_stored(pdev, resource, " <gart>");
+               }
+       }
+}
+
+static void mcf3_set_resources(device_t dev)
+{
+       /* Set the gart apeture */
+       set_agp_aperture(dev);
+
+       /* Set the generic PCI resources */
+       pci_dev_set_resources(dev);
+}
 
-static cpu_reset_count = 0;
 static void misc_control_init(struct device *dev)
 {
-       uint32_t cmd;
-       
-       printk_debug("NB: Function 3 Misc Control.. ");
-       
-       /* disable error reporting */
+       uint32_t cmd, cmd_ref;
+       int needs_reset;
+       struct device *f0_dev;
+
+       printk(BIOS_DEBUG, "NB: Function 3 Misc Control.. ");
+       needs_reset = 0;
+
+       /* Disable Machine checks from Invalid Locations.
+        * This is needed for PC backwards compatibility.
+        */
        cmd = pci_read_config32(dev, 0x44);
        cmd |= (1<<6) | (1<<25);
        pci_write_config32(dev, 0x44, cmd );
+#if CONFIG_K8_REV_F_SUPPORT == 0
        if (is_cpu_pre_c0()) {
-               /* errata 58 */
+
+               /* Errata 58
+                * Disable CPU low power states C2, C1 and throttling
+                */
                cmd = pci_read_config32(dev, 0x80);
                cmd &= ~(1<<0);
                pci_write_config32(dev, 0x80, cmd );
@@ -36,70 +137,99 @@ static void misc_control_init(struct device *dev)
                cmd &= ~(1<<24);
                cmd &= ~(1<<8);
                pci_write_config32(dev, 0x84, cmd );
-               /* errata 66 */
+
+               /* Errata 66
+                * Limit the number of downstream posted requests to 1
+                */
                cmd = pci_read_config32(dev, 0x70);
-               cmd &= ~(1<<0);
-               cmd |= (1<<1);
-               pci_write_config32(dev, 0x70, cmd );
+               if ((cmd & (3 << 0)) != 2) {
+                       cmd &= ~(3<<0);
+                       cmd |= (2<<0);
+                       pci_write_config32(dev, 0x70, cmd );
+                       needs_reset = 1;
+               }
                cmd = pci_read_config32(dev, 0x7c);
-               cmd &= ~(3<<4);
-               pci_write_config32(dev, 0x7c, cmd );
-       }
-       else {
-               /* errata 98 */
-#if 0          
+               if ((cmd & (3 << 4)) != 0) {
+                       cmd &= ~(3<<4);
+                       cmd |= (0<<4);
+                       pci_write_config32(dev, 0x7c, cmd );
+                       needs_reset = 1;
+               }
+               /* Clock Power/Timing Low */
                cmd = pci_read_config32(dev, 0xd4);
-               if(cmd != 0x04e20707) {
-                       cmd = 0x04e20707;
-                       pci_write_config32(dev, 0xd4, cmd );
-                       hard_reset();
+               if (cmd != 0x000D0001) {
+                       cmd = 0x000D0001;
+                       pci_write_config32(dev, 0xd4, cmd);
+                       needs_reset = 1; /* Needed? */
                }
-#endif
-
-               cmd = 0x04e20707;
-               pci_write_config32(dev, 0xd4, cmd );
        }
-
-/*
- * FIXME: This preprocessor check is a mere workaround. 
- * The right fix is to walk over all links on all nodes
- * and set the FIFO read pointer optimization value to
- * 0x25 for each link connected to an AMD HT device.
- *
- * The reason this is only enabled for machines with more 
- * than one CPU is that Athlon64 machines don't have the
- * link at all that is optimized in the code.
- */
-
-#if CONFIG_MAX_CPUS > 1        
-#if HAVE_HARD_RESET==1
-       cpu_reset_count++;
-       cmd = pci_read_config32(dev, 0xdc);
-       if((cmd & 0x0000ff00) != 0x02500) {
-               cmd &= 0xffff00ff;
-               cmd |= 0x00002500;
-               pci_write_config32(dev, 0xdc, cmd );
-               if(cpu_reset_count==CONFIG_MAX_CPUS) {
-                       printk_debug("resetting cpu\n");
-                       hard_reset();
+       else if(is_cpu_pre_d0()) {
+               struct device *f2_dev;
+               uint32_t dcl;
+               f2_dev = dev_find_slot(0, dev->path.pci.devfn - 3 + 2);
+               /* Errata 98
+                * Set Clk Ramp Hystersis to 7
+                * Clock Power/Timing Low
+                */
+               cmd_ref = 0x04e20707; /* Registered */
+               dcl = pci_read_config32(f2_dev, DRAM_CONFIG_LOW);
+               if (dcl & DCL_UnBuffDimm) {
+                       cmd_ref = 0x000D0701; /* Unbuffered */
                }
-       } 
+               cmd = pci_read_config32(dev, 0xd4);
+               if(cmd != cmd_ref) {
+                       pci_write_config32(dev, 0xd4, cmd_ref );
+                       needs_reset = 1; /* Needed? */
+               }
+       }
 #endif
-#endif 
-       printk_debug("done.\n");
+       /* Optimize the Link read pointers */
+       f0_dev = dev_find_slot(0, dev->path.pci.devfn - 3);
+       if (f0_dev) {
+               int link;
+               cmd_ref = cmd = pci_read_config32(dev, 0xdc);
+               for(link = 0; link < 3; link++) {
+                       uint32_t link_type;
+                       unsigned reg;
+                       /* This works on an Athlon64 because unimplemented links return 0 */
+                       reg = 0x98 + (link * 0x20);
+                       link_type = pci_read_config32(f0_dev, reg);
+                       /* Only handle coherent link here please */
+                       if ((link_type & (LinkConnected|InitComplete|NonCoherent))
+                               == (LinkConnected|InitComplete))
+                       {
+                               cmd &= ~(0xff << (link *8));
+                               /* FIXME this assumes the device on the other side is an AMD device */
+                               cmd |= 0x25 << (link *8);
+                       }
+               }
+               if (cmd != cmd_ref) {
+                       pci_write_config32(dev, 0xdc, cmd);
+                       needs_reset = 1;
+               }
+       }
+       else {
+               printk(BIOS_ERR, "Missing f0 device!\n");
+       }
+       if (needs_reset) {
+               printk(BIOS_DEBUG, "resetting cpu\n");
+               hard_reset();
+       }
+       printk(BIOS_DEBUG, "done.\n");
 }
 
+
 static struct device_operations mcf3_ops  = {
-       .read_resources   = pci_dev_read_resources,
-       .set_resources    = pci_dev_set_resources,
+       .read_resources   = mcf3_read_resources,
+       .set_resources    = mcf3_set_resources,
        .enable_resources = pci_dev_enable_resources,
        .init             = misc_control_init,
        .scan_bus         = 0,
+       .ops_pci          = 0,
 };
 
-static struct pci_driver mcf3_driver __pci_driver = {
+static const struct pci_driver mcf3_driver __pci_driver = {
        .ops    = &mcf3_ops,
        .vendor = PCI_VENDOR_ID_AMD,
        .device = 0x1103,
 };
-