summaryrefslogtreecommitdiff
path: root/src/mainboard/iwave/iWRainbowG6/romstage.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mainboard/iwave/iWRainbowG6/romstage.c')
-rw-r--r--src/mainboard/iwave/iWRainbowG6/romstage.c379
1 files changed, 379 insertions, 0 deletions
diff --git a/src/mainboard/iwave/iWRainbowG6/romstage.c b/src/mainboard/iwave/iWRainbowG6/romstage.c
new file mode 100644
index 0000000000..339a8f5eec
--- /dev/null
+++ b/src/mainboard/iwave/iWRainbowG6/romstage.c
@@ -0,0 +1,379 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2009-2010 iWave Systems
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of
+ * the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#include <stdint.h>
+#include <string.h>
+
+#include <arch/io.h>
+#include <arch/romcc_io.h>
+#include <device/pci_def.h>
+#include <device/pnp_def.h>
+#include <cpu/x86/lapic.h>
+#include <cpu/x86/cache.h>
+#include <arch/cpu.h>
+
+#include <console/console.h>
+#if 0
+#include "ram/ramtest.c"
+#include "southbridge/intel/sch/early_smbus.c"
+#endif
+
+//#include "pc80/mc146818rtc_early.c"
+//#include "pc80/serial.c"
+
+#define RFID_TEST 0
+
+#if RFID_TEST
+#define RFID_ADDR 0xA0
+#define RFID_SELECT_CARD_COMMAND 0x01
+#define SELECT_COMMAND_LENGTH 0x01
+
+#define SMBUS_BASE_ADDRESS 0x400
+
+static u32 sch_SMbase_read(void)
+{
+ u32 SMBusBase;
+ SMBusBase = pci_read_config32(PCI_DEV(0, 0x1f, 0), 0x40); /*SM Bus Address */
+ SMBusBase &= 0xFFFF;
+ printk(BIOS_DEBUG, "SM Bus Base. =%x\r\n", SMBusBase);
+ return SMBusBase;
+}
+
+static void sch_SMbase_init(void)
+{
+ u32 SMBusBase;
+ SMBusBase = sch_SMbase_read();
+ outb(0x3F, SMBusBase + SMBCLKDIV);
+}
+
+static void sch_SMbus_regs(void)
+{
+ u32 SMBusBase;
+ SMBusBase = sch_SMbase_read();
+ printk(BIOS_DEBUG, "SMBHSTCNT. =%x\r\n", inb(SMBusBase + SMBHSTCNT));
+ printk(BIOS_DEBUG, "SMBHSTSTS. =%x\r\n", inb(SMBusBase + SMBHSTSTS));
+ printk(BIOS_DEBUG, "SMBCLKDIV. =%x\r\n", inb(SMBusBase + SMBCLKDIV));
+
+ printk(BIOS_DEBUG, "SMBHSTADD. =%x\r\n", inb(SMBusBase + SMBHSTADD));
+ printk(BIOS_DEBUG, "SMBHSTCMD. =%x\r\n", inb(SMBusBase + SMBHSTCMD));
+}
+
+void smb_clear()
+{
+ u32 SMBusBase;
+ SMBusBase = sch_SMbase_read();
+ outb(0x00, SMBusBase + SMBHSTCNT);
+ outb(0x07, SMBusBase + SMBHSTSTS);
+}
+
+void data_clear()
+{
+ u32 SMBusBase;
+ SMBusBase = sch_SMbase_read();
+ outb(0x00, SMBusBase + SMBHSTDAT0);
+ outb(0x00, SMBusBase + SMBHSTCMD);
+ outb(0x00, SMBusBase + SMBHSTDAT1);
+ outb(0x00, SMBusBase + SMBHSTDATB);
+ outb(0x00, SMBusBase + (SMBHSTDATB + 0x1));
+ outb(0x00, SMBusBase + (SMBHSTDATB + 0x2));
+ outb(0x00, SMBusBase + (SMBHSTDATB + 0x3));
+ outb(0x00, SMBusBase + (SMBHSTDATB + 0x4));
+ outb(0x00, SMBusBase + (SMBHSTDATB + 0x5));
+ outb(0x00, SMBusBase + (SMBHSTDATB + 0x6));
+}
+
+void transaction1(unsigned char dev_addr)
+{
+ int temp, a;
+ u32 SMBusBase;
+ SMBusBase = sch_SMbase_read();
+ printk(BIOS_DEBUG, "Transaction 1");
+ //clear the control and status registers
+ smb_clear();
+ //clear the data register
+ data_clear();
+ //program TSA register
+ outb(dev_addr, SMBusBase + SMBHSTADD);
+ //program command register
+ outb(0x04, SMBusBase + SMBHSTCMD);
+ //write data register
+ outb(0x04, SMBusBase + SMBHSTDAT0);
+ outb(0x04, SMBusBase + SMBHSTDATB);
+
+ outb(0x09, SMBusBase + (SMBHSTDATB + 0x1));
+ outb(0x11, SMBusBase + (SMBHSTDATB + 0x2));
+ outb(0x22, SMBusBase + (SMBHSTDATB + 0x3));
+
+ //set the control register
+ outb(0x15, SMBusBase + SMBHSTCNT);
+ //check the status register for busy state
+ //sch_SMbus_regs ();
+ temp = inb(SMBusBase + SMBHSTSTS);
+ //printk(BIOS_DEBUG, "SM Bus Busy.. status =%x\r\n",temp);
+ //printk(BIOS_DEBUG, "SMBHSTSTS. =%x\r\n",inb(SMBusBase+SMBHSTSTS));
+ do {
+ temp = inb(SMBusBase + SMBHSTSTS);
+ printk(BIOS_DEBUG, "SM Bus Busy.. status =%x\r\n", temp);
+ //sch_SMbus_regs ();
+ printk(BIOS_DEBUG, "SMBHSTSTS. =%x\r\n",
+ inb(SMBusBase + SMBHSTSTS));
+ if (temp > 0)
+ break;
+ } while (1);
+
+ switch (temp) {
+ case 1:
+ printk(BIOS_DEBUG, "SM Bus Success");
+ break;
+ default:
+ printk(BIOS_DEBUG, "SM Bus error %d", temp);
+ break;
+
+ }
+ sch_SMbus_regs();
+ printk(BIOS_DEBUG, "Command in TRansaction 1=%x\r\n\n",
+ inb(SMBusBase + SMBHSTCMD));
+}
+
+void transaction2(unsigned char dev_addr)
+{
+ int temp, a;
+ u32 SMBusBase;
+ SMBusBase = sch_SMbase_read();
+ printk(BIOS_DEBUG, "Transaction 2");
+ //clear the control and status registers
+ smb_clear();
+ //clear the data register
+ data_clear();
+ //program TSA register
+ outb(dev_addr, SMBusBase + SMBHSTADD);
+ //program command register
+ outb(0x03, SMBusBase + SMBHSTCMD);
+ //write data register
+ outb(0x02, SMBusBase + SMBHSTDAT0);
+ outb(0x03, SMBusBase + SMBHSTDATB);
+ outb(0x09, SMBusBase + (SMBHSTDATB + 0x1));
+ outb(0x15, SMBusBase + SMBHSTCNT);
+ //check the status register for busy state
+ //sch_SMbus_regs ();
+ temp = inb(SMBusBase + SMBHSTSTS);
+ //printk(BIOS_DEBUG, "SM Bus Busy.. status =%x\r\n",temp);
+ //printk(BIOS_DEBUG, "SMBHSTSTS. =%x\r\n",inb(SMBusBase+SMBHSTSTS));
+ do {
+ temp = inb(SMBusBase + SMBHSTSTS);
+ printk(BIOS_DEBUG, "SM Bus Busy.. status =%x\r\n", temp);
+ //sch_SMbus_regs ();
+ printk(BIOS_DEBUG, "SMBHSTSTS. =%x\r\n",
+ inb(SMBusBase + SMBHSTSTS));
+ if (temp > 0)
+ break;
+ } while (1);
+
+ switch (temp) {
+ case 1:
+ printk(BIOS_DEBUG, "SM Bus Success");
+ break;
+ default:
+ printk(BIOS_DEBUG, "SM Bus error %d", temp);
+ break;
+
+ }
+ sch_SMbus_regs();
+
+ printk(BIOS_DEBUG, "Command in TRansaction 2=%x\r\n\n",
+ inb(SMBusBase + SMBHSTCMD));
+}
+
+void transaction3(unsigned char dev_addr)
+{
+ int temp, index, length;
+ u32 SMBusBase;
+ SMBusBase = sch_SMbase_read();
+ printk(BIOS_DEBUG, "smb_read_multiple_bytes");
+ smb_clear();
+ data_clear();
+ outb(dev_addr, SMBusBase + SMBHSTADD);
+ outb(0x03, SMBusBase + SMBHSTCMD);
+ outb(0x11, SMBusBase + SMBHSTCNT);
+
+ //data_clear();
+ outb(dev_addr + 1, SMBusBase + SMBHSTADD);
+
+ outb(0x15, SMBusBase + SMBHSTCNT);
+
+ // sch_SMbus_regs ();
+ //check the status register for busy state
+ //temp=inb(SMBusBase+SMBHSTSTS);
+ //printk(BIOS_DEBUG, "SM Bus Busy.. status =%x\r\n",temp);
+ //sch_SMbus_regs ();
+ //printk(BIOS_DEBUG, "SMBHSTSTS. =%x\r\n",inb(SMBusBase+SMBHSTSTS));
+ do {
+ temp = inb(SMBusBase + SMBHSTSTS);
+ printk(BIOS_DEBUG, "SMBHSTSTS. =%x\r\n",
+ inb(SMBusBase + SMBHSTSTS));
+ //sch_SMbus_regs ();
+ if (temp > 0)
+ break;
+ } while (1);
+
+ switch (temp) {
+ case 1:
+ printk(BIOS_DEBUG, "SM Bus Success\n");
+ break;
+ default:
+ printk(BIOS_DEBUG, "SM Bus error %d", temp);
+ break;
+
+ }
+
+ sch_SMbus_regs();
+ printk(BIOS_DEBUG, "ADDRESS is.. %x\r\n", inb(SMBusBase + SMBHSTADD));
+ length = inb(SMBusBase + SMBHSTDAT0);
+
+ printk(BIOS_DEBUG, "Length is.. %x\r\n", inb(SMBusBase + SMBHSTDAT0));
+
+ printk(BIOS_DEBUG, "Command is... %x\r\n", inb(SMBusBase + SMBHSTDATB));
+ printk(BIOS_DEBUG, "Status .. %x\r\n", inb(SMBusBase + SMBHSTDATB + 1));
+ for (index = 0; index < length; index++)
+ printk(BIOS_DEBUG, "Serial Byte[%x]..%x\r\n", index,
+ inb(SMBusBase + SMBHSTDATB + index));
+}
+
+int selectcard(void)
+{
+ int i;
+ printk(BIOS_DEBUG, "%s", "\r\nCase 9....... \n\r");
+ // send the length byte and command code through RFID interface
+
+ transaction1(RFID_ADDR);
+ transaction2(RFID_ADDR);
+ transaction3(RFID_ADDR);
+ return (1);
+}
+#endif
+
+#include "northbridge/intel/sch/early_init.c"
+#include "northbridge/intel/sch/raminit.h"
+#include "northbridge/intel/sch/raminit.c"
+
+
+static void sch_enable_lpc(void)
+{
+ /* Initialize the FWH decode/Enable registers according to platform design */
+ pci_write_config32(PCI_DEV(0, 0x1f, 0), 0xD0, 0x00112233);
+ pci_write_config32(PCI_DEV(0, 0x1f, 0), 0xD4, 0xC0000000);
+ pci_write_config32(PCI_DEV(0, 0x1f, 0), 0x60, 0x808A8B8B);
+ pci_write_config32(PCI_DEV(0, 0x1f, 0), 0x64, 0x8F898F89);
+}
+
+static void sch_shadow_CMC(void)
+{
+ u32 reg32;
+ /* FIXME: proper dest, proper src, and wbinvd, too */
+ memcpy((void *)CMC_SHADOW, (void *)0xfffd0000, 64 * 1024);
+ // __asm__ volatile ("wbinvd \n"
+ //);
+ printk(BIOS_DEBUG, "copy done ");
+ memcpy((void *)0x3f5f0000, (void *)0x3faf0000, 64 * 1024);
+ printk(BIOS_DEBUG, "copy 2 done ");
+ reg32 = cpuid_eax(0x00000001);
+ printk(BIOS_INFO, "CPU ID: %d.\n", reg32);
+
+ reg32 = cpuid_eax(0x80000008);
+ printk(BIOS_INFO, "Physical Address size: %d.\n", (reg32 & 0xFF));
+ printk(BIOS_INFO, "Virtual Address size: %d.\n", ((reg32 & 0xFF00) >> 8));
+ sch_port_access_write_ram_cmd(0xB8, 4, 0, 0x3faf0000);
+ printk(BIOS_DEBUG, "1 ");
+ sch_port_access_write_ram_cmd(0xBA, 4, 0, reg32);
+ printk(BIOS_DEBUG, "2 ");
+}
+
+static void poulsbo_setup_Stage1Regs(void)
+{
+ u32 reg32;
+
+ printk(BIOS_DEBUG, "E000/F000 Routing ");
+ reg32 = sch_port_access_read(2, 3, 4);
+ sch_port_access_write(2, 3, 4, (reg32 | 0x6));
+}
+
+static void poulsbo_setup_Stage2Regs(void)
+{
+ u32 reg32;
+ printk(BIOS_DEBUG, "Reserved");
+ reg32 = pci_read_config32(PCI_DEV(0, 0x2, 0), 0x62);
+ pci_write_config32(PCI_DEV(0, 0x2, 0), 0x62, (reg32 | 0x3));
+ /*Slot capabilities */
+ pci_write_config32(PCI_DEV(0, 28, 0), 0x54, 0x80500);
+ pci_write_config32(PCI_DEV(0, 28, 1), 0x54, 0x100500);
+ /* FIXME: CPU ID identification */
+ printk(BIOS_DEBUG, " done.\n");
+}
+
+void main(unsigned long bist)
+{
+ int boot_mode = 0;
+
+ if (bist == 0) {
+ enable_lapic();
+ }
+
+ sch_enable_lpc();
+ /* Set up the console */
+ uart_init();
+ console_init();
+
+ /* Halt if there was a built in self test failure */
+ // report_bist_failure(bist);
+ // outl (0x00,0x1088);
+
+ /* Perform some early chipset initialization required
+ * before RAM initialization can work
+ */
+ sch_early_initialization();
+ sdram_initialize(boot_mode);
+
+ sch_shadow_CMC();
+ poulsbo_setup_Stage1Regs();
+ poulsbo_setup_Stage2Regs();
+#if 0
+ sch_SMbase_init ();
+
+ /* Perform some initialization that must run before stage2 */
+#endif
+
+ /* This should probably go away. Until now it is required
+ * and mainboard specific
+ */
+
+ /* Chipset Errata! */
+ pci_write_config16(PCI_DEV(0, 0x2, 0), GGC, 0x20);
+ pci_write_config32(PCI_DEV(0, 0x2, 0), 0xc4, 0x00000002);
+ pci_write_config32(PCI_DEV(0, 0x2, 0), 0xe0, 0x00008000);
+ pci_write_config32(PCI_DEV(0, 0x2, 0), 0xf0, 0x00000005);
+ pci_write_config16(PCI_DEV(0, 0x2, 0), 0xf7, 0x80);
+ pci_write_config16(PCI_DEV(0, 0x2, 0), 0x4, 0x7);
+
+#if RFID_TEST
+ sch_SMbase_init();
+ selectcard();
+#endif
+}