aboutsummaryrefslogtreecommitdiff
path: root/src/northbridge/intel/i82830/raminit.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/northbridge/intel/i82830/raminit.c')
-rw-r--r--src/northbridge/intel/i82830/raminit.c508
1 files changed, 0 insertions, 508 deletions
diff --git a/src/northbridge/intel/i82830/raminit.c b/src/northbridge/intel/i82830/raminit.c
deleted file mode 100644
index e0f2c6e476..0000000000
--- a/src/northbridge/intel/i82830/raminit.c
+++ /dev/null
@@ -1,508 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2008-2010 Joseph Smith <joe@settoplinux.org>
- *
- * 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; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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 <spd.h>
-#include <delay.h>
-#include "lib/debug.c"
-#include "i82830.h"
-
-/*-----------------------------------------------------------------------------
-Macros and definitions.
------------------------------------------------------------------------------*/
-
-/* Debugging macros. */
-#if IS_ENABLED(CONFIG_DEBUG_RAM_SETUP)
-#define PRINTK_DEBUG(x...) printk(BIOS_DEBUG, x)
-#define DUMPNORTH() dump_pci_device(PCI_DEV(0, 0, 0))
-#else
-#define PRINTK_DEBUG(x...)
-#define DUMPNORTH()
-#endif
-
-/* DRC[10:8] - Refresh Mode Select (RMS).
- * 0x0 for Refresh Disabled (Self Refresh)
- * 0x1 for Refresh interval 15.6 us for 133MHz
- * 0x2 for Refresh interval 7.8 us for 133MHz
- * 0x7 for Refresh interval 128 Clocks. (Fast Refresh Mode)
- */
-#define RAM_COMMAND_REFRESH 0x1
-
-/* DRC[6:4] - SDRAM Mode Select (SMS). */
-#define RAM_COMMAND_SELF_REFRESH 0x0
-#define RAM_COMMAND_NOP 0x1
-#define RAM_COMMAND_PRECHARGE 0x2
-#define RAM_COMMAND_MRS 0x3
-#define RAM_COMMAND_CBR 0x6
-#define RAM_COMMAND_NORMAL 0x7
-
-/* DRC[29] - Initialization Complete (IC). */
-#define RAM_COMMAND_IC 0x1
-
-/*-----------------------------------------------------------------------------
-DIMM-initialization functions.
------------------------------------------------------------------------------*/
-
-static void do_ram_command(u32 command)
-{
- u32 reg32;
-
- /* Configure the RAM command. */
- reg32 = pci_read_config32(NORTHBRIDGE, DRC);
- /* Clear bits 29, 10-8, 6-4. */
- reg32 &= 0xdffff88f;
- reg32 |= command << 4;
- PRINTK_DEBUG(" Sending RAM command 0x%08x", reg32);
- pci_write_config32(NORTHBRIDGE, DRC, reg32);
-}
-
-static void ram_read32(u8 dimm_start, u32 offset)
-{
- u32 reg32, base_addr = 32 * 1024 * 1024 * dimm_start;
- if (offset == 0x55aa55aa) {
- reg32 = read32((u32 *)base_addr);
- PRINTK_DEBUG(" Reading RAM at 0x%08x => 0x%08x\n", base_addr, reg32);
- PRINTK_DEBUG(" Writing RAM at 0x%08x <= 0x%08x\n", base_addr, offset);
- write32((u32 *)base_addr, offset);
- reg32 = read32((u32 *)base_addr);
- PRINTK_DEBUG(" Reading RAM at 0x%08x => 0x%08x\n", base_addr, reg32);
- } else {
- PRINTK_DEBUG(" to 0x%08x\n", base_addr + offset);
- read32((u32 *)(base_addr + offset));
- }
-}
-
-static void initialize_dimm_rows(void)
-{
- int i, row;
- u8 dimm_start, dimm_end;
- unsigned device;
-
- dimm_start = 0;
-
- for (row = 0; row < (DIMM_SOCKETS * 2); row++) {
-
- switch (row) {
- case 0:
- device = DIMM0;
- break;
- case 1:
- device = DIMM0;
- break;
- case 2:
- device = DIMM0 + 1;
- break;
- case 3:
- device = DIMM0 + 1;
- break;
- }
-
- dimm_end = pci_read_config8(NORTHBRIDGE, DRB + row);
-
- if (dimm_end > dimm_start) {
- printk(BIOS_DEBUG, "Initializing SDRAM Row %u\n", row);
-
- /* NOP command */
- PRINTK_DEBUG(" NOP\n");
- do_ram_command(RAM_COMMAND_NOP);
- ram_read32(dimm_start, 0);
- udelay(200);
-
- /* Pre-charge all banks (at least 200 us after NOP) */
- PRINTK_DEBUG(" Pre-charging all banks\n");
- do_ram_command(RAM_COMMAND_PRECHARGE);
- ram_read32(dimm_start, 0);
- udelay(1);
-
- /* 8 CBR refreshes (Auto Refresh) */
- PRINTK_DEBUG(" 8 CBR refreshes\n");
- for (i = 0; i < 8; i++) {
- do_ram_command(RAM_COMMAND_CBR);
- ram_read32(dimm_start, 0);
- udelay(1);
- }
-
- /* MRS command */
- /* TODO: Set offset 0x1d0 according to DRT values */
- PRINTK_DEBUG(" MRS\n");
- do_ram_command(RAM_COMMAND_MRS);
- ram_read32(dimm_start, 0x1d0);
- udelay(2);
-
- /* Set GMCH-M Mode Select bits back to NORMAL operation mode */
- PRINTK_DEBUG(" Normal operation mode\n");
- do_ram_command(RAM_COMMAND_NORMAL);
- ram_read32(dimm_start, 0);
- udelay(1);
-
- /* Perform a dummy memory read/write cycle */
- PRINTK_DEBUG(" Performing dummy read/write\n");
- ram_read32(dimm_start, 0x55aa55aa);
- udelay(1);
- }
- /* Set the start of the next DIMM. */
- dimm_start = dimm_end;
- }
-}
-
-/*-----------------------------------------------------------------------------
-DIMM-independent configuration functions.
------------------------------------------------------------------------------*/
-
-struct dimm_size {
- unsigned int side1;
- unsigned int side2;
-};
-
-static struct dimm_size spd_get_dimm_size(unsigned device)
-{
- struct dimm_size sz;
- int i, module_density, dimm_banks;
- sz.side1 = 0;
- module_density = spd_read_byte(device, SPD_DENSITY_OF_EACH_ROW_ON_MODULE);
- dimm_banks = spd_read_byte(device, SPD_NUM_DIMM_BANKS);
-
- /* Find the size of side1. */
- /* Find the larger value. The larger value is always side1. */
- for (i = 512; i >= 0; i >>= 1) {
- if ((module_density & i) == i) {
- sz.side1 = i;
- break;
- }
- }
-
- /* Set to 0 in case it's single sided. */
- sz.side2 = 0;
-
- /* Test if it's a dual-sided DIMM. */
- if (dimm_banks > 1) {
- /* Test to see if there's a second value, if so it's asymmetrical. */
- if (module_density != i) {
- /* Find the second value, picking up where we left off. */
- /* i >>= 1 done initially to make sure we don't get the same value again. */
- for (i >>= 1; i >= 0; i >>= 1) {
- if (module_density == (sz.side1 | i)) {
- sz.side2 = i;
- break;
- }
- }
- /* If not, it's symmetrical */
- } else {
- sz.side2 = sz.side1;
- }
- }
-
- /* SPD byte 31 is the memory size divided by 4 so we
- * need to multiply by 4 to get the total size.
- */
- sz.side1 *= 4;
- sz.side2 *= 4;
- return sz;
-}
-
-static void set_dram_row_boundaries(void)
-{
- int i, value, drb1, drb2;
-
- for (i = 0; i < DIMM_SOCKETS; i++) {
- struct dimm_size sz;
- unsigned device;
- device = DIMM0 + i;
- drb1 = 0;
- drb2 = 0;
-
- /* First check if a DIMM is actually present. */
- if (spd_read_byte(device, SPD_MEMORY_TYPE) == 0x4) {
- printk(BIOS_DEBUG, "Found DIMM in slot %u\n", i);
- sz = spd_get_dimm_size(device);
- printk(BIOS_DEBUG, " DIMM is %uMB on side 1\n", sz.side1);
- printk(BIOS_DEBUG, " DIMM is %uMB on side 2\n", sz.side2);
-
- /* - Memory compatibility checks - */
-
- /* Test for PC133 (i82830 only supports PC133) */
- /* PC133 SPD9 - cycle time is always 75 */
- if (spd_read_byte(device, SPD_MIN_CYCLE_TIME_AT_CAS_MAX) != 0x75) {
- printk(BIOS_ERR, "SPD9 DIMM Is Not PC133 Compatable\n");
- die("HALT\n");
- }
- /* PC133 SPD10 - access time is always 54 */
- if (spd_read_byte(device, SPD_ACCESS_TIME_FROM_CLOCK) != 0x54) {
- printk(BIOS_ERR, "SPD10 DIMM Is Not PC133 Compatable\n");
- die("HALT\n");
- }
-
- /* The i82830 only supports a symmetrical dual-sided dimms
- * and can't handle DIMMs smaller than 32MB per
- * side or larger than 256MB per side.
- */
- if ((sz.side2 != 0) && (sz.side1 != sz.side2)) {
- printk(BIOS_ERR, "This northbridge only supports\n");
- printk(BIOS_ERR, "symmetrical dual-sided DIMMs\n");
- printk(BIOS_ERR, "booting as a single-sided DIMM\n");
- sz.side2 = 0;
- }
- if ((sz.side1 < 32)) {
- printk(BIOS_ERR, "DIMMs smaller than 32MB per side\n");
- printk(BIOS_ERR, "are not supported on this northbridge\n");
- die("HALT\n");
- }
-
- if ((sz.side1 > 256)) {
- printk(BIOS_ERR, "DIMMs larger than 256MB per side\n");
- printk(BIOS_ERR, "are not supported on this northbridge\n");
- die("HALT\n");
- }
- /* - End Memory compatibility checks - */
-
- /* We need to divide size by 32 to set up the
- * DRB registers.
- */
- if (sz.side1)
- drb1 = sz.side1 / 32;
- if (sz.side2)
- drb2 = sz.side2 / 32;
- } else {
- printk(BIOS_DEBUG, "No DIMM found in slot %u\n", i);
-
- /* If there's no DIMM in the slot, set value to 0. */
- drb1 = 0;
- drb2 = 0;
- }
- /* Set the value for DRAM Row Boundary Registers */
- if (i == 0) {
- pci_write_config8(NORTHBRIDGE, DRB, drb1);
- pci_write_config8(NORTHBRIDGE, DRB + 1, drb1 + drb2);
- PRINTK_DEBUG(" DRB 0x%02x has been set to 0x%02x\n", DRB, drb1);
- PRINTK_DEBUG(" DRB1 0x%02x has been set to 0x%02x\n", DRB + 1, drb1 + drb2);
- } else if (i == 1) {
- value = pci_read_config8(NORTHBRIDGE, DRB + 1);
- pci_write_config8(NORTHBRIDGE, DRB + 2, value + drb1);
- pci_write_config8(NORTHBRIDGE, DRB + 3, value + drb1 + drb2);
- PRINTK_DEBUG(" DRB2 0x%02x has been set to 0x%02x\n", DRB + 2, value + drb1);
- PRINTK_DEBUG(" DRB3 0x%02x has been set to 0x%02x\n", DRB + 3, value + drb1 + drb2);
-
- /* We need to set the highest DRB value to 0x64 and 0x65.
- * These are supposed to be "Reserved" but memory will
- * not initialize properly if we don't.
- */
- value = pci_read_config8(NORTHBRIDGE, DRB + 3);
- pci_write_config8(NORTHBRIDGE, DRB + 4, value);
- pci_write_config8(NORTHBRIDGE, DRB + 5, value);
- }
- }
-}
-
-static void set_dram_row_attributes(void)
-{
- int i, dra, col, width, value;
-
- for (i = 0; i < DIMM_SOCKETS; i++) {
- unsigned device;
- device = DIMM0 + i;
-
- /* First check if a DIMM is actually present. */
- if (spd_read_byte(device, SPD_MEMORY_TYPE) == 0x4) {
- PRINTK_DEBUG("Found DIMM in slot %u\n", i);
-
- dra = 0x00;
-
- /* columns */
- col = spd_read_byte(device, SPD_NUM_COLUMNS);
-
- /* data width */
- width = spd_read_byte(device, SPD_MODULE_DATA_WIDTH_LSB);
-
- /* calculate page size in bits */
- value = ((1 << col) * width);
-
- /* convert to Kilobytes */
- dra = ((value / 8) >> 10);
-
- /* # of banks of DIMM (single or double sided) */
- value = spd_read_byte(device, SPD_NUM_DIMM_BANKS);
-
- if (value == 1) {
- if (dra == 2) {
- dra = 0xF0; /* 2KB */
- } else if (dra == 4) {
- dra = 0xF1; /* 4KB */
- } else if (dra == 8) {
- dra = 0xF2; /* 8KB */
- } else if (dra == 16) {
- dra = 0xF3; /* 16KB */
- } else {
- printk(BIOS_ERR, "Page size not supported\n");
- die("HALT\n");
- }
- } else if (value == 2) {
- if (dra == 2) {
- dra = 0x00; /* 2KB */
- } else if (dra == 4) {
- dra = 0x11; /* 4KB */
- } else if (dra == 8) {
- dra = 0x22; /* 8KB */
- } else if (dra == 16) {
- dra = 0x33; /* 16KB */
- } else {
- printk(BIOS_ERR, "Page size not supported\n");
- die("HALT\n");
- }
- } else {
- printk(BIOS_ERR, "# of banks of DIMM not supported\n");
- die("HALT\n");
- }
-
- } else {
- PRINTK_DEBUG("No DIMM found in slot %u\n", i);
-
- /* If there's no DIMM in the slot, set dra value to 0xFF. */
- dra = 0xFF;
- }
-
- /* Set the value for DRAM Row Attribute Registers */
- pci_write_config8(NORTHBRIDGE, DRA + i, dra);
- PRINTK_DEBUG(" DRA 0x%02x has been set to 0x%02x\n", DRA + i, dra);
- }
-}
-
-static void set_dram_timing(void)
-{
- /* Set the value for DRAM Timing Register */
- /* TODO: Configure the value according to SPD values. */
- pci_write_config32(NORTHBRIDGE, DRT, 0x00000010);
-}
-
-static void set_dram_buffer_strength(void)
-{
- /* TODO: This needs to be set according to the DRAM tech
- * (x8, x16, or x32). Argh, Intel provides no docs on this!
- * Currently, it needs to be pulled from the output of
- * lspci -xxx Rx92
- */
-
- /* Set the value for System Memory Buffer Strength Control Registers */
- pci_write_config32(NORTHBRIDGE, BUFF_SC, 0xFC9B491B);
-}
-
-/*-----------------------------------------------------------------------------
-Public interface.
------------------------------------------------------------------------------*/
-
-static void sdram_set_registers(void)
-{
- printk(BIOS_DEBUG, "Setting initial SDRAM registers....\n");
-
- /* Calculate the value for DRT DRAM Timing Register */
- set_dram_timing();
-
- /* Setup System Memory Buffer Strength Control Registers */
- set_dram_buffer_strength();
-
- /* Setup DRAM Row Boundary Registers */
- set_dram_row_boundaries();
-
- /* Setup DRAM Row Attribute Registers */
- set_dram_row_attributes();
-
- printk(BIOS_DEBUG, "Initial SDRAM registers have been set.\n");
-}
-
-static void northbridge_set_registers(void)
-{
- u16 value;
- int igd_memory = 0;
-
- printk(BIOS_DEBUG, "Setting initial Northbridge registers....\n");
-
- /* Set the value for Fixed DRAM Hole Control Register */
- pci_write_config8(NORTHBRIDGE, FDHC, 0x00);
-
- /* Set the value for Programmable Attribute Map Registers
- * Ideally, this should be R/W for as many ranges as possible.
- */
- pci_write_config8(NORTHBRIDGE, PAM0, 0x30);
- pci_write_config8(NORTHBRIDGE, PAM1, 0x33);
- pci_write_config8(NORTHBRIDGE, PAM2, 0x33);
- pci_write_config8(NORTHBRIDGE, PAM3, 0x33);
- pci_write_config8(NORTHBRIDGE, PAM4, 0x33);
- pci_write_config8(NORTHBRIDGE, PAM5, 0x33);
- pci_write_config8(NORTHBRIDGE, PAM6, 0x33);
-
- /* Set the value for System Management RAM Control Register */
- pci_write_config8(NORTHBRIDGE, SMRAM, 0x02);
-
- /* Set the value for GMCH Control Register #0 */
- pci_write_config16(NORTHBRIDGE, GCC0, 0xA072);
-
- /* Set the value for Aperture Base Configuration Register */
- pci_write_config32(NORTHBRIDGE, APBASE, 0x00000008);
-
- /* Set the value for GMCH Control Register #1 */
- switch (CONFIG_VIDEO_MB) {
- case 512: /* 512K of memory */
- igd_memory = 0x2;
- break;
- case 1: /* 1M of memory */
- igd_memory = 0x3;
- break;
- case 8: /* 8M of memory */
- igd_memory = 0x4;
- break;
- default: /* No memory */
- pci_write_config16(NORTHBRIDGE, GCC1, 0x0002);
- igd_memory = 0x0;
- }
-
- value = pci_read_config16(NORTHBRIDGE, GCC1);
- value |= igd_memory << 4;
- value |= 1; // 64MB aperture
- pci_write_config16(NORTHBRIDGE, GCC1, value);
-
- printk(BIOS_DEBUG, "Initial Northbridge registers have been set.\n");
-}
-
-static void sdram_initialize(void)
-{
- u32 reg32;
-
- /* Setup Initial SDRAM Registers */
- sdram_set_registers();
-
- /* Wait until power/voltages and clocks are stable (200us). */
- udelay(200);
-
- /* Initialize each row of memory one at a time */
- initialize_dimm_rows();
-
- /* Enable Refresh */
- PRINTK_DEBUG("Enabling Refresh\n");
- reg32 = pci_read_config32(NORTHBRIDGE, DRC);
- reg32 |= (RAM_COMMAND_REFRESH << 8);
- pci_write_config32(NORTHBRIDGE, DRC, reg32);
-
- /* Set initialization complete */
- PRINTK_DEBUG("Setting initialization complete\n");
- reg32 = pci_read_config32(NORTHBRIDGE, DRC);
- reg32 |= (RAM_COMMAND_IC << 29);
- pci_write_config32(NORTHBRIDGE, DRC, reg32);
-
- /* Setup Initial Northbridge Registers */
- northbridge_set_registers();
-
- PRINTK_DEBUG("Northbridge following SDRAM init:\n");
- DUMPNORTH();
-}