add idl4k kernel firmware version 1.13.0.105

This commit is contained in:
Jaroslav Kysela
2015-03-26 17:22:37 +01:00
parent 5194d2792e
commit e9070cdc77
31064 changed files with 12769984 additions and 0 deletions

View File

@@ -0,0 +1,92 @@
config EMBEDDED6xx
bool "Embedded 6xx/7xx/7xxx-based boards"
depends on 6xx && BROKEN_ON_SMP
config LINKSTATION
bool "Linkstation / Kurobox(HG) from Buffalo"
depends on EMBEDDED6xx
select MPIC
select FSL_SOC
select PPC_UDBG_16550 if SERIAL_8250
select DEFAULT_UIMAGE
select MPC10X_OPENPIC
select MPC10X_BRIDGE
help
Select LINKSTATION if configuring for one of PPC- (MPC8241)
based NAS systems from Buffalo Technology. So far only
KuroboxHG has been tested. In the future classical Kurobox,
Linkstation-I HD-HLAN and HD-HGLAN versions, and PPC-based
Terastation systems should be supported too.
config STORCENTER
bool "IOMEGA StorCenter"
depends on EMBEDDED6xx
select MPIC
select FSL_SOC
select PPC_UDBG_16550 if SERIAL_8250
select MPC10X_OPENPIC
select MPC10X_BRIDGE
help
Select STORCENTER if configuring for the iomega StorCenter
with an 8241 CPU in it.
config MPC7448HPC2
bool "Freescale MPC7448HPC2(Taiga)"
depends on EMBEDDED6xx
select TSI108_BRIDGE
select DEFAULT_UIMAGE
select PPC_UDBG_16550
select TSI108_BRIDGE
help
Select MPC7448HPC2 if configuring for Freescale MPC7448HPC2 (Taiga)
platform
config PPC_HOLLY
bool "PPC750GX/CL with TSI10x bridge (Hickory/Holly)"
depends on EMBEDDED6xx
select TSI108_BRIDGE
select PPC_UDBG_16550
select TSI108_BRIDGE
help
Select PPC_HOLLY if configuring for an IBM 750GX/CL Eval
Board with TSI108/9 bridge (Hickory/Holly)
config PPC_PRPMC2800
bool "Motorola-PrPMC2800"
depends on EMBEDDED6xx
select MV64X60
select NOT_COHERENT_CACHE
help
This option enables support for the Motorola PrPMC2800 board
config PPC_C2K
bool "SBS/GEFanuc C2K board"
depends on EMBEDDED6xx
select MV64X60
select NOT_COHERENT_CACHE
select MTD_CFI_I4
help
This option enables support for the GE Fanuc C2K board (formerly
an SBS board).
config TSI108_BRIDGE
bool
select PCI
select MPIC
select MPIC_WEIRD
config MPC10X_BRIDGE
bool
select PPC_INDIRECT_PCI
config MV64X60
bool
select PPC_INDIRECT_PCI
select CHECK_CACHE_COHERENCY
config MPC10X_OPENPIC
bool
config MPC10X_STORE_GATHERING
bool "Enable MPC10x store gathering"
depends on MPC10X_BRIDGE

View File

@@ -0,0 +1,9 @@
#
# Makefile for the 6xx/7xx/7xxxx linux kernel.
#
obj-$(CONFIG_MPC7448HPC2) += mpc7448_hpc2.o
obj-$(CONFIG_LINKSTATION) += linkstation.o ls_uart.o
obj-$(CONFIG_STORCENTER) += storcenter.o
obj-$(CONFIG_PPC_HOLLY) += holly.o
obj-$(CONFIG_PPC_PRPMC2800) += prpmc2800.o
obj-$(CONFIG_PPC_C2K) += c2k.o

View File

@@ -0,0 +1,149 @@
/*
* Board setup routines for the GEFanuc C2K board
*
* Author: Remi Machet <rmachet@slac.stanford.edu>
*
* Originated from prpmc2800.c
*
* 2008 (c) Stanford University
* 2007 (c) MontaVista, Software, Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*/
#include <linux/stddef.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/seq_file.h>
#include <linux/time.h>
#include <linux/of.h>
#include <asm/machdep.h>
#include <asm/prom.h>
#include <asm/system.h>
#include <asm/time.h>
#include <mm/mmu_decl.h>
#include <sysdev/mv64x60.h>
#define MV64x60_MPP_CNTL_0 0x0000
#define MV64x60_MPP_CNTL_2 0x0008
#define MV64x60_GPP_IO_CNTL 0x0000
#define MV64x60_GPP_LEVEL_CNTL 0x0010
#define MV64x60_GPP_VALUE_SET 0x0018
static void __iomem *mv64x60_mpp_reg_base;
static void __iomem *mv64x60_gpp_reg_base;
static void __init c2k_setup_arch(void)
{
struct device_node *np;
phys_addr_t paddr;
const unsigned int *reg;
/*
* ioremap mpp and gpp registers in case they are later
* needed by c2k_reset_board().
*/
np = of_find_compatible_node(NULL, NULL, "marvell,mv64360-mpp");
reg = of_get_property(np, "reg", NULL);
paddr = of_translate_address(np, reg);
of_node_put(np);
mv64x60_mpp_reg_base = ioremap(paddr, reg[1]);
np = of_find_compatible_node(NULL, NULL, "marvell,mv64360-gpp");
reg = of_get_property(np, "reg", NULL);
paddr = of_translate_address(np, reg);
of_node_put(np);
mv64x60_gpp_reg_base = ioremap(paddr, reg[1]);
#ifdef CONFIG_PCI
mv64x60_pci_init();
#endif
}
static void c2k_reset_board(void)
{
u32 temp;
local_irq_disable();
temp = in_le32(mv64x60_mpp_reg_base + MV64x60_MPP_CNTL_0);
temp &= 0xFFFF0FFF;
out_le32(mv64x60_mpp_reg_base + MV64x60_MPP_CNTL_0, temp);
temp = in_le32(mv64x60_gpp_reg_base + MV64x60_GPP_LEVEL_CNTL);
temp |= 0x00000004;
out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_LEVEL_CNTL, temp);
temp = in_le32(mv64x60_gpp_reg_base + MV64x60_GPP_IO_CNTL);
temp |= 0x00000004;
out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_IO_CNTL, temp);
temp = in_le32(mv64x60_mpp_reg_base + MV64x60_MPP_CNTL_2);
temp &= 0xFFFF0FFF;
out_le32(mv64x60_mpp_reg_base + MV64x60_MPP_CNTL_2, temp);
temp = in_le32(mv64x60_gpp_reg_base + MV64x60_GPP_LEVEL_CNTL);
temp |= 0x00080000;
out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_LEVEL_CNTL, temp);
temp = in_le32(mv64x60_gpp_reg_base + MV64x60_GPP_IO_CNTL);
temp |= 0x00080000;
out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_IO_CNTL, temp);
out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_VALUE_SET, 0x00080004);
}
static void c2k_restart(char *cmd)
{
c2k_reset_board();
msleep(100);
panic("restart failed\n");
}
#ifdef CONFIG_NOT_COHERENT_CACHE
#define COHERENCY_SETTING "off"
#else
#define COHERENCY_SETTING "on"
#endif
void c2k_show_cpuinfo(struct seq_file *m)
{
seq_printf(m, "Vendor\t\t: GEFanuc\n");
seq_printf(m, "coherency\t: %s\n", COHERENCY_SETTING);
}
/*
* Called very early, device-tree isn't unflattened
*/
static int __init c2k_probe(void)
{
unsigned long root = of_get_flat_dt_root();
if (!of_flat_dt_is_compatible(root, "GEFanuc,C2K"))
return 0;
printk(KERN_INFO "Detected a GEFanuc C2K board\n");
_set_L2CR(0);
_set_L2CR(L2CR_L2E | L2CR_L2PE | L2CR_L2I);
return 1;
}
define_machine(c2k) {
.name = "C2K",
.probe = c2k_probe,
.setup_arch = c2k_setup_arch,
.init_early = mv64x60_init_early,
.show_cpuinfo = c2k_show_cpuinfo,
.init_IRQ = mv64x60_init_irq,
.get_irq = mv64x60_get_irq,
.restart = c2k_restart,
.calibrate_decr = generic_calibrate_decr,
};

