diff options
Diffstat (limited to 'src/northbridge/intel/sch/raminit.c')
-rw-r--r-- | src/northbridge/intel/sch/raminit.c | 249 |
1 files changed, 146 insertions, 103 deletions
diff --git a/src/northbridge/intel/sch/raminit.c b/src/northbridge/intel/sch/raminit.c index d2e8af8..5e49682 100644 --- a/src/northbridge/intel/sch/raminit.c +++ b/src/northbridge/intel/sch/raminit.c @@ -5,8 +5,7 @@ * * 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. + * 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 @@ -24,6 +23,7 @@ #include <spd.h> #include "raminit.h" #include "sch.h" + #define DEBUG_RAM_SETUP #define SOFTSTRSP(base, off) *((volatile u8 *)((base) + (off))) @@ -42,17 +42,18 @@ static void detect_fsb(struct sys_info *sysinfo) { u32 reg32; + reg32 = sch_port_access_read(5, 3, 4); - if (reg32 & BIT(3)) { + if (reg32 & BIT(3)) sysinfo->fsb_frequency = 533; - } else { + 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; @@ -82,12 +83,12 @@ static void detect_softstraps(struct sys_info *sysinfo) 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!"); + /* 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 */ + /* Timings from soft strap */ reg8 = SOFTSTRSP(sbase, 0x87f0); temp = reg8 & 0x30; temp = temp >> 4; @@ -98,7 +99,7 @@ static void detect_softstraps(struct sys_info *sysinfo) temp = reg8 & 0x03; sysinfo->trp = temp; - /*Geometry from Softstrap */ + /* Geometry from Softstrap */ reg8 = SOFTSTRSP(sbase, 0x87f1); temp = reg8 & 0x06; @@ -108,7 +109,7 @@ static void detect_softstraps(struct sys_info *sysinfo) temp = reg8 & 0x01; sysinfo->data_width = temp; - /*Refresh rate default 7.8us */ + /* Refresh rate default 7.8us */ sysinfo->refresh = 3; } } @@ -117,44 +118,55 @@ 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 + /* + * 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 */ + 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); + 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); + 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 */ + * 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); - + 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 */ + /* + * 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) { + if (sysinfo->fsb_frequency == 533) reg32 |= 1; - } else { + else reg32 &= ~(BIT(0)); - } - reg32 = 0x006911c; // FIXME ? + reg32 = 0x006911c; // FIXME ? - sch_port_access_write(SCH_MSG_DUNIT_PORT, SCH_MSG_DUNIT_REG_DCO, 4, reg32); + sch_port_access_write(SCH_MSG_DUNIT_PORT, SCH_MSG_DUNIT_REG_DCO, 4, + reg32); } static void program_dll_config(struct sys_info *sysinfo) @@ -167,119 +179,152 @@ static void program_dll_config(struct sys_info *sysinfo) 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) { + if (sysinfo->fsb_frequency == 533) sch_port_access_write(SCH_MSG_DUNIT_PORT, 0x20, 4, 0x993B); - } else { + 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 = + 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); + 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 { + 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. */ + 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 miscellaneous 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 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 */ + * 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 + 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); + 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); + 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 */ + /* + * 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) */ + 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) */ + 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) */ + 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 */ + 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 */ + 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) */ + 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 */ + 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 */ + 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 + 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. */ + 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); + 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 + * @param boot_mode 0 = normal, 1 = resume */ - void sdram_initialize(int boot_mode) { struct sys_info sysinfo; @@ -289,27 +334,27 @@ void sdram_initialize(int boot_mode) memset(&sysinfo, 0, sizeof(sysinfo)); - detect_fsb(&sysinfo); detect_softstraps(&sysinfo); program_sch_dram_data(&sysinfo); /* cold boot */ - if (boot_mode == BOOT_MODE_NORMAL) { + if (boot_mode == BOOT_MODE_NORMAL) do_jedec_init(&sysinfo); - } else { + else program_dll_config(&sysinfo); - } - /* raminit complete */ - reg32 = sch_port_access_read(SCH_MSG_DUNIT_PORT, SCH_MSG_DUNIT_REG_DCO, 4); + /* 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); + sch_port_access_write(SCH_MSG_DUNIT_PORT, + SCH_MSG_DUNIT_REG_DCO, 4, reg32); - /* setting up TOM */ + /* Setting up TOM. */ reg32 = 0x10000000; reg32 = reg32 >> sysinfo.data_width; reg32 = reg32 << sysinfo.device_density; @@ -317,15 +362,13 @@ void sdram_initialize(int boot_mode) reg32 = 0x40000000; sch_port_access_write(2, 8, 4, reg32); - /* resume mode */ - if (boot_mode == BOOT_MODE_RESUME) { + /* 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); } - |