Drop remainders of PPC port

Signed-off-by: Stefan Reinauer <stepan@coresystems.de>
Acked-by: Ronald G. Minnich <rminnich@gmail.com>



git-svn-id: svn://svn.coreboot.org/coreboot/trunk@4885 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
This commit is contained in:
Stefan Reinauer 2009-10-28 19:40:46 +00:00 committed by Stefan Reinauer
parent e696942cfc
commit 88214a48cc
31 changed files with 0 additions and 2563 deletions

View File

@ -1,5 +1,3 @@
source src/northbridge/amd/Kconfig
#source src/northbridge/ibm/Kconfig
source src/northbridge/intel/Kconfig
#source src/northbridge/motorola/Kconfig
source src/northbridge/via/Kconfig

View File

@ -1,5 +1,3 @@
subdirs-y += amd
#subdirs-y += ibm
subdirs-y += intel
#subdirs-y += motorola
subdirs-y += via

View File

@ -1,2 +0,0 @@
#source src/northbridge/ibm/cpc710/Kconfig
#source src/northbridge/ibm/cpc925/Kconfig

View File

@ -1,2 +0,0 @@
subdirs-y += cpc710
subdirs-y += cpc925

View File

@ -1,14 +0,0 @@
#
# Config file for IBM CPC710
#
config chip.h
initobject cpc710.o
initobject cpc710_pci.o
#initobject cpc710_sdram.o
object cpc710.o
object cpc710_pci.o
#object cpc710_sdram.o
driver cpc710_northbridge.o

View File

@ -1,6 +0,0 @@
struct northbridge_ibm_cpc710_config {
/* Nothing yet */
};
extern struct chip_operations northbridge_ibm_cpc710_ops;

View File

@ -1,92 +0,0 @@
#include <stdint.h>
#include <arch/io.h>
#include "cpc710.h"
#define MCCR_DEFAULT \
CPC710_MCCR_DIAG_MODE | \
CPC710_MCCR_ECC_DISABLE | \
CPC710_MCCR_REFRESH_7CY | \
CPC710_MCCR_DATA_MASK | \
CPC710_MCCR_FIXED_BITS
void cpc710_init(void);
void sdram_init(void);
extern void cpc710_pci_init(void);
void
setCPC710(uint32_t addr, uint32_t data)
{
out_be32((unsigned *)(CPC710_PHYS_CPC0 + addr), data);
}
uint32_t
getCPC710(uint32_t addr)
{
return (uint32_t)in_be32((unsigned *)(CPC710_PHYS_CPC0 + addr));
}
void
memory_init(void)
{
cpc710_init();
sdram_init();
cpc710_pci_init();
}
void
cpc710_init(void)
{
setCPC710(CPC710_CPC0_RSTR, 0xf0000000);
(void)getCPC710(CPC710_CPC0_MPSR);
setCPC710(CPC710_CPC0_SIOC0, 0x00000000);
setCPC710(CPC710_CPC0_PIDR, 0x00000000);
setCPC710(CPC710_CPC0_UCTL, 0x00780000);
setCPC710(CPC710_CPC0_ABCNTL, 0x00000000);
setCPC710(CPC710_CPC0_SRST, 0x00000000);
setCPC710(CPC710_CPC0_ERRC, 0x00000000);
setCPC710(CPC710_CPC0_SESR, 0x00000000);
setCPC710(CPC710_CPC0_SEAR, 0x00000000);
setCPC710(CPC710_CPC0_PGCHP, 0x000000e0);
setCPC710(CPC710_CPC0_GPDIR, 0x40000000);
setCPC710(CPC710_CPC0_GPOUT, 0x40000000);
setCPC710(CPC710_CPC0_ATAS, 0x709c2508);
setCPC710(CPC710_CPC0_AVDG, 0x00000000);
setCPC710(CPC710_SDRAM0_MESR, 0x00000000);
setCPC710(CPC710_SDRAM0_MEAR, 0x00000000);
setCPC710(CPC710_SDRAM0_MWPR, 0x00000000);
setCPC710(CPC710_CPC0_RGBAN1, 0x00000000);
}
void
sdram_init()
{
uint32_t mccr;
/*
* Reset memory configuration
*/
setCPC710(CPC710_SDRAM0_MCER0, 0x00000000);
setCPC710(CPC710_SDRAM0_MCER1, 0x00000000);
setCPC710(CPC710_SDRAM0_MCER2, 0x00000000);
setCPC710(CPC710_SDRAM0_MCER3, 0x00000000);
setCPC710(CPC710_SDRAM0_MCER4, 0x00000000);
setCPC710(CPC710_SDRAM0_MCER5, 0x00000000);
setCPC710(CPC710_SDRAM0_MCER6, 0x00000000);
setCPC710(CPC710_SDRAM0_MCER7, 0x00000000);
setCPC710(CPC710_SDRAM0_MCCR, MCCR_DEFAULT);
/*
* Temoporarily configure memory. This will be
* replaced by i2c later.
*/
setCPC710(CPC710_SDRAM0_MCER0, 0x80000080);
setCPC710(CPC710_SDRAM0_MCER1, 0x82000080);
setCPC710(CPC710_SDRAM0_MCCR, 0xd2b06000);
/*
* wait for SDRAM init
*/
do {
mccr = getCPC710(CPC710_SDRAM0_MCCR);
} while (mccr & CPC710_MCCR_INIT_STATUS != CPC710_MCCR_INIT_STATUS);
}

View File

@ -1,99 +0,0 @@
/*
* (C) Copyright 2002
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* 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., 51 Franklin St, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
#ifndef _CPC710_H_
#define _CPC710_H_
/* Revision */
#define CPC710_TYPE_100 0x80
#define CPC710_TYPE_100P 0x90
/* System control area */
#define CPC710_PHYS_SCA 0xff000000
#define CPC710_SCA_CPC0 0x000000
#define CPC710_SCA_SDRAM0 0x000000
#define CPC710_SCA_DMA0 0x1C0000
#define CPC710_PHYS_CPC0 (CPC710_PHYS_SCA + CPC710_SCA_CPC0)
#define CPC710_PHYS_SDRAM0 (CPC710_PHYS_SCA + CPC710_SCA_SDRAM0)
#define CPC710_CPC0_PIDR 0x0008
#define CPC710_CPC0_PCICNFR 0x000c
#define CPC710_CPC0_RSTR 0x0010
#define CPC710_CPC0_SPOR 0x00e8
#define CPC710_CPC0_UCTL 0x1000
#define CPC710_CPC0_MPSR 0x1010
#define CPC710_CPC0_SIOC0 0x1020
#define CPC710_CPC0_ABCNTL 0x1030
#define CPC710_CPC0_SRST 0x1040
#define CPC710_CPC0_ERRC 0x1050
#define CPC710_CPC0_SESR 0x1060
#define CPC710_CPC0_SEAR 0x1070
#define CPC710_CPC0_PGCHP 0x1100
#define CPC710_CPC0_RGBAN0 0x1110
#define CPC710_CPC0_RGBAN1 0x1120
#define CPC710_CPC0_GPDIR 0x1130
#define CPC710_CPC0_GPIN 0x1140
#define CPC710_CPC0_GPOUT 0x1150
#define CPC710_CPC0_ATAS 0x1160
#define CPC710_CPC0_AVDG 0x1170
#define CPC710_CPC0_PCIBAR 0x200018
#define CPC710_CPC0_PCIENB 0x201000
#define CPC710_SDRAM0_MCCR 0x1200
#define CPC710_SDRAM0_MWPR 0x1210
#define CPC710_SDRAM0_MESR 0x1220
#define CPC710_SDRAM0_MEAR 0x1230
#define CPC710_SDRAM0_MCER0 0x1300
#define CPC710_SDRAM0_MCER1 0x1310
#define CPC710_SDRAM0_MCER2 0x1320
#define CPC710_SDRAM0_MCER3 0x1330
#define CPC710_SDRAM0_MCER4 0x1340
#define CPC710_SDRAM0_MCER5 0x1350
#define CPC710_SDRAM0_MCER6 0x1360
#define CPC710_SDRAM0_MCER7 0x1370
#define CPC710_SDRAM0_SIOR0 0x1400
#define CPC710_SDRAM0_SIOR1 0x1420
/* Configuration space registers */
#define CPC710_BUS_NUMBER 0x40
#define CPC710_SUB_BUS_NUMBER 0x41
/* MCCR register bits */
#define CPC710_MCCR_INIT_STATUS 0x20000000
#define CPC710_MCCR_DIAG_MODE 0x40000000
#define CPC710_MCCR_ECC_DISABLE 0x08000000
#define CPC710_MCCR_REFRESH_7CY 0x02000000
#define CPC710_MCCR_DATA_MASK 0x00100000
#define CPC710_MCCR_FIXED_BITS 0x00008000
extern void setCPC710(uint32_t, uint32_t);
extern uint32_t getCPC710(uint32_t);
#endif

View File

@ -1,79 +0,0 @@
#include <console/console.h>
#include <arch/io.h>
#include <stdint.h>
#include <device/device.h>
#include <device/pci.h>
#include <stdlib.h>
#include <string.h>
#include <bitops.h>
#include <cpu/cpu.h>
#include "chip.h"
static void ram_resource(device_t dev, unsigned long index,
unsigned long basek, unsigned long sizek)
{
struct resource *resource;
if (!sizek) {
return;
}
resource = new_resource(dev, index);
resource->base = ((resource_t)basek) << 10;
resource->size = ((resource_t)sizek) << 10;
resource->flags = IORESOURCE_MEM | IORESOURCE_CACHEABLE | \
IORESOURCE_FIXED | IORESOURCE_STORED | IORESOURCE_ASSIGNED;
}
static void pci_domain_set_resources(device_t dev)
{
int idx;
/* Report the memory regions */
idx = 10;
ram_resource(dev, idx++, 0, 1024*1024); /* FIXME */
/* And assign the resources */
assign_resources(&dev->link[0]);
}
static struct device_operations pci_domain_ops = {
.read_resources = pci_domain_read_resources,
.set_resources = pci_domain_set_resources,
.enable_resources = enable_childrens_resources,
.init = 0,
.scan_bus = pci_domain_scan_bus,
.ops_pci_bus = &pci_ppc_conf1,
};
static void cpu_bus_init(device_t dev)
{
initialize_cpus(&dev->link[0]);
}
static void cpu_bus_noop(device_t dev)
{
}
static struct device_operations cpu_bus_ops = {
.read_resources = cpu_bus_noop,
.set_resources = cpu_bus_noop,
.enable_resources = cpu_bus_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_PCI_DOMAIN) {
dev->ops = &pci_domain_ops;
}
else if (dev->path.type == DEVICE_PATH_CPU_BUS) {
dev->ops = &cpu_bus_ops;
}
}
struct chip_operations northbridge_ibm_cpc710_ops = {
CHIP_NAME("IBM CPC710 Northbridge")
.enable_dev = enable_dev,
};

