Skip to content

Commit

Permalink
[POWERPC] 85xx: Add support for Wind River SBC8560 in arch/powerpc
Browse files Browse the repository at this point in the history
This adds support for the Wind River SBC8560 board, implemented as
powerpc.  It closely follows the implementation of the MPC8560ADS.

Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
  • Loading branch information
Paul Gortmaker authored and Kumar Gala committed Jan 28, 2008
1 parent 1a7507c commit 2c19806
Show file tree
Hide file tree
Showing 3 changed files with 295 additions and 2 deletions.
11 changes: 9 additions & 2 deletions arch/powerpc/platforms/85xx/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,13 @@ config TQM8560
select TQM85xx
select CPM2

config SBC8560
bool "Wind River SBC8560"
select DEFAULT_UIMAGE
select PPC_CPM_NEW_BINDING
help
This option enables support for the Wind River SBC8560 board

endchoice

config TQM85xx
Expand All @@ -96,7 +103,7 @@ config MPC8540
config MPC8560
bool
select CPM2
default y if MPC8560_ADS || STX_GP3
default y if MPC8560_ADS || STX_GP3 || SBC8560

config MPC85xx
bool
Expand All @@ -106,4 +113,4 @@ config MPC85xx
select FSL_PCI if PCI
select SERIAL_8250_SHARE_IRQ if SERIAL_8250
default y if MPC8540_ADS || MPC85xx_CDS || MPC8560_ADS \
|| MPC85xx_MDS || MPC85xx_DS || STX_GP3
|| MPC85xx_MDS || MPC85xx_DS || STX_GP3 || SBC8560
1 change: 1 addition & 0 deletions arch/powerpc/platforms/85xx/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ obj-$(CONFIG_MPC85xx_DS) += mpc85xx_ds.o
obj-$(CONFIG_MPC85xx_MDS) += mpc85xx_mds.o
obj-$(CONFIG_STX_GP3) += stx_gp3.o
obj-$(CONFIG_TQM85xx) += tqm85xx.o
obj-$(CONFIG_SBC8560) += sbc8560.o
285 changes: 285 additions & 0 deletions arch/powerpc/platforms/85xx/sbc8560.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,285 @@
/*
* Wind River SBC8560 setup and early boot code.
*
* Copyright 2007 Wind River Systems Inc.
*
* By Paul Gortmaker (see MAINTAINERS for contact information)
*
* Based largely on the MPC8560ADS support - Copyright 2005 Freescale 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/delay.h>
#include <linux/seq_file.h>
#include <linux/of_platform.h>

#include <asm/system.h>
#include <asm/time.h>
#include <asm/machdep.h>
#include <asm/pci-bridge.h>
#include <asm/mpic.h>
#include <mm/mmu_decl.h>
#include <asm/udbg.h>

#include <sysdev/fsl_soc.h>
#include <sysdev/fsl_pci.h>

#ifdef CONFIG_CPM2
#include <asm/cpm2.h>
#include <sysdev/cpm2_pic.h>
#endif

#ifdef CONFIG_CPM2

static void cpm2_cascade(unsigned int irq, struct irq_desc *desc)
{
int cascade_irq;

while ((cascade_irq = cpm2_get_irq()) >= 0)
generic_handle_irq(cascade_irq);

desc->chip->eoi(irq);
}

#endif /* CONFIG_CPM2 */

static void __init sbc8560_pic_init(void)
{
struct mpic *mpic;
struct resource r;
struct device_node *np = NULL;
#ifdef CONFIG_CPM2
int irq;
#endif

np = of_find_node_by_type(np, "open-pic");
if (!np) {
printk(KERN_ERR "Could not find open-pic node\n");
return;
}

if (of_address_to_resource(np, 0, &r)) {
printk(KERN_ERR "Could not map mpic register space\n");
of_node_put(np);
return;
}

mpic = mpic_alloc(np, r.start,
MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN,
0, 256, " OpenPIC ");
BUG_ON(mpic == NULL);
of_node_put(np);

mpic_init(mpic);

#ifdef CONFIG_CPM2
/* Setup CPM2 PIC */
np = of_find_compatible_node(NULL, NULL, "fsl,cpm2-pic");
if (np == NULL) {
printk(KERN_ERR "PIC init: can not find fsl,cpm2-pic node\n");
return;
}
irq = irq_of_parse_and_map(np, 0);

cpm2_pic_init(np);
of_node_put(np);
set_irq_chained_handler(irq, cpm2_cascade);
#endif
}

/*
* Setup the architecture
*/
#ifdef CONFIG_CPM2
struct cpm_pin {
int port, pin, flags;
};