View File

@@ -0,0 +1,304 @@
/*
* Board setup routines for the IBM 750GX/CL platform w/ TSI10x bridge
*
* Copyright 2007 IBM Corporation
*
* Stephen Winiecki <stevewin@us.ibm.com>
* Josh Boyer <jwboyer@linux.vnet.ibm.com>
*
* Based on code from mpc7448_hpc2.c
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*/
#include <linux/stddef.h>
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/kdev_t.h>
#include <linux/console.h>
#include <linux/delay.h>
#include <linux/irq.h>
#include <linux/seq_file.h>
#include <linux/root_dev.h>
#include <linux/serial.h>
#include <linux/tty.h>
#include <linux/serial_core.h>
#include <linux/of_platform.h>
#include <asm/system.h>
#include <asm/time.h>
#include <asm/machdep.h>
#include <asm/prom.h>
#include <asm/udbg.h>
#include <asm/tsi108.h>
#include <asm/pci-bridge.h>
#include <asm/reg.h>
#include <mm/mmu_decl.h>
#include <asm/tsi108_irq.h>
#include <asm/tsi108_pci.h>
#include <asm/mpic.h>
#undef DEBUG
#define HOLLY_PCI_CFG_PHYS 0x7c000000
int holly_exclude_device(struct pci_controller *hose, u_char bus, u_char devfn)
{
if (bus == 0 && PCI_SLOT(devfn) == 0)
return PCIBIOS_DEVICE_NOT_FOUND;
else
return PCIBIOS_SUCCESSFUL;
}
static void holly_remap_bridge(void)
{
u32 lut_val, lut_addr;
int i;
printk(KERN_INFO "Remapping PCI bridge\n");
/* Re-init the PCI bridge and LUT registers to have mappings that don't
* rely on PIBS
*/
lut_addr = 0x900;
for (i = 0; i < 31; i++) {
tsi108_write_reg(TSI108_PB_OFFSET + lut_addr, 0x00000201);
lut_addr += 4;
tsi108_write_reg(TSI108_PB_OFFSET + lut_addr, 0x0);
lut_addr += 4;
}
/* Reserve the last LUT entry for PCI I/O space */
tsi108_write_reg(TSI108_PB_OFFSET + lut_addr, 0x00000241);
lut_addr += 4;
tsi108_write_reg(TSI108_PB_OFFSET + lut_addr, 0x0);
/* Map PCI I/O space */
tsi108_write_reg(TSI108_PCI_PFAB_IO_UPPER, 0x0);
tsi108_write_reg(TSI108_PCI_PFAB_IO, 0x1);
/* Map PCI CFG space */
tsi108_write_reg(TSI108_PCI_PFAB_BAR0_UPPER, 0x0);
tsi108_write_reg(TSI108_PCI_PFAB_BAR0, 0x7c000000 | 0x01);
/* We don't need MEM32 and PRM remapping so disable them */
tsi108_write_reg(TSI108_PCI_PFAB_MEM32, 0x0);
tsi108_write_reg(TSI108_PCI_PFAB_PFM3, 0x0);
tsi108_write_reg(TSI108_PCI_PFAB_PFM4, 0x0);
/* Set P2O_BAR0 */
tsi108_write_reg(TSI108_PCI_P2O_BAR0_UPPER, 0x0);
tsi108_write_reg(TSI108_PCI_P2O_BAR0, 0xc0000000);
/* Init the PCI LUTs to do no remapping */
lut_addr = 0x500;
lut_val = 0x00000002;
for (i = 0; i < 32; i++) {
tsi108_write_reg(TSI108_PCI_OFFSET + lut_addr, lut_val);
lut_addr += 4;
tsi108_write_reg(TSI108_PCI_OFFSET + lut_addr, 0x40000000);
lut_addr += 4;
lut_val += 0x02000000;
}
tsi108_write_reg(TSI108_PCI_P2O_PAGE_SIZES, 0x00007900);
/* Set 64-bit PCI bus address for system memory */
tsi108_write_reg(TSI108_PCI_P2O_BAR2_UPPER, 0x0);
tsi108_write_reg(TSI108_PCI_P2O_BAR2, 0x0);
}
static void __init holly_setup_arch(void)
{
struct device_node *np;
if (ppc_md.progress)
ppc_md.progress("holly_setup_arch():set_bridge", 0);
tsi108_csr_vir_base = get_vir_csrbase();
/* setup PCI host bridge */
holly_remap_bridge();
np = of_find_node_by_type(NULL, "pci");
if (np)
tsi108_setup_pci(np, HOLLY_PCI_CFG_PHYS, 1);
ppc_md.pci_exclude_device = holly_exclude_device;
if (ppc_md.progress)
ppc_md.progress("tsi108: resources set", 0x100);
printk(KERN_INFO "PPC750GX/CL Platform\n");
}
/*
* Interrupt setup and service. Interrupts on the holly come
* from the four external INT pins, PCI interrupts are routed via
* PCI interrupt control registers, it generates internal IRQ23
*
* Interrupt routing on the Holly Board:
* TSI108:PB_INT[0] -> CPU0:INT#
* TSI108:PB_INT[1] -> CPU0:MCP#
* TSI108:PB_INT[2] -> N/C
* TSI108:PB_INT[3] -> N/C
*/
static void __init holly_init_IRQ(void)
{
struct mpic *mpic;
phys_addr_t mpic_paddr = 0;
struct device_node *tsi_pic;
#ifdef CONFIG_PCI
unsigned int cascade_pci_irq;
struct device_node *tsi_pci;
struct device_node *cascade_node = NULL;
#endif
tsi_pic = of_find_node_by_type(NULL, "open-pic");
if (tsi_pic) {
unsigned int size;
const void *prop = of_get_property(tsi_pic, "reg", &size);
mpic_paddr = of_translate_address(tsi_pic, prop);
}
if (mpic_paddr == 0) {
printk(KERN_ERR "%s: No tsi108 PIC found !\n", __func__);
return;
}
pr_debug("%s: tsi108 pic phys_addr = 0x%x\n", __func__, (u32) mpic_paddr);
mpic = mpic_alloc(tsi_pic, mpic_paddr,
MPIC_PRIMARY | MPIC_BIG_ENDIAN | MPIC_WANTS_RESET |
MPIC_SPV_EOI | MPIC_NO_PTHROU_DIS | MPIC_REGSET_TSI108,
24,
NR_IRQS-4, /* num_sources used */
"Tsi108_PIC");
BUG_ON(mpic == NULL);
mpic_assign_isu(mpic, 0, mpic_paddr + 0x100);
mpic_init(mpic);
#ifdef CONFIG_PCI
tsi_pci = of_find_node_by_type(NULL, "pci");
if (tsi_pci == NULL) {
printk(KERN_ERR "%s: No tsi108 pci node found !\n", __func__);
return;
}
cascade_node = of_find_node_by_type(NULL, "pic-router");
if (cascade_node == NULL) {
printk(KERN_ERR "%s: No tsi108 pci cascade node found !\n", __func__);
return;
}
cascade_pci_irq = irq_of_parse_and_map(tsi_pci, 0);
pr_debug("%s: tsi108 cascade_pci_irq = 0x%x\n", __func__, (u32) cascade_pci_irq);
tsi108_pci_int_init(cascade_node);
set_irq_data(cascade_pci_irq, mpic);
set_irq_chained_handler(cascade_pci_irq, tsi108_irq_cascade);
#endif
/* Configure MPIC outputs to CPU0 */
tsi108_write_reg(TSI108_MPIC_OFFSET + 0x30c, 0);
of_node_put(tsi_pic);
}
void holly_show_cpuinfo(struct seq_file *m)
{
seq_printf(m, "vendor\t\t: IBM\n");
seq_printf(m, "machine\t\t: PPC750 GX/CL\n");
}
void holly_restart(char *cmd)
{
__be32 __iomem *ocn_bar1 = NULL;
unsigned long bar;
struct device_node *bridge = NULL;
const void *prop;
int size;
phys_addr_t addr = 0xc0000000;
local_irq_disable();
bridge = of_find_node_by_type(NULL, "tsi-bridge");
if (bridge) {
prop = of_get_property(bridge, "reg", &size);
addr = of_translate_address(bridge, prop);
}
addr += (TSI108_PB_OFFSET + 0x414);
ocn_bar1 = ioremap(addr, 0x4);
/* Turn on the BOOT bit so the addresses are correctly
* routed to the HLP interface */
bar = ioread32be(ocn_bar1);
bar |= 2;
iowrite32be(bar, ocn_bar1);
iosync();
/* Set SRR0 to the reset vector and turn on MSR_IP */
mtspr(SPRN_SRR0, 0xfff00100);
mtspr(SPRN_SRR1, MSR_IP);
/* Do an rfi to jump back to firmware. Somewhat evil,
* but it works
*/
__asm__ __volatile__("rfi" : : : "memory");
/* Spin until reset happens. Shouldn't really get here */
for (;;) ;
}
void holly_power_off(void)
{
local_irq_disable();
/* No way to shut power off with software */
for (;;) ;
}
void holly_halt(void)
{
holly_power_off();
}
/*
* Called very early, device-tree isn't unflattened
*/
static int __init holly_probe(void)
{
unsigned long root = of_get_flat_dt_root();
if (!of_flat_dt_is_compatible(root, "ibm,holly"))
return 0;
return 1;
}
static int ppc750_machine_check_exception(struct pt_regs *regs)
{
const struct exception_table_entry *entry;
/* Are we prepared to handle this fault */
if ((entry = search_exception_tables(regs->nip)) != NULL) {
tsi108_clear_pci_cfg_error();
regs->msr |= MSR_RI;
regs->nip = entry->fixup;
return 1;
}
return 0;
}
define_machine(holly){
.name = "PPC750 GX/CL TSI",
.probe = holly_probe,
.setup_arch = holly_setup_arch,
.init_IRQ = holly_init_IRQ,
.show_cpuinfo = holly_show_cpuinfo,
.get_irq = mpic_get_irq,
.restart = holly_restart,
.calibrate_decr = generic_calibrate_decr,
.machine_check_exception = ppc750_machine_check_exception,
.progress = udbg_progress,
};

