summaryrefslogtreecommitdiffstats
path: root/src/soc/intel/sch/raminit.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/soc/intel/sch/raminit.c')
-rw-r--r--src/soc/intel/sch/raminit.c373
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);
-}