View File

@ -1,119 +0,0 @@
#include <stdint.h>
#include <arch/io.h>
#include <arch/pciconf.h>
#include <delay.h>
#include "cpc710.h"
#include "cpc710_pci.h"
extern void setCPC710(uint32_t, uint32_t);
void
setCPC710_PCI32(uint32_t addr, uint32_t data)
{
out_be32((unsigned *)(CPC710_PCI32_CONFIG + addr), data);
}
#if 0
void
setCPC710_PCI64(uint32_t addr, uint32_t data)
{
out_be32((unsigned *)(CPC710_PCI64_CONFIG + addr), data);
}
#endif
void
cpc710_pci_init(void)
{
/* Enable PCI32 */
setCPC710(CPC710_CPC0_PCICNFR, 0x80000002); /* activate PCI32 config */
setCPC710(CPC710_CPC0_PCIBAR, CPC710_PCI32_CONFIG); /* PCI32 base address */
setCPC710(CPC710_CPC0_PCIENB, 0x80000000); /* enable addr space */
setCPC710(CPC710_CPC0_PCICNFR, 0x00000000); /* config done */
/* Reset PCI Status register */
pci_ppc_write_config16(0, 0, 0x06, 0xffff);
/* Configure bus number */
pci_ppc_write_config16(0, 0, 0x40, 0);
/* Set PCI configuration registers */
setCPC710_PCI32(CPC710_PCIL0_PCIDG, 0x40000000);
setCPC710_PCI32(CPC710_PCIL0_PIBAR, 0x00000000);
setCPC710_PCI32(CPC710_PCIL0_PMBAR, 0x00000000);
setCPC710_PCI32(CPC710_PCIL0_PR, 0xa000c000);
setCPC710_PCI32(CPC710_PCIL0_ACR, 0xfc000000);
setCPC710_PCI32(CPC710_PCIL0_MSIZE, CPC710_PCI32_MEM_SIZE);
setCPC710_PCI32(CPC710_PCIL0_IOSIZE, CPC710_PCI32_IO_SIZE);
setCPC710_PCI32(CPC710_PCIL0_SMBAR, CPC710_PCI32_MEM_BASE);
setCPC710_PCI32(CPC710_PCIL0_SIBAR, CPC710_PCI32_IO_BASE);
setCPC710_PCI32(CPC710_PCIL0_CTLRW, 0x00000000);
setCPC710_PCI32(CPC710_PCIL0_PSSIZE, 0x00000080);
setCPC710_PCI32(CPC710_PCIL0_BARPS, 0x00000000);
setCPC710_PCI32(CPC710_PCIL0_PSBAR, 0x00000080);
setCPC710_PCI32(CPC710_PCIL0_BPMDLK, 0x00000000);
setCPC710_PCI32(CPC710_PCIL0_TPMDLK, 0x00000000);
setCPC710_PCI32(CPC710_PCIL0_BIODLK, 0x00000000);
setCPC710_PCI32(CPC710_PCIL0_TIODLK, 0x00000000);
/* Enable address space */
pci_ppc_write_config16(0, 0, 0x04, 0xfda7);
setCPC710_PCI32(CPC710_PCIL0_CRR, 0xfc000000);
/*
* wait for PCI to reset
*/
udelay(250);
#if 0
/* Enable PCI64 */
setCPC710(CPC710_CPC0_PCICNFR, 0x80000003); /* activate PCI64 config */
setCPC710(CPC710_CPC0_PCIBAR, CPC710_PCI64_CONFIG); /* PCI64 base address */
setCPC710(CPC710_CPC0_PCIENB, 0x80000000); /* enable addr space */
setCPC710(CPC710_CPC0_PCICNFR, 0x00000000); /* config done */
/* Reset PCI Status register */
setCPC710_PCI64(CPC710_PCIL0_CFGADDR, 0x06000080);
setCPC710_PCI64_16(CPC710_PCIL0_CFGDATA, 0xffff);
/* Reset G_INT[A-D] bits in INT_RESET */
setCPC710_PCI64(CPC710_PCIL0_CFGADDR, 0x68000080);
setCPC710_PCI64(CPC710_PCIL0_CFGDATA, 0x0f000000);
/* Configure bus number BUSNO=1, SUBNO=1 */
setCPC710_PCI64(CPC710_PCIL0_CFGADDR, 0x40000080);
setCPC710_PCI64_16(CPC710_PCIL0_CFGDATA, 0x0101);
/* Set PCI configuration registers */
setCPC710_PCI64(CPC710_PCIL0_PSEA, 0x00000000);
setCPC710_PCI64(CPC710_PCIL0_PCIDG, 0xc0000000);
setCPC710_PCI64(CPC710_PCIL0_PIBAR, 0x00000000);
setCPC710_PCI64(CPC710_PCIL0_PMBAR, 0x00000000);
setCPC710_PCI64(CPC710_PCIL0_PR, 0x80008000);
setCPC710_PCI64(CPC710_PCIL0_ACR, 0xff000000);
setCPC710_PCI64(CPC710_PCIL0_MSIZE, CPC710_PCI64_MEM_SIZE);
setCPC710_PCI64(CPC710_PCIL0_IOSIZE, CPC710_PCI64_IO_SIZE);
setCPC710_PCI64(CPC710_PCIL0_SMBAR, CPC710_PCI64_MEM_BASE);
setCPC710_PCI64(CPC710_PCIL0_SIBAR, CPC710_PCI64_IO_BASE);
setCPC710_PCI64(CPC710_PCIL0_CTLRW, 0x02000000);
setCPC710_PCI64(CPC710_PCIL0_PSSIZE, 0x00000080);
/* Config PSBAR for PCI64 */
setCPC710_PCI64(CPC710_PCIL0_CFGADDR, 0x10000080);
setCPC710_PCI64(CPC710_PCIL0_CFGDATA, 0x00000080);
setCPC710_PCI64(CPC710_PCIL0_BARPS, 0x00000000);
setCPC710_PCI64(CPC710_PCIL0_INTSET, 0x00000000);
/* Enable address space */
setCPC710_PCI64(CPC710_PCIL0_CFGADDR, 0x04000180);
setCPC710_PCI64_16(CPC710_PCIL0_CFGDATA, 0xfda7);
setCPC710_PCI64(CPC710_PCIL0_CRR, 0xfc000000);
/*
* wait for PCI to reset
*/
udelay(250);
#endif
}

View File

@ -1,64 +0,0 @@
/*
* (C) Copyright 2002
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* 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., 51 Franklin St, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
#ifndef _CPC710_PCI_H_
#define _CPC710_PCI_H_
#define CPC710_PCI32_CONFIG (CONFIG_PCIC0_CFGADDR & 0xfff00000)
#define CPC710_PCI32_MEM_SIZE 0xf8000000
#define CPC710_PCI32_MEM_BASE 0xc0000000
#define CPC710_PCI32_IO_SIZE 0xf8000000
#define CPC710_PCI32_IO_BASE 0x80000000
//#define CPC710_PCI64_CONFIG 0xff400000
//#define CPC710_PCI64_MEM_SIZE 0xf8000000
//#define CPC710_PCI64_MEM_BASE 0xc8000000
//#define CPC710_PCI64_IO_SIZE 0xf8000000
//#define CPC710_PCI64_IO_BASE 0x88000000
#define CPC710_PCIL0_PSEA 0xf6110
#define CPC710_PCIL0_PCIDG 0xf6120
#define CPC710_PCIL0_INTACK 0xf7700
#define CPC710_PCIL0_PIBAR 0xf7800
#define CPC710_PCIL0_PMBAR 0xf7810
#define CPC710_PCIL0_CRR 0xf7ef0
#define CPC710_PCIL0_PR 0xf7f20
#define CPC710_PCIL0_ACR 0xf7f30
#define CPC710_PCIL0_MSIZE 0xf7f40
#define CPC710_PCIL0_IOSIZE 0xf7f60
#define CPC710_PCIL0_SMBAR 0xf7f80
#define CPC710_PCIL0_SIBAR 0xf7fc0
#define CPC710_PCIL0_CTLRW 0xf7fd0
#define CPC710_PCIL0_CFGADDR 0xf8000 /* little endian */
#define CPC710_PCIL0_CFGDATA 0xf8010 /* little endian */
#define CPC710_PCIL0_PSSIZE 0xf8100
#define CPC710_PCIL0_BARPS 0xf8120
#define CPC710_PCIL0_PSBAR 0xf8140
#define CPC710_PCIL0_BPMDLK 0xf8200
#define CPC710_PCIL0_TPMDLK 0xf8210
#define CPC710_PCIL0_BIODLK 0xf8220
#define CPC710_PCIL0_TIODLK 0xf8230
#define CPC710_PCIL0_INTSET 0xf8310
#endif

View File

@ -1,12 +0,0 @@
#include <mem.h>
struct mem_range *
sizeram(void)
{
static struct mem_range meminfo;
meminfo.basek = 0;
meminfo.sizek = 1024 * 1024; /* FIXME */
return &meminfo;
}

View File

@ -1,12 +0,0 @@
#
# Config file for IBM CPC925
#
config chip.h
initobject cpc925.o
initobject cpc925_pci.o
object cpc925.o
object cpc925_pci.o
driver cpc925_northbridge.o

View File

@ -1,6 +0,0 @@
struct northbridge_ibm_cpc925_config {
/* Nothing yet */
};
extern struct chip_operations northbridge_ibm_cpc925_ops;

View File

@ -1,24 +0,0 @@
#include <stdint.h>
#include <arch/io.h>
#include "cpc925.h"
void cpc925_init(void);
void sdram_init(void);
void
memory_init(void)
{
cpc925_init();
sdram_init();
cpc925_pci_init();
}
void
cpc925_init(void)
{
}
void
sdram_init()
{
}