View File

@@ -0,0 +1,175 @@
/*
* Board setup routines for the Buffalo Linkstation / Kurobox Platform.
*
* Copyright (C) 2006 G. Liakhovetski (g.liakhovetski@gmx.de)
*
* Based on sandpoint.c by Mark A. Greer
*
* This file is licensed under the terms of the GNU General Public License
* version 2. This program is licensed "as is" without any warranty of
* any kind, whether express or implied.
*/
#include <linux/kernel.h>
#include <linux/initrd.h>
#include <linux/of_platform.h>
#include <asm/time.h>
#include <asm/prom.h>
#include <asm/mpic.h>
#include <asm/pci-bridge.h>
#include "mpc10x.h"
static __initdata struct of_device_id of_bus_ids[] = {
{ .type = "soc", },
{ .compatible = "simple-bus", },
{},
};
static int __init declare_of_platform_devices(void)
{
of_platform_bus_probe(NULL, of_bus_ids, NULL);
return 0;
}
machine_device_initcall(linkstation, declare_of_platform_devices);
static int __init linkstation_add_bridge(struct device_node *dev)
{
#ifdef CONFIG_PCI
int len;
struct pci_controller *hose;
const int *bus_range;
printk("Adding PCI host bridge %s\n", dev->full_name);
bus_range = of_get_property(dev, "bus-range", &len);
if (bus_range == NULL || len < 2 * sizeof(int))
printk(KERN_WARNING "Can't get bus-range for %s, assume"
" bus 0\n", dev->full_name);
hose = pcibios_alloc_controller(dev);
if (hose == NULL)
return -ENOMEM;
hose->first_busno = bus_range ? bus_range[0] : 0;
hose->last_busno = bus_range ? bus_range[1] : 0xff;
setup_indirect_pci(hose, 0xfec00000, 0xfee00000, 0);
/* Interpret the "ranges" property */
/* This also maps the I/O region and sets isa_io/mem_base */
pci_process_bridge_OF_ranges(hose, dev, 1);
#endif
return 0;
}
static void __init linkstation_setup_arch(void)
{
struct device_node *np;
/* Lookup PCI host bridges */
for_each_compatible_node(np, "pci", "mpc10x-pci")
linkstation_add_bridge(np);
printk(KERN_INFO "BUFFALO Network Attached Storage Series\n");
printk(KERN_INFO "(C) 2002-2005 BUFFALO INC.\n");
}
/*
* Interrupt setup and service. Interrupts on the linkstation come
* from the four PCI slots plus onboard 8241 devices: I2C, DUART.
*/
static void __init linkstation_init_IRQ(void)
{
struct mpic *mpic;
struct device_node *dnp;
const u32 *prop;
int size;
phys_addr_t paddr;
dnp = of_find_node_by_type(NULL, "open-pic");
if (dnp == NULL)
return;
prop = of_get_property(dnp, "reg", &size);
paddr = (phys_addr_t)of_translate_address(dnp, prop);
mpic = mpic_alloc(dnp, paddr, MPIC_PRIMARY | MPIC_WANTS_RESET, 4, 32, " EPIC ");
BUG_ON(mpic == NULL);
/* PCI IRQs */
mpic_assign_isu(mpic, 0, paddr + 0x10200);
/* I2C */
mpic_assign_isu(mpic, 1, paddr + 0x11000);
/* ttyS0, ttyS1 */
mpic_assign_isu(mpic, 2, paddr + 0x11100);
mpic_init(mpic);
}
extern void avr_uart_configure(void);
extern void avr_uart_send(const char);
static void linkstation_restart(char *cmd)
{
local_irq_disable();
/* Reset system via AVR */
avr_uart_configure();
/* Send reboot command */
avr_uart_send('C');
for(;;) /* Spin until reset happens */
avr_uart_send('G'); /* "kick" */
}
static void linkstation_power_off(void)
{
local_irq_disable();
/* Power down system via AVR */
avr_uart_configure();
/* send shutdown command */
avr_uart_send('E');
for(;;) /* Spin until power-off happens */
avr_uart_send('G'); /* "kick" */
/* NOTREACHED */
}
static void linkstation_halt(void)
{
linkstation_power_off();
/* NOTREACHED */
}
static void linkstation_show_cpuinfo(struct seq_file *m)
{
seq_printf(m, "vendor\t\t: Buffalo Technology\n");
seq_printf(m, "machine\t\t: Linkstation I/Kurobox(HG)\n");
}
static int __init linkstation_probe(void)
{
unsigned long root;
root = of_get_flat_dt_root();
if (!of_flat_dt_is_compatible(root, "linkstation"))
return 0;
return 1;
}
define_machine(linkstation){
.name = "Buffalo Linkstation",
.probe = linkstation_probe,
.setup_arch = linkstation_setup_arch,
.init_IRQ = linkstation_init_IRQ,
.show_cpuinfo = linkstation_show_cpuinfo,
.get_irq = mpic_get_irq,
.restart = linkstation_restart,
.power_off = linkstation_power_off,
.halt = linkstation_halt,
.calibrate_decr = generic_calibrate_decr,
};