static const struct cpm_pin sbc8560_pins[] = {
/* SCC1 */
{3, 29, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
{3, 30, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY},
{3, 31, CPM_PIN_INPUT | CPM_PIN_PRIMARY},

/* SCC2 */
{3, 26, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
{3, 27, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
{3, 28, CPM_PIN_INPUT | CPM_PIN_PRIMARY},

/* FCC2 */
{1, 18, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
{1, 19, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
{1, 20, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
{1, 21, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
{1, 22, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
{1, 23, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
{1, 24, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
{1, 25, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
{1, 26, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
{1, 27, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
{1, 28, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
{1, 29, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY},
{1, 30, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
{1, 31, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
{2, 18, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, /* CLK14 */
{2, 19, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, /* CLK13 */

/* FCC3 */
{1, 4, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
{1, 5, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
{1, 6, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
{1, 7, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
{1, 8, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
{1, 9, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
{1, 10, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
{1, 11, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
{1, 12, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
{1, 13, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
{1, 14, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
{1, 15, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
{1, 16, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
{1, 17, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
{2, 16, CPM_PIN_INPUT | CPM_PIN_SECONDARY}, /* CLK16 */
{2, 17, CPM_PIN_INPUT | CPM_PIN_SECONDARY}, /* CLK15 */
};

static void __init init_ioports(void)
{
int i;

for (i = 0; i < ARRAY_SIZE(sbc8560_pins); i++) {
struct cpm_pin *pin = &sbc8560_pins[i];
cpm2_set_pin(pin->port, pin->pin, pin->flags);
}

cpm2_clk_setup(CPM_CLK_SCC1, CPM_BRG1, CPM_CLK_RX);
cpm2_clk_setup(CPM_CLK_SCC1, CPM_BRG1, CPM_CLK_TX);
cpm2_clk_setup(CPM_CLK_SCC2, CPM_BRG2, CPM_CLK_RX);
cpm2_clk_setup(CPM_CLK_SCC2, CPM_BRG2, CPM_CLK_TX);
cpm2_clk_setup(CPM_CLK_FCC2, CPM_CLK13, CPM_CLK_RX);
cpm2_clk_setup(CPM_CLK_FCC2, CPM_CLK14, CPM_CLK_TX);
cpm2_clk_setup(CPM_CLK_FCC3, CPM_CLK15, CPM_CLK_RX);
cpm2_clk_setup(CPM_CLK_FCC3, CPM_CLK16, CPM_CLK_TX);
}
#endif

static void __init sbc8560_setup_arch(void)
{
#ifdef CONFIG_PCI
struct device_node *np;
#endif

if (ppc_md.progress)
ppc_md.progress("sbc8560_setup_arch()", 0);

#ifdef CONFIG_CPM2
cpm2_reset();
init_ioports();
#endif

#ifdef CONFIG_PCI
for_each_compatible_node(np, "pci", "fsl,mpc8540-pci")
fsl_add_bridge(np, 1);
#endif
}

static void sbc8560_show_cpuinfo(struct seq_file *m)
{
uint pvid, svid, phid1;
uint memsize = total_memory;

pvid = mfspr(SPRN_PVR);
svid = mfspr(SPRN_SVR);

seq_printf(m, "Vendor\t\t: Wind River\n");
seq_printf(m, "Machine\t\t: SBC8560\n");
seq_printf(m, "PVR\t\t: 0x%x\n", pvid);
seq_printf(m, "SVR\t\t: 0x%x\n", svid);

/* Display cpu Pll setting */
phid1 = mfspr(SPRN_HID1);
seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f));

/* Display the amount of memory */
seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024));
}

static struct of_device_id __initdata of_bus_ids[] = {
{ .name = "soc", },
{ .type = "soc", },
{ .name = "cpm", },
{ .name = "localbus", },
{},
};

static int __init declare_of_platform_devices(void)
{
if (!machine_is(sbc8560))
return 0;

of_platform_bus_probe(NULL, of_bus_ids, NULL);
return 0;
}
device_initcall(declare_of_platform_devices);

/*
* Called very early, device-tree isn't unflattened
*/
static int __init sbc8560_probe(void)
{
unsigned long root = of_get_flat_dt_root();

return of_flat_dt_is_compatible(root, "SBC8560");
}

#ifdef CONFIG_RTC_DRV_M48T59
static int __init sbc8560_rtc_init(void)
{
struct device_node *np;
struct resource res;
struct platform_device *rtc_dev;

np = of_find_compatible_node(NULL, NULL, "m48t59");
if (np == NULL) {
printk("No RTC in DTB. Has it been eaten by wild dogs?\n");
return -ENODEV;
}

of_address_to_resource(np, 0, &res);
of_node_put(np);

printk("Found RTC (m48t59) at i/o 0x%x\n", res.start);

rtc_dev = platform_device_register_simple("rtc-m48t59", 0, &res, 1);

if (IS_ERR(rtc_dev)) {
printk("Registering sbc8560 RTC device failed\n");
return PTR_ERR(rtc_dev);
}

return 0;
}

arch_initcall(sbc8560_rtc_init);

#endif /* M48T59 */

define_machine(sbc8560) {
.name = "SBC8560",
.probe = sbc8560_probe,
.setup_arch = sbc8560_setup_arch,
.init_IRQ = sbc8560_pic_init,
.show_cpuinfo = sbc8560_show_cpuinfo,
.get_irq = mpic_get_irq,
.restart = fsl_rstcr_restart,
.calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress,
};

0 comments on commit 2c19806

Please sign in to comment.