View File

@ -1,4 +0,0 @@
#ifndef _CPC925_H_
#define _CPC925_H_
#endif

View File

@ -1,79 +0,0 @@
#include <console/console.h>
#include <arch/io.h>
#include <stdint.h>
#include <device/device.h>
#include <device/pci.h>
#include <stdlib.h>
#include <string.h>
#include <bitops.h>
#include <cpu/cpu.h>
#include "chip.h"
static void ram_resource(device_t dev, unsigned long index,
unsigned long basek, unsigned long sizek)
{
struct resource *resource;
if (!sizek) {
return;
}
resource = new_resource(dev, index);
resource->base = ((resource_t)basek) << 10;
resource->size = ((resource_t)sizek) << 10;
resource->flags = IORESOURCE_MEM | IORESOURCE_CACHEABLE | \
IORESOURCE_FIXED | IORESOURCE_STORED | IORESOURCE_ASSIGNED;
}
static void pci_domain_set_resources(device_t dev)
{
int idx;
/* Report the memory regions */
idx = 10;
ram_resource(dev, idx++, 0, 1024*1024); /* FIXME */
/* And assign the resources */
assign_resources(&dev->link[0]);
}
static struct device_operations pci_domain_ops = {
.read_resources = pci_domain_read_resources,
.set_resources = pci_domain_set_resources,
.enable_resources = enable_childrens_resources,
.init = 0,
.scan_bus = pci_domain_scan_bus,
.ops_pci_bus = &pci_ppc_conf1,
};
static void cpu_bus_init(device_t dev)
{
initialize_cpus(&dev->link[0]);
}
static void cpu_bus_noop(device_t dev)
{
}
static struct device_operations cpu_bus_ops = {
.read_resources = cpu_bus_noop,
.set_resources = cpu_bus_noop,
.enable_resources = cpu_bus_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_PCI_DOMAIN) {
dev->ops = &pci_domain_ops;
}
else if (dev->path.type == DEVICE_PATH_CPU_BUS) {
dev->ops = &cpu_bus_ops;
}
}
struct chip_operations northbridge_ibm_cpc925_ops = {
CHIP_NAME("IBM CPC925 Northbridge")
.enable_dev = enable_dev,
};

View File

@ -1,9 +0,0 @@
#include <stdint.h>
#include <arch/io.h>
#include "cpc925.h"
#include "cpc925_pci.h"
void
cpc925_pci_init(void)
{
}

View File

@ -1,4 +0,0 @@
#ifndef _CPC925_PCI_H_
#define _CPC925_PCI_H_
#endif

View File

@ -1 +0,0 @@
#source src/northbridge/motorola/mpc107/Kconfig

View File

@ -1 +0,0 @@
subdirs-y += mpc107

View File

@ -1,10 +0,0 @@
#
# Objects linked with coreboot
#
config chip.h
# We need sdram_init() in ppc_main()
initobject meminfo.o
initobject mpc107.o
object mpc107_northbridge.c

View File

@ -1,6 +0,0 @@
struct northbridge_motorola_mpc107_config {
/* Nothing yet */
};
extern struct chip_operations northbridge_motorola_mpc107_ops;

View File

