Drop northbridge/i440lx
All boards using it have been deleted a long time ago. Change-Id: Ib1c4018ab6ec27868c0e2fdbf9c91323ead076fb Signed-off-by: Stefan Reinauer <stefan.reinauer@coreboot.org> Reviewed-on: http://review.coreboot.org/12236 Tested-by: build bot (Jenkins) Reviewed-by: Ronald G. Minnich <rminnich@gmail.com>
This commit is contained in:
parent
ac901e6bed
commit
31ff120a2c
|
@ -1,23 +0,0 @@
|
|||
##
|
||||
## This file is part of the coreboot project.
|
||||
##
|
||||
## Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
|
||||
##
|
||||
## 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.
|
||||
##
|
||||
|
||||
config NORTHBRIDGE_INTEL_I440LX
|
||||
bool
|
||||
select HAVE_DEBUG_RAM_SETUP
|
||||
select LATE_CBMEM_INIT
|
|
@ -1,25 +0,0 @@
|
|||
##
|
||||
## This file is part of the coreboot project.
|
||||
##
|
||||
## Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
|
||||
##
|
||||
## 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.
|
||||
##
|
||||
## 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.
|
||||
##
|
||||
|
||||
ifeq ($(CONFIG_NORTHBRIDGE_INTEL_I440LX),y)
|
||||
|
||||
ramstage-y += northbridge.c
|
||||
|
||||
endif
|
|
@ -1,72 +0,0 @@
|
|||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright (C) 2006 Uwe Hermann <uwe@hermann-uwe.de>
|
||||
* Copyright (C) 2009 Maciej Pijanka <maciej.pijanka@gmail.com>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Datasheet:
|
||||
* - Name: Intel 440LX AGPset: 82443LX Host Bridge/Controller
|
||||
* - PDF: 29056402.pdf
|
||||
*/
|
||||
|
||||
/*
|
||||
* Host-to-PCI Bridge Registers.
|
||||
* The values in parenthesis are the default values as per datasheet.
|
||||
* Any addresses between 0x00 and 0xff not listed below are either
|
||||
*
|
||||
* i didnt listed every register that IS implemented, just usefull ones
|
||||
* -- Maciej `agaran` Pijanka
|
||||
*
|
||||
* Reserved or Intel Reserved and should not be touched.
|
||||
*/
|
||||
#define APBASE 0x34 /* Aperture Base Address (0x00000008) */
|
||||
#define PACCFG 0x50 /* 440LX PAC Configuration Register (0s00_s000_0000_0s00b) */
|
||||
#define DBC 0x53 /* DRAM Row Type Register (0x83) */
|
||||
#define DRT 0x55 /* DRAM Row Type Register (0x0000) */
|
||||
#define DRAMC 0x57 /* DRAM Control (0x01) */
|
||||
#define DRAMT 0x58 /* DRAM Timing (0x00) */
|
||||
#define PAM 0x59 /* Programmable Attribute Map, 7 registers (0x00). */
|
||||
#define DRB 0x60 /* DRAM Row Boundary, 8 registers (0x01). */
|
||||
#define FDHC 0x68 /* Fixed SDRAM Hole Control (0x00). */
|
||||
#define DRAMXC 0x6A /* Dram Extended Control Register (0x0000) */
|
||||
#define MBSC 0x6C /* Memory Buffer Strength Control: (0x55555555) */
|
||||
|
||||
#define SMRAM 0x72 /* System Management RAM Control (0x02). */
|
||||
#define ERRCMD 0x90 /* Error Command Register (0x80). */
|
||||
#define ERRSTS0 0x91 /* Error Status (0x0000). */
|
||||
#define ERRSTS1 0x92 /* Error Status (0x0000). */
|
||||
// TODO: AGP stuff.
|
||||
|
||||
/* For convenience: */
|
||||
#define DRB0 0x60
|
||||
#define DRB1 0x61
|
||||
#define DRB2 0x62
|
||||
#define DRB3 0x63
|
||||
#define DRB4 0x64
|
||||
#define DRB5 0x65
|
||||
#define DRB6 0x66
|
||||
#define DRB7 0x67
|
||||
|
||||
#define PAM0 0x59
|
||||
#define PAM1 0x5a
|
||||
#define PAM2 0x5b
|
||||
#define PAM3 0x5c
|
||||
#define PAM4 0x5d
|
||||
#define PAM5 0x5e
|
||||
#define PAM6 0x5f
|
|
@ -1,137 +0,0 @@
|
|||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright (C) 2007 Uwe Hermann <uwe@hermann-uwe.de>
|
||||
* Copyright (C) 2009 Maciej Pijanka <maciej.pijanka@gmail.com>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <console/console.h>
|
||||
#include <arch/io.h>
|
||||
#include <stdint.h>
|
||||
#include <device/device.h>
|
||||
#include <device/pci.h>
|
||||
#include <device/pci_ids.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <cbmem.h>
|
||||
#include <cpu/cpu.h>
|
||||
#include <pc80/keyboard.h>
|
||||
#include "northbridge.h"
|
||||
#include "i440lx.h"
|
||||
|
||||
/* This code is mostly same as 440BX created by Uwe Hermann,
|
||||
* i done only very minor changes like renamed functions to 440lx etc
|
||||
* Maciej
|
||||
*/
|
||||
|
||||
static void northbridge_init(device_t dev)
|
||||
{
|
||||
printk(BIOS_SPEW, "Northbridge Init\n");
|
||||
}
|
||||
|
||||
static struct device_operations northbridge_operations = {
|
||||
.read_resources = pci_dev_read_resources,
|
||||
.set_resources = pci_dev_set_resources,
|
||||
.enable_resources = pci_dev_enable_resources,
|
||||
.init = northbridge_init,
|
||||
.enable = 0,
|
||||
.ops_pci = 0,
|
||||
};
|
||||
|
||||
static const struct pci_driver northbridge_driver __pci_driver = {
|
||||
.ops = &northbridge_operations,
|
||||
.vendor = PCI_VENDOR_ID_INTEL,
|
||||
.device = 0x7180,
|
||||
};
|
||||
|
||||
static void i440lx_domain_set_resources(device_t dev)
|
||||
{
|
||||
device_t mc_dev;
|
||||
uint32_t pci_tolm;
|
||||
|
||||
pci_tolm = find_pci_tolm(dev->link_list);
|
||||
mc_dev = dev->link_list->children;
|
||||
if (mc_dev) {
|
||||
unsigned long tomk, tolmk;
|
||||
int idx;
|
||||
|
||||
/* Figure out which areas are/should be occupied by RAM. The
|
||||
* value of the highest DRB denotes the end of the physical
|
||||
* memory (in units of 8MB).
|
||||
*/
|
||||
tomk = ((unsigned long)pci_read_config8(mc_dev, DRB7));
|
||||
|
||||
/* Convert to KB. */
|
||||
tomk *= (8 * 1024);
|
||||
|
||||
printk(BIOS_DEBUG, "Setting RAM size to %lu MB\n", tomk / 1024);
|
||||
|
||||
/* Compute the top of low memory. */
|
||||
tolmk = pci_tolm / 1024;
|
||||
|
||||
if (tolmk >= tomk) {
|
||||
/* The PCI hole does not overlap the memory. */
|
||||
tolmk = tomk;
|
||||
}
|
||||
|
||||
/* Report the memory regions. */
|
||||
idx = 10;
|
||||
ram_resource(dev, idx++, 0, 640);
|
||||
ram_resource(dev, idx++, 768, tolmk - 768);
|
||||
|
||||
set_top_of_ram(tomk * 1024);
|
||||
}
|
||||
assign_resources(dev->link_list);
|
||||
}
|
||||
|
||||
static struct device_operations pci_domain_ops = {
|
||||
.read_resources = pci_domain_read_resources,
|
||||
.set_resources = i440lx_domain_set_resources,
|
||||
.enable_resources = NULL,
|
||||
.init = NULL,
|
||||
.scan_bus = pci_domain_scan_bus,
|
||||
.ops_pci_bus = pci_bus_default_ops,
|
||||
};
|
||||
|
||||
static void cpu_bus_init(device_t dev)
|
||||
{
|
||||
initialize_cpus(dev->link_list);
|
||||
}
|
||||
|
||||
static struct device_operations cpu_bus_ops = {
|
||||
.read_resources = DEVICE_NOOP,
|
||||
.set_resources = DEVICE_NOOP,
|
||||
.enable_resources = DEVICE_NOOP,
|
||||
.init = cpu_bus_init,
|
||||
.scan_bus = 0,
|
||||
};
|
||||
|
||||
static void enable_dev(struct device *dev)
|
||||
{
|
||||
/* Set the operations if it is a special bus type */
|
||||
if (dev->path.type == DEVICE_PATH_DOMAIN) {
|
||||
dev->ops = &pci_domain_ops;
|
||||
}
|
||||
else if (dev->path.type == DEVICE_PATH_CPU_CLUSTER) {
|
||||
dev->ops = &cpu_bus_ops;
|
||||
}
|
||||
}
|
||||
|
||||
struct chip_operations northbridge_intel_i440lx_ops = {
|
||||
CHIP_NAME("Intel 82443LX (440LX) Northbridge")
|
||||
.enable_dev = enable_dev,
|
||||
};
|
|
@ -1,26 +0,0 @@
|
|||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright (C) 2009 Maciej Pijanka <maciej.pijanka@gmail.com>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef NORTHBRIDGE_INTEL_440LX_H
|
||||
#define NORTHBRIDGE_INTEL_440LX_H
|
||||
|
||||
extern unsigned int i440lx_scan_root_bus(device_t root, unsigned int max);
|
||||
|
||||
#endif /* NORTHBRIDGE_INTEL_440LX_H */
|
|
@ -1,453 +0,0 @@
|
|||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright (C) 2007-2008 Uwe Hermann <uwe@hermann-uwe.de>
|
||||
* Copyright (C) 2009 Maciej Pijanka <maciej.pijanka@gmail.com>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <spd.h>
|
||||
#include <delay.h>
|
||||
#include <stdlib.h>
|
||||
#include "i440lx.h"
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Macros and definitions.
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
/* Uncomment this to enable debugging output. */
|
||||
|
||||
/* Debugging macros. */
|
||||
#if CONFIG_DEBUG_RAM_SETUP
|
||||
#define PRINT_DEBUG(x) printk(BIOS_DEBUG, x)
|
||||
#define PRINT_DEBUG_HEX8(x) printk(BIOS_DEBUG, "%02x", x)
|
||||
#define PRINT_DEBUG_HEX16(x) printk(BIOS_DEBUG, "%04x", x)
|
||||
#define PRINT_DEBUG_HEX32(x) printk(BIOS_DEBUG, "%08x", x)
|
||||
#define DUMPNORTH() dump_pci_device(PCI_DEV(0, 0, 0))
|
||||
#else
|
||||
#define PRINT_DEBUG(x)
|
||||
#define PRINT_DEBUG_HEX8(x)
|
||||
#define PRINT_DEBUG_HEX16(x)
|
||||
#define PRINT_DEBUG_HEX32(x)
|
||||
#define DUMPNORTH()
|
||||
#endif
|
||||
|
||||
#define NB PCI_DEV(0, 0, 0)
|
||||
|
||||
/* DRAMXC[7:5] - DRAM extended control register (SMS). */
|
||||
#define RAM_COMMAND_NORMAL 0x0
|
||||
#define RAM_COMMAND_NOP 0x1 // (NOPCE)
|
||||
#define RAM_COMMAND_PRECHARGE 0x2 // ABPCE
|
||||
#define RAM_COMMAND_MRS 0x3 // MRSCE
|
||||
#define RAM_COMMAND_CBR 0x4 // CBRC
|
||||
// rest are reserved
|
||||
|
||||
/* Table format: register, bitmask, value. */
|
||||
static const long register_values[] = {
|
||||
// ~0x02 == bit 9
|
||||
// 0x04 == bit 10
|
||||
// BASE is 0x8A but we dont want bit 9 or 10 have ENABLED so 0x8C
|
||||
PACCFG + 1, 0x38, 0x8c,
|
||||
|
||||
DBC, 0x00, 0xC3,
|
||||
|
||||
DRT, 0x00, 0xFF,
|
||||
DRT+1, 0x00, 0xFF,
|
||||
|
||||
DRAMC, 0x00, 0x00, /* disable refresh for now. */
|
||||
DRAMT, 0x00, 0x00,
|
||||
|
||||
PAM0, 0x00, 0x30, // everything is a mem
|
||||
PAM1, 0x00, 0x33,
|
||||
PAM2, 0x00, 0x33,
|
||||
PAM3, 0x00, 0x33,
|
||||
PAM4, 0x00, 0x33,
|
||||
PAM5, 0x00, 0x33,
|
||||
PAM6, 0x00, 0x33,
|
||||
|
||||
/* Set the DRBs to zero for now, this will be fixed later. */
|
||||
DRB0, 0x00, 0x00,
|
||||
DRB1, 0x00, 0x00,
|
||||
DRB2, 0x00, 0x00,
|
||||
DRB3, 0x00, 0x00,
|
||||
DRB4, 0x00, 0x00,
|
||||
DRB5, 0x00, 0x00,
|
||||
DRB6, 0x00, 0x00,
|
||||
DRB7, 0x00, 0x00,
|
||||
|
||||
/* No memory holes. */
|
||||
FDHC, 0x00, 0x00,
|
||||
};
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
SDRAM configuration functions.
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Send the specified RAM command to all DIMMs.
|
||||
*
|
||||
* @param command The RAM command to send to the DIMM(s).
|
||||
*/
|
||||
static void do_ram_command(u32 command)
|
||||
{
|
||||
int i, caslatency;
|
||||
u8 dimm_start, dimm_end;
|
||||
u16 reg16;
|
||||
u32 addr, addr_offset;
|
||||
|
||||
/* Configure the RAM command. */
|
||||
reg16 = pci_read_config16(NB, DRAMXC);
|
||||
reg16 &= 0xff1f; /* Clear bits 7-5. */
|
||||
reg16 |= (u16) (command << 5); /* Write command into bits 7-5. */
|
||||
pci_write_config16(NB, DRAMXC, reg16);
|
||||
|
||||
/*
|
||||
* RAM_COMMAND_NORMAL affects only the memory controller and
|
||||
* doesn't need to be "sent" to the DIMMs.
|
||||
*/
|
||||
if (command == RAM_COMMAND_NORMAL)
|
||||
return;
|
||||
|
||||
/* Send the RAM command to each row of memory. */
|
||||
dimm_start = 0;
|
||||
for (i = 0; i < (DIMM_SOCKETS * 2); i++) {
|
||||
addr_offset = 0;
|
||||
caslatency = 3; /* TODO: Dynamically get CAS latency later. */
|
||||
|
||||
/* before translation it is
|
||||
*
|
||||
* M[02:00] Burst Length
|
||||
* M[03:03] Burst Type
|
||||
* M[06:04] Cas Latency
|
||||
* 000 - Reserved
|
||||
* 001 - Reserved
|
||||
* 010 - CAS 2
|
||||
* 011 - CAS 3
|
||||
* 100 - Reserved
|
||||
* 101 - Reserved
|
||||
* 110 - Reserved
|
||||
* 111 - Reserved
|
||||
* M[08:07] Op Mode
|
||||
* Must Be 00b (Defined mode)
|
||||
* M[09:09] Write Burst Mode
|
||||
* 0 - Programmed burst length
|
||||
* 1 - Single location access
|
||||
* M[11:10] Reserved
|
||||
* write 0 to ensure compatibility with....
|
||||
*/
|
||||
|
||||
/* seems constructed value will be right shifted by 3 bit, thus constructed value
|
||||
* must be left shifted by 3
|
||||
* so possible formula is (caslatency <<4)|(burst_type << 1)|(burst length)
|
||||
* then << 3 shift to compensate shift in Memory Controller
|
||||
*/
|
||||
if (command == RAM_COMMAND_MRS) {
|
||||
if (caslatency == 3)
|
||||
addr_offset = 0x1d0;
|
||||
if (caslatency == 2)
|
||||
addr_offset = 0x150;
|
||||
}
|
||||
|
||||
dimm_end = pci_read_config8(NB, DRB + i);
|
||||
|
||||
addr = (dimm_start * 8 * 1024 * 1024) + addr_offset;
|
||||
if (dimm_end > dimm_start) {
|
||||
#if 0
|
||||
PRINT_DEBUG(" Sending RAM command 0x");
|
||||
PRINT_DEBUG_HEX16(reg16);
|
||||
PRINT_DEBUG(" to 0x");
|
||||
PRINT_DEBUG_HEX32(addr);
|
||||
PRINT_DEBUG("\n");
|
||||
#endif
|
||||
|
||||
read32(addr);
|
||||
}
|
||||
|
||||
/* Set the start of the next DIMM. */
|
||||
dimm_start = dimm_end;
|
||||
}
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
DIMM-independant configuration functions.
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
static void spd_enable_refresh(void)
|
||||
{
|
||||
uint8_t reg;
|
||||
|
||||
reg = pci_read_config8(NB, DRAMC);
|
||||
|
||||
/* this chipset offer only two choices regarding refresh
|
||||
* refresh disabled, or refresh normal
|
||||
*/
|
||||
|
||||
pci_write_config8(NB, DRAMC, reg | 0x01);
|
||||
reg = pci_read_config8(NB, DRAMC);
|
||||
|
||||
PRINT_DEBUG("spd_enable_refresh: dramc = 0x");
|
||||
PRINT_DEBUG_HEX8(reg);
|
||||
PRINT_DEBUG("\n");
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Public interface.
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
static void northbridge_init(void)
|
||||
{
|
||||
uint32_t reg32;
|
||||
|
||||
reg32 = pci_read_config32(NB, APBASE);
|
||||
reg32 &= 0xe8000000U;
|
||||
pci_write_config32(NB, APBASE, reg32);
|
||||
|
||||
#if CONFIG_DEBUG_RAM_SETUP
|
||||
/*
|
||||
* apbase dont get set still, no idea what i have doing wrong yet,
|
||||
* i am almost sure that somehow i set it by mistake once, but can't
|
||||
* repeat that.
|
||||
*/
|
||||
reg32 = pci_read_config32(NB, APBASE);
|
||||
PRINT_DEBUG("APBASE ");
|
||||
PRINT_DEBUG_HEX32(reg32);
|
||||
PRINT_DEBUG("\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This routine sets RAM controller inside northbridge to known state
|
||||
*
|
||||
*/
|
||||
static void sdram_set_registers(void)
|
||||
{
|
||||
int i, max;
|
||||
|
||||
/* nice banner with FSB shown? do we have
|
||||
* any standart policy about such things?
|
||||
*/
|
||||
#if 0
|
||||
uint16_t reg16;
|
||||
reg16 = pci_read_config16(NB, PACCFG);
|
||||
printk(BIOS_DEBUG, "i82443LX Host Freq: 6%C MHz\n", (reg16 & 0x4000) ? '0' : '6');
|
||||
#endif
|
||||
|
||||
PRINT_DEBUG("Northbridge prior to SDRAM init:\n");
|
||||
DUMPNORTH();
|
||||
|
||||
northbridge_init();
|
||||
|
||||
max = ARRAY_SIZE(register_values);
|
||||
|
||||
/* Set registers as specified in the register_values[] array. */
|
||||
for (i = 0; i < max; i += 3) {
|
||||
uint8_t reg,tmp;
|
||||
reg = pci_read_config8(NB, register_values[i]);
|
||||
reg &= register_values[i + 1];
|
||||
reg |= register_values[i + 2] & ~(register_values[i + 1]);
|
||||
pci_write_config8(NB, register_values[i], reg);
|
||||
|
||||
/*
|
||||
* i am not sure if that is needed, but was usefull
|
||||
* for me to confirm what got written
|
||||
*/
|
||||
#if CONFIG_DEBUG_RAM_SETUP
|
||||
PRINT_DEBUG(" Set register 0x");
|
||||
PRINT_DEBUG_HEX8(register_values[i]);
|
||||
PRINT_DEBUG(" to 0x");
|
||||
PRINT_DEBUG_HEX8(reg);
|
||||
tmp = pci_read_config8(NB, register_values[i]);
|
||||
PRINT_DEBUG(" readed 0x");
|
||||
PRINT_DEBUG_HEX8(tmp);
|
||||
if (tmp == reg) {
|
||||
PRINT_DEBUG(" OK ");
|
||||
} else {
|
||||
PRINT_DEBUG(" FAIL ");
|
||||
}
|
||||
PRINT_DEBUG("\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
PRINT_DEBUG("Northbridge atexit sdram set registers\n");
|
||||
DUMPNORTH();
|
||||
}
|
||||
|
||||
|
||||
static void sdram_set_spd_registers(void)
|
||||
{
|
||||
int i;
|
||||
u16 memsize = 0;
|
||||
|
||||
for (i = 0; i < DIMM_SOCKETS; i++) {
|
||||
uint16_t ds = 0; // dimm size
|
||||
int j;
|
||||
/* this code skips second bank on each socket (no idea how to fix it now)
|
||||
*/
|
||||
|
||||
PRINT_DEBUG("DIMM");
|
||||
PRINT_DEBUG_HEX8(i);
|
||||
PRINT_DEBUG(" rows: ");
|
||||
PRINT_DEBUG_HEX8(spd_read_byte(DIMM0 + i, SPD_NUM_DIMM_BANKS) & 0xFF);
|
||||
PRINT_DEBUG(" rowsize: ");
|
||||
PRINT_DEBUG_HEX8(spd_read_byte(DIMM0 + i, SPD_DENSITY_OF_EACH_ROW_ON_MODULE) & 0xFF);
|
||||
PRINT_DEBUG(" modulesize: ");
|
||||
|
||||
j = spd_read_byte(DIMM0 + i, SPD_NUM_DIMM_BANKS);
|
||||
if (j < 0)
|
||||
j = 0;
|
||||
else
|
||||
ds = j;
|
||||
|
||||
j = spd_read_byte(DIMM0 + i, SPD_DENSITY_OF_EACH_ROW_ON_MODULE);
|
||||
|
||||
if (j < 0)
|
||||
j = 0;
|
||||
else
|
||||
ds = ds * (j >> 1); // convert from 4MB to 8MB units in place
|
||||
|
||||
|
||||
/* This is more or less crude hack
|
||||
* allowing to run this target under qemu (even if that is not really
|
||||
* same hardware emulated),
|
||||
* probably some kconfig expert option should be added to enable/disable
|
||||
* this nicelly
|
||||
*/
|
||||
#if 0
|
||||
if (ds == 0 && memsize == 0)
|
||||
ds = 0x8;
|
||||
#endif
|
||||
|
||||
|
||||
// todo: support for bank with not equal sizes as per jedec standart?
|
||||
|
||||
/*
|
||||
* because density is reported in units of 4Mbyte
|
||||
* and rows in device are just value,
|
||||
* and for setting registers we need value in 8Mbyte units
|
||||
*/
|
||||
|
||||
PRINT_DEBUG_HEX16(ds);
|
||||
PRINT_DEBUG("\n");
|
||||
|
||||
memsize += ds;
|
||||
|
||||
pci_write_config8(NB, DRB + (2*i), memsize);
|
||||
pci_write_config8(NB, DRB + (2*i) + 1, memsize);
|
||||
if (ds > 0) {
|
||||
/* i have no idea why pci_read_config16 not work for
|
||||
* me correctly here
|
||||
*/
|
||||
ds = pci_read_config8(NB, DRT+1);
|
||||
ds <<=8;
|
||||
ds |= pci_read_config8(NB, DRT);
|
||||
|
||||
PRINT_DEBUG("DRT ");
|
||||
PRINT_DEBUG_HEX16(ds);
|
||||
|
||||
ds &= ~(0x01 << (4 * i));
|
||||
|
||||
PRINT_DEBUG(" ");
|
||||
PRINT_DEBUG_HEX16(ds);
|
||||
PRINT_DEBUG("\n");
|
||||
|
||||
/*
|
||||
* modify DRT register if current row isn't empty
|
||||
* code assume its SDRAM plugged (should check if its sdram or EDO,
|
||||
* edo would have 0x00 as constand instead 0x10 for SDRAM
|
||||
* also this code is buggy because ignores second row of each dimm socket
|
||||
*/
|
||||
|
||||
/* and as above write_config16 not work here too)
|
||||
* pci_write_config16(NB, DRT, j);
|
||||
*/
|
||||
|
||||
pci_write_config8(NB, DRT+1, ds >> 8);
|
||||
pci_write_config8(NB, DRT, ds & 0xFF);
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
PRINT_DEBUG("Mem: 0x");
|
||||
PRINT_DEBUG_HEX16(memsize * 8);
|
||||
PRINT_DEBUG(" MB\n");
|
||||
|
||||
if (memsize == 0) {
|
||||
/* maybe we should use some nice die/hlt sequence with printing on console
|
||||
* that no memory found, get lost, i can't run?
|
||||
* maybe such event_handler can be commonly defined routine to decrease
|
||||
* code duplication?
|
||||
*/
|
||||
PRINT_DEBUG("No memory detected via SPD\n");
|
||||
PRINT_DEBUG("Reverting to hardcoded 64M single side dimm in first bank\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Set DRAMC. Don't enable refresh for now. */
|
||||
pci_write_config8(NB, DRAMC, 0x00);
|
||||
|
||||
/* Cas latency 3, and other shouldbe properly from spd too */
|
||||
pci_write_config8(NB, DRAMT, 0xAC);
|
||||
|
||||
/* TODO? */
|
||||
pci_write_config8(NB, PCI_LATENCY_TIMER, 0x40);
|
||||
|
||||
// set drive strength
|
||||
pci_write_config32(NB, MBSC, 0x00000000);
|
||||
}
|
||||
|
||||
static void sdram_enable(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* 0. Wait until power/voltages and clocks are stable (200us). */
|
||||
udelay(200);
|
||||
|
||||
/* 1. Apply NOP. Wait 200 clock cycles (clock might be 60 or 66 MHz). */
|
||||
PRINT_DEBUG("RAM Enable 1: Apply NOP\n");
|
||||
do_ram_command(RAM_COMMAND_NOP);
|
||||
udelay(200);
|
||||
|
||||
/* 2. Precharge all. Wait tRP. */
|
||||
PRINT_DEBUG("RAM Enable 2: Precharge all\n");
|
||||
do_ram_command(RAM_COMMAND_PRECHARGE);
|
||||
udelay(1);
|
||||
|
||||
/* 3. Perform 8 refresh cycles. Wait tRC each time. */
|
||||
PRINT_DEBUG("RAM Enable 3: CBR\n");
|
||||
for (i = 0; i < 8; i++) {
|
||||
do_ram_command(RAM_COMMAND_CBR);
|
||||
udelay(1);
|
||||
}
|
||||
|
||||
/* 4. Mode register set. Wait two memory cycles. */
|
||||
PRINT_DEBUG("RAM Enable 4: Mode register set\n");
|
||||
do_ram_command(RAM_COMMAND_MRS);
|
||||
udelay(2);
|
||||
|
||||
/* 5. Normal operation. */
|
||||
PRINT_DEBUG("RAM Enable 5: Normal operation\n");
|
||||
do_ram_command(RAM_COMMAND_NORMAL);
|
||||
udelay(1);
|
||||
|
||||
/* 6. Finally enable refresh. */
|
||||
PRINT_DEBUG("RAM Enable 6: Enable refresh\n");
|
||||
pci_write_config8(NB, DRAMC, 0x01);
|
||||
spd_enable_refresh();
|
||||
udelay(1);
|
||||
|
||||
PRINT_DEBUG("Northbridge following SDRAM init:\n");
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright (C) 2007 Uwe Hermann <uwe@hermann-uwe.de>
|
||||
* Copyright (C) 2009 Maciej Pijanka <maciej.pijanka@gmail.com>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef RAMINIT_H
|
||||
#define RAMINIT_H
|
||||
|
||||
/* The 440LX supports up to four (single- or double-sided) DIMMs. */
|
||||
#define DIMM_SOCKETS 4
|
||||
|
||||
#endif /* RAMINIT_H */
|
Loading…
Reference in New Issue