summaryrefslogtreecommitdiff
path: root/src/northbridge
diff options
context:
space:
mode:
Diffstat (limited to 'src/northbridge')
-rw-r--r--src/northbridge/amd/gx2/chip.h3
-rw-r--r--src/northbridge/amd/gx2/chipsetinit.c90
-rw-r--r--src/northbridge/amd/gx2/grphinit.c24
-rw-r--r--src/northbridge/amd/gx2/northbridge.c65
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);