@ -1,517 +0,0 @@
/**************************************************
*
* copyright @ motorola, 1999
*
*************************************************/
#include <pci.h>
#include <printk.h>
#include <northbridge/motorola/mpc107/epic.h>
extern struct pci_ops pci_direct_ppc;
typedef void (*VOIDFUNCPTR) (void); /* ptr to function returning void */
struct SrcVecTable SrcVecTable[MAXVEC] = /* Addr/Vector cross-reference tbl */
{
{ EPIC_EX_INT0_VEC_REG, "External Direct/Serial Source 0"},
{ EPIC_EX_INT1_VEC_REG, "External Direct/Serial Source 1"},
{ EPIC_EX_INT2_VEC_REG, "External Direct/Serial Source 2"},
{ EPIC_EX_INT3_VEC_REG, "External Direct/Serial Source 3"},
{ EPIC_EX_INT4_VEC_REG, "External Direct/Serial Source 4"},
{ EPIC_SR_INT5_VEC_REG, "External Serial Source 5"},
{ EPIC_SR_INT6_VEC_REG, "External Serial Source 6"},
{ EPIC_SR_INT7_VEC_REG, "External Serial Source 7"},
{ EPIC_SR_INT8_VEC_REG, "External Serial Source 8"},
{ EPIC_SR_INT9_VEC_REG, "External Serial Source 9"},
{ EPIC_SR_INT10_VEC_REG, "External Serial Source 10"},
{ EPIC_SR_INT11_VEC_REG, "External Serial Source 11"},
{ EPIC_SR_INT12_VEC_REG, "External Serial Source 12"},
{ EPIC_SR_INT13_VEC_REG, "External Serial Source 13"},
{ EPIC_SR_INT14_VEC_REG, "External Serial Source 14"},
{ EPIC_SR_INT15_VEC_REG, "External Serial Source 15"},
{ EPIC_I2C_INT_VEC_REG, "Internal I2C Source"},
{ EPIC_DMA0_INT_VEC_REG, "Internal DMA0 Source"},
{ EPIC_DMA1_INT_VEC_REG, "Internal DMA1 Source"},
{ EPIC_MSG_INT_VEC_REG, "Internal Message Source"},
};
VOIDFUNCPTR intVecTbl[MAXVEC]; /* Interrupt vector table */
/****************************************************************************
* epicInit - Initialize the EPIC registers
*
* This routine resets the Global Configuration Register, thus it:
* - Disables all interrupts
* - Sets epic registers to reset values
* - Sets the value of the Processor Current Task Priority to the
* highest priority (0xF).
* epicInit then sets the EPIC operation mode to Mixed Mode (vs. Pass
* Through or 8259 compatible mode).
*
* If IRQType (input) is Direct IRQs:
* - IRQType is written to the SIE bit of the EPIC Interrupt
* Configuration register (ICR).
* - clkRatio is ignored.
* If IRQType is Serial IRQs:
* - both IRQType and clkRatio will be written to the ICR register
*/
void epicInit
(
unsigned int IRQType, /* Direct or Serial */
unsigned int clkRatio /* Clk Ratio for Serial IRQs */
)
{
ULONG tmp;
tmp = sysEUMBBARRead(EPIC_GLOBAL_REG);
tmp |= 0xa0000000; /* Set the Global Conf. register */
sysEUMBBARWrite(EPIC_GLOBAL_REG, tmp);
/*
* Wait for EPIC to reset - CLH
*/
while( (sysEUMBBARRead(EPIC_GLOBAL_REG) & 0x80000000) == 1);
sysEUMBBARWrite(EPIC_GLOBAL_REG, 0x20000000);
tmp = sysEUMBBARRead(EPIC_INT_CONF_REG); /* Read interrupt conf. reg */
if (IRQType == EPIC_DIRECT_IRQ) /* direct mode */
sysEUMBBARWrite(EPIC_INT_CONF_REG, tmp & 0xf7ffffff);
else /* Serial mode */
{
tmp = (clkRatio << 28) | 0x08000000; /* Set clock ratio */
sysEUMBBARWrite(EPIC_INT_CONF_REG, tmp);
}
while (epicIntAck() != 0xff) /* Clear all pending interrupts */
epicEOI();
}
/****************************************************************************
* epicIntEnable - Enable an interrupt source
*
* This routine clears the mask bit of an external, an internal or
* a Timer register to enable the interrupt.
*
* RETURNS: None
*/
void epicIntEnable(int intVec)
{
ULONG tmp;
ULONG srAddr;
srAddr = SrcVecTable[intVec].srcAddr; /* Retrieve src Vec/Prio register */
tmp = sysEUMBBARRead(srAddr);
tmp &= ~EPIC_VEC_PRI_MASK; /* Clear the mask bit */
tmp |= (EPIC_VEC_PRI_DFLT_PRI << 16); /* Set priority to Default - CLH */
tmp |= intVec; /* Set Vector number */
sysEUMBBARWrite(srAddr, tmp);
return;
}
/****************************************************************************
* epicIntDisable - Disable an interrupt source
*
* This routine sets the mask bit of an external, an internal or
* a Timer register to disable the interrupt.
*
* RETURNS: OK or ERROR
*
*/
void epicIntDisable
(
int intVec /* Interrupt vector number */
)
{
ULONG tmp, srAddr;
srAddr = SrcVecTable[intVec].srcAddr;
tmp = sysEUMBBARRead(srAddr);
tmp |= 0x80000000; /* Set the mask bit */
sysEUMBBARWrite(srAddr, tmp);
return;
}
/****************************************************************************
* epicIntSourceConfig - Set properties of an interrupt source
*
* This function sets interrupt properites (Polarity, Sense, Interrupt
* Prority, and Interrupt Vector) of an Interrupt Source. The properties
* can be set when the current source is not in-request or in-service,
* which is determined by the Activity bit. This routine return ERROR
* if the the Activity bit is 1 (in-request or in-service).
*
* This function assumes that the Source Vector/Priority register (input)
* is a valid address.
*
* RETURNS: OK or ERROR
*/
int epicIntSourceConfig
(
int Vect, /* interrupt source vector number */
int Polarity, /* interrupt source polarity */
int Sense, /* interrupt source Sense */
int Prio /* interrupt source priority */
)
{
ULONG tmp, newVal;
ULONG actBit, srAddr;
srAddr = SrcVecTable[Vect].srcAddr;
tmp = sysEUMBBARRead(srAddr);
actBit = (tmp & 40000000) >> 30; /* retrieve activity bit - bit 30 */
if (actBit == 1)
return ERROR;
tmp &= 0xff30ff00; /* Erase previously set P,S,Prio,Vector bits */
newVal = (Polarity << 23) | (Sense << 22) | (Prio << 16) | Vect;
sysEUMBBARWrite(srAddr, tmp | newVal );
return (OK);
}
/****************************************************************************
* epicIntAck - acknowledge an interrupt
*
* This function reads the Interrupt acknowldge register and return
* the vector number of the highest pending interrupt.
*
* RETURNS: Interrupt Vector number.
*/
unsigned int epicIntAck(void)
{
return(sysEUMBBARRead( EPIC_PROC_INT_ACK_REG ));
}
/****************************************************************************
* epicEOI - signal an end of interrupt
*
* This function writes 0x0 to the EOI register to signal end of interrupt.
* It is usually called after an interrupt routine is served.
*
* RETURNS: None
*/
void epicEOI(void)
{
sysEUMBBARWrite(EPIC_PROC_EOI_REG, 0x0);
}
/****************************************************************************
* epicCurTaskPrioSet - sets the priority of the Processor Current Task
*
* This function should be called after epicInit() to lower the priority
* of the processor current task.
*
* RETURNS: OK or ERROR
*/
int epicCurTaskPrioSet
(
int prioNum /* New priority value */
)
{
if ( (prioNum < 0) || (prioNum > 0xF))
return ERROR;
sysEUMBBARWrite(EPIC_PROC_CTASK_PRI_REG, prioNum);
return OK;
}
/************************************************************************
* function: epicIntTaskGet
*
* description: Get value of processor current interrupt task priority register
*
* note:
***********************************************************************/
unsigned char epicIntTaskGet()
{
/* get the interrupt task priority register */
ULONG reg;
unsigned char rec;
reg = sysEUMBBARRead( EPIC_PROC_CTASK_PRI_REG );
rec = ( reg & 0x0F );
return rec;
}
/**************************************************************
* function: epicISR
*
* description: EPIC service routine called by the core exception
* at 0x500
*
* note:
**************************************************************/
unsigned int epicISR(void)
{
return 0;
}
/************************************************************
* function: epicModeGet
*
* description: query EPIC mode, return 0 if pass through mode
* return 1 if mixed mode
*
* note:
*************************************************************/
unsigned int epicModeGet(void)
{
ULONG val;
val = sysEUMBBARRead( EPIC_GLOBAL_REG );
return (( val & 0x20000000 ) >> 29);
}
/*********************************************
* function: epicConfigGet
*
* description: Get the EPIC interrupt Configuration
* return 0 if not error, otherwise return 1
*
* note:
********************************************/
void epicConfigGet( unsigned int *clkRatio, unsigned int *serEnable)
{
ULONG val;
val = sysEUMBBARRead( EPIC_INT_CONF_REG );
*clkRatio = ( val & 0x70000000 ) >> 28;
*serEnable = ( val & 0x8000000 ) >> 27;
}
/*******************************************************************
* sysEUMBBARRead - Read a 32-bit EUMBBAR register
*
* This routine reads the content of a register in the Embedded
* Utilities Memory Block, and swaps to big endian before returning
* the value.
*
* RETURNS: The content of the specified EUMBBAR register.
*/
ULONG sysEUMBBARRead
(
ULONG regNum
)
{
u32 temp;
pci_direct_ppc.read_dword(0, 0, regNum, &temp);
return ( temp );
}
/*******************************************************************
* sysEUMBBARWrite - Write a 32-bit EUMBBAR register
*
* This routine swaps the value to little endian then writes it to
* a register in the Embedded Utilities Memory Block address space.
*
* RETURNS: N/A
*/
void sysEUMBBARWrite
(
ULONG regNum, /* EUMBBAR register address */
u32 regVal /* Value to be written */
)
{
pci_direct_ppc.read_dword(0, 0, regNum, &regVal);
return ;
}
/********************************************************
* function: epicVendorId
*
* description: return the EPIC Vendor Identification
* register:
*
* siliccon version, device id, and vendor id
*
* note:
********************************************************/
void epicVendorId
(
unsigned int *step,
unsigned int *devId,
unsigned int *venId
)
{
ULONG val;
val = sysEUMBBARRead( EPIC_VENDOR_ID_REG );
*step = ( val & 0x00FF0000 ) >> 16;
*devId = ( val & 0x0000FF00 ) >> 8;
*venId = ( val & 0x000000FF );
}
/**************************************************
* function: epicFeatures
*
* description: return the number of IRQ supported,
* number of CPU, and the version of the
* OpenEPIC
*
* note:
*************************************************/
void epicFeatures
(
unsigned int *noIRQs,
unsigned int *noCPUs,
unsigned int *verId
)
{
ULONG val;
val = sysEUMBBARRead( EPIC_FEATURES_REG );
*noIRQs = ( val & 0x07FF0000 ) >> 16;
*noCPUs = ( val & 0x00001F00 ) >> 8;
*verId = ( val & 0x000000FF );
}
/*********************************************************
* function: epciTmFrequncySet
*
* description: Set the timer frequency reporting register
********************************************************/
void epicTmFrequencySet( unsigned int frq )
{
sysEUMBBARWrite(EPIC_TM_FREQ_REG, frq);
}
/*******************************************************
* function: epicTmFrequncyGet
*
* description: Get the current value of the Timer Frequency
* Reporting register
*
******************************************************/
unsigned int epicTmFrequencyGet(void)
{
return( sysEUMBBARRead(EPIC_TM_FREQ_REG)) ;
}
/****************************************************
* function: epicTmBaseSet
*
* description: Set the #n global timer base count register
* return 0 if no error, otherwise return 1.
*
* note:
****************************************************/
unsigned int epicTmBaseSet
(
ULONG srcAddr, /* Address of the Timer Base register */
unsigned int cnt, /* Base count */
unsigned int inhibit /* 1 - count inhibit */
)
{
unsigned int val = 0x80000000;
/* First inhibit counting the timer */
sysEUMBBARWrite(srcAddr, val) ;
/* set the new value */
val = (cnt & 0x7fffffff) | ((inhibit & 0x1) << 31);
sysEUMBBARWrite(srcAddr, val) ;
return 0;
}
/***********************************************************************
* function: epicTmBaseGet
*
* description: Get the current value of the global timer base count register
* return 0 if no error, otherwise return 1.
*
* note:
***********************************************************************/
unsigned int epicTmBaseGet( ULONG srcAddr, unsigned int *val )
{
*val = sysEUMBBARRead( srcAddr );
*val = *val & 0x7fffffff;
return 0;
}
/***********************************************************
* function: epicTmCountGet
*
* description: Get the value of a given global timer
* current count register
* return 0 if no error, otherwise return 1
* note:
**********************************************************/
unsigned int epicTmCountGet( ULONG srcAddr, unsigned int *val )
{
*val = sysEUMBBARRead( srcAddr );
*val = *val & 0x7fffffff;
return 0;
}
/***********************************************************
* function: epicTmInhibit
*
* description: Stop counting of a given global timer
* return 0 if no error, otherwise return 1
*
* note:
***********************************************************/
unsigned int epicTmInhibit( unsigned int srcAddr )
{
ULONG val;
val = sysEUMBBARRead( srcAddr );
val |= 0x80000000;
sysEUMBBARWrite( srcAddr, val );
return 0;
}
/******************************************************************
* function: epicTmEnable
*
* description: Enable counting of a given global timer
* return 0 if no error, otherwise return 1
*
* note:
*****************************************************************/
unsigned int epicTmEnable( ULONG srcAddr )
{
ULONG val;
val = sysEUMBBARRead( srcAddr );
val &= 0x7fffffff;
sysEUMBBARWrite( srcAddr, val );
return 0;
}
void epicSourcePrint(int Vect)
{
ULONG srcVal;
srcVal = sysEUMBBARRead(SrcVecTable[Vect].srcAddr);
printk_info("%s\n", SrcVecTable[Vect].srcName);
printk_info("Address = 0x%lx\n", SrcVecTable[Vect].srcAddr);
printk_info("Vector = %ld\n", (srcVal & 0x000000FF) );
printk_info("Mask = %ld\n", srcVal >> 31);
printk_info("Activitiy = %ld\n", (srcVal & 40000000) >> 30);
printk_info("Polarity = %ld\n", (srcVal & 0x00800000) >> 23);
printk_info("Sense = %ld\n", (srcVal & 0x00400000) >> 22);
printk_info("Priority = %ld\n", (srcVal & 0x000F0000) >> 16);
}

View File

@ -1,99 +0,0 @@
/*
* (C) Copyright 2002
* Humboldt Solutions Ltd, <adrian@humboldt.co.uk>
*
* 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., 51 Franklin St, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include "i2c.h"
static i2c_bus *first_i2c = NULL;
#if 0
int register_i2c_bus(const i2c_fn *fn, char *tag, void *data)
{
i2c_bus *bus = malloc (sizeof (i2c_bus));
if (bus)
{
bus->fn = fn;
bus->tag = tag;
bus->data = data;
bus->next = first_i2c;
first_i2c = bus;
return 0;
}
return -1;
}
#endif
i2c_bus *find_i2c_bus(const char *name)
{
int len;
if (! name)
return first_i2c;
if (first_i2c)
{
i2c_bus *i2c;
len = strlen(name);
for (i2c = first_i2c; i2c; i2c = i2c->next)
if (strlen(i2c->tag) == len && memcmp (name, i2c->tag, len) == 0)
return i2c;
}
return NULL;
}
void i2c_start(struct i2c_bus *bus)
{
if (! bus)
bus = first_i2c;
bus->fn->start(bus);
}
void i2c_stop(struct i2c_bus *bus)
{
if (! bus)
bus = first_i2c;
bus->fn->stop(bus);
}
int i2c_master_write(struct i2c_bus *bus, int target, int address,
const uint8_t *data, int length)
{
if (! bus)
bus = first_i2c;
return bus->fn->master_write(bus, target, address, data, length);
}
int i2c_master_read(struct i2c_bus *bus, int target, int address,
uint8_t *data, int length)
{
if (! bus)
bus = first_i2c;
return bus->fn->master_read(bus, target, address, data, length);
}

View File

@ -1,57 +0,0 @@
/*
* (C) Copyright 2002
* Humboldt Solutions Ltd, <adrian@humboldt.co.uk>
*
* 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., 51 Franklin St, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
#ifndef _I2C_H
#define _I2C_H
struct i2c_bus;
typedef struct i2c_fn
{
void (* start)(struct i2c_bus *bus);
void (* stop)(struct i2c_bus *bus);
int (* master_write)(struct i2c_bus *bus, int target, int address,
const uint8_t *data, int length);
int (* master_read)(struct i2c_bus *bus, int target, int address,
uint8_t *data, int length);
} i2c_fn;
typedef struct i2c_bus
{
const i2c_fn *fn;
char *tag;
void *data;
struct i2c_bus *next;
} i2c_bus;
i2c_bus *find_i2c_bus(const char *name);
int register_i2c_bus(const i2c_fn *fn, char *tag, void *data);
void i2c_start(struct i2c_bus *bus);
void i2c_stop(struct i2c_bus *bus);
int i2c_master_write(struct i2c_bus *bus, int target, int address,
const uint8_t *data, int length);
int i2c_master_read(struct i2c_bus *bus, int target, int address,
uint8_t *data, int length);
void init_i2c_nvram(const char *i2c_tag);
extern i2c_fn mpc107_i2c_fn;
#endif

View File

@ -1,200 +0,0 @@
/*
* (C) Copyright 2001
* Humboldt Solutions Ltd, adrian@humboldt.co.uk.
*
* 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., 51 Franklin St, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
#include <console/console.h>
#include "mpc107.h"
void
sdram_dimm_to_bank_info(const char *data, sdram_dimm_info *dimm)
{
sdram_bank_info *bank1 = dimm->bank1;
sdram_bank_info *bank2 = dimm->bank2;
unsigned char csum = 0;
unsigned char x;
int i;
int no_cas_latencies = 0;
char latency[3];
/* Mark banks initially broken */
bank1->size = 0;
bank2->size = 0;
if (data[0] < 64)
{
printk_info("SPD data too short\n");
return;
}
for(i = 0; i < 63; i++)
csum += data[i];
if (csum != data[63])
{
printk_info("Broken checksum 0x%x, should be 0x%x\n", data[63], csum);
return;
}
if (data[2] != 0x04)
{
printk_info("SDRAM Only\n");
return;
}
bank1->row_bits = data[3] & 0x0f;
if (data[3] >> 4)
bank2->row_bits = data[3] >> 4;
else
bank2->row_bits = bank1->row_bits;
bank1->internal_banks = bank2->internal_banks = data[17];
bank1->col_bits = data[4] & 0x0f;
if (data[4] >> 4)
bank2->col_bits = data[4] >> 4;
else
bank2->col_bits = bank1->col_bits;
if (data[7] || (data[6] != 80 && data[6] != 72 && data[6] != 64))
{
printk_info("Data width incorrect\n");
return;
}
if (data[8] != 0x01)
{
printk_info("3.3V TTL DIMMS only\n");
return;
}
/* Extract CAS latencies in reverse order, as we only get info on
the highest ones. */
x = data[18];
for(i = 7; i > 0; i--)
{
if (x & 0x40)
{
if (no_cas_latencies < 3)
latency[no_cas_latencies] = i;
no_cas_latencies++;
}
x <<= 1;
}
/* Now fill in other timings - we're most interested in the lowest
CAS latency, so we shuffle data to put that first. */
for(i = no_cas_latencies; i >= 0; i--)
bank1->cas_latency[no_cas_latencies - i - 1] =
bank2->cas_latency[no_cas_latencies - i - 1] =
latency[i];
for(i = no_cas_latencies; i < 3; i++)
bank1->cas_latency[i] = bank2->cas_latency[i] = 0;
/* Store values for the highest cas latency */
bank1->cycle_time[no_cas_latencies - 1] =
bank2->cycle_time[no_cas_latencies- 1] =
100 * (data[9] >> 4) + 10 * (data[9] & 0xf);
bank1->access_time[no_cas_latencies - 1] =
bank2->access_time[no_cas_latencies - 1] =
100 * (data[10] >> 4) + 10 * (data[10] & 0xf);
/* Then the second highest */
if (no_cas_latencies > 1)
{
bank1->cycle_time[no_cas_latencies - 2] =
bank2->cycle_time[no_cas_latencies- 2] =
100 * (data[23] >> 4) + 10 * (data[23] & 0xf);
bank1->access_time[no_cas_latencies - 2] =
bank2->access_time[no_cas_latencies - 2] =
100 * (data[24] >> 4) + 10 * (data[24] & 0xf);
}
/* Then the third highest */
if (no_cas_latencies > 2)
{
bank1->cycle_time[no_cas_latencies - 3] =
bank2->cycle_time[no_cas_latencies- 3] =
100 * (data[25] >> 2) + 25 * (data[25] & 0x3);
bank1->access_time[no_cas_latencies - 3] =
bank2->access_time[no_cas_latencies - 3] =
100 * (data[26] >> 2) + 25 * (data[26] & 0x3);
}
for(i = 0; i < no_cas_latencies; i++)
printk_debug("CL %d: cycle %dns access %dns\n",
bank1->cas_latency[i], bank1->cycle_time[i] / 100,
bank1->access_time[i] / 100);
/* Other timings */
bank1->min_back_to_back = bank2->min_back_to_back = data[15];
bank1->min_row_precharge = bank2->min_row_precharge = data[27];
bank1->min_active_to_active = bank2->min_active_to_active = data[28];
bank1->min_ras_to_cas = bank2->min_ras_to_cas = data[29];
bank1->min_ras = bank2->min_ras = data[30];
/* Error detection type */
bank1->error_detect = bank2->error_detect = data[11];
/* Crucial row sizes - these mark the data as valid */
for(i = 7; i >= 0; i--)
{
if (data[31] & (1 << i))
{
bank1->size = (4*1024*1024) << i;
break;
}
}
if (data[5] > 1)
{
for(i-- ; i >= 0; i--)
{
if (data[31] & (1 << i))
{
bank2->size = (4*1024*1024) << i;
break;
}
}
if (! bank2->size)
bank2->size = bank1->size;
}
dimm->size = bank1->size + bank2->size;
}
void
print_sdram_bank_info(const sdram_bank_info *bank)
{
if (bank->size)
printk_debug(" Bank %d: %dMB\n", bank->number, bank->size / (1024*1024));
}
static const char *error_types[] = {"", "Parity ", "ECC "};
void
print_sdram_dimm_info(const sdram_dimm_info *dimm)
{
printk_debug("Dimm %d: ", dimm->number);
if (dimm->size) {
printk_debug("%dMB CL%d (%s): Running at CL%d %s\n",
dimm->size / (1024*1024), dimm->bank1->cas_latency[0],
dimm->part_number,
dimm->bank1->actual_cas,
error_types[dimm->bank1->actual_detect]);
print_sdram_bank_info(dimm->bank1);
print_sdram_bank_info(dimm->bank2);
} else
printk_debug("(none)\n");
}

View File