View File

@@ -0,0 +1,142 @@
/*
* AVR power-management chip interface for the Buffalo Linkstation /
* Kurobox Platform.
*
* Author: 2006 (c) G. Liakhovetski
* g.liakhovetski@gmx.de
*
* This file is licensed under the terms of the GNU General Public License
* version 2. This program is licensed "as is" without any warranty of
* any kind, whether express or implied.
*/
#include <linux/workqueue.h>
#include <linux/string.h>
#include <linux/delay.h>
#include <linux/serial_reg.h>
#include <linux/serial_8250.h>
#include <asm/io.h>
#include <asm/prom.h>
#include <asm/termbits.h>
#include "mpc10x.h"
static void __iomem *avr_addr;
static unsigned long avr_clock;
static struct work_struct wd_work;
static void wd_stop(struct work_struct *unused)
{
const char string[] = "AAAAFFFFJJJJ>>>>VVVV>>>>ZZZZVVVVKKKK";
int i = 0, rescue = 8;
int len = strlen(string);
while (rescue--) {
int j;
char lsr = in_8(avr_addr + UART_LSR);
if (lsr & (UART_LSR_THRE | UART_LSR_TEMT)) {
for (j = 0; j < 16 && i < len; j++, i++)
out_8(avr_addr + UART_TX, string[i]);
if (i == len) {
/* Read "OK" back: 4ms for the last "KKKK"
plus a couple bytes back */
msleep(7);
printk("linkstation: disarming the AVR watchdog: ");
while (in_8(avr_addr + UART_LSR) & UART_LSR_DR)
printk("%c", in_8(avr_addr + UART_RX));
break;
}
}
msleep(17);
}
printk("\n");
}
#define AVR_QUOT(clock) ((clock) + 8 * 9600) / (16 * 9600)
void avr_uart_configure(void)
{
unsigned char cval = UART_LCR_WLEN8;
unsigned int quot = AVR_QUOT(avr_clock);
if (!avr_addr || !avr_clock)
return;
out_8(avr_addr + UART_LCR, cval); /* initialise UART */
out_8(avr_addr + UART_MCR, 0);
out_8(avr_addr + UART_IER, 0);
cval |= UART_LCR_STOP | UART_LCR_PARITY | UART_LCR_EPAR;
out_8(avr_addr + UART_LCR, cval); /* Set character format */
out_8(avr_addr + UART_LCR, cval | UART_LCR_DLAB); /* set DLAB */
out_8(avr_addr + UART_DLL, quot & 0xff); /* LS of divisor */
out_8(avr_addr + UART_DLM, quot >> 8); /* MS of divisor */
out_8(avr_addr + UART_LCR, cval); /* reset DLAB */
out_8(avr_addr + UART_FCR, UART_FCR_ENABLE_FIFO); /* enable FIFO */
}
void avr_uart_send(const char c)
{
if (!avr_addr || !avr_clock)
return;
out_8(avr_addr + UART_TX, c);
out_8(avr_addr + UART_TX, c);
out_8(avr_addr + UART_TX, c);
out_8(avr_addr + UART_TX, c);
}
static void __init ls_uart_init(void)
{
local_irq_disable();
#ifndef CONFIG_SERIAL_8250
out_8(avr_addr + UART_FCR, UART_FCR_ENABLE_FIFO); /* enable FIFO */
out_8(avr_addr + UART_FCR, UART_FCR_ENABLE_FIFO |
UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); /* clear FIFOs */
out_8(avr_addr + UART_FCR, 0);
out_8(avr_addr + UART_IER, 0);
/* Clear up interrupts */
(void) in_8(avr_addr + UART_LSR);
(void) in_8(avr_addr + UART_RX);
(void) in_8(avr_addr + UART_IIR);
(void) in_8(avr_addr + UART_MSR);
#endif
avr_uart_configure();
local_irq_enable();
}
static int __init ls_uarts_init(void)
{
struct device_node *avr;
phys_addr_t phys_addr;
int len;
avr = of_find_node_by_path("/soc10x/serial@80004500");
if (!avr)
return -EINVAL;
avr_clock = *(u32*)of_get_property(avr, "clock-frequency", &len);
phys_addr = ((u32*)of_get_property(avr, "reg", &len))[0];
if (!avr_clock || !phys_addr)
return -EINVAL;
avr_addr = ioremap(phys_addr, 32);
if (!avr_addr)
return -EFAULT;
ls_uart_init();
INIT_WORK(&wd_work, wd_stop);
schedule_work(&wd_work);
return 0;
}
machine_late_initcall(linkstation, ls_uarts_init);

View File

@@ -0,0 +1,180 @@
/*
* Common routines for the Motorola SPS MPC106/8240/107 Host bridge/Mem
* ctlr/EPIC/etc.
*
* Author: Mark A. Greer
* mgreer@mvista.com
*
* 2001 (c) MontaVista, Software, Inc. This file is licensed under
* the terms of the GNU General Public License version 2. This program
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
*/
#ifndef __PPC_KERNEL_MPC10X_H
#define __PPC_KERNEL_MPC10X_H
#include <linux/pci_ids.h>
#include <asm/pci-bridge.h>
/*
* The values here don't completely map everything but should work in most
* cases.
*
* MAP A (PReP Map)
* Processor: 0x80000000 - 0x807fffff -> PCI I/O: 0x00000000 - 0x007fffff
* Processor: 0xc0000000 - 0xdfffffff -> PCI MEM: 0x00000000 - 0x1fffffff
* PCI MEM: 0x80000000 -> Processor System Memory: 0x00000000
* EUMB mapped to: ioremap_base - 0x00100000 (ioremap_base - 1 MB)
*
* MAP B (CHRP Map)
* Processor: 0xfe000000 - 0xfebfffff -> PCI I/O: 0x00000000 - 0x00bfffff
* Processor: 0x80000000 - 0xbfffffff -> PCI MEM: 0x80000000 - 0xbfffffff
* PCI MEM: 0x00000000 -> Processor System Memory: 0x00000000
* EUMB mapped to: ioremap_base - 0x00100000 (ioremap_base - 1 MB)
*/
/*
* Define the vendor/device IDs for the various bridges--should be added to
* <linux/pci_ids.h>
*/
#define MPC10X_BRIDGE_106 ((PCI_DEVICE_ID_MOTOROLA_MPC106 << 16) | \
PCI_VENDOR_ID_MOTOROLA)
#define MPC10X_BRIDGE_8240 ((0x0003 << 16) | PCI_VENDOR_ID_MOTOROLA)
#define MPC10X_BRIDGE_107 ((0x0004 << 16) | PCI_VENDOR_ID_MOTOROLA)
#define MPC10X_BRIDGE_8245 ((0x0006 << 16) | PCI_VENDOR_ID_MOTOROLA)
/* Define the type of map to use */
#define MPC10X_MEM_MAP_A 1
#define MPC10X_MEM_MAP_B 2
/* Map A (PReP Map) Defines */
#define MPC10X_MAPA_CNFG_ADDR 0x80000cf8
#define MPC10X_MAPA_CNFG_DATA 0x80000cfc
#define MPC10X_MAPA_ISA_IO_BASE 0x80000000
#define MPC10X_MAPA_ISA_MEM_BASE 0xc0000000
#define MPC10X_MAPA_DRAM_OFFSET 0x80000000
#define MPC10X_MAPA_PCI_INTACK_ADDR 0xbffffff0
#define MPC10X_MAPA_PCI_IO_START 0x00000000
#define MPC10X_MAPA_PCI_IO_END (0x00800000 - 1)
#define MPC10X_MAPA_PCI_MEM_START 0x00000000
#define MPC10X_MAPA_PCI_MEM_END (0x20000000 - 1)
#define MPC10X_MAPA_PCI_MEM_OFFSET (MPC10X_MAPA_ISA_MEM_BASE - \
MPC10X_MAPA_PCI_MEM_START)
/* Map B (CHRP Map) Defines */
#define MPC10X_MAPB_CNFG_ADDR 0xfec00000
#define MPC10X_MAPB_CNFG_DATA 0xfee00000
#define MPC10X_MAPB_ISA_IO_BASE 0xfe000000
#define MPC10X_MAPB_ISA_MEM_BASE 0x80000000
#define MPC10X_MAPB_DRAM_OFFSET 0x00000000
#define MPC10X_MAPB_PCI_INTACK_ADDR 0xfef00000
#define MPC10X_MAPB_PCI_IO_START 0x00000000
#define MPC10X_MAPB_PCI_IO_END (0x00c00000 - 1)
#define MPC10X_MAPB_PCI_MEM_START 0x80000000
#define MPC10X_MAPB_PCI_MEM_END (0xc0000000 - 1)
#define MPC10X_MAPB_PCI_MEM_OFFSET (MPC10X_MAPB_ISA_MEM_BASE - \
MPC10X_MAPB_PCI_MEM_START)
/* Set hose members to values appropriate for the mem map used */
#define MPC10X_SETUP_HOSE(hose, map) { \
(hose)->pci_mem_offset = MPC10X_MAP##map##_PCI_MEM_OFFSET; \
(hose)->io_space.start = MPC10X_MAP##map##_PCI_IO_START; \
(hose)->io_space.end = MPC10X_MAP##map##_PCI_IO_END; \
(hose)->mem_space.start = MPC10X_MAP##map##_PCI_MEM_START; \
(hose)->mem_space.end = MPC10X_MAP##map##_PCI_MEM_END; \
(hose)->io_base_virt = (void *)MPC10X_MAP##map##_ISA_IO_BASE; \
}
/* Miscellaneous Configuration register offsets */
#define MPC10X_CFG_PIR_REG 0x09
#define MPC10X_CFG_PIR_HOST_BRIDGE 0x00
#define MPC10X_CFG_PIR_AGENT 0x01
#define MPC10X_CFG_EUMBBAR 0x78
#define MPC10X_CFG_PICR1_REG 0xa8
#define MPC10X_CFG_PICR1_ADDR_MAP_MASK 0x00010000
#define MPC10X_CFG_PICR1_ADDR_MAP_A 0x00010000
#define MPC10X_CFG_PICR1_ADDR_MAP_B 0x00000000
#define MPC10X_CFG_PICR1_SPEC_PCI_RD 0x00000004
#define MPC10X_CFG_PICR1_ST_GATH_EN 0x00000040
#define MPC10X_CFG_PICR2_REG 0xac
#define MPC10X_CFG_PICR2_COPYBACK_OPT 0x00000001
#define MPC10X_CFG_MAPB_OPTIONS_REG 0xe0
#define MPC10X_CFG_MAPB_OPTIONS_CFAE 0x80 /* CPU_FD_ALIAS_EN */
#define MPC10X_CFG_MAPB_OPTIONS_PFAE 0x40 /* PCI_FD_ALIAS_EN */
#define MPC10X_CFG_MAPB_OPTIONS_DR 0x20 /* DLL_RESET */
#define MPC10X_CFG_MAPB_OPTIONS_PCICH 0x08 /* PCI_COMPATIBILITY_HOLE */
#define MPC10X_CFG_MAPB_OPTIONS_PROCCH 0x04 /* PROC_COMPATIBILITY_HOLE */
/* Define offsets for the memory controller registers in the config space */
#define MPC10X_MCTLR_MEM_START_1 0x80 /* Banks 0-3 */
#define MPC10X_MCTLR_MEM_START_2 0x84 /* Banks 4-7 */
#define MPC10X_MCTLR_EXT_MEM_START_1 0x88 /* Banks 0-3 */
#define MPC10X_MCTLR_EXT_MEM_START_2 0x8c /* Banks 4-7 */
#define MPC10X_MCTLR_MEM_END_1 0x90 /* Banks 0-3 */
#define MPC10X_MCTLR_MEM_END_2 0x94 /* Banks 4-7 */
#define MPC10X_MCTLR_EXT_MEM_END_1 0x98 /* Banks 0-3 */
#define MPC10X_MCTLR_EXT_MEM_END_2 0x9c /* Banks 4-7 */
#define MPC10X_MCTLR_MEM_BANK_ENABLES 0xa0
/* Define some offset in the EUMB */
#define MPC10X_EUMB_SIZE 0x00100000 /* Total EUMB size (1MB) */
#define MPC10X_EUMB_MU_OFFSET 0x00000000 /* Msg Unit reg offset */
#define MPC10X_EUMB_MU_SIZE 0x00001000 /* Msg Unit reg size */
#define MPC10X_EUMB_DMA_OFFSET 0x00001000 /* DMA Unit reg offset */
#define MPC10X_EUMB_DMA_SIZE 0x00001000 /* DMA Unit reg size */
#define MPC10X_EUMB_ATU_OFFSET 0x00002000 /* Addr xlate reg offset */
#define MPC10X_EUMB_ATU_SIZE 0x00001000 /* Addr xlate reg size */
#define MPC10X_EUMB_I2C_OFFSET 0x00003000 /* I2C Unit reg offset */
#define MPC10X_EUMB_I2C_SIZE 0x00001000 /* I2C Unit reg size */
#define MPC10X_EUMB_DUART_OFFSET 0x00004000 /* DUART Unit reg offset (8245) */
#define MPC10X_EUMB_DUART_SIZE 0x00001000 /* DUART Unit reg size (8245) */
#define MPC10X_EUMB_EPIC_OFFSET 0x00040000 /* EPIC offset in EUMB */
#define MPC10X_EUMB_EPIC_SIZE 0x00030000 /* EPIC size */
#define MPC10X_EUMB_PM_OFFSET 0x000fe000 /* Performance Monitor reg offset (8245) */
#define MPC10X_EUMB_PM_SIZE 0x00001000 /* Performance Monitor reg size (8245) */
#define MPC10X_EUMB_WP_OFFSET 0x000ff000 /* Data path diagnostic, watchpoint reg offset */
#define MPC10X_EUMB_WP_SIZE 0x00001000 /* Data path diagnostic, watchpoint reg size */
/*
* Define some recommended places to put the EUMB regs.
* For both maps, recommend putting the EUMB from 0xeff00000 to 0xefffffff.
*/
extern unsigned long ioremap_base;
#define MPC10X_MAPA_EUMB_BASE (ioremap_base - MPC10X_EUMB_SIZE)
#define MPC10X_MAPB_EUMB_BASE MPC10X_MAPA_EUMB_BASE
enum ppc_sys_devices {
MPC10X_IIC1,
MPC10X_DMA0,
MPC10X_DMA1,
MPC10X_UART0,
MPC10X_UART1,
NUM_PPC_SYS_DEVS,
};
int mpc10x_bridge_init(struct pci_controller *hose,
uint current_map,
uint new_map,
uint phys_eumb_base);
unsigned long mpc10x_get_mem_size(uint mem_map);
int mpc10x_enable_store_gathering(struct pci_controller *hose);
int mpc10x_disable_store_gathering(struct pci_controller *hose);
/* For MPC107 boards that use the built-in openpic */
void mpc10x_set_openpic(void);
#endif /* __PPC_KERNEL_MPC10X_H */

