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:
parent
e696942cfc
commit
88214a48cc
|
@ -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
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
subdirs-y += amd
|
||||
#subdirs-y += ibm
|
||||
subdirs-y += intel
|
||||
#subdirs-y += motorola
|
||||
subdirs-y += via
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
#source src/northbridge/ibm/cpc710/Kconfig
|
||||
#source src/northbridge/ibm/cpc925/Kconfig
|
|
@ -1,2 +0,0 @@
|
|||
subdirs-y += cpc710
|
||||
subdirs-y += cpc925
|
|
@ -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
|
|
@ -1,6 +0,0 @@
|
|||
|
||||
struct northbridge_ibm_cpc710_config {
|
||||
/* Nothing yet */
|
||||
};
|
||||
|
||||
extern struct chip_operations northbridge_ibm_cpc710_ops;
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -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,
|
||||
};
|
|
@ -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
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -1,6 +0,0 @@
|
|||
|
||||
struct northbridge_ibm_cpc925_config {
|
||||
/* Nothing yet */
|
||||
};
|
||||
|
||||
extern struct chip_operations northbridge_ibm_cpc925_ops;
|
|
@ -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()
|
||||
{
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
#ifndef _CPC925_H_
|
||||
#define _CPC925_H_
|
||||
|
||||
#endif
|
|
@ -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,
|
||||
};
|
|
@ -1,9 +0,0 @@
|
|||
#include <stdint.h>
|
||||
#include <arch/io.h>
|
||||
#include "cpc925.h"
|
||||
#include "cpc925_pci.h"
|
||||
|
||||
void
|
||||
cpc925_pci_init(void)
|
||||
{
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
#ifndef _CPC925_PCI_H_
|
||||
#define _CPC925_PCI_H_
|
||||
|
||||
#endif
|
|
@ -1 +0,0 @@
|
|||
#source src/northbridge/motorola/mpc107/Kconfig
|
|
@ -1 +0,0 @@
|
|||
subdirs-y += mpc107
|
|
@ -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
|
|
@ -1,6 +0,0 @@
|
|||
|
||||
struct northbridge_motorola_mpc107_config {
|
||||
/* Nothing yet */
|
||||
};
|
||||
|
||||
extern struct chip_operations northbridge_motorola_mpc107_ops;
|
|
@ -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, ®Val);
|
||||
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);
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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
|
|
@ -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");
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -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,
|
||||
};
|
|
@ -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)
|
||||
{
|
||||
}
|
Loading…
Reference in New Issue