@ -1,744 +0,0 @@
/*
* (C) Copyright 2001
* Humboldt Solutions Ltd, adrian@humboldt.co.uk.
*
* 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., 51 Franklin St, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
#include <stdint.h>
#include <ppc.h>
#include <string.h>
#include <printk.h>
#include <arch/io.h>
#include <arch/pciconf.h>
#include <timer.h>
#include <clock.h>
#include "i2c.h"
#include "mpc107.h"
#define NUM_DIMMS 1
#define NUM_BANKS 2
void mpc107_init(void);
void
memory_init(void)
{
unsigned dimm;
uint32_t mem_size;
struct sdram_dimm_info dimms[NUM_DIMMS];
struct sdram_bank_info banks[NUM_BANKS];
mpc107_init();
mpc107_probe_dimms(NUM_DIMMS, dimms, banks);
mem_size = mpc107_config_memory(NUM_BANKS, banks, 2);
for (dimm = 0; dimm < NUM_DIMMS; dimm ++)
print_sdram_dimm_info(&dimms[dimm]);
printk_info("Configured %dMB memory\n", mem_size / (1024*1024));
}
/*
* Configure the MPC107 with the most pessimistic settings. These
* are modified by reading the SPD EEPROM and adjusting accordingly.
* One thing to note. The SPD settings can be wrong, as
* was the case for my machine. I could only configure 32Mb out of
* 128Mb using these settings.
*/
void
mpc107_init(void)
{
uint16_t reg16;
uint32_t reg32;
uint32_t is32bits;
/*
* PCI Cmd
*/
pci_ppc_write_config16(0, 0, 0x04, 0x0006);
/*
* PCI Stat
*/
reg16 = pci_ppc_read_config16(0, 0, 0x06);
reg16 |= 0xffff;
pci_ppc_write_config16(0, 0, 0x06, reg16);
/*
* PICR1
* 0x00400000 burst read wait states = 1
* 0x00040000 processor type = 603/750
* 0x00002000 enable LocalBusSlave
* 0x00001000 enable Flash write
* 0x00000800 enable MCP* assertion
* 0x00000400 enable TEA* assertion
* 0x00000200 enable data bus parking
* 0x00000080 restrict flash write width
* 0x00000040 enable PCI store gathering
* 0x00000010 enable loop-snoop
* 0x00000008 enable address bus parking
* 0x00000004 enable speculative PCI reads
*/
reg32 = pci_ppc_read_config32(0, 0, 0xa8);
/*
* Preserve RCS0/Addr Map bits
*/
reg32 &= 0x11;
reg32 |= 0xff041a98;
pci_ppc_write_config32(0, 0, 0xa8, reg32);
/*
* PICR2
* 0x20000000 no Serialize Config cycles
* 0x08000000 No PCI Snoop cycles
* 0x04000000 FF0 is Local ROM
* 0x02000000 Flash write lockout
* 0x00000000 snoop wt states = 0
* 0x00040000 snoop wt states = 1
* 0x00080000 snoop wt states = 2
* 0x000c0000 snoop wt states = 3
* 0x00000000 addr phase wt states = 0
* 0x00000004 addr phase wt states = 1
* 0x00000008 addr phase wt states = 2
* 0x0000000c addr phase wt states = 3
*/
reg32 = 0x04000000;
pci_ppc_write_config32(0, 0, 0xac, reg32);
/*
* EUMBBAR
*/
reg32 = 0xfc000000;
pci_ppc_write_config32(0, 0, 0x78, reg32);
/*
* MCCR1 - Set MEMGO bit later!
* 0x75800000 Safe local ROM = 10+3 clocks
* 0x73800000 Fast local ROM = 7+3 clocks
* 0x00100000 Burst ROM/Flash enable
* 0x00040000 Self-refresh enable
* 0x00020000 EDO/FP enable (else SDRAM)
* 0x00010000 Parity check
* 0x0000FFFF 16Mbit/2 bank SDRAM
* 0x0000AAAA 256Mbit/4 bank SDRAM
* 0x00005555 64Mbit/2 bank SDRAM
* 0x00000000 64Mbit/4 bank SDRAM
*/
reg32 = pci_ppc_read_config32(0, 0, 0xf0);
is32bits = (reg32 & 0x00400000) == 0;
reg32 &= 0x00080000; /* Preserve MEMGO bit in case we're in RAM */
reg32 |= 0x75800000;
pci_ppc_write_config32(0, 0, 0xf0, reg32);
/*
* MCCR2
* 0x40000000 TS_WAIT_TIMER = 3 clocks
* 0x04000000 ASRISE = 2 clocks
* 0x00400000 ASFALL = 2 clocks
* 0x00100000 SDRAM parity (else ECC)
* 0x00080000 SDRAM inline writes
* 0x00040000 SDRAM inline reads
* 0x00020000 ECC enable
* 0x00010000 EDO (else FP)
* 0x000004cc Refresh 33MHz bus (307 clocks)
* 0x00000cc4 Refresh 66MHz bus (817 clocks)
* 0x000010fc Refresh 83MHz bus (1087 clocks)
* 0x0000150c Refresh 100MHz bus (1347 clocks)
* 0x00001d2c Refresh 133MHz bus (1867 clocks)
* 0x00000002 Reserve a page
* 0x00000001 RWM parity
*/
reg32 = 0x044004cc;
pci_ppc_write_config32(0, 0, 0xf4, reg32);
/*
* MCCR3
* 0x70000000 BSTOPRE_M = 7
* 0x08000000 REFREC = 8 clocks
* 0x00400000 RDLAT = 4 clocks
* 0x00300000 RDLAT = 3 clocks
*/
reg32 = 0x78400000;
pci_ppc_write_config32(0, 0, 0xf8, reg32);
/*
* MCCR4
* 0x30000000 PRETOACT = 3 clocks
* 0x05000000 ACTOPRE = 5 clocks
* 0x00800000 Enable 8-beat burst (32-bit bus)
* 0x00400000 Enable Inline ECC/Parity
* 0x00200000 Enable Extended ROM (RCS2/RCS3)
* 0x00100000 Registered buffers
* 0x00000000 BSTOPRE_U = 0
* 0x00020000 Change RCS1 to 8-bit mode
* 0x00008000 Registered DIMMs
* 0x00003000 CAS Latencey (CL=3)
* 0x00002000 CAS Latencey (CL=2)
* 0x00000200 Sequential wrap/4-beat burst
* 0x00000300 Sequential wrap/8-beat burst
* 0x00000030 Reserve a page
* 0x00000009 RWM parity
*/
reg32 = 0x35323239;
if (!is32bits)
reg32 |= 0x0300;
pci_ppc_write_config32(0, 0, 0xfc, reg32);
/*
* MSAR1/MSAR2/MESAR1/MESAR2
*
* Assume each memory block is 32Mb. This is
* most likely NOT correct.
*/
pci_ppc_write_config32(0, 0, 0x80, 0xc0804000);
pci_ppc_write_config32(0, 0, 0x84, 0xc0804000);
pci_ppc_write_config32(0, 0, 0x88, 0x00000000);
pci_ppc_write_config32(0, 0, 0x8c, 0x01010101);
/*
* MEAR1/MEAR2/MEEAR1/MEEAR2
*/
pci_ppc_write_config32(0, 0, 0x90, 0xffbf7f3f);
pci_ppc_write_config32(0, 0, 0x94, 0xffbf7f3f);
pci_ppc_write_config32(0, 0, 0x98, 0x00000000);
pci_ppc_write_config32(0, 0, 0x9c, 0x10101010);
/*
* ODCR
* 0x80 PCI I/O 50 ohms
* 0x40 CPU I/O 50 ohms
* 0x30 Mem I/O 8 ohms
* 0x20 Mem I/O 13 ohms
* 0x10 Mem I/O 20 ohms
* 0x00 Mem I/O 40 ohms
* 0x0c PCIClk 8 ohms
* 0x08 PCIClk 13 ohms
* 0x04 PCIClk 20 ohms
* 0x00 PCIClk 40 ohms
* 0x03 MemClk 8 ohms
* 0x02 MemClk 13.3 ohms
* 0x01 MemClk 20 ohms
* 0x00 MemClk 40 ohms
*/
pci_ppc_write_config8(0, 0, 0x73, 0xd1);
/*
* CDCR
* 0x8000 PCI_SYNC_OUT disabled
* 0x7c00 PCI_CLK disabled
* 0x0300 CPU_CLK 8 ohms
* 0x0200 CPU_CLK 13 ohms
* 0x0100 CPU_CLK 20 ohms
* 0x0000 CPU_CLK 40 ohms
* 0x0080 SDRAM_SYNC_OUT disabled
* 0x0078 SDRAM_CLK disabled
* 0x0004 CPU_CLK0 disabled
* 0x0002 CPU_CLK1 disabled
* 0x0001 CPU_CLK2 disabled
*/
pci_ppc_write_config16(0, 0, 0x74, 0xfd00);
/*
* MICR
* 0x80 MCP 1=open-drain, 0=output
* 0x40 SRESET 1=open-drain, 0=output
* 0x20 QACK 1=high-Z, 0=output
*/
pci_ppc_write_config8(0, 0, 0x76, 0x40);
/*
* MBEN
* 0x02 Enable bank 1
* 0x01 Enable bank 0
*/
pci_ppc_write_config8(0, 0, 0xa0, 0x03);
/*
* PGMAX
* 0x32 33MHz value w/ROMFAL=8
*/
pci_ppc_write_config8(0, 0, 0xa3, 0x32);
/*
* Wait 200us
*/
udelay(200);
/*
* Now set memgo bit in MCCR1
*/
reg32 = pci_ppc_read_config32(0, 0, 0xf0);
reg32 |= 0x00080000; /* MEMGO=1 */
pci_ppc_write_config32(0, 0, 0xf0, reg32);
/*
* Wait again
*/
udelay(10000);
}
/*
* Configure real memory settings.
*/
unsigned long
mpc107_config_memory(int no_banks, sdram_bank_info *bank, int for_real)
{
int i, j;
char ignore[8];
/* Convert bus clock to cycle time in 100ns units */
unsigned cycle_time = 10 * (2500000000U / get_timer_freq());
/* Approximate */
unsigned access_time = cycle_time - 300;
unsigned cas_latency = 0;
unsigned rdlat;
unsigned refint;
unsigned refrec;
unsigned acttorw, acttopre;
unsigned pretoact, bstopre;
enum sdram_error_detect error_detect;
uint32_t mccr1;
uint32_t mccr2;
uint32_t mccr3;
uint32_t mccr4;
uint8_t bank_enable;
uint32_t memstart1, memstart2;
uint32_t extmemstart1, extmemstart2;
uint32_t memend1, memend2;
uint32_t extmemend1, extmemend2;
uint32_t mem_size;
printk_debug("Configuring DIMMS...\n");
/* Set up the ignore mask */
for(i = 0; i < no_banks; i++)
ignore[i] = (bank[i].size == 0);
/* Pick best CAS latency possible */
for (i = 0; i < no_banks; i++)
{
if (! ignore[i])
{
for (j = 0; j < 3; j++)
{
if (cycle_time >= bank[i].cycle_time[j] &&
access_time >= bank[i].access_time[j])
{
cas_latency = bank[i].cas_latency[j];
break;
}
}
}
}
if (!cas_latency)
return 0;
/* For various parameters there is a risk of clashing between banks */
error_detect = (for_real > 1) ? ERRORS_ECC : ERRORS_NONE;
for (i = 0; i < no_banks; i++)
{
if (! ignore[i])
{
{
for (j = 0; j < 3; j++)
if (bank[i].cas_latency[j] == cas_latency)
break;
if (j == 3)
{
ignore[i] = 1;
if (! for_real)
printk_info("Disabling memory bank %d (cas latency)\n", i);
}
if (bank[i].error_detect < error_detect)
error_detect = bank[i].error_detect;
}
}
}
/* Read in configuration of port X */
mccr1 = pci_ppc_read_config32(0, 0, 0xf0);
mccr2 = pci_ppc_read_config32(0, 0, 0xf4);
mccr4 = pci_ppc_read_config32(0, 0, 0xfc);
mccr1 &= 0xfff00000;
mccr2 &= 0xffe00000;
mccr3 = 0;
mccr4 &= 0x00230000;
pretoact = 0;
acttorw = 0;
acttopre = 0;
for (i = 0; i < no_banks; i++)
if (! ignore[i])
{
int rowcode = -1;
if (for_real)
{
bank[i].actual_detect = error_detect;
bank[i].actual_cas = cas_latency;
}
switch (bank[i].row_bits) {
case 13:
if (bank[i].internal_banks == 4)
rowcode = 2;
else if (bank[i].internal_banks == 2)
rowcode = 1;
break;
case 12:
if (bank[i].internal_banks == 4)
rowcode = 0;
else if (bank[i].internal_banks == 2)
rowcode = 1;
break;
case 11:
if (bank[i].internal_banks == 4)
rowcode = 0;
else if (bank[i].internal_banks == 2)
rowcode = 3;
break;
}
if (rowcode == -1) {
ignore[i] = 1;
if (! for_real)
printk_info("Memory bank %d disabled: row bits %d and banks %d not supported\n", i, bank[i].row_bits, bank[i].internal_banks);
} else
mccr1 |= rowcode << (2 * i);
/* Update worst case settings */
if (! ignore[i]) {
if (bank[i].min_row_precharge > pretoact)
pretoact = bank[i].min_row_precharge;
if (bank[i].min_ras_to_cas > acttorw)
acttorw = bank[i].min_ras_to_cas;
if (bank[i].min_ras > acttopre)
acttopre = bank[i].min_ras;
}
}
/* Now convert to clock cycles, rounding up */
pretoact = (100 * pretoact + cycle_time - 1) / cycle_time;
acttopre = (100 * acttopre + cycle_time - 1) / cycle_time;
acttorw = (100 * acttorw + cycle_time - 1) / cycle_time;
refrec = acttopre;
bstopre = 0x240; /* Set conservative values, because we can't derive */
refint = 1000;
if (error_detect == ERRORS_ECC)
{
rdlat = cas_latency + 2;
mccr4 |= 0x00400000;
mccr2 |= 0x000c0001;
}
else
{
rdlat = cas_latency + 1;
mccr4 |= 0x00100000;
}
if (pretoact > 16 || acttopre > 16 || acttorw > 16)
if (! for_real)
printk_info("Timings out of range\n");
mccr4 |= ((pretoact & 0x0f) << 28) | ((acttopre & 0xf) << 24) |
((acttorw & 0x0f) << 4) |
((bstopre & 0x003) << 18) | ((bstopre & 0x3c0) >> 6) |
(cas_latency << 12) | 0x00000200 /* burst length */ ;
mccr3 |= ((bstopre & 0x03c) << 26) |
((refrec & 0x0f) << 24) | (rdlat << 20);
mccr2 |= refint << 2;
mccr1 |= 0x00080000; /* memgo */
mem_size = 0;
memstart1 = memstart2 = 0;
extmemstart1 = extmemstart2 = 0;
memend1 = memend2 = 0;
extmemend1 = extmemend2 = 0;
bank_enable = 0;
for (i = 0; i < no_banks; i++) {
if (! ignore[i]) {
uint32_t end = mem_size + bank[i].size - 1;
bank_enable |= 1 << i;
if (i < 4) {
memstart1 |= ((mem_size >> 20) & 0xff) << (8 * i);
extmemstart1 |= ((mem_size >> 28) & 0x03) << (8 * i);
memend1 |= ((end >> 20) & 0xff) << (8 * i);
extmemend1 |= ((end >> 28) & 0x03) << (8 * i);
} else {
int k = i - 4;
memstart2 |= ((mem_size >> 20) & 0xff) << (8 * k);
extmemstart2 |= ((mem_size >> 28) & 0x03) << (8 * k);
memend2 |= ((end >> 20) & 0xff) << (8 * k);
extmemend2 |= ((end >> 28) & 0x03) << (8 * k);
}
mem_size += bank[i].size;
}
}
if (for_real)
{
/*
* Mask MEMGO bit before setting MCCR1
*/
printk_debug("Setting memory configuration registers...\n");
mccr1 &= ~0x80000;
printk_debug(" MCCR1 = 0x%08x\n", mccr1);
pci_ppc_write_config32(0, 0, 0xf0, mccr1);
printk_debug(" MBEN = 0x%02x\n", bank_enable);
pci_ppc_write_config8(0, 0, 0xa0, bank_enable);
printk_debug(" MSAR1 = 0x%08x\n", memstart1);
pci_ppc_write_config32(0, 0, 0x80, memstart1);
printk_debug(" MSAR2 = 0x%08x\n", memstart2);
pci_ppc_write_config32(0, 0, 0x84, memstart2);
printk_debug(" MSAR3 = 0x%08x\n", extmemstart1);
pci_ppc_write_config32(0, 0, 0x88, extmemstart1);
printk_debug(" MSAR4 = 0x%08x\n", extmemstart2);
pci_ppc_write_config32(0, 0, 0x8c, extmemstart2);
printk_debug(" MEAR1 = 0x%08x\n", memend1);
pci_ppc_write_config32(0, 0, 0x90, memend1);
printk_debug(" MEAR2 = 0x%08x\n", memend2);
pci_ppc_write_config32(0, 0, 0x94, memend2);
printk_debug(" MEAR3 = 0x%08x\n", extmemend1);
pci_ppc_write_config32(0, 0, 0x98, extmemend1);
printk_debug(" MEAR4 = 0x%08x\n", extmemend2);
pci_ppc_write_config32(0, 0, 0x9c, extmemend2);
printk_debug(" MCCR2 = 0x%08x\n", mccr2);
pci_ppc_write_config32(0, 0, 0xf4, mccr2);
printk_debug(" MCCR3 = 0x%08x\n", mccr3);
pci_ppc_write_config32(0, 0, 0xf8, mccr3);
printk_debug(" MCCR4 = 0x%08x\n", mccr4);
pci_ppc_write_config32(0, 0, 0xfc, mccr4);
udelay(200);
/*
* Set MEMGO bit
*/
mccr1 |= 0x80000;
printk_debug(" MCCR1 = 0x%08x\n", mccr1);
pci_ppc_write_config32(0, 0, 0xf0, mccr1);
udelay(10000);
printk_debug("done.\n");
}
return mem_size;
}
static int
i2c_wait(unsigned timeout, int writing)
{
uint32_t x;
while (((x = readl(MPC107_BASE + MPC107_I2CSR)) & (MPC107_I2C_CSR_MCF | MPC107_I2C_CSR_MIF))
!= (MPC107_I2C_CSR_MCF | MPC107_I2C_CSR_MIF)) {
if (ticks_since_boot() > timeout)
return -1;
}
if (x & MPC107_I2C_CSR_MAL) {
return -1;
}
if (writing && (x & MPC107_I2C_CSR_RXAK)) {
printk_debug("No RXAK\n");
/* generate stop */
writel(MPC107_I2C_CCR_MEN, MPC107_BASE + MPC107_I2CCR);
return -1;
}
writel(0, MPC107_BASE + MPC107_I2CSR);
return 0;
}
static void
mpc107_i2c_start(struct i2c_bus *bus)
{
/* Set clock */
writel(0x1031, MPC107_BASE + MPC107_I2CFDR);
/* Clear arbitration */
writel(0, MPC107_BASE + MPC107_I2CSR);
}
static void
mpc107_i2c_stop(struct i2c_bus *bus)
{
/* After last DIMM shut down I2C */
writel(0x0, MPC107_BASE + MPC107_I2CCR);
}
static int
mpc107_i2c_byte_write(struct i2c_bus *bus, int target, int address, uint8_t data)
{
unsigned timeout = ticks_since_boot() + 3 * get_hz();
/* Must wait here for clocks to start */
udelay(25000);
/* Start with MEN */
writel(MPC107_I2C_CCR_MEN, MPC107_BASE + MPC107_I2CCR);
/* Start as master */
writel(MPC107_I2C_CCR_MEN | MPC107_I2C_CCR_MSTA | MPC107_I2C_CCR_MTX, MPC107_BASE + MPC107_I2CCR);
/* Write target byte */
writel(target, MPC107_BASE + MPC107_I2CDR);
if (i2c_wait(timeout, 1) < 0)
return -1;
/* Write data address byte */
writel(address, MPC107_BASE + MPC107_I2CDR);
if (i2c_wait(timeout, 1) < 0)
return -1;
/* Write data byte */
writel(data, MPC107_BASE + MPC107_I2CDR);
if (i2c_wait(timeout, 1) < 0)
return -1;
/* generate stop */
writel(MPC107_I2C_CCR_MEN, MPC107_BASE + MPC107_I2CCR);
return 0;
}
static int
mpc107_i2c_master_write(struct i2c_bus *bus, int target, int address, const uint8_t *data, int length)
{
unsigned count;
for(count = 0; count < length; count++)
{
if (mpc107_i2c_byte_write(bus, target, address, data[count]) < 0)
return -1;
}
return count;
}
#define DIMM_LENGTH 0xfff
static int
mpc107_i2c_master_read(struct i2c_bus *bus, int target, int address,
uint8_t *data, int length)
{
unsigned timeout = ticks_since_boot() + 3 * get_hz();
unsigned count;
/* Must wait here for clocks to start */
udelay(25000);
/* Start with MEN */
writel(MPC107_I2C_CCR_MEN, MPC107_BASE + MPC107_I2CCR);
/* Start as master */
writel(MPC107_I2C_CCR_MEN | MPC107_I2C_CCR_MSTA | MPC107_I2C_CCR_MTX, MPC107_BASE + MPC107_I2CCR);
/* Write target byte */
writel(target, MPC107_BASE + MPC107_I2CDR);
if (i2c_wait(timeout, 1) < 0)
return -1;
/* Write data address byte */
writel(address, MPC107_BASE + MPC107_I2CDR);
if (i2c_wait(timeout, 1) < 0)
return -1;
/* Switch to read - restart */
writel(MPC107_I2C_CCR_MEN | MPC107_I2C_CCR_MSTA | MPC107_I2C_CCR_MTX | MPC107_I2C_CCR_RSTA, MPC107_BASE + MPC107_I2CCR);
/* Write target address byte - this time with the read flag set */
writel(target | 1, MPC107_BASE + MPC107_I2CDR);
if (i2c_wait(timeout, 0) < 0)
return -1;
if (length == 1)
writel(MPC107_I2C_CCR_MEN | MPC107_I2C_CCR_MSTA | MPC107_I2C_CCR_TXAK, MPC107_BASE + MPC107_I2CCR);
else
writel(MPC107_I2C_CCR_MEN | MPC107_I2C_CCR_MSTA, MPC107_BASE + MPC107_I2CCR);
/* Dummy read */
readl(MPC107_BASE + MPC107_I2CDR);
count = 0;
while (count < length) {
if (i2c_wait(timeout, 0) < 0)
return -1;
/* Generate txack on next to last byte */
if (count == length - 2)
writel(MPC107_I2C_CCR_MEN | MPC107_I2C_CCR_MSTA | MPC107_I2C_CCR_TXAK, MPC107_BASE + MPC107_I2CCR);
/* Generate stop on last byte */
if (count == length - 1)
writel(MPC107_I2C_CCR_MEN | MPC107_I2C_CCR_TXAK, MPC107_BASE + MPC107_I2CCR);
data[count] = readl(MPC107_BASE + MPC107_I2CDR);
if (count == 0 && length == DIMM_LENGTH) {
if (data[0] == 0xff) {
printk_debug("I2C device not present\n");
length = 3;
} else {
length = data[0];
if (length < 3)
length = 3;
}
}
count++;
}
/* Finish with disable master */
writel(MPC107_I2C_CCR_MEN, MPC107_BASE + MPC107_I2CCR);
return length;
}
i2c_fn mpc107_i2c_fn = {
mpc107_i2c_start, mpc107_i2c_stop,
mpc107_i2c_master_write, mpc107_i2c_master_read
};
/*
* Find dimm information.
*/
void
mpc107_probe_dimms(int no_dimms, sdram_dimm_info *dimms, sdram_bank_info *bank)
{
unsigned char data[256];
unsigned dimm;
printk_debug("Probing DIMMS...\n");
mpc107_i2c_start(NULL);
for(dimm = 0; dimm < no_dimms; dimm++)
{
dimms[dimm].number = dimm;
dimms[dimm].bank1 = bank + dimm*NUM_BANKS;
dimms[dimm].bank2 = bank + dimm*NUM_BANKS + 1;
bank[dimm*NUM_BANKS].size = 0;
bank[dimm*NUM_BANKS+1].size = 0;
bank[dimm*NUM_BANKS].number = 0;
bank[dimm*NUM_BANKS+1].number = 1;
}
for (dimm = 0; dimm < no_dimms; dimm ++) {
unsigned limit = mpc107_i2c_master_read(NULL, 0xa0 + 2*dimm, 0,
data, DIMM_LENGTH);
if (limit > 3) {
sdram_dimm_to_bank_info(data, dimms + dimm);
memcpy(dimms[dimm].part_number, data + 73, 18);
dimms[dimm].part_number[18] = 0;
printk_debug("Part Number: %s\n", dimms[dimm].part_number);
}
}
mpc107_i2c_stop(NULL);
}

