SPEAr13xx: Add source files
This patch adds source files for SPEAr13xx Machines. Signed-off-by: Viresh Kumar <viresh.kumar@st.com> Signed-off-by: Deepak Sikri <deepak.sikri@st.com> Signed-off-by: Shiraz Hashim <shiraz.hashim@st.com>
This commit is contained in:
Родитель
b31e23726b
Коммит
e3978dc7df
|
@ -0,0 +1,18 @@
|
|||
#
|
||||
# SPEAr13XX Machine configuration file
|
||||
#
|
||||
|
||||
if ARCH_SPEAR13XX
|
||||
|
||||
menu "SPEAr13xx Implementations"
|
||||
config MACH_SPEAR1310
|
||||
bool "SPEAr1310 Machine support with Device Tree"
|
||||
help
|
||||
Supports ST SPEAr1310 machine configured via the device-tree
|
||||
|
||||
config MACH_SPEAR1340
|
||||
bool "SPEAr1340 Machine support with Device Tree"
|
||||
help
|
||||
Supports ST SPEAr1340 machine configured via the device-tree
|
||||
endmenu
|
||||
endif #ARCH_SPEAR13XX
|
|
@ -0,0 +1,10 @@
|
|||
#
|
||||
# Makefile for SPEAr13XX machine series
|
||||
#
|
||||
|
||||
obj-$(CONFIG_SMP) += headsmp.o platsmp.o
|
||||
obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
|
||||
|
||||
obj-$(CONFIG_ARCH_SPEAR13XX) += spear13xx.o
|
||||
obj-$(CONFIG_MACH_SPEAR1310) += spear1310.o
|
||||
obj-$(CONFIG_MACH_SPEAR1340) += spear1340.o
|
|
@ -0,0 +1,6 @@
|
|||
zreladdr-y += 0x00008000
|
||||
params_phys-y := 0x00000100
|
||||
initrd_phys-y := 0x00800000
|
||||
|
||||
dtb-$(CONFIG_MACH_SPEAR1310) += spear1310-evb.dtb
|
||||
dtb-$(CONFIG_MACH_SPEAR1340) += spear1340-evb.dtb
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* arch/arm/mach-spear13XX/headsmp.S
|
||||
*
|
||||
* Picked from realview
|
||||
* Copyright (c) 2012 ST Microelectronics Limited
|
||||
* Shiraz Hashim <shiraz.hashim@st.com>
|
||||
*
|
||||
* 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/linkage.h>
|
||||
#include <linux/init.h>
|
||||
|
||||
__INIT
|
||||
|
||||
/*
|
||||
* spear13xx specific entry point for secondary CPUs. This provides
|
||||
* a "holding pen" into which all secondary cores are held until we're
|
||||
* ready for them to initialise.
|
||||
*/
|
||||
ENTRY(spear13xx_secondary_startup)
|
||||
mrc p15, 0, r0, c0, c0, 5
|
||||
and r0, r0, #15
|
||||
adr r4, 1f
|
||||
ldmia r4, {r5, r6}
|
||||
sub r4, r4, r5
|
||||
add r6, r6, r4
|
||||
pen: ldr r7, [r6]
|
||||
cmp r7, r0
|
||||
bne pen
|
||||
|
||||
/* re-enable coherency */
|
||||
mrc p15, 0, r0, c1, c0, 1
|
||||
orr r0, r0, #(1 << 6) | (1 << 0)
|
||||
mcr p15, 0, r0, c1, c0, 1
|
||||
/*
|
||||
* we've been released from the holding pen: secondary_stack
|
||||
* should now contain the SVC stack for this core
|
||||
*/
|
||||
b secondary_startup
|
||||
|
||||
.align
|
||||
1: .long .
|
||||
.long pen_release
|
||||
ENDPROC(spear13xx_secondary_startup)
|
|
@ -0,0 +1,119 @@
|
|||
/*
|
||||
* linux/arch/arm/mach-spear13xx/hotplug.c
|
||||
*
|
||||
* Copyright (C) 2012 ST Microelectronics Ltd.
|
||||
* Deepak Sikri <deepak.sikri@st.com>
|
||||
*
|
||||
* based upon linux/arch/arm/mach-realview/hotplug.c
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/smp.h>
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/cp15.h>
|
||||
#include <asm/smp_plat.h>
|
||||
|
||||
extern volatile int pen_release;
|
||||
|
||||
static inline void cpu_enter_lowpower(void)
|
||||
{
|
||||
unsigned int v;
|
||||
|
||||
flush_cache_all();
|
||||
asm volatile(
|
||||
" mcr p15, 0, %1, c7, c5, 0\n"
|
||||
" dsb\n"
|
||||
/*
|
||||
* Turn off coherency
|
||||
*/
|
||||
" mrc p15, 0, %0, c1, c0, 1\n"
|
||||
" bic %0, %0, #0x20\n"
|
||||
" mcr p15, 0, %0, c1, c0, 1\n"
|
||||
" mrc p15, 0, %0, c1, c0, 0\n"
|
||||
" bic %0, %0, %2\n"
|
||||
" mcr p15, 0, %0, c1, c0, 0\n"
|
||||
: "=&r" (v)
|
||||
: "r" (0), "Ir" (CR_C)
|
||||
: "cc", "memory");
|
||||
}
|
||||
|
||||
static inline void cpu_leave_lowpower(void)
|
||||
{
|
||||
unsigned int v;
|
||||
|
||||
asm volatile("mrc p15, 0, %0, c1, c0, 0\n"
|
||||
" orr %0, %0, %1\n"
|
||||
" mcr p15, 0, %0, c1, c0, 0\n"
|
||||
" mrc p15, 0, %0, c1, c0, 1\n"
|
||||
" orr %0, %0, #0x20\n"
|
||||
" mcr p15, 0, %0, c1, c0, 1\n"
|
||||
: "=&r" (v)
|
||||
: "Ir" (CR_C)
|
||||
: "cc");
|
||||
}
|
||||
|
||||
static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
|
||||
{
|
||||
for (;;) {
|
||||
wfi();
|
||||
|
||||
if (pen_release == cpu) {
|
||||
/*
|
||||
* OK, proper wakeup, we're done
|
||||
*/
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Getting here, means that we have come out of WFI without
|
||||
* having been woken up - this shouldn't happen
|
||||
*
|
||||
* Just note it happening - when we're woken, we can report
|
||||
* its occurrence.
|
||||
*/
|
||||
(*spurious)++;
|
||||
}
|
||||
}
|
||||
|
||||
int platform_cpu_kill(unsigned int cpu)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* platform-specific code to shutdown a CPU
|
||||
*
|
||||
* Called with IRQs disabled
|
||||
*/
|
||||
void __cpuinit platform_cpu_die(unsigned int cpu)
|
||||
{
|
||||
int spurious = 0;
|
||||
|
||||
/*
|
||||
* we're ready for shutdown now, so do it
|
||||
*/
|
||||
cpu_enter_lowpower();
|
||||
platform_do_lowpower(cpu, &spurious);
|
||||
|
||||
/*
|
||||
* bring this CPU back into the world of cache
|
||||
* coherency, and then restore interrupts
|
||||
*/
|
||||
cpu_leave_lowpower();
|
||||
|
||||
if (spurious)
|
||||
pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious);
|
||||
}
|
||||
|
||||
int platform_cpu_disable(unsigned int cpu)
|
||||
{
|
||||
/*
|
||||
* we don't allow CPU 0 to be shutdown (it is still too special
|
||||
* e.g. clock tick interrupts)
|
||||
*/
|
||||
return cpu == 0 ? -EPERM : 0;
|
||||
}
|
|
@ -0,0 +1,127 @@
|
|||
/*
|
||||
* arch/arm/mach-spear13xx/platsmp.c
|
||||
*
|
||||
* based upon linux/arch/arm/mach-realview/platsmp.c
|
||||
*
|
||||
* Copyright (C) 2012 ST Microelectronics Ltd.
|
||||
* Shiraz Hashim <shiraz.hashim@st.com>
|
||||
*
|
||||
* 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/delay.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/smp.h>
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/hardware/gic.h>
|
||||
#include <asm/smp_scu.h>
|
||||
#include <mach/spear.h>
|
||||
|
||||
/*
|
||||
* control for which core is the next to come out of the secondary
|
||||
* boot "holding pen"
|
||||
*/
|
||||
volatile int __cpuinitdata pen_release = -1;
|
||||
static DEFINE_SPINLOCK(boot_lock);
|
||||
|
||||
static void __iomem *scu_base = IOMEM(VA_SCU_BASE);
|
||||
extern void spear13xx_secondary_startup(void);
|
||||
|
||||
void __cpuinit platform_secondary_init(unsigned int cpu)
|
||||
{
|
||||
/*
|
||||
* if any interrupts are already enabled for the primary
|
||||
* core (e.g. timer irq), then they will not have been enabled
|
||||
* for us: do so
|
||||
*/
|
||||
gic_secondary_init(0);
|
||||
|
||||
/*
|
||||
* let the primary processor know we're out of the
|
||||
* pen, then head off into the C entry point
|
||||
*/
|
||||
pen_release = -1;
|
||||
smp_wmb();
|
||||
|
||||
/*
|
||||
* Synchronise with the boot thread.
|
||||
*/
|
||||
spin_lock(&boot_lock);
|
||||
spin_unlock(&boot_lock);
|
||||
}
|
||||
|
||||
int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
|
||||
{
|
||||
unsigned long timeout;
|
||||
|
||||
/*
|
||||
* set synchronisation state between this boot processor
|
||||
* and the secondary one
|
||||
*/
|
||||
spin_lock(&boot_lock);
|
||||
|
||||
/*
|
||||
* The secondary processor is waiting to be released from
|
||||
* the holding pen - release it, then wait for it to flag
|
||||
* that it has been released by resetting pen_release.
|
||||
*
|
||||
* Note that "pen_release" is the hardware CPU ID, whereas
|
||||
* "cpu" is Linux's internal ID.
|
||||
*/
|
||||
pen_release = cpu;
|
||||
flush_cache_all();
|
||||
outer_flush_all();
|
||||
|
||||
timeout = jiffies + (1 * HZ);
|
||||
while (time_before(jiffies, timeout)) {
|
||||
smp_rmb();
|
||||
if (pen_release == -1)
|
||||
break;
|
||||
|
||||
udelay(10);
|
||||
}
|
||||
|
||||
/*
|
||||
* now the secondary core is starting up let it run its
|
||||
* calibrations, then wait for it to finish
|
||||
*/
|
||||
spin_unlock(&boot_lock);
|
||||
|
||||
return pen_release != -1 ? -ENOSYS : 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialise the CPU possible map early - this describes the CPUs
|
||||
* which may be present or become present in the system.
|
||||
*/
|
||||
void __init smp_init_cpus(void)
|
||||
{
|
||||
unsigned int i, ncores = scu_get_core_count(scu_base);
|
||||
|
||||
if (ncores > nr_cpu_ids) {
|
||||
pr_warn("SMP: %u cores greater than maximum (%u), clipping\n",
|
||||
ncores, nr_cpu_ids);
|
||||
ncores = nr_cpu_ids;
|
||||
}
|
||||
|
||||
for (i = 0; i < ncores; i++)
|
||||
set_cpu_possible(i, true);
|
||||
|
||||
set_smp_cross_call(gic_raise_softirq);
|
||||
}
|
||||
|
||||
void __init platform_smp_prepare_cpus(unsigned int max_cpus)
|
||||
{
|
||||
|
||||
scu_enable(scu_base);
|
||||
|
||||
/*
|
||||
* Write the address of secondary startup into the system-wide location
|
||||
* (presently it is in SRAM). The BootMonitor waits until it receives a
|
||||
* soft interrupt, and then the secondary CPU branches to this address.
|
||||
*/
|
||||
__raw_writel(virt_to_phys(spear13xx_secondary_startup), SYS_LOCATION);
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* arch/arm/mach-spear13xx/spear1310.c
|
||||
*
|
||||
* SPEAr1310 machine source file
|
||||
*
|
||||
* Copyright (C) 2012 ST Microelectronics
|
||||
* Viresh Kumar <viresh.kumar@st.com>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) "SPEAr1310: " fmt
|
||||
|
||||
#include <linux/amba/pl022.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <asm/hardware/gic.h>
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/map.h>
|
||||
#include <mach/generic.h>
|
||||
#include <mach/spear.h>
|
||||
|
||||
/* Base addresses */
|
||||
#define SPEAR1310_SSP1_BASE UL(0x5D400000)
|
||||
#define SPEAR1310_SATA0_BASE UL(0xB1000000)
|
||||
#define SPEAR1310_SATA1_BASE UL(0xB1800000)
|
||||
#define SPEAR1310_SATA2_BASE UL(0xB4000000)
|
||||
|
||||
/* ssp device registration */
|
||||
static struct pl022_ssp_controller ssp1_plat_data = {
|
||||
.bus_id = 0,
|
||||
.enable_dma = 0,
|
||||
.num_chipselect = 3,
|
||||
};
|
||||
|
||||
/* Add SPEAr1310 auxdata to pass platform data */
|
||||
static struct of_dev_auxdata spear1310_auxdata_lookup[] __initdata = {
|
||||
OF_DEV_AUXDATA("arasan,cf-spear1340", MCIF_CF_BASE, NULL, &cf_dma_priv),
|
||||
OF_DEV_AUXDATA("snps,dma-spear1340", DMAC0_BASE, NULL, &dmac_plat_data),
|
||||
OF_DEV_AUXDATA("snps,dma-spear1340", DMAC1_BASE, NULL, &dmac_plat_data),
|
||||
OF_DEV_AUXDATA("arm,pl022", SSP_BASE, NULL, &pl022_plat_data),
|
||||
|
||||
OF_DEV_AUXDATA("arm,pl022", SPEAR1310_SSP1_BASE, NULL, &ssp1_plat_data),
|
||||
{}
|
||||
};
|
||||
|
||||
static void __init spear1310_dt_init(void)
|
||||
{
|
||||
of_platform_populate(NULL, of_default_bus_match_table,
|
||||
spear1310_auxdata_lookup, NULL);
|
||||
}
|
||||
|
||||
static const char * const spear1310_dt_board_compat[] = {
|
||||
"st,spear1310",
|
||||
"st,spear1310-evb",
|
||||
NULL,
|
||||
};
|
||||
|
||||
/*
|
||||
* Following will create 16MB static virtual/physical mappings
|
||||
* PHYSICAL VIRTUAL
|
||||
* 0xD8000000 0xFA000000
|
||||
*/
|
||||
struct map_desc spear1310_io_desc[] __initdata = {
|
||||
{
|
||||
.virtual = VA_SPEAR1310_RAS_GRP1_BASE,
|
||||
.pfn = __phys_to_pfn(SPEAR1310_RAS_GRP1_BASE),
|
||||
.length = SZ_16M,
|
||||
.type = MT_DEVICE
|
||||
},
|
||||
};
|
||||
|
||||
static void __init spear1310_map_io(void)
|
||||
{
|
||||
iotable_init(spear1310_io_desc, ARRAY_SIZE(spear1310_io_desc));
|
||||
spear13xx_map_io();
|
||||
}
|
||||
|
||||
DT_MACHINE_START(SPEAR1310_DT, "ST SPEAr1310 SoC with Flattened Device Tree")
|
||||
.map_io = spear1310_map_io,
|
||||
.init_irq = spear13xx_dt_init_irq,
|
||||
.handle_irq = gic_handle_irq,
|
||||
.timer = &spear13xx_timer,
|
||||
.init_machine = spear1310_dt_init,
|
||||
.restart = spear_restart,
|
||||
.dt_compat = spear1310_dt_board_compat,
|
||||
MACHINE_END
|
|
@ -0,0 +1,192 @@
|
|||
/*
|
||||
* arch/arm/mach-spear13xx/spear1340.c
|
||||
*
|
||||
* SPEAr1340 machine source file
|
||||
*
|
||||
* Copyright (C) 2012 ST Microelectronics
|
||||
* Viresh Kumar <viresh.kumar@st.com>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) "SPEAr1340: " fmt
|
||||
|
||||
#include <linux/ahci_platform.h>
|
||||
#include <linux/amba/serial.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/dw_dmac.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <asm/hardware/gic.h>
|
||||
#include <asm/mach/arch.h>
|
||||
#include <mach/dma.h>
|
||||
#include <mach/generic.h>
|
||||
#include <mach/spear.h>
|
||||
|
||||
/* Base addresses */
|
||||
#define SPEAR1340_SATA_BASE UL(0xB1000000)
|
||||
#define SPEAR1340_UART1_BASE UL(0xB4100000)
|
||||
|
||||
/* Power Management Registers */
|
||||
#define SPEAR1340_PCM_CFG (VA_MISC_BASE + 0x100)
|
||||
#define SPEAR1340_PCM_WKUP_CFG (VA_MISC_BASE + 0x104)
|
||||
#define SPEAR1340_SWITCH_CTR (VA_MISC_BASE + 0x108)
|
||||
|
||||
#define SPEAR1340_PERIP1_SW_RST (VA_MISC_BASE + 0x318)
|
||||
#define SPEAR1340_PERIP2_SW_RST (VA_MISC_BASE + 0x31C)
|
||||
#define SPEAR1340_PERIP3_SW_RST (VA_MISC_BASE + 0x320)
|
||||
|
||||
/* PCIE - SATA configuration registers */
|
||||
#define SPEAR1340_PCIE_SATA_CFG (VA_MISC_BASE + 0x424)
|
||||
/* PCIE CFG MASks */
|
||||
#define SPEAR1340_PCIE_CFG_DEVICE_PRESENT (1 << 11)
|
||||
#define SPEAR1340_PCIE_CFG_POWERUP_RESET (1 << 10)
|
||||
#define SPEAR1340_PCIE_CFG_CORE_CLK_EN (1 << 9)
|
||||
#define SPEAR1340_PCIE_CFG_AUX_CLK_EN (1 << 8)
|
||||
#define SPEAR1340_SATA_CFG_TX_CLK_EN (1 << 4)
|
||||
#define SPEAR1340_SATA_CFG_RX_CLK_EN (1 << 3)
|
||||
#define SPEAR1340_SATA_CFG_POWERUP_RESET (1 << 2)
|
||||
#define SPEAR1340_SATA_CFG_PM_CLK_EN (1 << 1)
|
||||
#define SPEAR1340_PCIE_SATA_SEL_PCIE (0)
|
||||
#define SPEAR1340_PCIE_SATA_SEL_SATA (1)
|
||||
#define SPEAR1340_SATA_PCIE_CFG_MASK 0xF1F
|
||||
#define SPEAR1340_PCIE_CFG_VAL (SPEAR1340_PCIE_SATA_SEL_PCIE | \
|
||||
SPEAR1340_PCIE_CFG_AUX_CLK_EN | \
|
||||
SPEAR1340_PCIE_CFG_CORE_CLK_EN | \
|
||||
SPEAR1340_PCIE_CFG_POWERUP_RESET | \
|
||||
SPEAR1340_PCIE_CFG_DEVICE_PRESENT)
|
||||
#define SPEAR1340_SATA_CFG_VAL (SPEAR1340_PCIE_SATA_SEL_SATA | \
|
||||
SPEAR1340_SATA_CFG_PM_CLK_EN | \
|
||||
SPEAR1340_SATA_CFG_POWERUP_RESET | \
|
||||
SPEAR1340_SATA_CFG_RX_CLK_EN | \
|
||||
SPEAR1340_SATA_CFG_TX_CLK_EN)
|
||||
|
||||
#define SPEAR1340_PCIE_MIPHY_CFG (VA_MISC_BASE + 0x428)
|
||||
#define SPEAR1340_MIPHY_OSC_BYPASS_EXT (1 << 31)
|
||||
#define SPEAR1340_MIPHY_CLK_REF_DIV2 (1 << 27)
|
||||
#define SPEAR1340_MIPHY_CLK_REF_DIV4 (2 << 27)
|
||||
#define SPEAR1340_MIPHY_CLK_REF_DIV8 (3 << 27)
|
||||
#define SPEAR1340_MIPHY_PLL_RATIO_TOP(x) (x << 0)
|
||||
#define SPEAR1340_PCIE_SATA_MIPHY_CFG_SATA \
|
||||
(SPEAR1340_MIPHY_OSC_BYPASS_EXT | \
|
||||
SPEAR1340_MIPHY_CLK_REF_DIV2 | \
|
||||
SPEAR1340_MIPHY_PLL_RATIO_TOP(60))
|
||||
#define SPEAR1340_PCIE_SATA_MIPHY_CFG_SATA_25M_CRYSTAL_CLK \
|
||||
(SPEAR1340_MIPHY_PLL_RATIO_TOP(120))
|
||||
#define SPEAR1340_PCIE_SATA_MIPHY_CFG_PCIE \
|
||||
(SPEAR1340_MIPHY_OSC_BYPASS_EXT | \
|
||||
SPEAR1340_MIPHY_PLL_RATIO_TOP(25))
|
||||
|
||||
static struct dw_dma_slave uart1_dma_param[] = {
|
||||
{
|
||||
/* Tx */
|
||||
.cfg_hi = DWC_CFGH_DST_PER(SPEAR1340_DMA_REQ_UART1_TX),
|
||||
.cfg_lo = 0,
|
||||
.src_master = DMA_MASTER_MEMORY,
|
||||
.dst_master = SPEAR1340_DMA_MASTER_UART1,
|
||||
}, {
|
||||
/* Rx */
|
||||
.cfg_hi = DWC_CFGH_SRC_PER(SPEAR1340_DMA_REQ_UART1_RX),
|
||||
.cfg_lo = 0,
|
||||
.src_master = SPEAR1340_DMA_MASTER_UART1,
|
||||
.dst_master = DMA_MASTER_MEMORY,
|
||||
}
|
||||
};
|
||||
|
||||
static struct amba_pl011_data uart1_data = {
|
||||
.dma_filter = dw_dma_filter,
|
||||
.dma_tx_param = &uart1_dma_param[0],
|
||||
.dma_rx_param = &uart1_dma_param[1],
|
||||
};
|
||||
|
||||
/* SATA device registration */
|
||||
static int sata_miphy_init(struct device *dev, void __iomem *addr)
|
||||
{
|
||||
writel(SPEAR1340_SATA_CFG_VAL, SPEAR1340_PCIE_SATA_CFG);
|
||||
writel(SPEAR1340_PCIE_SATA_MIPHY_CFG_SATA_25M_CRYSTAL_CLK,
|
||||
SPEAR1340_PCIE_MIPHY_CFG);
|
||||
/* Switch on sata power domain */
|
||||
writel((readl(SPEAR1340_PCM_CFG) | (0x800)), SPEAR1340_PCM_CFG);
|
||||
msleep(20);
|
||||
/* Disable PCIE SATA Controller reset */
|
||||
writel((readl(SPEAR1340_PERIP1_SW_RST) & (~0x1000)),
|
||||
SPEAR1340_PERIP1_SW_RST);
|
||||
msleep(20);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sata_miphy_exit(struct device *dev)
|
||||
{
|
||||
writel(0, SPEAR1340_PCIE_SATA_CFG);
|
||||
writel(0, SPEAR1340_PCIE_MIPHY_CFG);
|
||||
|
||||
/* Enable PCIE SATA Controller reset */
|
||||
writel((readl(SPEAR1340_PERIP1_SW_RST) | (0x1000)),
|
||||
SPEAR1340_PERIP1_SW_RST);
|
||||
msleep(20);
|
||||
/* Switch off sata power domain */
|
||||
writel((readl(SPEAR1340_PCM_CFG) & (~0x800)), SPEAR1340_PCM_CFG);
|
||||
msleep(20);
|
||||
}
|
||||
|
||||
int sata_suspend(struct device *dev)
|
||||
{
|
||||
if (dev->power.power_state.event == PM_EVENT_FREEZE)
|
||||
return 0;
|
||||
|
||||
sata_miphy_exit(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sata_resume(struct device *dev)
|
||||
{
|
||||
if (dev->power.power_state.event == PM_EVENT_THAW)
|
||||
return 0;
|
||||
|
||||
return sata_miphy_init(dev, NULL);
|
||||
}
|
||||
|
||||
static struct ahci_platform_data sata_pdata = {
|
||||
.init = sata_miphy_init,
|
||||
.exit = sata_miphy_exit,
|
||||
.suspend = sata_suspend,
|
||||
.resume = sata_resume,
|
||||
};
|
||||
|
||||
/* Add SPEAr1340 auxdata to pass platform data */
|
||||
static struct of_dev_auxdata spear1340_auxdata_lookup[] __initdata = {
|
||||
OF_DEV_AUXDATA("arasan,cf-spear1340", MCIF_CF_BASE, NULL, &cf_dma_priv),
|
||||
OF_DEV_AUXDATA("snps,dma-spear1340", DMAC0_BASE, NULL, &dmac_plat_data),
|
||||
OF_DEV_AUXDATA("snps,dma-spear1340", DMAC1_BASE, NULL, &dmac_plat_data),
|
||||
OF_DEV_AUXDATA("arm,pl022", SSP_BASE, NULL, &pl022_plat_data),
|
||||
|
||||
OF_DEV_AUXDATA("snps,spear-ahci", SPEAR1340_SATA_BASE, NULL,
|
||||
&sata_pdata),
|
||||
OF_DEV_AUXDATA("arm,pl011", SPEAR1340_UART1_BASE, NULL, &uart1_data),
|
||||
{}
|
||||
};
|
||||
|
||||
static void __init spear1340_dt_init(void)
|
||||
{
|
||||
of_platform_populate(NULL, of_default_bus_match_table,
|
||||
spear1340_auxdata_lookup, NULL);
|
||||
}
|
||||
|
||||
static const char * const spear1340_dt_board_compat[] = {
|
||||
"st,spear1340",
|
||||
"st,spear1340-evb",
|
||||
NULL,
|
||||
};
|
||||
|
||||
DT_MACHINE_START(SPEAR1340_DT, "ST SPEAr1340 SoC with Flattened Device Tree")
|
||||
.map_io = spear13xx_map_io,
|
||||
.init_irq = spear13xx_dt_init_irq,
|
||||
.handle_irq = gic_handle_irq,
|
||||
.timer = &spear13xx_timer,
|
||||
.init_machine = spear1340_dt_init,
|
||||
.restart = spear_restart,
|
||||
.dt_compat = spear1340_dt_board_compat,
|
||||
MACHINE_END
|
|
@ -0,0 +1,197 @@
|
|||
/*
|
||||
* arch/arm/mach-spear13xx/spear13xx.c
|
||||
*
|
||||
* SPEAr13XX machines common source file
|
||||
*
|
||||
* Copyright (C) 2012 ST Microelectronics
|
||||
* Viresh Kumar <viresh.kumar@st.com>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) "SPEAr13xx: " fmt
|
||||
|
||||
#include <linux/amba/pl022.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/dw_dmac.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <asm/hardware/cache-l2x0.h>
|
||||
#include <asm/hardware/gic.h>
|
||||
#include <asm/mach/map.h>
|
||||
#include <asm/smp_twd.h>
|
||||
#include <mach/dma.h>
|
||||
#include <mach/generic.h>
|
||||
#include <mach/spear.h>
|
||||
|
||||
/* common dw_dma filter routine to be used by peripherals */
|
||||
bool dw_dma_filter(struct dma_chan *chan, void *slave)
|
||||
{
|
||||
struct dw_dma_slave *dws = (struct dw_dma_slave *)slave;
|
||||
|
||||
if (chan->device->dev == dws->dma_dev) {
|
||||
chan->private = slave;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* ssp device registration */
|
||||
static struct dw_dma_slave ssp_dma_param[] = {
|
||||
{
|
||||
/* Tx */
|
||||
.cfg_hi = DWC_CFGH_DST_PER(DMA_REQ_SSP0_TX),
|
||||
.cfg_lo = 0,
|
||||
.src_master = DMA_MASTER_MEMORY,
|
||||
.dst_master = DMA_MASTER_SSP0,
|
||||
}, {
|
||||
/* Rx */
|
||||
.cfg_hi = DWC_CFGH_SRC_PER(DMA_REQ_SSP0_RX),
|
||||
.cfg_lo = 0,
|
||||
.src_master = DMA_MASTER_SSP0,
|
||||
.dst_master = DMA_MASTER_MEMORY,
|
||||
}
|
||||
};
|
||||
|
||||
struct pl022_ssp_controller pl022_plat_data = {
|
||||
.bus_id = 0,
|
||||
.enable_dma = 1,
|
||||
.dma_filter = dw_dma_filter,
|
||||
.dma_rx_param = &ssp_dma_param[1],
|
||||
.dma_tx_param = &ssp_dma_param[0],
|
||||
.num_chipselect = 3,
|
||||
};
|
||||
|
||||
/* CF device registration */
|
||||
struct dw_dma_slave cf_dma_priv = {
|
||||
.cfg_hi = 0,
|
||||
.cfg_lo = 0,
|
||||
.src_master = 0,
|
||||
.dst_master = 0,
|
||||
};
|
||||
|
||||
/* dmac device registeration */
|
||||
struct dw_dma_platform_data dmac_plat_data = {
|
||||
.nr_channels = 8,
|
||||
.chan_allocation_order = CHAN_ALLOCATION_DESCENDING,
|
||||
.chan_priority = CHAN_PRIORITY_DESCENDING,
|
||||
};
|
||||
|
||||
void __init spear13xx_l2x0_init(void)
|
||||
{
|
||||
/*
|
||||
* 512KB (64KB/way), 8-way associativity, parity supported
|
||||
*
|
||||
* FIXME: 9th bit, of Auxillary Controller register must be set
|
||||
* for some spear13xx devices for stable L2 operation.
|
||||
*
|
||||
* Enable Early BRESP, L2 prefetch for Instruction and Data,
|
||||
* write alloc and 'Full line of zero' options
|
||||
*
|
||||
*/
|
||||
|
||||
writel_relaxed(0x06, VA_L2CC_BASE + L2X0_PREFETCH_CTRL);
|
||||
|
||||
/*
|
||||
* Program following latencies in order to make
|
||||
* SPEAr1340 work at 600 MHz
|
||||
*/
|
||||
writel_relaxed(0x221, VA_L2CC_BASE + L2X0_TAG_LATENCY_CTRL);
|
||||
writel_relaxed(0x441, VA_L2CC_BASE + L2X0_DATA_LATENCY_CTRL);
|
||||
l2x0_init(VA_L2CC_BASE, 0x70A60001, 0xfe00ffff);
|
||||
}
|
||||
|
||||
/*
|
||||
* Following will create 16MB static virtual/physical mappings
|
||||
* PHYSICAL VIRTUAL
|
||||
* 0xB3000000 0xFE000000
|
||||
* 0xE0000000 0xFD000000
|
||||
* 0xEC000000 0xFC000000
|
||||
* 0xED000000 0xFB000000
|
||||
*/
|
||||
struct map_desc spear13xx_io_desc[] __initdata = {
|
||||
{
|
||||
.virtual = VA_PERIP_GRP2_BASE,
|
||||
.pfn = __phys_to_pfn(PERIP_GRP2_BASE),
|
||||
.length = SZ_16M,
|
||||
.type = MT_DEVICE
|
||||
}, {
|
||||
.virtual = VA_PERIP_GRP1_BASE,
|
||||
.pfn = __phys_to_pfn(PERIP_GRP1_BASE),
|
||||
.length = SZ_16M,
|
||||
.type = MT_DEVICE
|
||||
}, {
|
||||
.virtual = VA_A9SM_AND_MPMC_BASE,
|
||||
.pfn = __phys_to_pfn(A9SM_AND_MPMC_BASE),
|
||||
.length = SZ_16M,
|
||||
.type = MT_DEVICE
|
||||
}, {
|
||||
.virtual = (unsigned long)VA_L2CC_BASE,
|
||||
.pfn = __phys_to_pfn(L2CC_BASE),
|
||||
.length = SZ_4K,
|
||||
.type = MT_DEVICE
|
||||
},
|
||||
};
|
||||
|
||||
/* This will create static memory mapping for selected devices */
|
||||
void __init spear13xx_map_io(void)
|
||||
{
|
||||
iotable_init(spear13xx_io_desc, ARRAY_SIZE(spear13xx_io_desc));
|
||||
}
|
||||
|
||||
static void __init spear13xx_clk_init(void)
|
||||
{
|
||||
if (of_machine_is_compatible("st,spear1310"))
|
||||
spear1310_clk_init();
|
||||
else if (of_machine_is_compatible("st,spear1340"))
|
||||
spear1340_clk_init();
|
||||
else
|
||||
pr_err("%s: Unknown machine\n", __func__);
|
||||
}
|
||||
|
||||
static void __init spear13xx_timer_init(void)
|
||||
{
|
||||
char pclk_name[] = "osc_24m_clk";
|
||||
struct clk *gpt_clk, *pclk;
|
||||
|
||||
spear13xx_clk_init();
|
||||
|
||||
/* get the system timer clock */
|
||||
gpt_clk = clk_get_sys("gpt0", NULL);
|
||||
if (IS_ERR(gpt_clk)) {
|
||||
pr_err("%s:couldn't get clk for gpt\n", __func__);
|
||||
BUG();
|
||||
}
|
||||
|
||||
/* get the suitable parent clock for timer*/
|
||||
pclk = clk_get(NULL, pclk_name);
|
||||
if (IS_ERR(pclk)) {
|
||||
pr_err("%s:couldn't get %s as parent for gpt\n", __func__,
|
||||
pclk_name);
|
||||
BUG();
|
||||
}
|
||||
|
||||
clk_set_parent(gpt_clk, pclk);
|
||||
clk_put(gpt_clk);
|
||||
clk_put(pclk);
|
||||
|
||||
spear_setup_of_timer();
|
||||
twd_local_timer_of_register();
|
||||
}
|
||||
|
||||
struct sys_timer spear13xx_timer = {
|
||||
.init = spear13xx_timer_init,
|
||||
};
|
||||
|
||||
static const struct of_device_id gic_of_match[] __initconst = {
|
||||
{ .compatible = "arm,cortex-a9-gic", .data = gic_of_init },
|
||||
{ /* Sentinel */ }
|
||||
};
|
||||
|
||||
void __init spear13xx_dt_init_irq(void)
|
||||
{
|
||||
of_irq_init(gic_of_match);
|
||||
}
|
|
@ -16,6 +16,7 @@
|
|||
#include <mach/spear.h>
|
||||
#include <mach/generic.h>
|
||||
|
||||
#define SPEAR13XX_SYS_SW_RES (VA_MISC_BASE + 0x204)
|
||||
void spear_restart(char mode, const char *cmd)
|
||||
{
|
||||
if (mode == 's') {
|
||||
|
@ -23,6 +24,10 @@ void spear_restart(char mode, const char *cmd)
|
|||
soft_restart(0);
|
||||
} else {
|
||||
/* hardware reset, Use on-chip reset capability */
|
||||
#ifdef CONFIG_ARCH_SPEAR13XX
|
||||
writel_relaxed(0x01, SPEAR13XX_SYS_SW_RES);
|
||||
#else
|
||||
sysctl_soft_reset((void __iomem *)VA_SPEAR_SYS_CTRL_BASE);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче