mirror of
https://github.com/AetherDroid/android_kernel_samsung_on5xelte.git
synced 2025-09-09 01:28:05 -04:00
Fixed MTP to work with TWRP
This commit is contained in:
commit
f6dfaef42e
50820 changed files with 20846062 additions and 0 deletions
284
arch/powerpc/platforms/85xx/Kconfig
Normal file
284
arch/powerpc/platforms/85xx/Kconfig
Normal file
|
@ -0,0 +1,284 @@
|
|||
menuconfig FSL_SOC_BOOKE
|
||||
bool "Freescale Book-E Machine Type"
|
||||
depends on PPC_85xx || PPC_BOOK3E
|
||||
select FSL_SOC
|
||||
select PPC_UDBG_16550
|
||||
select MPIC
|
||||
select PPC_PCI_CHOICE
|
||||
select FSL_PCI if PCI
|
||||
select SERIAL_8250_EXTENDED if SERIAL_8250
|
||||
select SERIAL_8250_SHARE_IRQ if SERIAL_8250
|
||||
default y
|
||||
|
||||
if FSL_SOC_BOOKE
|
||||
|
||||
if PPC32
|
||||
|
||||
config FSL_85XX_CACHE_SRAM
|
||||
bool
|
||||
select PPC_LIB_RHEAP
|
||||
help
|
||||
When selected, this option enables cache-sram support
|
||||
for memory allocation on P1/P2 QorIQ platforms.
|
||||
cache-sram-size and cache-sram-offset kernel boot
|
||||
parameters should be passed when this option is enabled.
|
||||
|
||||
config BSC9131_RDB
|
||||
bool "Freescale BSC9131RDB"
|
||||
select DEFAULT_UIMAGE
|
||||
help
|
||||
This option enables support for the Freescale BSC9131RDB board.
|
||||
The BSC9131 is a heterogeneous SoC containing an e500v2 powerpc and a
|
||||
StarCore SC3850 DSP
|
||||
Manufacturer : Freescale Semiconductor, Inc
|
||||
|
||||
config C293_PCIE
|
||||
bool "Freescale C293PCIE"
|
||||
select DEFAULT_UIMAGE
|
||||
help
|
||||
This option enables support for the C293PCIE board
|
||||
|
||||
config BSC9132_QDS
|
||||
bool "Freescale BSC9132QDS"
|
||||
select DEFAULT_UIMAGE
|
||||
help
|
||||
This option enables support for the Freescale BSC9132 QDS board.
|
||||
BSC9132 is a heterogeneous SoC containing dual e500v2 powerpc cores
|
||||
and dual StarCore SC3850 DSP cores.
|
||||
Manufacturer : Freescale Semiconductor, Inc
|
||||
|
||||
config MPC8540_ADS
|
||||
bool "Freescale MPC8540 ADS"
|
||||
select DEFAULT_UIMAGE
|
||||
help
|
||||
This option enables support for the MPC 8540 ADS board
|
||||
|
||||
config MPC8560_ADS
|
||||
bool "Freescale MPC8560 ADS"
|
||||
select DEFAULT_UIMAGE
|
||||
select CPM2
|
||||
help
|
||||
This option enables support for the MPC 8560 ADS board
|
||||
|
||||
config MPC85xx_CDS
|
||||
bool "Freescale MPC85xx CDS"
|
||||
select DEFAULT_UIMAGE
|
||||
select PPC_I8259
|
||||
select HAS_RAPIDIO
|
||||
help
|
||||
This option enables support for the MPC85xx CDS board
|
||||
|
||||
config MPC85xx_MDS
|
||||
bool "Freescale MPC85xx MDS"
|
||||
select DEFAULT_UIMAGE
|
||||
select PHYLIB
|
||||
select HAS_RAPIDIO
|
||||
select SWIOTLB
|
||||
help
|
||||
This option enables support for the MPC85xx MDS board
|
||||
|
||||
config MPC8536_DS
|
||||
bool "Freescale MPC8536 DS"
|
||||
select DEFAULT_UIMAGE
|
||||
select SWIOTLB
|
||||
help
|
||||
This option enables support for the MPC8536 DS board
|
||||
|
||||
config MPC85xx_DS
|
||||
bool "Freescale MPC85xx DS"
|
||||
select PPC_I8259
|
||||
select DEFAULT_UIMAGE
|
||||
select FSL_ULI1575 if PCI
|
||||
select SWIOTLB
|
||||
help
|
||||
This option enables support for the MPC85xx DS (MPC8544 DS) board
|
||||
|
||||
config MPC85xx_RDB
|
||||
bool "Freescale MPC85xx RDB"
|
||||
select PPC_I8259
|
||||
select DEFAULT_UIMAGE
|
||||
select FSL_ULI1575 if PCI
|
||||
select SWIOTLB
|
||||
help
|
||||
This option enables support for the MPC85xx RDB (P2020 RDB) board
|
||||
|
||||
config P1010_RDB
|
||||
bool "Freescale P1010RDB"
|
||||
select DEFAULT_UIMAGE
|
||||
help
|
||||
This option enables support for the MPC85xx RDB (P1010 RDB) board
|
||||
|
||||
P1010RDB contains P1010Si, which provides CPU performance up to 800
|
||||
MHz and 1600 DMIPS, additional functionality and faster interfaces
|
||||
(DDR3/3L, SATA II, and PCI Express).
|
||||
|
||||
config P1022_DS
|
||||
bool "Freescale P1022 DS"
|
||||
select DEFAULT_UIMAGE
|
||||
select SWIOTLB
|
||||
help
|
||||
This option enables support for the Freescale P1022DS reference board.
|
||||
|
||||
config P1022_RDK
|
||||
bool "Freescale / iVeia P1022 RDK"
|
||||
select DEFAULT_UIMAGE
|
||||
help
|
||||
This option enables support for the Freescale / iVeia P1022RDK
|
||||
reference board.
|
||||
|
||||
config P1023_RDB
|
||||
bool "Freescale P1023 RDB"
|
||||
select DEFAULT_UIMAGE
|
||||
help
|
||||
This option enables support for the P1023 RDB board.
|
||||
|
||||
config TWR_P102x
|
||||
bool "Freescale TWR-P102x"
|
||||
select DEFAULT_UIMAGE
|
||||
help
|
||||
This option enables support for the TWR-P1025 board.
|
||||
|
||||
config SOCRATES
|
||||
bool "Socrates"
|
||||
select DEFAULT_UIMAGE
|
||||
help
|
||||
This option enables support for the Socrates board.
|
||||
|
||||
config KSI8560
|
||||
bool "Emerson KSI8560"
|
||||
select DEFAULT_UIMAGE
|
||||
help
|
||||
This option enables support for the Emerson KSI8560 board
|
||||
|
||||
config XES_MPC85xx
|
||||
bool "X-ES single-board computer"
|
||||
select DEFAULT_UIMAGE
|
||||
help
|
||||
This option enables support for the various single-board
|
||||
computers from Extreme Engineering Solutions (X-ES) based on
|
||||
Freescale MPC85xx processors.
|
||||
Manufacturer: Extreme Engineering Solutions, Inc.
|
||||
URL: <http://www.xes-inc.com/>
|
||||
|
||||
config STX_GP3
|
||||
bool "Silicon Turnkey Express GP3"
|
||||
help
|
||||
This option enables support for the Silicon Turnkey Express GP3
|
||||
board.
|
||||
select CPM2
|
||||
select DEFAULT_UIMAGE
|
||||
|
||||
config TQM8540
|
||||
bool "TQ Components TQM8540"
|
||||
help
|
||||
This option enables support for the TQ Components TQM8540 board.
|
||||
select DEFAULT_UIMAGE
|
||||
select TQM85xx
|
||||
|
||||
config TQM8541
|
||||
bool "TQ Components TQM8541"
|
||||
help
|
||||
This option enables support for the TQ Components TQM8541 board.
|
||||
select DEFAULT_UIMAGE
|
||||
select TQM85xx
|
||||
select CPM2
|
||||
|
||||
config TQM8548
|
||||
bool "TQ Components TQM8548"
|
||||
help
|
||||
This option enables support for the TQ Components TQM8548 board.
|
||||
select DEFAULT_UIMAGE
|
||||
select TQM85xx
|
||||
|
||||
config TQM8555
|
||||
bool "TQ Components TQM8555"
|
||||
help
|
||||
This option enables support for the TQ Components TQM8555 board.
|
||||
select DEFAULT_UIMAGE
|
||||
select TQM85xx
|
||||
select CPM2
|
||||
|
||||
config TQM8560
|
||||
bool "TQ Components TQM8560"
|
||||
help
|
||||
This option enables support for the TQ Components TQM8560 board.
|
||||
select DEFAULT_UIMAGE
|
||||
select TQM85xx
|
||||
select CPM2
|
||||
|
||||
config SBC8548
|
||||
bool "Wind River SBC8548"
|
||||
select DEFAULT_UIMAGE
|
||||
help
|
||||
This option enables support for the Wind River SBC8548 board
|
||||
|
||||
config PPA8548
|
||||
bool "Prodrive PPA8548"
|
||||
help
|
||||
This option enables support for the Prodrive PPA8548 board.
|
||||
select DEFAULT_UIMAGE
|
||||
select HAS_RAPIDIO
|
||||
|
||||
config GE_IMP3A
|
||||
bool "GE Intelligent Platforms IMP3A"
|
||||
select DEFAULT_UIMAGE
|
||||
select SWIOTLB
|
||||
select MMIO_NVRAM
|
||||
select ARCH_REQUIRE_GPIOLIB
|
||||
select GE_FPGA
|
||||
help
|
||||
This option enables support for the GE Intelligent Platforms IMP3A
|
||||
board.
|
||||
|
||||
This board is a 3U CompactPCI Single Board Computer with a Freescale
|
||||
P2020 processor.
|
||||
|
||||
config SGY_CTS1000
|
||||
tristate "Servergy CTS-1000 support"
|
||||
select GPIOLIB
|
||||
select OF_GPIO
|
||||
depends on CORENET_GENERIC
|
||||
help
|
||||
Enable this to support functionality in Servergy's CTS-1000 systems.
|
||||
|
||||
endif # PPC32
|
||||
|
||||
config PPC_QEMU_E500
|
||||
bool "QEMU generic e500 platform"
|
||||
select DEFAULT_UIMAGE
|
||||
help
|
||||
This option enables support for running as a QEMU guest using
|
||||
QEMU's generic e500 machine. This is not required if you're
|
||||
using a QEMU machine that targets a specific board, such as
|
||||
mpc8544ds.
|
||||
|
||||
Unlike most e500 boards that target a specific CPU, this
|
||||
platform works with any e500-family CPU that QEMU supports.
|
||||
Thus, you'll need to make sure CONFIG_PPC_E500MC is set or
|
||||
unset based on the emulated CPU (or actual host CPU in the case
|
||||
of KVM).
|
||||
|
||||
config CORENET_GENERIC
|
||||
bool "Freescale CoreNet Generic"
|
||||
select DEFAULT_UIMAGE
|
||||
select E500
|
||||
select PPC_E500MC
|
||||
select PHYS_64BIT
|
||||
select SWIOTLB
|
||||
select ARCH_REQUIRE_GPIOLIB
|
||||
select GPIO_MPC8XXX
|
||||
select HAS_RAPIDIO
|
||||
select PPC_EPAPR_HV_PIC
|
||||
help
|
||||
This option enables support for the FSL CoreNet based boards.
|
||||
For 32bit kernel, the following boards are supported:
|
||||
P2041 RDB, P3041 DS, P4080 DS, kmcoge4, and OCA4080
|
||||
For 64bit kernel, the following boards are supported:
|
||||
T208x QDS/RDB, T4240 QDS/RDB and B4 QDS
|
||||
The following boards are supported for both 32bit and 64bit kernel:
|
||||
P5020 DS, P5040 DS and T104xQDS/RDB
|
||||
|
||||
endif # FSL_SOC_BOOKE
|
||||
|
||||
config TQM85xx
|
||||
bool
|
33
arch/powerpc/platforms/85xx/Makefile
Normal file
33
arch/powerpc/platforms/85xx/Makefile
Normal file
|
@ -0,0 +1,33 @@
|
|||
#
|
||||
# Makefile for the PowerPC 85xx linux kernel.
|
||||
#
|
||||
obj-$(CONFIG_SMP) += smp.o
|
||||
|
||||
obj-y += common.o
|
||||
|
||||
obj-$(CONFIG_BSC9131_RDB) += bsc913x_rdb.o
|
||||
obj-$(CONFIG_BSC9132_QDS) += bsc913x_qds.o
|
||||
obj-$(CONFIG_C293_PCIE) += c293pcie.o
|
||||
obj-$(CONFIG_MPC8540_ADS) += mpc85xx_ads.o
|
||||
obj-$(CONFIG_MPC8560_ADS) += mpc85xx_ads.o
|
||||
obj-$(CONFIG_MPC85xx_CDS) += mpc85xx_cds.o
|
||||
obj-$(CONFIG_MPC8536_DS) += mpc8536_ds.o
|
||||
obj-$(CONFIG_MPC85xx_DS) += mpc85xx_ds.o
|
||||
obj-$(CONFIG_MPC85xx_MDS) += mpc85xx_mds.o
|
||||
obj-$(CONFIG_MPC85xx_RDB) += mpc85xx_rdb.o
|
||||
obj-$(CONFIG_P1010_RDB) += p1010rdb.o
|
||||
obj-$(CONFIG_P1022_DS) += p1022_ds.o
|
||||
obj-$(CONFIG_P1022_RDK) += p1022_rdk.o
|
||||
obj-$(CONFIG_P1023_RDB) += p1023_rdb.o
|
||||
obj-$(CONFIG_TWR_P102x) += twr_p102x.o
|
||||
obj-$(CONFIG_CORENET_GENERIC) += corenet_generic.o
|
||||
obj-$(CONFIG_STX_GP3) += stx_gp3.o
|
||||
obj-$(CONFIG_TQM85xx) += tqm85xx.o
|
||||
obj-$(CONFIG_SBC8548) += sbc8548.o
|
||||
obj-$(CONFIG_PPA8548) += ppa8548.o
|
||||
obj-$(CONFIG_SOCRATES) += socrates.o socrates_fpga_pic.o
|
||||
obj-$(CONFIG_KSI8560) += ksi8560.o
|
||||
obj-$(CONFIG_XES_MPC85xx) += xes_mpc85xx.o
|
||||
obj-$(CONFIG_GE_IMP3A) += ge_imp3a.o
|
||||
obj-$(CONFIG_PPC_QEMU_E500) += qemu_e500.o
|
||||
obj-$(CONFIG_SGY_CTS1000) += sgy_cts1000.o
|
74
arch/powerpc/platforms/85xx/bsc913x_qds.c
Normal file
74
arch/powerpc/platforms/85xx/bsc913x_qds.c
Normal file
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* BSC913xQDS Board Setup
|
||||
*
|
||||
* Author:
|
||||
* Harninder Rai <harninder.rai@freescale.com>
|
||||
* Priyanka Jain <Priyanka.Jain@freescale.com>
|
||||
*
|
||||
* Copyright 2014 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/of_platform.h>
|
||||
#include <linux/pci.h>
|
||||
#include <asm/mpic.h>
|
||||
#include <sysdev/fsl_soc.h>
|
||||
#include <asm/udbg.h>
|
||||
|
||||
#include "mpc85xx.h"
|
||||
#include "smp.h"
|
||||
|
||||
void __init bsc913x_qds_pic_init(void)
|
||||
{
|
||||
struct mpic *mpic = mpic_alloc(NULL, 0, MPIC_BIG_ENDIAN |
|
||||
MPIC_SINGLE_DEST_CPU,
|
||||
0, 256, " OpenPIC ");
|
||||
|
||||
if (!mpic)
|
||||
pr_err("bsc913x: Failed to allocate MPIC structure\n");
|
||||
else
|
||||
mpic_init(mpic);
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup the architecture
|
||||
*/
|
||||
static void __init bsc913x_qds_setup_arch(void)
|
||||
{
|
||||
if (ppc_md.progress)
|
||||
ppc_md.progress("bsc913x_qds_setup_arch()", 0);
|
||||
|
||||
#if defined(CONFIG_SMP)
|
||||
mpc85xx_smp_init();
|
||||
#endif
|
||||
|
||||
pr_info("bsc913x board from Freescale Semiconductor\n");
|
||||
}
|
||||
|
||||
machine_device_initcall(bsc9132_qds, mpc85xx_common_publish_devices);
|
||||
|
||||
/*
|
||||
* Called very early, device-tree isn't unflattened
|
||||
*/
|
||||
|
||||
static int __init bsc9132_qds_probe(void)
|
||||
{
|
||||
unsigned long root = of_get_flat_dt_root();
|
||||
|
||||
return of_flat_dt_is_compatible(root, "fsl,bsc9132qds");
|
||||
}
|
||||
|
||||
define_machine(bsc9132_qds) {
|
||||
.name = "BSC9132 QDS",
|
||||
.probe = bsc9132_qds_probe,
|
||||
.setup_arch = bsc913x_qds_setup_arch,
|
||||
.init_IRQ = bsc913x_qds_pic_init,
|
||||
.get_irq = mpic_get_irq,
|
||||
.restart = fsl_rstcr_restart,
|
||||
.calibrate_decr = generic_calibrate_decr,
|
||||
.progress = udbg_progress,
|
||||
};
|
67
arch/powerpc/platforms/85xx/bsc913x_rdb.c
Normal file
67
arch/powerpc/platforms/85xx/bsc913x_rdb.c
Normal file
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* BSC913xRDB Board Setup
|
||||
*
|
||||
* Author: Priyanka Jain <Priyanka.Jain@freescale.com>
|
||||
*
|
||||
* Copyright 2011-2012 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/of_platform.h>
|
||||
#include <linux/pci.h>
|
||||
#include <asm/mpic.h>
|
||||
#include <sysdev/fsl_soc.h>
|
||||
#include <asm/udbg.h>
|
||||
|
||||
#include "mpc85xx.h"
|
||||
|
||||
void __init bsc913x_rdb_pic_init(void)
|
||||
{
|
||||
struct mpic *mpic = mpic_alloc(NULL, 0, MPIC_BIG_ENDIAN |
|
||||
MPIC_SINGLE_DEST_CPU,
|
||||
0, 256, " OpenPIC ");
|
||||
|
||||
if (!mpic)
|
||||
pr_err("bsc913x: Failed to allocate MPIC structure\n");
|
||||
else
|
||||
mpic_init(mpic);
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup the architecture
|
||||
*/
|
||||
static void __init bsc913x_rdb_setup_arch(void)
|
||||
{
|
||||
if (ppc_md.progress)
|
||||
ppc_md.progress("bsc913x_rdb_setup_arch()", 0);
|
||||
|
||||
pr_info("bsc913x board from Freescale Semiconductor\n");
|
||||
}
|
||||
|
||||
machine_device_initcall(bsc9131_rdb, mpc85xx_common_publish_devices);
|
||||
|
||||
/*
|
||||
* Called very early, device-tree isn't unflattened
|
||||
*/
|
||||
|
||||
static int __init bsc9131_rdb_probe(void)
|
||||
{
|
||||
unsigned long root = of_get_flat_dt_root();
|
||||
|
||||
return of_flat_dt_is_compatible(root, "fsl,bsc9131rdb");
|
||||
}
|
||||
|
||||
define_machine(bsc9131_rdb) {
|
||||
.name = "BSC9131 RDB",
|
||||
.probe = bsc9131_rdb_probe,
|
||||
.setup_arch = bsc913x_rdb_setup_arch,
|
||||
.init_IRQ = bsc913x_rdb_pic_init,
|
||||
.get_irq = mpic_get_irq,
|
||||
.restart = fsl_rstcr_restart,
|
||||
.calibrate_decr = generic_calibrate_decr,
|
||||
.progress = udbg_progress,
|
||||
};
|
77
arch/powerpc/platforms/85xx/c293pcie.c
Normal file
77
arch/powerpc/platforms/85xx/c293pcie.c
Normal file
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* C293PCIE Board Setup
|
||||
*
|
||||
* Copyright 2013 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/of_fdt.h>
|
||||
#include <linux/of_platform.h>
|
||||
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/udbg.h>
|
||||
#include <asm/mpic.h>
|
||||
|
||||
#include <sysdev/fsl_soc.h>
|
||||
#include <sysdev/fsl_pci.h>
|
||||
|
||||
#include "mpc85xx.h"
|
||||
|
||||
void __init c293_pcie_pic_init(void)
|
||||
{
|
||||
struct mpic *mpic = mpic_alloc(NULL, 0, MPIC_BIG_ENDIAN |
|
||||
MPIC_SINGLE_DEST_CPU, 0, 256, " OpenPIC ");
|
||||
|
||||
BUG_ON(mpic == NULL);
|
||||
|
||||
mpic_init(mpic);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Setup the architecture
|
||||
*/
|
||||
static void __init c293_pcie_setup_arch(void)
|
||||
{
|
||||
if (ppc_md.progress)
|
||||
ppc_md.progress("c293_pcie_setup_arch()", 0);
|
||||
|
||||
fsl_pci_assign_primary();
|
||||
|
||||
printk(KERN_INFO "C293 PCIE board from Freescale Semiconductor\n");
|
||||
}
|
||||
|
||||
machine_arch_initcall(c293_pcie, mpc85xx_common_publish_devices);
|
||||
|
||||
/*
|
||||
* Called very early, device-tree isn't unflattened
|
||||
*/
|
||||
static int __init c293_pcie_probe(void)
|
||||
{
|
||||
unsigned long root = of_get_flat_dt_root();
|
||||
|
||||
if (of_flat_dt_is_compatible(root, "fsl,C293PCIE"))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
define_machine(c293_pcie) {
|
||||
.name = "C293 PCIE",
|
||||
.probe = c293_pcie_probe,
|
||||
.setup_arch = c293_pcie_setup_arch,
|
||||
.init_IRQ = c293_pcie_pic_init,
|
||||
#ifdef CONFIG_PCI
|
||||
.pcibios_fixup_bus = fsl_pcibios_fixup_bus,
|
||||
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
|
||||
#endif
|
||||
.get_irq = mpic_get_irq,
|
||||
.restart = fsl_rstcr_restart,
|
||||
.calibrate_decr = generic_calibrate_decr,
|
||||
.progress = udbg_progress,
|
||||
};
|
128
arch/powerpc/platforms/85xx/common.c
Normal file
128
arch/powerpc/platforms/85xx/common.c
Normal file
|
@ -0,0 +1,128 @@
|
|||
/*
|
||||
* Routines common to most mpc85xx-based boards.
|
||||
*
|
||||
* This 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/of_irq.h>
|
||||
#include <linux/of_platform.h>
|
||||
|
||||
#include <asm/qe.h>
|
||||
#include <sysdev/cpm2_pic.h>
|
||||
|
||||
#include "mpc85xx.h"
|
||||
|
||||
static const struct of_device_id mpc85xx_common_ids[] __initconst = {
|
||||
{ .type = "soc", },
|
||||
{ .compatible = "soc", },
|
||||
{ .compatible = "simple-bus", },
|
||||
{ .name = "cpm", },
|
||||
{ .name = "localbus", },
|
||||
{ .compatible = "gianfar", },
|
||||
{ .compatible = "fsl,qe", },
|
||||
{ .compatible = "fsl,cpm2", },
|
||||
{ .compatible = "fsl,srio", },
|
||||
/* So that the DMA channel nodes can be probed individually: */
|
||||
{ .compatible = "fsl,eloplus-dma", },
|
||||
/* For the PMC driver */
|
||||
{ .compatible = "fsl,mpc8548-guts", },
|
||||
/* Probably unnecessary? */
|
||||
{ .compatible = "gpio-leds", },
|
||||
/* For all PCI controllers */
|
||||
{ .compatible = "fsl,mpc8540-pci", },
|
||||
{ .compatible = "fsl,mpc8548-pcie", },
|
||||
{ .compatible = "fsl,p1022-pcie", },
|
||||
{ .compatible = "fsl,p1010-pcie", },
|
||||
{ .compatible = "fsl,p1023-pcie", },
|
||||
{ .compatible = "fsl,p4080-pcie", },
|
||||
{ .compatible = "fsl,qoriq-pcie-v2.4", },
|
||||
{ .compatible = "fsl,qoriq-pcie-v2.3", },
|
||||
{ .compatible = "fsl,qoriq-pcie-v2.2", },
|
||||
{},
|
||||
};
|
||||
|
||||
int __init mpc85xx_common_publish_devices(void)
|
||||
{
|
||||
return of_platform_bus_probe(NULL, mpc85xx_common_ids, NULL);
|
||||
}
|
||||
#ifdef CONFIG_CPM2
|
||||
static void cpm2_cascade(unsigned int irq, struct irq_desc *desc)
|
||||
{
|
||||
struct irq_chip *chip = irq_desc_get_chip(desc);
|
||||
int cascade_irq;
|
||||
|
||||
while ((cascade_irq = cpm2_get_irq()) >= 0)
|
||||
generic_handle_irq(cascade_irq);
|
||||
|
||||
chip->irq_eoi(&desc->irq_data);
|
||||
}
|
||||
|
||||
|
||||
void __init mpc85xx_cpm2_pic_init(void)
|
||||
{
|
||||
struct device_node *np;
|
||||
int irq;
|
||||
|
||||
/* 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);
|
||||
if (irq == NO_IRQ) {
|
||||
of_node_put(np);
|
||||
printk(KERN_ERR "PIC init: got no IRQ for cpm cascade\n");
|
||||
return;
|
||||
}
|
||||
|
||||
cpm2_pic_init(np);
|
||||
of_node_put(np);
|
||||
irq_set_chained_handler(irq, cpm2_cascade);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_QUICC_ENGINE
|
||||
void __init mpc85xx_qe_init(void)
|
||||
{
|
||||
struct device_node *np;
|
||||
|
||||
np = of_find_compatible_node(NULL, NULL, "fsl,qe");
|
||||
if (!np) {
|
||||
np = of_find_node_by_name(NULL, "qe");
|
||||
if (!np) {
|
||||
pr_err("%s: Could not find Quicc Engine node\n",
|
||||
__func__);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!of_device_is_available(np)) {
|
||||
of_node_put(np);
|
||||
return;
|
||||
}
|
||||
|
||||
qe_reset();
|
||||
of_node_put(np);
|
||||
|
||||
}
|
||||
|
||||
void __init mpc85xx_qe_par_io_init(void)
|
||||
{
|
||||
struct device_node *np;
|
||||
|
||||
np = of_find_node_by_name(NULL, "par_io");
|
||||
if (np) {
|
||||
struct device_node *ucc;
|
||||
|
||||
par_io_init(np);
|
||||
of_node_put(np);
|
||||
|
||||
for_each_node_by_name(ucc, "ucc")
|
||||
par_io_of_config(ucc);
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
215
arch/powerpc/platforms/85xx/corenet_generic.c
Normal file
215
arch/powerpc/platforms/85xx/corenet_generic.c
Normal file
|
@ -0,0 +1,215 @@
|
|||
/*
|
||||
* Corenet based SoC DS Setup
|
||||
*
|
||||
* Maintained by Kumar Gala (see MAINTAINERS for contact information)
|
||||
*
|
||||
* Copyright 2009-2011 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/kernel.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/kdev_t.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
#include <asm/time.h>
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/pci-bridge.h>
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/ppc-pci.h>
|
||||
#include <mm/mmu_decl.h>
|
||||
#include <asm/prom.h>
|
||||
#include <asm/udbg.h>
|
||||
#include <asm/mpic.h>
|
||||
#include <asm/ehv_pic.h>
|
||||
#include <asm/qe_ic.h>
|
||||
|
||||
#include <linux/of_platform.h>
|
||||
#include <sysdev/fsl_soc.h>
|
||||
#include <sysdev/fsl_pci.h>
|
||||
#include "smp.h"
|
||||
#include "mpc85xx.h"
|
||||
|
||||
void __init corenet_gen_pic_init(void)
|
||||
{
|
||||
struct mpic *mpic;
|
||||
unsigned int flags = MPIC_BIG_ENDIAN | MPIC_SINGLE_DEST_CPU |
|
||||
MPIC_NO_RESET;
|
||||
|
||||
struct device_node *np;
|
||||
|
||||
if (ppc_md.get_irq == mpic_get_coreint_irq)
|
||||
flags |= MPIC_ENABLE_COREINT;
|
||||
|
||||
mpic = mpic_alloc(NULL, 0, flags, 0, 512, " OpenPIC ");
|
||||
BUG_ON(mpic == NULL);
|
||||
|
||||
mpic_init(mpic);
|
||||
|
||||
np = of_find_compatible_node(NULL, NULL, "fsl,qe-ic");
|
||||
if (np) {
|
||||
qe_ic_init(np, 0, qe_ic_cascade_low_mpic,
|
||||
qe_ic_cascade_high_mpic);
|
||||
of_node_put(np);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup the architecture
|
||||
*/
|
||||
void __init corenet_gen_setup_arch(void)
|
||||
{
|
||||
mpc85xx_smp_init();
|
||||
|
||||
swiotlb_detect_4g();
|
||||
|
||||
#if defined(CONFIG_FSL_PCI) && defined(CONFIG_ZONE_DMA32)
|
||||
/*
|
||||
* Inbound windows don't cover the full lower 4 GiB
|
||||
* due to conflicts with PCICSRBAR and outbound windows,
|
||||
* so limit the DMA32 zone to 2 GiB, to allow consistent
|
||||
* allocations to succeed.
|
||||
*/
|
||||
limit_zone_pfn(ZONE_DMA32, 1UL << (31 - PAGE_SHIFT));
|
||||
#endif
|
||||
|
||||
pr_info("%s board\n", ppc_md.name);
|
||||
|
||||
mpc85xx_qe_init();
|
||||
}
|
||||
|
||||
static const struct of_device_id of_device_ids[] = {
|
||||
{
|
||||
.compatible = "simple-bus"
|
||||
},
|
||||
{
|
||||
.compatible = "fsl,srio",
|
||||
},
|
||||
{
|
||||
.compatible = "fsl,p4080-pcie",
|
||||
},
|
||||
{
|
||||
.compatible = "fsl,qoriq-pcie-v2.2",
|
||||
},
|
||||
{
|
||||
.compatible = "fsl,qoriq-pcie-v2.3",
|
||||
},
|
||||
{
|
||||
.compatible = "fsl,qoriq-pcie-v2.4",
|
||||
},
|
||||
{
|
||||
.compatible = "fsl,qoriq-pcie-v3.0",
|
||||
},
|
||||
{
|
||||
.compatible = "fsl,qe",
|
||||
},
|
||||
/* The following two are for the Freescale hypervisor */
|
||||
{
|
||||
.name = "hypervisor",
|
||||
},
|
||||
{
|
||||
.name = "handles",
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
||||
int __init corenet_gen_publish_devices(void)
|
||||
{
|
||||
return of_platform_bus_probe(NULL, of_device_ids, NULL);
|
||||
}
|
||||
|
||||
static const char * const boards[] __initconst = {
|
||||
"fsl,P2041RDB",
|
||||
"fsl,P3041DS",
|
||||
"fsl,OCA4080",
|
||||
"fsl,P4080DS",
|
||||
"fsl,P5020DS",
|
||||
"fsl,P5040DS",
|
||||
"fsl,T2080QDS",
|
||||
"fsl,T2080RDB",
|
||||
"fsl,T2081QDS",
|
||||
"fsl,T4240QDS",
|
||||
"fsl,T4240RDB",
|
||||
"fsl,B4860QDS",
|
||||
"fsl,B4420QDS",
|
||||
"fsl,B4220QDS",
|
||||
"fsl,T1040QDS",
|
||||
"fsl,T1042QDS",
|
||||
"fsl,T1040RDB",
|
||||
"fsl,T1042RDB",
|
||||
"fsl,T1042RDB_PI",
|
||||
"keymile,kmcoge4",
|
||||
NULL
|
||||
};
|
||||
|
||||
/*
|
||||
* Called very early, device-tree isn't unflattened
|
||||
*/
|
||||
static int __init corenet_generic_probe(void)
|
||||
{
|
||||
unsigned long root = of_get_flat_dt_root();
|
||||
char hv_compat[24];
|
||||
int i;
|
||||
#ifdef CONFIG_SMP
|
||||
extern struct smp_ops_t smp_85xx_ops;
|
||||
#endif
|
||||
|
||||
if (of_flat_dt_match(root, boards))
|
||||
return 1;
|
||||
|
||||
/* Check if we're running under the Freescale hypervisor */
|
||||
for (i = 0; boards[i]; i++) {
|
||||
snprintf(hv_compat, sizeof(hv_compat), "%s-hv", boards[i]);
|
||||
if (of_flat_dt_is_compatible(root, hv_compat)) {
|
||||
ppc_md.init_IRQ = ehv_pic_init;
|
||||
|
||||
ppc_md.get_irq = ehv_pic_get_irq;
|
||||
ppc_md.restart = fsl_hv_restart;
|
||||
ppc_md.power_off = fsl_hv_halt;
|
||||
ppc_md.halt = fsl_hv_halt;
|
||||
#ifdef CONFIG_SMP
|
||||
/*
|
||||
* Disable the timebase sync operations because we
|
||||
* can't write to the timebase registers under the
|
||||
* hypervisor.
|
||||
*/
|
||||
smp_85xx_ops.give_timebase = NULL;
|
||||
smp_85xx_ops.take_timebase = NULL;
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
define_machine(corenet_generic) {
|
||||
.name = "CoreNet Generic",
|
||||
.probe = corenet_generic_probe,
|
||||
.setup_arch = corenet_gen_setup_arch,
|
||||
.init_IRQ = corenet_gen_pic_init,
|
||||
#ifdef CONFIG_PCI
|
||||
.pcibios_fixup_bus = fsl_pcibios_fixup_bus,
|
||||
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
|
||||
#endif
|
||||
.get_irq = mpic_get_coreint_irq,
|
||||
.restart = fsl_rstcr_restart,
|
||||
.calibrate_decr = generic_calibrate_decr,
|
||||
.progress = udbg_progress,
|
||||
#ifdef CONFIG_PPC64
|
||||
.power_save = book3e_idle,
|
||||
#else
|
||||
.power_save = e500_idle,
|
||||
#endif
|
||||
};
|
||||
|
||||
machine_arch_initcall(corenet_generic, corenet_gen_publish_devices);
|
||||
|
||||
#ifdef CONFIG_SWIOTLB
|
||||
machine_arch_initcall(corenet_generic, swiotlb_setup_bus_notifier);
|
||||
#endif
|
224
arch/powerpc/platforms/85xx/ge_imp3a.c
Normal file
224
arch/powerpc/platforms/85xx/ge_imp3a.c
Normal file
|
@ -0,0 +1,224 @@
|
|||
/*
|
||||
* GE IMP3A Board Setup
|
||||
*
|
||||
* Author Martyn Welch <martyn.welch@ge.com>
|
||||
*
|
||||
* Copyright 2010 GE Intelligent Platforms Embedded Systems, 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.
|
||||
*
|
||||
* Based on: mpc85xx_ds.c (MPC85xx DS Board Setup)
|
||||
* Copyright 2007 Freescale Semiconductor Inc.
|
||||
*/
|
||||
|
||||
#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/interrupt.h>
|
||||
#include <linux/of_platform.h>
|
||||
|
||||
#include <asm/time.h>
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/pci-bridge.h>
|
||||
#include <mm/mmu_decl.h>
|
||||
#include <asm/prom.h>
|
||||
#include <asm/udbg.h>
|
||||
#include <asm/mpic.h>
|
||||
#include <asm/swiotlb.h>
|
||||
#include <asm/nvram.h>
|
||||
|
||||
#include <sysdev/fsl_soc.h>
|
||||
#include <sysdev/fsl_pci.h>
|
||||
#include "smp.h"
|
||||
|
||||
#include "mpc85xx.h"
|
||||
#include <sysdev/ge/ge_pic.h>
|
||||
|
||||
void __iomem *imp3a_regs;
|
||||
|
||||
void __init ge_imp3a_pic_init(void)
|
||||
{
|
||||
struct mpic *mpic;
|
||||
struct device_node *np;
|
||||
struct device_node *cascade_node = NULL;
|
||||
unsigned long root = of_get_flat_dt_root();
|
||||
|
||||
if (of_flat_dt_is_compatible(root, "fsl,MPC8572DS-CAMP")) {
|
||||
mpic = mpic_alloc(NULL, 0,
|
||||
MPIC_NO_RESET |
|
||||
MPIC_BIG_ENDIAN |
|
||||
MPIC_SINGLE_DEST_CPU,
|
||||
0, 256, " OpenPIC ");
|
||||
} else {
|
||||
mpic = mpic_alloc(NULL, 0,
|
||||
MPIC_BIG_ENDIAN |
|
||||
MPIC_SINGLE_DEST_CPU,
|
||||
0, 256, " OpenPIC ");
|
||||
}
|
||||
|
||||
BUG_ON(mpic == NULL);
|
||||
mpic_init(mpic);
|
||||
/*
|
||||
* There is a simple interrupt handler in the main FPGA, this needs
|
||||
* to be cascaded into the MPIC
|
||||
*/
|
||||
for_each_node_by_type(np, "interrupt-controller")
|
||||
if (of_device_is_compatible(np, "gef,fpga-pic-1.00")) {
|
||||
cascade_node = np;
|
||||
break;
|
||||
}
|
||||
|
||||
if (cascade_node == NULL) {
|
||||
printk(KERN_WARNING "IMP3A: No FPGA PIC\n");
|
||||
return;
|
||||
}
|
||||
|
||||
gef_pic_init(cascade_node);
|
||||
of_node_put(cascade_node);
|
||||
}
|
||||
|
||||
static void ge_imp3a_pci_assign_primary(void)
|
||||
{
|
||||
#ifdef CONFIG_PCI
|
||||
struct device_node *np;
|
||||
struct resource rsrc;
|
||||
|
||||
for_each_node_by_type(np, "pci") {
|
||||
if (of_device_is_compatible(np, "fsl,mpc8540-pci") ||
|
||||
of_device_is_compatible(np, "fsl,mpc8548-pcie") ||
|
||||
of_device_is_compatible(np, "fsl,p2020-pcie")) {
|
||||
of_address_to_resource(np, 0, &rsrc);
|
||||
if ((rsrc.start & 0xfffff) == 0x9000)
|
||||
fsl_pci_primary = np;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup the architecture
|
||||
*/
|
||||
static void __init ge_imp3a_setup_arch(void)
|
||||
{
|
||||
struct device_node *regs;
|
||||
|
||||
if (ppc_md.progress)
|
||||
ppc_md.progress("ge_imp3a_setup_arch()", 0);
|
||||
|
||||
mpc85xx_smp_init();
|
||||
|
||||
ge_imp3a_pci_assign_primary();
|
||||
|
||||
swiotlb_detect_4g();
|
||||
|
||||
/* Remap basic board registers */
|
||||
regs = of_find_compatible_node(NULL, NULL, "ge,imp3a-fpga-regs");
|
||||
if (regs) {
|
||||
imp3a_regs = of_iomap(regs, 0);
|
||||
if (imp3a_regs == NULL)
|
||||
printk(KERN_WARNING "Unable to map board registers\n");
|
||||
of_node_put(regs);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_MMIO_NVRAM)
|
||||
mmio_nvram_init();
|
||||
#endif
|
||||
|
||||
printk(KERN_INFO "GE Intelligent Platforms IMP3A 3U cPCI SBC\n");
|
||||
}
|
||||
|
||||
/* Return the PCB revision */
|
||||
static unsigned int ge_imp3a_get_pcb_rev(void)
|
||||
{
|
||||
unsigned int reg;
|
||||
|
||||
reg = ioread16(imp3a_regs);
|
||||
return (reg >> 8) & 0xff;
|
||||
}
|
||||
|
||||
/* Return the board (software) revision */
|
||||
static unsigned int ge_imp3a_get_board_rev(void)
|
||||
{
|
||||
unsigned int reg;
|
||||
|
||||
reg = ioread16(imp3a_regs + 0x2);
|
||||
return reg & 0xff;
|
||||
}
|
||||
|
||||
/* Return the FPGA revision */
|
||||
static unsigned int ge_imp3a_get_fpga_rev(void)
|
||||
{
|
||||
unsigned int reg;
|
||||
|
||||
reg = ioread16(imp3a_regs + 0x2);
|
||||
return (reg >> 8) & 0xff;
|
||||
}
|
||||
|
||||
/* Return compactPCI Geographical Address */
|
||||
static unsigned int ge_imp3a_get_cpci_geo_addr(void)
|
||||
{
|
||||
unsigned int reg;
|
||||
|
||||
reg = ioread16(imp3a_regs + 0x6);
|
||||
return (reg & 0x0f00) >> 8;
|
||||
}
|
||||
|
||||
/* Return compactPCI System Controller Status */
|
||||
static unsigned int ge_imp3a_get_cpci_is_syscon(void)
|
||||
{
|
||||
unsigned int reg;
|
||||
|
||||
reg = ioread16(imp3a_regs + 0x6);
|
||||
return reg & (1 << 12);
|
||||
}
|
||||
|
||||
static void ge_imp3a_show_cpuinfo(struct seq_file *m)
|
||||
{
|
||||
seq_printf(m, "Vendor\t\t: GE Intelligent Platforms\n");
|
||||
|
||||
seq_printf(m, "Revision\t: %u%c\n", ge_imp3a_get_pcb_rev(),
|
||||
('A' + ge_imp3a_get_board_rev() - 1));
|
||||
|
||||
seq_printf(m, "FPGA Revision\t: %u\n", ge_imp3a_get_fpga_rev());
|
||||
|
||||
seq_printf(m, "cPCI geo. addr\t: %u\n", ge_imp3a_get_cpci_geo_addr());
|
||||
|
||||
seq_printf(m, "cPCI syscon\t: %s\n",
|
||||
ge_imp3a_get_cpci_is_syscon() ? "yes" : "no");
|
||||
}
|
||||
|
||||
/*
|
||||
* Called very early, device-tree isn't unflattened
|
||||
*/
|
||||
static int __init ge_imp3a_probe(void)
|
||||
{
|
||||
unsigned long root = of_get_flat_dt_root();
|
||||
|
||||
return of_flat_dt_is_compatible(root, "ge,IMP3A");
|
||||
}
|
||||
|
||||
machine_arch_initcall(ge_imp3a, mpc85xx_common_publish_devices);
|
||||
|
||||
machine_arch_initcall(ge_imp3a, swiotlb_setup_bus_notifier);
|
||||
|
||||
define_machine(ge_imp3a) {
|
||||
.name = "GE_IMP3A",
|
||||
.probe = ge_imp3a_probe,
|
||||
.setup_arch = ge_imp3a_setup_arch,
|
||||
.init_IRQ = ge_imp3a_pic_init,
|
||||
.show_cpuinfo = ge_imp3a_show_cpuinfo,
|
||||
#ifdef CONFIG_PCI
|
||||
.pcibios_fixup_bus = fsl_pcibios_fixup_bus,
|
||||
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
|
||||
#endif
|
||||
.get_irq = mpic_get_irq,
|
||||
.restart = fsl_rstcr_restart,
|
||||
.calibrate_decr = generic_calibrate_decr,
|
||||
.progress = udbg_progress,
|
||||
};
|
193
arch/powerpc/platforms/85xx/ksi8560.c
Normal file
193
arch/powerpc/platforms/85xx/ksi8560.c
Normal file
|
@ -0,0 +1,193 @@
|
|||
/*
|
||||
* Board setup routines for the Emerson KSI8560
|
||||
*
|
||||
* Author: Alexandr Smirnov <asmirnov@ru.mvista.com>
|
||||
*
|
||||
* Based on mpc85xx_ads.c maintained by Kumar Gala
|
||||
*
|
||||
* 2008 (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/pci.h>
|
||||
#include <linux/kdev_t.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/of_platform.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 <asm/prom.h>
|
||||
|
||||
#include <sysdev/fsl_soc.h>
|
||||
#include <sysdev/fsl_pci.h>
|
||||
|
||||
#include <asm/cpm2.h>
|
||||
#include <sysdev/cpm2_pic.h>
|
||||
|
||||
#include "mpc85xx.h"
|
||||
|
||||
#define KSI8560_CPLD_HVR 0x04 /* Hardware Version Register */
|
||||
#define KSI8560_CPLD_PVR 0x08 /* PLD Version Register */
|
||||
#define KSI8560_CPLD_RCR1 0x30 /* Reset Command Register 1 */
|
||||
|
||||
#define KSI8560_CPLD_RCR1_CPUHR 0x80 /* CPU Hard Reset */
|
||||
|
||||
static void __iomem *cpld_base = NULL;
|
||||
|
||||
static void machine_restart(char *cmd)
|
||||
{
|
||||
if (cpld_base)
|
||||
out_8(cpld_base + KSI8560_CPLD_RCR1, KSI8560_CPLD_RCR1_CPUHR);
|
||||
else
|
||||
printk(KERN_ERR "Can't find CPLD base, hang forever\n");
|
||||
|
||||
for (;;);
|
||||
}
|
||||
|
||||
static void __init ksi8560_pic_init(void)
|
||||
{
|
||||
struct mpic *mpic = mpic_alloc(NULL, 0, MPIC_BIG_ENDIAN,
|
||||
0, 256, " OpenPIC ");
|
||||
BUG_ON(mpic == NULL);
|
||||
mpic_init(mpic);
|
||||
|
||||
mpc85xx_cpm2_pic_init();
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CPM2
|
||||
/*
|
||||
* Setup I/O ports
|
||||
*/
|
||||
struct cpm_pin {
|
||||
int port, pin, flags;
|
||||
};
|
||||
|
||||
static struct cpm_pin __initdata ksi8560_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},
|
||||
|
||||
/* FCC1 */
|
||||
{0, 14, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
|
||||
{0, 15, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
|
||||
{0, 16, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
|
||||
{0, 17, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
|
||||
{0, 18, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
|
||||
{0, 19, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
|
||||
{0, 20, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
|
||||
{0, 21, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
|
||||
{0, 26, CPM_PIN_INPUT | CPM_PIN_SECONDARY},
|
||||
{0, 27, CPM_PIN_INPUT | CPM_PIN_SECONDARY},
|
||||
{0, 28, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY},
|
||||
{0, 29, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY},
|
||||
{0, 30, CPM_PIN_INPUT | CPM_PIN_SECONDARY},
|
||||
{0, 31, CPM_PIN_INPUT | CPM_PIN_SECONDARY},
|
||||
{2, 23, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, /* CLK9 */
|
||||
{2, 22, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, /* CLK10 */
|
||||
|
||||
};
|
||||
|
||||
static void __init init_ioports(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(ksi8560_pins); i++) {
|
||||
struct cpm_pin *pin = &ksi8560_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_FCC1, CPM_CLK9, CPM_CLK_RX);
|
||||
cpm2_clk_setup(CPM_CLK_FCC1, CPM_CLK10, CPM_CLK_TX);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Setup the architecture
|
||||
*/
|
||||
static void __init ksi8560_setup_arch(void)
|
||||
{
|
||||
struct device_node *cpld;
|
||||
|
||||
cpld = of_find_compatible_node(NULL, NULL, "emerson,KSI8560-cpld");
|
||||
if (cpld)
|
||||
cpld_base = of_iomap(cpld, 0);
|
||||
else
|
||||
printk(KERN_ERR "Can't find CPLD in device tree\n");
|
||||
|
||||
if (ppc_md.progress)
|
||||
ppc_md.progress("ksi8560_setup_arch()", 0);
|
||||
|
||||
#ifdef CONFIG_CPM2
|
||||
cpm2_reset();
|
||||
init_ioports();
|
||||
#endif
|
||||
}
|
||||
|
||||
static void ksi8560_show_cpuinfo(struct seq_file *m)
|
||||
{
|
||||
uint pvid, svid, phid1;
|
||||
|
||||
pvid = mfspr(SPRN_PVR);
|
||||
svid = mfspr(SPRN_SVR);
|
||||
|
||||
seq_printf(m, "Vendor\t\t: Emerson Network Power\n");
|
||||
seq_printf(m, "Board\t\t: KSI8560\n");
|
||||
|
||||
if (cpld_base) {
|
||||
seq_printf(m, "Hardware rev\t: %d\n",
|
||||
in_8(cpld_base + KSI8560_CPLD_HVR));
|
||||
seq_printf(m, "CPLD rev\t: %d\n",
|
||||
in_8(cpld_base + KSI8560_CPLD_PVR));
|
||||
} else
|
||||
seq_printf(m, "Unknown Hardware and CPLD revs\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));
|
||||
}
|
||||
|
||||
machine_device_initcall(ksi8560, mpc85xx_common_publish_devices);
|
||||
|
||||
/*
|
||||
* Called very early, device-tree isn't unflattened
|
||||
*/
|
||||
static int __init ksi8560_probe(void)
|
||||
{
|
||||
unsigned long root = of_get_flat_dt_root();
|
||||
|
||||
return of_flat_dt_is_compatible(root, "emerson,KSI8560");
|
||||
}
|
||||
|
||||
define_machine(ksi8560) {
|
||||
.name = "KSI8560",
|
||||
.probe = ksi8560_probe,
|
||||
.setup_arch = ksi8560_setup_arch,
|
||||
.init_IRQ = ksi8560_pic_init,
|
||||
.show_cpuinfo = ksi8560_show_cpuinfo,
|
||||
.get_irq = mpic_get_irq,
|
||||
.restart = machine_restart,
|
||||
.calibrate_decr = generic_calibrate_decr,
|
||||
};
|
85
arch/powerpc/platforms/85xx/mpc8536_ds.c
Normal file
85
arch/powerpc/platforms/85xx/mpc8536_ds.c
Normal file
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* MPC8536 DS Board Setup
|
||||
*
|
||||
* Copyright 2008 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/delay.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/of_platform.h>
|
||||
|
||||
#include <asm/time.h>
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/pci-bridge.h>
|
||||
#include <mm/mmu_decl.h>
|
||||
#include <asm/prom.h>
|
||||
#include <asm/udbg.h>
|
||||
#include <asm/mpic.h>
|
||||
#include <asm/swiotlb.h>
|
||||
|
||||
#include <sysdev/fsl_soc.h>
|
||||
#include <sysdev/fsl_pci.h>
|
||||
|
||||
#include "mpc85xx.h"
|
||||
|
||||
void __init mpc8536_ds_pic_init(void)
|
||||
{
|
||||
struct mpic *mpic = mpic_alloc(NULL, 0, MPIC_BIG_ENDIAN,
|
||||
0, 256, " OpenPIC ");
|
||||
BUG_ON(mpic == NULL);
|
||||
mpic_init(mpic);
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup the architecture
|
||||
*/
|
||||
static void __init mpc8536_ds_setup_arch(void)
|
||||
{
|
||||
if (ppc_md.progress)
|
||||
ppc_md.progress("mpc8536_ds_setup_arch()", 0);
|
||||
|
||||
fsl_pci_assign_primary();
|
||||
|
||||
swiotlb_detect_4g();
|
||||
|
||||
printk("MPC8536 DS board from Freescale Semiconductor\n");
|
||||
}
|
||||
|
||||
machine_arch_initcall(mpc8536_ds, mpc85xx_common_publish_devices);
|
||||
|
||||
machine_arch_initcall(mpc8536_ds, swiotlb_setup_bus_notifier);
|
||||
|
||||
/*
|
||||
* Called very early, device-tree isn't unflattened
|
||||
*/
|
||||
static int __init mpc8536_ds_probe(void)
|
||||
{
|
||||
unsigned long root = of_get_flat_dt_root();
|
||||
|
||||
return of_flat_dt_is_compatible(root, "fsl,mpc8536ds");
|
||||
}
|
||||
|
||||
define_machine(mpc8536_ds) {
|
||||
.name = "MPC8536 DS",
|
||||
.probe = mpc8536_ds_probe,
|
||||
.setup_arch = mpc8536_ds_setup_arch,
|
||||
.init_IRQ = mpc8536_ds_pic_init,
|
||||
#ifdef CONFIG_PCI
|
||||
.pcibios_fixup_bus = fsl_pcibios_fixup_bus,
|
||||
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
|
||||
#endif
|
||||
.get_irq = mpic_get_irq,
|
||||
.restart = fsl_rstcr_restart,
|
||||
.calibrate_decr = generic_calibrate_decr,
|
||||
.progress = udbg_progress,
|
||||
};
|
19
arch/powerpc/platforms/85xx/mpc85xx.h
Normal file
19
arch/powerpc/platforms/85xx/mpc85xx.h
Normal file
|
@ -0,0 +1,19 @@
|
|||
#ifndef MPC85xx_H
|
||||
#define MPC85xx_H
|
||||
extern int mpc85xx_common_publish_devices(void);
|
||||
|
||||
#ifdef CONFIG_CPM2
|
||||
extern void mpc85xx_cpm2_pic_init(void);
|
||||
#else
|
||||
static inline void __init mpc85xx_cpm2_pic_init(void) {}
|
||||
#endif /* CONFIG_CPM2 */
|
||||
|
||||
#ifdef CONFIG_QUICC_ENGINE
|
||||
extern void mpc85xx_qe_init(void);
|
||||
extern void mpc85xx_qe_par_io_init(void);
|
||||
#else
|
||||
static inline void __init mpc85xx_qe_init(void) {}
|
||||
static inline void __init mpc85xx_qe_par_io_init(void) {}
|
||||
#endif
|
||||
|
||||
#endif
|
193
arch/powerpc/platforms/85xx/mpc85xx_ads.c
Normal file
193
arch/powerpc/platforms/85xx/mpc85xx_ads.c
Normal file
|
@ -0,0 +1,193 @@
|
|||
/*
|
||||
* MPC85xx setup and early boot code plus other random bits.
|
||||
*
|
||||
* Maintained by Kumar Gala (see MAINTAINERS for contact information)
|
||||
*
|
||||
* Copyright 2005 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/delay.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/of_platform.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
|
||||
|
||||
#include "mpc85xx.h"
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
static int mpc85xx_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;
|
||||
}
|
||||
#endif /* CONFIG_PCI */
|
||||
|
||||
static void __init mpc85xx_ads_pic_init(void)
|
||||
{
|
||||
struct mpic *mpic = mpic_alloc(NULL, 0, MPIC_BIG_ENDIAN,
|
||||
0, 256, " OpenPIC ");
|
||||
BUG_ON(mpic == NULL);
|
||||
mpic_init(mpic);
|
||||
|
||||
mpc85xx_cpm2_pic_init();
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup the architecture
|
||||
*/
|
||||
#ifdef CONFIG_CPM2
|
||||
struct cpm_pin {
|
||||
int port, pin, flags;
|
||||
};
|
||||
|
||||
static const struct cpm_pin mpc8560_ads_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 */
|
||||
{2, 12, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
|
||||
{2, 13, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
|
||||
{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, 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_PRIMARY}, /* CLK16 */
|
||||
{2, 17, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, /* CLK15 */
|
||||
{2, 27, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
|
||||
};
|
||||
|
||||
static void __init init_ioports(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(mpc8560_ads_pins); i++) {
|
||||
const struct cpm_pin *pin = &mpc8560_ads_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 mpc85xx_ads_setup_arch(void)
|
||||
{
|
||||
if (ppc_md.progress)
|
||||
ppc_md.progress("mpc85xx_ads_setup_arch()", 0);
|
||||
|
||||
#ifdef CONFIG_CPM2
|
||||
cpm2_reset();
|
||||
init_ioports();
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
ppc_md.pci_exclude_device = mpc85xx_exclude_device;
|
||||
#endif
|
||||
|
||||
fsl_pci_assign_primary();
|
||||
}
|
||||
|
||||
static void mpc85xx_ads_show_cpuinfo(struct seq_file *m)
|
||||
{
|
||||
uint pvid, svid, phid1;
|
||||
|
||||
pvid = mfspr(SPRN_PVR);
|
||||
svid = mfspr(SPRN_SVR);
|
||||
|
||||
seq_printf(m, "Vendor\t\t: Freescale Semiconductor\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));
|
||||
}
|
||||
|
||||
machine_arch_initcall(mpc85xx_ads, mpc85xx_common_publish_devices);
|
||||
|
||||
/*
|
||||
* Called very early, device-tree isn't unflattened
|
||||
*/
|
||||
static int __init mpc85xx_ads_probe(void)
|
||||
{
|
||||
unsigned long root = of_get_flat_dt_root();
|
||||
|
||||
return of_flat_dt_is_compatible(root, "MPC85xxADS");
|
||||
}
|
||||
|
||||
define_machine(mpc85xx_ads) {
|
||||
.name = "MPC85xx ADS",
|
||||
.probe = mpc85xx_ads_probe,
|
||||
.setup_arch = mpc85xx_ads_setup_arch,
|
||||
.init_IRQ = mpc85xx_ads_pic_init,
|
||||
.show_cpuinfo = mpc85xx_ads_show_cpuinfo,
|
||||
.get_irq = mpic_get_irq,
|
||||
.restart = fsl_rstcr_restart,
|
||||
.calibrate_decr = generic_calibrate_decr,
|
||||
.progress = udbg_progress,
|
||||
};
|
394
arch/powerpc/platforms/85xx/mpc85xx_cds.c
Normal file
394
arch/powerpc/platforms/85xx/mpc85xx_cds.c
Normal file
|
@ -0,0 +1,394 @@
|
|||
/*
|
||||
* MPC85xx setup and early boot code plus other random bits.
|
||||
*
|
||||
* Maintained by Kumar Gala (see MAINTAINERS for contact information)
|
||||
*
|
||||
* Copyright 2005, 2011-2012 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/init.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/reboot.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/kdev_t.h>
|
||||
#include <linux/major.h>
|
||||
#include <linux/console.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/initrd.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/fsl_devices.h>
|
||||
#include <linux/of_platform.h>
|
||||
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/page.h>
|
||||
#include <linux/atomic.h>
|
||||
#include <asm/time.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/ipic.h>
|
||||
#include <asm/pci-bridge.h>
|
||||
#include <asm/irq.h>
|
||||
#include <mm/mmu_decl.h>
|
||||
#include <asm/prom.h>
|
||||
#include <asm/udbg.h>
|
||||
#include <asm/mpic.h>
|
||||
#include <asm/i8259.h>
|
||||
|
||||
#include <sysdev/fsl_soc.h>
|
||||
#include <sysdev/fsl_pci.h>
|
||||
|
||||
#include "mpc85xx.h"
|
||||
|
||||
/*
|
||||
* The CDS board contains an FPGA/CPLD called "Cadmus", which collects
|
||||
* various logic and performs system control functions.
|
||||
* Here is the FPGA/CPLD register map.
|
||||
*/
|
||||
struct cadmus_reg {
|
||||
u8 cm_ver; /* Board version */
|
||||
u8 cm_csr; /* General control/status */
|
||||
u8 cm_rst; /* Reset control */
|
||||
u8 cm_hsclk; /* High speed clock */
|
||||
u8 cm_hsxclk; /* High speed clock extended */
|
||||
u8 cm_led; /* LED data */
|
||||
u8 cm_pci; /* PCI control/status */
|
||||
u8 cm_dma; /* DMA control */
|
||||
u8 res[248]; /* Total 256 bytes */
|
||||
};
|
||||
|
||||
static struct cadmus_reg *cadmus;
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
|
||||
#define ARCADIA_HOST_BRIDGE_IDSEL 17
|
||||
#define ARCADIA_2ND_BRIDGE_IDSEL 3
|
||||
|
||||
static int mpc85xx_exclude_device(struct pci_controller *hose,
|
||||
u_char bus, u_char devfn)
|
||||
{
|
||||
/* We explicitly do not go past the Tundra 320 Bridge */
|
||||
if ((bus == 1) && (PCI_SLOT(devfn) == ARCADIA_2ND_BRIDGE_IDSEL))
|
||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
if ((bus == 0) && (PCI_SLOT(devfn) == ARCADIA_2ND_BRIDGE_IDSEL))
|
||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
else
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
static void mpc85xx_cds_restart(char *cmd)
|
||||
{
|
||||
struct pci_dev *dev;
|
||||
u_char tmp;
|
||||
|
||||
if ((dev = pci_get_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686,
|
||||
NULL))) {
|
||||
|
||||
/* Use the VIA Super Southbridge to force a PCI reset */
|
||||
pci_read_config_byte(dev, 0x47, &tmp);
|
||||
pci_write_config_byte(dev, 0x47, tmp | 1);
|
||||
|
||||
/* Flush the outbound PCI write queues */
|
||||
pci_read_config_byte(dev, 0x47, &tmp);
|
||||
|
||||
/*
|
||||
* At this point, the harware reset should have triggered.
|
||||
* However, if it doesn't work for some mysterious reason,
|
||||
* just fall through to the default reset below.
|
||||
*/
|
||||
|
||||
pci_dev_put(dev);
|
||||
}
|
||||
|
||||
/*
|
||||
* If we can't find the VIA chip (maybe the P2P bridge is disabled)
|
||||
* or the VIA chip reset didn't work, just use the default reset.
|
||||
*/
|
||||
fsl_rstcr_restart(NULL);
|
||||
}
|
||||
|
||||
static void __init mpc85xx_cds_pci_irq_fixup(struct pci_dev *dev)
|
||||
{
|
||||
u_char c;
|
||||
if (dev->vendor == PCI_VENDOR_ID_VIA) {
|
||||
switch (dev->device) {
|
||||
case PCI_DEVICE_ID_VIA_82C586_1:
|
||||
/*
|
||||
* U-Boot does not set the enable bits
|
||||
* for the IDE device. Force them on here.
|
||||
*/
|
||||
pci_read_config_byte(dev, 0x40, &c);
|
||||
c |= 0x03; /* IDE: Chip Enable Bits */
|
||||
pci_write_config_byte(dev, 0x40, c);
|
||||
|
||||
/*
|
||||
* Since only primary interface works, force the
|
||||
* IDE function to standard primary IDE interrupt
|
||||
* w/ 8259 offset
|
||||
*/
|
||||
dev->irq = 14;
|
||||
pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
|
||||
break;
|
||||
/*
|
||||
* Force legacy USB interrupt routing
|
||||
*/
|
||||
case PCI_DEVICE_ID_VIA_82C586_2:
|
||||
/* There are two USB controllers.
|
||||
* Identify them by functon number
|
||||
*/
|
||||
if (PCI_FUNC(dev->devfn) == 3)
|
||||
dev->irq = 11;
|
||||
else
|
||||
dev->irq = 10;
|
||||
pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void skip_fake_bridge(struct pci_dev *dev)
|
||||
{
|
||||
/* Make it an error to skip the fake bridge
|
||||
* in pci_setup_device() in probe.c */
|
||||
dev->hdr_type = 0x7f;
|
||||
}
|
||||
DECLARE_PCI_FIXUP_EARLY(0x1957, 0x3fff, skip_fake_bridge);
|
||||
DECLARE_PCI_FIXUP_EARLY(0x3fff, 0x1957, skip_fake_bridge);
|
||||
DECLARE_PCI_FIXUP_EARLY(0xff3f, 0x5719, skip_fake_bridge);
|
||||
|
||||
#define PCI_DEVICE_ID_IDT_TSI310 0x01a7
|
||||
|
||||
/*
|
||||
* Fix Tsi310 PCI-X bridge resource.
|
||||
* Force the bridge to open a window from 0x0000-0x1fff in PCI I/O space.
|
||||
* This allows legacy I/O(i8259, etc) on the VIA southbridge to be accessed.
|
||||
*/
|
||||
void mpc85xx_cds_fixup_bus(struct pci_bus *bus)
|
||||
{
|
||||
struct pci_dev *dev = bus->self;
|
||||
struct resource *res = bus->resource[0];
|
||||
|
||||
if (dev != NULL &&
|
||||
dev->vendor == PCI_VENDOR_ID_IBM &&
|
||||
dev->device == PCI_DEVICE_ID_IDT_TSI310) {
|
||||
if (res) {
|
||||
res->start = 0;
|
||||
res->end = 0x1fff;
|
||||
res->flags = IORESOURCE_IO;
|
||||
pr_info("mpc85xx_cds: PCI bridge resource fixup applied\n");
|
||||
pr_info("mpc85xx_cds: %pR\n", res);
|
||||
}
|
||||
}
|
||||
|
||||
fsl_pcibios_fixup_bus(bus);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PPC_I8259
|
||||
static void mpc85xx_8259_cascade_handler(unsigned int irq,
|
||||
struct irq_desc *desc)
|
||||
{
|
||||
unsigned int cascade_irq = i8259_irq();
|
||||
|
||||
if (cascade_irq != NO_IRQ)
|
||||
/* handle an interrupt from the 8259 */
|
||||
generic_handle_irq(cascade_irq);
|
||||
|
||||
/* check for any interrupts from the shared IRQ line */
|
||||
handle_fasteoi_irq(irq, desc);
|
||||
}
|
||||
|
||||
static irqreturn_t mpc85xx_8259_cascade_action(int irq, void *dev_id)
|
||||
{
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static struct irqaction mpc85xxcds_8259_irqaction = {
|
||||
.handler = mpc85xx_8259_cascade_action,
|
||||
.flags = IRQF_SHARED | IRQF_NO_THREAD,
|
||||
.name = "8259 cascade",
|
||||
};
|
||||
#endif /* PPC_I8259 */
|
||||
#endif /* CONFIG_PCI */
|
||||
|
||||
static void __init mpc85xx_cds_pic_init(void)
|
||||
{
|
||||
struct mpic *mpic;
|
||||
mpic = mpic_alloc(NULL, 0, MPIC_BIG_ENDIAN,
|
||||
0, 256, " OpenPIC ");
|
||||
BUG_ON(mpic == NULL);
|
||||
mpic_init(mpic);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_PPC_I8259) && defined(CONFIG_PCI)
|
||||
static int mpc85xx_cds_8259_attach(void)
|
||||
{
|
||||
int ret;
|
||||
struct device_node *np = NULL;
|
||||
struct device_node *cascade_node = NULL;
|
||||
int cascade_irq;
|
||||
|
||||
/* Initialize the i8259 controller */
|
||||
for_each_node_by_type(np, "interrupt-controller")
|
||||
if (of_device_is_compatible(np, "chrp,iic")) {
|
||||
cascade_node = np;
|
||||
break;
|
||||
}
|
||||
|
||||
if (cascade_node == NULL) {
|
||||
printk(KERN_DEBUG "Could not find i8259 PIC\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
cascade_irq = irq_of_parse_and_map(cascade_node, 0);
|
||||
if (cascade_irq == NO_IRQ) {
|
||||
printk(KERN_ERR "Failed to map cascade interrupt\n");
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
i8259_init(cascade_node, 0);
|
||||
of_node_put(cascade_node);
|
||||
|
||||
/*
|
||||
* Hook the interrupt to make sure desc->action is never NULL.
|
||||
* This is required to ensure that the interrupt does not get
|
||||
* disabled when the last user of the shared IRQ line frees their
|
||||
* interrupt.
|
||||
*/
|
||||
if ((ret = setup_irq(cascade_irq, &mpc85xxcds_8259_irqaction))) {
|
||||
printk(KERN_ERR "Failed to setup cascade interrupt\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Success. Connect our low-level cascade handler. */
|
||||
irq_set_handler(cascade_irq, mpc85xx_8259_cascade_handler);
|
||||
|
||||
return 0;
|
||||
}
|
||||
machine_device_initcall(mpc85xx_cds, mpc85xx_cds_8259_attach);
|
||||
|
||||
#endif /* CONFIG_PPC_I8259 */
|
||||
|
||||
static void mpc85xx_cds_pci_assign_primary(void)
|
||||
{
|
||||
#ifdef CONFIG_PCI
|
||||
struct device_node *np;
|
||||
|
||||
if (fsl_pci_primary)
|
||||
return;
|
||||
|
||||
/*
|
||||
* MPC85xx_CDS has ISA bridge but unfortunately there is no
|
||||
* isa node in device tree. We now looking for i8259 node as
|
||||
* a workaround for such a broken device tree. This routine
|
||||
* is for complying to all device trees.
|
||||
*/
|
||||
np = of_find_node_by_name(NULL, "i8259");
|
||||
while ((fsl_pci_primary = of_get_parent(np))) {
|
||||
of_node_put(np);
|
||||
np = fsl_pci_primary;
|
||||
|
||||
if ((of_device_is_compatible(np, "fsl,mpc8540-pci") ||
|
||||
of_device_is_compatible(np, "fsl,mpc8548-pcie")) &&
|
||||
of_device_is_available(np))
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup the architecture
|
||||
*/
|
||||
static void __init mpc85xx_cds_setup_arch(void)
|
||||
{
|
||||
struct device_node *np;
|
||||
int cds_pci_slot;
|
||||
|
||||
if (ppc_md.progress)
|
||||
ppc_md.progress("mpc85xx_cds_setup_arch()", 0);
|
||||
|
||||
np = of_find_compatible_node(NULL, NULL, "fsl,mpc8548cds-fpga");
|
||||
if (!np) {
|
||||
pr_err("Could not find FPGA node.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
cadmus = of_iomap(np, 0);
|
||||
of_node_put(np);
|
||||
if (!cadmus) {
|
||||
pr_err("Fail to map FPGA area.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (ppc_md.progress) {
|
||||
char buf[40];
|
||||
cds_pci_slot = ((in_8(&cadmus->cm_csr) >> 6) & 0x3) + 1;
|
||||
snprintf(buf, 40, "CDS Version = 0x%x in slot %d\n",
|
||||
in_8(&cadmus->cm_ver), cds_pci_slot);
|
||||
ppc_md.progress(buf, 0);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
ppc_md.pci_irq_fixup = mpc85xx_cds_pci_irq_fixup;
|
||||
ppc_md.pci_exclude_device = mpc85xx_exclude_device;
|
||||
#endif
|
||||
|
||||
mpc85xx_cds_pci_assign_primary();
|
||||
fsl_pci_assign_primary();
|
||||
}
|
||||
|
||||
static void mpc85xx_cds_show_cpuinfo(struct seq_file *m)
|
||||
{
|
||||
uint pvid, svid, phid1;
|
||||
|
||||
pvid = mfspr(SPRN_PVR);
|
||||
svid = mfspr(SPRN_SVR);
|
||||
|
||||
seq_printf(m, "Vendor\t\t: Freescale Semiconductor\n");
|
||||
seq_printf(m, "Machine\t\t: MPC85xx CDS (0x%x)\n",
|
||||
in_8(&cadmus->cm_ver));
|
||||
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));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Called very early, device-tree isn't unflattened
|
||||
*/
|
||||
static int __init mpc85xx_cds_probe(void)
|
||||
{
|
||||
unsigned long root = of_get_flat_dt_root();
|
||||
|
||||
return of_flat_dt_is_compatible(root, "MPC85xxCDS");
|
||||
}
|
||||
|
||||
machine_arch_initcall(mpc85xx_cds, mpc85xx_common_publish_devices);
|
||||
|
||||
define_machine(mpc85xx_cds) {
|
||||
.name = "MPC85xx CDS",
|
||||
.probe = mpc85xx_cds_probe,
|
||||
.setup_arch = mpc85xx_cds_setup_arch,
|
||||
.init_IRQ = mpc85xx_cds_pic_init,
|
||||
.show_cpuinfo = mpc85xx_cds_show_cpuinfo,
|
||||
.get_irq = mpic_get_irq,
|
||||
#ifdef CONFIG_PCI
|
||||
.restart = mpc85xx_cds_restart,
|
||||
.pcibios_fixup_bus = mpc85xx_cds_fixup_bus,
|
||||
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
|
||||
#else
|
||||
.restart = fsl_rstcr_restart,
|
||||
#endif
|
||||
.calibrate_decr = generic_calibrate_decr,
|
||||
.progress = udbg_progress,
|
||||
};
|
248
arch/powerpc/platforms/85xx/mpc85xx_ds.c
Normal file
248
arch/powerpc/platforms/85xx/mpc85xx_ds.c
Normal file
|
@ -0,0 +1,248 @@
|
|||
/*
|
||||
* MPC85xx DS Board Setup
|
||||
*
|
||||
* Author Xianghua Xiao (x.xiao@freescale.com)
|
||||
* Roy Zang <tie-fei.zang@freescale.com>
|
||||
* - Add PCI/PCI Exprees support
|
||||
* Copyright 2007 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/delay.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/of_platform.h>
|
||||
|
||||
#include <asm/time.h>
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/pci-bridge.h>
|
||||
#include <mm/mmu_decl.h>
|
||||
#include <asm/prom.h>
|
||||
#include <asm/udbg.h>
|
||||
#include <asm/mpic.h>
|
||||
#include <asm/i8259.h>
|
||||
#include <asm/swiotlb.h>
|
||||
|
||||
#include <sysdev/fsl_soc.h>
|
||||
#include <sysdev/fsl_pci.h>
|
||||
#include "smp.h"
|
||||
|
||||
#include "mpc85xx.h"
|
||||
|
||||
#undef DEBUG
|
||||
|
||||
#ifdef DEBUG
|
||||
#define DBG(fmt, args...) printk(KERN_ERR "%s: " fmt, __func__, ## args)
|
||||
#else
|
||||
#define DBG(fmt, args...)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PPC_I8259
|
||||
static void mpc85xx_8259_cascade(unsigned int irq, struct irq_desc *desc)
|
||||
{
|
||||
struct irq_chip *chip = irq_desc_get_chip(desc);
|
||||
unsigned int cascade_irq = i8259_irq();
|
||||
|
||||
if (cascade_irq != NO_IRQ) {
|
||||
generic_handle_irq(cascade_irq);
|
||||
}
|
||||
chip->irq_eoi(&desc->irq_data);
|
||||
}
|
||||
#endif /* CONFIG_PPC_I8259 */
|
||||
|
||||
void __init mpc85xx_ds_pic_init(void)
|
||||
{
|
||||
struct mpic *mpic;
|
||||
#ifdef CONFIG_PPC_I8259
|
||||
struct device_node *np;
|
||||
struct device_node *cascade_node = NULL;
|
||||
int cascade_irq;
|
||||
#endif
|
||||
unsigned long root = of_get_flat_dt_root();
|
||||
|
||||
if (of_flat_dt_is_compatible(root, "fsl,MPC8572DS-CAMP")) {
|
||||
mpic = mpic_alloc(NULL, 0,
|
||||
MPIC_NO_RESET |
|
||||
MPIC_BIG_ENDIAN |
|
||||
MPIC_SINGLE_DEST_CPU,
|
||||
0, 256, " OpenPIC ");
|
||||
} else {
|
||||
mpic = mpic_alloc(NULL, 0,
|
||||
MPIC_BIG_ENDIAN |
|
||||
MPIC_SINGLE_DEST_CPU,
|
||||
0, 256, " OpenPIC ");
|
||||
}
|
||||
|
||||
BUG_ON(mpic == NULL);
|
||||
mpic_init(mpic);
|
||||
|
||||
#ifdef CONFIG_PPC_I8259
|
||||
/* Initialize the i8259 controller */
|
||||
for_each_node_by_type(np, "interrupt-controller")
|
||||
if (of_device_is_compatible(np, "chrp,iic")) {
|
||||
cascade_node = np;
|
||||
break;
|
||||
}
|
||||
|
||||
if (cascade_node == NULL) {
|
||||
printk(KERN_DEBUG "Could not find i8259 PIC\n");
|
||||
return;
|
||||
}
|
||||
|
||||
cascade_irq = irq_of_parse_and_map(cascade_node, 0);
|
||||
if (cascade_irq == NO_IRQ) {
|
||||
printk(KERN_ERR "Failed to map cascade interrupt\n");
|
||||
return;
|
||||
}
|
||||
|
||||
DBG("mpc85xxds: cascade mapped to irq %d\n", cascade_irq);
|
||||
|
||||
i8259_init(cascade_node, 0);
|
||||
of_node_put(cascade_node);
|
||||
|
||||
irq_set_chained_handler(cascade_irq, mpc85xx_8259_cascade);
|
||||
#endif /* CONFIG_PPC_I8259 */
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
extern int uli_exclude_device(struct pci_controller *hose,
|
||||
u_char bus, u_char devfn);
|
||||
|
||||
static struct device_node *pci_with_uli;
|
||||
|
||||
static int mpc85xx_exclude_device(struct pci_controller *hose,
|
||||
u_char bus, u_char devfn)
|
||||
{
|
||||
if (hose->dn == pci_with_uli)
|
||||
return uli_exclude_device(hose, bus, devfn);
|
||||
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
#endif /* CONFIG_PCI */
|
||||
|
||||
static void __init mpc85xx_ds_uli_init(void)
|
||||
{
|
||||
#ifdef CONFIG_PCI
|
||||
struct device_node *node;
|
||||
|
||||
/* See if we have a ULI under the primary */
|
||||
|
||||
node = of_find_node_by_name(NULL, "uli1575");
|
||||
while ((pci_with_uli = of_get_parent(node))) {
|
||||
of_node_put(node);
|
||||
node = pci_with_uli;
|
||||
|
||||
if (pci_with_uli == fsl_pci_primary) {
|
||||
ppc_md.pci_exclude_device = mpc85xx_exclude_device;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup the architecture
|
||||
*/
|
||||
static void __init mpc85xx_ds_setup_arch(void)
|
||||
{
|
||||
if (ppc_md.progress)
|
||||
ppc_md.progress("mpc85xx_ds_setup_arch()", 0);
|
||||
|
||||
swiotlb_detect_4g();
|
||||
fsl_pci_assign_primary();
|
||||
mpc85xx_ds_uli_init();
|
||||
mpc85xx_smp_init();
|
||||
|
||||
printk("MPC85xx DS board from Freescale Semiconductor\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* Called very early, device-tree isn't unflattened
|
||||
*/
|
||||
static int __init mpc8544_ds_probe(void)
|
||||
{
|
||||
unsigned long root = of_get_flat_dt_root();
|
||||
|
||||
return !!of_flat_dt_is_compatible(root, "MPC8544DS");
|
||||
}
|
||||
|
||||
machine_arch_initcall(mpc8544_ds, mpc85xx_common_publish_devices);
|
||||
machine_arch_initcall(mpc8572_ds, mpc85xx_common_publish_devices);
|
||||
machine_arch_initcall(p2020_ds, mpc85xx_common_publish_devices);
|
||||
|
||||
machine_arch_initcall(mpc8544_ds, swiotlb_setup_bus_notifier);
|
||||
machine_arch_initcall(mpc8572_ds, swiotlb_setup_bus_notifier);
|
||||
machine_arch_initcall(p2020_ds, swiotlb_setup_bus_notifier);
|
||||
|
||||
/*
|
||||
* Called very early, device-tree isn't unflattened
|
||||
*/
|
||||
static int __init mpc8572_ds_probe(void)
|
||||
{
|
||||
unsigned long root = of_get_flat_dt_root();
|
||||
|
||||
return !!of_flat_dt_is_compatible(root, "fsl,MPC8572DS");
|
||||
}
|
||||
|
||||
/*
|
||||
* Called very early, device-tree isn't unflattened
|
||||
*/
|
||||
static int __init p2020_ds_probe(void)
|
||||
{
|
||||
unsigned long root = of_get_flat_dt_root();
|
||||
|
||||
return !!of_flat_dt_is_compatible(root, "fsl,P2020DS");
|
||||
}
|
||||
|
||||
define_machine(mpc8544_ds) {
|
||||
.name = "MPC8544 DS",
|
||||
.probe = mpc8544_ds_probe,
|
||||
.setup_arch = mpc85xx_ds_setup_arch,
|
||||
.init_IRQ = mpc85xx_ds_pic_init,
|
||||
#ifdef CONFIG_PCI
|
||||
.pcibios_fixup_bus = fsl_pcibios_fixup_bus,
|
||||
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
|
||||
#endif
|
||||
.get_irq = mpic_get_irq,
|
||||
.restart = fsl_rstcr_restart,
|
||||
.calibrate_decr = generic_calibrate_decr,
|
||||
.progress = udbg_progress,
|
||||
};
|
||||
|
||||
define_machine(mpc8572_ds) {
|
||||
.name = "MPC8572 DS",
|
||||
.probe = mpc8572_ds_probe,
|
||||
.setup_arch = mpc85xx_ds_setup_arch,
|
||||
.init_IRQ = mpc85xx_ds_pic_init,
|
||||
#ifdef CONFIG_PCI
|
||||
.pcibios_fixup_bus = fsl_pcibios_fixup_bus,
|
||||
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
|
||||
#endif
|
||||
.get_irq = mpic_get_irq,
|
||||
.restart = fsl_rstcr_restart,
|
||||
.calibrate_decr = generic_calibrate_decr,
|
||||
.progress = udbg_progress,
|
||||
};
|
||||
|
||||
define_machine(p2020_ds) {
|
||||
.name = "P2020 DS",
|
||||
.probe = p2020_ds_probe,
|
||||
.setup_arch = mpc85xx_ds_setup_arch,
|
||||
.init_IRQ = mpc85xx_ds_pic_init,
|
||||
#ifdef CONFIG_PCI
|
||||
.pcibios_fixup_bus = fsl_pcibios_fixup_bus,
|
||||
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
|
||||
#endif
|
||||
.get_irq = mpic_get_irq,
|
||||
.restart = fsl_rstcr_restart,
|
||||
.calibrate_decr = generic_calibrate_decr,
|
||||
.progress = udbg_progress,
|
||||
};
|
443
arch/powerpc/platforms/85xx/mpc85xx_mds.c
Normal file
443
arch/powerpc/platforms/85xx/mpc85xx_mds.c
Normal file
|
@ -0,0 +1,443 @@
|
|||
/*
|
||||
* Copyright (C) 2006-2010, 2012-2013 Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Author: Andy Fleming <afleming@freescale.com>
|
||||
*
|
||||
* Based on 83xx/mpc8360e_pb.c by:
|
||||
* Li Yang <LeoLi@freescale.com>
|
||||
* Yin Olivia <Hong-hua.Yin@freescale.com>
|
||||
*
|
||||
* Description:
|
||||
* MPC85xx MDS board specific routines.
|
||||
*
|
||||
* 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/init.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/reboot.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/kdev_t.h>
|
||||
#include <linux/major.h>
|
||||
#include <linux/console.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/initrd.h>
|
||||
#include <linux/fsl_devices.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/phy.h>
|
||||
#include <linux/memblock.h>
|
||||
|
||||
#include <linux/atomic.h>
|
||||
#include <asm/time.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/pci-bridge.h>
|
||||
#include <asm/irq.h>
|
||||
#include <mm/mmu_decl.h>
|
||||
#include <asm/prom.h>
|
||||
#include <asm/udbg.h>
|
||||
#include <sysdev/fsl_soc.h>
|
||||
#include <sysdev/fsl_pci.h>
|
||||
#include <sysdev/simple_gpio.h>
|
||||
#include <asm/qe.h>
|
||||
#include <asm/qe_ic.h>
|
||||
#include <asm/mpic.h>
|
||||
#include <asm/swiotlb.h>
|
||||
#include <asm/fsl_guts.h>
|
||||
#include "smp.h"
|
||||
|
||||
#include "mpc85xx.h"
|
||||
|
||||
#undef DEBUG
|
||||
#ifdef DEBUG
|
||||
#define DBG(fmt...) udbg_printf(fmt)
|
||||
#else
|
||||
#define DBG(fmt...)
|
||||
#endif
|
||||
|
||||
#define MV88E1111_SCR 0x10
|
||||
#define MV88E1111_SCR_125CLK 0x0010
|
||||
static int mpc8568_fixup_125_clock(struct phy_device *phydev)
|
||||
{
|
||||
int scr;
|
||||
int err;
|
||||
|
||||
/* Workaround for the 125 CLK Toggle */
|
||||
scr = phy_read(phydev, MV88E1111_SCR);
|
||||
|
||||
if (scr < 0)
|
||||
return scr;
|
||||
|
||||
err = phy_write(phydev, MV88E1111_SCR, scr & ~(MV88E1111_SCR_125CLK));
|
||||
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = phy_write(phydev, MII_BMCR, BMCR_RESET);
|
||||
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
scr = phy_read(phydev, MV88E1111_SCR);
|
||||
|
||||
if (scr < 0)
|
||||
return scr;
|
||||
|
||||
err = phy_write(phydev, MV88E1111_SCR, scr | 0x0008);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int mpc8568_mds_phy_fixups(struct phy_device *phydev)
|
||||
{
|
||||
int temp;
|
||||
int err;
|
||||
|
||||
/* Errata */
|
||||
err = phy_write(phydev,29, 0x0006);
|
||||
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
temp = phy_read(phydev, 30);
|
||||
|
||||
if (temp < 0)
|
||||
return temp;
|
||||
|
||||
temp = (temp & (~0x8000)) | 0x4000;
|
||||
err = phy_write(phydev,30, temp);
|
||||
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = phy_write(phydev,29, 0x000a);
|
||||
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
temp = phy_read(phydev, 30);
|
||||
|
||||
if (temp < 0)
|
||||
return temp;
|
||||
|
||||
temp = phy_read(phydev, 30);
|
||||
|
||||
if (temp < 0)
|
||||
return temp;
|
||||
|
||||
temp &= ~0x0020;
|
||||
|
||||
err = phy_write(phydev,30,temp);
|
||||
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* Disable automatic MDI/MDIX selection */
|
||||
temp = phy_read(phydev, 16);
|
||||
|
||||
if (temp < 0)
|
||||
return temp;
|
||||
|
||||
temp &= ~0x0060;
|
||||
err = phy_write(phydev,16,temp);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/* ************************************************************************
|
||||
*
|
||||
* Setup the architecture
|
||||
*
|
||||
*/
|
||||
#ifdef CONFIG_QUICC_ENGINE
|
||||
static void __init mpc85xx_mds_reset_ucc_phys(void)
|
||||
{
|
||||
struct device_node *np;
|
||||
static u8 __iomem *bcsr_regs;
|
||||
|
||||
/* Map BCSR area */
|
||||
np = of_find_node_by_name(NULL, "bcsr");
|
||||
if (!np)
|
||||
return;
|
||||
|
||||
bcsr_regs = of_iomap(np, 0);
|
||||
of_node_put(np);
|
||||
if (!bcsr_regs)
|
||||
return;
|
||||
|
||||
if (machine_is(mpc8568_mds)) {
|
||||
#define BCSR_UCC1_GETH_EN (0x1 << 7)
|
||||
#define BCSR_UCC2_GETH_EN (0x1 << 7)
|
||||
#define BCSR_UCC1_MODE_MSK (0x3 << 4)
|
||||
#define BCSR_UCC2_MODE_MSK (0x3 << 0)
|
||||
|
||||
/* Turn off UCC1 & UCC2 */
|
||||
clrbits8(&bcsr_regs[8], BCSR_UCC1_GETH_EN);
|
||||
clrbits8(&bcsr_regs[9], BCSR_UCC2_GETH_EN);
|
||||
|
||||
/* Mode is RGMII, all bits clear */
|
||||
clrbits8(&bcsr_regs[11], BCSR_UCC1_MODE_MSK |
|
||||
BCSR_UCC2_MODE_MSK);
|
||||
|
||||
/* Turn UCC1 & UCC2 on */
|
||||
setbits8(&bcsr_regs[8], BCSR_UCC1_GETH_EN);
|
||||
setbits8(&bcsr_regs[9], BCSR_UCC2_GETH_EN);
|
||||
} else if (machine_is(mpc8569_mds)) {
|
||||
#define BCSR7_UCC12_GETHnRST (0x1 << 2)
|
||||
#define BCSR8_UEM_MARVELL_RST (0x1 << 1)
|
||||
#define BCSR_UCC_RGMII (0x1 << 6)
|
||||
#define BCSR_UCC_RTBI (0x1 << 5)
|
||||
/*
|
||||
* U-Boot mangles interrupt polarity for Marvell PHYs,
|
||||
* so reset built-in and UEM Marvell PHYs, this puts
|
||||
* the PHYs into their normal state.
|
||||
*/
|
||||
clrbits8(&bcsr_regs[7], BCSR7_UCC12_GETHnRST);
|
||||
setbits8(&bcsr_regs[8], BCSR8_UEM_MARVELL_RST);
|
||||
|
||||
setbits8(&bcsr_regs[7], BCSR7_UCC12_GETHnRST);
|
||||
clrbits8(&bcsr_regs[8], BCSR8_UEM_MARVELL_RST);
|
||||
|
||||
for_each_compatible_node(np, "network", "ucc_geth") {
|
||||
const unsigned int *prop;
|
||||
int ucc_num;
|
||||
|
||||
prop = of_get_property(np, "cell-index", NULL);
|
||||
if (prop == NULL)
|
||||
continue;
|
||||
|
||||
ucc_num = *prop - 1;
|
||||
|
||||
prop = of_get_property(np, "phy-connection-type", NULL);
|
||||
if (prop == NULL)
|
||||
continue;
|
||||
|
||||
if (strcmp("rtbi", (const char *)prop) == 0)
|
||||
clrsetbits_8(&bcsr_regs[7 + ucc_num],
|
||||
BCSR_UCC_RGMII, BCSR_UCC_RTBI);
|
||||
}
|
||||
} else if (machine_is(p1021_mds)) {
|
||||
#define BCSR11_ENET_MICRST (0x1 << 5)
|
||||
/* Reset Micrel PHY */
|
||||
clrbits8(&bcsr_regs[11], BCSR11_ENET_MICRST);
|
||||
setbits8(&bcsr_regs[11], BCSR11_ENET_MICRST);
|
||||
}
|
||||
|
||||
iounmap(bcsr_regs);
|
||||
}
|
||||
|
||||
static void __init mpc85xx_mds_qe_init(void)
|
||||
{
|
||||
struct device_node *np;
|
||||
|
||||
mpc85xx_qe_init();
|
||||
mpc85xx_qe_par_io_init();
|
||||
mpc85xx_mds_reset_ucc_phys();
|
||||
|
||||
if (machine_is(p1021_mds)) {
|
||||
|
||||
struct ccsr_guts __iomem *guts;
|
||||
|
||||
np = of_find_node_by_name(NULL, "global-utilities");
|
||||
if (np) {
|
||||
guts = of_iomap(np, 0);
|
||||
if (!guts)
|
||||
pr_err("mpc85xx-rdb: could not map global utilities register\n");
|
||||
else{
|
||||
/* P1021 has pins muxed for QE and other functions. To
|
||||
* enable QE UEC mode, we need to set bit QE0 for UCC1
|
||||
* in Eth mode, QE0 and QE3 for UCC5 in Eth mode, QE9
|
||||
* and QE12 for QE MII management signals in PMUXCR
|
||||
* register.
|
||||
*/
|
||||
setbits32(&guts->pmuxcr, MPC85xx_PMUXCR_QE(0) |
|
||||
MPC85xx_PMUXCR_QE(3) |
|
||||
MPC85xx_PMUXCR_QE(9) |
|
||||
MPC85xx_PMUXCR_QE(12));
|
||||
iounmap(guts);
|
||||
}
|
||||
of_node_put(np);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static void __init mpc85xx_mds_qeic_init(void)
|
||||
{
|
||||
struct device_node *np;
|
||||
|
||||
np = of_find_compatible_node(NULL, NULL, "fsl,qe");
|
||||
if (!of_device_is_available(np)) {
|
||||
of_node_put(np);
|
||||
return;
|
||||
}
|
||||
|
||||
np = of_find_compatible_node(NULL, NULL, "fsl,qe-ic");
|
||||
if (!np) {
|
||||
np = of_find_node_by_type(NULL, "qeic");
|
||||
if (!np)
|
||||
return;
|
||||
}
|
||||
|
||||
if (machine_is(p1021_mds))
|
||||
qe_ic_init(np, 0, qe_ic_cascade_low_mpic,
|
||||
qe_ic_cascade_high_mpic);
|
||||
else
|
||||
qe_ic_init(np, 0, qe_ic_cascade_muxed_mpic, NULL);
|
||||
of_node_put(np);
|
||||
}
|
||||
#else
|
||||
static void __init mpc85xx_mds_qe_init(void) { }
|
||||
static void __init mpc85xx_mds_qeic_init(void) { }
|
||||
#endif /* CONFIG_QUICC_ENGINE */
|
||||
|
||||
static void __init mpc85xx_mds_setup_arch(void)
|
||||
{
|
||||
if (ppc_md.progress)
|
||||
ppc_md.progress("mpc85xx_mds_setup_arch()", 0);
|
||||
|
||||
mpc85xx_smp_init();
|
||||
|
||||
mpc85xx_mds_qe_init();
|
||||
|
||||
fsl_pci_assign_primary();
|
||||
|
||||
swiotlb_detect_4g();
|
||||
}
|
||||
|
||||
|
||||
static int __init board_fixups(void)
|
||||
{
|
||||
char phy_id[20];
|
||||
char *compstrs[2] = {"fsl,gianfar-mdio", "fsl,ucc-mdio"};
|
||||
struct device_node *mdio;
|
||||
struct resource res;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(compstrs); i++) {
|
||||
mdio = of_find_compatible_node(NULL, NULL, compstrs[i]);
|
||||
|
||||
of_address_to_resource(mdio, 0, &res);
|
||||
snprintf(phy_id, sizeof(phy_id), "%llx:%02x",
|
||||
(unsigned long long)res.start, 1);
|
||||
|
||||
phy_register_fixup_for_id(phy_id, mpc8568_fixup_125_clock);
|
||||
phy_register_fixup_for_id(phy_id, mpc8568_mds_phy_fixups);
|
||||
|
||||
/* Register a workaround for errata */
|
||||
snprintf(phy_id, sizeof(phy_id), "%llx:%02x",
|
||||
(unsigned long long)res.start, 7);
|
||||
phy_register_fixup_for_id(phy_id, mpc8568_mds_phy_fixups);
|
||||
|
||||
of_node_put(mdio);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
machine_arch_initcall(mpc8568_mds, board_fixups);
|
||||
machine_arch_initcall(mpc8569_mds, board_fixups);
|
||||
|
||||
static int __init mpc85xx_publish_devices(void)
|
||||
{
|
||||
if (machine_is(mpc8568_mds))
|
||||
simple_gpiochip_init("fsl,mpc8568mds-bcsr-gpio");
|
||||
if (machine_is(mpc8569_mds))
|
||||
simple_gpiochip_init("fsl,mpc8569mds-bcsr-gpio");
|
||||
|
||||
return mpc85xx_common_publish_devices();
|
||||
}
|
||||
|
||||
machine_arch_initcall(mpc8568_mds, mpc85xx_publish_devices);
|
||||
machine_arch_initcall(mpc8569_mds, mpc85xx_publish_devices);
|
||||
machine_arch_initcall(p1021_mds, mpc85xx_common_publish_devices);
|
||||
|
||||
machine_arch_initcall(mpc8568_mds, swiotlb_setup_bus_notifier);
|
||||
machine_arch_initcall(mpc8569_mds, swiotlb_setup_bus_notifier);
|
||||
machine_arch_initcall(p1021_mds, swiotlb_setup_bus_notifier);
|
||||
|
||||
static void __init mpc85xx_mds_pic_init(void)
|
||||
{
|
||||
struct mpic *mpic = mpic_alloc(NULL, 0, MPIC_BIG_ENDIAN |
|
||||
MPIC_SINGLE_DEST_CPU,
|
||||
0, 256, " OpenPIC ");
|
||||
BUG_ON(mpic == NULL);
|
||||
|
||||
mpic_init(mpic);
|
||||
mpc85xx_mds_qeic_init();
|
||||
}
|
||||
|
||||
static int __init mpc85xx_mds_probe(void)
|
||||
{
|
||||
unsigned long root = of_get_flat_dt_root();
|
||||
|
||||
return of_flat_dt_is_compatible(root, "MPC85xxMDS");
|
||||
}
|
||||
|
||||
define_machine(mpc8568_mds) {
|
||||
.name = "MPC8568 MDS",
|
||||
.probe = mpc85xx_mds_probe,
|
||||
.setup_arch = mpc85xx_mds_setup_arch,
|
||||
.init_IRQ = mpc85xx_mds_pic_init,
|
||||
.get_irq = mpic_get_irq,
|
||||
.restart = fsl_rstcr_restart,
|
||||
.calibrate_decr = generic_calibrate_decr,
|
||||
.progress = udbg_progress,
|
||||
#ifdef CONFIG_PCI
|
||||
.pcibios_fixup_bus = fsl_pcibios_fixup_bus,
|
||||
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
|
||||
#endif
|
||||
};
|
||||
|
||||
static int __init mpc8569_mds_probe(void)
|
||||
{
|
||||
unsigned long root = of_get_flat_dt_root();
|
||||
|
||||
return of_flat_dt_is_compatible(root, "fsl,MPC8569EMDS");
|
||||
}
|
||||
|
||||
define_machine(mpc8569_mds) {
|
||||
.name = "MPC8569 MDS",
|
||||
.probe = mpc8569_mds_probe,
|
||||
.setup_arch = mpc85xx_mds_setup_arch,
|
||||
.init_IRQ = mpc85xx_mds_pic_init,
|
||||
.get_irq = mpic_get_irq,
|
||||
.restart = fsl_rstcr_restart,
|
||||
.calibrate_decr = generic_calibrate_decr,
|
||||
.progress = udbg_progress,
|
||||
#ifdef CONFIG_PCI
|
||||
.pcibios_fixup_bus = fsl_pcibios_fixup_bus,
|
||||
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
|
||||
#endif
|
||||
};
|
||||
|
||||
static int __init p1021_mds_probe(void)
|
||||
{
|
||||
unsigned long root = of_get_flat_dt_root();
|
||||
|
||||
return of_flat_dt_is_compatible(root, "fsl,P1021MDS");
|
||||
|
||||
}
|
||||
|
||||
define_machine(p1021_mds) {
|
||||
.name = "P1021 MDS",
|
||||
.probe = p1021_mds_probe,
|
||||
.setup_arch = mpc85xx_mds_setup_arch,
|
||||
.init_IRQ = mpc85xx_mds_pic_init,
|
||||
.get_irq = mpic_get_irq,
|
||||
.restart = fsl_rstcr_restart,
|
||||
.calibrate_decr = generic_calibrate_decr,
|
||||
.progress = udbg_progress,
|
||||
#ifdef CONFIG_PCI
|
||||
.pcibios_fixup_bus = fsl_pcibios_fixup_bus,
|
||||
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
|
||||
#endif
|
||||
};
|
||||
|
375
arch/powerpc/platforms/85xx/mpc85xx_rdb.c
Normal file
375
arch/powerpc/platforms/85xx/mpc85xx_rdb.c
Normal file
|
@ -0,0 +1,375 @@
|
|||
/*
|
||||
* MPC85xx RDB Board Setup
|
||||
*
|
||||
* Copyright 2009,2012-2013 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/delay.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/of_platform.h>
|
||||
|
||||
#include <asm/time.h>
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/pci-bridge.h>
|
||||
#include <mm/mmu_decl.h>
|
||||
#include <asm/prom.h>
|
||||
#include <asm/udbg.h>
|
||||
#include <asm/mpic.h>
|
||||
#include <asm/qe.h>
|
||||
#include <asm/qe_ic.h>
|
||||
#include <asm/fsl_guts.h>
|
||||
|
||||
#include <sysdev/fsl_soc.h>
|
||||
#include <sysdev/fsl_pci.h>
|
||||
#include "smp.h"
|
||||
|
||||
#include "mpc85xx.h"
|
||||
|
||||
#undef DEBUG
|
||||
|
||||
#ifdef DEBUG
|
||||
#define DBG(fmt, args...) printk(KERN_ERR "%s: " fmt, __func__, ## args)
|
||||
#else
|
||||
#define DBG(fmt, args...)
|
||||
#endif
|
||||
|
||||
|
||||
void __init mpc85xx_rdb_pic_init(void)
|
||||
{
|
||||
struct mpic *mpic;
|
||||
unsigned long root = of_get_flat_dt_root();
|
||||
|
||||
#ifdef CONFIG_QUICC_ENGINE
|
||||
struct device_node *np;
|
||||
#endif
|
||||
|
||||
if (of_flat_dt_is_compatible(root, "fsl,MPC85XXRDB-CAMP")) {
|
||||
mpic = mpic_alloc(NULL, 0, MPIC_NO_RESET |
|
||||
MPIC_BIG_ENDIAN |
|
||||
MPIC_SINGLE_DEST_CPU,
|
||||
0, 256, " OpenPIC ");
|
||||
} else {
|
||||
mpic = mpic_alloc(NULL, 0,
|
||||
MPIC_BIG_ENDIAN |
|
||||
MPIC_SINGLE_DEST_CPU,
|
||||
0, 256, " OpenPIC ");
|
||||
}
|
||||
|
||||
BUG_ON(mpic == NULL);
|
||||
mpic_init(mpic);
|
||||
|
||||
#ifdef CONFIG_QUICC_ENGINE
|
||||
np = of_find_compatible_node(NULL, NULL, "fsl,qe-ic");
|
||||
if (np) {
|
||||
qe_ic_init(np, 0, qe_ic_cascade_low_mpic,
|
||||
qe_ic_cascade_high_mpic);
|
||||
of_node_put(np);
|
||||
|
||||
} else
|
||||
pr_err("%s: Could not find qe-ic node\n", __func__);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup the architecture
|
||||
*/
|
||||
static void __init mpc85xx_rdb_setup_arch(void)
|
||||
{
|
||||
if (ppc_md.progress)
|
||||
ppc_md.progress("mpc85xx_rdb_setup_arch()", 0);
|
||||
|
||||
mpc85xx_smp_init();
|
||||
|
||||
fsl_pci_assign_primary();
|
||||
|
||||
#ifdef CONFIG_QUICC_ENGINE
|
||||
mpc85xx_qe_init();
|
||||
mpc85xx_qe_par_io_init();
|
||||
#if defined(CONFIG_UCC_GETH) || defined(CONFIG_SERIAL_QE)
|
||||
if (machine_is(p1025_rdb)) {
|
||||
struct device_node *np;
|
||||
|
||||
struct ccsr_guts __iomem *guts;
|
||||
|
||||
np = of_find_node_by_name(NULL, "global-utilities");
|
||||
if (np) {
|
||||
guts = of_iomap(np, 0);
|
||||
if (!guts) {
|
||||
|
||||
pr_err("mpc85xx-rdb: could not map global utilities register\n");
|
||||
|
||||
} else {
|
||||
/* P1025 has pins muxed for QE and other functions. To
|
||||
* enable QE UEC mode, we need to set bit QE0 for UCC1
|
||||
* in Eth mode, QE0 and QE3 for UCC5 in Eth mode, QE9
|
||||
* and QE12 for QE MII management singals in PMUXCR
|
||||
* register.
|
||||
*/
|
||||
setbits32(&guts->pmuxcr, MPC85xx_PMUXCR_QE(0) |
|
||||
MPC85xx_PMUXCR_QE(3) |
|
||||
MPC85xx_PMUXCR_QE(9) |
|
||||
MPC85xx_PMUXCR_QE(12));
|
||||
iounmap(guts);
|
||||
}
|
||||
of_node_put(np);
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
#endif /* CONFIG_QUICC_ENGINE */
|
||||
|
||||
printk(KERN_INFO "MPC85xx RDB board from Freescale Semiconductor\n");
|
||||
}
|
||||
|
||||
machine_arch_initcall(p2020_rdb, mpc85xx_common_publish_devices);
|
||||
machine_arch_initcall(p2020_rdb_pc, mpc85xx_common_publish_devices);
|
||||
machine_arch_initcall(p1020_mbg_pc, mpc85xx_common_publish_devices);
|
||||
machine_arch_initcall(p1020_rdb, mpc85xx_common_publish_devices);
|
||||
machine_arch_initcall(p1020_rdb_pc, mpc85xx_common_publish_devices);
|
||||
machine_arch_initcall(p1020_rdb_pd, mpc85xx_common_publish_devices);
|
||||
machine_arch_initcall(p1020_utm_pc, mpc85xx_common_publish_devices);
|
||||
machine_arch_initcall(p1021_rdb_pc, mpc85xx_common_publish_devices);
|
||||
machine_arch_initcall(p1025_rdb, mpc85xx_common_publish_devices);
|
||||
machine_arch_initcall(p1024_rdb, mpc85xx_common_publish_devices);
|
||||
|
||||
/*
|
||||
* Called very early, device-tree isn't unflattened
|
||||
*/
|
||||
static int __init p2020_rdb_probe(void)
|
||||
{
|
||||
unsigned long root = of_get_flat_dt_root();
|
||||
|
||||
if (of_flat_dt_is_compatible(root, "fsl,P2020RDB"))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __init p1020_rdb_probe(void)
|
||||
{
|
||||
unsigned long root = of_get_flat_dt_root();
|
||||
|
||||
if (of_flat_dt_is_compatible(root, "fsl,P1020RDB"))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __init p1020_rdb_pc_probe(void)
|
||||
{
|
||||
unsigned long root = of_get_flat_dt_root();
|
||||
|
||||
return of_flat_dt_is_compatible(root, "fsl,P1020RDB-PC");
|
||||
}
|
||||
|
||||
static int __init p1020_rdb_pd_probe(void)
|
||||
{
|
||||
unsigned long root = of_get_flat_dt_root();
|
||||
|
||||
return of_flat_dt_is_compatible(root, "fsl,P1020RDB-PD");
|
||||
}
|
||||
|
||||
static int __init p1021_rdb_pc_probe(void)
|
||||
{
|
||||
unsigned long root = of_get_flat_dt_root();
|
||||
|
||||
if (of_flat_dt_is_compatible(root, "fsl,P1021RDB-PC"))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __init p2020_rdb_pc_probe(void)
|
||||
{
|
||||
unsigned long root = of_get_flat_dt_root();
|
||||
|
||||
if (of_flat_dt_is_compatible(root, "fsl,P2020RDB-PC"))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __init p1025_rdb_probe(void)
|
||||
{
|
||||
unsigned long root = of_get_flat_dt_root();
|
||||
|
||||
return of_flat_dt_is_compatible(root, "fsl,P1025RDB");
|
||||
}
|
||||
|
||||
static int __init p1020_mbg_pc_probe(void)
|
||||
{
|
||||
unsigned long root = of_get_flat_dt_root();
|
||||
|
||||
return of_flat_dt_is_compatible(root, "fsl,P1020MBG-PC");
|
||||
}
|
||||
|
||||
static int __init p1020_utm_pc_probe(void)
|
||||
{
|
||||
unsigned long root = of_get_flat_dt_root();
|
||||
|
||||
return of_flat_dt_is_compatible(root, "fsl,P1020UTM-PC");
|
||||
}
|
||||
|
||||
static int __init p1024_rdb_probe(void)
|
||||
{
|
||||
unsigned long root = of_get_flat_dt_root();
|
||||
|
||||
return of_flat_dt_is_compatible(root, "fsl,P1024RDB");
|
||||
}
|
||||
|
||||
define_machine(p2020_rdb) {
|
||||
.name = "P2020 RDB",
|
||||
.probe = p2020_rdb_probe,
|
||||
.setup_arch = mpc85xx_rdb_setup_arch,
|
||||
.init_IRQ = mpc85xx_rdb_pic_init,
|
||||
#ifdef CONFIG_PCI
|
||||
.pcibios_fixup_bus = fsl_pcibios_fixup_bus,
|
||||
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
|
||||
#endif
|
||||
.get_irq = mpic_get_irq,
|
||||
.restart = fsl_rstcr_restart,
|
||||
.calibrate_decr = generic_calibrate_decr,
|
||||
.progress = udbg_progress,
|
||||
};
|
||||
|
||||
define_machine(p1020_rdb) {
|
||||
.name = "P1020 RDB",
|
||||
.probe = p1020_rdb_probe,
|
||||
.setup_arch = mpc85xx_rdb_setup_arch,
|
||||
.init_IRQ = mpc85xx_rdb_pic_init,
|
||||
#ifdef CONFIG_PCI
|
||||
.pcibios_fixup_bus = fsl_pcibios_fixup_bus,
|
||||
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
|
||||
#endif
|
||||
.get_irq = mpic_get_irq,
|
||||
.restart = fsl_rstcr_restart,
|
||||
.calibrate_decr = generic_calibrate_decr,
|
||||
.progress = udbg_progress,
|
||||
};
|
||||
|
||||
define_machine(p1021_rdb_pc) {
|
||||
.name = "P1021 RDB-PC",
|
||||
.probe = p1021_rdb_pc_probe,
|
||||
.setup_arch = mpc85xx_rdb_setup_arch,
|
||||
.init_IRQ = mpc85xx_rdb_pic_init,
|
||||
#ifdef CONFIG_PCI
|
||||
.pcibios_fixup_bus = fsl_pcibios_fixup_bus,
|
||||
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
|
||||
#endif
|
||||
.get_irq = mpic_get_irq,
|
||||
.restart = fsl_rstcr_restart,
|
||||
.calibrate_decr = generic_calibrate_decr,
|
||||
.progress = udbg_progress,
|
||||
};
|
||||
|
||||
define_machine(p2020_rdb_pc) {
|
||||
.name = "P2020RDB-PC",
|
||||
.probe = p2020_rdb_pc_probe,
|
||||
.setup_arch = mpc85xx_rdb_setup_arch,
|
||||
.init_IRQ = mpc85xx_rdb_pic_init,
|
||||
#ifdef CONFIG_PCI
|
||||
.pcibios_fixup_bus = fsl_pcibios_fixup_bus,
|
||||
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
|
||||
#endif
|
||||
.get_irq = mpic_get_irq,
|
||||
.restart = fsl_rstcr_restart,
|
||||
.calibrate_decr = generic_calibrate_decr,
|
||||
.progress = udbg_progress,
|
||||
};
|
||||
|
||||
define_machine(p1025_rdb) {
|
||||
.name = "P1025 RDB",
|
||||
.probe = p1025_rdb_probe,
|
||||
.setup_arch = mpc85xx_rdb_setup_arch,
|
||||
.init_IRQ = mpc85xx_rdb_pic_init,
|
||||
#ifdef CONFIG_PCI
|
||||
.pcibios_fixup_bus = fsl_pcibios_fixup_bus,
|
||||
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
|
||||
#endif
|
||||
.get_irq = mpic_get_irq,
|
||||
.restart = fsl_rstcr_restart,
|
||||
.calibrate_decr = generic_calibrate_decr,
|
||||
.progress = udbg_progress,
|
||||
};
|
||||
|
||||
define_machine(p1020_mbg_pc) {
|
||||
.name = "P1020 MBG-PC",
|
||||
.probe = p1020_mbg_pc_probe,
|
||||
.setup_arch = mpc85xx_rdb_setup_arch,
|
||||
.init_IRQ = mpc85xx_rdb_pic_init,
|
||||
#ifdef CONFIG_PCI
|
||||
.pcibios_fixup_bus = fsl_pcibios_fixup_bus,
|
||||
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
|
||||
#endif
|
||||
.get_irq = mpic_get_irq,
|
||||
.restart = fsl_rstcr_restart,
|
||||
.calibrate_decr = generic_calibrate_decr,
|
||||
.progress = udbg_progress,
|
||||
};
|
||||
|
||||
define_machine(p1020_utm_pc) {
|
||||
.name = "P1020 UTM-PC",
|
||||
.probe = p1020_utm_pc_probe,
|
||||
.setup_arch = mpc85xx_rdb_setup_arch,
|
||||
.init_IRQ = mpc85xx_rdb_pic_init,
|
||||
#ifdef CONFIG_PCI
|
||||
.pcibios_fixup_bus = fsl_pcibios_fixup_bus,
|
||||
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
|
||||
#endif
|
||||
.get_irq = mpic_get_irq,
|
||||
.restart = fsl_rstcr_restart,
|
||||
.calibrate_decr = generic_calibrate_decr,
|
||||
.progress = udbg_progress,
|
||||
};
|
||||
|
||||
define_machine(p1020_rdb_pc) {
|
||||
.name = "P1020RDB-PC",
|
||||
.probe = p1020_rdb_pc_probe,
|
||||
.setup_arch = mpc85xx_rdb_setup_arch,
|
||||
.init_IRQ = mpc85xx_rdb_pic_init,
|
||||
#ifdef CONFIG_PCI
|
||||
.pcibios_fixup_bus = fsl_pcibios_fixup_bus,
|
||||
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
|
||||
#endif
|
||||
.get_irq = mpic_get_irq,
|
||||
.restart = fsl_rstcr_restart,
|
||||
.calibrate_decr = generic_calibrate_decr,
|
||||
.progress = udbg_progress,
|
||||
};
|
||||
|
||||
define_machine(p1020_rdb_pd) {
|
||||
.name = "P1020RDB-PD",
|
||||
.probe = p1020_rdb_pd_probe,
|
||||
.setup_arch = mpc85xx_rdb_setup_arch,
|
||||
.init_IRQ = mpc85xx_rdb_pic_init,
|
||||
#ifdef CONFIG_PCI
|
||||
.pcibios_fixup_bus = fsl_pcibios_fixup_bus,
|
||||
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
|
||||
#endif
|
||||
.get_irq = mpic_get_irq,
|
||||
.restart = fsl_rstcr_restart,
|
||||
.calibrate_decr = generic_calibrate_decr,
|
||||
.progress = udbg_progress,
|
||||
};
|
||||
|
||||
define_machine(p1024_rdb) {
|
||||
.name = "P1024 RDB",
|
||||
.probe = p1024_rdb_probe,
|
||||
.setup_arch = mpc85xx_rdb_setup_arch,
|
||||
.init_IRQ = mpc85xx_rdb_pic_init,
|
||||
#ifdef CONFIG_PCI
|
||||
.pcibios_fixup_bus = fsl_pcibios_fixup_bus,
|
||||
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
|
||||
#endif
|
||||
.get_irq = mpic_get_irq,
|
||||
.restart = fsl_rstcr_restart,
|
||||
.calibrate_decr = generic_calibrate_decr,
|
||||
.progress = udbg_progress,
|
||||
};
|
87
arch/powerpc/platforms/85xx/p1010rdb.c
Normal file
87
arch/powerpc/platforms/85xx/p1010rdb.c
Normal file
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* P1010RDB Board Setup
|
||||
*
|
||||
* Copyright 2011 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/delay.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/of_platform.h>
|
||||
|
||||
#include <asm/time.h>
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/pci-bridge.h>
|
||||
#include <mm/mmu_decl.h>
|
||||
#include <asm/prom.h>
|
||||
#include <asm/udbg.h>
|
||||
#include <asm/mpic.h>
|
||||
|
||||
#include <sysdev/fsl_soc.h>
|
||||
#include <sysdev/fsl_pci.h>
|
||||
|
||||
#include "mpc85xx.h"
|
||||
|
||||
void __init p1010_rdb_pic_init(void)
|
||||
{
|
||||
struct mpic *mpic = mpic_alloc(NULL, 0, MPIC_BIG_ENDIAN |
|
||||
MPIC_SINGLE_DEST_CPU,
|
||||
0, 256, " OpenPIC ");
|
||||
|
||||
BUG_ON(mpic == NULL);
|
||||
|
||||
mpic_init(mpic);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Setup the architecture
|
||||
*/
|
||||
static void __init p1010_rdb_setup_arch(void)
|
||||
{
|
||||
if (ppc_md.progress)
|
||||
ppc_md.progress("p1010_rdb_setup_arch()", 0);
|
||||
|
||||
fsl_pci_assign_primary();
|
||||
|
||||
printk(KERN_INFO "P1010 RDB board from Freescale Semiconductor\n");
|
||||
}
|
||||
|
||||
machine_arch_initcall(p1010_rdb, mpc85xx_common_publish_devices);
|
||||
machine_arch_initcall(p1010_rdb, swiotlb_setup_bus_notifier);
|
||||
|
||||
/*
|
||||
* Called very early, device-tree isn't unflattened
|
||||
*/
|
||||
static int __init p1010_rdb_probe(void)
|
||||
{
|
||||
unsigned long root = of_get_flat_dt_root();
|
||||
|
||||
if (of_flat_dt_is_compatible(root, "fsl,P1010RDB"))
|
||||
return 1;
|
||||
if (of_flat_dt_is_compatible(root, "fsl,P1010RDB-PB"))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
define_machine(p1010_rdb) {
|
||||
.name = "P1010 RDB",
|
||||
.probe = p1010_rdb_probe,
|
||||
.setup_arch = p1010_rdb_setup_arch,
|
||||
.init_IRQ = p1010_rdb_pic_init,
|
||||
#ifdef CONFIG_PCI
|
||||
.pcibios_fixup_bus = fsl_pcibios_fixup_bus,
|
||||
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
|
||||
#endif
|
||||
.get_irq = mpic_get_irq,
|
||||
.restart = fsl_rstcr_restart,
|
||||
.calibrate_decr = generic_calibrate_decr,
|
||||
.progress = udbg_progress,
|
||||
};
|
576
arch/powerpc/platforms/85xx/p1022_ds.c
Normal file
576
arch/powerpc/platforms/85xx/p1022_ds.c
Normal file
|
@ -0,0 +1,576 @@
|
|||
/*
|
||||
* P1022DS board specific routines
|
||||
*
|
||||
* Authors: Travis Wheatley <travis.wheatley@freescale.com>
|
||||
* Dave Liu <daveliu@freescale.com>
|
||||
* Timur Tabi <timur@freescale.com>
|
||||
*
|
||||
* Copyright 2010 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* This file is taken from the Freescale P1022DS BSP, with modifications:
|
||||
* 2) No AMP support
|
||||
* 3) No PCI endpoint support
|
||||
*
|
||||
* 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/pci.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <asm/div64.h>
|
||||
#include <asm/mpic.h>
|
||||
#include <asm/swiotlb.h>
|
||||
|
||||
#include <sysdev/fsl_soc.h>
|
||||
#include <sysdev/fsl_pci.h>
|
||||
#include <asm/udbg.h>
|
||||
#include <asm/fsl_guts.h>
|
||||
#include <asm/fsl_lbc.h>
|
||||
#include "smp.h"
|
||||
|
||||
#include "mpc85xx.h"
|
||||
|
||||
#if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE)
|
||||
|
||||
#define PMUXCR_ELBCDIU_MASK 0xc0000000
|
||||
#define PMUXCR_ELBCDIU_NOR16 0x80000000
|
||||
#define PMUXCR_ELBCDIU_DIU 0x40000000
|
||||
|
||||
/*
|
||||
* Board-specific initialization of the DIU. This code should probably be
|
||||
* executed when the DIU is opened, rather than in arch code, but the DIU
|
||||
* driver does not have a mechanism for this (yet).
|
||||
*
|
||||
* This is especially problematic on the P1022DS because the local bus (eLBC)
|
||||
* and the DIU video signals share the same pins, which means that enabling the
|
||||
* DIU will disable access to NOR flash.
|
||||
*/
|
||||
|
||||
/* DIU Pixel Clock bits of the CLKDVDR Global Utilities register */
|
||||
#define CLKDVDR_PXCKEN 0x80000000
|
||||
#define CLKDVDR_PXCKINV 0x10000000
|
||||
#define CLKDVDR_PXCKDLY 0x06000000
|
||||
#define CLKDVDR_PXCLK_MASK 0x00FF0000
|
||||
|
||||
/* Some ngPIXIS register definitions */
|
||||
#define PX_CTL 3
|
||||
#define PX_BRDCFG0 8
|
||||
#define PX_BRDCFG1 9
|
||||
|
||||
#define PX_BRDCFG0_ELBC_SPI_MASK 0xc0
|
||||
#define PX_BRDCFG0_ELBC_SPI_ELBC 0x00
|
||||
#define PX_BRDCFG0_ELBC_SPI_NULL 0xc0
|
||||
#define PX_BRDCFG0_ELBC_DIU 0x02
|
||||
|
||||
#define PX_BRDCFG1_DVIEN 0x80
|
||||
#define PX_BRDCFG1_DFPEN 0x40
|
||||
#define PX_BRDCFG1_BACKLIGHT 0x20
|
||||
#define PX_BRDCFG1_DDCEN 0x10
|
||||
|
||||
#define PX_CTL_ALTACC 0x80
|
||||
|
||||
/*
|
||||
* DIU Area Descriptor
|
||||
*
|
||||
* Note that we need to byte-swap the value before it's written to the AD
|
||||
* register. So even though the registers don't look like they're in the same
|
||||
* bit positions as they are on the MPC8610, the same value is written to the
|
||||
* AD register on the MPC8610 and on the P1022.
|
||||
*/
|
||||
#define AD_BYTE_F 0x10000000
|
||||
#define AD_ALPHA_C_MASK 0x0E000000
|
||||
#define AD_ALPHA_C_SHIFT 25
|
||||
#define AD_BLUE_C_MASK 0x01800000
|
||||
#define AD_BLUE_C_SHIFT 23
|
||||
#define AD_GREEN_C_MASK 0x00600000
|
||||
#define AD_GREEN_C_SHIFT 21
|
||||
#define AD_RED_C_MASK 0x00180000
|
||||
#define AD_RED_C_SHIFT 19
|
||||
#define AD_PALETTE 0x00040000
|
||||
#define AD_PIXEL_S_MASK 0x00030000
|
||||
#define AD_PIXEL_S_SHIFT 16
|
||||
#define AD_COMP_3_MASK 0x0000F000
|
||||
#define AD_COMP_3_SHIFT 12
|
||||
#define AD_COMP_2_MASK 0x00000F00
|
||||
#define AD_COMP_2_SHIFT 8
|
||||
#define AD_COMP_1_MASK 0x000000F0
|
||||
#define AD_COMP_1_SHIFT 4
|
||||
#define AD_COMP_0_MASK 0x0000000F
|
||||
#define AD_COMP_0_SHIFT 0
|
||||
|
||||
#define MAKE_AD(alpha, red, blue, green, size, c0, c1, c2, c3) \
|
||||
cpu_to_le32(AD_BYTE_F | (alpha << AD_ALPHA_C_SHIFT) | \
|
||||
(blue << AD_BLUE_C_SHIFT) | (green << AD_GREEN_C_SHIFT) | \
|
||||
(red << AD_RED_C_SHIFT) | (c3 << AD_COMP_3_SHIFT) | \
|
||||
(c2 << AD_COMP_2_SHIFT) | (c1 << AD_COMP_1_SHIFT) | \
|
||||
(c0 << AD_COMP_0_SHIFT) | (size << AD_PIXEL_S_SHIFT))
|
||||
|
||||
struct fsl_law {
|
||||
u32 lawbar;
|
||||
u32 reserved1;
|
||||
u32 lawar;
|
||||
u32 reserved[5];
|
||||
};
|
||||
|
||||
#define LAWBAR_MASK 0x00F00000
|
||||
#define LAWBAR_SHIFT 12
|
||||
|
||||
#define LAWAR_EN 0x80000000
|
||||
#define LAWAR_TGT_MASK 0x01F00000
|
||||
#define LAW_TRGT_IF_LBC (0x04 << 20)
|
||||
|
||||
#define LAWAR_MASK (LAWAR_EN | LAWAR_TGT_MASK)
|
||||
#define LAWAR_MATCH (LAWAR_EN | LAW_TRGT_IF_LBC)
|
||||
|
||||
#define BR_BA 0xFFFF8000
|
||||
|
||||
/*
|
||||
* Map a BRx value to a physical address
|
||||
*
|
||||
* The localbus BRx registers only store the lower 32 bits of the address. To
|
||||
* obtain the upper four bits, we need to scan the LAW table. The entry which
|
||||
* maps to the localbus will contain the upper four bits.
|
||||
*/
|
||||
static phys_addr_t lbc_br_to_phys(const void *ecm, unsigned int count, u32 br)
|
||||
{
|
||||
#ifndef CONFIG_PHYS_64BIT
|
||||
/*
|
||||
* If we only have 32-bit addressing, then the BRx address *is* the
|
||||
* physical address.
|
||||
*/
|
||||
return br & BR_BA;
|
||||
#else
|
||||
const struct fsl_law *law = ecm + 0xc08;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
u64 lawbar = in_be32(&law[i].lawbar);
|
||||
u32 lawar = in_be32(&law[i].lawar);
|
||||
|
||||
if ((lawar & LAWAR_MASK) == LAWAR_MATCH)
|
||||
/* Extract the upper four bits */
|
||||
return (br & BR_BA) | ((lawbar & LAWBAR_MASK) << 12);
|
||||
}
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* p1022ds_set_monitor_port: switch the output to a different monitor port
|
||||
*/
|
||||
static void p1022ds_set_monitor_port(enum fsl_diu_monitor_port port)
|
||||
{
|
||||
struct device_node *guts_node;
|
||||
struct device_node *lbc_node = NULL;
|
||||
struct device_node *law_node = NULL;
|
||||
struct ccsr_guts __iomem *guts;
|
||||
struct fsl_lbc_regs *lbc = NULL;
|
||||
void *ecm = NULL;
|
||||
u8 __iomem *lbc_lcs0_ba = NULL;
|
||||
u8 __iomem *lbc_lcs1_ba = NULL;
|
||||
phys_addr_t cs0_addr, cs1_addr;
|
||||
u32 br0, or0, br1, or1;
|
||||
const __be32 *iprop;
|
||||
unsigned int num_laws;
|
||||
u8 b;
|
||||
|
||||
/* Map the global utilities registers. */
|
||||
guts_node = of_find_compatible_node(NULL, NULL, "fsl,p1022-guts");
|
||||
if (!guts_node) {
|
||||
pr_err("p1022ds: missing global utilities device node\n");
|
||||
return;
|
||||
}
|
||||
|
||||
guts = of_iomap(guts_node, 0);
|
||||
if (!guts) {
|
||||
pr_err("p1022ds: could not map global utilities device\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
lbc_node = of_find_compatible_node(NULL, NULL, "fsl,p1022-elbc");
|
||||
if (!lbc_node) {
|
||||
pr_err("p1022ds: missing localbus node\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
lbc = of_iomap(lbc_node, 0);
|
||||
if (!lbc) {
|
||||
pr_err("p1022ds: could not map localbus node\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
law_node = of_find_compatible_node(NULL, NULL, "fsl,ecm-law");
|
||||
if (!law_node) {
|
||||
pr_err("p1022ds: missing local access window node\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ecm = of_iomap(law_node, 0);
|
||||
if (!ecm) {
|
||||
pr_err("p1022ds: could not map local access window node\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
iprop = of_get_property(law_node, "fsl,num-laws", NULL);
|
||||
if (!iprop) {
|
||||
pr_err("p1022ds: LAW node is missing fsl,num-laws property\n");
|
||||
goto exit;
|
||||
}
|
||||
num_laws = be32_to_cpup(iprop);
|
||||
|
||||
/*
|
||||
* Indirect mode requires both BR0 and BR1 to be set to "GPCM",
|
||||
* otherwise writes to these addresses won't actually appear on the
|
||||
* local bus, and so the PIXIS won't see them.
|
||||
*
|
||||
* In FCM mode, writes go to the NAND controller, which does not pass
|
||||
* them to the localbus directly. So we force BR0 and BR1 into GPCM
|
||||
* mode, since we don't care about what's behind the localbus any
|
||||
* more.
|
||||
*/
|
||||
br0 = in_be32(&lbc->bank[0].br);
|
||||
br1 = in_be32(&lbc->bank[1].br);
|
||||
or0 = in_be32(&lbc->bank[0].or);
|
||||
or1 = in_be32(&lbc->bank[1].or);
|
||||
|
||||
/* Make sure CS0 and CS1 are programmed */
|
||||
if (!(br0 & BR_V) || !(br1 & BR_V)) {
|
||||
pr_err("p1022ds: CS0 and/or CS1 is not programmed\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/*
|
||||
* Use the existing BRx/ORx values if it's already GPCM. Otherwise,
|
||||
* force the values to simple 32KB GPCM windows with the most
|
||||
* conservative timing.
|
||||
*/
|
||||
if ((br0 & BR_MSEL) != BR_MS_GPCM) {
|
||||
br0 = (br0 & BR_BA) | BR_V;
|
||||
or0 = 0xFFFF8000 | 0xFF7;
|
||||
out_be32(&lbc->bank[0].br, br0);
|
||||
out_be32(&lbc->bank[0].or, or0);
|
||||
}
|
||||
if ((br1 & BR_MSEL) != BR_MS_GPCM) {
|
||||
br1 = (br1 & BR_BA) | BR_V;
|
||||
or1 = 0xFFFF8000 | 0xFF7;
|
||||
out_be32(&lbc->bank[1].br, br1);
|
||||
out_be32(&lbc->bank[1].or, or1);
|
||||
}
|
||||
|
||||
cs0_addr = lbc_br_to_phys(ecm, num_laws, br0);
|
||||
if (!cs0_addr) {
|
||||
pr_err("p1022ds: could not determine physical address for CS0"
|
||||
" (BR0=%08x)\n", br0);
|
||||
goto exit;
|
||||
}
|
||||
cs1_addr = lbc_br_to_phys(ecm, num_laws, br1);
|
||||
if (!cs1_addr) {
|
||||
pr_err("p1022ds: could not determine physical address for CS1"
|
||||
" (BR1=%08x)\n", br1);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
lbc_lcs0_ba = ioremap(cs0_addr, 1);
|
||||
if (!lbc_lcs0_ba) {
|
||||
pr_err("p1022ds: could not ioremap CS0 address %llx\n",
|
||||
(unsigned long long)cs0_addr);
|
||||
goto exit;
|
||||
}
|
||||
lbc_lcs1_ba = ioremap(cs1_addr, 1);
|
||||
if (!lbc_lcs1_ba) {
|
||||
pr_err("p1022ds: could not ioremap CS1 address %llx\n",
|
||||
(unsigned long long)cs1_addr);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Make sure we're in indirect mode first. */
|
||||
if ((in_be32(&guts->pmuxcr) & PMUXCR_ELBCDIU_MASK) !=
|
||||
PMUXCR_ELBCDIU_DIU) {
|
||||
struct device_node *pixis_node;
|
||||
void __iomem *pixis;
|
||||
|
||||
pixis_node =
|
||||
of_find_compatible_node(NULL, NULL, "fsl,p1022ds-fpga");
|
||||
if (!pixis_node) {
|
||||
pr_err("p1022ds: missing pixis node\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
pixis = of_iomap(pixis_node, 0);
|
||||
of_node_put(pixis_node);
|
||||
if (!pixis) {
|
||||
pr_err("p1022ds: could not map pixis registers\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Enable indirect PIXIS mode. */
|
||||
setbits8(pixis + PX_CTL, PX_CTL_ALTACC);
|
||||
iounmap(pixis);
|
||||
|
||||
/* Switch the board mux to the DIU */
|
||||
out_8(lbc_lcs0_ba, PX_BRDCFG0); /* BRDCFG0 */
|
||||
b = in_8(lbc_lcs1_ba);
|
||||
b |= PX_BRDCFG0_ELBC_DIU;
|
||||
out_8(lbc_lcs1_ba, b);
|
||||
|
||||
/* Set the chip mux to DIU mode. */
|
||||
clrsetbits_be32(&guts->pmuxcr, PMUXCR_ELBCDIU_MASK,
|
||||
PMUXCR_ELBCDIU_DIU);
|
||||
in_be32(&guts->pmuxcr);
|
||||
}
|
||||
|
||||
|
||||
switch (port) {
|
||||
case FSL_DIU_PORT_DVI:
|
||||
/* Enable the DVI port, disable the DFP and the backlight */
|
||||
out_8(lbc_lcs0_ba, PX_BRDCFG1);
|
||||
b = in_8(lbc_lcs1_ba);
|
||||
b &= ~(PX_BRDCFG1_DFPEN | PX_BRDCFG1_BACKLIGHT);
|
||||
b |= PX_BRDCFG1_DVIEN;
|
||||
out_8(lbc_lcs1_ba, b);
|
||||
break;
|
||||
case FSL_DIU_PORT_LVDS:
|
||||
/*
|
||||
* LVDS also needs backlight enabled, otherwise the display
|
||||
* will be blank.
|
||||
*/
|
||||
/* Enable the DFP port, disable the DVI and the backlight */
|
||||
out_8(lbc_lcs0_ba, PX_BRDCFG1);
|
||||
b = in_8(lbc_lcs1_ba);
|
||||
b &= ~PX_BRDCFG1_DVIEN;
|
||||
b |= PX_BRDCFG1_DFPEN | PX_BRDCFG1_BACKLIGHT;
|
||||
out_8(lbc_lcs1_ba, b);
|
||||
break;
|
||||
default:
|
||||
pr_err("p1022ds: unsupported monitor port %i\n", port);
|
||||
}
|
||||
|
||||
exit:
|
||||
if (lbc_lcs1_ba)
|
||||
iounmap(lbc_lcs1_ba);
|
||||
if (lbc_lcs0_ba)
|
||||
iounmap(lbc_lcs0_ba);
|
||||
if (lbc)
|
||||
iounmap(lbc);
|
||||
if (ecm)
|
||||
iounmap(ecm);
|
||||
if (guts)
|
||||
iounmap(guts);
|
||||
|
||||
of_node_put(law_node);
|
||||
of_node_put(lbc_node);
|
||||
of_node_put(guts_node);
|
||||
}
|
||||
|
||||
/**
|
||||
* p1022ds_set_pixel_clock: program the DIU's clock
|
||||
*
|
||||
* @pixclock: the wavelength, in picoseconds, of the clock
|
||||
*/
|
||||
void p1022ds_set_pixel_clock(unsigned int pixclock)
|
||||
{
|
||||
struct device_node *guts_np = NULL;
|
||||
struct ccsr_guts __iomem *guts;
|
||||
unsigned long freq;
|
||||
u64 temp;
|
||||
u32 pxclk;
|
||||
|
||||
/* Map the global utilities registers. */
|
||||
guts_np = of_find_compatible_node(NULL, NULL, "fsl,p1022-guts");
|
||||
if (!guts_np) {
|
||||
pr_err("p1022ds: missing global utilities device node\n");
|
||||
return;
|
||||
}
|
||||
|
||||
guts = of_iomap(guts_np, 0);
|
||||
of_node_put(guts_np);
|
||||
if (!guts) {
|
||||
pr_err("p1022ds: could not map global utilities device\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Convert pixclock from a wavelength to a frequency */
|
||||
temp = 1000000000000ULL;
|
||||
do_div(temp, pixclock);
|
||||
freq = temp;
|
||||
|
||||
/*
|
||||
* 'pxclk' is the ratio of the platform clock to the pixel clock.
|
||||
* This number is programmed into the CLKDVDR register, and the valid
|
||||
* range of values is 2-255.
|
||||
*/
|
||||
pxclk = DIV_ROUND_CLOSEST(fsl_get_sys_freq(), freq);
|
||||
pxclk = clamp_t(u32, pxclk, 2, 255);
|
||||
|
||||
/* Disable the pixel clock, and set it to non-inverted and no delay */
|
||||
clrbits32(&guts->clkdvdr,
|
||||
CLKDVDR_PXCKEN | CLKDVDR_PXCKDLY | CLKDVDR_PXCLK_MASK);
|
||||
|
||||
/* Enable the clock and set the pxclk */
|
||||
setbits32(&guts->clkdvdr, CLKDVDR_PXCKEN | (pxclk << 16));
|
||||
|
||||
iounmap(guts);
|
||||
}
|
||||
|
||||
/**
|
||||
* p1022ds_valid_monitor_port: set the monitor port for sysfs
|
||||
*/
|
||||
enum fsl_diu_monitor_port
|
||||
p1022ds_valid_monitor_port(enum fsl_diu_monitor_port port)
|
||||
{
|
||||
switch (port) {
|
||||
case FSL_DIU_PORT_DVI:
|
||||
case FSL_DIU_PORT_LVDS:
|
||||
return port;
|
||||
default:
|
||||
return FSL_DIU_PORT_DVI; /* Dual-link LVDS is not supported */
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void __init p1022_ds_pic_init(void)
|
||||
{
|
||||
struct mpic *mpic = mpic_alloc(NULL, 0, MPIC_BIG_ENDIAN |
|
||||
MPIC_SINGLE_DEST_CPU,
|
||||
0, 256, " OpenPIC ");
|
||||
BUG_ON(mpic == NULL);
|
||||
mpic_init(mpic);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE)
|
||||
|
||||
/* TRUE if there is a "video=fslfb" command-line parameter. */
|
||||
static bool fslfb;
|
||||
|
||||
/*
|
||||
* Search for a "video=fslfb" command-line parameter, and set 'fslfb' to
|
||||
* true if we find it.
|
||||
*
|
||||
* We need to use early_param() instead of __setup() because the normal
|
||||
* __setup() gets called to late. However, early_param() gets called very
|
||||
* early, before the device tree is unflattened, so all we can do now is set a
|
||||
* global variable. Later on, p1022_ds_setup_arch() will use that variable
|
||||
* to determine if we need to update the device tree.
|
||||
*/
|
||||
static int __init early_video_setup(char *options)
|
||||
{
|
||||
fslfb = (strncmp(options, "fslfb:", 6) == 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
early_param("video", early_video_setup);
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Setup the architecture
|
||||
*/
|
||||
static void __init p1022_ds_setup_arch(void)
|
||||
{
|
||||
if (ppc_md.progress)
|
||||
ppc_md.progress("p1022_ds_setup_arch()", 0);
|
||||
|
||||
#if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE)
|
||||
diu_ops.set_monitor_port = p1022ds_set_monitor_port;
|
||||
diu_ops.set_pixel_clock = p1022ds_set_pixel_clock;
|
||||
diu_ops.valid_monitor_port = p1022ds_valid_monitor_port;
|
||||
|
||||
/*
|
||||
* Disable the NOR and NAND flash nodes if there is video=fslfb...
|
||||
* command-line parameter. When the DIU is active, the localbus is
|
||||
* unavailable, so we have to disable these nodes before the MTD
|
||||
* driver loads.
|
||||
*/
|
||||
if (fslfb) {
|
||||
struct device_node *np =
|
||||
of_find_compatible_node(NULL, NULL, "fsl,p1022-elbc");
|
||||
|
||||
if (np) {
|
||||
struct device_node *np2;
|
||||
|
||||
of_node_get(np);
|
||||
np2 = of_find_compatible_node(np, NULL, "cfi-flash");
|
||||
if (np2) {
|
||||
static struct property nor_status = {
|
||||
.name = "status",
|
||||
.value = "disabled",
|
||||
.length = sizeof("disabled"),
|
||||
};
|
||||
|
||||
/*
|
||||
* of_update_property() is called before
|
||||
* kmalloc() is available, so the 'new' object
|
||||
* should be allocated in the global area.
|
||||
* The easiest way is to do that is to
|
||||
* allocate one static local variable for each
|
||||
* call to this function.
|
||||
*/
|
||||
pr_info("p1022ds: disabling %s node",
|
||||
np2->full_name);
|
||||
of_update_property(np2, &nor_status);
|
||||
of_node_put(np2);
|
||||
}
|
||||
|
||||
of_node_get(np);
|
||||
np2 = of_find_compatible_node(np, NULL,
|
||||
"fsl,elbc-fcm-nand");
|
||||
if (np2) {
|
||||
static struct property nand_status = {
|
||||
.name = "status",
|
||||
.value = "disabled",
|
||||
.length = sizeof("disabled"),
|
||||
};
|
||||
|
||||
pr_info("p1022ds: disabling %s node",
|
||||
np2->full_name);
|
||||
of_update_property(np2, &nand_status);
|
||||
of_node_put(np2);
|
||||
}
|
||||
|
||||
of_node_put(np);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
mpc85xx_smp_init();
|
||||
|
||||
fsl_pci_assign_primary();
|
||||
|
||||
swiotlb_detect_4g();
|
||||
|
||||
pr_info("Freescale P1022 DS reference board\n");
|
||||
}
|
||||
|
||||
machine_arch_initcall(p1022_ds, mpc85xx_common_publish_devices);
|
||||
|
||||
machine_arch_initcall(p1022_ds, swiotlb_setup_bus_notifier);
|
||||
|
||||
/*
|
||||
* Called very early, device-tree isn't unflattened
|
||||
*/
|
||||
static int __init p1022_ds_probe(void)
|
||||
{
|
||||
unsigned long root = of_get_flat_dt_root();
|
||||
|
||||
return of_flat_dt_is_compatible(root, "fsl,p1022ds");
|
||||
}
|
||||
|
||||
define_machine(p1022_ds) {
|
||||
.name = "P1022 DS",
|
||||
.probe = p1022_ds_probe,
|
||||
.setup_arch = p1022_ds_setup_arch,
|
||||
.init_IRQ = p1022_ds_pic_init,
|
||||
#ifdef CONFIG_PCI
|
||||
.pcibios_fixup_bus = fsl_pcibios_fixup_bus,
|
||||
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
|
||||
#endif
|
||||
.get_irq = mpic_get_irq,
|
||||
.restart = fsl_rstcr_restart,
|
||||
.calibrate_decr = generic_calibrate_decr,
|
||||
.progress = udbg_progress,
|
||||
};
|
156
arch/powerpc/platforms/85xx/p1022_rdk.c
Normal file
156
arch/powerpc/platforms/85xx/p1022_rdk.c
Normal file
|
@ -0,0 +1,156 @@
|
|||
/*
|
||||
* P1022 RDK board specific routines
|
||||
*
|
||||
* Copyright 2012 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* Author: Timur Tabi <timur@freescale.com>
|
||||
*
|
||||
* Based on p1022_ds.c
|
||||
*
|
||||
* 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/pci.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <asm/div64.h>
|
||||
#include <asm/mpic.h>
|
||||
#include <asm/swiotlb.h>
|
||||
|
||||
#include <sysdev/fsl_soc.h>
|
||||
#include <sysdev/fsl_pci.h>
|
||||
#include <asm/udbg.h>
|
||||
#include <asm/fsl_guts.h>
|
||||
#include "smp.h"
|
||||
|
||||
#include "mpc85xx.h"
|
||||
|
||||
#if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE)
|
||||
|
||||
/* DIU Pixel Clock bits of the CLKDVDR Global Utilities register */
|
||||
#define CLKDVDR_PXCKEN 0x80000000
|
||||
#define CLKDVDR_PXCKINV 0x10000000
|
||||
#define CLKDVDR_PXCKDLY 0x06000000
|
||||
#define CLKDVDR_PXCLK_MASK 0x00FF0000
|
||||
|
||||
/**
|
||||
* p1022rdk_set_pixel_clock: program the DIU's clock
|
||||
*
|
||||
* @pixclock: the wavelength, in picoseconds, of the clock
|
||||
*/
|
||||
void p1022rdk_set_pixel_clock(unsigned int pixclock)
|
||||
{
|
||||
struct device_node *guts_np = NULL;
|
||||
struct ccsr_guts __iomem *guts;
|
||||
unsigned long freq;
|
||||
u64 temp;
|
||||
u32 pxclk;
|
||||
|
||||
/* Map the global utilities registers. */
|
||||
guts_np = of_find_compatible_node(NULL, NULL, "fsl,p1022-guts");
|
||||
if (!guts_np) {
|
||||
pr_err("p1022rdk: missing global utilties device node\n");
|
||||
return;
|
||||
}
|
||||
|
||||
guts = of_iomap(guts_np, 0);
|
||||
of_node_put(guts_np);
|
||||
if (!guts) {
|
||||
pr_err("p1022rdk: could not map global utilties device\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Convert pixclock from a wavelength to a frequency */
|
||||
temp = 1000000000000ULL;
|
||||
do_div(temp, pixclock);
|
||||
freq = temp;
|
||||
|
||||
/*
|
||||
* 'pxclk' is the ratio of the platform clock to the pixel clock.
|
||||
* This number is programmed into the CLKDVDR register, and the valid
|
||||
* range of values is 2-255.
|
||||
*/
|
||||
pxclk = DIV_ROUND_CLOSEST(fsl_get_sys_freq(), freq);
|
||||
pxclk = clamp_t(u32, pxclk, 2, 255);
|
||||
|
||||
/* Disable the pixel clock, and set it to non-inverted and no delay */
|
||||
clrbits32(&guts->clkdvdr,
|
||||
CLKDVDR_PXCKEN | CLKDVDR_PXCKDLY | CLKDVDR_PXCLK_MASK);
|
||||
|
||||
/* Enable the clock and set the pxclk */
|
||||
setbits32(&guts->clkdvdr, CLKDVDR_PXCKEN | (pxclk << 16));
|
||||
|
||||
iounmap(guts);
|
||||
}
|
||||
|
||||
/**
|
||||
* p1022rdk_valid_monitor_port: set the monitor port for sysfs
|
||||
*/
|
||||
enum fsl_diu_monitor_port
|
||||
p1022rdk_valid_monitor_port(enum fsl_diu_monitor_port port)
|
||||
{
|
||||
return FSL_DIU_PORT_DVI;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void __init p1022_rdk_pic_init(void)
|
||||
{
|
||||
struct mpic *mpic = mpic_alloc(NULL, 0, MPIC_BIG_ENDIAN |
|
||||
MPIC_SINGLE_DEST_CPU,
|
||||
0, 256, " OpenPIC ");
|
||||
BUG_ON(mpic == NULL);
|
||||
mpic_init(mpic);
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup the architecture
|
||||
*/
|
||||
static void __init p1022_rdk_setup_arch(void)
|
||||
{
|
||||
if (ppc_md.progress)
|
||||
ppc_md.progress("p1022_rdk_setup_arch()", 0);
|
||||
|
||||
#if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE)
|
||||
diu_ops.set_pixel_clock = p1022rdk_set_pixel_clock;
|
||||
diu_ops.valid_monitor_port = p1022rdk_valid_monitor_port;
|
||||
#endif
|
||||
|
||||
mpc85xx_smp_init();
|
||||
|
||||
fsl_pci_assign_primary();
|
||||
|
||||
swiotlb_detect_4g();
|
||||
|
||||
pr_info("Freescale / iVeia P1022 RDK reference board\n");
|
||||
}
|
||||
|
||||
machine_arch_initcall(p1022_rdk, mpc85xx_common_publish_devices);
|
||||
|
||||
machine_arch_initcall(p1022_rdk, swiotlb_setup_bus_notifier);
|
||||
|
||||
/*
|
||||
* Called very early, device-tree isn't unflattened
|
||||
*/
|
||||
static int __init p1022_rdk_probe(void)
|
||||
{
|
||||
unsigned long root = of_get_flat_dt_root();
|
||||
|
||||
return of_flat_dt_is_compatible(root, "fsl,p1022rdk");
|
||||
}
|
||||
|
||||
define_machine(p1022_rdk) {
|
||||
.name = "P1022 RDK",
|
||||
.probe = p1022_rdk_probe,
|
||||
.setup_arch = p1022_rdk_setup_arch,
|
||||
.init_IRQ = p1022_rdk_pic_init,
|
||||
#ifdef CONFIG_PCI
|
||||
.pcibios_fixup_bus = fsl_pcibios_fixup_bus,
|
||||
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
|
||||
#endif
|
||||
.get_irq = mpic_get_irq,
|
||||
.restart = fsl_rstcr_restart,
|
||||
.calibrate_decr = generic_calibrate_decr,
|
||||
.progress = udbg_progress,
|
||||
};
|
122
arch/powerpc/platforms/85xx/p1023_rdb.c
Normal file
122
arch/powerpc/platforms/85xx/p1023_rdb.c
Normal file
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
* Copyright 2010-2011, 2013 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* Author: Roy Zang <tie-fei.zang@freescale.com>
|
||||
*
|
||||
* Description:
|
||||
* P1023 RDB Board Setup
|
||||
*
|
||||
* 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/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/fsl_devices.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/of_device.h>
|
||||
|
||||
#include <asm/time.h>
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/pci-bridge.h>
|
||||
#include <mm/mmu_decl.h>
|
||||
#include <asm/prom.h>
|
||||
#include <asm/udbg.h>
|
||||
#include <asm/mpic.h>
|
||||
#include "smp.h"
|
||||
|
||||
#include <sysdev/fsl_soc.h>
|
||||
#include <sysdev/fsl_pci.h>
|
||||
|
||||
#include "mpc85xx.h"
|
||||
|
||||
/* ************************************************************************
|
||||
*
|
||||
* Setup the architecture
|
||||
*
|
||||
*/
|
||||
static void __init mpc85xx_rdb_setup_arch(void)
|
||||
{
|
||||
struct device_node *np;
|
||||
|
||||
if (ppc_md.progress)
|
||||
ppc_md.progress("p1023_rdb_setup_arch()", 0);
|
||||
|
||||
/* Map BCSR area */
|
||||
np = of_find_node_by_name(NULL, "bcsr");
|
||||
if (np != NULL) {
|
||||
static u8 __iomem *bcsr_regs;
|
||||
|
||||
bcsr_regs = of_iomap(np, 0);
|
||||
of_node_put(np);
|
||||
|
||||
if (!bcsr_regs) {
|
||||
printk(KERN_ERR
|
||||
"BCSR: Failed to map bcsr register space\n");
|
||||
return;
|
||||
} else {
|
||||
#define BCSR15_I2C_BUS0_SEG_CLR 0x07
|
||||
#define BCSR15_I2C_BUS0_SEG2 0x02
|
||||
/*
|
||||
* Note: Accessing exclusively i2c devices.
|
||||
*
|
||||
* The i2c controller selects initially ID EEPROM in the u-boot;
|
||||
* but if menu configuration selects RTC support in the kernel,
|
||||
* the i2c controller switches to select RTC chip in the kernel.
|
||||
*/
|
||||
#ifdef CONFIG_RTC_CLASS
|
||||
/* Enable RTC chip on the segment #2 of i2c */
|
||||
clrbits8(&bcsr_regs[15], BCSR15_I2C_BUS0_SEG_CLR);
|
||||
setbits8(&bcsr_regs[15], BCSR15_I2C_BUS0_SEG2);
|
||||
#endif
|
||||
|
||||
iounmap(bcsr_regs);
|
||||
}
|
||||
}
|
||||
|
||||
mpc85xx_smp_init();
|
||||
|
||||
fsl_pci_assign_primary();
|
||||
}
|
||||
|
||||
machine_arch_initcall(p1023_rdb, mpc85xx_common_publish_devices);
|
||||
|
||||
static void __init mpc85xx_rdb_pic_init(void)
|
||||
{
|
||||
struct mpic *mpic = mpic_alloc(NULL, 0, MPIC_BIG_ENDIAN |
|
||||
MPIC_SINGLE_DEST_CPU,
|
||||
0, 256, " OpenPIC ");
|
||||
|
||||
BUG_ON(mpic == NULL);
|
||||
|
||||
mpic_init(mpic);
|
||||
}
|
||||
|
||||
static int __init p1023_rdb_probe(void)
|
||||
{
|
||||
unsigned long root = of_get_flat_dt_root();
|
||||
|
||||
return of_flat_dt_is_compatible(root, "fsl,P1023RDB");
|
||||
|
||||
}
|
||||
|
||||
define_machine(p1023_rdb) {
|
||||
.name = "P1023 RDB",
|
||||
.probe = p1023_rdb_probe,
|
||||
.setup_arch = mpc85xx_rdb_setup_arch,
|
||||
.init_IRQ = mpc85xx_rdb_pic_init,
|
||||
.get_irq = mpic_get_irq,
|
||||
.restart = fsl_rstcr_restart,
|
||||
.calibrate_decr = generic_calibrate_decr,
|
||||
.progress = udbg_progress,
|
||||
#ifdef CONFIG_PCI
|
||||
.pcibios_fixup_bus = fsl_pcibios_fixup_bus,
|
||||
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
|
||||
#endif
|
||||
};
|
99
arch/powerpc/platforms/85xx/ppa8548.c
Normal file
99
arch/powerpc/platforms/85xx/ppa8548.c
Normal file
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
* ppa8548 setup and early boot code.
|
||||
*
|
||||
* Copyright 2009 Prodrive B.V..
|
||||
*
|
||||
* By Stef van Os (see MAINTAINERS for contact information)
|
||||
*
|
||||
* Based on the SBC8548 support - Copyright 2007 Wind River Systems Inc.
|
||||
* Based on the MPC8548CDS 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/init.h>
|
||||
#include <linux/reboot.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/of_fdt.h>
|
||||
#include <linux/of_platform.h>
|
||||
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/udbg.h>
|
||||
#include <asm/mpic.h>
|
||||
|
||||
#include <sysdev/fsl_soc.h>
|
||||
|
||||
static void __init ppa8548_pic_init(void)
|
||||
{
|
||||
struct mpic *mpic = mpic_alloc(NULL, 0, MPIC_BIG_ENDIAN,
|
||||
0, 256, " OpenPIC ");
|
||||
BUG_ON(mpic == NULL);
|
||||
mpic_init(mpic);
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup the architecture
|
||||
*/
|
||||
static void __init ppa8548_setup_arch(void)
|
||||
{
|
||||
if (ppc_md.progress)
|
||||
ppc_md.progress("ppa8548_setup_arch()", 0);
|
||||
}
|
||||
|
||||
static void ppa8548_show_cpuinfo(struct seq_file *m)
|
||||
{
|
||||
uint32_t svid, phid1;
|
||||
|
||||
svid = mfspr(SPRN_SVR);
|
||||
|
||||
seq_printf(m, "Vendor\t\t: Prodrive B.V.\n");
|
||||
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));
|
||||
}
|
||||
|
||||
static const struct of_device_id of_bus_ids[] __initconst = {
|
||||
{ .name = "soc", },
|
||||
{ .type = "soc", },
|
||||
{ .compatible = "simple-bus", },
|
||||
{ .compatible = "gianfar", },
|
||||
{ .compatible = "fsl,srio", },
|
||||
{},
|
||||
};
|
||||
|
||||
static int __init declare_of_platform_devices(void)
|
||||
{
|
||||
of_platform_bus_probe(NULL, of_bus_ids, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
machine_device_initcall(ppa8548, declare_of_platform_devices);
|
||||
|
||||
/*
|
||||
* Called very early, device-tree isn't unflattened
|
||||
*/
|
||||
static int __init ppa8548_probe(void)
|
||||
{
|
||||
unsigned long root = of_get_flat_dt_root();
|
||||
|
||||
return of_flat_dt_is_compatible(root, "ppa8548");
|
||||
}
|
||||
|
||||
define_machine(ppa8548) {
|
||||
.name = "ppa8548",
|
||||
.probe = ppa8548_probe,
|
||||
.setup_arch = ppa8548_setup_arch,
|
||||
.init_IRQ = ppa8548_pic_init,
|
||||
.show_cpuinfo = ppa8548_show_cpuinfo,
|
||||
.get_irq = mpic_get_irq,
|
||||
.restart = fsl_rstcr_restart,
|
||||
.calibrate_decr = generic_calibrate_decr,
|
||||
.progress = udbg_progress,
|
||||
};
|
85
arch/powerpc/platforms/85xx/qemu_e500.c
Normal file
85
arch/powerpc/platforms/85xx/qemu_e500.c
Normal file
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* Paravirt target for a generic QEMU e500 machine
|
||||
*
|
||||
* This is intended to be a flexible device-tree-driven platform, not fixed
|
||||
* to a particular piece of hardware or a particular spec of virtual hardware,
|
||||
* beyond the assumption of an e500-family CPU. Some things are still hardcoded
|
||||
* here, such as MPIC, but this is a limitation of the current code rather than
|
||||
* an interface contract with QEMU.
|
||||
*
|
||||
* Copyright 2012 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/kernel.h>
|
||||
#include <linux/of_fdt.h>
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/time.h>
|
||||
#include <asm/udbg.h>
|
||||
#include <asm/mpic.h>
|
||||
#include <sysdev/fsl_soc.h>
|
||||
#include <sysdev/fsl_pci.h>
|
||||
#include "smp.h"
|
||||
#include "mpc85xx.h"
|
||||
|
||||
void __init qemu_e500_pic_init(void)
|
||||
{
|
||||
struct mpic *mpic;
|
||||
unsigned int flags = MPIC_BIG_ENDIAN | MPIC_SINGLE_DEST_CPU |
|
||||
MPIC_ENABLE_COREINT;
|
||||
|
||||
mpic = mpic_alloc(NULL, 0, flags, 0, 256, " OpenPIC ");
|
||||
|
||||
BUG_ON(mpic == NULL);
|
||||
mpic_init(mpic);
|
||||
}
|
||||
|
||||
static void __init qemu_e500_setup_arch(void)
|
||||
{
|
||||
ppc_md.progress("qemu_e500_setup_arch()", 0);
|
||||
|
||||
fsl_pci_assign_primary();
|
||||
swiotlb_detect_4g();
|
||||
#if defined(CONFIG_FSL_PCI) && defined(CONFIG_ZONE_DMA32)
|
||||
/*
|
||||
* Inbound windows don't cover the full lower 4 GiB
|
||||
* due to conflicts with PCICSRBAR and outbound windows,
|
||||
* so limit the DMA32 zone to 2 GiB, to allow consistent
|
||||
* allocations to succeed.
|
||||
*/
|
||||
limit_zone_pfn(ZONE_DMA32, 1UL << (31 - PAGE_SHIFT));
|
||||
#endif
|
||||
mpc85xx_smp_init();
|
||||
}
|
||||
|
||||
/*
|
||||
* Called very early, device-tree isn't unflattened
|
||||
*/
|
||||
static int __init qemu_e500_probe(void)
|
||||
{
|
||||
unsigned long root = of_get_flat_dt_root();
|
||||
|
||||
return !!of_flat_dt_is_compatible(root, "fsl,qemu-e500");
|
||||
}
|
||||
|
||||
machine_arch_initcall(qemu_e500, mpc85xx_common_publish_devices);
|
||||
|
||||
define_machine(qemu_e500) {
|
||||
.name = "QEMU e500",
|
||||
.probe = qemu_e500_probe,
|
||||
.setup_arch = qemu_e500_setup_arch,
|
||||
.init_IRQ = qemu_e500_pic_init,
|
||||
#ifdef CONFIG_PCI
|
||||
.pcibios_fixup_bus = fsl_pcibios_fixup_bus,
|
||||
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
|
||||
#endif
|
||||
.get_irq = mpic_get_coreint_irq,
|
||||
.restart = fsl_rstcr_restart,
|
||||
.calibrate_decr = generic_calibrate_decr,
|
||||
.progress = udbg_progress,
|
||||
};
|
142
arch/powerpc/platforms/85xx/sbc8548.c
Normal file
142
arch/powerpc/platforms/85xx/sbc8548.c
Normal file
|
@ -0,0 +1,142 @@
|
|||
/*
|
||||
* Wind River SBC8548 setup and early boot code.
|
||||
*
|
||||
* Copyright 2007 Wind River Systems Inc.
|
||||
*
|
||||
* By Paul Gortmaker (see MAINTAINERS for contact information)
|
||||
*
|
||||
* Based largely on the MPC8548CDS 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/init.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/reboot.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/kdev_t.h>
|
||||
#include <linux/major.h>
|
||||
#include <linux/console.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/initrd.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/fsl_devices.h>
|
||||
#include <linux/of_platform.h>
|
||||
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/page.h>
|
||||
#include <linux/atomic.h>
|
||||
#include <asm/time.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/ipic.h>
|
||||
#include <asm/pci-bridge.h>
|
||||
#include <asm/irq.h>
|
||||
#include <mm/mmu_decl.h>
|
||||
#include <asm/prom.h>
|
||||
#include <asm/udbg.h>
|
||||
#include <asm/mpic.h>
|
||||
|
||||
#include <sysdev/fsl_soc.h>
|
||||
#include <sysdev/fsl_pci.h>
|
||||
|
||||
#include "mpc85xx.h"
|
||||
|
||||
static int sbc_rev;
|
||||
|
||||
static void __init sbc8548_pic_init(void)
|
||||
{
|
||||
struct mpic *mpic = mpic_alloc(NULL, 0, MPIC_BIG_ENDIAN,
|
||||
0, 256, " OpenPIC ");
|
||||
BUG_ON(mpic == NULL);
|
||||
mpic_init(mpic);
|
||||
}
|
||||
|
||||
/* Extract the HW Rev from the EPLD on the board */
|
||||
static int __init sbc8548_hw_rev(void)
|
||||
{
|
||||
struct device_node *np;
|
||||
struct resource res;
|
||||
unsigned int *rev;
|
||||
int board_rev = 0;
|
||||
|
||||
np = of_find_compatible_node(NULL, NULL, "hw-rev");
|
||||
if (np == NULL) {
|
||||
printk("No HW-REV found in DTB.\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
of_address_to_resource(np, 0, &res);
|
||||
of_node_put(np);
|
||||
|
||||
rev = ioremap(res.start,sizeof(unsigned int));
|
||||
board_rev = (*rev) >> 28;
|
||||
iounmap(rev);
|
||||
|
||||
return board_rev;
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup the architecture
|
||||
*/
|
||||
static void __init sbc8548_setup_arch(void)
|
||||
{
|
||||
if (ppc_md.progress)
|
||||
ppc_md.progress("sbc8548_setup_arch()", 0);
|
||||
|
||||
fsl_pci_assign_primary();
|
||||
|
||||
sbc_rev = sbc8548_hw_rev();
|
||||
}
|
||||
|
||||
static void sbc8548_show_cpuinfo(struct seq_file *m)
|
||||
{
|
||||
uint pvid, svid, phid1;
|
||||
|
||||
pvid = mfspr(SPRN_PVR);
|
||||
svid = mfspr(SPRN_SVR);
|
||||
|
||||
seq_printf(m, "Vendor\t\t: Wind River\n");
|
||||
seq_printf(m, "Machine\t\t: SBC8548 v%d\n", sbc_rev);
|
||||
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));
|
||||
}
|
||||
|
||||
machine_arch_initcall(sbc8548, mpc85xx_common_publish_devices);
|
||||
|
||||
/*
|
||||
* Called very early, device-tree isn't unflattened
|
||||
*/
|
||||
static int __init sbc8548_probe(void)
|
||||
{
|
||||
unsigned long root = of_get_flat_dt_root();
|
||||
|
||||
return of_flat_dt_is_compatible(root, "SBC8548");
|
||||
}
|
||||
|
||||
define_machine(sbc8548) {
|
||||
.name = "SBC8548",
|
||||
.probe = sbc8548_probe,
|
||||
.setup_arch = sbc8548_setup_arch,
|
||||
.init_IRQ = sbc8548_pic_init,
|
||||
.show_cpuinfo = sbc8548_show_cpuinfo,
|
||||
.get_irq = mpic_get_irq,
|
||||
.restart = fsl_rstcr_restart,
|
||||
#ifdef CONFIG_PCI
|
||||
.pcibios_fixup_bus = fsl_pcibios_fixup_bus,
|
||||
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
|
||||
#endif
|
||||
.calibrate_decr = generic_calibrate_decr,
|
||||
.progress = udbg_progress,
|
||||
};
|
176
arch/powerpc/platforms/85xx/sgy_cts1000.c
Normal file
176
arch/powerpc/platforms/85xx/sgy_cts1000.c
Normal file
|
@ -0,0 +1,176 @@
|
|||
/*
|
||||
* Servergy CTS-1000 Setup
|
||||
*
|
||||
* Maintained by Ben Collins <ben.c@servergy.com>
|
||||
*
|
||||
* Copyright 2012 by Servergy, 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/platform_device.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/reboot.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
#include <asm/machdep.h>
|
||||
|
||||
static struct device_node *halt_node;
|
||||
|
||||
static const struct of_device_id child_match[] = {
|
||||
{
|
||||
.compatible = "sgy,gpio-halt",
|
||||
},
|
||||
{},
|
||||
};
|
||||
|
||||
static void gpio_halt_wfn(struct work_struct *work)
|
||||
{
|
||||
/* Likely wont return */
|
||||
orderly_poweroff(true);
|
||||
}
|
||||
static DECLARE_WORK(gpio_halt_wq, gpio_halt_wfn);
|
||||
|
||||
static void gpio_halt_cb(void)
|
||||
{
|
||||
enum of_gpio_flags flags;
|
||||
int trigger, gpio;
|
||||
|
||||
if (!halt_node)
|
||||
return;
|
||||
|
||||
gpio = of_get_gpio_flags(halt_node, 0, &flags);
|
||||
|
||||
if (!gpio_is_valid(gpio))
|
||||
return;
|
||||
|
||||
trigger = (flags == OF_GPIO_ACTIVE_LOW);
|
||||
|
||||
printk(KERN_INFO "gpio-halt: triggering GPIO.\n");
|
||||
|
||||
/* Probably wont return */
|
||||
gpio_set_value(gpio, trigger);
|
||||
}
|
||||
|
||||
/* This IRQ means someone pressed the power button and it is waiting for us
|
||||
* to handle the shutdown/poweroff. */
|
||||
static irqreturn_t gpio_halt_irq(int irq, void *__data)
|
||||
{
|
||||
printk(KERN_INFO "gpio-halt: shutdown due to power button IRQ.\n");
|
||||
schedule_work(&gpio_halt_wq);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
};
|
||||
|
||||
static int gpio_halt_probe(struct platform_device *pdev)
|
||||
{
|
||||
enum of_gpio_flags flags;
|
||||
struct device_node *node = pdev->dev.of_node;
|
||||
int gpio, err, irq;
|
||||
int trigger;
|
||||
|
||||
if (!node)
|
||||
return -ENODEV;
|
||||
|
||||
/* If there's no matching child, this isn't really an error */
|
||||
halt_node = of_find_matching_node(node, child_match);
|
||||
if (!halt_node)
|
||||
return 0;
|
||||
|
||||
/* Technically we could just read the first one, but punish
|
||||
* DT writers for invalid form. */
|
||||
if (of_gpio_count(halt_node) != 1)
|
||||
return -EINVAL;
|
||||
|
||||
/* Get the gpio number relative to the dynamic base. */
|
||||
gpio = of_get_gpio_flags(halt_node, 0, &flags);
|
||||
if (!gpio_is_valid(gpio))
|
||||
return -EINVAL;
|
||||
|
||||
err = gpio_request(gpio, "gpio-halt");
|
||||
if (err) {
|
||||
printk(KERN_ERR "gpio-halt: error requesting GPIO %d.\n",
|
||||
gpio);
|
||||
halt_node = NULL;
|
||||
return err;
|
||||
}
|
||||
|
||||
trigger = (flags == OF_GPIO_ACTIVE_LOW);
|
||||
|
||||
gpio_direction_output(gpio, !trigger);
|
||||
|
||||
/* Now get the IRQ which tells us when the power button is hit */
|
||||
irq = irq_of_parse_and_map(halt_node, 0);
|
||||
err = request_irq(irq, gpio_halt_irq, IRQF_TRIGGER_RISING |
|
||||
IRQF_TRIGGER_FALLING, "gpio-halt", halt_node);
|
||||
if (err) {
|
||||
printk(KERN_ERR "gpio-halt: error requesting IRQ %d for "
|
||||
"GPIO %d.\n", irq, gpio);
|
||||
gpio_free(gpio);
|
||||
halt_node = NULL;
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Register our halt function */
|
||||
ppc_md.halt = gpio_halt_cb;
|
||||
ppc_md.power_off = gpio_halt_cb;
|
||||
|
||||
printk(KERN_INFO "gpio-halt: registered GPIO %d (%d trigger, %d"
|
||||
" irq).\n", gpio, trigger, irq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gpio_halt_remove(struct platform_device *pdev)
|
||||
{
|
||||
if (halt_node) {
|
||||
int gpio = of_get_gpio(halt_node, 0);
|
||||
int irq = irq_of_parse_and_map(halt_node, 0);
|
||||
|
||||
free_irq(irq, halt_node);
|
||||
|
||||
ppc_md.halt = NULL;
|
||||
ppc_md.power_off = NULL;
|
||||
|
||||
gpio_free(gpio);
|
||||
|
||||
halt_node = NULL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id gpio_halt_match[] = {
|
||||
/* We match on the gpio bus itself and scan the children since they
|
||||
* wont be matched against us. We know the bus wont match until it
|
||||
* has been registered too. */
|
||||
{
|
||||
.compatible = "fsl,qoriq-gpio",
|
||||
},
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, gpio_halt_match);
|
||||
|
||||
static struct platform_driver gpio_halt_driver = {
|
||||
.driver = {
|
||||
.name = "gpio-halt",
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = gpio_halt_match,
|
||||
},
|
||||
.probe = gpio_halt_probe,
|
||||
.remove = gpio_halt_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(gpio_halt_driver);
|
||||
|
||||
MODULE_DESCRIPTION("Driver to support GPIO triggered system halt for Servergy CTS-1000 Systems.");
|
||||
MODULE_VERSION("1.0");
|
||||
MODULE_AUTHOR("Ben Collins <ben.c@servergy.com>");
|
||||
MODULE_LICENSE("GPL");
|
504
arch/powerpc/platforms/85xx/smp.c
Normal file
504
arch/powerpc/platforms/85xx/smp.c
Normal file
|
@ -0,0 +1,504 @@
|
|||
/*
|
||||
* Author: Andy Fleming <afleming@freescale.com>
|
||||
* Kumar Gala <galak@kernel.crashing.org>
|
||||
*
|
||||
* Copyright 2006-2008, 2011-2012 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/init.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/kexec.h>
|
||||
#include <linux/highmem.h>
|
||||
#include <linux/cpu.h>
|
||||
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/page.h>
|
||||
#include <asm/mpic.h>
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/dbell.h>
|
||||
#include <asm/fsl_guts.h>
|
||||
#include <asm/code-patching.h>
|
||||
#include <asm/cputhreads.h>
|
||||
|
||||
#include <sysdev/fsl_soc.h>
|
||||
#include <sysdev/mpic.h>
|
||||
#include "smp.h"
|
||||
|
||||
struct epapr_spin_table {
|
||||
u32 addr_h;
|
||||
u32 addr_l;
|
||||
u32 r3_h;
|
||||
u32 r3_l;
|
||||
u32 reserved;
|
||||
u32 pir;
|
||||
};
|
||||
|
||||
static struct ccsr_guts __iomem *guts;
|
||||
static u64 timebase;
|
||||
static int tb_req;
|
||||
static int tb_valid;
|
||||
|
||||
static void mpc85xx_timebase_freeze(int freeze)
|
||||
{
|
||||
uint32_t mask;
|
||||
|
||||
mask = CCSR_GUTS_DEVDISR_TB0 | CCSR_GUTS_DEVDISR_TB1;
|
||||
if (freeze)
|
||||
setbits32(&guts->devdisr, mask);
|
||||
else
|
||||
clrbits32(&guts->devdisr, mask);
|
||||
|
||||
in_be32(&guts->devdisr);
|
||||
}
|
||||
|
||||
static void mpc85xx_give_timebase(void)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
local_irq_save(flags);
|
||||
|
||||
while (!tb_req)
|
||||
barrier();
|
||||
tb_req = 0;
|
||||
|
||||
mpc85xx_timebase_freeze(1);
|
||||
#ifdef CONFIG_PPC64
|
||||
/*
|
||||
* e5500/e6500 have a workaround for erratum A-006958 in place
|
||||
* that will reread the timebase until TBL is non-zero.
|
||||
* That would be a bad thing when the timebase is frozen.
|
||||
*
|
||||
* Thus, we read it manually, and instead of checking that
|
||||
* TBL is non-zero, we ensure that TB does not change. We don't
|
||||
* do that for the main mftb implementation, because it requires
|
||||
* a scratch register
|
||||
*/
|
||||
{
|
||||
u64 prev;
|
||||
|
||||
asm volatile("mfspr %0, %1" : "=r" (timebase) :
|
||||
"i" (SPRN_TBRL));
|
||||
|
||||
do {
|
||||
prev = timebase;
|
||||
asm volatile("mfspr %0, %1" : "=r" (timebase) :
|
||||
"i" (SPRN_TBRL));
|
||||
} while (prev != timebase);
|
||||
}
|
||||
#else
|
||||
timebase = get_tb();
|
||||
#endif
|
||||
mb();
|
||||
tb_valid = 1;
|
||||
|
||||
while (tb_valid)
|
||||
barrier();
|
||||
|
||||
mpc85xx_timebase_freeze(0);
|
||||
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
|
||||
static void mpc85xx_take_timebase(void)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
local_irq_save(flags);
|
||||
|
||||
tb_req = 1;
|
||||
while (!tb_valid)
|
||||
barrier();
|
||||
|
||||
set_tb(timebase >> 32, timebase & 0xffffffff);
|
||||
isync();
|
||||
tb_valid = 0;
|
||||
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HOTPLUG_CPU
|
||||
static void smp_85xx_mach_cpu_die(void)
|
||||
{
|
||||
unsigned int cpu = smp_processor_id();
|
||||
u32 tmp;
|
||||
|
||||
local_irq_disable();
|
||||
idle_task_exit();
|
||||
generic_set_cpu_dead(cpu);
|
||||
mb();
|
||||
|
||||
mtspr(SPRN_TCR, 0);
|
||||
|
||||
__flush_disable_L1();
|
||||
tmp = (mfspr(SPRN_HID0) & ~(HID0_DOZE|HID0_SLEEP)) | HID0_NAP;
|
||||
mtspr(SPRN_HID0, tmp);
|
||||
isync();
|
||||
|
||||
/* Enter NAP mode. */
|
||||
tmp = mfmsr();
|
||||
tmp |= MSR_WE;
|
||||
mb();
|
||||
mtmsr(tmp);
|
||||
isync();
|
||||
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline void flush_spin_table(void *spin_table)
|
||||
{
|
||||
flush_dcache_range((ulong)spin_table,
|
||||
(ulong)spin_table + sizeof(struct epapr_spin_table));
|
||||
}
|
||||
|
||||
static inline u32 read_spin_table_addr_l(void *spin_table)
|
||||
{
|
||||
flush_dcache_range((ulong)spin_table,
|
||||
(ulong)spin_table + sizeof(struct epapr_spin_table));
|
||||
return in_be32(&((struct epapr_spin_table *)spin_table)->addr_l);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PPC64
|
||||
static void wake_hw_thread(void *info)
|
||||
{
|
||||
void fsl_secondary_thread_init(void);
|
||||
unsigned long imsr1, inia1;
|
||||
int nr = *(const int *)info;
|
||||
|
||||
imsr1 = MSR_KERNEL;
|
||||
inia1 = *(unsigned long *)fsl_secondary_thread_init;
|
||||
|
||||
mttmr(TMRN_IMSR1, imsr1);
|
||||
mttmr(TMRN_INIA1, inia1);
|
||||
mtspr(SPRN_TENS, TEN_THREAD(1));
|
||||
|
||||
smp_generic_kick_cpu(nr);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int smp_85xx_kick_cpu(int nr)
|
||||
{
|
||||
unsigned long flags;
|
||||
const u64 *cpu_rel_addr;
|
||||
__iomem struct epapr_spin_table *spin_table;
|
||||
struct device_node *np;
|
||||
int hw_cpu = get_hard_smp_processor_id(nr);
|
||||
int ioremappable;
|
||||
int ret = 0;
|
||||
|
||||
WARN_ON(nr < 0 || nr >= NR_CPUS);
|
||||
WARN_ON(hw_cpu < 0 || hw_cpu >= NR_CPUS);
|
||||
|
||||
pr_debug("smp_85xx_kick_cpu: kick CPU #%d\n", nr);
|
||||
|
||||
#ifdef CONFIG_PPC64
|
||||
/* Threads don't use the spin table */
|
||||
if (cpu_thread_in_core(nr) != 0) {
|
||||
int primary = cpu_first_thread_sibling(nr);
|
||||
|
||||
if (WARN_ON_ONCE(!cpu_has_feature(CPU_FTR_SMT)))
|
||||
return -ENOENT;
|
||||
|
||||
if (cpu_thread_in_core(nr) != 1) {
|
||||
pr_err("%s: cpu %d: invalid hw thread %d\n",
|
||||
__func__, nr, cpu_thread_in_core(nr));
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
if (!cpu_online(primary)) {
|
||||
pr_err("%s: cpu %d: primary %d not online\n",
|
||||
__func__, nr, primary);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
smp_call_function_single(primary, wake_hw_thread, &nr, 0);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
np = of_get_cpu_node(nr, NULL);
|
||||
cpu_rel_addr = of_get_property(np, "cpu-release-addr", NULL);
|
||||
|
||||
if (cpu_rel_addr == NULL) {
|
||||
printk(KERN_ERR "No cpu-release-addr for cpu %d\n", nr);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
/*
|
||||
* A secondary core could be in a spinloop in the bootpage
|
||||
* (0xfffff000), somewhere in highmem, or somewhere in lowmem.
|
||||
* The bootpage and highmem can be accessed via ioremap(), but
|
||||
* we need to directly access the spinloop if its in lowmem.
|
||||
*/
|
||||
ioremappable = *cpu_rel_addr > virt_to_phys(high_memory);
|
||||
|
||||
/* Map the spin table */
|
||||
if (ioremappable)
|
||||
spin_table = ioremap_prot(*cpu_rel_addr,
|
||||
sizeof(struct epapr_spin_table), _PAGE_COHERENT);
|
||||
else
|
||||
spin_table = phys_to_virt(*cpu_rel_addr);
|
||||
|
||||
local_irq_save(flags);
|
||||
#ifdef CONFIG_PPC32
|
||||
#ifdef CONFIG_HOTPLUG_CPU
|
||||
/* Corresponding to generic_set_cpu_dead() */
|
||||
generic_set_cpu_up(nr);
|
||||
|
||||
if (system_state == SYSTEM_RUNNING) {
|
||||
/*
|
||||
* To keep it compatible with old boot program which uses
|
||||
* cache-inhibit spin table, we need to flush the cache
|
||||
* before accessing spin table to invalidate any staled data.
|
||||
* We also need to flush the cache after writing to spin
|
||||
* table to push data out.
|
||||
*/
|
||||
flush_spin_table(spin_table);
|
||||
out_be32(&spin_table->addr_l, 0);
|
||||
flush_spin_table(spin_table);
|
||||
|
||||
/*
|
||||
* We don't set the BPTR register here since it already points
|
||||
* to the boot page properly.
|
||||
*/
|
||||
mpic_reset_core(nr);
|
||||
|
||||
/*
|
||||
* wait until core is ready...
|
||||
* We need to invalidate the stale data, in case the boot
|
||||
* loader uses a cache-inhibited spin table.
|
||||
*/
|
||||
if (!spin_event_timeout(
|
||||
read_spin_table_addr_l(spin_table) == 1,
|
||||
10000, 100)) {
|
||||
pr_err("%s: timeout waiting for core %d to reset\n",
|
||||
__func__, hw_cpu);
|
||||
ret = -ENOENT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* clear the acknowledge status */
|
||||
__secondary_hold_acknowledge = -1;
|
||||
}
|
||||
#endif
|
||||
flush_spin_table(spin_table);
|
||||
out_be32(&spin_table->pir, hw_cpu);
|
||||
out_be32(&spin_table->addr_l, __pa(__early_start));
|
||||
flush_spin_table(spin_table);
|
||||
|
||||
/* Wait a bit for the CPU to ack. */
|
||||
if (!spin_event_timeout(__secondary_hold_acknowledge == hw_cpu,
|
||||
10000, 100)) {
|
||||
pr_err("%s: timeout waiting for core %d to ack\n",
|
||||
__func__, hw_cpu);
|
||||
ret = -ENOENT;
|
||||
goto out;
|
||||
}
|
||||
out:
|
||||
#else
|
||||
smp_generic_kick_cpu(nr);
|
||||
|
||||
flush_spin_table(spin_table);
|
||||
out_be32(&spin_table->pir, hw_cpu);
|
||||
out_be64((u64 *)(&spin_table->addr_h),
|
||||
__pa(ppc_function_entry(generic_secondary_smp_init)));
|
||||
flush_spin_table(spin_table);
|
||||
#endif
|
||||
|
||||
local_irq_restore(flags);
|
||||
|
||||
if (ioremappable)
|
||||
iounmap(spin_table);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct smp_ops_t smp_85xx_ops = {
|
||||
.kick_cpu = smp_85xx_kick_cpu,
|
||||
.cpu_bootable = smp_generic_cpu_bootable,
|
||||
#ifdef CONFIG_HOTPLUG_CPU
|
||||
.cpu_disable = generic_cpu_disable,
|
||||
.cpu_die = generic_cpu_die,
|
||||
#endif
|
||||
#ifdef CONFIG_KEXEC
|
||||
.give_timebase = smp_generic_give_timebase,
|
||||
.take_timebase = smp_generic_take_timebase,
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef CONFIG_KEXEC
|
||||
atomic_t kexec_down_cpus = ATOMIC_INIT(0);
|
||||
|
||||
void mpc85xx_smp_kexec_cpu_down(int crash_shutdown, int secondary)
|
||||
{
|
||||
local_irq_disable();
|
||||
|
||||
if (secondary) {
|
||||
atomic_inc(&kexec_down_cpus);
|
||||
/* loop forever */
|
||||
while (1);
|
||||
}
|
||||
}
|
||||
|
||||
static void mpc85xx_smp_kexec_down(void *arg)
|
||||
{
|
||||
if (ppc_md.kexec_cpu_down)
|
||||
ppc_md.kexec_cpu_down(0,1);
|
||||
}
|
||||
|
||||
static void map_and_flush(unsigned long paddr)
|
||||
{
|
||||
struct page *page = pfn_to_page(paddr >> PAGE_SHIFT);
|
||||
unsigned long kaddr = (unsigned long)kmap(page);
|
||||
|
||||
flush_dcache_range(kaddr, kaddr + PAGE_SIZE);
|
||||
kunmap(page);
|
||||
}
|
||||
|
||||
/**
|
||||
* Before we reset the other cores, we need to flush relevant cache
|
||||
* out to memory so we don't get anything corrupted, some of these flushes
|
||||
* are performed out of an overabundance of caution as interrupts are not
|
||||
* disabled yet and we can switch cores
|
||||
*/
|
||||
static void mpc85xx_smp_flush_dcache_kexec(struct kimage *image)
|
||||
{
|
||||
kimage_entry_t *ptr, entry;
|
||||
unsigned long paddr;
|
||||
int i;
|
||||
|
||||
if (image->type == KEXEC_TYPE_DEFAULT) {
|
||||
/* normal kexec images are stored in temporary pages */
|
||||
for (ptr = &image->head; (entry = *ptr) && !(entry & IND_DONE);
|
||||
ptr = (entry & IND_INDIRECTION) ?
|
||||
phys_to_virt(entry & PAGE_MASK) : ptr + 1) {
|
||||
if (!(entry & IND_DESTINATION)) {
|
||||
map_and_flush(entry);
|
||||
}
|
||||
}
|
||||
/* flush out last IND_DONE page */
|
||||
map_and_flush(entry);
|
||||
} else {
|
||||
/* crash type kexec images are copied to the crash region */
|
||||
for (i = 0; i < image->nr_segments; i++) {
|
||||
struct kexec_segment *seg = &image->segment[i];
|
||||
for (paddr = seg->mem; paddr < seg->mem + seg->memsz;
|
||||
paddr += PAGE_SIZE) {
|
||||
map_and_flush(paddr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* also flush the kimage struct to be passed in as well */
|
||||
flush_dcache_range((unsigned long)image,
|
||||
(unsigned long)image + sizeof(*image));
|
||||
}
|
||||
|
||||
static void mpc85xx_smp_machine_kexec(struct kimage *image)
|
||||
{
|
||||
int timeout = INT_MAX;
|
||||
int i, num_cpus = num_present_cpus();
|
||||
|
||||
mpc85xx_smp_flush_dcache_kexec(image);
|
||||
|
||||
if (image->type == KEXEC_TYPE_DEFAULT)
|
||||
smp_call_function(mpc85xx_smp_kexec_down, NULL, 0);
|
||||
|
||||
while ( (atomic_read(&kexec_down_cpus) != (num_cpus - 1)) &&
|
||||
( timeout > 0 ) )
|
||||
{
|
||||
timeout--;
|
||||
}
|
||||
|
||||
if ( !timeout )
|
||||
printk(KERN_ERR "Unable to bring down secondary cpu(s)");
|
||||
|
||||
for_each_online_cpu(i)
|
||||
{
|
||||
if ( i == smp_processor_id() ) continue;
|
||||
mpic_reset_core(i);
|
||||
}
|
||||
|
||||
default_machine_kexec(image);
|
||||
}
|
||||
#endif /* CONFIG_KEXEC */
|
||||
|
||||
static void smp_85xx_basic_setup(int cpu_nr)
|
||||
{
|
||||
if (cpu_has_feature(CPU_FTR_DBELL))
|
||||
doorbell_setup_this_cpu();
|
||||
}
|
||||
|
||||
static void smp_85xx_setup_cpu(int cpu_nr)
|
||||
{
|
||||
mpic_setup_this_cpu();
|
||||
smp_85xx_basic_setup(cpu_nr);
|
||||
}
|
||||
|
||||
static const struct of_device_id mpc85xx_smp_guts_ids[] = {
|
||||
{ .compatible = "fsl,mpc8572-guts", },
|
||||
{ .compatible = "fsl,p1020-guts", },
|
||||
{ .compatible = "fsl,p1021-guts", },
|
||||
{ .compatible = "fsl,p1022-guts", },
|
||||
{ .compatible = "fsl,p1023-guts", },
|
||||
{ .compatible = "fsl,p2020-guts", },
|
||||
{},
|
||||
};
|
||||
|
||||
void __init mpc85xx_smp_init(void)
|
||||
{
|
||||
struct device_node *np;
|
||||
|
||||
|
||||
np = of_find_node_by_type(NULL, "open-pic");
|
||||
if (np) {
|
||||
smp_85xx_ops.probe = smp_mpic_probe;
|
||||
smp_85xx_ops.setup_cpu = smp_85xx_setup_cpu;
|
||||
smp_85xx_ops.message_pass = smp_mpic_message_pass;
|
||||
} else
|
||||
smp_85xx_ops.setup_cpu = smp_85xx_basic_setup;
|
||||
|
||||
if (cpu_has_feature(CPU_FTR_DBELL)) {
|
||||
/*
|
||||
* If left NULL, .message_pass defaults to
|
||||
* smp_muxed_ipi_message_pass
|
||||
*/
|
||||
smp_85xx_ops.message_pass = NULL;
|
||||
smp_85xx_ops.cause_ipi = doorbell_cause_ipi;
|
||||
smp_85xx_ops.probe = NULL;
|
||||
}
|
||||
|
||||
np = of_find_matching_node(NULL, mpc85xx_smp_guts_ids);
|
||||
if (np) {
|
||||
guts = of_iomap(np, 0);
|
||||
of_node_put(np);
|
||||
if (!guts) {
|
||||
pr_err("%s: Could not map guts node address\n",
|
||||
__func__);
|
||||
return;
|
||||
}
|
||||
smp_85xx_ops.give_timebase = mpc85xx_give_timebase;
|
||||
smp_85xx_ops.take_timebase = mpc85xx_take_timebase;
|
||||
#ifdef CONFIG_HOTPLUG_CPU
|
||||
ppc_md.cpu_die = smp_85xx_mach_cpu_die;
|
||||
#endif
|
||||
}
|
||||
|
||||
smp_ops = &smp_85xx_ops;
|
||||
|
||||
#ifdef CONFIG_KEXEC
|
||||
ppc_md.kexec_cpu_down = mpc85xx_smp_kexec_cpu_down;
|
||||
ppc_md.machine_kexec = mpc85xx_smp_machine_kexec;
|
||||
#endif
|
||||
}
|
15
arch/powerpc/platforms/85xx/smp.h
Normal file
15
arch/powerpc/platforms/85xx/smp.h
Normal file
|
@ -0,0 +1,15 @@
|
|||
#ifndef POWERPC_85XX_SMP_H_
|
||||
#define POWERPC_85XX_SMP_H_ 1
|
||||
|
||||
#include <linux/init.h>
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
void __init mpc85xx_smp_init(void);
|
||||
#else
|
||||
static inline void mpc85xx_smp_init(void)
|
||||
{
|
||||
/* Nothing to do */
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* not POWERPC_85XX_SMP_H_ */
|
99
arch/powerpc/platforms/85xx/socrates.c
Normal file
99
arch/powerpc/platforms/85xx/socrates.c
Normal file
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
* Copyright (c) 2008 Emcraft Systems
|
||||
* Sergei Poselenov <sposelenov@emcraft.com>
|
||||
*
|
||||
* Based on MPC8560 ADS and arch/ppc tqm85xx ports
|
||||
*
|
||||
* Maintained by Kumar Gala (see MAINTAINERS for contact information)
|
||||
*
|
||||
* Copyright 2008 Freescale Semiconductor Inc.
|
||||
*
|
||||
* Copyright (c) 2005-2006 DENX Software Engineering
|
||||
* Stefan Roese <sr@denx.de>
|
||||
*
|
||||
* Based on original work by
|
||||
* Kumar Gala <kumar.gala@freescale.com>
|
||||
* Copyright 2004 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/delay.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/of_platform.h>
|
||||
|
||||
#include <asm/time.h>
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/pci-bridge.h>
|
||||
#include <asm/mpic.h>
|
||||
#include <asm/prom.h>
|
||||
#include <mm/mmu_decl.h>
|
||||
#include <asm/udbg.h>
|
||||
|
||||
#include <sysdev/fsl_soc.h>
|
||||
#include <sysdev/fsl_pci.h>
|
||||
|
||||
#include "mpc85xx.h"
|
||||
#include "socrates_fpga_pic.h"
|
||||
|
||||
static void __init socrates_pic_init(void)
|
||||
{
|
||||
struct device_node *np;
|
||||
|
||||
struct mpic *mpic = mpic_alloc(NULL, 0, MPIC_BIG_ENDIAN,
|
||||
0, 256, " OpenPIC ");
|
||||
BUG_ON(mpic == NULL);
|
||||
mpic_init(mpic);
|
||||
|
||||
np = of_find_compatible_node(NULL, NULL, "abb,socrates-fpga-pic");
|
||||
if (!np) {
|
||||
printk(KERN_ERR "Could not find socrates-fpga-pic node\n");
|
||||
return;
|
||||
}
|
||||
socrates_fpga_pic_init(np);
|
||||
of_node_put(np);
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup the architecture
|
||||
*/
|
||||
static void __init socrates_setup_arch(void)
|
||||
{
|
||||
if (ppc_md.progress)
|
||||
ppc_md.progress("socrates_setup_arch()", 0);
|
||||
|
||||
fsl_pci_assign_primary();
|
||||
}
|
||||
|
||||
machine_arch_initcall(socrates, mpc85xx_common_publish_devices);
|
||||
|
||||
/*
|
||||
* Called very early, device-tree isn't unflattened
|
||||
*/
|
||||
static int __init socrates_probe(void)
|
||||
{
|
||||
unsigned long root = of_get_flat_dt_root();
|
||||
|
||||
if (of_flat_dt_is_compatible(root, "abb,socrates"))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
define_machine(socrates) {
|
||||
.name = "Socrates",
|
||||
.probe = socrates_probe,
|
||||
.setup_arch = socrates_setup_arch,
|
||||
.init_IRQ = socrates_pic_init,
|
||||
.get_irq = mpic_get_irq,
|
||||
.restart = fsl_rstcr_restart,
|
||||
.calibrate_decr = generic_calibrate_decr,
|
||||
.progress = udbg_progress,
|
||||
};
|
314
arch/powerpc/platforms/85xx/socrates_fpga_pic.c
Normal file
314
arch/powerpc/platforms/85xx/socrates_fpga_pic.c
Normal file
|
@ -0,0 +1,314 @@
|
|||
/*
|
||||
* Copyright (C) 2008 Ilya Yanok, Emcraft Systems
|
||||
*
|
||||
*
|
||||
* 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/irq.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
/*
|
||||
* The FPGA supports 9 interrupt sources, which can be routed to 3
|
||||
* interrupt request lines of the MPIC. The line to be used can be
|
||||
* specified through the third cell of FDT property "interrupts".
|
||||
*/
|
||||
|
||||
#define SOCRATES_FPGA_NUM_IRQS 9
|
||||
|
||||
#define FPGA_PIC_IRQCFG (0x0)
|
||||
#define FPGA_PIC_IRQMASK(n) (0x4 + 0x4 * (n))
|
||||
|
||||
#define SOCRATES_FPGA_IRQ_MASK ((1 << SOCRATES_FPGA_NUM_IRQS) - 1)
|
||||
|
||||
struct socrates_fpga_irq_info {
|
||||
unsigned int irq_line;
|
||||
int type;
|
||||
};
|
||||
|
||||
/*
|
||||
* Interrupt routing and type table
|
||||
*
|
||||
* IRQ_TYPE_NONE means the interrupt type is configurable,
|
||||
* otherwise it's fixed to the specified value.
|
||||
*/
|
||||
static struct socrates_fpga_irq_info fpga_irqs[SOCRATES_FPGA_NUM_IRQS] = {
|
||||
[0] = {0, IRQ_TYPE_NONE},
|
||||
[1] = {0, IRQ_TYPE_LEVEL_HIGH},
|
||||
[2] = {0, IRQ_TYPE_LEVEL_LOW},
|
||||
[3] = {0, IRQ_TYPE_NONE},
|
||||
[4] = {0, IRQ_TYPE_NONE},
|
||||
[5] = {0, IRQ_TYPE_NONE},
|
||||
[6] = {0, IRQ_TYPE_NONE},
|
||||
[7] = {0, IRQ_TYPE_NONE},
|
||||
[8] = {0, IRQ_TYPE_LEVEL_HIGH},
|
||||
};
|
||||
|
||||
static DEFINE_RAW_SPINLOCK(socrates_fpga_pic_lock);
|
||||
|
||||
static void __iomem *socrates_fpga_pic_iobase;
|
||||
static struct irq_domain *socrates_fpga_pic_irq_host;
|
||||
static unsigned int socrates_fpga_irqs[3];
|
||||
|
||||
static inline uint32_t socrates_fpga_pic_read(int reg)
|
||||
{
|
||||
return in_be32(socrates_fpga_pic_iobase + reg);
|
||||
}
|
||||
|
||||
static inline void socrates_fpga_pic_write(int reg, uint32_t val)
|
||||
{
|
||||
out_be32(socrates_fpga_pic_iobase + reg, val);
|
||||
}
|
||||
|
||||
static inline unsigned int socrates_fpga_pic_get_irq(unsigned int irq)
|
||||
{
|
||||
uint32_t cause;
|
||||
unsigned long flags;
|
||||
int i;
|
||||
|
||||
/* Check irq line routed to the MPIC */
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (irq == socrates_fpga_irqs[i])
|
||||
break;
|
||||
}
|
||||
if (i == 3)
|
||||
return NO_IRQ;
|
||||
|
||||
raw_spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
|
||||
cause = socrates_fpga_pic_read(FPGA_PIC_IRQMASK(i));
|
||||
raw_spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
|
||||
for (i = SOCRATES_FPGA_NUM_IRQS - 1; i >= 0; i--) {
|
||||
if (cause >> (i + 16))
|
||||
break;
|
||||
}
|
||||
return irq_linear_revmap(socrates_fpga_pic_irq_host,
|
||||
(irq_hw_number_t)i);
|
||||
}
|
||||
|
||||
void socrates_fpga_pic_cascade(unsigned int irq, struct irq_desc *desc)
|
||||
{
|
||||
struct irq_chip *chip = irq_desc_get_chip(desc);
|
||||
unsigned int cascade_irq;
|
||||
|
||||
/*
|
||||
* See if we actually have an interrupt, call generic handling code if
|
||||
* we do.
|
||||
*/
|
||||
cascade_irq = socrates_fpga_pic_get_irq(irq);
|
||||
|
||||
if (cascade_irq != NO_IRQ)
|
||||
generic_handle_irq(cascade_irq);
|
||||
chip->irq_eoi(&desc->irq_data);
|
||||
}
|
||||
|
||||
static void socrates_fpga_pic_ack(struct irq_data *d)
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned int irq_line, hwirq = irqd_to_hwirq(d);
|
||||
uint32_t mask;
|
||||
|
||||
irq_line = fpga_irqs[hwirq].irq_line;
|
||||
raw_spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
|
||||
mask = socrates_fpga_pic_read(FPGA_PIC_IRQMASK(irq_line))
|
||||
& SOCRATES_FPGA_IRQ_MASK;
|
||||
mask |= (1 << (hwirq + 16));
|
||||
socrates_fpga_pic_write(FPGA_PIC_IRQMASK(irq_line), mask);
|
||||
raw_spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
|
||||
}
|
||||
|
||||
static void socrates_fpga_pic_mask(struct irq_data *d)
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned int hwirq = irqd_to_hwirq(d);
|
||||
int irq_line;
|
||||
u32 mask;
|
||||
|
||||
irq_line = fpga_irqs[hwirq].irq_line;
|
||||
raw_spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
|
||||
mask = socrates_fpga_pic_read(FPGA_PIC_IRQMASK(irq_line))
|
||||
& SOCRATES_FPGA_IRQ_MASK;
|
||||
mask &= ~(1 << hwirq);
|
||||
socrates_fpga_pic_write(FPGA_PIC_IRQMASK(irq_line), mask);
|
||||
raw_spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
|
||||
}
|
||||
|
||||
static void socrates_fpga_pic_mask_ack(struct irq_data *d)
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned int hwirq = irqd_to_hwirq(d);
|
||||
int irq_line;
|
||||
u32 mask;
|
||||
|
||||
irq_line = fpga_irqs[hwirq].irq_line;
|
||||
raw_spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
|
||||
mask = socrates_fpga_pic_read(FPGA_PIC_IRQMASK(irq_line))
|
||||
& SOCRATES_FPGA_IRQ_MASK;
|
||||
mask &= ~(1 << hwirq);
|
||||
mask |= (1 << (hwirq + 16));
|
||||
socrates_fpga_pic_write(FPGA_PIC_IRQMASK(irq_line), mask);
|
||||
raw_spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
|
||||
}
|
||||
|
||||
static void socrates_fpga_pic_unmask(struct irq_data *d)
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned int hwirq = irqd_to_hwirq(d);
|
||||
int irq_line;
|
||||
u32 mask;
|
||||
|
||||
irq_line = fpga_irqs[hwirq].irq_line;
|
||||
raw_spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
|
||||
mask = socrates_fpga_pic_read(FPGA_PIC_IRQMASK(irq_line))
|
||||
& SOCRATES_FPGA_IRQ_MASK;
|
||||
mask |= (1 << hwirq);
|
||||
socrates_fpga_pic_write(FPGA_PIC_IRQMASK(irq_line), mask);
|
||||
raw_spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
|
||||
}
|
||||
|
||||
static void socrates_fpga_pic_eoi(struct irq_data *d)
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned int hwirq = irqd_to_hwirq(d);
|
||||
int irq_line;
|
||||
u32 mask;
|
||||
|
||||
irq_line = fpga_irqs[hwirq].irq_line;
|
||||
raw_spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
|
||||
mask = socrates_fpga_pic_read(FPGA_PIC_IRQMASK(irq_line))
|
||||
& SOCRATES_FPGA_IRQ_MASK;
|
||||
mask |= (1 << (hwirq + 16));
|
||||
socrates_fpga_pic_write(FPGA_PIC_IRQMASK(irq_line), mask);
|
||||
raw_spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
|
||||
}
|
||||
|
||||
static int socrates_fpga_pic_set_type(struct irq_data *d,
|
||||
unsigned int flow_type)
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned int hwirq = irqd_to_hwirq(d);
|
||||
int polarity;
|
||||
u32 mask;
|
||||
|
||||
if (fpga_irqs[hwirq].type != IRQ_TYPE_NONE)
|
||||
return -EINVAL;
|
||||
|
||||
switch (flow_type & IRQ_TYPE_SENSE_MASK) {
|
||||
case IRQ_TYPE_LEVEL_HIGH:
|
||||
polarity = 1;
|
||||
break;
|
||||
case IRQ_TYPE_LEVEL_LOW:
|
||||
polarity = 0;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
raw_spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
|
||||
mask = socrates_fpga_pic_read(FPGA_PIC_IRQCFG);
|
||||
if (polarity)
|
||||
mask |= (1 << hwirq);
|
||||
else
|
||||
mask &= ~(1 << hwirq);
|
||||
socrates_fpga_pic_write(FPGA_PIC_IRQCFG, mask);
|
||||
raw_spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct irq_chip socrates_fpga_pic_chip = {
|
||||
.name = "FPGA-PIC",
|
||||
.irq_ack = socrates_fpga_pic_ack,
|
||||
.irq_mask = socrates_fpga_pic_mask,
|
||||
.irq_mask_ack = socrates_fpga_pic_mask_ack,
|
||||
.irq_unmask = socrates_fpga_pic_unmask,
|
||||
.irq_eoi = socrates_fpga_pic_eoi,
|
||||
.irq_set_type = socrates_fpga_pic_set_type,
|
||||
};
|
||||
|
||||
static int socrates_fpga_pic_host_map(struct irq_domain *h, unsigned int virq,
|
||||
irq_hw_number_t hwirq)
|
||||
{
|
||||
/* All interrupts are LEVEL sensitive */
|
||||
irq_set_status_flags(virq, IRQ_LEVEL);
|
||||
irq_set_chip_and_handler(virq, &socrates_fpga_pic_chip,
|
||||
handle_fasteoi_irq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int socrates_fpga_pic_host_xlate(struct irq_domain *h,
|
||||
struct device_node *ct, const u32 *intspec, unsigned int intsize,
|
||||
irq_hw_number_t *out_hwirq, unsigned int *out_flags)
|
||||
{
|
||||
struct socrates_fpga_irq_info *fpga_irq = &fpga_irqs[intspec[0]];
|
||||
|
||||
*out_hwirq = intspec[0];
|
||||
if (fpga_irq->type == IRQ_TYPE_NONE) {
|
||||
/* type is configurable */
|
||||
if (intspec[1] != IRQ_TYPE_LEVEL_LOW &&
|
||||
intspec[1] != IRQ_TYPE_LEVEL_HIGH) {
|
||||
pr_warning("FPGA PIC: invalid irq type, "
|
||||
"setting default active low\n");
|
||||
*out_flags = IRQ_TYPE_LEVEL_LOW;
|
||||
} else {
|
||||
*out_flags = intspec[1];
|
||||
}
|
||||
} else {
|
||||
/* type is fixed */
|
||||
*out_flags = fpga_irq->type;
|
||||
}
|
||||
|
||||
/* Use specified interrupt routing */
|
||||
if (intspec[2] <= 2)
|
||||
fpga_irq->irq_line = intspec[2];
|
||||
else
|
||||
pr_warning("FPGA PIC: invalid irq routing\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct irq_domain_ops socrates_fpga_pic_host_ops = {
|
||||
.map = socrates_fpga_pic_host_map,
|
||||
.xlate = socrates_fpga_pic_host_xlate,
|
||||
};
|
||||
|
||||
void socrates_fpga_pic_init(struct device_node *pic)
|
||||
{
|
||||
unsigned long flags;
|
||||
int i;
|
||||
|
||||
/* Setup an irq_domain structure */
|
||||
socrates_fpga_pic_irq_host = irq_domain_add_linear(pic,
|
||||
SOCRATES_FPGA_NUM_IRQS, &socrates_fpga_pic_host_ops, NULL);
|
||||
if (socrates_fpga_pic_irq_host == NULL) {
|
||||
pr_err("FPGA PIC: Unable to allocate host\n");
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
socrates_fpga_irqs[i] = irq_of_parse_and_map(pic, i);
|
||||
if (socrates_fpga_irqs[i] == NO_IRQ) {
|
||||
pr_warning("FPGA PIC: can't get irq%d.\n", i);
|
||||
continue;
|
||||
}
|
||||
irq_set_chained_handler(socrates_fpga_irqs[i],
|
||||
socrates_fpga_pic_cascade);
|
||||
}
|
||||
|
||||
socrates_fpga_pic_iobase = of_iomap(pic, 0);
|
||||
|
||||
raw_spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
|
||||
socrates_fpga_pic_write(FPGA_PIC_IRQMASK(0),
|
||||
SOCRATES_FPGA_IRQ_MASK << 16);
|
||||
socrates_fpga_pic_write(FPGA_PIC_IRQMASK(1),
|
||||
SOCRATES_FPGA_IRQ_MASK << 16);
|
||||
socrates_fpga_pic_write(FPGA_PIC_IRQMASK(2),
|
||||
SOCRATES_FPGA_IRQ_MASK << 16);
|
||||
raw_spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
|
||||
|
||||
pr_info("FPGA PIC: Setting up Socrates FPGA PIC\n");
|
||||
}
|
16
arch/powerpc/platforms/85xx/socrates_fpga_pic.h
Normal file
16
arch/powerpc/platforms/85xx/socrates_fpga_pic.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* Copyright (C) 2008 Ilya Yanok, Emcraft Systems
|
||||
*
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SOCRATES_FPGA_PIC_H
|
||||
#define SOCRATES_FPGA_PIC_H
|
||||
|
||||
void socrates_fpga_pic_init(struct device_node *pic);
|
||||
|
||||
#endif
|
111
arch/powerpc/platforms/85xx/stx_gp3.c
Normal file
111
arch/powerpc/platforms/85xx/stx_gp3.c
Normal file
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
* Based on MPC8560 ADS and arch/ppc stx_gp3 ports
|
||||
*
|
||||
* Maintained by Kumar Gala (see MAINTAINERS for contact information)
|
||||
*
|
||||
* Copyright 2008 Freescale Semiconductor Inc.
|
||||
*
|
||||
* Dan Malek <dan@embeddededge.com>
|
||||
* Copyright 2004 Embedded Edge, LLC
|
||||
*
|
||||
* Copied from mpc8560_ads.c
|
||||
* Copyright 2002, 2003 Motorola Inc.
|
||||
*
|
||||
* Ported to 2.6, Matt Porter <mporter@kernel.crashing.org>
|
||||
* Copyright 2004-2005 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 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/time.h>
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/pci-bridge.h>
|
||||
#include <asm/mpic.h>
|
||||
#include <asm/prom.h>
|
||||
#include <mm/mmu_decl.h>
|
||||
#include <asm/udbg.h>
|
||||
|
||||
#include <sysdev/fsl_soc.h>
|
||||
#include <sysdev/fsl_pci.h>
|
||||
|
||||
#include "mpc85xx.h"
|
||||
|
||||
#ifdef CONFIG_CPM2
|
||||
#include <asm/cpm2.h>
|
||||
#endif /* CONFIG_CPM2 */
|
||||
|
||||
static void __init stx_gp3_pic_init(void)
|
||||
{
|
||||
struct mpic *mpic = mpic_alloc(NULL, 0, MPIC_BIG_ENDIAN,
|
||||
0, 256, " OpenPIC ");
|
||||
BUG_ON(mpic == NULL);
|
||||
mpic_init(mpic);
|
||||
|
||||
mpc85xx_cpm2_pic_init();
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup the architecture
|
||||
*/
|
||||
static void __init stx_gp3_setup_arch(void)
|
||||
{
|
||||
if (ppc_md.progress)
|
||||
ppc_md.progress("stx_gp3_setup_arch()", 0);
|
||||
|
||||
fsl_pci_assign_primary();
|
||||
|
||||
#ifdef CONFIG_CPM2
|
||||
cpm2_reset();
|
||||
#endif
|
||||
}
|
||||
|
||||
static void stx_gp3_show_cpuinfo(struct seq_file *m)
|
||||
{
|
||||
uint pvid, svid, phid1;
|
||||
|
||||
pvid = mfspr(SPRN_PVR);
|
||||
svid = mfspr(SPRN_SVR);
|
||||
|
||||
seq_printf(m, "Vendor\t\t: RPC Electronics STx\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));
|
||||
}
|
||||
|
||||
machine_arch_initcall(stx_gp3, mpc85xx_common_publish_devices);
|
||||
|
||||
/*
|
||||
* Called very early, device-tree isn't unflattened
|
||||
*/
|
||||
static int __init stx_gp3_probe(void)
|
||||
{
|
||||
unsigned long root = of_get_flat_dt_root();
|
||||
|
||||
return of_flat_dt_is_compatible(root, "stx,gp3-8560");
|
||||
}
|
||||
|
||||
define_machine(stx_gp3) {
|
||||
.name = "STX GP3",
|
||||
.probe = stx_gp3_probe,
|
||||
.setup_arch = stx_gp3_setup_arch,
|
||||
.init_IRQ = stx_gp3_pic_init,
|
||||
.show_cpuinfo = stx_gp3_show_cpuinfo,
|
||||
.get_irq = mpic_get_irq,
|
||||
.restart = fsl_rstcr_restart,
|
||||
.calibrate_decr = generic_calibrate_decr,
|
||||
.progress = udbg_progress,
|
||||
};
|
138
arch/powerpc/platforms/85xx/tqm85xx.c
Normal file
138
arch/powerpc/platforms/85xx/tqm85xx.c
Normal file
|
@ -0,0 +1,138 @@
|
|||
/*
|
||||
* Based on MPC8560 ADS and arch/ppc tqm85xx ports
|
||||
*
|
||||
* Maintained by Kumar Gala (see MAINTAINERS for contact information)
|
||||
*
|
||||
* Copyright 2008 Freescale Semiconductor Inc.
|
||||
*
|
||||
* Copyright (c) 2005-2006 DENX Software Engineering
|
||||
* Stefan Roese <sr@denx.de>
|
||||
*
|
||||
* Based on original work by
|
||||
* Kumar Gala <kumar.gala@freescale.com>
|
||||
* Copyright 2004 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/delay.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/of_platform.h>
|
||||
|
||||
#include <asm/time.h>
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/pci-bridge.h>
|
||||
#include <asm/mpic.h>
|
||||
#include <asm/prom.h>
|
||||
#include <mm/mmu_decl.h>
|
||||
#include <asm/udbg.h>
|
||||
|
||||
#include <sysdev/fsl_soc.h>
|
||||
#include <sysdev/fsl_pci.h>
|
||||
|
||||
#include "mpc85xx.h"
|
||||
|
||||
#ifdef CONFIG_CPM2
|
||||
#include <asm/cpm2.h>
|
||||
#endif /* CONFIG_CPM2 */
|
||||
|
||||
static void __init tqm85xx_pic_init(void)
|
||||
{
|
||||
struct mpic *mpic = mpic_alloc(NULL, 0,
|
||||
MPIC_BIG_ENDIAN,
|
||||
0, 256, " OpenPIC ");
|
||||
BUG_ON(mpic == NULL);
|
||||
mpic_init(mpic);
|
||||
|
||||
mpc85xx_cpm2_pic_init();
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup the architecture
|
||||
*/
|
||||
static void __init tqm85xx_setup_arch(void)
|
||||
{
|
||||
if (ppc_md.progress)
|
||||
ppc_md.progress("tqm85xx_setup_arch()", 0);
|
||||
|
||||
#ifdef CONFIG_CPM2
|
||||
cpm2_reset();
|
||||
#endif
|
||||
|
||||
fsl_pci_assign_primary();
|
||||
}
|
||||
|
||||
static void tqm85xx_show_cpuinfo(struct seq_file *m)
|
||||
{
|
||||
uint pvid, svid, phid1;
|
||||
|
||||
pvid = mfspr(SPRN_PVR);
|
||||
svid = mfspr(SPRN_SVR);
|
||||
|
||||
seq_printf(m, "Vendor\t\t: TQ Components\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));
|
||||
}
|
||||
|
||||
static void tqm85xx_ti1520_fixup(struct pci_dev *pdev)
|
||||
{
|
||||
unsigned int val;
|
||||
|
||||
/* Do not do the fixup on other platforms! */
|
||||
if (!machine_is(tqm85xx))
|
||||
return;
|
||||
|
||||
dev_info(&pdev->dev, "Using TI 1520 fixup on TQM85xx\n");
|
||||
|
||||
/*
|
||||
* Enable P2CCLK bit in system control register
|
||||
* to enable CLOCK output to power chip
|
||||
*/
|
||||
pci_read_config_dword(pdev, 0x80, &val);
|
||||
pci_write_config_dword(pdev, 0x80, val | (1 << 27));
|
||||
|
||||
}
|
||||
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1520,
|
||||
tqm85xx_ti1520_fixup);
|
||||
|
||||
machine_arch_initcall(tqm85xx, mpc85xx_common_publish_devices);
|
||||
|
||||
static const char * const board[] __initconst = {
|
||||
"tqc,tqm8540",
|
||||
"tqc,tqm8541",
|
||||
"tqc,tqm8548",
|
||||
"tqc,tqm8555",
|
||||
"tqc,tqm8560",
|
||||
NULL
|
||||
};
|
||||
|
||||
/*
|
||||
* Called very early, device-tree isn't unflattened
|
||||
*/
|
||||
static int __init tqm85xx_probe(void)
|
||||
{
|
||||
return of_flat_dt_match(of_get_flat_dt_root(), board);
|
||||
}
|
||||
|
||||
define_machine(tqm85xx) {
|
||||
.name = "TQM85xx",
|
||||
.probe = tqm85xx_probe,
|
||||
.setup_arch = tqm85xx_setup_arch,
|
||||
.init_IRQ = tqm85xx_pic_init,
|
||||
.show_cpuinfo = tqm85xx_show_cpuinfo,
|
||||
.get_irq = mpic_get_irq,
|
||||
.restart = fsl_rstcr_restart,
|
||||
.calibrate_decr = generic_calibrate_decr,
|
||||
.progress = udbg_progress,
|
||||
};
|
148
arch/powerpc/platforms/85xx/twr_p102x.c
Normal file
148
arch/powerpc/platforms/85xx/twr_p102x.c
Normal file
|
@ -0,0 +1,148 @@
|
|||
/*
|
||||
* Copyright 2010-2011, 2013 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* Author: Michael Johnston <michael.johnston@freescale.com>
|
||||
*
|
||||
* Description:
|
||||
* TWR-P102x Board Setup
|
||||
*
|
||||
* 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/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/of_platform.h>
|
||||
|
||||
#include <asm/pci-bridge.h>
|
||||
#include <asm/udbg.h>
|
||||
#include <asm/mpic.h>
|
||||
#include <asm/qe.h>
|
||||
#include <asm/qe_ic.h>
|
||||
#include <asm/fsl_guts.h>
|
||||
|
||||
#include <sysdev/fsl_soc.h>
|
||||
#include <sysdev/fsl_pci.h>
|
||||
#include "smp.h"
|
||||
|
||||
#include "mpc85xx.h"
|
||||
|
||||
static void __init twr_p1025_pic_init(void)
|
||||
{
|
||||
struct mpic *mpic;
|
||||
|
||||
#ifdef CONFIG_QUICC_ENGINE
|
||||
struct device_node *np;
|
||||
#endif
|
||||
|
||||
mpic = mpic_alloc(NULL, 0, MPIC_BIG_ENDIAN |
|
||||
MPIC_SINGLE_DEST_CPU,
|
||||
0, 256, " OpenPIC ");
|
||||
|
||||
BUG_ON(mpic == NULL);
|
||||
mpic_init(mpic);
|
||||
|
||||
#ifdef CONFIG_QUICC_ENGINE
|
||||
np = of_find_compatible_node(NULL, NULL, "fsl,qe-ic");
|
||||
if (np) {
|
||||
qe_ic_init(np, 0, qe_ic_cascade_low_mpic,
|
||||
qe_ic_cascade_high_mpic);
|
||||
of_node_put(np);
|
||||
} else
|
||||
pr_err("Could not find qe-ic node\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
/* ************************************************************************
|
||||
*
|
||||
* Setup the architecture
|
||||
*
|
||||
*/
|
||||
static void __init twr_p1025_setup_arch(void)
|
||||
{
|
||||
#ifdef CONFIG_QUICC_ENGINE
|
||||
struct device_node *np;
|
||||
#endif
|
||||
|
||||
if (ppc_md.progress)
|
||||
ppc_md.progress("twr_p1025_setup_arch()", 0);
|
||||
|
||||
mpc85xx_smp_init();
|
||||
|
||||
fsl_pci_assign_primary();
|
||||
|
||||
#ifdef CONFIG_QUICC_ENGINE
|
||||
mpc85xx_qe_init();
|
||||
mpc85xx_qe_par_io_init();
|
||||
|
||||
#if defined(CONFIG_UCC_GETH) || defined(CONFIG_SERIAL_QE)
|
||||
if (machine_is(twr_p1025)) {
|
||||
struct ccsr_guts __iomem *guts;
|
||||
|
||||
np = of_find_compatible_node(NULL, NULL, "fsl,p1021-guts");
|
||||
if (np) {
|
||||
guts = of_iomap(np, 0);
|
||||
if (!guts)
|
||||
pr_err("twr_p1025: could not map global utilities register\n");
|
||||
else {
|
||||
/* P1025 has pins muxed for QE and other functions. To
|
||||
* enable QE UEC mode, we need to set bit QE0 for UCC1
|
||||
* in Eth mode, QE0 and QE3 for UCC5 in Eth mode, QE9
|
||||
* and QE12 for QE MII management signals in PMUXCR
|
||||
* register.
|
||||
* Set QE mux bits in PMUXCR */
|
||||
setbits32(&guts->pmuxcr, MPC85xx_PMUXCR_QE(0) |
|
||||
MPC85xx_PMUXCR_QE(3) |
|
||||
MPC85xx_PMUXCR_QE(9) |
|
||||
MPC85xx_PMUXCR_QE(12));
|
||||
iounmap(guts);
|
||||
|
||||
#if defined(CONFIG_SERIAL_QE)
|
||||
/* On P1025TWR board, the UCC7 acted as UART port.
|
||||
* However, The UCC7's CTS pin is low level in default,
|
||||
* it will impact the transmission in full duplex
|
||||
* communication. So disable the Flow control pin PA18.
|
||||
* The UCC7 UART just can use RXD and TXD pins.
|
||||
*/
|
||||
par_io_config_pin(0, 18, 0, 0, 0, 0);
|
||||
#endif
|
||||
/* Drive PB29 to CPLD low - CPLD will then change
|
||||
* muxing from LBC to QE */
|
||||
par_io_config_pin(1, 29, 1, 0, 0, 0);
|
||||
par_io_data_set(1, 29, 0);
|
||||
}
|
||||
of_node_put(np);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif /* CONFIG_QUICC_ENGINE */
|
||||
|
||||
pr_info("TWR-P1025 board from Freescale Semiconductor\n");
|
||||
}
|
||||
|
||||
machine_arch_initcall(twr_p1025, mpc85xx_common_publish_devices);
|
||||
|
||||
static int __init twr_p1025_probe(void)
|
||||
{
|
||||
unsigned long root = of_get_flat_dt_root();
|
||||
|
||||
return of_flat_dt_is_compatible(root, "fsl,TWR-P1025");
|
||||
}
|
||||
|
||||
define_machine(twr_p1025) {
|
||||
.name = "TWR-P1025",
|
||||
.probe = twr_p1025_probe,
|
||||
.setup_arch = twr_p1025_setup_arch,
|
||||
.init_IRQ = twr_p1025_pic_init,
|
||||
#ifdef CONFIG_PCI
|
||||
.pcibios_fixup_bus = fsl_pcibios_fixup_bus,
|
||||
#endif
|
||||
.get_irq = mpic_get_irq,
|
||||
.restart = fsl_rstcr_restart,
|
||||
.calibrate_decr = generic_calibrate_decr,
|
||||
.progress = udbg_progress,
|
||||
};
|
209
arch/powerpc/platforms/85xx/xes_mpc85xx.c
Normal file
209
arch/powerpc/platforms/85xx/xes_mpc85xx.c
Normal file
|
@ -0,0 +1,209 @@
|
|||
/*
|
||||
* Copyright (C) 2009 Extreme Engineering Solutions, Inc.
|
||||
*
|
||||
* X-ES board-specific functionality
|
||||
*
|
||||
* Based on mpc85xx_ds code from Freescale Semiconductor, Inc.
|
||||
*
|
||||
* Author: Nate Case <ncase@xes-inc.com>
|
||||
*
|
||||
* This 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/delay.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/of_platform.h>
|
||||
|
||||
#include <asm/time.h>
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/pci-bridge.h>
|
||||
#include <mm/mmu_decl.h>
|
||||
#include <asm/prom.h>
|
||||
#include <asm/udbg.h>
|
||||
#include <asm/mpic.h>
|
||||
|
||||
#include <sysdev/fsl_soc.h>
|
||||
#include <sysdev/fsl_pci.h>
|
||||
#include "smp.h"
|
||||
|
||||
#include "mpc85xx.h"
|
||||
|
||||
/* A few bit definitions needed for fixups on some boards */
|
||||
#define MPC85xx_L2CTL_L2E 0x80000000 /* L2 enable */
|
||||
#define MPC85xx_L2CTL_L2I 0x40000000 /* L2 flash invalidate */
|
||||
#define MPC85xx_L2CTL_L2SIZ_MASK 0x30000000 /* L2 SRAM size (R/O) */
|
||||
|
||||
void __init xes_mpc85xx_pic_init(void)
|
||||
{
|
||||
struct mpic *mpic = mpic_alloc(NULL, 0, MPIC_BIG_ENDIAN,
|
||||
0, 256, " OpenPIC ");
|
||||
BUG_ON(mpic == NULL);
|
||||
mpic_init(mpic);
|
||||
}
|
||||
|
||||
static void xes_mpc85xx_configure_l2(void __iomem *l2_base)
|
||||
{
|
||||
volatile uint32_t ctl, tmp;
|
||||
|
||||
asm volatile("msync; isync");
|
||||
tmp = in_be32(l2_base);
|
||||
|
||||
/*
|
||||
* xMon may have enabled part of L2 as SRAM, so we need to set it
|
||||
* up for all cache mode just to be safe.
|
||||
*/
|
||||
printk(KERN_INFO "xes_mpc85xx: Enabling L2 as cache\n");
|
||||
|
||||
ctl = MPC85xx_L2CTL_L2E | MPC85xx_L2CTL_L2I;
|
||||
if (of_machine_is_compatible("MPC8540") ||
|
||||
of_machine_is_compatible("MPC8560"))
|
||||
/*
|
||||
* Assume L2 SRAM is used fully for cache, so set
|
||||
* L2BLKSZ (bits 4:5) to match L2SIZ (bits 2:3).
|
||||
*/
|
||||
ctl |= (tmp & MPC85xx_L2CTL_L2SIZ_MASK) >> 2;
|
||||
|
||||
asm volatile("msync; isync");
|
||||
out_be32(l2_base, ctl);
|
||||
asm volatile("msync; isync");
|
||||
}
|
||||
|
||||
static void xes_mpc85xx_fixups(void)
|
||||
{
|
||||
struct device_node *np;
|
||||
int err;
|
||||
|
||||
/*
|
||||
* Legacy xMon firmware on some X-ES boards does not enable L2
|
||||
* as cache. We must ensure that they get enabled here.
|
||||
*/
|
||||
for_each_node_by_name(np, "l2-cache-controller") {
|
||||
struct resource r[2];
|
||||
void __iomem *l2_base;
|
||||
|
||||
/* Only MPC8548, MPC8540, and MPC8560 boards are affected */
|
||||
if (!of_device_is_compatible(np,
|
||||
"fsl,mpc8548-l2-cache-controller") &&
|
||||
!of_device_is_compatible(np,
|
||||
"fsl,mpc8540-l2-cache-controller") &&
|
||||
!of_device_is_compatible(np,
|
||||
"fsl,mpc8560-l2-cache-controller"))
|
||||
continue;
|
||||
|
||||
err = of_address_to_resource(np, 0, &r[0]);
|
||||
if (err) {
|
||||
printk(KERN_WARNING "xes_mpc85xx: Could not get "
|
||||
"resource for device tree node '%s'",
|
||||
np->full_name);
|
||||
continue;
|
||||
}
|
||||
|
||||
l2_base = ioremap(r[0].start, resource_size(&r[0]));
|
||||
|
||||
xes_mpc85xx_configure_l2(l2_base);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup the architecture
|
||||
*/
|
||||
static void __init xes_mpc85xx_setup_arch(void)
|
||||
{
|
||||
struct device_node *root;
|
||||
const char *model = "Unknown";
|
||||
|
||||
root = of_find_node_by_path("/");
|
||||
if (root == NULL)
|
||||
return;
|
||||
|
||||
model = of_get_property(root, "model", NULL);
|
||||
|
||||
printk(KERN_INFO "X-ES MPC85xx-based single-board computer: %s\n",
|
||||
model + strlen("xes,"));
|
||||
|
||||
xes_mpc85xx_fixups();
|
||||
|
||||
mpc85xx_smp_init();
|
||||
|
||||
fsl_pci_assign_primary();
|
||||
}
|
||||
|
||||
machine_arch_initcall(xes_mpc8572, mpc85xx_common_publish_devices);
|
||||
machine_arch_initcall(xes_mpc8548, mpc85xx_common_publish_devices);
|
||||
machine_arch_initcall(xes_mpc8540, mpc85xx_common_publish_devices);
|
||||
|
||||
/*
|
||||
* Called very early, device-tree isn't unflattened
|
||||
*/
|
||||
static int __init xes_mpc8572_probe(void)
|
||||
{
|
||||
unsigned long root = of_get_flat_dt_root();
|
||||
|
||||
return of_flat_dt_is_compatible(root, "xes,MPC8572");
|
||||
}
|
||||
|
||||
static int __init xes_mpc8548_probe(void)
|
||||
{
|
||||
unsigned long root = of_get_flat_dt_root();
|
||||
|
||||
return of_flat_dt_is_compatible(root, "xes,MPC8548");
|
||||
}
|
||||
|
||||
static int __init xes_mpc8540_probe(void)
|
||||
{
|
||||
unsigned long root = of_get_flat_dt_root();
|
||||
|
||||
return of_flat_dt_is_compatible(root, "xes,MPC8540");
|
||||
}
|
||||
|
||||
define_machine(xes_mpc8572) {
|
||||
.name = "X-ES MPC8572",
|
||||
.probe = xes_mpc8572_probe,
|
||||
.setup_arch = xes_mpc85xx_setup_arch,
|
||||
.init_IRQ = xes_mpc85xx_pic_init,
|
||||
#ifdef CONFIG_PCI
|
||||
.pcibios_fixup_bus = fsl_pcibios_fixup_bus,
|
||||
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
|
||||
#endif
|
||||
.get_irq = mpic_get_irq,
|
||||
.restart = fsl_rstcr_restart,
|
||||
.calibrate_decr = generic_calibrate_decr,
|
||||
.progress = udbg_progress,
|
||||
};
|
||||
|
||||
define_machine(xes_mpc8548) {
|
||||
.name = "X-ES MPC8548",
|
||||
.probe = xes_mpc8548_probe,
|
||||
.setup_arch = xes_mpc85xx_setup_arch,
|
||||
.init_IRQ = xes_mpc85xx_pic_init,
|
||||
#ifdef CONFIG_PCI
|
||||
.pcibios_fixup_bus = fsl_pcibios_fixup_bus,
|
||||
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
|
||||
#endif
|
||||
.get_irq = mpic_get_irq,
|
||||
.restart = fsl_rstcr_restart,
|
||||
.calibrate_decr = generic_calibrate_decr,
|
||||
.progress = udbg_progress,
|
||||
};
|
||||
|
||||
define_machine(xes_mpc8540) {
|
||||
.name = "X-ES MPC8540",
|
||||
.probe = xes_mpc8540_probe,
|
||||
.setup_arch = xes_mpc85xx_setup_arch,
|
||||
.init_IRQ = xes_mpc85xx_pic_init,
|
||||
#ifdef CONFIG_PCI
|
||||
.pcibios_fixup_bus = fsl_pcibios_fixup_bus,
|
||||
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
|
||||
#endif
|
||||
.get_irq = mpic_get_irq,
|
||||
.restart = fsl_rstcr_restart,
|
||||
.calibrate_decr = generic_calibrate_decr,
|
||||
.progress = udbg_progress,
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue