Author: uwe Date: 2007-07-08 02:19:26 +0200 (Sun, 08 Jul 2007) New Revision: 439
Modified: LinuxBIOSv3/northbridge/amd/geodelx/geodelx.c LinuxBIOSv3/northbridge/amd/geodelx/geodelxinit.c LinuxBIOSv3/northbridge/amd/geodelx/raminit.c Log: Even more coding style fixes and other cosmetic fixes (trivial).
Signed-off-by: Uwe Hermann uwe@hermann-uwe.de Acked-by: Uwe Hermann uwe@hermann-uwe.de
Modified: LinuxBIOSv3/northbridge/amd/geodelx/geodelx.c =================================================================== --- LinuxBIOSv3/northbridge/amd/geodelx/geodelx.c 2007-07-07 21:18:47 UTC (rev 438) +++ LinuxBIOSv3/northbridge/amd/geodelx/geodelx.c 2007-07-08 00:19:26 UTC (rev 439) @@ -30,54 +30,74 @@ #include <io.h> #include <amd_geodelx.h>
-/* here is programming for the various MSRs.*/ +/* Here is programming for the various MSRs. */ #define IM_QWAIT 0x100000
-/* set in high nibl */ -#define DMCF_WRITE_SERIALIZE_REQUEST (2<<12) /* 2 outstanding */ +/* Set in high nibble. */ +#define DMCF_WRITE_SERIALIZE_REQUEST (2 << 12) /* 2 outstanding */
-#define DMCF_SERIAL_LOAD_MISSES (2) /* enabled */ +#define DMCF_SERIAL_LOAD_MISSES 2 /* Enabled */
-/* these are the 8-bit attributes for controlling RCONF registers - * RCONF is Region CONFiguraiton, and controls caching and other - * attributes of a region. Just like MTRRs, only different. - */ -#define CACHE_DISABLE (1<<0) -#define WRITE_ALLOCATE (1<<1) -#define WRITE_PROTECT (1<<2) -#define WRITE_THROUGH (1<<3) -#define WRITE_COMBINE (1<<4) -#define WRITE_SERIALIZE (1<<5) +/* These are the 8-bit attributes for controlling RCONF registers. + * + * RCONF is Region CONFiguration, and controls caching and other + * attributes of a region. Just like MTRRs, only different. + */ +#define CACHE_DISABLE (1 << 0) +#define WRITE_ALLOCATE (1 << 1) +#define WRITE_PROTECT (1 << 2) +#define WRITE_THROUGH (1 << 3) +#define WRITE_COMBINE (1 << 4) +#define WRITE_SERIALIZE (1 << 5)
-/* ram has none of this stuff */ -#define RAM_PROPERTIES (0) -#define DEVICE_PROPERTIES (WRITE_SERIALIZE|CACHE_DISABLE) -#define ROM_PROPERTIES (WRITE_SERIALIZE|WRITE_PROTECT|CACHE_DISABLE) -#define MSR_WS_CD_DEFAULT (0x21212121) +/* RAM has none of this stuff. */ +#define RAM_PROPERTIES 0 +#define DEVICE_PROPERTIES (WRITE_SERIALIZE|CACHE_DISABLE) +#define ROM_PROPERTIES (WRITE_SERIALIZE|WRITE_PROTECT|CACHE_DISABLE) +#define MSR_WS_CD_DEFAULT 0x21212121
/* RCONF registers 1810-1817 give you 8 registers with which to * program protection regions the are region configuration range * registers, or RRCF in msr terms, the are a straight base, top * address assign, since they are 4k aligned. */ -/* so no left-shift needed for top or base */ -#define RRCF_LOW(base,properties) (base|(1<<8)|properties) -#define RRCF_LOW_CD(base) RRCF_LOW(base, CACHE_DISABLE) +/* So no left-shift needed for top or base. */ +#define RRCF_LOW(base, properties) (base | (1 << 8) | properties) +#define RRCF_LOW_CD(base) RRCF_LOW(base, CACHE_DISABLE)
-/* build initializer for P2D MSR */ -/* this is complex enough that you are going to need to RTFM if you - * really want to understand it. +/* Build initializer for P2D MSR. + * + * This is complex enough that you are going to need to RTFM if you + * really want to understand it. */ -#define P2D_BM(msr, pdid1, bizarro, pbase, pmask) {msr, {.hi=(pdid1<<29)|(bizarro<<28)|(pbase>>24), .lo=(pbase<<8)|pmask}} -#define P2D_BMO(msr, pdid1, bizarro, poffset, pbase, pmask) {msr, {.hi=(pdid1<<29)|(bizarro<<28)|(poffset<<8)|(pbase>>24), .lo=(pbase<<8)|pmask}} -#define P2D_R(msr, pdid1, bizarro, pmax, pmin) {msr, {.hi=(pdid1<<29)|(bizarro<<28)|(pmax>>12), .lo=(pmax<<20)|pmin}} -#define P2D_RO(msr, pdid1, bizarro, poffset, pmax, pmin) {msr, {.hi=(pdid1<<29)|(bizarro<<28)|(poffset<<8)|(pmax>>12), .lo=(pmax<<20)|pmin}} -#define P2D_SC(msr, pdid1, bizarro, wen, ren,pscbase) {msr, {.hi=(pdid1<<29)|(bizarro<<28)|(wen), .lo=(ren<<16)|(pscbase>>18)}} -#define IOD_BM(msr, pdid1, bizarro, ibase, imask) {msr, {.hi=(pdid1<<29)|(bizarro<<28)|(ibase>>12), .lo=(ibase<<20)|imask}} -#define IOD_SC(msr, pdid1, bizarro, en, wen, ren, ibase) {msr, {.hi=(pdid1<<29)|(bizarro<<28), .lo=(en<<24)|(wen<<21)|(ren<<20)|(ibase<<3)}} +#define P2D_BM(msr, pdid1, bizarro, pbase, pmask) \ + {msr, {.hi = (pdid1 << 29) | (bizarro << 28) | (pbase >> 24), \ + .lo = (pbase << 8) | pmask}} +#define P2D_BMO(msr, pdid1, bizarro, poffset, pbase, pmask) \ + {msr, {.hi = (pdid1 << 29) | (bizarro << 28) | \ + (poffset << 8) | (pbase >> 24), \ + .lo = (pbase << 8) | pmask}} +#define P2D_R(msr, pdid1, bizarro, pmax, pmin) \ + {msr, {.hi = (pdid1 << 29) | (bizarro << 28) | (pmax >> 12), \ + .lo = (pmax << 20) | pmin}} +#define P2D_RO(msr, pdid1, bizarro, poffset, pmax, pmin) \ + {msr, {.hi = (pdid1 << 29) | (bizarro << 28) | \ + (poffset << 8) | (pmax >> 12), \ + .lo = (pmax << 20) | pmin}} +#define P2D_SC(msr, pdid1, bizarro, wen, ren,pscbase) \ + {msr, {.hi = (pdid1 << 29) | (bizarro << 28) | (wen), \ + .lo = (ren << 16) | (pscbase >> 18)}} +#define IOD_BM(msr, pdid1, bizarro, ibase, imask) \ + {msr, {.hi = (pdid1 << 29) | (bizarro << 28) | (ibase >> 12), \ + .lo = (ibase << 20) | imask}} +#define IOD_SC(msr, pdid1, bizarro, en, wen, ren, ibase) \ + {msr, {.hi = (pdid1 << 29) | (bizarro << 28), \ + .lo = (en << 24) | (wen << 21) | \ + (ren << 20) | (ibase << 3)}}
#define BRIDGE_IO_MASK (IORESOURCE_IO | IORESOURCE_MEM)
+/* TODO: Should be in some header file? */ extern void graphics_init(void); extern void cpu_bug(void); extern void chipsetinit(void); @@ -90,195 +110,213 @@
struct msr_defaults { int msr_no; - struct msr msr; + struct msr msr; } msr_defaults[] = { - {0x1700, {.hi = 0,.lo = IM_QWAIT}}, - {0x1800, {.hi = DMCF_WRITE_SERIALIZE_REQUEST, - .lo = DMCF_SERIAL_LOAD_MISSES}}, + { 0x1700, {.hi = 0,.lo = IM_QWAIT}}, + { 0x1800, {.hi = DMCF_WRITE_SERIALIZE_REQUEST, + .lo = DMCF_SERIAL_LOAD_MISSES}}, + /* 1808 will be done down below, so we have to do 180a->1817 - * (well, 1813 really) + * (well, 1813 really). */ - /* for 180a, for now, we assume VSM will configure it */ - /* 180b is left at reset value,a0000-bffff is non-cacheable */ - /* 180c, c0000-dffff is set to write serialize and non-cachable */ - /* oops, 180c will be set by cpu bug handling in cpubug.c */ - //{0x180c, {.hi = MSR_WS_CD_DEFAULT, .lo = MSR_WS_CD_DEFAULT}}, - /* 180d is left at default, e0000-fffff is non-cached */ - /* we will assume 180e, the ssm region configuration, is left - * at default or set by VSM */ - /* we will not set 0x180f, the DMM,yet + /* For 180a, for now, we assume VSM will configure it. */ + /* 180b is left at reset value, a0000-bffff is non-cacheable. */ + /* 180c, c0000-dffff is set to write serialize and non-cachable. */ + /* Oops, 180c will be set by CPU bug handling in cpubug.c. */ + /* TODO: There's no cpubug.c. */ + // {0x180c, {.hi = MSR_WS_CD_DEFAULT, .lo = MSR_WS_CD_DEFAULT}}, + /* 180d is left at default, e0000-fffff is non-cached. */ + /* We will assume 180e, the ssm region configuration, is left + * at default or set by VSM. */ - //{0x1810, {.hi=0xee7ff000, .lo=RRCF_LOW(0xee000000, WRITE_COMBINE|CACHE_DISABLE)}}, - //{0x1811, {.hi = 0xefffb000, .lo = RRCF_LOW_CD(0xefff8000)}}, - //{0x1812, {.hi = 0xefff7000, .lo = RRCF_LOW_CD(0xefff4000)}}, - //{0x1813, {.hi = 0xefff3000, .lo = RRCF_LOW_CD(0xefff0000)}}, - /* now for GLPCI routing */ + /* We will not set 0x180f, the DMM, yet. */ + + // {0x1810, {.hi = 0xee7ff000, + // .lo = RRCF_LOW(0xee000000, WRITE_COMBINE|CACHE_DISABLE)}}, + // {0x1811, {.hi = 0xefffb000, .lo = RRCF_LOW_CD(0xefff8000)}}, + // {0x1812, {.hi = 0xefff7000, .lo = RRCF_LOW_CD(0xefff4000)}}, + // {0x1813, {.hi = 0xefff3000, .lo = RRCF_LOW_CD(0xefff0000)}}, + + /* Now for GLPCI routing. */ + /* GLIU0 */ - P2D_BM(MSR_GLIU0_BASE1, 0x1, 0x0, 0x0, 0xfff80), - P2D_BM(MSR_GLIU0_BASE2, 0x1, 0x0, 0x80000, 0xfffe0), + P2D_BM(MSR_GLIU0_BASE1, 0x1, 0x0, 0x0, 0xfff80), + P2D_BM(MSR_GLIU0_BASE2, 0x1, 0x0, 0x80000, 0xfffe0), P2D_SC(MSR_GLIU0_SHADOW, 0x1, 0x0, 0x0, 0xff03, 0xC0000), + /* GLIU1 */ - P2D_BM(MSR_GLIU1_BASE1, 0x1, 0x0, 0x0, 0xfff80), - P2D_BM(MSR_GLIU1_BASE2, 0x1, 0x0, 0x80000, 0xfffe0), - P2D_SC(MSR_GLIU1_SHADOW, 0x1, 0x0, 0x0, 0xff03, 0xC0000), - {0} + P2D_BM(MSR_GLIU1_BASE1, 0x1, 0x0, 0x0, 0xfff80), + P2D_BM(MSR_GLIU1_BASE2, 0x1, 0x0, 0x80000, 0xfffe0), + P2D_SC(MSR_GLIU1_SHADOW, 0x1, 0x0, 0x0, 0xff03, 0xC0000), + + {0}, };
-/** - * Size up ram. All we need to here is read the MSR for DRAM and grab - * out the sizing bits. Note that this code depends on initram - * having run. It uses the MSRs, not the SPDs, and the MSRs of course - * are set up by initram. - */ +/** + * Size up ram. + * + * All we need to do here is read the MSR for DRAM and grab out the sizing + * bits. Note that this code depends on initram having run. It uses the MSRs, + * not the SPDs, and the MSRs of course are set up by initram. + * + * @return TODO + */ int sizeram(void) { - struct msr msr; + struct msr msr; int sizem = 0; unsigned short dimm;
/* Get the RAM size from the memory controller as calculated - * and set by auto_size_dimm() + * and set by auto_size_dimm(). */ msr = rdmsr(MC_CF07_DATA); - printk(BIOS_DEBUG,"sizeram: _MSR MC_CF07_DATA: %08x:%08x\n", msr.hi, msr.lo); - - /* dimm 0 */ + printk(BIOS_DEBUG, "sizeram: _MSR MC_CF07_DATA: %08x:%08x\n", msr.hi, + msr.lo); + + /* DIMM 0 */ dimm = msr.hi; - /* installed? */ + /* Installed? */ if ((dimm & 7) != 7) { /* 1:8MB, 2:16MB, 3:32MB, 4:64MB, ... 7:512MB, 8:1GB */ - sizem = 4 << ((dimm >> 12) & 0x0F); } - - /* dimm 1 */ + sizem = 4 << ((dimm >> 12) & 0x0F); + } + + /* DIMM 1 */ dimm = msr.hi >> 16; - /* installed? */ + /* Installed? */ if ((dimm & 7) != 7) { /* 1:8MB, 2:16MB, 3:32MB, 4:64MB, ... 7:512MB, 8:1GB */ sizem += 4 << ((dimm >> 12) & 0x0F); }
- printk(BIOS_DEBUG,"sizeram: sizem 0x%xMB\n", sizem); + printk(BIOS_DEBUG, "sizeram: sizem 0x%xMB\n", sizem); + return sizem; }
-/** - * enable_shadow. Currently not set up. - * @param dev The nortbridge device. - */ -static void enable_shadow(struct device * dev) +/** + * Currently not set up. + * + * @param dev The nortbridge device. + */ +static void enable_shadow(struct device *dev) { }
/** - * init the northbridge pci device. Right now this a no op. We leave - * it here as a hook for later use. - * @param dev The nortbridge device. - */ -static void geodelx_northbridge_init(struct device * dev) + * Initialize the northbridge PCI device. + * Right now this a no op. We leave it here as a hook for later use. + * + * @param dev The nortbridge device. + */ +static void geodelx_northbridge_init(struct device *dev) { - //struct msr msr; + /* struct msr msr; */
- printk(BIOS_SPEW,">> Entering northbridge.c: %s\n", __FUNCTION__); + printk(BIOS_SPEW, ">> Entering northbridge.c: %s\n", __FUNCTION__);
enable_shadow(dev); - /* - * Swiss cheese - */ - //msr = rdmsr(MSR_GLIU0_SHADOW);
- //msr.hi |= 0x3; - //msr.lo |= 0x30000; +#if 0 + /* Swiss cheese */ + msr = rdmsr(MSR_GLIU0_SHADOW);
- //printk(BIOS_DEBUG,"MSR 0x%08X is now 0x%08X:0x%08X\n", MSR_GLIU0_SHADOW, msr.hi, msr.lo); - //printk(BIOS_DEBUG,"MSR 0x%08X is now 0x%08X:0x%08X\n", MSR_GLIU1_SHADOW, msr.hi, msr.lo); + msr.hi |= 0x3; + msr.lo |= 0x30000; + + printk(BIOS_DEBUG,"MSR 0x%08X is now 0x%08X:0x%08X\n", MSR_GLIU0_SHADOW, msr.hi, msr.lo); + printk(BIOS_DEBUG,"MSR 0x%08X is now 0x%08X:0x%08X\n", MSR_GLIU1_SHADOW, msr.hi, msr.lo); +#endif }
-/** - * Set resources for the PCI northbridge device. This function is - * required due to VSA interactions. - * @param dev The nortbridge device. - */ +/** + * Set resources for the PCI northbridge device. + * This function is required due to VSA interactions. + * + * @param dev The nortbridge device. + */ void geodelx_northbridge_set_resources(struct device *dev) { struct resource *resource, *last; - unsigned link; + unsigned int link; u8 line;
last = &dev->resource[dev->resources];
for (resource = &dev->resource[0]; resource < last; resource++) { - - /* - * from AMD: do not change the base address, it will - * make the VSA virtual registers unusable + /* From AMD: do not change the base address, it will + * make the VSA virtual registers unusable. */ - //pci_set_resource(dev, resource); - // FIXME: static allocation may conflict with dynamic mappings! + // pci_set_resource(dev, resource); + // FIXME: Static allocation may conflict with dynamic mappings! } - + for (link = 0; link < dev->links; link++) { struct bus *bus; bus = &dev->link[link]; if (bus->children) { - printk(BIOS_DEBUG, - "my_dev_set_resources: phase4_assign_resources %d\n", bus); + printk(BIOS_DEBUG, + "my_dev_set_resources: phase4_assign_resources %d\n", + bus); phase4_assign_resources(bus); } } - - /* set a default latency timer */ + + /* Set a default latency timer. */ pci_write_config8(dev, PCI_LATENCY_TIMER, 0x40); - - /* set a default secondary latency timer */ - if ((dev->hdr_type & 0x7f) == PCI_HEADER_TYPE_BRIDGE) { + + /* Set a default secondary latency timer. */ + if ((dev->hdr_type & 0x7f) == PCI_HEADER_TYPE_BRIDGE) pci_write_config8(dev, PCI_SEC_LATENCY_TIMER, 0x40); - }
- /* zero the irq settings */ + /* Zero the IRQ settings. */ line = pci_read_config8(dev, PCI_INTERRUPT_PIN); - if (line) { + if (line) pci_write_config8(dev, PCI_INTERRUPT_LINE, 0); - }
- /* set the cache line size, so far 64 bytes is good for everyone */ + /* Set the cache line size, so far 64 bytes is good for everyone. */ pci_write_config8(dev, PCI_CACHE_LINE_SIZE, 64 >> 2); }
- - -/** - * Set resources for the PCI domain. Just set up basic global ranges - * for IO and memory Allocation of sub-resources draws on these - * top-level resources in the usual hierarchical manner. - * @param dev The nortbridge device. - */ -static void geodelx_pci_domain_read_resources(struct device * dev) +/** + * Set resources for the PCI domain. + * + * Just set up basic global ranges for I/O and memory. Allocation of + * sub-resources draws on these top-level resources in the usual + * hierarchical manner. + * + * @param dev The nortbridge device. + */ +static void geodelx_pci_domain_read_resources(struct device *dev) { struct resource *resource; - printk(BIOS_SPEW,">> Entering northbridge.c: %s\n", __FUNCTION__);
- /* Initialize the system wide io space constraints */ + printk(BIOS_SPEW, ">> Entering northbridge.c: %s\n", __FUNCTION__); + + /* Initialize the system wide I/O space constraints. */ resource = new_resource(dev, IOINDEX_SUBTRACTIVE(0, 0)); resource->limit = 0xffffUL; resource->flags = - IORESOURCE_IO | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED; + IORESOURCE_IO | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED;
- /* Initialize the system wide memory resources constraints */ + /* Initialize the system wide memory resources constraints. */ resource = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0)); resource->limit = 0xffffffffULL; resource->flags = - IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED; + IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED; }
-/** - * Create a ram resource, by taking the passed-in size and createing - * a resource record. - * @param dev the device - * @param index a resource index - * @param basek base memory address in k - * @param sizek size of memory in k - */ -static void ram_resource(struct device * dev, unsigned long index, +/** + * Create a RAM resource, by taking the passed-in size and creating + * a resource record. + * + * @param dev The device. + * @param index A resource index. + * @param basek Base memory address in KB. + * @param sizek Size of memory in KB. + */ +static void ram_resource(struct device *dev, unsigned long index, unsigned long basek, unsigned long sizek) { struct resource *resource; @@ -290,159 +328,169 @@ resource->base = ((resource_t) basek) << 10; resource->size = ((resource_t) sizek) << 10; resource->flags = IORESOURCE_MEM | IORESOURCE_CACHEABLE | - IORESOURCE_FIXED | IORESOURCE_STORED | IORESOURCE_ASSIGNED; + IORESOURCE_FIXED | IORESOURCE_STORED | IORESOURCE_ASSIGNED; }
-/** - * Set resources in the pci domain. Also, as a side effect, create a - * ram resource in the child which, interestingly enough, is the - * north bridge pci device, for later allocation of address space. - * @param dev the device - */ - static void geodelx_pci_domain_set_resources(struct device * dev) +/** + * Set resources in the PCI domain. + * + * Also, as a side effect, create a RAM resource in the child which, + * interestingly enough, is the northbridge PCI device, for later + * allocation of address space. + * + * @param dev The device. + */ +static void geodelx_pci_domain_set_resources(struct device *dev) { int idx; - struct device * mc_dev; + struct device *mc_dev;
- printk(BIOS_SPEW,">> Entering northbridge.c: %s\n", __FUNCTION__); + printk(BIOS_SPEW, ">> Entering northbridge.c: %s\n", __FUNCTION__);
mc_dev = dev->link[0].children; if (mc_dev) { - /* Report the memory regions */ + /* Report the memory regions. */ idx = 10; + /* 0 .. 640 KB */ ram_resource(dev, idx++, 0, 640); - /* Systop - 1 MB -> KB*/ - ram_resource(dev, idx++, 1024, (get_systop() - 0x100000) / 1024); + /* 1 MB .. (Systop - 1 MB) (converted to KB) */ + ram_resource(dev, idx++, 1024, + (get_systop() - (1 * 1024 * 1024)) / 1024); }
phase4_assign_resources(&dev->link[0]); }
/** - * enable the pci domain. A littly tricky on this chipset due to the - * VSA interactions. This must happen before any PCI scans happen. - * we do early northbridge init to make sure pci scans will work, but - * the weird part is we actually have to run some code in x86 mode to - * get the VSM installed, since the VSM actually handles some PCI bus - * scan tasks via the System Management Interrupt. Yes, it gets - * tricky ... - * @param dev the device - */ -static void geodelx_pci_domain_phase2(struct device * dev) + * Enable the PCI domain. + * + * A littly tricky on this chipset due to the VSA interactions. This must + * happen before any PCI scans happen. We do early northbridge init to make + * sure PCI scans will work, but the weird part is we actually have to run + * some code in x86 mode to get the VSM installed, since the VSM actually + * handles some PCI bus scan tasks via the System Management Interrupt. + * Yes, it gets tricky... + * + * @param dev The device. + */ +static void geodelx_pci_domain_phase2(struct device *dev) { + printk(BIOS_SPEW, ">> Entering northbridge.c: %s\n", __FUNCTION__);
- printk(BIOS_SPEW,">> Entering northbridge.c: %s\n", __FUNCTION__); - northbridge_init_early(); #warning cpu bug has been moved to initram stage -// cpu_bug(); + /* cpu_bug(); */ chipsetinit();
setup_realmode_idt();
- printk(BIOS_DEBUG,"Before VSA:\n"); - // print_conf(); -#warning Not doing vsm bios -- linux will fail. -// do_vsmbios(); // do the magic stuff here, so prepare your tambourine ;) + printk(BIOS_DEBUG, "Before VSA:\n"); + /* print_conf(); */ +#warning Not doing vsm bios -- linux will fail. + /* Do the magic stuff here, so prepare your tambourine ;) */ + /* do_vsmbios(); */ + printk(BIOS_DEBUG, "After VSA:\n"); + /* print_conf(); */
- printk(BIOS_DEBUG,"After VSA:\n"); - // print_conf(); - -#warning graphics_init is disabled. -// graphics_init(); +#warning graphics_init is disabled. + /* graphics_init(); */ pci_set_method(dev); }
/** - * Support for scan bus from the "tippy top" -- i.e. the pci domain, - * not the 0:0.0 device. - * @param dev The pci domain device - * @param max max number of devices to scan. - */ -static unsigned int geodelx_pci_domain_scan_bus(struct device * dev, unsigned int max) + * Support for scan bus from the "tippy top" -- i.e. the PCI domain, + * not the 0:0.0 device. + * + * @param dev The PCI domain device. + * @param max Maximum number of devices to scan. + */ +static unsigned int geodelx_pci_domain_scan_bus(struct device *dev, + unsigned int max) { - printk(BIOS_SPEW,">> Entering northbridge.c: %s\n", __FUNCTION__); + printk(BIOS_SPEW, ">> Entering northbridge.c: %s\n", __FUNCTION__);
max = pci_scan_bus(&dev->link[0], PCI_DEVFN(0, 0), 0xff, max); return max; }
- /** - * Support for apic cluster init. TODO should we do this in phase 2? - * It is now done in phase 6 - * @param dev The pci domain device - */ -static void cpu_bus_init(struct device * dev) + * Support for APIC cluster init. + * + * TODO: Should we do this in phase 2? It is now done in phase 6. + * + * @param dev The PCI domain device. + */ +static void cpu_bus_init(struct device *dev) { - printk(BIOS_SPEW,">> Entering northbridge.c: %s\n", __FUNCTION__); - printk(BIOS_SPEW,">> Exiting northbridge.c: %s\n", __FUNCTION__); - + printk(BIOS_SPEW, ">> Entering northbridge.c: %s\n", __FUNCTION__); + printk(BIOS_SPEW, ">> Exiting northbridge.c: %s\n", __FUNCTION__); }
-static void cpu_bus_noop(struct device * dev) +static void cpu_bus_noop(struct device *dev) { }
-/* the same hardware, being multifunction, has several roles. In this - * case, the north is a pci domain controller, apic cluster, and the - * traditional 0:0.0 device - */ +/* The same hardware, being multifunction, has several roles. In this case, + * the northbridge is a PCI domain controller, APIC cluster, and the + * traditional 0:0.0 device. + */
-/* Here are the operations for when the northbridge is running a PCI - * domain. - */ +/** Operations for when the northbridge is running a PCI domain. */ struct device_operations geodelx_pcidomainops = { - .constructor = default_device_constructor, - .phase2_setup_scan_bus = geodelx_pci_domain_phase2, - .phase3_scan = geodelx_pci_domain_scan_bus, - .phase4_read_resources = geodelx_pci_domain_read_resources, - .phase4_set_resources = geodelx_pci_domain_set_resources, - .phase5_enable_resources = enable_childrens_resources, - .phase6_init = 0, - .ops_pci_bus = &pci_cf8_conf1, - + .constructor = default_device_constructor, + .phase2_setup_scan_bus = geodelx_pci_domain_phase2, + .phase3_scan = geodelx_pci_domain_scan_bus, + .phase4_read_resources = geodelx_pci_domain_read_resources, + .phase4_set_resources = geodelx_pci_domain_set_resources, + .phase5_enable_resources = enable_childrens_resources, + .phase6_init = 0, + .ops_pci_bus = &pci_cf8_conf1, };
-/* Here are the operations for when the northbridge is running an APIC - * cluster. - */ +/** Operations for when the northbridge is running an APIC cluster. */ struct device_operations geodelx_apicops = { - .constructor = default_device_constructor, - .phase3_scan = 0, - .phase4_read_resources = cpu_bus_noop, - .phase4_set_resources = cpu_bus_noop, - .phase5_enable_resources = cpu_bus_noop, - .phase6_init = cpu_bus_init, - .ops_pci_bus = &pci_cf8_conf1, + .constructor = default_device_constructor, + .phase3_scan = 0, + .phase4_read_resources = cpu_bus_noop, + .phase4_set_resources = cpu_bus_noop, + .phase5_enable_resources = cpu_bus_noop, + .phase6_init = cpu_bus_init, + .ops_pci_bus = &pci_cf8_conf1, };
-/* Here are the operations for when the northbridge is running a PCI - * device. - */ +/** Operations for when the northbridge is running a PCI device. */ struct device_operations geodelx_pci_ops = { - .constructor = default_device_constructor, - .phase3_scan = geodelx_pci_domain_scan_bus, - .phase4_read_resources = geodelx_pci_domain_read_resources, - .phase4_set_resources = geodelx_northbridge_set_resources, - .phase5_enable_resources = enable_childrens_resources, - .phase6_init = geodelx_northbridge_init, - .ops_pci_bus = &pci_cf8_conf1, - + .constructor = default_device_constructor, + .phase3_scan = geodelx_pci_domain_scan_bus, + .phase4_read_resources = geodelx_pci_domain_read_resources, + .phase4_set_resources = geodelx_northbridge_set_resources, + .phase5_enable_resources = enable_childrens_resources, + .phase6_init = geodelx_northbridge_init, + .ops_pci_bus = &pci_cf8_conf1, };
+/** + * The constructor for the device. + * Domain ops and APIC cluster ops and PCI device ops are different. + */ +struct constructor geodelx_north_constructors[] = { + /* Northbridge running a PCI domain. */ + {.id = {.type = DEVICE_ID_PCI_DOMAIN, + .u = {.pci_domain = {.vendor = PCI_VENDOR_ID_AMD, + .device = PCI_DEVICE_ID_AMD_LXBRIDGE}}}, + .ops = &geodelx_pcidomainops},
-/* The constructor for the device. */ -/* Domain ops and apic cluster ops and pci device ops are different */ -struct constructor geodelx_north_constructors[] = { - {.id = {.type = DEVICE_ID_PCI_DOMAIN, - .u = {.pci_domain = {.vendor = PCI_VENDOR_ID_AMD,.device = PCI_DEVICE_ID_AMD_LXBRIDGE}}}, - &geodelx_pcidomainops}, - {.id = {.type = DEVICE_ID_APIC_CLUSTER, - .u = {.apic_cluster = {.vendor = PCI_VENDOR_ID_AMD,.device = PCI_DEVICE_ID_AMD_LXBRIDGE}}}, - &geodelx_apicops}, - {.id = {.type = DEVICE_ID_PCI, - .u = {.pci = {.vendor = PCI_VENDOR_ID_AMD,.device = PCI_DEVICE_ID_AMD_LXBRIDGE}}}, - &geodelx_pci_ops}, - {.ops = 0}, + /* Northbridge running an APIC cluster. */ + {.id = {.type = DEVICE_ID_APIC_CLUSTER, + .u = {.apic_cluster = {.vendor = PCI_VENDOR_ID_AMD, + .device = PCI_DEVICE_ID_AMD_LXBRIDGE}}}, + .ops = &geodelx_apicops}, + + /* Northbridge running a PCI device. */ + {.id = {.type = DEVICE_ID_PCI, + .u = {.pci = {.vendor = PCI_VENDOR_ID_AMD, + .device = PCI_DEVICE_ID_AMD_LXBRIDGE}}}, + .ops = &geodelx_pci_ops}, + + {.ops = 0}, };
Modified: LinuxBIOSv3/northbridge/amd/geodelx/geodelxinit.c =================================================================== --- LinuxBIOSv3/northbridge/amd/geodelx/geodelxinit.c 2007-07-07 21:18:47 UTC (rev 438) +++ LinuxBIOSv3/northbridge/amd/geodelx/geodelxinit.c 2007-07-08 00:19:26 UTC (rev 439) @@ -37,21 +37,21 @@ };
struct gliutable gliu0table[] = { - /* 0-7FFFF to MC */ + /* 0-7FFFF to MC */ {.desc_name = MSR_GLIU0_BASE1,.desc_type = BM,.hi = MSR_MC + 0x0, .lo = 0x0FFF80}, - /* 80000-9ffff to Mc */ + /* 80000-9FFFF to MC */ {.desc_name = MSR_GLIU0_BASE2,.desc_type = BM,.hi = MSR_MC + 0x0, .lo = (0x80 << 20) + 0x0FFFE0}, - /* C0000-Fffff split to MC and PCI (sub decode) A0000-Bffff - * handled by SoftVideo + /* C0000-FFFFF split to MC and PCI (sub decode) A0000-BFFFF + * handled by SoftVideo. */ {.desc_name = MSR_GLIU0_SHADOW,.desc_type = SC_SHADOW, .hi = MSR_MC + 0x0,.lo = 0x03}, - /* Catch and fix dynamicly. */ + /* Catch and fix dynamically. */ {.desc_name = MSR_GLIU0_SYSMEM,.desc_type = R_SYSMEM, .hi = MSR_MC,.lo = 0x0}, - /* Catch and fix dynamicly. */ + /* Catch and fix dynamically. */ {.desc_name = MSR_GLIU0_SMM,.desc_type = BMO_SMM, .hi = MSR_MC,.lo = 0x0}, {.desc_name = GLIU0_GLD_MSR_COH,.desc_type = OTHER, @@ -60,24 +60,24 @@ };
struct gliutable gliu1table[] = { - /* 0-7FFFF to MC */ + /* 0-7FFFF to MC */ {.desc_name = MSR_GLIU1_BASE1,.desc_type = BM,.hi = MSR_GL0 + 0x0, .lo = 0x0FFF80}, - /* 80000-9ffff to Mc */ + /* 80000-9FFFF to MC */ {.desc_name = MSR_GLIU1_BASE2,.desc_type = BM,.hi = MSR_GL0 + 0x0, .lo = (0x80 << 20) + 0x0FFFE0}, - /* C0000-Fffff split to MC and PCI (sub decode) */ + /* C0000-Fffff split to MC and PCI (sub decode) */ {.desc_name = MSR_GLIU1_SHADOW,.desc_type = SC_SHADOW, .hi = MSR_GL0 + 0x0,.lo = 0x03}, - /* Catch and fix dynamicly. */ + /* Catch and fix dynamically. */ {.desc_name = MSR_GLIU1_SYSMEM,.desc_type = R_SYSMEM, .hi = MSR_GL0,.lo = 0x0}, - /* Catch and fix dynamicly. */ + /* Catch and fix dynamically. */ {.desc_name = MSR_GLIU1_SMM,.desc_type = BM_SMM, .hi = MSR_GL0,.lo = 0x0}, {.desc_name = GLIU1_GLD_MSR_COH,.desc_type = OTHER, .hi = 0x0,.lo = GL1_GLIU0}, - /* FooGlue FPU 0xF0 */ + /* FooGlue FPU 0xF0 */ {.desc_name = MSR_GLIU1_FPU_TRAP,.desc_type = SCIO, .hi = (GL1_GLCP << 29) + 0x0,.lo = 0x033000F0}, {.desc_name = GL_END,.desc_type = GL_END,.hi = 0x0,.lo = 0x0}, @@ -87,121 +87,116 @@
struct msrinit { unsigned long msrnum; - struct msr msr; + struct msr msr; };
struct msrinit clock_gating_default[] = { - {GLIU0_GLD_MSR_PM, {.hi = 0x00,.lo = 0x0005}}, - {MC_GLD_MSR_PM, {.hi = 0x00,.lo = 0x0001}}, - {VG_GLD_MSR_PM, {.hi = 0x00,.lo = 0x0015}}, - {GP_GLD_MSR_PM, {.hi = 0x00,.lo = 0x0001}}, - {DF_GLD_MSR_PM, {.hi = 0x00,.lo = 0x0555}}, - {GLIU1_GLD_MSR_PM, {.hi = 0x00,.lo = 0x0005}}, - {GLCP_GLD_MSR_PM, {.hi = 0x00,.lo = 0x0014}}, - {GLPCI_GLD_MSR_PM, {.hi = 0x00,.lo = 0x0015}}, - {VIP_GLD_MSR_PM, {.hi = 0x00,.lo = 0x0005}}, - {AES_GLD_MSR_PM, {.hi = 0x00,.lo = 0x0015}}, - {CPU_BC_PMODE_MSR, {.hi = 0x00,.lo = 0x70303}}, - {0xffffffff, {0xffffffff, 0xffffffff}}, + {GLIU0_GLD_MSR_PM, {.hi = 0x00,.lo = 0x0005}}, + {MC_GLD_MSR_PM, {.hi = 0x00,.lo = 0x0001}}, + {VG_GLD_MSR_PM, {.hi = 0x00,.lo = 0x0015}}, + {GP_GLD_MSR_PM, {.hi = 0x00,.lo = 0x0001}}, + {DF_GLD_MSR_PM, {.hi = 0x00,.lo = 0x0555}}, + {GLIU1_GLD_MSR_PM, {.hi = 0x00,.lo = 0x0005}}, + {GLCP_GLD_MSR_PM, {.hi = 0x00,.lo = 0x0014}}, + {GLPCI_GLD_MSR_PM, {.hi = 0x00,.lo = 0x0015}}, + {VIP_GLD_MSR_PM, {.hi = 0x00,.lo = 0x0005}}, + {AES_GLD_MSR_PM, {.hi = 0x00,.lo = 0x0015}}, + {CPU_BC_PMODE_MSR, {.hi = 0x00,.lo = 0x70303}}, // TODO: Correct? + {0xffffffff, {0xffffffff, 0xffffffff}}, };
-/* */ -/* SET GeodeLink PRIORITY*/ -/* */ +/** GeodeLink priority table. */ struct msrinit geode_link_priority_table[] = { - {CPU_GLD_MSR_CONFIG, {.hi = 0x00,.lo = 0x0220}}, - {DF_GLD_MSR_MASTER_CONF, {.hi = 0x00,.lo = 0x0000}}, - {VG_GLD_MSR_CONFIG, {.hi = 0x00,.lo = 0x0720}}, - {GP_GLD_MSR_CONFIG, {.hi = 0x00,.lo = 0x0010}}, - {GLPCI_GLD_MSR_CONFIG, {.hi = 0x00,.lo = 0x0017}}, - {GLCP_GLD_MSR_CONF, {.hi = 0x00,.lo = 0x0001}}, - {VIP_GLD_MSR_CONFIG, {.hi = 0x00,.lo = 0x0622}}, - {AES_GLD_MSR_CONFIG, {.hi = 0x00,.lo = 0x0013}}, - {0x0FFFFFFFF, {0x0FFFFFFFF, 0x0FFFFFFFF}}, /* END */ + {CPU_GLD_MSR_CONFIG, {.hi = 0x00,.lo = 0x0220}}, + {DF_GLD_MSR_MASTER_CONF, {.hi = 0x00,.lo = 0x0000}}, + {VG_GLD_MSR_CONFIG, {.hi = 0x00,.lo = 0x0720}}, + {GP_GLD_MSR_CONFIG, {.hi = 0x00,.lo = 0x0010}}, + {GLPCI_GLD_MSR_CONFIG, {.hi = 0x00,.lo = 0x0017}}, + {GLCP_GLD_MSR_CONF, {.hi = 0x00,.lo = 0x0001}}, + {VIP_GLD_MSR_CONFIG, {.hi = 0x00,.lo = 0x0622}}, + {AES_GLD_MSR_CONFIG, {.hi = 0x00,.lo = 0x0013}}, + {0x0FFFFFFFF, {0x0FFFFFFFF, 0x0FFFFFFFF}}, };
extern int sizeram(void);
/** - * Write a GeodeLink MSR. - * @param gl A Geode Link table descriptor - */ + * Write a GeodeLink MSR. + * + * @param gl A GeodeLink table descriptor. + */ static void writeglmsr(struct gliutable *gl) { - struct msr msr; + struct msr msr;
msr.lo = gl->lo; msr.hi = gl->hi; - wrmsr(gl->desc_name, msr); // MSR - see table above - printk(BIOS_SPEW, - "%s: MSR 0x%08x, val 0x%08x:0x%08x\n", - __FUNCTION__, gl->desc_name, msr.hi, msr.lo); + wrmsr(gl->desc_name, msr); /* MSR - see table above. */ + printk(BIOS_SPEW, + "%s: MSR 0x%08x, val 0x%08x:0x%08x\n", + __FUNCTION__, gl->desc_name, msr.hi, msr.lo); }
/** - * Read the MSR specified in the gl struct. If the low 32 bits is zero, - * indicating - * it has not been set, set it. - * @param gl A Geode Link table descriptor - */ + * Read the MSR specified in the gl struct. If the low 32 bits are zero, + * indicating it has not been set, set it. + * + * @param gl A GeodeLink table descriptor. + */ static void ShadowInit(struct gliutable *gl) { - struct msr msr; + struct msr msr;
msr = rdmsr(gl->desc_name); - - if (msr.lo == 0) { + if (msr.lo == 0) writeglmsr(gl); - } }
-extern int sizeram(void); - /** - * Set up the system memory registers, i.e. memory that can be used - * for non-VSM (or SMM) purposes. - * @param gl A Geode Link table descriptor - */ - + * Set up the system memory registers, i.e. memory that can be used + * for non-VSM (or SMM) purposes. + * + * @param gl A GeodeLink table descriptor. + */ static void sysmem_init(struct gliutable *gl) { - struct msr msr; + struct msr msr; int sizembytes, sizebytes;
- /* - * Figure out how much RAM is in the machine and alocate all to the + /* Figure out how much RAM is in the machine and allocate all to the * system. We will adjust for SMM now and Frame Buffer later. */ sizembytes = sizeram(); - printk(BIOS_DEBUG, "%s: enable for %dMBytes\n", + printk(BIOS_DEBUG, "%s: enable for %dMBytes\n", __FUNCTION__, sizembytes); sizebytes = sizembytes << 20;
sizebytes -= ((SMM_SIZE * 1024) + 1); - printk(BIOS_DEBUG, "usable RAM: %d bytes\n", sizebytes); + printk(BIOS_DEBUG, "Usable RAM: %d bytes\n", sizebytes);
- /* 20 bit address The bottom 12 bits go into bits 20-31 in msr.lo - The top 8 bits go into 0-7 of msr.hi. */ + /* 20 bit address. The bottom 12 bits go into bits 20-31 in msr.lo. + * The top 8 bits go into 0-7 of msr.hi. + */ sizebytes--; msr.hi = (gl->hi & 0xFFFFFF00) | (sizebytes >> 24); - sizebytes <<= 8; /* move bits 23:12 in bits 31:20. */ + sizebytes <<= 8; /* Move bits 23:12 in bits 31:20. */ sizebytes &= 0xfff00000; - sizebytes |= 0x100; /* start at 1MB */ + sizebytes |= 0x100; /* Start at 1 MB. */ msr.lo = sizebytes;
- wrmsr(gl->desc_name, msr); // MSR - see table above + wrmsr(gl->desc_name, msr); /* MSR - see table above. */ printk(BIOS_DEBUG, "%s: MSR 0x%08x, val 0x%08x:0x%08x\n", __FUNCTION__, - gl->desc_name, msr.hi, msr.lo); + gl->desc_name, msr.hi, msr.lo); }
/** - * Set up GL0 memory mapping. Again, SMM memory is subtracted. - * @param gl A Geode Link table descriptor - */ - + * Set up GL0 memory mapping. Again, SMM memory is subtracted. + * + * @param gl A GeodeLink table descriptor. + */ static void SMMGL0Init(struct gliutable *gl) { - struct msr msr; + struct msr msr; int sizebytes = sizeram() << 20; long offset;
@@ -209,7 +204,7 @@
printk(BIOS_DEBUG, "%s: %d bytes\n", __FUNCTION__, sizebytes);
- /* calculate the Two's complement offset */ + /* Calculate the "two's complement" offset. */ offset = sizebytes - SMM_OFFSET; offset = (offset >> 12) & 0x000fffff; printk(BIOS_DEBUG, "%s: offset is 0x%08x\n", __FUNCTION__, SMM_OFFSET); @@ -220,94 +215,89 @@ msr.lo = SMM_OFFSET << 8; msr.lo |= ((~(SMM_SIZE * 1024) + 1) >> 12) & 0xfffff;
- wrmsr(gl->desc_name, msr); // MSR - See table above + wrmsr(gl->desc_name, msr); /* MSR - See table above. */ printk(BIOS_DEBUG, "%s: MSR 0x%08x, val 0x%08x:0x%08x\n", __FUNCTION__, - gl->desc_name, msr.hi, msr.lo); + gl->desc_name, msr.hi, msr.lo); }
/** - * Set up GL1 memory mapping. Again, SMM memory is subtracted. - * @param gl A Geode Link table descriptor - */ - + * Set up GL1 memory mapping. Again, SMM memory is subtracted. + * + * @param gl A GeodeLink table descriptor. + */ static void SMMGL1Init(struct gliutable *gl) { - struct msr msr; + struct msr msr; printk(BIOS_DEBUG, "%s:\n", __FUNCTION__);
msr.hi = gl->hi; - /* I don't think this is needed */ + /* I don't think this is needed. */ msr.hi &= 0xffffff00; msr.hi |= (SMM_OFFSET >> 24); msr.lo = (SMM_OFFSET << 8) & 0xFFF00000; msr.lo |= ((~(SMM_SIZE * 1024) + 1) >> 12) & 0xfffff;
- wrmsr(gl->desc_name, msr); // MSR - See table above + wrmsr(gl->desc_name, msr); /* MSR - See table above. */ printk(BIOS_DEBUG, "%s: MSR 0x%08x, val 0x%08x:0x%08x\n", __FUNCTION__, - gl->desc_name, msr.hi, msr.lo); + gl->desc_name, msr.hi, msr.lo); }
/** - * Set up all Geode Link Interfaces. Iterate over the table until done. - * Case out on the link type, and call the appropriate function. - * @param gl A Geode Link table descriptor - */ - + * Set up all GeodeLink interfaces. Iterate over the table until done. + * + * Case out on the link type, and call the appropriate function. + * + * @param gl A GeodeLink table descriptor. + */ static void GLIUInit(struct gliutable *gl) { - while (gl->desc_type != GL_END) { switch (gl->desc_type) { default: - /* For Unknown types: Write then read MSR */ + /* For unknown types: Write then read MSR. */ writeglmsr(gl); - case SC_SHADOW: /* Check for a Shadow entry */ + case SC_SHADOW: /* Check for a Shadow entry. */ ShadowInit(gl); break; - - case R_SYSMEM: /* check for a SYSMEM entry */ + case R_SYSMEM: /* Check for a SYSMEM entry. */ sysmem_init(gl); break; - - case BMO_SMM: /* check for a SMM entry */ + case BMO_SMM: /* Check for a SMM entry. */ SMMGL0Init(gl); break; - - case BM_SMM: /* check for a SMM entry */ + case BM_SMM: /* Check for a SMM entry. */ SMMGL1Init(gl); break; } gl++; } - }
/** - * Set up the region config registers for the Geode Link PCI interface. - * R0: 0-640KB, - * R1: 1MB - Top of System Memory - * R2: SMM Memory - * R3: Framebuffer? - not set up yet - */ + * Set up the region config registers for the GeodeLink PCI interface. + * + * R0: 0 - 640 KB + * R1: 1 MB - Top of System Memory + * R2: SMM Memory + * R3: Framebuffer? - not set up yet. + */ static void GLPCI_init(void) { - struct gliutable *gl = 0; - int i; - struct msr msr; - int msrnum, enable_preempt, enable_cpu_override; + struct gliutable *gl = NULL; + struct msr msr; + int i, msrnum, enable_preempt, enable_cpu_override; int nic_grants_control, enable_bus_parking;
- /* R0 - GLPCI settings for Conventional Memory space. */ + /* R0 - GLPCI settings for Conventional Memory space. */ msr.hi = (0x09F000 >> 12) << GLPCI_RC_UPPER_TOP_SHIFT; /* 640 */ - msr.lo = 0; /* 0 */ - msr.lo |= - GLPCI_RC_LOWER_EN_SET + GLPCI_RC_LOWER_PF_SET + - GLPCI_RC_LOWER_WC_SET; + msr.lo = 0; /* 0 */ + msr.lo |= GLPCI_RC_LOWER_EN_SET + GLPCI_RC_LOWER_PF_SET + + GLPCI_RC_LOWER_WC_SET; msrnum = GLPCI_RC0; wrmsr(msrnum, msr);
- /* R1 - GLPCI settings for SysMem space. */ - /* Get systop from GLIU0 SYSTOP Descriptor */ + /* R1 - GLPCI settings for SysMem space. */ + /* Get systop from GLIU0 SYSTOP Descriptor. */ for (i = 0; gliu0table[i].desc_name != GL_END; i++) { if (gliu0table[i].desc_type == R_SYSMEM) { gl = &gliu0table[i]; @@ -318,51 +308,52 @@ unsigned long pah, pal; msrnum = gl->desc_name; msr = rdmsr(msrnum); - /* example R_SYSMEM value: 20:00:00:0f:fb:f0:01:00 + + /* Example: R_SYSMEM value 20:00:00:0f:fb:f0:01:00 * translates to a base of 0x00100000 and top of 0xffbf0000 - * base of 1M and top of around 256M + * base of 1M and top of around 256M. */ /* we have to create a page-aligned (4KB page) address - * for base and top */ - /* So we need a high page aligned addresss (pah) and + * for base and top. + * So we need a high page aligned addresss (pah) and * low page aligned address (pal) pah is from msr.hi * << 12 | msr.low >> 20. pal is msr.lo << 12 */ pah = ((msr.hi & 0xFF) << 12) | ((msr.lo >> 20) & 0xFFF); - /* we have the page address. Now make it a - * page-aligned address */ + + /* We have the page address. Now make it page-aligned. */ pah <<= 12;
pal = msr.lo << 12; msr.hi = pah; msr.lo = pal; - msr.lo |= - GLPCI_RC_LOWER_EN_SET | GLPCI_RC_LOWER_PF_SET | - GLPCI_RC_LOWER_WC_SET; - printk(BIOS_DEBUG, + msr.lo |= GLPCI_RC_LOWER_EN_SET | GLPCI_RC_LOWER_PF_SET | + GLPCI_RC_LOWER_WC_SET; + printk(BIOS_DEBUG, "GLPCI R1: system msr.lo 0x%08x msr.hi 0x%08x\n", - msr.lo, msr.hi); + msr.lo, msr.hi); msrnum = GLPCI_RC1; wrmsr(msrnum, msr); }
- /* R2 - GLPCI settings for SMM space */ - msr.hi = - ((SMM_OFFSET + - (SMM_SIZE * 1024 - 1)) >> 12) << GLPCI_RC_UPPER_TOP_SHIFT; + /* R2 - GLPCI settings for SMM space. */ + msr.hi = ((SMM_OFFSET + + (SMM_SIZE * 1024 - 1)) >> 12) << GLPCI_RC_UPPER_TOP_SHIFT; msr.lo = (SMM_OFFSET >> 12) << GLPCI_RC_LOWER_BASE_SHIFT; msr.lo |= GLPCI_RC_LOWER_EN_SET | GLPCI_RC_LOWER_PF_SET; - printk(BIOS_DEBUG, "GLPCI R2: system msr.lo 0x%08x msr.hi 0x%08x\n", + printk(BIOS_DEBUG, "GLPCI R2: system msr.lo 0x%08x msr.hi 0x%08x\n", msr.lo, msr.hi); msrnum = GLPCI_RC2; wrmsr(msrnum, msr);
- /* this is done elsewhere already, but it does no harm to do - * it more than once */ - /* write serialize memory hole to PCI. Need to to unWS when - * something is shadowed regardless of cachablility. */ - msr.lo = 0x021212121; /* cache disabled and write serialized */ - msr.hi = 0x021212121; /* cache disabled and write serialized */ + /* This is done elsewhere already, but it does no harm to do + * it more than once. + */ + /* Write serialize memory hole to PCI. Need to to unWS when + * something is shadowed regardless of cachablility. + */ + msr.lo = 0x021212121; /* Cache disabled and write serialized. */ + msr.hi = 0x021212121; /* Cache disabled and write serialized. */
msrnum = CPU_RCONF_A0_BF; wrmsr(msrnum, msr); @@ -373,8 +364,9 @@ msrnum = CPU_RCONF_E0_FF; wrmsr(msrnum, msr);
- /* Set Non-Cacheable Read Only for NorthBound Transactions to - * Memory. The Enable bit is handled in the Shadow setup. */ + /* Set Non-Cacheable Read Only for NorthBound Transactions to + * Memory. The Enable bit is handled in the Shadow setup. + */ msrnum = GLPCI_A0_BF; msr.hi = 0x35353535; msr.lo = 0x35353535; @@ -390,20 +382,19 @@ msr.lo = 0x35353535; wrmsr(msrnum, msr);
- /* Set WSREQ */ + /* Set WSREQ. */ msrnum = CPU_DM_CONFIG0; msr = rdmsr(msrnum); msr.hi &= ~(7 << DM_CONFIG0_UPPER_WSREQ_SHIFT); - /* reduce to 1 for safe mode */ + /* Reduce to 1 for safe mode. */ msr.hi |= 2 << DM_CONFIG0_UPPER_WSREQ_SHIFT; wrmsr(msrnum, msr);
- /* The following settings will not work with a CS5530 southbridge */ - /* we are ignoring the 5530 case for now, and perhaps forever. */ + /* The following settings will not work with a CS5530 southbridge. + * We are ignoring the CS5530 case for now, and perhaps forever. + */
- /* */ /* 553x NB Init */ - /* */
/* Arbiter setup */ enable_preempt = @@ -424,9 +415,9 @@
msrnum = GLPCI_CTRL; msr = rdmsr(msrnum); - /* (Out will be disabled in CPUBUG649 for < 2.0 parts .) */ - msr.lo |= GLPCI_CTRL_LOWER_ME_SET | GLPCI_CTRL_LOWER_OWC_SET - | GLPCI_CTRL_LOWER_PCD_SET; + /* Out will be disabled in CPUBUG649 for < 2.0 parts. */ + msr.lo |= GLPCI_CTRL_LOWER_ME_SET | GLPCI_CTRL_LOWER_OWC_SET | + GLPCI_CTRL_LOWER_PCD_SET; msr.lo |= GLPCI_CTRL_LOWER_LDE_SET;
msr.lo &= ~(0x03 << GLPCI_CTRL_LOWER_IRFC_SHIFT); @@ -454,11 +445,11 @@ /* Set GLPCI Latency Timer */ msrnum = GLPCI_CTRL; msr = rdmsr(msrnum); - /* Change once 1.x is gone */ + /* Change once 1.x is gone. */ msr.hi |= 0x1F << GLPCI_CTRL_UPPER_LAT_SHIFT; wrmsr(msrnum, msr);
- /* GLPCI_SPARE */ + /* GLPCI_SPARE */ msrnum = GLPCI_SPARE; msr = rdmsr(msrnum); msr.lo &= ~0x7; @@ -470,11 +461,11 @@ }
/** - * Enable Clock Gating in ALL MSRs which relate to clocks. - */ + * Enable Clock Gating in ALL MSRs which relate to clocks. + */ static void clock_gating_init(void) { - struct msr msr; + struct msr msr; struct msrinit *gating = clock_gating_default; int i;
@@ -482,18 +473,17 @@ msr = rdmsr(gating->msrnum); msr.hi |= gating->msr.hi; msr.lo |= gating->msr.lo; - wrmsr(gating->msrnum, msr); // MSR - See the table above + wrmsr(gating->msrnum, msr); /* MSR - See table above. */ gating += 1; } - }
/** - * Set all Geode Link Priority register as determined by the - */ + * Set all GeodeLink priority registers as determined by the TODO. + */ static void geode_link_priority(void) { - struct msr msr; + struct msr msr; struct msrinit *prio = geode_link_priority_table; int i;
@@ -502,74 +492,78 @@ msr.hi |= prio->msr.hi; msr.lo &= ~0xfff; msr.lo |= prio->msr.lo; - wrmsr(prio->msrnum, msr); // MSR - See the table above + wrmsr(prio->msrnum, msr); /* MSR - See table above. */ prio += 1; } }
/** - * Get the GLIU0 shadow register settings - * If the set_shadow function is used then all shadow descriptors - * will stay sync'ed. + * Get the GLIU0 shadow register settings. + * + * If the set_shadow() function is used then all shadow descriptors + * will stay sync'ed. + * + * @return TODO */ static u64 get_shadow(void) { - struct msr msr; + struct msr msr;
msr = rdmsr(MSR_GLIU0_SHADOW); return (((u64) msr.hi) << 32) | msr.lo; }
/** - * Set the cache RConf registers for the memory hole. - * Keeps all cache shadow descriptors sync'ed. - * This is part of the PCI lockup solution - * @param Hi the high 32 bits of the msr setting - * @param lo The low 32 bits of the msr setting + * Set the cache RConf registers for the memory hole. + * + * Keeps all cache shadow descriptors sync'ed. + * This is part of the PCI lockup solution. + * + * @param shadowHi The high 32 bits of the msr setting. + * @param shadowLo The low 32 bits of the msr setting. */ static void set_shadowRCONF(u32 shadowHi, u32 shadowLo) { - - // ok this is whacky bit translation time. + /* Ok, this is whacky bit translation time. */ int bit; u8 shadowByte; - struct msr msr = { 0, 0 }; + struct msr msr = { 0, 0 }; shadowByte = (u8) (shadowLo >> 16);
- // load up D000 settings in edx. + /* Load up D000 settings in edx. */ for (bit = 8; (bit > 4); bit--) { msr.hi <<= 8; - msr.hi |= 1; // cache disable PCI/Shadow memory + msr.hi |= 1; /* Cache disable PCI/Shadow memory. */ if (shadowByte && (1 << bit)) - msr.hi |= 0x20; // write serialize PCI memory + msr.hi |= 0x20; /* Write serialize PCI memory. */ }
- // load up C000 settings in eax. - for (; bit; bit--) { + /* Load up C000 settings in eax. */ + for (/* Nothing */; bit; bit--) { msr.lo <<= 8; - msr.lo |= 1; // cache disable PCI/Shadow memory + msr.lo |= 1; /* Cache disable PCI/Shadow memory. */ if (shadowByte && (1 << bit)) - msr.lo |= 0x20; // write serialize PCI memory + msr.lo |= 0x20; /* Write serialize PCI memory. */ }
wrmsr(CPU_RCONF_C0_DF, msr);
shadowByte = (u8) (shadowLo >> 24);
- // load up F000 settings in edx. + /* Load up F000 settings in edx. */ for (bit = 8; (bit > 4); bit--) { msr.hi <<= 8; - msr.hi |= 1; // cache disable PCI/Shadow memory + msr.hi |= 1; /* Cache disable PCI/Shadow memory. */ if (shadowByte && (1 << bit)) - msr.hi |= 0x20; // write serialize PCI memory + msr.hi |= 0x20; /* Write serialize PCI memory. */ }
- // load up E000 settings in eax. - for (; bit; bit--) { + /* Load up E000 settings in eax. */ + for (/* Nothing */; bit; bit--) { msr.lo <<= 8; - msr.lo |= 1; // cache disable PCI/Shadow memory + msr.lo |= 1; /* Cache disable PCI/Shadow memory. */ if (shadowByte && (1 << bit)) - msr.lo |= 0x20; // write serialize PCI memory + msr.lo |= 0x20; /* write serialize PCI memory. */ }
wrmsr(CPU_RCONF_E0_FF, msr); @@ -577,15 +571,17 @@
/** * Set the GLPCI registers for the memory hole. + * * Keeps all cache shadow descriptors sync'ed. - * @param shadowhi the high 32 bits of the msr setting - * @param shadowlo The low 32 bits of the msr setting - */ + * + * @param shadowhi The high 32 bits of the msr setting. + * @param shadowlo The low 32 bits of the msr setting. + */ static void set_shadowGLPCI(u32 shadowhi, u32 shadowlo) { - struct msr msr; + struct msr msr;
-// Set the Enable Register. + /* Set the Enable register. */ msr = rdmsr(GLPCI_REN); msr.lo &= 0xFFFF00FF; msr.lo |= ((shadowlo & 0xFFFF0000) >> 8); @@ -593,14 +589,17 @@ }
/** - * Set the GLIU SC register settings. Scans descriptor tables for - * SC_SHADOW. Keeps all shadow descriptors sync'ed. - * @param shadowSettings Shadow register settings + * Set the GLIU SC register settings. + * + * Scans descriptor tables for SC_SHADOW. + * Keeps all shadow descriptors sync'ed. + * + * @param shadowSettings Shadow register settings. */ static void set_shadow(u64 shadowSettings) { int i; - struct msr msr; + struct msr msr; struct gliutable *pTable; u32 shadowLo, shadowHi;
@@ -609,66 +608,70 @@
set_shadowRCONF(shadowHi, shadowLo); set_shadowGLPCI(shadowHi, shadowLo); - + for (i = 0; gliutables[i]; i++) { for (pTable = gliutables[i]; pTable->desc_type != GL_END; pTable++) { if (pTable->desc_type == SC_SHADOW) { - msr = rdmsr(pTable->desc_name); msr.lo = (u32) shadowSettings; - /* maintain PDID in upper EDX*/ - msr.hi &= 0xFFFF0000; + /* Maintain PDID in upper EDX. */ + msr.hi &= 0xFFFF0000; msr.hi |= - ((u32) (shadowSettings >> 32)) & - 0x0000FFFF; - // MSR - See the table above + ((u32) (shadowSettings >> 32)) & 0x0000FFFF; + /* MSR - See the table above. */ wrmsr(pTable->desc_name, msr); } } } }
+/** + * TODO. + */ static void rom_shadow_settings(void) { + u64 shadowSettings = get_shadow();
- u64 shadowSettings = get_shadow(); - // Disable read & writes + /* Disable read & writes. */ shadowSettings &= (u64) 0xFFFF00000000FFFFULL; - // Enable reads for F0000-FFFFF + + /* Enable reads for F0000-FFFFF. */ shadowSettings |= (u64) 0x00000000F0000000ULL; - // Enable rw for C0000-CFFFF + + /* Enable read & writes for C0000-CFFFF. */ shadowSettings |= (u64) 0x0000FFFFFFFF0000ULL; + set_shadow(shadowSettings); }
/** + * Set up RCONF_DEFAULT and any other RCONF registers needed. * - * - * Set up RCONF_DEFAULT and any other RCONF registers needed - * - * DEVRC_RCONF_DEFAULT: - * ROMRC(63:56) = 04h write protect ROMBASE - * ROMBASE(36:55) = 0FFFC0h Top of PCI/bottom of rom chipselect area - * DEVRC(35:28) = 39h cache disabled in PCI memory + WS bit on - + Write Combine + write burst. - * SYSTOP(27:8) = top of system memory - * SYSRC(7:0) = 0 writeback, can set to 08h to make writethrough - * - */ -#define SYSMEM_RCONF_WRITETHROUGH 8 -#define DEVRC_RCONF_DEFAULT 0x21 -#define ROMBASE_RCONF_DEFAULT 0xFFFC0000 -#define ROMRC_RCONF_DEFAULT 0x25 + * DEVRC_RCONF_DEFAULT: + * ROMRC(63:56) = 0x04 Write protect ROMBASE + * ROMBASE(36:55) = 0x0FFFC0 Top of PCI/bottom of ROM chipselect area + * DEVRC(35:28) = 0x39 Cache disabled in PCI memory + WS bit on + * Write Combine + write burst. + * SYSTOP(27:8) = top of system memory + * SYSRC(7:0) = 0 Writeback, can set to 0x08 to make writethrough + */ +#define SYSMEM_RCONF_WRITETHROUGH 8 +#define DEVRC_RCONF_DEFAULT 0x21 +#define ROMBASE_RCONF_DEFAULT 0xFFFC0000 +#define ROMRC_RCONF_DEFAULT 0x25
+/** + * TODO. + */ static void enable_L1_cache(void) { - struct gliutable *gl = 0; + struct gliutable *gl = NULL; int i; - struct msr msr; + struct msr msr; u8 SysMemCacheProp;
- /* Locate SYSMEM entry in GLIU0table */ + /* Locate SYSMEM entry in GLIU0table. */ for (i = 0; gliu0table[i].desc_name != GL_END; i++) { if (gliu0table[i].desc_type == R_SYSMEM) { gl = &gliu0table[i]; @@ -676,43 +679,46 @@ } } if (gl == 0) { - post_code(0xCE); /* POST_RCONFInitError */ - while (1) ; + post_code(POST_RCONFInitError); + while (1); /* TODO: Should be hlt()? */ } + // sysdescfound: msr = rdmsr(gl->desc_name);
- /* 20 bit address - The bottom 12 bits go into bits 20-31 in eax, the + /* 20 bit address - The bottom 12 bits go into bits 20-31 in eax, the * top 8 bits go into 0-7 of edx. */ msr.lo = (msr.lo & 0xFFFFFF00) | (msr.hi & 0xFF); msr.lo = ((msr.lo << 12) | (msr.lo >> 20)) & 0x000FFFFF; msr.lo <<= RCONF_DEFAULT_LOWER_SYSTOP_SHIFT; // 8
- // Set Default SYSMEM region properties - // NOT writethrough == writeback 8 (or ~8) + /* Set Default SYSMEM region properties. + * NOT writethrough == writeback 8 (or ~8) + */ msr.lo &= ~SYSMEM_RCONF_WRITETHROUGH;
- // Set PCI space cache properties - // setting is split betwwen hi and lo... + /* Set PCI space cache properties. + * Setting is split between hi and lo... + */ msr.hi = (DEVRC_RCONF_DEFAULT >> 4); msr.lo |= (DEVRC_RCONF_DEFAULT << 28);
- // Set the ROMBASE. This is usually FFFC0000h + /* Set the ROMBASE. This is usually 0xFFFC0000. */ msr.hi |= (ROMBASE_RCONF_DEFAULT >> 12) << RCONF_DEFAULT_UPPER_ROMBASE_SHIFT;
- // Set ROMBASE cache properties. + /* Set ROMBASE cache properties. */ msr.hi |= ((ROMRC_RCONF_DEFAULT >> 8) | (ROMRC_RCONF_DEFAULT << 24));
- // now program RCONF_DEFAULT + /* Now program RCONF_DEFAULT. */ wrmsr(CPU_RCONF_DEFAULT, msr); printk(BIOS_DEBUG, "CPU_RCONF_DEFAULT (1808): 0x%08X:0x%08X\n", msr.hi, - msr.lo); + msr.lo);
- // RCONF_BYPASS: Cache tablewalk properties and - // SMM/DMM header access properties. - // Set to match system memory cache properties. + /* RCONF_BYPASS: Cache tablewalk properties and SMM/DMM header access + * properties. Set to match system memory cache properties. + */ msr = rdmsr(CPU_RCONF_DEFAULT); SysMemCacheProp = (u8) (msr.lo & 0xFF); msr = rdmsr(CPU_RCONF_BYPASS); @@ -720,37 +726,37 @@ (msr.lo & 0xFFFF0000) | (SysMemCacheProp << 8) | SysMemCacheProp; wrmsr(CPU_RCONF_BYPASS, msr);
- printk(BIOS_DEBUG, "CPU_RCONF_BYPASS (180A): 0x%08x : 0x%08x\n", + printk(BIOS_DEBUG, "CPU_RCONF_BYPASS (180A): 0x%08x : 0x%08x\n", msr.hi, msr.lo); }
-/** - * Enable the L2 cache MSRs. - */ +/** + * Enable the L2 cache MSRs. + */ static void enable_L2_cache(void) { - struct msr msr; + struct msr msr;
/* Instruction Memory Configuration register - * set EBE bit, required when L2 cache is enabled + * set EBE bit, required when L2 cache is enabled. */ msr = rdmsr(CPU_IM_CONFIG); msr.lo |= 0x400; wrmsr(CPU_IM_CONFIG, msr);
- /* Data Memory Subsystem Configuration register - * set EVCTONRPL bit, required when L2 cache is enabled in victim mode + /* Data Memory Subsystem Configuration register. Set EVCTONRPL bit, + * required when L2 cache is enabled in victim mode. */ msr = rdmsr(CPU_DM_CONFIG0); msr.lo |= 0x4000; wrmsr(CPU_DM_CONFIG0, msr);
- /* invalidate L2 cache */ + /* Invalidate L2 cache. */ msr.hi = 0x00; msr.lo = 0x10; wrmsr(CPU_BC_L2_CONF, msr);
- /* Enable L2 cache */ + /* Enable L2 cache. */ msr.hi = 0x00; msr.lo = 0x0f; wrmsr(CPU_BC_L2_CONF, msr); @@ -763,31 +769,37 @@ #define CONFIG_VIDEO_MB 8 #endif
-/** - * set up all LX cache registers, L1, L2, and x86. - */ +/** + * Set up all LX cache registers, L1, L2, and x86. + */ static void setup_lx_cache(void) { - struct msr msr; + struct msr msr;
enable_L1_cache(); enable_L2_cache();
- // Make sure all INVD instructions are treated as WBINVD. We do this - // because we've found some programs which require this behavior. + /* Make sure all INVD instructions are treated as WBINVD. We do this + * because we've found some programs which require this behavior. + */ msr = rdmsr(CPU_DM_CONFIG0); msr.lo |= DM_CONFIG0_LOWER_WBINVD_SET; wrmsr(CPU_DM_CONFIG0, msr);
enable_cache(); - __asm__("wbinvd\n"); + __asm__("wbinvd\n"); /* TODO: Use wbinvd() function? */ }
+/** + * TODO. + * + * @return TODO. + */ u32 get_systop(void) { - struct gliutable *gl = 0; + struct gliutable *gl = NULL; u32 systop; - struct msr msr; + struct msr msr; int i;
for (i = 0; gliu0table[i].desc_name != GL_END; i++) { @@ -798,45 +810,44 @@ } if (gl) { msr = rdmsr(gl->desc_name); - systop = ((msr.hi & 0xFF) << 24) | - ((msr.lo & 0xFFF00000) >> 8); + systop = ((msr.hi & 0xFF) << 24) | ((msr.lo & 0xFFF00000) >> 8); systop += 0x1000; /* 4K */ } else { systop = ((sizeram() - CONFIG_VIDEO_MB) * 1024) - SMM_SIZE - 1024; } + return systop; }
-/** northbridge_init_early Do all the Nasty Bits that have to - * happen. These can be done once memory is up, but before much else - * is done. So we do them in Phase 2. - */ +/** + * Do all the Nasty Bits that have to happen. + * + * These can be done once memory is up, but before much else is done. + * So we do them in phase 2. + */ void northbridge_init_early(void) { - struct msr msr; int i; + struct msr msr; + printk(BIOS_DEBUG, "Enter %s\n", __FUNCTION__);
for (i = 0; gliutables[i]; i++) GLIUInit(gliutables[i]);
- /* Now that the descriptor to memory is set up. */ - /* The memory controller needs one read to synch its lines - * before it can be used. + /* Now that the descriptor to memory is set up, the memory controller + * needs one read to synch it's lines before it can be used. */ i = *(int *)0;
geode_link_priority(); - setup_lx_cache(); - rom_shadow_settings(); - GLPCI_init(); - clock_gating_init();
- __asm__ __volatile__("FINIT\n"); + __asm__ __volatile__("FINIT\n"); /* TODO: Create finit() function? */ + printk(BIOS_DEBUG, "Exit %s\n", __FUNCTION__); }
Modified: LinuxBIOSv3/northbridge/amd/geodelx/raminit.c =================================================================== --- LinuxBIOSv3/northbridge/amd/geodelx/raminit.c 2007-07-07 21:18:47 UTC (rev 438) +++ LinuxBIOSv3/northbridge/amd/geodelx/raminit.c 2007-07-08 00:19:26 UTC (rev 439) @@ -32,16 +32,19 @@ #include <amd_geodelx.h> #include <southbridge/amd/cs5536/cs5536.h>
-static const u8 num_col_addr[] = { - 0x00, 0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F +static const u8 num_col_addr[] = { + 0x00, 0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, };
/** - * Auto-detect, using SPD, the DIMM size. It's the usual magic, with - * all the usual failiure points that can happen. - * @param dimm -- The SMBus address of the DIMM - */ + * Auto-detect, using SPD, the DIMM size. It's the usual magic, with + * all the usual failure points that can happen. + * + * @param dimm TODO + * @param dimm0 The SMBus address of DIMM 0 (mainboard-dependent). + * @param dimm1 The SMBus address of DIMM 1 (mainboard-dependent). + */ static void auto_size_dimm(unsigned int dimm, u8 dimm0, u8 dimm1) { u32 dimm_setting; @@ -51,13 +54,10 @@
dimm_setting = 0;
- /* Check that we have a dimm */ - if (smbus_read_byte(dimm, SPD_MEMORY_TYPE) == 0xFF) { + /* Check that we have a DIMM. */ + if (smbus_read_byte(dimm, SPD_MEMORY_TYPE) == 0xFF) return; - }
- /* Field: Module Banks per DIMM */ - /* EEPROM byte usage: (5) Number of DIMM Banks */ spd_byte = smbus_read_byte(dimm, SPD_NUM_DIMM_BANKS); if ((MIN_MOD_BANKS > spd_byte) && (spd_byte > MAX_MOD_BANKS)) { printk(BIOS_EMERG, "Number of module banks not compatible\n"); @@ -66,8 +66,6 @@ } dimm_setting |= (spd_byte >> 1) << CF07_UPPER_D0_MB_SHIFT;
- /* Field: Banks per SDRAM device */ - /* EEPROM byte usage: (17) Number of Banks on SDRAM Device */ spd_byte = smbus_read_byte(dimm, SPD_NUM_BANKS_PER_SDRAM); if ((MIN_DEV_BANKS > spd_byte) && (spd_byte > MAX_DEV_BANKS)) { printk(BIOS_EMERG, "Number of device banks not compatible\n"); @@ -76,59 +74,58 @@ } dimm_setting |= (spd_byte >> 2) << CF07_UPPER_D0_CB_SHIFT;
- /* Field: DIMM size - *; EEPROM byte usage: (3) Number or Row Addresses - *; (4) Number of Column Addresses - *; (5) Number of DIMM Banks - *; (31) Module Bank Density - *; Size = Module Density * Module Banks - */ if ((smbus_read_byte(dimm, SPD_NUM_ROWS) & 0xF0) || (smbus_read_byte(dimm, SPD_NUM_COLUMNS) & 0xF0)) { - printk(BIOS_EMERG, "Assymetirc DIMM not compatible\n"); + printk(BIOS_EMERG, "Asymmetric DIMM not compatible\n"); post_code(ERROR_UNSUPPORTED_DIMM); hlt(); }
+ /* Size = Module Density * Module Banks */ dimm_size = smbus_read_byte(dimm, SPD_BANK_DENSITY); - /* align so 1GB(bit0) is bit 8, this is a little weird to get gcc to not optimize this out */ + /* Align so 1 GB (bit 0) is bit 8. This is a little weird to get gcc + * to not optimize this out. + */ dimm_size |= (dimm_size << 8); - /* and off 2GB DIMM size : not supported and the 1GB size we just moved up to bit 8 as well as all the extra on top */ + /* And off 2 GB DIMM size: not supported and the 1 GB size we just + * moved up to bit 8 as well as all the extra on top. + */ dimm_size &= 0x01FC; - /* Module Density * Module Banks */ - /* shift to multiply by # DIMM banks */ + /* Module Density * Module Banks */ + /* Shift to multiply by the number of DIMM banks. */ dimm_size <<= (dimm_setting >> CF07_UPPER_D0_MB_SHIFT) & 1; dimm_size = __builtin_ctz(dimm_size); - if (dimm_size > 8) { /* 8 is 1GB only support 1GB per DIMM */ + if (dimm_size > 8) { /* 8 is 1 GB only support 1 GB per DIMM */ printk(BIOS_EMERG, "Only support up to 1 GB per DIMM\n"); post_code(ERROR_DENSITY_DIMM); hlt(); } dimm_setting |= dimm_size << CF07_UPPER_D0_SZ_SHIFT;
- /* Field: PAGE size - * EEPROM byte usage: (4) Number of Column Addresses - * PageSize = 2^# Column Addresses * Data width in bytes (should be 8bytes for a normal DIMM) - * - * But this really works by magic. - *If ma[12:0] is the memory address pins, and pa[12:0] is the physical column address - *that MC generates, here is how the MC assigns the pa onto the ma pins: - * - *ma 12 11 10 09 08 07 06 05 04 03 02 01 00 - *------------------------------------------- - *pa 09 08 07 06 05 04 03 (7 col addr bits = 1K page size) - *pa 10 09 08 07 06 05 04 03 (8 col addr bits = 2K page size) - *pa 11 10 09 08 07 06 05 04 03 (9 col addr bits = 4K page size) - *pa 12 11 10 09 08 07 06 05 04 03 (10 col addr bits = 8K page size) - *pa 13 AP 12 11 10 09 08 07 06 05 04 03 (11 col addr bits = 16K page size) - *pa 14 13 AP 12 11 10 09 08 07 06 05 04 03 (12 col addr bits = 32K page size) - * *AP=autoprecharge bit - * - *Remember that pa[2:0] are zeroed out since it's a 64-bit data bus (8 bytes), - *so lower 3 address bits are dont_cares.So from the table above, - *it's easier to see what the old code is doing: if for example,#col_addr_bits=7(06h), - *it adds 3 to get 10, then does 2^10=1K. Get it? - */ + /* PageSize = 2 ^ (number of column addresses) * data width in bytes + * (should be 8 bytes for a normal DIMM) + * + * If ma[12:0] is the memory address pins, and pa[12:0] is the + * physical column address that the memory controller (MC) generates, + * here is how the MC assigns the pa onto the ma pins: + * + * ma 12 11 10 09 08 07 06 05 04 03 02 01 00 + * ------------------------------------------- + * pa 09 08 07 06 05 04 03 (7 col addr bits = 1K page size) + * pa 10 09 08 07 06 05 04 03 (8 col addr bits = 2K page size) + * pa 11 10 09 08 07 06 05 04 03 (9 col addr bits = 4K page size) + * pa 12 11 10 09 08 07 06 05 04 03 (10 col addr bits = 8K page size) + * pa 13 AP 12 11 10 09 08 07 06 05 04 03 (11 col addr bits = 16K page size) + * pa 14 13 AP 12 11 10 09 08 07 06 05 04 03 (12 col addr bits = 32K page size) + * + * (AP = autoprecharge bit) + * + * Remember that pa[2:0] are zeroed out since it's a 64-bit data bus + * (8 bytes), so lower 3 address bits are dont_cares. So from the + * table above, it's easier to see what the old code is doing: if for + * example, #col_addr_bits = 7 (06h), it adds 3 to get 10, then does + * 2^10=1K. Get it? + */
spd_byte = num_col_addr[smbus_read_byte(dimm, SPD_NUM_COLUMNS) & 0xF]; if (spd_byte > MAX_COL_ADDR) { @@ -137,10 +134,12 @@ hlt(); } spd_byte -= 7; - if (spd_byte > 5) { /* if the value is above 6 it means >12 address lines */ - spd_byte = 7; /* which means >32k so set to disabled */ + /* If the value is above 6 it means >12 address lines... */ + if (spd_byte > 5) { + spd_byte = 7; /* ...which means >32k so set to disabled. */ } - dimm_setting |= spd_byte << CF07_UPPER_D0_PSZ_SHIFT; /* 0=1k,1=2k,2=4k,etc */ + /* 0 = 1k, 1 = 2k, 2 = 4k, etc. */ + dimm_setting |= spd_byte << CF07_UPPER_D0_PSZ_SHIFT;
msr = rdmsr(MC_CF07_DATA); if (dimm == dimm0) { @@ -153,11 +152,15 @@ wrmsr(MC_CF07_DATA, msr); }
-/** Try to compute the max DDR clock rate. The only bad news here is that if you have got a geode link - * speed that is too fast, you are going to pay for it: the system will hlt! - * @param dimm0 dimm0 SMBus address - * @param dimm1 dimm1 SMBus address - */ +/** + * Try to compute the max. DDR clock rate. + * + * The only bad news here is that if you have got a GeodeLink speed that is + * too fast, you are going to pay for it: the system will hlt! + * + * @param dimm0 The SMBus address of DIMM 0 (mainboard-dependent). + * @param dimm1 The SMBus address of DIMM 1 (mainboard-dependent). + */ static void check_ddr_max(u8 dimm0, u8 dimm1) { u8 spd_byte0, spd_byte1; @@ -165,32 +168,32 @@
/* PC133 identifier */ spd_byte0 = smbus_read_byte(dimm0, SPD_MIN_CYCLE_TIME_AT_CAS_MAX); - if (spd_byte0 == 0xFF) { + if (spd_byte0 == 0xFF) spd_byte0 = 0; - } spd_byte1 = smbus_read_byte(dimm1, SPD_MIN_CYCLE_TIME_AT_CAS_MAX); - if (spd_byte1 == 0xFF) { + if (spd_byte1 == 0xFF) spd_byte1 = 0; + + /* I don't think you need this check. */ +#if 0 + if (spd_byte0 < 0xA0 || spd_byte0 < 0xA0) { + printk(BIOS_EMERG, "DIMM overclocked. Check GeodeLink speed\n"); + post_code(POST_PLL_MEM_FAIL); + hlt(); } +#endif
- /* I don't think you need this check. - if (spd_byte0 < 0xA0 || spd_byte0 < 0xA0){ - printk(BIOS_EMERG, "DIMM overclocked. Check GeodeLink Speed\n"); - post_code(POST_PLL_MEM_FAIL); - hlt(); - } */ - - /* Use the slowest DIMM */ + /* Use the slowest DIMM. */ if (spd_byte0 < spd_byte1) { spd_byte0 = spd_byte1; }
- /* Turn SPD ns time into MHZ. Check what the asm does to this math. */ + /* Turn SPD ns time into MHz. Check what the asm does to this math. */ speed = 2 * ((10000 / (((spd_byte0 >> 4) * 10) + (spd_byte0 & 0x0F))));
- /* current speed > max speed? */ + /* Current speed > max speed? */ if (geode_link_speed() > speed) { - printk(BIOS_EMERG, "DIMM overclocked. Check GeodeLink Speed\n"); + printk(BIOS_EMERG, "DIMM overclocked. Check GeodeLink speed\n"); post_code(POST_PLL_MEM_FAIL); hlt(); } @@ -198,11 +201,14 @@
const u16 REFRESH_RATE[] = { 15, 3, 7, 31, 62, 125 }; /* ns */
-/** - * compute a refresh rate. You have to read both dimms and take the one that requires a faster rate. - * @param dimm0 dimm0 SMBus address - * @param dimm1 dimm1 SMBus address - */ +/** + * Compute a refresh rate. + * + * You have to read both DIMMs and take the one that requires a faster rate. + * + * @param dimm0 The SMBus address of DIMM 0 (mainboard-dependent). + * @param dimm1 The SMBus address of DIMM 1 (mainboard-dependent). + */ static void set_refresh_rate(u8 dimm0, u8 dimm1) { u8 spd_byte0, spd_byte1; @@ -223,40 +229,41 @@ } rate1 = REFRESH_RATE[spd_byte1];
- /* Use the faster rate (lowest number) */ + /* Use the faster rate (lowest number). */ if (rate0 > rate1) { rate0 = rate1; }
msr = rdmsr(MC_CF07_DATA); - msr.lo |= ((rate0 * (geode_link_speed() / 2)) / 16) - << CF07_LOWER_REF_INT_SHIFT; + msr.lo |= ((rate0 * (geode_link_speed() / 2)) / 16) + << CF07_LOWER_REF_INT_SHIFT; wrmsr(MC_CF07_DATA, msr); }
-const u8 CASDDR[] = { 5, 5, 2, 6, 3, 7, 4, 0 }; /* 1(1.5), 1.5, 2, 2.5, 3, 3.5, 4, 0 */ +/* 1(1.5), 1.5, 2, 2.5, 3, 3.5, 4, 0 */ +const u8 CASDDR[] = { 5, 5, 2, 6, 3, 7, 4, 0 };
/** - * Compute the CAS rate. - * EEPROM byte usage: (18) SDRAM device attributes - CAS latency - * EEPROM byte usage: (23) SDRAM Minimum Clock Cycle Time @ CLX -.5 - * EEPROM byte usage: (25) SDRAM Minimum Clock Cycle Time @ CLX -1 - * - * The CAS setting is based on the information provided in each DIMMs SPD. - * The speed at which a DIMM can run is described relative to the slowest - * CAS the DIMM supports. Each speed for the relative CAS settings is - * checked that it is within the GeodeLink speed. If it isn't within the GeodeLink - * speed, the CAS setting is removed from the list of good settings for - * the DIMM. This is done for both DIMMs and the lists are compared to - * find the lowest common CAS latency setting. If there are no CAS settings - * in common we out a ERROR_DIFF_DIMMS (78h) to port 80h and halt. - * Result is that we will set fastest CAS Latency based on GeodeLink speed - * and SPD information. - * - * @param dimm0 dimm0 SMBus address - * @param dimm1 dimm1 SMBus address - * - */ + * Compute the CAS rate. + * + * The CAS setting is based on the information provided in each DIMMs SPD. + * + * The speed at which a DIMM can run is described relative to the slowest + * CAS the DIMM supports. Each speed for the relative CAS settings is + * checked that it is within the GeodeLink speed. If it isn't within the + * GeodeLink speed, the CAS setting is removed from the list of good settings + * for the DIMM. + * + * This is done for both DIMMs and the lists are compared to find the lowest + * common CAS latency setting. If there are no CAS settings + * in common we output a ERROR_DIFF_DIMMS (0x78) POST code and halt. + * + * Result is that we will set fastest CAS latency based on GeodeLink speed + * and SPD information. + * + * @param dimm0 The SMBus address of DIMM 0 (mainboard-dependent). + * @param dimm1 The SMBus address of DIMM 1 (mainboard-dependent). + */ static void set_cas(u8 dimm0, u8 dimm1) { u16 glspeed, dimm_speed; @@ -265,72 +272,78 @@
glspeed = geode_link_speed();
- /************************** dimm0 **********************************/ + /* DIMM 0 */ casmap0 = smbus_read_byte(dimm0, SPD_ACCEPTABLE_CAS_LATENCIES); if (casmap0 != 0xFF) { - /* IF -.5 timing is supported, check -.5 timing > GeodeLink */ + /* If -.5 timing is supported, check -.5 timing > GeodeLink. */ + /* EEPROM byte usage: (23) SDRAM Minimum Clock Cycle Time @ CLX -.5 */ spd_byte = smbus_read_byte(dimm0, SPD_SDRAM_CYCLE_TIME_2ND); if (spd_byte != 0) { - /* Turn SPD ns time into MHZ. Check what the asm does to this math. */ + /* Turn SPD ns time into MHz. Check what the asm does + * to this math. + */ dimm_speed = 2 * (10000 / (((spd_byte >> 4) * 10) + (spd_byte & 0x0F))); if (dimm_speed >= glspeed) { - /* IF -1 timing is supported, check -1 timing > GeodeLink */ + /* If -1 timing is supported, check -1 timing > GeodeLink. */ + /* EEPROM byte usage: (25) SDRAM Minimum Clock Cycle Time @ CLX -1 */ spd_byte = smbus_read_byte(dimm0, SPD_SDRAM_CYCLE_TIME_3RD); if (spd_byte != 0) { - /* Turn SPD ns time into MHZ. Check what the asm does to this math. */ + /* Turn SPD ns time into MHz. Check what the asm does to this math. */ dimm_speed = 2 * (10000 / (((spd_byte >> 4) * 10) + (spd_byte & 0x0F))); if (dimm_speed <= glspeed) { - /* set we can use -.5 timing but not -1 */ + /* Set we can use -.5 timing but not -1. */ spd_byte = 31 - __builtin_clz((u32) casmap0); - /* just want bits in the lower byte since we have to cast to a 32 */ + /* Just want bits in the lower byte since we have to cast to a 32. */ casmap0 &= 0xFF << (--spd_byte); } - } /*MIN_CYCLE_10 !=0 */ + } /* MIN_CYCLE_10 != 0 */ } else { - /* Timing_05 < GLspeed, can't use -.5 or -1 timing */ + /* Timing_05 < GLspeed, can't use -.5 or -1 timing. */ spd_byte = 31 - __builtin_clz((u32) casmap0); - /* just want bits in the lower byte since we have to cast to a 32 */ + /* Just want bits in the lower byte since we have to cast to a 32. */ casmap0 &= 0xFF << (spd_byte); } - } /*MIN_CYCLE_05 !=0 */ + } /* MIN_CYCLE_05 != 0 */ } else { /* No DIMM */ casmap0 = 0; }
- /************************** dimm1 **********************************/ + /* DIMM 1 */ casmap1 = smbus_read_byte(dimm1, SPD_ACCEPTABLE_CAS_LATENCIES); if (casmap1 != 0xFF) { - /* IF -.5 timing is supported, check -.5 timing > GeodeLink */ + /* If -.5 timing is supported, check -.5 timing > GeodeLink. */ + /* EEPROM byte usage: (23) SDRAM Minimum Clock Cycle Time @ CLX -.5 */ spd_byte = smbus_read_byte(dimm1, SPD_SDRAM_CYCLE_TIME_2ND); if (spd_byte != 0) { - /* Turn SPD ns time into MHZ. Check what the asm does to this math. */ + /* Turn SPD ns time into MHz. Check what the asm does to this math. */ dimm_speed = 2 * (10000 / (((spd_byte >> 4) * 10) + (spd_byte & 0x0F))); if (dimm_speed >= glspeed) { - /* IF -1 timing is supported, check -1 timing > GeodeLink */ + /* If -1 timing is supported, check -1 timing > GeodeLink. */ + /* EEPROM byte usage: (25) SDRAM Minimum Clock Cycle Time @ CLX -1 */ spd_byte = smbus_read_byte(dimm1, SPD_SDRAM_CYCLE_TIME_3RD); if (spd_byte != 0) { - /* Turn SPD ns time into MHZ. Check what the asm does to this math. */ + /* Turn SPD ns time into MHz. Check what the asm does to this math. */ dimm_speed = 2 * (10000 / (((spd_byte >> 4) * 10) + (spd_byte & 0x0F))); if (dimm_speed <= glspeed) { - /* set we can use -.5 timing but not -1 */ + /* Set we can use -.5 timing but not -1. */ spd_byte = 31 - __builtin_clz((u32) casmap1); - /* just want bits in the lower byte since we have to cast to a 32 */ + /* Just want bits in the lower byte since we have to cast to a 32. */ casmap1 &= 0xFF << (--spd_byte); } - } /*MIN_CYCLE_10 !=0 */ + } /* MIN_CYCLE_10 != 0 */ } else { - /* Timing_05 < GLspeed, can't use -.5 or -1 timing */ + /* Timing_05 < GLspeed, can't use -.5 or -1 timing. */ spd_byte = 31 - __builtin_clz((u32) casmap1); - /* just want bits in the lower byte since we have to cast to a 32 */ + /* Just want bits in the lower byte since we have to cast to a 32. */ casmap1 &= 0xFF << (spd_byte); } - } /*MIN_CYCLE_05 !=0 */ + } /* MIN_CYCLE_05 != 0 */ } else { /* No DIMM */ casmap1 = 0; }
- /********************* CAS_LAT MAP COMPARE ***************************/ + /* Compare CAS latencies. */ if (casmap0 == 0) { spd_byte = CASDDR[__builtin_ctz((u32) casmap1)]; } else if (casmap1 == 0) { @@ -338,7 +351,7 @@ } else if ((casmap0 &= casmap1)) { spd_byte = CASDDR[__builtin_ctz((u32) casmap0)]; } else { - printk(BIOS_EMERG, "DIMM CAS Latencies not compatible\n"); + printk(BIOS_EMERG, "DIMM CAS latencies not compatible\n"); post_code(ERROR_DIFF_DIMMS); hlt(); } @@ -349,12 +362,15 @@ wrmsr(MC_CF8F_DATA, msr); }
-/** - * set latencies for DRAM. These are the famed ras and cas latencies. - * Take the one with the tightest requirements, and use that for both. - * @param dimm0 dimm0 SMBus address - * @param dimm1 dimm1 SMBus address - */ +/** + * Set latencies for DRAM. + * + * These are the famed RAS and CAS latencies. Take the one with the tightest + * requirements, and use that for both. + * + * @param dimm0 The SMBus address of DIMM 0 (mainboard-dependent). + * @param dimm1 The SMBus address of DIMM 1 (mainboard-dependent). + */ static void set_latencies(u8 dimm0, u8 dimm1) { u32 memspeed, dimm_setting; @@ -367,36 +383,29 @@ /* MC_CF8F setup */ /* tRAS */ spd_byte0 = smbus_read_byte(dimm0, SPD_tRAS); - if (spd_byte0 == 0xFF) { + if (spd_byte0 == 0xFF) spd_byte0 = 0; - } spd_byte1 = smbus_read_byte(dimm1, SPD_tRAS); - if (spd_byte1 == 0xFF) { + if (spd_byte1 == 0xFF) spd_byte1 = 0; - } - if (spd_byte0 < spd_byte1) { + if (spd_byte0 < spd_byte1) spd_byte0 = spd_byte1; - }
/* (ns/(1/MHz) = (us*MHZ)/1000 = clocks/1000 = clocks) */ spd_byte1 = (spd_byte0 * memspeed) / 1000; - if (((spd_byte0 * memspeed) % 1000)) { + if (((spd_byte0 * memspeed) % 1000)) ++spd_byte1; - } dimm_setting |= spd_byte1 << CF8F_LOWER_ACT2PRE_SHIFT;
/* tRP */ spd_byte0 = smbus_read_byte(dimm0, SPD_tRP); - if (spd_byte0 == 0xFF) { + if (spd_byte0 == 0xFF) spd_byte0 = 0; - } spd_byte1 = smbus_read_byte(dimm1, SPD_tRP); - if (spd_byte1 == 0xFF) { + if (spd_byte1 == 0xFF) spd_byte1 = 0; - } - if (spd_byte0 < spd_byte1) { + if (spd_byte0 < spd_byte1) spd_byte0 = spd_byte1; - }
/* (ns/(1/MHz) = (us*MHZ)/1000 = clocks/1000 = clocks) */ spd_byte1 = ((spd_byte0 >> 2) * memspeed) / 1000; @@ -407,16 +416,13 @@
/* tRCD */ spd_byte0 = smbus_read_byte(dimm0, SPD_tRCD); - if (spd_byte0 == 0xFF) { + if (spd_byte0 == 0xFF) spd_byte0 = 0; - } spd_byte1 = smbus_read_byte(dimm1, SPD_tRCD); - if (spd_byte1 == 0xFF) { + if (spd_byte1 == 0xFF) spd_byte1 = 0; - } - if (spd_byte0 < spd_byte1) { + if (spd_byte0 < spd_byte1) spd_byte0 = spd_byte1; - }
/* (ns/(1/MHz) = (us*MHZ)/1000 = clocks/1000 = clocks) */ spd_byte1 = ((spd_byte0 >> 2) * memspeed) / 1000; @@ -427,16 +433,13 @@
/* tRRD */ spd_byte0 = smbus_read_byte(dimm0, SPD_tRRD); - if (spd_byte0 == 0xFF) { + if (spd_byte0 == 0xFF) spd_byte0 = 0; - } spd_byte1 = smbus_read_byte(dimm1, SPD_tRRD); - if (spd_byte1 == 0xFF) { + if (spd_byte1 == 0xFF) spd_byte1 = 0; - } - if (spd_byte0 < spd_byte1) { + if (spd_byte0 < spd_byte1) spd_byte0 = spd_byte1; - }
/* (ns/(1/MHz) = (us*MHZ)/1000 = clocks/1000 = clocks) */ spd_byte1 = ((spd_byte0 >> 2) * memspeed) / 1000; @@ -447,8 +450,8 @@
/* tRC = tRP + tRAS */ dimm_setting |= (((dimm_setting >> CF8F_LOWER_ACT2PRE_SHIFT) & 0x0F) + - ((dimm_setting >> CF8F_LOWER_PRE2ACT_SHIFT) & 0x07)) - << CF8F_LOWER_ACT2ACTREF_SHIFT; + ((dimm_setting >> CF8F_LOWER_PRE2ACT_SHIFT) & 0x07)) + << CF8F_LOWER_ACT2ACTREF_SHIFT;
msr = rdmsr(MC_CF8F_DATA); msr.lo &= 0xF00000FF; @@ -459,33 +462,36 @@ /* MC_CF1017 setup */ /* tRFC */ spd_byte0 = smbus_read_byte(dimm0, SPD_tRFC); - if (spd_byte0 == 0xFF) { + if (spd_byte0 == 0xFF) spd_byte0 = 0; - } spd_byte1 = smbus_read_byte(dimm1, SPD_tRFC); - if (spd_byte1 == 0xFF) { + if (spd_byte1 == 0xFF) spd_byte1 = 0; - } - if (spd_byte0 < spd_byte1) { + if (spd_byte0 < spd_byte1) spd_byte0 = spd_byte1; - }
if (spd_byte0) { /* (ns/(1/MHz) = (us*MHZ)/1000 = clocks/1000 = clocks) */ spd_byte1 = (spd_byte0 * memspeed) / 1000; - if (((spd_byte0 * memspeed) % 1000)) { + if (((spd_byte0 * memspeed) % 1000)) ++spd_byte1; - } - } else { /* Not all SPDs have tRFC setting. Use this formula tRFC = tRC + 1 clk */ + } else { + /* Not all SPDs have tRFC setting. + * Use this formula: tRFC = tRC + 1 clk. + */ spd_byte1 = ((dimm_setting >> CF8F_LOWER_ACT2ACTREF_SHIFT) & 0x0F) + 1; } - dimm_setting = spd_byte1 << CF1017_LOWER_REF2ACT_SHIFT; /* note this clears the cf8f dimm setting */ + + /* Note: This clears the cf8f DIMM setting. */ + dimm_setting = spd_byte1 << CF1017_LOWER_REF2ACT_SHIFT; msr = rdmsr(MC_CF1017_DATA); msr.lo &= ~(0x1F << CF1017_LOWER_REF2ACT_SHIFT); msr.lo |= dimm_setting; wrmsr(MC_CF1017_DATA, msr);
- /* tWTR: Set tWTR to 2 for 400MHz and above GLBUS (200Mhz mem) other wise it stay default(1) */ + /* tWTR: Set tWTR to 2 for 400 MHz and above GLBUS (200 Mhz mem) + * otherwise it stay default (1). + */ if (memspeed > 198) { msr = rdmsr(MC_CF1017_DATA); msr.lo &= ~(0x7 << CF1017_LOWER_WR_TO_RD_SHIFT); @@ -494,44 +500,46 @@ } }
-/** - * Set the registers for drive, namely drive and fet strength. - * @param dimm0 dimm0 SMBus address - * @param dimm1 dimm1 SMBus address - */ +/** + * Set the registers for drive, namely drive and fet strength. + * + * @param dimm0 The SMBus address of DIMM 0 (mainboard-dependent). + * @param dimm1 The SMBus address of DIMM 1 (mainboard-dependent). + */ static void set_extended_mode_registers(u8 dimm0, u8 dimm1) { u8 spd_byte0, spd_byte1; struct msr msr; + spd_byte0 = smbus_read_byte(dimm0, SPD_DEVICE_ATTRIBUTES_GENERAL); - if (spd_byte0 == 0xFF) { + if (spd_byte0 == 0xFF) spd_byte0 = 0; - } spd_byte1 = smbus_read_byte(dimm1, SPD_DEVICE_ATTRIBUTES_GENERAL); - if (spd_byte1 == 0xFF) { + if (spd_byte1 == 0xFF) spd_byte1 = 0; - } spd_byte1 &= spd_byte0;
msr = rdmsr(MC_CF07_DATA); - if (spd_byte1 & 1) { /* Drive Strength Control */ + if (spd_byte1 & 1) { + /* Drive Strength Control */ msr.lo |= CF07_LOWER_EMR_DRV_SET; } - if (spd_byte1 & 2) { /* FET Control */ + if (spd_byte1 & 2) { + /* FET Control */ msr.lo |= CF07_LOWER_EMR_QFC_SET; } wrmsr(MC_CF07_DATA, msr); }
/** - * Debug function. Only used when test hardware is connected. - */ + * Debug function. Only used when test hardware is connected. + */ static void EnableMTest(void) { struct msr msr;
msr = rdmsr(GLCP_DELAY_CONTROLS); - msr.hi &= ~(7 << 20); /* clear bits 54:52 */ + msr.hi &= ~(7 << 20); /* Clear bits 54:52. */ if (geode_link_speed() < 200) { msr.hi |= 2 << 20; } @@ -547,9 +555,10 @@ printk(BIOS_DEBUG, "Enabled MTest for TLA debug\n"); }
-/** Set SDRAM registers that need to be set independent of SPD or even presence or absence of DIMMs - * in a slot. Parameters are ignored. - */ +/** + * Set SDRAM registers that need to be set independent of SPD or even + * presence or absence of DIMMs in a slot. Parameters are ignored. + */ void sdram_set_registers(void) { struct msr msr; @@ -570,20 +579,24 @@ msrnum = MC_CF07_DATA; msr = rdmsr(msrnum); msr.lo &= ~0xF0; - msr.lo |= 0x40; /* set refresh to 4SDRAM clocks */ + msr.lo |= 0x40; /* Set refresh to 4 SDRAM clocks. */ wrmsr(msrnum, msr);
- /* Memory Interleave: Set HOI here otherwise default is LOI */ - /* msrnum = MC_CF8F_DATA; - msr = rdmsr(msrnum); - msr.hi |= CF8F_UPPER_HOI_LOI_SET; - wrmsr(msrnum, msr); */ + /* Memory Interleave: Set HOI here otherwise default is LOI. */ +#if 0 + msrnum = MC_CF8F_DATA; + msr = rdmsr(msrnum); + msr.hi |= CF8F_UPPER_HOI_LOI_SET; + wrmsr(msrnum, msr); +#endif }
-/** Set SDRAM registers that need to are determined by SPD. - * @param dimm0 dimm0 SMBus address - * @param dimm1 dimm1 SMBus address - */ +/** + * Set SDRAM registers that need to be determined by SPD. + * + * @param dimm0 The SMBus address of DIMM 0 (mainboard-dependent). + * @param dimm1 The SMBus address of DIMM 1 (mainboard-dependent). + */ void sdram_set_spd_registers(u8 dimm0, u8 dimm1) { u8 spd_byte; @@ -591,15 +604,16 @@ post_code(POST_MEM_SETUP);
spd_byte = smbus_read_byte(dimm0, SPD_MODULE_ATTRIBUTES); - /* Check DIMM is not Register and not Buffered DIMMs. */ + + /* Check DIMM is not Registered and not Buffered DIMMs. */ if ((spd_byte != 0xFF) && (spd_byte & 3)) { - printk(BIOS_EMERG, "dimm0 NOT COMPATIBLE\n"); + printk(BIOS_EMERG, "DIMM 0 NOT COMPATIBLE!\n"); post_code(ERROR_UNSUPPORTED_DIMM); hlt(); } spd_byte = smbus_read_byte(dimm1, SPD_MODULE_ATTRIBUTES); if ((spd_byte != 0xFF) && (spd_byte & 3)) { - printk(BIOS_EMERG, "dimm1 NOT COMPATIBLE\n"); + printk(BIOS_EMERG, "DIMM 1 NOT COMPATIBLE!\n"); post_code(ERROR_UNSUPPORTED_DIMM); hlt(); } @@ -609,79 +623,85 @@ /* Check that the memory is not overclocked. */ check_ddr_max(dimm0, dimm1);
- /* Size the DIMMS */ - /* this is gross. It is an artifact of our move to parametes instead of #defines. FIX ME */ - /* the fix is trivial but I want to see it work first. */ + /* Size the DIMMS. + * This is gross. It is an artifact of our move to parametes instead of + * #defines. FIXME! The fix is trivial but I want to see it work first. + */ post_code(POST_MEM_SETUP3); auto_size_dimm(dimm0, dimm0, dimm1); post_code(POST_MEM_SETUP4); auto_size_dimm(dimm1, dimm0, dimm1);
- /* Set CAS latency */ + /* Set CAS latency. */ post_code(POST_MEM_SETUP5); set_cas(dimm0, dimm1);
- /* Set all the other latencies here (tRAS, tRP....) */ + /* Set all the other latencies here (tRAS, tRP...). */ set_latencies(dimm0, dimm1);
- /* Set Extended Mode Registers */ + /* Set Extended Mode Registers. */ set_extended_mode_registers(dimm0, dimm1);
- /* Set Memory Refresh Rate */ + /* Set Memory Refresh Rate. */ set_refresh_rate(dimm0, dimm1); - }
/** - * enable the DRAMs. - * Section 6.1.3, LX processor databooks, BIOS Initialization Sequence - * Section 4.1.4, GX/CS5535 GeodeROM Porting guide - * Turn on MC/DIMM interface per JEDEC - * 1) Clock stabilizes > 200us - * 2) Assert CKE - * 3) Precharge All to put all banks into an idles state - * 4) EMRS to enable DLL - * 6) MRS w/ memory config & reset DLL set - * 7) Wait 200 clocks (2us) - * 8) Precharge All and 2 Auto refresh - * 9) MRS w/ memory config & reset DLL clear - * 8) DDR SDRAM ready for normal operation - * - * @param dimm0 dimm0 SMBus address - * @param dimm1 dimm1 SMBus address - */ + * Enable the DRAMs. + * + * Section 6.1.3, LX processor databooks, BIOS Initialization Sequence + * Section 4.1.4, GX/CS5535 GeodeROM Porting guide + * + * Turn on MC/DIMM interface per JEDEC: + * 1) Clock stabilizes > 200us + * 2) Assert CKE + * 3) Precharge All to put all banks into an idle state + * 4) EMRS to enable DLL + * 6) MRS w/ memory config & reset DLL set + * 7) Wait 200 clocks (2us) + * 8) Precharge All and 2 Auto refresh + * 9) MRS w/ memory config & reset DLL clear + * 8) DDR SDRAM ready for normal operation + * + * @param dimm0 The SMBus address of DIMM 0 (mainboard-dependent). + * @param dimm1 The SMBus address of DIMM 1 (mainboard-dependent). + */ void sdram_enable(u8 dimm0, u8 dimm1) { u32 i, msrnum; struct msr msr;
- post_code(POST_MEM_ENABLE); // post_76h + post_code(POST_MEM_ENABLE);
- /* Only enable MTest for TLA memory debug */ - /*EnableMTest(); */ + /* Only enable MTest for TLA memory debug. */ + /* EnableMTest(); */
- /* If both Page Size = "Not Installed" we have a problems and should halt. */ + /* If both Page Size = "Not Installed" we have a problem and + * should halt. + */ msr = rdmsr(MC_CF07_DATA); - if ((msr.hi & ((7 << CF07_UPPER_D1_PSZ_SHIFT) | (7 << CF07_UPPER_D0_PSZ_SHIFT))) == - ((7 << CF07_UPPER_D1_PSZ_SHIFT) | (7 << CF07_UPPER_D0_PSZ_SHIFT))) { + if ((msr.hi & ((7 << CF07_UPPER_D1_PSZ_SHIFT) | + (7 << CF07_UPPER_D0_PSZ_SHIFT))) == + ((7 << CF07_UPPER_D1_PSZ_SHIFT) | + (7 << CF07_UPPER_D0_PSZ_SHIFT))) { printk(BIOS_EMERG, "No memory in the system\n"); post_code(ERROR_NO_DIMMS); hlt(); }
- /* Set CKEs */ + /* Set CKEs. */ msrnum = MC_CFCLK_DBUG; msr = rdmsr(msrnum); msr.lo &= ~(CFCLK_LOWER_MASK_CKE_SET0 | CFCLK_LOWER_MASK_CKE_SET1); wrmsr(msrnum, msr);
- /* Force Precharge All on next command, EMRS */ + /* Force Precharge All on next command, EMRS. */ msrnum = MC_CFCLK_DBUG; msr = rdmsr(msrnum); msr.lo |= CFCLK_LOWER_FORCE_PRE_SET; wrmsr(msrnum, msr);
- /* EMRS to enable DLL (pre-setup done in setExtendedModeRegisters) */ + /* EMRS to enable DLL (pre-setup done in setExtendedModeRegisters). */ msrnum = MC_CF07_DATA; msr = rdmsr(msrnum); msr.lo |= CF07_LOWER_PROG_DRAM_SET | CF07_LOWER_LOAD_MODE_DDR_SET; @@ -689,13 +709,13 @@ msr.lo &= ~(CF07_LOWER_PROG_DRAM_SET | CF07_LOWER_LOAD_MODE_DDR_SET); wrmsr(msrnum, msr);
- /* Clear Force Precharge All */ + /* Clear Force Precharge All. */ msrnum = MC_CFCLK_DBUG; msr = rdmsr(msrnum); msr.lo &= ~CFCLK_LOWER_FORCE_PRE_SET; wrmsr(msrnum, msr);
- /* MRS Reset DLL - set */ + /* MRS Reset DLL - set. */ msrnum = MC_CF07_DATA; msr = rdmsr(msrnum); msr.lo |= CF07_LOWER_PROG_DRAM_SET | CF07_LOWER_LOAD_MODE_DLL_RESET; @@ -703,23 +723,23 @@ msr.lo &= ~(CF07_LOWER_PROG_DRAM_SET | CF07_LOWER_LOAD_MODE_DLL_RESET); wrmsr(msrnum, msr);
- /* 2us delay (200 clocks @ 200Mhz). We probably really don't - * need this but.... better safe. + /* 2us delay (200 clocks @ 200Mhz). We probably really don't need + * this but... better safe. + * + * Wait two 'port 61 ticks' (between 15us and 30us). + * This would be endless if the timer is stuck. */ - /* Wait 2 PORT61 ticks. between 15us and 30us */ - /* This would be endless if the timer is stuck. */ - while ((inb(0x61))) ; /* find the first edge */ - while (!(~inb(0x61))) ; + while ((inb(0x61))); /* Find the first edge. */ + while (!(~inb(0x61)));
- /* Force Precharge All on the next command, auto-refresh */ + /* Force Precharge All on the next command, auto-refresh. */ msrnum = MC_CFCLK_DBUG; msr = rdmsr(msrnum); msr.lo |= CFCLK_LOWER_FORCE_PRE_SET; wrmsr(msrnum, msr);
- /* Manually AUTO refresh #1 */ - /* If auto refresh was not enabled above we would need to do 8 - * refreshes to prime the pump before these 2. + /* Manually AUTO refresh #1. If auto refresh was not enabled above we + * would need to do 8 refreshes to prime the pump before these 2. */ msrnum = MC_CF07_DATA; msr = rdmsr(msrnum); @@ -728,14 +748,15 @@ msr.lo &= ~CF07_LOWER_REF_TEST_SET; wrmsr(msrnum, msr);
- /* Clear Force Precharge All */ + /* Clear Force Precharge All. */ msrnum = MC_CFCLK_DBUG; msr = rdmsr(msrnum); msr.lo &= ~CFCLK_LOWER_FORCE_PRE_SET; wrmsr(msrnum, msr);
- /* Manually AUTO refresh */ - /* The MC should insert the right delay between the refreshes */ + /* Manually AUTO refresh. + * The MC should insert the right delay between the refreshes. + */ msrnum = MC_CF07_DATA; msr = rdmsr(msrnum); msr.lo |= CF07_LOWER_REF_TEST_SET; @@ -743,7 +764,7 @@ msr.lo &= ~CF07_LOWER_REF_TEST_SET; wrmsr(msrnum, msr);
- /* MRS Reset DLL - clear */ + /* MRS Reset DLL - clear. */ msrnum = MC_CF07_DATA; msr = rdmsr(msrnum); msr.lo |= CF07_LOWER_PROG_DRAM_SET; @@ -751,13 +772,13 @@ msr.lo &= ~CF07_LOWER_PROG_DRAM_SET; wrmsr(msrnum, msr);
- /* Allow MC to tristate during idle cycles with MTEST OFF */ + /* Allow MC to tristate during idle cycles with MTEST OFF. */ msrnum = MC_CFCLK_DBUG; msr = rdmsr(msrnum); msr.lo &= ~CFCLK_LOWER_TRISTATE_DIS_SET; wrmsr(msrnum, msr);
- /* Disable SDCLK dimm1 slot if no DIMM installed to save power. */ + /* Disable SDCLK DIMM 1 slot if no DIMM installed (to save power). */ msr = rdmsr(MC_CF07_DATA); if ((msr.hi & (7 << CF07_UPPER_D1_PSZ_SHIFT)) == (7 << CF07_UPPER_D1_PSZ_SHIFT)) { @@ -767,53 +788,54 @@ wrmsr(msrnum, msr); }
- /* Set PMode0 Sensitivity Counter */ + /* Set PMode0 Sensitivity Counter. */ msr.lo = 0; /* pmode 0=0 most aggressive */ msr.hi = 0x200; /* pmode 1=200h */ wrmsr(MC_CF_PMCTR, msr);
- /* Set PMode1 Up delay enable */ + /* Set PMode1 Up delay enable. */ msrnum = MC_CF1017_DATA; msr = rdmsr(msrnum); msr.lo |= (209 << 8); /* bits[15:8] = 209 */ wrmsr(msrnum, msr);
printk(BIOS_DEBUG, "DRAM controller init done.\n"); - post_code(POST_MEM_SETUP_GOOD); //0x7E + post_code(POST_MEM_SETUP_GOOD);
- /* make sure there is nothing stale in the cache */ + /* Make sure there is nothing stale in the cache. */ /* CAR stack is in the cache __asm__ __volatile__("wbinvd\n"); */
- /* The RAM dll needs a write to lock on so generate a few dummy writes */ - /* Note: The descriptor needs to be enabled to point at memory */ + /* The RAM dll needs a write to lock on so generate a few dummy + * writes. Note: The descriptor needs to be enabled to point at memory. + */ volatile unsigned long *ptr; for (i = 0; i < 5; i++) { ptr = (void *)i; *ptr = (unsigned long)i; } - /* SWAPSiF for PBZ 4112 (Errata 34) */ - /* check for failed DLL settings now that we have done a memory write. */ + + /* SWAPSiF for PBZ 4112 (Errata 34) + * Check for failed DLL settings now that we have done a + * memory write. + */ msrnum = GLCP_DELAY_CONTROLS; msr = rdmsr(msrnum); if ((msr.lo & 0x7FF) == 0x104) { + /* If you had it you would need to clear out the fail boot + * count flag (depending on where it counts from etc). + */
- /* If you had it you would need to clear out the fail - * boot count flag (depending on where it counts from - * etc). - */ - /* The we are about to perform clears the PM_SSC - * register in the 5536 so will need to store the S3 - * resume *flag in NVRAM otherwise it would do a - * normal boot + * register in the CS5536 so will need to store the S3 + * resume flag in NVRAM otherwise it would do a normal boot. */
- /* Reset the system */ + /* Reset the system. */ msrnum = MDD_SOFT_RESET; msr = rdmsr(msrnum); msr.lo |= 1; wrmsr(msrnum, msr); } + printk(BIOS_DEBUG, "RAM DLL lock\n"); - }