View File

@@ -0,0 +1,227 @@
/*
* mpc7448_hpc2.c
*
* Board setup routines for the Freescale mpc7448hpc2(taiga) platform
*
* Author: Jacob Pan
* jacob.pan@freescale.com
* Author: Xianghua Xiao
* x.xiao@freescale.com
* Maintainer: Roy Zang <tie-fei.zang@freescale.com>
* Add Flat Device Tree support fot mpc7448hpc2 board
*
* Copyright 2004-2006 Freescale Semiconductor, Inc.
*
* 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.
*/
#include <linux/stddef.h>
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/kdev_t.h>
#include <linux/console.h>
#include <linux/delay.h>
#include <linux/irq.h>
#include <linux/seq_file.h>
#include <linux/root_dev.h>
#include <linux/serial.h>
#include <linux/tty.h>
#include <linux/serial_core.h>
#include <asm/system.h>
#include <asm/time.h>
#include <asm/machdep.h>
#include <asm/prom.h>
#include <asm/udbg.h>
#include <asm/tsi108.h>
#include <asm/pci-bridge.h>
#include <asm/reg.h>
#include <mm/mmu_decl.h>
#include <asm/tsi108_pci.h>
#include <asm/tsi108_irq.h>
#include <asm/mpic.h>
#undef DEBUG
#ifdef DEBUG
#define DBG(fmt...) do { printk(fmt); } while(0)
#else
#define DBG(fmt...) do { } while(0)
#endif
#define MPC7448HPC2_PCI_CFG_PHYS 0xfb000000
int mpc7448_hpc2_exclude_device(struct pci_controller *hose,
u_char bus, u_char devfn)
{
if (bus == 0 && PCI_SLOT(devfn) == 0)
return PCIBIOS_DEVICE_NOT_FOUND;
else
return PCIBIOS_SUCCESSFUL;
}
static void __init mpc7448_hpc2_setup_arch(void)
{
struct device_node *np;
if (ppc_md.progress)
ppc_md.progress("mpc7448_hpc2_setup_arch():set_bridge", 0);
tsi108_csr_vir_base = get_vir_csrbase();
/* setup PCI host bridge */
#ifdef CONFIG_PCI
for_each_compatible_node(np, "pci", "tsi108-pci")
tsi108_setup_pci(np, MPC7448HPC2_PCI_CFG_PHYS, 0);
ppc_md.pci_exclude_device = mpc7448_hpc2_exclude_device;
if (ppc_md.progress)
ppc_md.progress("tsi108: resources set", 0x100);
#endif
printk(KERN_INFO "MPC7448HPC2 (TAIGA) Platform\n");
printk(KERN_INFO
"Jointly ported by Freescale and Tundra Semiconductor\n");
printk(KERN_INFO
"Enabling L2 cache then enabling the HID0 prefetch engine.\n");
}
/*
* Interrupt setup and service. Interrupts on the mpc7448_hpc2 come
* from the four external INT pins, PCI interrupts are routed via
* PCI interrupt control registers, it generates internal IRQ23
*
* Interrupt routing on the Taiga Board:
* TSI108:PB_INT[0] -> CPU0:INT#
* TSI108:PB_INT[1] -> CPU0:MCP#
* TSI108:PB_INT[2] -> N/C
* TSI108:PB_INT[3] -> N/C
*/
static void __init mpc7448_hpc2_init_IRQ(void)
{
struct mpic *mpic;
phys_addr_t mpic_paddr = 0;
struct device_node *tsi_pic;
#ifdef CONFIG_PCI
unsigned int cascade_pci_irq;
struct device_node *tsi_pci;
struct device_node *cascade_node = NULL;
#endif
tsi_pic = of_find_node_by_type(NULL, "open-pic");
if (tsi_pic) {
unsigned int size;
const void *prop = of_get_property(tsi_pic, "reg", &size);
mpic_paddr = of_translate_address(tsi_pic, prop);
}
if (mpic_paddr == 0) {
printk("%s: No tsi108 PIC found !\n", __func__);
return;
}
DBG("%s: tsi108 pic phys_addr = 0x%x\n", __func__,
(u32) mpic_paddr);
mpic = mpic_alloc(tsi_pic, mpic_paddr,
MPIC_PRIMARY | MPIC_BIG_ENDIAN | MPIC_WANTS_RESET |
MPIC_SPV_EOI | MPIC_NO_PTHROU_DIS | MPIC_REGSET_TSI108,
24,
NR_IRQS-4, /* num_sources used */
"Tsi108_PIC");
BUG_ON(mpic == NULL);
mpic_assign_isu(mpic, 0, mpic_paddr + 0x100);
mpic_init(mpic);
#ifdef CONFIG_PCI
tsi_pci = of_find_node_by_type(NULL, "pci");
if (tsi_pci == NULL) {
printk("%s: No tsi108 pci node found !\n", __func__);
return;
}
cascade_node = of_find_node_by_type(NULL, "pic-router");
if (cascade_node == NULL) {
printk("%s: No tsi108 pci cascade node found !\n", __func__);
return;
}
cascade_pci_irq = irq_of_parse_and_map(tsi_pci, 0);
DBG("%s: tsi108 cascade_pci_irq = 0x%x\n", __func__,
(u32) cascade_pci_irq);
tsi108_pci_int_init(cascade_node);
set_irq_data(cascade_pci_irq, mpic);
set_irq_chained_handler(cascade_pci_irq, tsi108_irq_cascade);
#endif
/* Configure MPIC outputs to CPU0 */
tsi108_write_reg(TSI108_MPIC_OFFSET + 0x30c, 0);
of_node_put(tsi_pic);
}
void mpc7448_hpc2_show_cpuinfo(struct seq_file *m)
{
seq_printf(m, "vendor\t\t: Freescale Semiconductor\n");
}
void mpc7448_hpc2_restart(char *cmd)
{
local_irq_disable();
/* Set exception prefix high - to the firmware */
_nmask_and_or_msr(0, MSR_IP);
for (;;) ; /* Spin until reset happens */
}
void mpc7448_hpc2_power_off(void)
{
local_irq_disable();
for (;;) ; /* No way to shut power off with software */
}
void mpc7448_hpc2_halt(void)
{
mpc7448_hpc2_power_off();
}
/*
* Called very early, device-tree isn't unflattened
*/
static int __init mpc7448_hpc2_probe(void)
{
unsigned long root = of_get_flat_dt_root();
if (!of_flat_dt_is_compatible(root, "mpc74xx"))
return 0;
return 1;
}
static int mpc7448_machine_check_exception(struct pt_regs *regs)
{
const struct exception_table_entry *entry;
/* Are we prepared to handle this fault */
if ((entry = search_exception_tables(regs->nip)) != NULL) {
tsi108_clear_pci_cfg_error();
regs->msr |= MSR_RI;
regs->nip = entry->fixup;
return 1;
}
return 0;
}
define_machine(mpc7448_hpc2){
.name = "MPC7448 HPC2",
.probe = mpc7448_hpc2_probe,
.setup_arch = mpc7448_hpc2_setup_arch,
.init_IRQ = mpc7448_hpc2_init_IRQ,
.show_cpuinfo = mpc7448_hpc2_show_cpuinfo,
.get_irq = mpic_get_irq,
.restart = mpc7448_hpc2_restart,
.calibrate_decr = generic_calibrate_decr,
.machine_check_exception= mpc7448_machine_check_exception,
.progress = udbg_progress,
};

View File

@@ -0,0 +1,157 @@
/*
* Board setup routines for the Motorola PrPMC2800
*
* Author: Dale Farnsworth <dale@farnsworth.org>
*
* 2007 (c) MontaVista, Software, Inc. This file is licensed under
* the terms of the GNU General Public License version 2. This program
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
*/
#include <linux/stddef.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/seq_file.h>
#include <asm/machdep.h>
#include <asm/prom.h>
#include <asm/system.h>
#include <asm/time.h>
#include <mm/mmu_decl.h>
#include <sysdev/mv64x60.h>
#define MV64x60_MPP_CNTL_0 0x0000
#define MV64x60_MPP_CNTL_2 0x0008
#define MV64x60_GPP_IO_CNTL 0x0000
#define MV64x60_GPP_LEVEL_CNTL 0x0010
#define MV64x60_GPP_VALUE_SET 0x0018
#define PLATFORM_NAME_MAX 32
static char prpmc2800_platform_name[PLATFORM_NAME_MAX];
static void __iomem *mv64x60_mpp_reg_base;
static void __iomem *mv64x60_gpp_reg_base;
static void __init prpmc2800_setup_arch(void)
{
struct device_node *np;
phys_addr_t paddr;
const unsigned int *reg;
/*
* ioremap mpp and gpp registers in case they are later
* needed by prpmc2800_reset_board().
*/
np = of_find_compatible_node(NULL, NULL, "marvell,mv64360-mpp");
reg = of_get_property(np, "reg", NULL);
paddr = of_translate_address(np, reg);
of_node_put(np);
mv64x60_mpp_reg_base = ioremap(paddr, reg[1]);
np = of_find_compatible_node(NULL, NULL, "marvell,mv64360-gpp");
reg = of_get_property(np, "reg", NULL);
paddr = of_translate_address(np, reg);
of_node_put(np);
mv64x60_gpp_reg_base = ioremap(paddr, reg[1]);
#ifdef CONFIG_PCI
mv64x60_pci_init();
#endif
printk("Motorola %s\n", prpmc2800_platform_name);
}
static void prpmc2800_reset_board(void)
{
u32 temp;
local_irq_disable();
temp = in_le32(mv64x60_mpp_reg_base + MV64x60_MPP_CNTL_0);
temp &= 0xFFFF0FFF;
out_le32(mv64x60_mpp_reg_base + MV64x60_MPP_CNTL_0, temp);
temp = in_le32(mv64x60_gpp_reg_base + MV64x60_GPP_LEVEL_CNTL);
temp |= 0x00000004;
out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_LEVEL_CNTL, temp);
temp = in_le32(mv64x60_gpp_reg_base + MV64x60_GPP_IO_CNTL);
temp |= 0x00000004;
out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_IO_CNTL, temp);
temp = in_le32(mv64x60_mpp_reg_base + MV64x60_MPP_CNTL_2);
temp &= 0xFFFF0FFF;
out_le32(mv64x60_mpp_reg_base + MV64x60_MPP_CNTL_2, temp);
temp = in_le32(mv64x60_gpp_reg_base + MV64x60_GPP_LEVEL_CNTL);
temp |= 0x00080000;
out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_LEVEL_CNTL, temp);
temp = in_le32(mv64x60_gpp_reg_base + MV64x60_GPP_IO_CNTL);
temp |= 0x00080000;
out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_IO_CNTL, temp);
out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_VALUE_SET, 0x00080004);
}
static void prpmc2800_restart(char *cmd)
{
volatile ulong i = 10000000;
prpmc2800_reset_board();
while (i-- > 0);
panic("restart failed\n");
}
#ifdef CONFIG_NOT_COHERENT_CACHE
#define PPRPM2800_COHERENCY_SETTING "off"
#else
#define PPRPM2800_COHERENCY_SETTING "on"
#endif
void prpmc2800_show_cpuinfo(struct seq_file *m)
{
seq_printf(m, "Vendor\t\t: Motorola\n");
seq_printf(m, "coherency\t: %s\n", PPRPM2800_COHERENCY_SETTING);
}
/*
* Called very early, device-tree isn't unflattened
*/
static int __init prpmc2800_probe(void)
{
unsigned long root = of_get_flat_dt_root();
unsigned long len = PLATFORM_NAME_MAX;
void *m;
if (!of_flat_dt_is_compatible(root, "motorola,PrPMC2800"))
return 0;
/* Update ppc_md.name with name from dt */
m = of_get_flat_dt_prop(root, "model", &len);
if (m)
strncpy(prpmc2800_platform_name, m,
min((int)len, PLATFORM_NAME_MAX - 1));
_set_L2CR(_get_L2CR() | L2CR_L2E);
return 1;
}
define_machine(prpmc2800){
.name = prpmc2800_platform_name,
.probe = prpmc2800_probe,
.setup_arch = prpmc2800_setup_arch,
.init_early = mv64x60_init_early,
.show_cpuinfo = prpmc2800_show_cpuinfo,
.init_IRQ = mv64x60_init_irq,
.get_irq = mv64x60_get_irq,
.restart = prpmc2800_restart,
.calibrate_decr = generic_calibrate_decr,
};

View File

@@ -0,0 +1,145 @@
/*
* Board setup routines for the storcenter
*
* Copyright 2007 (C) Oyvind Repvik (nail@nslu2-linux.org)
* Copyright 2007 Andy Wilcox, Jon Loeliger
*
* Based on linkstation.c by G. Liakhovetski
*
* This file is licensed under the terms of the GNU General Public License
* version 2. This program is licensed "as is" without any warranty of
* any kind, whether express or implied.
*/
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/initrd.h>
#include <linux/of_platform.h>
#include <asm/system.h>
#include <asm/time.h>
#include <asm/prom.h>
#include <asm/mpic.h>
#include <asm/pci-bridge.h>
#include "mpc10x.h"
static __initdata struct of_device_id storcenter_of_bus[] = {
{ .name = "soc", },
{},
};
static int __init storcenter_device_probe(void)
{
of_platform_bus_probe(NULL, storcenter_of_bus, NULL);
return 0;
}
machine_device_initcall(storcenter, storcenter_device_probe);
static int __init storcenter_add_bridge(struct device_node *dev)
{
#ifdef CONFIG_PCI
int len;
struct pci_controller *hose;
const int *bus_range;
printk("Adding PCI host bridge %s\n", dev->full_name);
hose = pcibios_alloc_controller(dev);
if (hose == NULL)
return -ENOMEM;
bus_range = of_get_property(dev, "bus-range", &len);
hose->first_busno = bus_range ? bus_range[0] : 0;
hose->last_busno = bus_range ? bus_range[1] : 0xff;
setup_indirect_pci(hose, MPC10X_MAPB_CNFG_ADDR, MPC10X_MAPB_CNFG_DATA, 0);
/* Interpret the "ranges" property */
/* This also maps the I/O region and sets isa_io/mem_base */
pci_process_bridge_OF_ranges(hose, dev, 1);
#endif
return 0;
}
static void __init storcenter_setup_arch(void)
{
struct device_node *np;
/* Lookup PCI host bridges */
for_each_compatible_node(np, "pci", "mpc10x-pci")
storcenter_add_bridge(np);
printk(KERN_INFO "IOMEGA StorCenter\n");
}
/*
* Interrupt setup and service. Interrrupts on the turbostation come
* from the four PCI slots plus onboard 8241 devices: I2C, DUART.
*/
static void __init storcenter_init_IRQ(void)
{
struct mpic *mpic;
struct device_node *dnp;
const void *prop;
int size;
phys_addr_t paddr;
dnp = of_find_node_by_type(NULL, "open-pic");
if (dnp == NULL)
return;
prop = of_get_property(dnp, "reg", &size);
if (prop == NULL) {
of_node_put(dnp);
return;
}
paddr = (phys_addr_t)of_translate_address(dnp, prop);
mpic = mpic_alloc(dnp, paddr, MPIC_PRIMARY | MPIC_WANTS_RESET,
16, 32, " OpenPIC ");
of_node_put(dnp);
BUG_ON(mpic == NULL);
/*
* 16 Serial Interrupts followed by 16 Internal Interrupts.
* I2C is the second internal, so it is at 17, 0x11020.
*/
mpic_assign_isu(mpic, 0, paddr + 0x10200);
mpic_assign_isu(mpic, 1, paddr + 0x11000);
mpic_init(mpic);
}
static void storcenter_restart(char *cmd)
{
local_irq_disable();
/* Set exception prefix high - to the firmware */
_nmask_and_or_msr(0, MSR_IP);
/* Wait for reset to happen */
for (;;) ;
}
static int __init storcenter_probe(void)
{
unsigned long root = of_get_flat_dt_root();
return of_flat_dt_is_compatible(root, "iomega,storcenter");
}
define_machine(storcenter){
.name = "IOMEGA StorCenter",
.probe = storcenter_probe,
.setup_arch = storcenter_setup_arch,
.init_IRQ = storcenter_init_IRQ,
.get_irq = mpic_get_irq,
.restart = storcenter_restart,
.calibrate_decr = generic_calibrate_decr,
};