diff options
Diffstat (limited to 'src/northbridge')
-rw-r--r-- | src/northbridge/amd/gx2/chip.h | 3 | ||||
-rw-r--r-- | src/northbridge/amd/gx2/chipsetinit.c | 90 | ||||
-rw-r--r-- | src/northbridge/amd/gx2/grphinit.c | 24 | ||||
-rw-r--r-- | src/northbridge/amd/gx2/northbridge.c | 65 |
4 files changed, 139 insertions, 43 deletions
diff --git a/src/northbridge/amd/gx2/chip.h b/src/northbridge/amd/gx2/chip.h index 46e6ae87be..556c0e1de0 100644 --- a/src/northbridge/amd/gx2/chip.h +++ b/src/northbridge/amd/gx2/chip.h @@ -1,6 +1,7 @@ struct northbridge_amd_gx2_config { - uint16_t irqmap; + uint16_t irqmap; + int setupflash; }; extern struct chip_operations northbridge_amd_gx2_ops; diff --git a/src/northbridge/amd/gx2/chipsetinit.c b/src/northbridge/amd/gx2/chipsetinit.c index a149d626ef..3bd73f7c9c 100644 --- a/src/northbridge/amd/gx2/chipsetinit.c +++ b/src/northbridge/amd/gx2/chipsetinit.c @@ -163,7 +163,90 @@ pmChipsetInit(void) { } +struct FLASH_DEVICE { + unsigned char fType; /* Flash type: NOR or NAND */ + unsigned char fInterface; /* Flash interface: I/O or Memory */ + unsigned long fMask; /* Flash size/mask */ +}; + +struct FLASH_DEVICE FlashInitTable[] = { + { FLASH_TYPE_NAND, FLASH_IF_MEM, FLASH_MEM_4K }, /* CS0, or Flash Device 0 */ + { FLASH_TYPE_NONE, 0, 0 }, /* CS1, or Flash Device 1 */ + { FLASH_TYPE_NONE, 0, 0 }, /* CS2, or Flash Device 2 */ + { FLASH_TYPE_NONE, 0, 0 }, /* CS3, or Flash Device 3 */ +}; + +#define FlashInitTableLen (sizeof(FlashInitTable)/sizeof(FlashInitTable[0])) + +uint32_t FlashPort[] = { + MDD_LBAR_FLSH0, + MDD_LBAR_FLSH1, + MDD_LBAR_FLSH2, + MDD_LBAR_FLSH3 + }; + +/*************************************************************************** + * + * ChipsetFlashSetup + * + * Flash LBARs need to be setup before VSA init so the PCI BARs have + * correct size info. Call this routine only if flash needs to be + * configured (don't call it if you want IDE). + * + * Entry: + * Exit: + * Destroys: + * + **************************************************************************/ +static void ChipsetFlashSetup(void) +{ + msr_t msr; + int i; + int numEnabled = 0; + + printk_debug("ChipsetFlashSetup++\n"); + for (i = 0; i < FlashInitTableLen; i++) { + if (FlashInitTable[i].fType != FLASH_TYPE_NONE) { + printk_debug("Enable CS%d\n", i); + /* we need to configure the memory/IO mask */ + msr = rdmsr(FlashPort[i]); + msr.hi = 0; /* start with the "enabled" bit clear */ + if (FlashInitTable[i].fType == FLASH_TYPE_NAND) + msr.hi |= 0x00000002; + else + msr.hi &= ~0x00000002; + if (FlashInitTable[i].fInterface == FLASH_IF_MEM) + msr.hi |= 0x00000004; + else + msr.hi &= ~0x00000004; + msr.hi |= FlashInitTable[i].fMask; + printk_debug("WRMSR(0x%08X, %08X_%08X)\n", FlashPort[i], msr.hi, msr.lo); + wrmsr(FlashPort[i], msr); + + /* now write-enable the device */ + msr = rdmsr(MDD_NORF_CNTRL); + msr.lo |= (1 << i); + printk_debug("WRMSR(0x%08X, %08X_%08X)\n", MDD_NORF_CNTRL, msr.hi, msr.lo); + wrmsr(MDD_NORF_CNTRL, msr); + + /* update the number enabled */ + numEnabled++; + } + } + + /* enable the flash */ + if (0 != numEnabled) { + msr = rdmsr(MDD_PIN_OPT); + msr.lo &= ~1; /* PIN_OPT_IDE */ + printk_debug("WRMSR(0x%08X, %08X_%08X)\n", MDD_PIN_OPT, msr.hi, msr.lo); + wrmsr(MDD_PIN_OPT, msr); + } + printk_debug("ChipsetFlashSetup--\n"); + +} + + /* ***************************************************************************/ /* **/ /* * ChipsetGeodeLinkInit*/ @@ -202,7 +285,7 @@ ChipsetGeodeLinkInit(void){ } void -chipsetinit (void){ +chipsetinit (struct northbridge_amd_gx2_config *nb){ msr_t msr; struct msrinit *csi; int i; @@ -275,8 +358,9 @@ chipsetinit (void){ /* Flash Setup*/ - printk_err("NOT DOING ChipsetFlashSetup()!!!!!!!!!!!!!!!!!!\n"); -// ChipsetFlashSetup(); + printk_err("%sDOING ChipsetFlashSetup()!!!!!!!!!!!!!!!!!!\n", nb->setupflash? "NOT " : ""); + if (nb->setupflash) + ChipsetFlashSetup(); diff --git a/src/northbridge/amd/gx2/grphinit.c b/src/northbridge/amd/gx2/grphinit.c index 1d115c8c76..4e0da1789d 100644 --- a/src/northbridge/amd/gx2/grphinit.c +++ b/src/northbridge/amd/gx2/grphinit.c @@ -1,26 +1,32 @@ #include <arch/io.h> #include <stdint.h> - +#include <cpu/amd/vr.h> + #define VIDEO_MB 8 // MB of video memory -#define VRC_INDEX 0xAC1C // Index register -#define VRC_DATA 0xAC1E // Data register -#define VR_UNLOCK 0xFC53 // Virtual register unlock code -#define VRC_VG 0x02 // SoftVG Class -#define VG_MEM_SIZE 0x00 // bits 7:0 - 512K unit size, bit 8 controller priority - - /* * Write to a Virtual Register * AX = Class/Index * CX = data to write */ -static void vrWrite(uint16_t wClassIndex, uint16_t wData) +void vrWrite(uint16_t wClassIndex, uint16_t wData) { outl(((uint32_t) VR_UNLOCK << 16) | wClassIndex, VRC_INDEX); outw(wData, VRC_DATA); } + /* + * Read from a Virtual Register + * AX = Class/Index + * Returns a 16-bit word of data + */ +uint16_t vrRead(uint16_t wClassIndex) +{ + uint16_t wData; + outl(((uint32_t) VR_UNLOCK << 16) | wClassIndex, VRC_INDEX); + wData = inw(VRC_DATA); + return wData; +} /* * This function mirrors the Graphics_Init routine in GeodeROM. diff --git a/src/northbridge/amd/gx2/northbridge.c b/src/northbridge/amd/gx2/northbridge.c index 6ef9d55596..a0ad84669f 100644 --- a/src/northbridge/amd/gx2/northbridge.c +++ b/src/northbridge/amd/gx2/northbridge.c @@ -12,7 +12,7 @@ #include <cpu/amd/gx2def.h> #include <cpu/x86/msr.h> #include <cpu/x86/cache.h> - +#include <cpu/amd/vr.h> #define VIDEO_MB 8 extern void graphics_init(void); @@ -120,6 +120,28 @@ struct msr_defaults { {0} }; +/* note that dev is NOT used -- yet */ +static void irq_init_steering(struct device *dev, uint16_t irq_map) { + /* Set up IRQ steering */ + uint32_t pciAddr = 0x80000000 | (CHIPSET_DEV_NUM << 11) | 0x5C; + + printk_debug("%s(%08X [%08X], %04X)\n", __FUNCTION__, dev, pciAddr, irq_map); + + /* The IRQ steering values (in hex) are effectively dcba, where: + * <a> represents the IRQ for INTA, + * <b> represents the IRQ for INTB, + * <c> represents the IRQ for INTC, and + * <d> represents the IRQ for INTD. + * Thus, a value of irq_map = 0xAA5B translates to: + * INTA = IRQB (IRQ 11) + * INTB = IRQ5 (IRQ 5) + * INTC = IRQA (IRQ 10) + * INTD = IRQA (IRQ 10) + */ + outl(pciAddr & ~3, 0xCF8); + outl(irq_map, 0xCFC); +} + /* * setup_gx2_cache @@ -198,11 +220,12 @@ setup_gx2(void) msr.lo = 0x100 | ( ((membytes >>12) & 0xfff) << 20); wrmsr(0x40000029, msr); #endif +#if 0 msr = rdmsr(0x10000028); printk_debug("MSR 0x%x is now 0x%x:0x%x\n", 0x10000028, msr.hi,msr.lo); msr = rdmsr(0x40000029); printk_debug("MSR 0x%x is now 0x%x:0x%x\n", 0x40000029, msr.hi,msr.lo); - +#endif #if 1 /* fixme: SMM MSR 0x10000026 and 0x400000023 */ /* calculate the OFFSET field */ @@ -253,9 +276,11 @@ static void enable_shadow(device_t dev) static void northbridge_init(device_t dev) { + struct northbridge_amd_gx2_config *nb = (struct northbridge_amd_gx2_config *)dev->chip_info; printk_debug("northbridge: %s()\n", __FUNCTION__); enable_shadow(dev); + irq_init_steering(dev, nb->irqmap); } static struct device_operations northbridge_operations = { @@ -318,6 +343,7 @@ static void tolm_test(void *gp, struct device *dev, struct resource *new) *best_p = best; } +#if 0 static uint32_t find_pci_tolm(struct bus *bus) { struct resource *min; @@ -330,7 +356,7 @@ static uint32_t find_pci_tolm(struct bus *bus) } return tolm; } - +#endif #define FRAMEBUFFERK 4096 static void pci_domain_set_resources(device_t dev) @@ -380,8 +406,8 @@ static void pci_domain_set_resources(device_t dev) idx = 10; ram_resource(dev, idx++, 0, tolmk); } - assign_resources(&dev->link[0]); #endif + assign_resources(&dev->link[0]); } static unsigned int pci_domain_scan_bus(device_t dev, unsigned int max) @@ -417,33 +443,13 @@ static struct device_operations cpu_bus_ops = { void chipsetInit (void); -/* note that dev is NOT used -- yet */ -static void irq_init(struct device *dev, uint16_t irq_map) { - - /* Set up IRQ steering */ - uint32_t pciAddr = 0x80000000 | (CHIPSET_DEV_NUM << 11) | 0x5C; - - printk_debug("OLPC REVA ENTER %s\n", __FUNCTION__); - - /* The IRQ steering values (in hex) are effectively dcba, where: - * <a> represents the IRQ for INTA, - * <b> represents the IRQ for INTB, - * <c> represents the IRQ for INTC, and - * <d> represents the IRQ for INTD. - * Thus, a value of irq_map = 0xAA5B translates to: - * INTA = IRQB (IRQ 11) - * INTB = IRQ5 (IRQ 5) - * INTC = IRQA (IRQ 10) - * INTD = IRQA (IRQ 10) - */ - outl(pciAddr & ~3, 0xCF8); - outl(irq_map, 0xCFC); -} - - static void enable_dev(struct device *dev) { printk_debug("gx2 north: enable_dev\n"); + void northbridgeinit(void); + void chipsetinit(struct northbridge_amd_gx2_config *nb); + void setup_realmode_idt(void); + void do_vsmbios(void); /* Set the operations if it is a special bus type */ if (dev->path.type == DEVICE_PATH_PCI_DOMAIN) { struct northbridge_amd_gx2_config *nb = (struct northbridge_amd_gx2_config *)dev->chip_info; @@ -452,12 +458,11 @@ static void enable_dev(struct device *dev) /* cpubug MUST be called before setup_gx2(), so we force the issue here */ northbridgeinit(); cpubug(); - chipsetinit(); + chipsetinit(nb); setup_gx2(); /* do this here for now -- this chip really breaks our device model */ setup_realmode_idt(); do_vsmbios(); - irq_init(dev, nb->irqmap); graphics_init(); dev->ops = &pci_domain_ops; pci_set_method(dev); |