diff options
Diffstat (limited to 'src/soc/intel/sch/raminit.c')
-rw-r--r-- | src/soc/intel/sch/raminit.c | 373 |
1 files changed, 0 insertions, 373 deletions
diff --git a/src/soc/intel/sch/raminit.c b/src/soc/intel/sch/raminit.c deleted file mode 100644 index 1131510967eb..000000000000 --- a/src/soc/intel/sch/raminit.c +++ /dev/null @@ -1,373 +0,0 @@ -/* - * 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. - */ - -#include <string.h> -#include <cpu/x86/mtrr.h> -#include <cpu/x86/cache.h> -#include <spd.h> -#include "raminit.h" -#include "sch.h" - -#define DEBUG_RAM_SETUP -#define SOFTSTRSP(base, off) *((volatile u8 *)((base) + (off))) - -/* Debugging macros. */ -#if defined(DEBUG_RAM_SETUP) -#define PRINTK_DEBUG(x...) printk(BIOS_DEBUG, x) -#else -#define PRINTK_DEBUG(x...) -#endif - -#define BOOT_MODE_RESUME 1 -#define BOOT_MODE_NORMAL 0 - -#include "port_access.c" - -static void detect_fsb(struct sys_info *sysinfo) -{ - u32 reg32; - - reg32 = sch_port_access_read(5, 3, 4); - if (reg32 & BIT(3)) - sysinfo->fsb_frequency = 533; - else - sysinfo->fsb_frequency = 400; -} - -static u32 detect_softstrap_base(void) -{ - u32 reg32, base_addr; - - reg32 = sch_port_access_read(4, 0x71, 2); - reg32 &= 0x700; - reg32 = reg32 >> 7; - switch (reg32) { - case 7: - base_addr = 0xFFFB0000; - break; - case 6: - base_addr = 0xFFFC0000; - break; - case 5: - base_addr = 0xFFFD0000; - break; - case 4: - base_addr = 0xFFFE0000; - break; - default: - base_addr = 0; - die("No valid softstrap base found.\n"); - } - return base_addr; -} - -static void detect_softstraps(struct sys_info *sysinfo) -{ - u8 reg8, temp; - u32 sbase = detect_softstrap_base(); - - reg8 = SOFTSTRSP(sbase, 0x87f2); - sysinfo->ranks = reg8; - if (reg8 == 0) { - sysinfo->ram_param_source = RAM_PARAM_SOURCE_SPD; - /* FIXME: Implement SPD reading. */ - die("No support for reading DIMM config from SPD yet!"); - return; - } else { - sysinfo->ram_param_source = RAM_PARAM_SOURCE_SOFTSTRAP; - /* Timings from soft strap */ - reg8 = SOFTSTRSP(sbase, 0x87f0); - temp = reg8 & 0x30; - temp = temp >> 4; - sysinfo->cl = temp; - temp = reg8 & 0x0c; - temp = temp >> 2; - sysinfo->trcd = temp; - temp = reg8 & 0x03; - sysinfo->trp = temp; - - /* Geometry from Softstrap */ - reg8 = SOFTSTRSP(sbase, 0x87f1); - - temp = reg8 & 0x06; - temp = temp >> 1; - sysinfo->device_density = temp; - - temp = reg8 & 0x01; - sysinfo->data_width = temp; - - /* Refresh rate default 7.8us */ - sysinfo->refresh = 3; - } -} - -static void program_sch_dram_data(struct sys_info *sysinfo) -{ - u32 reg32; - - /* - * Program DRP DRAM Rank Population and Interface Register as per data - * in sysinfo SCH port 1 register 0..0xFF. - */ - reg32 = - sch_port_access_read(SCH_MSG_DUNIT_PORT, SCH_MSG_DUNIT_REG_DRP, 4); - reg32 &= ~(DRP_FIELDS); /* Clear all DRP fields we'll change. */ - /* Rank0 Device Width, Density, Enable */ - reg32 |= sysinfo->data_width | (sysinfo->device_density << 1) | (1 << 3); - /* Rank1 Device Width, Density, Enable */ - reg32 |= (sysinfo->data_width << 4) - | ((sysinfo->device_density) << 5) | (1 << 7); - sch_port_access_write(SCH_MSG_DUNIT_PORT, - SCH_MSG_DUNIT_REG_DRP, 4, reg32); - - /* - * Program DTR DRAM Timing Register as per data in sysinfo SCH port 1 - * register 1. - * - * tRD_dly = 2 (15:13 = 010b) - * 0X3F - */ - reg32 = - sch_port_access_read(SCH_MSG_DUNIT_PORT, SCH_MSG_DUNIT_REG_DTR, 4); - reg32 &= ~(DTR_FIELDS); /* Clear all DTR fields we'll change. */ - - reg32 = (sysinfo->trp); - reg32 |= (sysinfo->trcd) << 2; - reg32 |= (sysinfo->cl) << 4; - reg32 |= 0X4000; /* tRD_dly = 2 (15:13 = 010b) */ - sch_port_access_write(SCH_MSG_DUNIT_PORT, SCH_MSG_DUNIT_REG_DTR, 4, - reg32); - - /* - * DCO DRAM Controller Operation Register as per data in sysinfo - * SCH port 1 register 2 0xF. - */ - reg32 = - sch_port_access_read(SCH_MSG_DUNIT_PORT, SCH_MSG_DUNIT_REG_DCO, 4); - reg32 &= ~(DCO_FIELDS); /* Clear all DTR fields we'll change. */ - - if (sysinfo->fsb_frequency == 533) - reg32 |= 1; - else - reg32 &= ~(BIT(0)); - reg32 = 0x006911c; // FIXME ? - - sch_port_access_write(SCH_MSG_DUNIT_PORT, SCH_MSG_DUNIT_REG_DCO, 4, - reg32); -} - -static void program_dll_config(struct sys_info *sysinfo) -{ - if (sysinfo->fsb_frequency == 533) { - sch_port_access_write(SCH_MSG_DUNIT_PORT, 0x21, 4, 0x46464646); - sch_port_access_write(SCH_MSG_DUNIT_PORT, 0x22, 4, 0x46464646); - } else { - sch_port_access_write(SCH_MSG_DUNIT_PORT, 0x21, 4, 0x58585858); - sch_port_access_write(SCH_MSG_DUNIT_PORT, 0x22, 4, 0x58585858); - } - sch_port_access_write(SCH_MSG_DUNIT_PORT, 0x23, 4, 0x2222); - if (sysinfo->fsb_frequency == 533) - sch_port_access_write(SCH_MSG_DUNIT_PORT, 0x20, 4, 0x993B); - else - sch_port_access_write(SCH_MSG_DUNIT_PORT, 0x20, 4, 0xCC3B); -} - -static void do_jedec_init(struct sys_info *sysinfo) -{ - u32 reg32, rank, cmd, temp, num_ranks; - - /* Performs JEDEC memory initializattion for all memory rows */ - /* Set CKE0/1 low */ - reg32 = - sch_port_access_read(SCH_MSG_DUNIT_PORT, SCH_MSG_DUNIT_REG_DRP, 4); - reg32 |= DRP_CKE_DIS; - sch_port_access_write(SCH_MSG_DUNIT_PORT, - SCH_MSG_DUNIT_REG_DRP, 4, reg32); - reg32 = - sch_port_access_read(SCH_MSG_DUNIT_PORT, SCH_MSG_DUNIT_REG_DRP, 4); - rank = 0; - num_ranks = sysinfo->ranks; - - do { - /* Start clocks */ - reg32 = sch_port_access_read(SCH_MSG_DUNIT_PORT, - SCH_MSG_DUNIT_REG_DRP, 4); - reg32 &= ~(DRP_SCK_DIS); /* Enable all SCK/SCKB by def. */ - sch_port_access_write(1, SCH_MSG_DUNIT_REG_DRP, 4, reg32); - /* Program misc. SCH registers on rank 0 initialization. */ - reg32 = sch_port_access_read(SCH_MSG_DUNIT_PORT, - SCH_MSG_DUNIT_REG_DRP, 4); - if (rank == 0) - program_dll_config(sysinfo); - - printk(BIOS_DEBUG, "Setting up RAM\n"); - - /* - * Wait 200us - * reg32 = inb(ACPI_BASE + 8); PM1 Timer - * reg32 &=0xFFFFFF; - * reg32 +=0x2EE; - * do { - * reg32 = inb(ACPI_BASE + 8);PM1 Timer - * reg32 &= 0xFFFFFF; - * } while (reg32 < 0x2EE); - */ - - /* Apply NOP. */ - cmd = rank; - cmd |= SCH_DRAMINIT_CMD_NOP; - sch_port_access_write_ram_cmd(SCH_OPCODE_DRAMINIT, - SCH_MSG_DUNIT_PORT, 0, cmd); - /* Set CKE=high. */ - reg32 = sch_port_access_read(SCH_MSG_DUNIT_PORT, - SCH_MSG_DUNIT_REG_DRP, 4); - reg32 &= 0xFFFF9FFF; /* Clear both the CKE static disables. */ - sch_port_access_write(SCH_MSG_DUNIT_PORT, - SCH_MSG_DUNIT_REG_DRP, 4, reg32); - /* - * Wait 400ns (not needed when executing from flash). - * Precharge all. - */ - reg32 = sch_port_access_read(SCH_MSG_DUNIT_PORT, - SCH_MSG_DUNIT_REG_DRP, 4); - cmd = rank; - cmd |= SCH_DRAMINIT_CMD_PALL; - sch_port_access_write_ram_cmd(SCH_OPCODE_DRAMINIT, - SCH_MSG_DUNIT_PORT, 0, cmd); - - /* - * EMRS(2); High temp self refresh=disabled, - * partial array self refresh=full. - */ - cmd = rank; - cmd |= SCH_DRAMINIT_CMD_EMRS2; - sch_port_access_write_ram_cmd(SCH_OPCODE_DRAMINIT, - SCH_MSG_DUNIT_PORT, 0, cmd); - - /* EMRS(3) (no command). */ - cmd = rank; - cmd |= SCH_DRAMINIT_CMD_EMRS3; - sch_port_access_write_ram_cmd(SCH_OPCODE_DRAMINIT, - SCH_MSG_DUNIT_PORT, 0, cmd); - - /* EMRS(1); Enable DLL (Leave all bits in the command at 0). */ - cmd = rank; - cmd |= SCH_DRAMINIT_CMD_EMRS1; - sch_port_access_write_ram_cmd(SCH_OPCODE_DRAMINIT, - SCH_MSG_DUNIT_PORT, 0, cmd); - - /* MRS; Reset DLL (Set memory address bit 8). */ - cmd = rank; - cmd |= SCH_DRAMINIT_CMD_MRS; - cmd |= (SCH_JEDEC_DLLRESET << SCH_DRAMINIT_ADDR_OFFSET); - sch_port_access_write_ram_cmd(SCH_OPCODE_DRAMINIT, - SCH_MSG_DUNIT_PORT, 0, cmd); - - /* Precharge all. */ - cmd = rank; - cmd |= SCH_DRAMINIT_CMD_PALL; - sch_port_access_write_ram_cmd(SCH_OPCODE_DRAMINIT, - SCH_MSG_DUNIT_PORT, 0, cmd); - - /* Issue 2 auto-refresh commands. */ - cmd = rank; - cmd |= SCH_DRAMINIT_CMD_AREF; - sch_port_access_write_ram_cmd(SCH_OPCODE_DRAMINIT, - SCH_MSG_DUNIT_PORT, 0, cmd); - sch_port_access_write_ram_cmd(SCH_OPCODE_DRAMINIT, - SCH_MSG_DUNIT_PORT, 0, cmd); - - /* MRS command including tCL, tWR, burst length (always 4). */ - cmd = rank; - cmd |= (SCH_DRAMINIT_CMD_MRS + JEDEC_STATIC_PARAM); /* Static param */ - temp = sysinfo->cl; - temp += TCL_LOW; /* Adjust for the TCL base. */ - temp = temp << ((SCH_JEDEC_CL_OFFSET - + SCH_DRAMINIT_ADDR_OFFSET)); /* Ready the CAS latency */ - cmd |= temp; - sch_port_access_write_ram_cmd(SCH_OPCODE_DRAMINIT, - SCH_MSG_DUNIT_PORT, 0, cmd); - - /* - * Wait 200 clocks (max of 1us, so no need to delay). - * Issue EMRS(1):OCD default. - */ - cmd = rank; - cmd |= SCH_DRAMINIT_CMD_EMRS1; - cmd |= (SCH_JEDEC_OCD_DEFAULT << SCH_DRAMINIT_ADDR_OFFSET); - sch_port_access_write_ram_cmd(SCH_OPCODE_DRAMINIT, - SCH_MSG_DUNIT_PORT, 0, cmd); - - /* Issue EMRS(1): OCD cal. mode exit. */ - cmd = rank; - cmd |= SCH_DRAMINIT_CMD_EMRS1; - cmd |= (SCH_JEDEC_DQS_DIS << SCH_DRAMINIT_ADDR_OFFSET); - sch_port_access_write_ram_cmd(SCH_OPCODE_DRAMINIT, - SCH_MSG_DUNIT_PORT, 0, cmd); - rank += SCH_DRAMINIT_RANK_MASK; - num_ranks--; - } while (num_ranks); -} - -/** - * @param boot_mode 0 = normal, 1 = resume - */ -void sdram_initialize(int boot_mode) -{ - struct sys_info sysinfo; - u32 reg32; - - printk(BIOS_DEBUG, "Setting up RAM controller.\n"); - - memset(&sysinfo, 0, sizeof(sysinfo)); - - detect_fsb(&sysinfo); - detect_softstraps(&sysinfo); - - program_sch_dram_data(&sysinfo); - - /* cold boot */ - if (boot_mode == BOOT_MODE_NORMAL) - do_jedec_init(&sysinfo); - else - program_dll_config(&sysinfo); - - /* RAM init complete. */ - reg32 = - sch_port_access_read(SCH_MSG_DUNIT_PORT, SCH_MSG_DUNIT_REG_DCO, 4); - reg32 |= DCO_IC; - reg32 |= ((sysinfo.refresh) << 2); - reg32 = 0x006919c; - sch_port_access_write(SCH_MSG_DUNIT_PORT, - SCH_MSG_DUNIT_REG_DCO, 4, reg32); - - /* Setting up TOM. */ - reg32 = 0x10000000; - reg32 = reg32 >> sysinfo.data_width; - reg32 = reg32 << sysinfo.device_density; - reg32 = reg32 << sysinfo.ranks; - reg32 = 0x40000000; - sch_port_access_write(2, 8, 4, reg32); - - /* Resume mode. */ - if (boot_mode == BOOT_MODE_RESUME) - sch_port_access_write_ram_cmd(SCH_OPCODE_WAKEFULLON, - SCH_MSG_DUNIT_PORT, 0, 0); - - sch_port_access_write(2, 0, 4, 0x98); - sch_port_access_write(2, 3, 4, 0x7); - sch_port_access_write(3, 2, 4, 0x408); - sch_port_access_write(4, 0x71, 4, 0x600); -} |