View File

@ -1,121 +0,0 @@
/*
* (C) Copyright 2001
* Humboldt Solutions Ltd, adrian@humboldt.co.uk.
*
* 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., 51 Franklin St, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
#ifndef _MPC107_H
#define _MPC107_H
#ifdef ASM
#define BMC_BASE 0x8000 /* Bridge memory controller base address */
#else
#define MPC107_BASE 0xfc000000
#define MPC107_EUMBBAR 0x78
#define MPC107_PIC1 0xa8
#define MPC107_PIC1_CF_MP 0x000003
#define MPC107_PIC1_SPEC_PCI 0x000004
#define MPC107_PIC1_CF_APARK 0x000008
#define MPC107_PIC1_CF_LOOP_SNOOP 0x000010
#define MPC107_PIC1_LE_MODE 0x000020
#define MPC107_PIC1_ST_GATH_EN 0x000040
#define MPC107_PIC1_NO_BUS_WIDTH_CHECK 0x000080
#define MPC107_PIC1_TEA_EN 0x000400
#define MPC107_PIC1_MCP_EN 0x000800
#define MPC107_PIC1_FLASH_WR_EN 0x001000
#define MPC107_PIC1_CF_LBA_EN 0x002000
#define MPC107_PIC1_CF_MP_ID 0x00c000
#define MPC107_PIC1_ADDRESS_MAP 0x010000
#define MPC107_PIC1_PROC_TYPE 0x050000
#define MPC107_PIC1_RCS0 0x100000
#define MPC107_PIC1_CF_BREAD_WS 0xc00000
#define MPC107_I2CADR 0x3000
#define MPC107_I2CFDR 0x3004
#define MPC107_I2CCR 0x3008
#define MPC107_I2CSR 0x300c
#define MPC107_I2CDR 0x3010
#define MPC107_I2C_CCR_MEN 0x80
#define MPC107_I2C_CCR_MIEN 0x40
#define MPC107_I2C_CCR_MSTA 0x20
#define MPC107_I2C_CCR_MTX 0x10
#define MPC107_I2C_CCR_TXAK 0x08
#define MPC107_I2C_CCR_RSTA 0x04
#define MPC107_I2C_CSR_MCF 0x80
#define MPC107_I2C_CSR_MAAS 0x40
#define MPC107_I2C_CSR_MBB 0x20
#define MPC107_I2C_CSR_MAL 0x10
#define MPC107_I2C_CSR_SRW 0x04
#define MPC107_I2C_CSR_MIF 0x02
#define MPC107_I2C_CSR_RXAK 0x01
enum sdram_error_detect {
ERRORS_NONE, ERRORS_PARITY, ERRORS_ECC
};
typedef struct sdram_dimm_info
{
unsigned size;
unsigned number;
char part_number[20];
struct sdram_bank_info *bank1;
struct sdram_bank_info *bank2;
} sdram_dimm_info;
typedef struct sdram_bank_info
{
unsigned number;
unsigned char row_bits;
unsigned char internal_banks;
unsigned char col_bits;
unsigned char data_width;
/* Cycle and access times are stored with lowest CAS latency first. Units
are 0.01ns */
unsigned short cycle_time[3];
unsigned short access_time[3];
/* Best CAS latencies */
unsigned char cas_latency[3];
unsigned char cs_latency;
unsigned char we_latency;
unsigned char min_back_to_back;
unsigned char min_row_precharge;
unsigned char min_active_to_active;
unsigned char min_ras_to_cas;
unsigned char min_ras;
unsigned char burst_mask;
enum sdram_error_detect error_detect;
/* Bank size */
unsigned size;
unsigned long start;
unsigned long end;
enum sdram_error_detect actual_detect;
unsigned char actual_cas;
} sdram_bank_info;
extern void sdram_dimm_to_bank_info(const char *, sdram_dimm_info *);
extern void print_sdram_dimm_info(const sdram_dimm_info *);
extern void print_sdram_bank_info(const sdram_bank_info *);
extern unsigned long mpc107_config_memory(int, sdram_bank_info *, int);
extern void mpc107_probe_dimms(int, sdram_dimm_info *, sdram_bank_info *);
#endif
#endif

View File

@ -1,144 +0,0 @@
#include <console/console.h>
#include <arch/io.h>
#include <stdint.h>
#include <device/device.h>
#include <device/pci.h>
#include <stdlib.h>
#include <string.h>
#include <bitops.h>
#include <cpu/cpu.h>
#include "chip.h"
/*
* pci_domain_read_resources needs to create two resource regions,
* one for memory and one for I/O. These are required for the
* resource allocation code to function correctly. The regions should
* be large enough to hold all expected resources for all PCI
* devices.
*/
static void mpc107_domain_read_resources(device_t dev)
{
struct resource *resource;
/* Initialize the system wide io space constraints */
resource = new_resource(dev, IOINDEX_SUBTRACTIVE(0, 0));
resource->base = 0;
resource->limit = 0xffffUL;
resource->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED;
/* Initialize the system wide memory resources constraints */
resource = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0));
resource->base = 0x80000000ULL;
resource->limit = 0xfeffffffULL; /* We can put pci resources in the system controll area */
resource->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED;
}
/*
* pci_domain_set_resources creates memory resources describing the
* fixed memory on the system. This is not actually used anywhere
* except when the coreboot table is generated.
*/
static void pci_domain_set_resources(device_t dev)
{
device_t mc_dev;
/* Get the memory controller device */
mc_dev = dev->link[0].children;
if (mc_dev) {
/* Figure out which areas occupied by ram. */
int i, idx;
uint32_t memstart1, memstart2, extmemstart1, extmemstart2;
uint32_t memend1, memend2, extmemend1, extmemend2;
uint8_t bank_enable;
unsigned long start, end, size;
/* Find the memory setup */
memstart1 = pci_read_config32(mc_dev, 0x80);
memstart2 = pci_read_config32(mc_dev, 0x84);
extmemstart1 = pci_read_config32(mc_dev, 0x88);
extmemstart2 = pci_read_config32(mc_dev, 0x8c);
memend1 = pci_read_config32(mc_dev, 0x90);
memend2 = pci_read_config32(mc_dev, 0x94);
extmemend1 = pci_read_config32(mc_dev, 0x98);
extmemend2 = pci_read_config32(mc_dev, 0x9c);
bank_enable = pci_read_config32(mc_dev, 0xa0);
/* Report the memory regions */
idx = 10; /* Why does idx start at 10? */
for(i = 0; i < 8; i++) {
struct resource *res;
/* Ignore banks that are not enabled */
if (!(bank_enable & (1 << i))) {
continue;
}
/* Find the start and end of each bank */
if (i < 4) {
int shift = (8*i);
start = ((memstart1 >> shift) & 0xff) << 20;
start |= ((extmemstart1 >> shift) & 0xff) << 28;
end = ((memend1 >> shift) & 0xff) << 20;
end |= ((extmemend1 >> shift) & 0xff) << 28;
} else {
int shift = (8*(i - 4));
start = ((memstart2 >> shift) & 0xff) << 20;
start |= ((extmemstart2 >> shift) & 0xff) << 28;
end = ((memend2 >> shift) & 0xff) << 20;
end |= ((extmemend2 >> shift) & 0xff) << 28;
}
/* Comput the size of the bank */
size = (end + (1 << 20)) - start;
/* And now report the memory region */
res = new_resource(dev, idx++);
res->base = start;
res->size = size;
res->flags = IORESOURCE_MEM | IORESOURCE_CACHEABLE | \
IORESOURCE_FIXED | IORESOURCE_STORED | IORESOURCE_ASSIGNED;
}
}
/* And assign the resources */
assign_resources(&dev->link[0]);
}
static struct device_operations pci_domain_ops = {
.read_resources = mpc107_domain_read_resources,
.set_resources = pci_domain_set_resources,
.enable_resources = enable_childrens_resources,
.init = 0,
.scan_bus = pci_domain_scan_bus,
.ops_pci_bus = &pci_ppc_conf1,
};
static void cpu_bus_init(device_t dev)
{
initialize_cpus(&dev->link[0]);
}
static void cpu_bus_noop(device_t dev)
{
}
static struct device_operations cpu_bus_ops = {
.read_resources = cpu_bus_noop,
.set_resources = cpu_bus_noop,
.enable_resources = cpu_bus_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_PCI_DOMAIN) {
dev->ops = &pci_domain_ops;
}
else if (dev->path.type == DEVICE_PATH_CPU_BUS) {
dev->ops = &cpu_bus_ops;
}
}
struct chip_operations northbridge_motorola_mpc107_ops = {
CHIP_NAME("Motorola MPC107 Northbridge")
.enable_dev = enable_dev,
};

View File

@ -1,32 +0,0 @@
#include <stdint.h>
#include <device/pci.h>
#include "mpc107.h"
void
wait_for_other_cpus(void)
{
}
unsigned long
this_processors_id(void)
{
uint32_t pic1;
struct device *dev;
if ((dev = dev_find_slot(0, 0)) == 0)
return 0;
pic1 = pci_read_config32(dev, MPC107_PIC1);
return (pic1 & MPC107_PIC1_CF_MP_ID) >> 14;
}
unsigned long
processor_index(unsigned long id)
{
return id;
}
void
startup_other_cpus(unsigned long *map)
{
}