Merge branch 'heads/soc2' into boards2-base
This commit is contained in:
commit
63862f14bd
34 changed files with 1260 additions and 146 deletions
36
arch/arm/boot/dts/r7s72100.dtsi
Normal file
36
arch/arm/boot/dts/r7s72100.dtsi
Normal file
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Device Tree Source for the r7s72100 SoC
|
||||
*
|
||||
* Copyright (C) 2013 Renesas Solutions Corp.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/ {
|
||||
compatible = "renesas,r7s72100";
|
||||
interrupt-parent = <&gic>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
cpus {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
cpu@0 {
|
||||
device_type = "cpu";
|
||||
compatible = "arm,cortex-a9";
|
||||
reg = <0>;
|
||||
};
|
||||
};
|
||||
|
||||
gic: interrupt-controller@e8201000 {
|
||||
compatible = "arm,cortex-a9-gic";
|
||||
#interrupt-cells = <3>;
|
||||
#address-cells = <0>;
|
||||
interrupt-controller;
|
||||
reg = <0xe8201000 0x1000>,
|
||||
<0xe8202000 0x1000>;
|
||||
};
|
||||
};
|
|
@ -113,6 +113,12 @@ config ARCH_EMEV2
|
|||
select ARM_GIC
|
||||
select CPU_V7
|
||||
|
||||
config ARCH_R7S72100
|
||||
bool "RZ/A1H (R7S72100)"
|
||||
select ARM_GIC
|
||||
select CPU_V7
|
||||
select SH_CLK_CPG
|
||||
|
||||
comment "SH-Mobile Board Type"
|
||||
|
||||
config MACH_APE6EVM
|
||||
|
|
|
@ -15,8 +15,10 @@ obj-$(CONFIG_ARCH_R8A7740) += setup-r8a7740.o
|
|||
obj-$(CONFIG_ARCH_R8A7778) += setup-r8a7778.o
|
||||
obj-$(CONFIG_ARCH_R8A7779) += setup-r8a7779.o
|
||||
obj-$(CONFIG_ARCH_R8A7790) += setup-r8a7790.o
|
||||
obj-$(CONFIG_ARCH_R8A7791) += setup-r8a7791.o
|
||||
obj-$(CONFIG_ARCH_R8A7790) += setup-r8a7790.o setup-rcar-gen2.o
|
||||
obj-$(CONFIG_ARCH_R8A7791) += setup-r8a7791.o setup-rcar-gen2.o
|
||||
obj-$(CONFIG_ARCH_EMEV2) += setup-emev2.o
|
||||
obj-$(CONFIG_ARCH_R7S72100) += setup-r7s72100.o
|
||||
|
||||
# Clock objects
|
||||
ifndef CONFIG_COMMON_CLK
|
||||
|
@ -30,12 +32,15 @@ obj-$(CONFIG_ARCH_R8A7779) += clock-r8a7779.o
|
|||
obj-$(CONFIG_ARCH_R8A7790) += clock-r8a7790.o
|
||||
obj-$(CONFIG_ARCH_R8A7791) += clock-r8a7791.o
|
||||
obj-$(CONFIG_ARCH_EMEV2) += clock-emev2.o
|
||||
obj-$(CONFIG_ARCH_R7S72100) += clock-r7s72100.o
|
||||
endif
|
||||
|
||||
# SMP objects
|
||||
smp-y := platsmp.o headsmp.o
|
||||
smp-$(CONFIG_ARCH_SH73A0) += smp-sh73a0.o headsmp-scu.o platsmp-scu.o
|
||||
smp-$(CONFIG_ARCH_R8A7779) += smp-r8a7779.o headsmp-scu.o platsmp-scu.o
|
||||
smp-$(CONFIG_ARCH_R8A7790) += smp-r8a7790.o platsmp-apmu.o
|
||||
smp-$(CONFIG_ARCH_R8A7791) += smp-r8a7791.o platsmp-apmu.o
|
||||
smp-$(CONFIG_ARCH_EMEV2) += smp-emev2.o headsmp-scu.o platsmp-scu.o
|
||||
|
||||
# IRQ objects
|
||||
|
|
|
@ -57,7 +57,7 @@ static const char *ape6evm_boards_compat_dt[] __initdata = {
|
|||
};
|
||||
|
||||
DT_MACHINE_START(APE6EVM_DT, "ape6evm")
|
||||
.init_early = r8a73a4_init_delay,
|
||||
.init_early = r8a73a4_init_early,
|
||||
.init_machine = ape6evm_add_standard_devices,
|
||||
.dt_compat = ape6evm_boards_compat_dt,
|
||||
MACHINE_END
|
||||
|
|
|
@ -279,7 +279,7 @@ static const char *ape6evm_boards_compat_dt[] __initdata = {
|
|||
};
|
||||
|
||||
DT_MACHINE_START(APE6EVM_DT, "ape6evm")
|
||||
.init_early = r8a73a4_init_delay,
|
||||
.init_early = r8a73a4_init_early,
|
||||
.init_machine = ape6evm_add_standard_devices,
|
||||
.dt_compat = ape6evm_boards_compat_dt,
|
||||
MACHINE_END
|
||||
|
|
|
@ -38,8 +38,9 @@ static const char *lager_boards_compat_dt[] __initdata = {
|
|||
};
|
||||
|
||||
DT_MACHINE_START(LAGER_DT, "lager")
|
||||
.init_early = r8a7790_init_delay,
|
||||
.smp = smp_ops(r8a7790_smp_ops),
|
||||
.init_early = r8a7790_init_early,
|
||||
.init_time = rcar_gen2_timer_init,
|
||||
.init_machine = lager_add_standard_devices,
|
||||
.init_time = r8a7790_timer_init,
|
||||
.dt_compat = lager_boards_compat_dt,
|
||||
MACHINE_END
|
||||
|
|
|
@ -229,8 +229,9 @@ static const char *lager_boards_compat_dt[] __initdata = {
|
|||
};
|
||||
|
||||
DT_MACHINE_START(LAGER_DT, "lager")
|
||||
.init_early = r8a7790_init_delay,
|
||||
.init_time = r8a7790_timer_init,
|
||||
.smp = smp_ops(r8a7790_smp_ops),
|
||||
.init_early = r8a7790_init_early,
|
||||
.init_time = rcar_gen2_timer_init,
|
||||
.init_machine = lager_add_standard_devices,
|
||||
.dt_compat = lager_boards_compat_dt,
|
||||
MACHINE_END
|
||||
|
|
202
arch/arm/mach-shmobile/clock-r7s72100.c
Normal file
202
arch/arm/mach-shmobile/clock-r7s72100.c
Normal file
|
@ -0,0 +1,202 @@
|
|||
/*
|
||||
* r7a72100 clock framework support
|
||||
*
|
||||
* Copyright (C) 2013 Renesas Solutions Corp.
|
||||
* Copyright (C) 2012 Phil Edworthy
|
||||
* Copyright (C) 2011 Magnus Damm
|
||||
*
|
||||
* 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; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/sh_clk.h>
|
||||
#include <linux/clkdev.h>
|
||||
#include <mach/common.h>
|
||||
#include <mach/r7s72100.h>
|
||||
|
||||
/* registers */
|
||||
#define FRQCR 0xfcfe0010
|
||||
#define FRQCR2 0xfcfe0014
|
||||
#define STBCR3 0xfcfe0420
|
||||
#define STBCR4 0xfcfe0424
|
||||
|
||||
#define PLL_RATE 30
|
||||
|
||||
static struct clk_mapping cpg_mapping = {
|
||||
.phys = 0xfcfe0000,
|
||||
.len = 0x1000,
|
||||
};
|
||||
|
||||
/* Fixed 32 KHz root clock for RTC */
|
||||
static struct clk r_clk = {
|
||||
.rate = 32768,
|
||||
};
|
||||
|
||||
/*
|
||||
* Default rate for the root input clock, reset this with clk_set_rate()
|
||||
* from the platform code.
|
||||
*/
|
||||
static struct clk extal_clk = {
|
||||
.rate = 13330000,
|
||||
.mapping = &cpg_mapping,
|
||||
};
|
||||
|
||||
static unsigned long pll_recalc(struct clk *clk)
|
||||
{
|
||||
return clk->parent->rate * PLL_RATE;
|
||||
}
|
||||
|
||||
static struct sh_clk_ops pll_clk_ops = {
|
||||
.recalc = pll_recalc,
|
||||
};
|
||||
|
||||
static struct clk pll_clk = {
|
||||
.ops = &pll_clk_ops,
|
||||
.parent = &extal_clk,
|
||||
.flags = CLK_ENABLE_ON_INIT,
|
||||
};
|
||||
|
||||
static unsigned long bus_recalc(struct clk *clk)
|
||||
{
|
||||
return clk->parent->rate * 2 / 3;
|
||||
}
|
||||
|
||||
static struct sh_clk_ops bus_clk_ops = {
|
||||
.recalc = bus_recalc,
|
||||
};
|
||||
|
||||
static struct clk bus_clk = {
|
||||
.ops = &bus_clk_ops,
|
||||
.parent = &pll_clk,
|
||||
.flags = CLK_ENABLE_ON_INIT,
|
||||
};
|
||||
|
||||
static unsigned long peripheral0_recalc(struct clk *clk)
|
||||
{
|
||||
return clk->parent->rate / 12;
|
||||
}
|
||||
|
||||
static struct sh_clk_ops peripheral0_clk_ops = {
|
||||
.recalc = peripheral0_recalc,
|
||||
};
|
||||
|
||||
static struct clk peripheral0_clk = {
|
||||
.ops = &peripheral0_clk_ops,
|
||||
.parent = &pll_clk,
|
||||
.flags = CLK_ENABLE_ON_INIT,
|
||||
};
|
||||
|
||||
static unsigned long peripheral1_recalc(struct clk *clk)
|
||||
{
|
||||
return clk->parent->rate / 6;
|
||||
}
|
||||
|
||||
static struct sh_clk_ops peripheral1_clk_ops = {
|
||||
.recalc = peripheral1_recalc,
|
||||
};
|
||||
|
||||
static struct clk peripheral1_clk = {
|
||||
.ops = &peripheral1_clk_ops,
|
||||
.parent = &pll_clk,
|
||||
.flags = CLK_ENABLE_ON_INIT,
|
||||
};
|
||||
|
||||
struct clk *main_clks[] = {
|
||||
&r_clk,
|
||||
&extal_clk,
|
||||
&pll_clk,
|
||||
&bus_clk,
|
||||
&peripheral0_clk,
|
||||
&peripheral1_clk,
|
||||
};
|
||||
|
||||
static int div2[] = { 1, 3, 0, 3 }; /* 1, 2/3, reserve, 1/3 */
|
||||
static int multipliers[] = { 1, 2, 1, 1 };
|
||||
|
||||
static struct clk_div_mult_table div4_div_mult_table = {
|
||||
.divisors = div2,
|
||||
.nr_divisors = ARRAY_SIZE(div2),
|
||||
.multipliers = multipliers,
|
||||
.nr_multipliers = ARRAY_SIZE(multipliers),
|
||||
};
|
||||
|
||||
static struct clk_div4_table div4_table = {
|
||||
.div_mult_table = &div4_div_mult_table,
|
||||
};
|
||||
|
||||
enum { DIV4_I,
|
||||
DIV4_NR };
|
||||
|
||||
#define DIV4(_reg, _bit, _mask, _flags) \
|
||||
SH_CLK_DIV4(&pll_clk, _reg, _bit, _mask, _flags)
|
||||
|
||||
/* The mask field specifies the div2 entries that are valid */
|
||||
struct clk div4_clks[DIV4_NR] = {
|
||||
[DIV4_I] = DIV4(FRQCR, 8, 0xB, CLK_ENABLE_REG_16BIT
|
||||
| CLK_ENABLE_ON_INIT),
|
||||
};
|
||||
|
||||
enum { MSTP47, MSTP46, MSTP45, MSTP44, MSTP43, MSTP42, MSTP41, MSTP40,
|
||||
MSTP33, MSTP_NR };
|
||||
|
||||
static struct clk mstp_clks[MSTP_NR] = {
|
||||
[MSTP47] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 7, 0), /* SCIF0 */
|
||||
[MSTP46] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 6, 0), /* SCIF1 */
|
||||
[MSTP45] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 5, 0), /* SCIF2 */
|
||||
[MSTP44] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 4, 0), /* SCIF3 */
|
||||
[MSTP43] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 3, 0), /* SCIF4 */
|
||||
[MSTP42] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 2, 0), /* SCIF5 */
|
||||
[MSTP41] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 1, 0), /* SCIF6 */
|
||||
[MSTP40] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 0, 0), /* SCIF7 */
|
||||
[MSTP33] = SH_CLK_MSTP8(&peripheral0_clk, STBCR3, 3, 0), /* MTU2 */
|
||||
};
|
||||
|
||||
static struct clk_lookup lookups[] = {
|
||||
/* main clocks */
|
||||
CLKDEV_CON_ID("rclk", &r_clk),
|
||||
CLKDEV_CON_ID("extal", &extal_clk),
|
||||
CLKDEV_CON_ID("pll_clk", &pll_clk),
|
||||
CLKDEV_CON_ID("peripheral_clk", &peripheral1_clk),
|
||||
|
||||
/* DIV4 clocks */
|
||||
CLKDEV_CON_ID("cpu_clk", &div4_clks[DIV4_I]),
|
||||
|
||||
/* MSTP clocks */
|
||||
CLKDEV_ICK_ID("sci_fck", "sh-sci.0", &mstp_clks[MSTP47]),
|
||||
CLKDEV_ICK_ID("sci_fck", "sh-sci.1", &mstp_clks[MSTP46]),
|
||||
CLKDEV_ICK_ID("sci_fck", "sh-sci.2", &mstp_clks[MSTP45]),
|
||||
CLKDEV_ICK_ID("sci_fck", "sh-sci.3", &mstp_clks[MSTP44]),
|
||||
CLKDEV_ICK_ID("sci_fck", "sh-sci.4", &mstp_clks[MSTP43]),
|
||||
CLKDEV_ICK_ID("sci_fck", "sh-sci.5", &mstp_clks[MSTP42]),
|
||||
CLKDEV_ICK_ID("sci_fck", "sh-sci.6", &mstp_clks[MSTP41]),
|
||||
CLKDEV_ICK_ID("sci_fck", "sh-sci.7", &mstp_clks[MSTP40]),
|
||||
};
|
||||
|
||||
void __init r7s72100_clock_init(void)
|
||||
{
|
||||
int k, ret = 0;
|
||||
|
||||
for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
|
||||
ret = clk_register(main_clks[k]);
|
||||
|
||||
clkdev_add_table(lookups, ARRAY_SIZE(lookups));
|
||||
|
||||
if (!ret)
|
||||
ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
|
||||
|
||||
if (!ret)
|
||||
ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);
|
||||
|
||||
if (!ret)
|
||||
shmobile_clk_init();
|
||||
else
|
||||
panic("failed to setup rza1 clocks\n");
|
||||
}
|
|
@ -504,7 +504,7 @@ static struct clk div6_clks[DIV6_NR] = {
|
|||
|
||||
/* MSTP */
|
||||
enum {
|
||||
MSTP217, MSTP216, MSTP207, MSTP206, MSTP204, MSTP203,
|
||||
MSTP218, MSTP217, MSTP216, MSTP207, MSTP206, MSTP204, MSTP203,
|
||||
MSTP329, MSTP323, MSTP318, MSTP317, MSTP316,
|
||||
MSTP315, MSTP314, MSTP313, MSTP312, MSTP305, MSTP300,
|
||||
MSTP411, MSTP410, MSTP409,
|
||||
|
@ -519,6 +519,7 @@ static struct clk mstp_clks[MSTP_NR] = {
|
|||
[MSTP207] = SH_CLK_MSTP32(&div6_clks[DIV6_MP], SMSTPCR2, 7, 0), /* SCIFB1 */
|
||||
[MSTP216] = SH_CLK_MSTP32(&div6_clks[DIV6_MP], SMSTPCR2, 16, 0), /* SCIFB2 */
|
||||
[MSTP217] = SH_CLK_MSTP32(&div6_clks[DIV6_MP], SMSTPCR2, 17, 0), /* SCIFB3 */
|
||||
[MSTP218] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR2, 18, 0), /* DMAC */
|
||||
[MSTP300] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR3, 0, 0), /* IIC2 */
|
||||
[MSTP305] = SH_CLK_MSTP32(&div6_clks[DIV6_MMC1],SMSTPCR3, 5, 0), /* MMCIF1 */
|
||||
[MSTP312] = SH_CLK_MSTP32(&div6_clks[DIV6_SDHI2],SMSTPCR3, 12, 0), /* SDHI2 */
|
||||
|
@ -578,6 +579,8 @@ static struct clk_lookup lookups[] = {
|
|||
CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP207]),
|
||||
CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP216]),
|
||||
CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP217]),
|
||||
CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP218]),
|
||||
CLKDEV_DEV_ID("e6700020.dma-controller", &mstp_clks[MSTP218]),
|
||||
CLKDEV_DEV_ID("rcar_thermal", &mstp_clks[MSTP522]),
|
||||
CLKDEV_DEV_ID("e6520000.i2c", &mstp_clks[MSTP300]),
|
||||
CLKDEV_DEV_ID("sh_mmcif.1", &mstp_clks[MSTP305]),
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
#define SMSTPCR5 0xe6150144
|
||||
#define SMSTPCR7 0xe615014c
|
||||
#define SMSTPCR8 0xe6150990
|
||||
#define SMSTPCR9 0xe6150994
|
||||
|
||||
#define SDCKCR 0xE6150074
|
||||
#define SD2CKCR 0xE6150078
|
||||
|
@ -181,6 +182,7 @@ static struct clk div6_clks[DIV6_NR] = {
|
|||
|
||||
/* MSTP */
|
||||
enum {
|
||||
MSTP931, MSTP930, MSTP929, MSTP928,
|
||||
MSTP813,
|
||||
MSTP726, MSTP725, MSTP724, MSTP723, MSTP722, MSTP721, MSTP720,
|
||||
MSTP717, MSTP716,
|
||||
|
@ -192,6 +194,10 @@ enum {
|
|||
};
|
||||
|
||||
static struct clk mstp_clks[MSTP_NR] = {
|
||||
[MSTP931] = SH_CLK_MSTP32(&hp_clk, SMSTPCR9, 31, 0), /* I2C0 */
|
||||
[MSTP930] = SH_CLK_MSTP32(&hp_clk, SMSTPCR9, 30, 0), /* I2C1 */
|
||||
[MSTP929] = SH_CLK_MSTP32(&hp_clk, SMSTPCR9, 29, 0), /* I2C2 */
|
||||
[MSTP928] = SH_CLK_MSTP32(&hp_clk, SMSTPCR9, 28, 0), /* I2C3 */
|
||||
[MSTP813] = SH_CLK_MSTP32(&p_clk, SMSTPCR8, 13, 0), /* Ether */
|
||||
[MSTP726] = SH_CLK_MSTP32(&zx_clk, SMSTPCR7, 26, 0), /* LVDS0 */
|
||||
[MSTP725] = SH_CLK_MSTP32(&zx_clk, SMSTPCR7, 25, 0), /* LVDS1 */
|
||||
|
@ -271,6 +277,10 @@ static struct clk_lookup lookups[] = {
|
|||
CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP720]),
|
||||
CLKDEV_DEV_ID("sh-sci.8", &mstp_clks[MSTP717]),
|
||||
CLKDEV_DEV_ID("sh-sci.9", &mstp_clks[MSTP716]),
|
||||
CLKDEV_DEV_ID("e6508000.i2c", &mstp_clks[MSTP931]),
|
||||
CLKDEV_DEV_ID("e6518000.i2c", &mstp_clks[MSTP930]),
|
||||
CLKDEV_DEV_ID("e6530000.i2c", &mstp_clks[MSTP929]),
|
||||
CLKDEV_DEV_ID("e6540000.i2c", &mstp_clks[MSTP928]),
|
||||
CLKDEV_DEV_ID("r8a7790-ether", &mstp_clks[MSTP813]),
|
||||
CLKDEV_DEV_ID("rcar_thermal", &mstp_clks[MSTP522]),
|
||||
CLKDEV_DEV_ID("ee200000.mmcif", &mstp_clks[MSTP315]),
|
||||
|
@ -300,7 +310,7 @@ static struct clk_lookup lookups[] = {
|
|||
|
||||
void __init r8a7790_clock_init(void)
|
||||
{
|
||||
u32 mode = r8a7790_read_mode_pins();
|
||||
u32 mode = rcar_gen2_read_mode_pins();
|
||||
int k, ret = 0;
|
||||
|
||||
switch (mode & (MD(14) | MD(13))) {
|
||||
|
|
|
@ -40,6 +40,9 @@ shmobile_boot_fn:
|
|||
.globl shmobile_boot_arg
|
||||
shmobile_boot_arg:
|
||||
2: .space 4
|
||||
.globl shmobile_boot_size
|
||||
shmobile_boot_size:
|
||||
.long . - shmobile_boot_vector
|
||||
|
||||
/*
|
||||
* Per-CPU SMP boot function/argument selection code based on MPIDR
|
||||
|
|
|
@ -9,16 +9,23 @@ extern void shmobile_setup_console(void);
|
|||
extern void shmobile_boot_vector(void);
|
||||
extern unsigned long shmobile_boot_fn;
|
||||
extern unsigned long shmobile_boot_arg;
|
||||
extern unsigned long shmobile_boot_size;
|
||||
extern void shmobile_smp_boot(void);
|
||||
extern void shmobile_smp_sleep(void);
|
||||
extern void shmobile_smp_hook(unsigned int cpu, unsigned long fn,
|
||||
unsigned long arg);
|
||||
extern int shmobile_smp_cpu_disable(unsigned int cpu);
|
||||
extern void shmobile_invalidate_start(void);
|
||||
extern void shmobile_boot_scu(void);
|
||||
extern void shmobile_smp_scu_prepare_cpus(unsigned int max_cpus);
|
||||
extern int shmobile_smp_scu_boot_secondary(unsigned int cpu,
|
||||
struct task_struct *idle);
|
||||
extern void shmobile_smp_scu_cpu_die(unsigned int cpu);
|
||||
extern int shmobile_smp_scu_cpu_kill(unsigned int cpu);
|
||||
extern void shmobile_smp_apmu_prepare_cpus(unsigned int max_cpus);
|
||||
extern int shmobile_smp_apmu_boot_secondary(unsigned int cpu,
|
||||
struct task_struct *idle);
|
||||
extern void shmobile_smp_apmu_cpu_die(unsigned int cpu);
|
||||
extern int shmobile_smp_apmu_cpu_kill(unsigned int cpu);
|
||||
extern void shmobile_invalidate_start(void);
|
||||
struct clk;
|
||||
extern int shmobile_clk_init(void);
|
||||
extern void shmobile_handle_irq_intc(struct pt_regs *);
|
||||
|
@ -39,7 +46,6 @@ static inline int shmobile_cpuidle_init(void) { return 0; }
|
|||
#endif
|
||||
|
||||
extern void __iomem *shmobile_scu_base;
|
||||
extern void shmobile_smp_init_cpus(unsigned int ncores);
|
||||
|
||||
static inline void __init shmobile_init_late(void)
|
||||
{
|
||||
|
|
8
arch/arm/mach-shmobile/include/mach/r7s72100.h
Normal file
8
arch/arm/mach-shmobile/include/mach/r7s72100.h
Normal file
|
@ -0,0 +1,8 @@
|
|||
#ifndef __ASM_R7S72100_H__
|
||||
#define __ASM_R7S72100_H__
|
||||
|
||||
void r7s72100_add_dt_devices(void);
|
||||
void r7s72100_clock_init(void);
|
||||
void r7s72100_init_early(void);
|
||||
|
||||
#endif /* __ASM_R7S72100_H__ */
|
|
@ -1,10 +1,19 @@
|
|||
#ifndef __ASM_R8A73A4_H__
|
||||
#define __ASM_R8A73A4_H__
|
||||
|
||||
/* DMA slave IDs */
|
||||
enum {
|
||||
SHDMA_SLAVE_INVALID,
|
||||
SHDMA_SLAVE_MMCIF0_TX,
|
||||
SHDMA_SLAVE_MMCIF0_RX,
|
||||
SHDMA_SLAVE_MMCIF1_TX,
|
||||
SHDMA_SLAVE_MMCIF1_RX,
|
||||
};
|
||||
|
||||
void r8a73a4_add_standard_devices(void);
|
||||
void r8a73a4_add_dt_devices(void);
|
||||
void r8a73a4_clock_init(void);
|
||||
void r8a73a4_pinmux_init(void);
|
||||
void r8a73a4_init_delay(void);
|
||||
void r8a73a4_init_early(void);
|
||||
|
||||
#endif /* __ASM_R8A73A4_H__ */
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/*
|
||||
* Copyright (C) 2013 Renesas Solutions Corp.
|
||||
* Copyright (C) 2013 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
|
||||
* Copyright (C) 2013 Cogent Embedded, 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
|
||||
|
@ -21,6 +22,13 @@
|
|||
#include <linux/sh_eth.h>
|
||||
#include <linux/platform_data/camera-rcar.h>
|
||||
|
||||
/* HPB-DMA slave IDs */
|
||||
enum {
|
||||
HPBDMA_SLAVE_DUMMY,
|
||||
HPBDMA_SLAVE_SDHI0_TX,
|
||||
HPBDMA_SLAVE_SDHI0_RX,
|
||||
};
|
||||
|
||||
extern void r8a7778_add_standard_devices(void);
|
||||
extern void r8a7778_add_standard_devices_dt(void);
|
||||
extern void r8a7778_add_ether_device(struct sh_eth_plat_data *pdata);
|
||||
|
@ -33,6 +41,7 @@ extern void r8a7778_init_delay(void);
|
|||
extern void r8a7778_init_irq_dt(void);
|
||||
extern void r8a7778_clock_init(void);
|
||||
extern void r8a7778_init_irq_extpin(int irlm);
|
||||
extern void r8a7778_init_irq_extpin_dt(int irlm);
|
||||
extern void r8a7778_pinmux_init(void);
|
||||
|
||||
extern int r8a7778_usb_phy_power(bool enable);
|
||||
|
|
|
@ -6,6 +6,13 @@
|
|||
#include <linux/sh_eth.h>
|
||||
#include <linux/platform_data/camera-rcar.h>
|
||||
|
||||
/* HPB-DMA slave IDs */
|
||||
enum {
|
||||
HPBDMA_SLAVE_DUMMY,
|
||||
HPBDMA_SLAVE_SDHI0_TX,
|
||||
HPBDMA_SLAVE_SDHI0_RX,
|
||||
};
|
||||
|
||||
struct platform_device;
|
||||
|
||||
struct r8a7779_pm_ch {
|
||||
|
@ -26,6 +33,7 @@ static inline struct r8a7779_pm_ch *to_r8a7779_ch(struct generic_pm_domain *d)
|
|||
|
||||
extern void r8a7779_init_delay(void);
|
||||
extern void r8a7779_init_irq_extpin(int irlm);
|
||||
extern void r8a7779_init_irq_extpin_dt(int irlm);
|
||||
extern void r8a7779_init_irq_dt(void);
|
||||
extern void r8a7779_map_io(void);
|
||||
extern void r8a7779_earlytimer_init(void);
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
#ifndef __ASM_R8A7790_H__
|
||||
#define __ASM_R8A7790_H__
|
||||
|
||||
#include <mach/rcar-gen2.h>
|
||||
|
||||
void r8a7790_add_standard_devices(void);
|
||||
void r8a7790_add_dt_devices(void);
|
||||
void r8a7790_clock_init(void);
|
||||
void r8a7790_pinmux_init(void);
|
||||
void r8a7790_init_delay(void);
|
||||
void r8a7790_timer_init(void);
|
||||
|
||||
#define MD(nr) BIT(nr)
|
||||
u32 r8a7790_read_mode_pins(void);
|
||||
void r8a7790_init_early(void);
|
||||
extern struct smp_operations r8a7790_smp_ops;
|
||||
|
||||
#endif /* __ASM_R8A7790_H__ */
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
#ifndef __ASM_R8A7791_H__
|
||||
#define __ASM_R8A7791_H__
|
||||
|
||||
void r8a7791_add_standard_devices(void);
|
||||
void r8a7791_add_dt_devices(void);
|
||||
void r8a7791_clock_init(void);
|
||||
void r8a7791_init_early(void);
|
||||
extern struct smp_operations r8a7791_smp_ops;
|
||||
|
||||
#endif /* __ASM_R8A7791_H__ */
|
||||
|
|
8
arch/arm/mach-shmobile/include/mach/rcar-gen2.h
Normal file
8
arch/arm/mach-shmobile/include/mach/rcar-gen2.h
Normal file
|
@ -0,0 +1,8 @@
|
|||
#ifndef __ASM_RCAR_GEN2_H__
|
||||
#define __ASM_RCAR_GEN2_H__
|
||||
|
||||
void rcar_gen2_timer_init(void);
|
||||
#define MD(nr) BIT(nr)
|
||||
u32 rcar_gen2_read_mode_pins(void);
|
||||
|
||||
#endif /* __ASM_RCAR_GEN2_H__ */
|
195
arch/arm/mach-shmobile/platsmp-apmu.c
Normal file
195
arch/arm/mach-shmobile/platsmp-apmu.c
Normal file
|
@ -0,0 +1,195 @@
|
|||
/*
|
||||
* SMP support for SoCs with APMU
|
||||
*
|
||||
* Copyright (C) 2013 Magnus Damm
|
||||
*
|
||||
* 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/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/smp.h>
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/cp15.h>
|
||||
#include <asm/smp_plat.h>
|
||||
#include <mach/common.h>
|
||||
|
||||
static struct {
|
||||
void __iomem *iomem;
|
||||
int bit;
|
||||
} apmu_cpus[CONFIG_NR_CPUS];
|
||||
|
||||
#define WUPCR_OFFS 0x10
|
||||
#define PSTR_OFFS 0x40
|
||||
#define CPUNCR_OFFS(n) (0x100 + (0x10 * (n)))
|
||||
|
||||
static int apmu_power_on(void __iomem *p, int bit)
|
||||
{
|
||||
/* request power on */
|
||||
writel_relaxed(BIT(bit), p + WUPCR_OFFS);
|
||||
|
||||
/* wait for APMU to finish */
|
||||
while (readl_relaxed(p + WUPCR_OFFS) != 0)
|
||||
;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int apmu_power_off(void __iomem *p, int bit)
|
||||
{
|
||||
/* request Core Standby for next WFI */
|
||||
writel_relaxed(3, p + CPUNCR_OFFS(bit));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int apmu_power_off_poll(void __iomem *p, int bit)
|
||||
{
|
||||
int k;
|
||||
|
||||
for (k = 0; k < 1000; k++) {
|
||||
if (((readl_relaxed(p + PSTR_OFFS) >> (bit * 4)) & 0x03) == 3)
|
||||
return 1;
|
||||
|
||||
mdelay(1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int apmu_wrap(int cpu, int (*fn)(void __iomem *p, int cpu))
|
||||
{
|
||||
void __iomem *p = apmu_cpus[cpu].iomem;
|
||||
|
||||
return p ? fn(p, apmu_cpus[cpu].bit) : -EINVAL;
|
||||
}
|
||||
|
||||
static void apmu_init_cpu(struct resource *res, int cpu, int bit)
|
||||
{
|
||||
if (apmu_cpus[cpu].iomem)
|
||||
return;
|
||||
|
||||
apmu_cpus[cpu].iomem = ioremap_nocache(res->start, resource_size(res));
|
||||
apmu_cpus[cpu].bit = bit;
|
||||
|
||||
pr_debug("apmu ioremap %d %d 0x%08x 0x%08x\n", cpu, bit,
|
||||
res->start, resource_size(res));
|
||||
}
|
||||
|
||||
static struct {
|
||||
struct resource iomem;
|
||||
int cpus[4];
|
||||
} apmu_config[] = {
|
||||
{
|
||||
.iomem = DEFINE_RES_MEM(0xe6152000, 0x88),
|
||||
.cpus = { 0, 1, 2, 3 },
|
||||
},
|
||||
{
|
||||
.iomem = DEFINE_RES_MEM(0xe6151000, 0x88),
|
||||
.cpus = { 0x100, 0x101, 0x102, 0x103 },
|
||||
}
|
||||
};
|
||||
|
||||
static void apmu_parse_cfg(void (*fn)(struct resource *res, int cpu, int bit))
|
||||
{
|
||||
u32 id;
|
||||
int k;
|
||||
int bit, index;
|
||||
bool is_allowed;
|
||||
|
||||
for (k = 0; k < ARRAY_SIZE(apmu_config); k++) {
|
||||
/* only enable the cluster that includes the boot CPU */
|
||||
is_allowed = false;
|
||||
for (bit = 0; bit < ARRAY_SIZE(apmu_config[k].cpus); bit++) {
|
||||
id = apmu_config[k].cpus[bit];
|
||||
if (id >= 0) {
|
||||
if (id == cpu_logical_map(0))
|
||||
is_allowed = true;
|
||||
}
|
||||
}
|
||||
if (!is_allowed)
|
||||
continue;
|
||||
|
||||
for (bit = 0; bit < ARRAY_SIZE(apmu_config[k].cpus); bit++) {
|
||||
id = apmu_config[k].cpus[bit];
|
||||
if (id >= 0) {
|
||||
index = get_logical_index(id);
|
||||
if (index >= 0)
|
||||
fn(&apmu_config[k].iomem, index, bit);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void __init shmobile_smp_apmu_prepare_cpus(unsigned int max_cpus)
|
||||
{
|
||||
/* install boot code shared by all CPUs */
|
||||
shmobile_boot_fn = virt_to_phys(shmobile_smp_boot);
|
||||
shmobile_boot_arg = MPIDR_HWID_BITMASK;
|
||||
|
||||
/* perform per-cpu setup */
|
||||
apmu_parse_cfg(apmu_init_cpu);
|
||||
}
|
||||
|
||||
int shmobile_smp_apmu_boot_secondary(unsigned int cpu, struct task_struct *idle)
|
||||
{
|
||||
/* For this particular CPU register boot vector */
|
||||
shmobile_smp_hook(cpu, virt_to_phys(shmobile_invalidate_start), 0);
|
||||
|
||||
return apmu_wrap(cpu, apmu_power_on);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HOTPLUG_CPU
|
||||
/* nicked from arch/arm/mach-exynos/hotplug.c */
|
||||
static inline void cpu_enter_lowpower_a15(void)
|
||||
{
|
||||
unsigned int v;
|
||||
|
||||
asm volatile(
|
||||
" mrc p15, 0, %0, c1, c0, 0\n"
|
||||
" bic %0, %0, %1\n"
|
||||
" mcr p15, 0, %0, c1, c0, 0\n"
|
||||
: "=&r" (v)
|
||||
: "Ir" (CR_C)
|
||||
: "cc");
|
||||
|
||||
flush_cache_louis();
|
||||
|
||||
asm volatile(
|
||||
/*
|
||||
* Turn off coherency
|
||||
*/
|
||||
" mrc p15, 0, %0, c1, c0, 1\n"
|
||||
" bic %0, %0, %1\n"
|
||||
" mcr p15, 0, %0, c1, c0, 1\n"
|
||||
: "=&r" (v)
|
||||
: "Ir" (0x40)
|
||||
: "cc");
|
||||
|
||||
isb();
|
||||
dsb();
|
||||
}
|
||||
|
||||
void shmobile_smp_apmu_cpu_die(unsigned int cpu)
|
||||
{
|
||||
/* For this particular CPU deregister boot vector */
|
||||
shmobile_smp_hook(cpu, 0, 0);
|
||||
|
||||
/* Select next sleep mode using the APMU */
|
||||
apmu_wrap(cpu, apmu_power_off);
|
||||
|
||||
/* Do ARM specific CPU shutdown */
|
||||
cpu_enter_lowpower_a15();
|
||||
|
||||
/* jump to shared mach-shmobile sleep / reset code */
|
||||
shmobile_smp_sleep();
|
||||
}
|
||||
|
||||
int shmobile_smp_apmu_cpu_kill(unsigned int cpu)
|
||||
{
|
||||
return apmu_wrap(cpu, apmu_power_off_poll);
|
||||
}
|
||||
#endif
|
|
@ -7,6 +7,7 @@
|
|||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
|
@ -16,6 +17,26 @@
|
|||
#include <asm/smp_scu.h>
|
||||
#include <mach/common.h>
|
||||
|
||||
static int shmobile_smp_scu_notifier_call(struct notifier_block *nfb,
|
||||
unsigned long action, void *hcpu)
|
||||
{
|
||||
unsigned int cpu = (long)hcpu;
|
||||
|
||||
switch (action) {
|
||||
case CPU_UP_PREPARE:
|
||||
/* For this particular CPU register SCU SMP boot vector */
|
||||
shmobile_smp_hook(cpu, virt_to_phys(shmobile_boot_scu),
|
||||
(unsigned long)shmobile_scu_base);
|
||||
break;
|
||||
};
|
||||
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
|
||||
static struct notifier_block shmobile_smp_scu_notifier = {
|
||||
.notifier_call = shmobile_smp_scu_notifier_call,
|
||||
};
|
||||
|
||||
void __init shmobile_smp_scu_prepare_cpus(unsigned int max_cpus)
|
||||
{
|
||||
/* install boot code shared by all CPUs */
|
||||
|
@ -25,14 +46,9 @@ void __init shmobile_smp_scu_prepare_cpus(unsigned int max_cpus)
|
|||
/* enable SCU and cache coherency on booting CPU */
|
||||
scu_enable(shmobile_scu_base);
|
||||
scu_power_mode(shmobile_scu_base, SCU_PM_NORMAL);
|
||||
}
|
||||
|
||||
int shmobile_smp_scu_boot_secondary(unsigned int cpu, struct task_struct *idle)
|
||||
{
|
||||
/* For this particular CPU register SCU boot vector */
|
||||
shmobile_smp_hook(cpu, virt_to_phys(shmobile_boot_scu),
|
||||
(unsigned long)shmobile_scu_base);
|
||||
return 0;
|
||||
/* Use CPU notifier for reset vector control */
|
||||
register_cpu_notifier(&shmobile_smp_scu_notifier);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HOTPLUG_CPU
|
||||
|
|
|
@ -11,25 +11,10 @@
|
|||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#include <linux/init.h>
|
||||
#include <linux/smp.h>
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/smp_plat.h>
|
||||
#include <mach/common.h>
|
||||
|
||||
void __init shmobile_smp_init_cpus(unsigned int ncores)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
extern unsigned long shmobile_smp_fn[];
|
||||
extern unsigned long shmobile_smp_arg[];
|
||||
extern unsigned long shmobile_smp_mpidr[];
|
||||
|
@ -44,3 +29,10 @@ void shmobile_smp_hook(unsigned int cpu, unsigned long fn, unsigned long arg)
|
|||
shmobile_smp_arg[cpu] = arg;
|
||||
flush_cache_all();
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HOTPLUG_CPU
|
||||
int shmobile_smp_cpu_disable(unsigned int cpu)
|
||||
{
|
||||
return 0; /* Hotplug of any CPU is supported */
|
||||
}
|
||||
#endif
|
||||
|
|
88
arch/arm/mach-shmobile/setup-r7s72100.c
Normal file
88
arch/arm/mach-shmobile/setup-r7s72100.c
Normal file
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* r7s72100 processor support
|
||||
*
|
||||
* Copyright (C) 2013 Renesas Solutions Corp.
|
||||
* Copyright (C) 2013 Magnus Damm
|
||||
*
|
||||
* 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; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <linux/irq.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/serial_sci.h>
|
||||
#include <mach/common.h>
|
||||
#include <mach/irqs.h>
|
||||
#include <mach/r7s72100.h>
|
||||
#include <asm/mach/arch.h>
|
||||
|
||||
#define SCIF_DATA(index, baseaddr, irq) \
|
||||
[index] = { \
|
||||
.type = PORT_SCIF, \
|
||||
.regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, \
|
||||
.flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP, \
|
||||
.scbrr_algo_id = SCBRR_ALGO_2, \
|
||||
.scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_RE | SCSCR_TE | \
|
||||
SCSCR_REIE, \
|
||||
.mapbase = baseaddr, \
|
||||
.irqs = { irq + 1, irq + 2, irq + 3, irq }, \
|
||||
}
|
||||
|
||||
enum { SCIF0, SCIF1, SCIF2, SCIF3, SCIF4, SCIF5, SCIF6, SCIF7 };
|
||||
|
||||
static const struct plat_sci_port scif[] __initconst = {
|
||||
SCIF_DATA(SCIF0, 0xe8007000, gic_iid(221)), /* SCIF0 */
|
||||
SCIF_DATA(SCIF1, 0xe8007800, gic_iid(225)), /* SCIF1 */
|
||||
SCIF_DATA(SCIF2, 0xe8008000, gic_iid(229)), /* SCIF2 */
|
||||
SCIF_DATA(SCIF3, 0xe8008800, gic_iid(233)), /* SCIF3 */
|
||||
SCIF_DATA(SCIF4, 0xe8009000, gic_iid(237)), /* SCIF4 */
|
||||
SCIF_DATA(SCIF5, 0xe8009800, gic_iid(241)), /* SCIF5 */
|
||||
SCIF_DATA(SCIF6, 0xe800a000, gic_iid(245)), /* SCIF6 */
|
||||
SCIF_DATA(SCIF7, 0xe800a800, gic_iid(249)), /* SCIF7 */
|
||||
};
|
||||
|
||||
static inline void r7s72100_register_scif(int idx)
|
||||
{
|
||||
platform_device_register_data(&platform_bus, "sh-sci", idx, &scif[idx],
|
||||
sizeof(struct plat_sci_port));
|
||||
}
|
||||
|
||||
void __init r7s72100_add_dt_devices(void)
|
||||
{
|
||||
r7s72100_register_scif(SCIF0);
|
||||
r7s72100_register_scif(SCIF1);
|
||||
r7s72100_register_scif(SCIF2);
|
||||
r7s72100_register_scif(SCIF3);
|
||||
r7s72100_register_scif(SCIF4);
|
||||
r7s72100_register_scif(SCIF5);
|
||||
r7s72100_register_scif(SCIF6);
|
||||
r7s72100_register_scif(SCIF7);
|
||||
}
|
||||
|
||||
void __init r7s72100_init_early(void)
|
||||
{
|
||||
shmobile_setup_delay(400, 1, 3); /* Cortex-A9 @ 400MHz */
|
||||
}
|
||||
|
||||
#ifdef CONFIG_USE_OF
|
||||
static const char *r7s72100_boards_compat_dt[] __initdata = {
|
||||
"renesas,r7s72100",
|
||||
NULL,
|
||||
};
|
||||
|
||||
DT_MACHINE_START(R7S72100_DT, "Generic R7S72100 (Flattened Device Tree)")
|
||||
.init_early = r7s72100_init_early,
|
||||
.dt_compat = r7s72100_boards_compat_dt,
|
||||
MACHINE_END
|
||||
#endif /* CONFIG_USE_OF */
|
|
@ -22,8 +22,10 @@
|
|||
#include <linux/of_platform.h>
|
||||
#include <linux/platform_data/irq-renesas-irqc.h>
|
||||
#include <linux/serial_sci.h>
|
||||
#include <linux/sh_dma.h>
|
||||
#include <linux/sh_timer.h>
|
||||
#include <mach/common.h>
|
||||
#include <mach/dma-register.h>
|
||||
#include <mach/irqs.h>
|
||||
#include <mach/r8a73a4.h>
|
||||
#include <asm/mach/arch.h>
|
||||
|
@ -199,15 +201,104 @@ void __init r8a73a4_add_dt_devices(void)
|
|||
r8a7790_register_cmt(10);
|
||||
}
|
||||
|
||||
/* DMA */
|
||||
static const struct sh_dmae_slave_config dma_slaves[] = {
|
||||
{
|
||||
.slave_id = SHDMA_SLAVE_MMCIF0_TX,
|
||||
.addr = 0xee200034,
|
||||
.chcr = CHCR_TX(XMIT_SZ_32BIT),
|
||||
.mid_rid = 0xd1,
|
||||
}, {
|
||||
.slave_id = SHDMA_SLAVE_MMCIF0_RX,
|
||||
.addr = 0xee200034,
|
||||
.chcr = CHCR_RX(XMIT_SZ_32BIT),
|
||||
.mid_rid = 0xd2,
|
||||
}, {
|
||||
.slave_id = SHDMA_SLAVE_MMCIF1_TX,
|
||||
.addr = 0xee220034,
|
||||
.chcr = CHCR_TX(XMIT_SZ_32BIT),
|
||||
.mid_rid = 0xe1,
|
||||
}, {
|
||||
.slave_id = SHDMA_SLAVE_MMCIF1_RX,
|
||||
.addr = 0xee220034,
|
||||
.chcr = CHCR_RX(XMIT_SZ_32BIT),
|
||||
.mid_rid = 0xe2,
|
||||
},
|
||||
};
|
||||
|
||||
#define DMAE_CHANNEL(a, b) \
|
||||
{ \
|
||||
.offset = (a) - 0x20, \
|
||||
.dmars = (a) - 0x20 + 0x40, \
|
||||
.chclr_bit = (b), \
|
||||
.chclr_offset = 0x80 - 0x20, \
|
||||
}
|
||||
|
||||
static const struct sh_dmae_channel dma_channels[] = {
|
||||
DMAE_CHANNEL(0x8000, 0),
|
||||
DMAE_CHANNEL(0x8080, 1),
|
||||
DMAE_CHANNEL(0x8100, 2),
|
||||
DMAE_CHANNEL(0x8180, 3),
|
||||
DMAE_CHANNEL(0x8200, 4),
|
||||
DMAE_CHANNEL(0x8280, 5),
|
||||
DMAE_CHANNEL(0x8300, 6),
|
||||
DMAE_CHANNEL(0x8380, 7),
|
||||
DMAE_CHANNEL(0x8400, 8),
|
||||
DMAE_CHANNEL(0x8480, 9),
|
||||
DMAE_CHANNEL(0x8500, 10),
|
||||
DMAE_CHANNEL(0x8580, 11),
|
||||
DMAE_CHANNEL(0x8600, 12),
|
||||
DMAE_CHANNEL(0x8680, 13),
|
||||
DMAE_CHANNEL(0x8700, 14),
|
||||
DMAE_CHANNEL(0x8780, 15),
|
||||
DMAE_CHANNEL(0x8800, 16),
|
||||
DMAE_CHANNEL(0x8880, 17),
|
||||
DMAE_CHANNEL(0x8900, 18),
|
||||
DMAE_CHANNEL(0x8980, 19),
|
||||
};
|
||||
|
||||
static const struct sh_dmae_pdata dma_pdata = {
|
||||
.slave = dma_slaves,
|
||||
.slave_num = ARRAY_SIZE(dma_slaves),
|
||||
.channel = dma_channels,
|
||||
.channel_num = ARRAY_SIZE(dma_channels),
|
||||
.ts_low_shift = TS_LOW_SHIFT,
|
||||
.ts_low_mask = TS_LOW_BIT << TS_LOW_SHIFT,
|
||||
.ts_high_shift = TS_HI_SHIFT,
|
||||
.ts_high_mask = TS_HI_BIT << TS_HI_SHIFT,
|
||||
.ts_shift = dma_ts_shift,
|
||||
.ts_shift_num = ARRAY_SIZE(dma_ts_shift),
|
||||
.dmaor_init = DMAOR_DME,
|
||||
.chclr_present = 1,
|
||||
.chclr_bitwise = 1,
|
||||
};
|
||||
|
||||
static struct resource dma_resources[] = {
|
||||
DEFINE_RES_MEM(0xe6700020, 0x89e0),
|
||||
DEFINE_RES_IRQ_NAMED(gic_spi(220), "error_irq"),
|
||||
{
|
||||
/* IRQ for channels 0-19 */
|
||||
.start = gic_spi(200),
|
||||
.end = gic_spi(219),
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
#define r8a73a4_register_dmac() \
|
||||
platform_device_register_resndata(&platform_bus, "sh-dma-engine", 0, \
|
||||
dma_resources, ARRAY_SIZE(dma_resources), \
|
||||
&dma_pdata, sizeof(dma_pdata))
|
||||
|
||||
void __init r8a73a4_add_standard_devices(void)
|
||||
{
|
||||
r8a73a4_add_dt_devices();
|
||||
r8a73a4_register_irqc(0);
|
||||
r8a73a4_register_irqc(1);
|
||||
r8a73a4_register_thermal();
|
||||
r8a73a4_register_dmac();
|
||||
}
|
||||
|
||||
void __init r8a73a4_init_delay(void)
|
||||
void __init r8a73a4_init_early(void)
|
||||
{
|
||||
#ifndef CONFIG_ARM_ARCH_TIMER
|
||||
shmobile_setup_delay(1500, 2, 4); /* Cortex-A15 @ 1500MHz */
|
||||
|
@ -222,7 +313,7 @@ static const char *r8a73a4_boards_compat_dt[] __initdata = {
|
|||
};
|
||||
|
||||
DT_MACHINE_START(R8A73A4_DT, "Generic R8A73A4 (Flattened Device Tree)")
|
||||
.init_early = r8a73a4_init_delay,
|
||||
.init_early = r8a73a4_init_early,
|
||||
.dt_compat = r8a73a4_boards_compat_dt,
|
||||
MACHINE_END
|
||||
#endif /* CONFIG_USE_OF */
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include <linux/irqchip/arm-gic.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/platform_data/dma-rcar-hpbdma.h>
|
||||
#include <linux/platform_data/gpio-rcar.h>
|
||||
#include <linux/platform_data/irq-renesas-intc-irqpin.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
@ -356,6 +357,88 @@ void __init r8a7778_add_dt_devices(void)
|
|||
r8a7778_register_tmu(1);
|
||||
}
|
||||
|
||||
/* HPB-DMA */
|
||||
|
||||
/* Asynchronous mode register (ASYNCMDR) bits */
|
||||
#define HPB_DMAE_ASYNCMDR_ASMD22_MASK BIT(2) /* SDHI0 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASMD22_SINGLE BIT(2) /* SDHI0 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASMD22_MULTI 0 /* SDHI0 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASMD21_MASK BIT(1) /* SDHI0 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASMD21_SINGLE BIT(1) /* SDHI0 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASMD21_MULTI 0 /* SDHI0 */
|
||||
|
||||
static const struct hpb_dmae_slave_config hpb_dmae_slaves[] = {
|
||||
{
|
||||
.id = HPBDMA_SLAVE_SDHI0_TX,
|
||||
.addr = 0xffe4c000 + 0x30,
|
||||
.dcr = HPB_DMAE_DCR_SPDS_16BIT |
|
||||
HPB_DMAE_DCR_DMDL |
|
||||
HPB_DMAE_DCR_DPDS_16BIT,
|
||||
.rstr = HPB_DMAE_ASYNCRSTR_ASRST21 |
|
||||
HPB_DMAE_ASYNCRSTR_ASRST22 |
|
||||
HPB_DMAE_ASYNCRSTR_ASRST23,
|
||||
.mdr = HPB_DMAE_ASYNCMDR_ASMD21_MULTI,
|
||||
.mdm = HPB_DMAE_ASYNCMDR_ASMD21_MASK,
|
||||
.port = 0x0D0C,
|
||||
.flags = HPB_DMAE_SET_ASYNC_RESET | HPB_DMAE_SET_ASYNC_MODE,
|
||||
.dma_ch = 21,
|
||||
}, {
|
||||
.id = HPBDMA_SLAVE_SDHI0_RX,
|
||||
.addr = 0xffe4c000 + 0x30,
|
||||
.dcr = HPB_DMAE_DCR_SMDL |
|
||||
HPB_DMAE_DCR_SPDS_16BIT |
|
||||
HPB_DMAE_DCR_DPDS_16BIT,
|
||||
.rstr = HPB_DMAE_ASYNCRSTR_ASRST21 |
|
||||
HPB_DMAE_ASYNCRSTR_ASRST22 |
|
||||
HPB_DMAE_ASYNCRSTR_ASRST23,
|
||||
.mdr = HPB_DMAE_ASYNCMDR_ASMD22_MULTI,
|
||||
.mdm = HPB_DMAE_ASYNCMDR_ASMD22_MASK,
|
||||
.port = 0x0D0C,
|
||||
.flags = HPB_DMAE_SET_ASYNC_RESET | HPB_DMAE_SET_ASYNC_MODE,
|
||||
.dma_ch = 22,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct hpb_dmae_channel hpb_dmae_channels[] = {
|
||||
HPB_DMAE_CHANNEL(0x7e, HPBDMA_SLAVE_SDHI0_TX), /* ch. 21 */
|
||||
HPB_DMAE_CHANNEL(0x7e, HPBDMA_SLAVE_SDHI0_RX), /* ch. 22 */
|
||||
};
|
||||
|
||||
static struct hpb_dmae_pdata dma_platform_data __initdata = {
|
||||
.slaves = hpb_dmae_slaves,
|
||||
.num_slaves = ARRAY_SIZE(hpb_dmae_slaves),
|
||||
.channels = hpb_dmae_channels,
|
||||
.num_channels = ARRAY_SIZE(hpb_dmae_channels),
|
||||
.ts_shift = {
|
||||
[XMIT_SZ_8BIT] = 0,
|
||||
[XMIT_SZ_16BIT] = 1,
|
||||
[XMIT_SZ_32BIT] = 2,
|
||||
},
|
||||
.num_hw_channels = 39,
|
||||
};
|
||||
|
||||
static struct resource hpb_dmae_resources[] __initdata = {
|
||||
/* Channel registers */
|
||||
DEFINE_RES_MEM(0xffc08000, 0x1000),
|
||||
/* Common registers */
|
||||
DEFINE_RES_MEM(0xffc09000, 0x170),
|
||||
/* Asynchronous reset registers */
|
||||
DEFINE_RES_MEM(0xffc00300, 4),
|
||||
/* Asynchronous mode registers */
|
||||
DEFINE_RES_MEM(0xffc00400, 4),
|
||||
/* IRQ for DMA channels */
|
||||
DEFINE_RES_NAMED(gic_iid(0x7b), 5, NULL, IORESOURCE_IRQ),
|
||||
};
|
||||
|
||||
static void __init r8a7778_register_hpb_dmae(void)
|
||||
{
|
||||
platform_device_register_resndata(&platform_bus, "hpb-dma-engine", -1,
|
||||
hpb_dmae_resources,
|
||||
ARRAY_SIZE(hpb_dmae_resources),
|
||||
&dma_platform_data,
|
||||
sizeof(dma_platform_data));
|
||||
}
|
||||
|
||||
void __init r8a7778_add_standard_devices(void)
|
||||
{
|
||||
r8a7778_add_dt_devices();
|
||||
|
@ -366,6 +449,8 @@ void __init r8a7778_add_standard_devices(void)
|
|||
r8a7778_register_hspi(0);
|
||||
r8a7778_register_hspi(1);
|
||||
r8a7778_register_hspi(2);
|
||||
|
||||
r8a7778_register_hpb_dmae();
|
||||
}
|
||||
|
||||
void __init r8a7778_init_late(void)
|
||||
|
@ -391,7 +476,7 @@ static struct resource irqpin_resources[] __initdata = {
|
|||
DEFINE_RES_IRQ(gic_iid(0x3e)), /* IRQ3 */
|
||||
};
|
||||
|
||||
void __init r8a7778_init_irq_extpin(int irlm)
|
||||
void __init r8a7778_init_irq_extpin_dt(int irlm)
|
||||
{
|
||||
void __iomem *icr0 = ioremap_nocache(0xfe780000, PAGE_SIZE);
|
||||
unsigned long tmp;
|
||||
|
@ -409,7 +494,11 @@ void __init r8a7778_init_irq_extpin(int irlm)
|
|||
tmp |= (1 << 21); /* LVLMODE = 1 */
|
||||
iowrite32(tmp, icr0);
|
||||
iounmap(icr0);
|
||||
}
|
||||
|
||||
void __init r8a7778_init_irq_extpin(int irlm)
|
||||
{
|
||||
r8a7778_init_irq_extpin_dt(irlm);
|
||||
if (irlm)
|
||||
platform_device_register_resndata(
|
||||
&platform_bus, "renesas_intc_irqpin", -1,
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include <linux/irqchip.h>
|
||||
#include <linux/irqchip/arm-gic.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/platform_data/dma-rcar-hpbdma.h>
|
||||
#include <linux/platform_data/gpio-rcar.h>
|
||||
#include <linux/platform_data/irq-renesas-intc-irqpin.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
@ -97,7 +98,7 @@ static struct resource irqpin0_resources[] __initdata = {
|
|||
DEFINE_RES_IRQ(gic_spi(30)), /* IRQ3 */
|
||||
};
|
||||
|
||||
void __init r8a7779_init_irq_extpin(int irlm)
|
||||
void __init r8a7779_init_irq_extpin_dt(int irlm)
|
||||
{
|
||||
void __iomem *icr0 = ioremap_nocache(0xfe780000, PAGE_SIZE);
|
||||
u32 tmp;
|
||||
|
@ -115,7 +116,11 @@ void __init r8a7779_init_irq_extpin(int irlm)
|
|||
tmp |= (1 << 21); /* LVLMODE = 1 */
|
||||
iowrite32(tmp, icr0);
|
||||
iounmap(icr0);
|
||||
}
|
||||
|
||||
void __init r8a7779_init_irq_extpin(int irlm)
|
||||
{
|
||||
r8a7779_init_irq_extpin_dt(irlm);
|
||||
if (irlm)
|
||||
platform_device_register_resndata(
|
||||
&platform_bus, "renesas_intc_irqpin", -1,
|
||||
|
@ -632,6 +637,158 @@ static struct platform_device_info *vin_info_table[] __initdata = {
|
|||
&vin3_info,
|
||||
};
|
||||
|
||||
/* HPB-DMA */
|
||||
|
||||
/* Asynchronous mode register bits */
|
||||
#define HPB_DMAE_ASYNCMDR_ASMD43_MASK BIT(23) /* MMC1 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASMD43_SINGLE BIT(23) /* MMC1 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASMD43_MULTI 0 /* MMC1 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASBTMD43_MASK BIT(22) /* MMC1 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASBTMD43_BURST BIT(22) /* MMC1 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASBTMD43_NBURST 0 /* MMC1 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASMD24_MASK BIT(21) /* MMC0 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASMD24_SINGLE BIT(21) /* MMC0 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASMD24_MULTI 0 /* MMC0 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASBTMD24_MASK BIT(20) /* MMC0 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASBTMD24_BURST BIT(20) /* MMC0 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASBTMD24_NBURST 0 /* MMC0 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASMD41_MASK BIT(19) /* SDHI3 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASMD41_SINGLE BIT(19) /* SDHI3 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASMD41_MULTI 0 /* SDHI3 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASBTMD41_MASK BIT(18) /* SDHI3 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASBTMD41_BURST BIT(18) /* SDHI3 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASBTMD41_NBURST 0 /* SDHI3 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASMD40_MASK BIT(17) /* SDHI3 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASMD40_SINGLE BIT(17) /* SDHI3 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASMD40_MULTI 0 /* SDHI3 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASBTMD40_MASK BIT(16) /* SDHI3 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASBTMD40_BURST BIT(16) /* SDHI3 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASBTMD40_NBURST 0 /* SDHI3 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASMD39_MASK BIT(15) /* SDHI3 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASMD39_SINGLE BIT(15) /* SDHI3 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASMD39_MULTI 0 /* SDHI3 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASBTMD39_MASK BIT(14) /* SDHI3 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASBTMD39_BURST BIT(14) /* SDHI3 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASBTMD39_NBURST 0 /* SDHI3 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASMD27_MASK BIT(13) /* SDHI2 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASMD27_SINGLE BIT(13) /* SDHI2 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASMD27_MULTI 0 /* SDHI2 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASBTMD27_MASK BIT(12) /* SDHI2 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASBTMD27_BURST BIT(12) /* SDHI2 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASBTMD27_NBURST 0 /* SDHI2 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASMD26_MASK BIT(11) /* SDHI2 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASMD26_SINGLE BIT(11) /* SDHI2 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASMD26_MULTI 0 /* SDHI2 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASBTMD26_MASK BIT(10) /* SDHI2 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASBTMD26_BURST BIT(10) /* SDHI2 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASBTMD26_NBURST 0 /* SDHI2 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASMD25_MASK BIT(9) /* SDHI2 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASMD25_SINGLE BIT(9) /* SDHI2 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASMD25_MULTI 0 /* SDHI2 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASBTMD25_MASK BIT(8) /* SDHI2 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASBTMD25_BURST BIT(8) /* SDHI2 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASBTMD25_NBURST 0 /* SDHI2 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASMD23_MASK BIT(7) /* SDHI0 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASMD23_SINGLE BIT(7) /* SDHI0 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASMD23_MULTI 0 /* SDHI0 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASBTMD23_MASK BIT(6) /* SDHI0 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASBTMD23_BURST BIT(6) /* SDHI0 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASBTMD23_NBURST 0 /* SDHI0 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASMD22_MASK BIT(5) /* SDHI0 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASMD22_SINGLE BIT(5) /* SDHI0 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASMD22_MULTI 0 /* SDHI0 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASBTMD22_MASK BIT(4) /* SDHI0 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASBTMD22_BURST BIT(4) /* SDHI0 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASBTMD22_NBURST 0 /* SDHI0 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASMD21_MASK BIT(3) /* SDHI0 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASMD21_SINGLE BIT(3) /* SDHI0 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASMD21_MULTI 0 /* SDHI0 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASBTMD21_MASK BIT(2) /* SDHI0 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASBTMD21_BURST BIT(2) /* SDHI0 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASBTMD21_NBURST 0 /* SDHI0 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASMD20_MASK BIT(1) /* SDHI1 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASMD20_SINGLE BIT(1) /* SDHI1 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASMD20_MULTI 0 /* SDHI1 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASBTMD20_MASK BIT(0) /* SDHI1 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASBTMD20_BURST BIT(0) /* SDHI1 */
|
||||
#define HPB_DMAE_ASYNCMDR_ASBTMD20_NBURST 0 /* SDHI1 */
|
||||
|
||||
static const struct hpb_dmae_slave_config hpb_dmae_slaves[] = {
|
||||
{
|
||||
.id = HPBDMA_SLAVE_SDHI0_TX,
|
||||
.addr = 0xffe4c000 + 0x30,
|
||||
.dcr = HPB_DMAE_DCR_SPDS_16BIT |
|
||||
HPB_DMAE_DCR_DMDL |
|
||||
HPB_DMAE_DCR_DPDS_16BIT,
|
||||
.rstr = HPB_DMAE_ASYNCRSTR_ASRST21 |
|
||||
HPB_DMAE_ASYNCRSTR_ASRST22 |
|
||||
HPB_DMAE_ASYNCRSTR_ASRST23,
|
||||
.mdr = HPB_DMAE_ASYNCMDR_ASMD21_SINGLE |
|
||||
HPB_DMAE_ASYNCMDR_ASBTMD21_NBURST,
|
||||
.mdm = HPB_DMAE_ASYNCMDR_ASMD21_MASK |
|
||||
HPB_DMAE_ASYNCMDR_ASBTMD21_MASK,
|
||||
.port = 0x0D0C,
|
||||
.flags = HPB_DMAE_SET_ASYNC_RESET | HPB_DMAE_SET_ASYNC_MODE,
|
||||
.dma_ch = 21,
|
||||
}, {
|
||||
.id = HPBDMA_SLAVE_SDHI0_RX,
|
||||
.addr = 0xffe4c000 + 0x30,
|
||||
.dcr = HPB_DMAE_DCR_SMDL |
|
||||
HPB_DMAE_DCR_SPDS_16BIT |
|
||||
HPB_DMAE_DCR_DPDS_16BIT,
|
||||
.rstr = HPB_DMAE_ASYNCRSTR_ASRST21 |
|
||||
HPB_DMAE_ASYNCRSTR_ASRST22 |
|
||||
HPB_DMAE_ASYNCRSTR_ASRST23,
|
||||
.mdr = HPB_DMAE_ASYNCMDR_ASMD22_SINGLE |
|
||||
HPB_DMAE_ASYNCMDR_ASBTMD22_NBURST,
|
||||
.mdm = HPB_DMAE_ASYNCMDR_ASMD22_MASK |
|
||||
HPB_DMAE_ASYNCMDR_ASBTMD22_MASK,
|
||||
.port = 0x0D0C,
|
||||
.flags = HPB_DMAE_SET_ASYNC_RESET | HPB_DMAE_SET_ASYNC_MODE,
|
||||
.dma_ch = 22,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct hpb_dmae_channel hpb_dmae_channels[] = {
|
||||
HPB_DMAE_CHANNEL(0x93, HPBDMA_SLAVE_SDHI0_TX), /* ch. 21 */
|
||||
HPB_DMAE_CHANNEL(0x93, HPBDMA_SLAVE_SDHI0_RX), /* ch. 22 */
|
||||
};
|
||||
|
||||
static struct hpb_dmae_pdata dma_platform_data __initdata = {
|
||||
.slaves = hpb_dmae_slaves,
|
||||
.num_slaves = ARRAY_SIZE(hpb_dmae_slaves),
|
||||
.channels = hpb_dmae_channels,
|
||||
.num_channels = ARRAY_SIZE(hpb_dmae_channels),
|
||||
.ts_shift = {
|
||||
[XMIT_SZ_8BIT] = 0,
|
||||
[XMIT_SZ_16BIT] = 1,
|
||||
[XMIT_SZ_32BIT] = 2,
|
||||
},
|
||||
.num_hw_channels = 44,
|
||||
};
|
||||
|
||||
static struct resource hpb_dmae_resources[] __initdata = {
|
||||
/* Channel registers */
|
||||
DEFINE_RES_MEM(0xffc08000, 0x1000),
|
||||
/* Common registers */
|
||||
DEFINE_RES_MEM(0xffc09000, 0x170),
|
||||
/* Asynchronous reset registers */
|
||||
DEFINE_RES_MEM(0xffc00300, 4),
|
||||
/* Asynchronous mode registers */
|
||||
DEFINE_RES_MEM(0xffc00400, 4),
|
||||
/* IRQ for DMA channels */
|
||||
DEFINE_RES_NAMED(gic_iid(0x8e), 12, NULL, IORESOURCE_IRQ),
|
||||
};
|
||||
|
||||
static void __init r8a7779_register_hpb_dmae(void)
|
||||
{
|
||||
platform_device_register_resndata(&platform_bus, "hpb-dma-engine", -1,
|
||||
hpb_dmae_resources,
|
||||
ARRAY_SIZE(hpb_dmae_resources),
|
||||
&dma_platform_data,
|
||||
sizeof(dma_platform_data));
|
||||
}
|
||||
|
||||
static struct platform_device *r8a7779_devices_dt[] __initdata = {
|
||||
&scif0_device,
|
||||
&scif1_device,
|
||||
|
@ -665,6 +822,7 @@ void __init r8a7779_add_standard_devices(void)
|
|||
ARRAY_SIZE(r8a7779_devices_dt));
|
||||
platform_add_devices(r8a7779_standard_devices,
|
||||
ARRAY_SIZE(r8a7779_standard_devices));
|
||||
r8a7779_register_hpb_dmae();
|
||||
}
|
||||
|
||||
void __init r8a7779_add_ether_device(struct sh_eth_plat_data *pdata)
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <linux/clocksource.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/of_platform.h>
|
||||
|
@ -31,17 +30,18 @@
|
|||
#include <mach/r8a7790.h>
|
||||
#include <asm/mach/arch.h>
|
||||
|
||||
static struct resource pfc_resources[] __initdata = {
|
||||
static const struct resource pfc_resources[] __initconst = {
|
||||
DEFINE_RES_MEM(0xe6060000, 0x250),
|
||||
};
|
||||
|
||||
#define R8A7790_GPIO(idx) \
|
||||
static struct resource r8a7790_gpio##idx##_resources[] __initdata = { \
|
||||
static const struct resource r8a7790_gpio##idx##_resources[] __initconst = { \
|
||||
DEFINE_RES_MEM(0xe6050000 + 0x1000 * (idx), 0x50), \
|
||||
DEFINE_RES_IRQ(gic_spi(4 + (idx))), \
|
||||
}; \
|
||||
\
|
||||
static struct gpio_rcar_config r8a7790_gpio##idx##_platform_data __initdata = { \
|
||||
static const struct gpio_rcar_config \
|
||||
r8a7790_gpio##idx##_platform_data __initconst = { \
|
||||
.gpio_base = 32 * (idx), \
|
||||
.irq_base = 0, \
|
||||
.number_of_pins = 32, \
|
||||
|
@ -112,7 +112,7 @@ void __init r8a7790_pinmux_init(void)
|
|||
enum { SCIFA0, SCIFA1, SCIFB0, SCIFB1, SCIFB2, SCIFA2, SCIF0, SCIF1,
|
||||
HSCIF0, HSCIF1 };
|
||||
|
||||
static struct plat_sci_port scif[] __initdata = {
|
||||
static const struct plat_sci_port scif[] __initconst = {
|
||||
SCIFA_DATA(SCIFA0, 0xe6c40000, gic_spi(144)), /* SCIFA0 */
|
||||
SCIFA_DATA(SCIFA1, 0xe6c50000, gic_spi(145)), /* SCIFA1 */
|
||||
SCIFB_DATA(SCIFB0, 0xe6c20000, gic_spi(148)), /* SCIFB0 */
|
||||
|
@ -131,11 +131,11 @@ static inline void r8a7790_register_scif(int idx)
|
|||
sizeof(struct plat_sci_port));
|
||||
}
|
||||
|
||||
static struct renesas_irqc_config irqc0_data __initdata = {
|
||||
static const struct renesas_irqc_config irqc0_data __initconst = {
|
||||
.irq_base = irq_pin(0), /* IRQ0 -> IRQ3 */
|
||||
};
|
||||
|
||||
static struct resource irqc0_resources[] __initdata = {
|
||||
static const struct resource irqc0_resources[] __initconst = {
|
||||
DEFINE_RES_MEM(0xe61c0000, 0x200), /* IRQC Event Detector Block_0 */
|
||||
DEFINE_RES_IRQ(gic_spi(0)), /* IRQ0 */
|
||||
DEFINE_RES_IRQ(gic_spi(1)), /* IRQ1 */
|
||||
|
@ -150,7 +150,7 @@ static struct resource irqc0_resources[] __initdata = {
|
|||
&irqc##idx##_data, \
|
||||
sizeof(struct renesas_irqc_config))
|
||||
|
||||
static struct resource thermal_resources[] __initdata = {
|
||||
static const struct resource thermal_resources[] __initconst = {
|
||||
DEFINE_RES_MEM(0xe61f0000, 0x14),
|
||||
DEFINE_RES_MEM(0xe61f0100, 0x38),
|
||||
DEFINE_RES_IRQ(gic_spi(69)),
|
||||
|
@ -161,13 +161,13 @@ static struct resource thermal_resources[] __initdata = {
|
|||
thermal_resources, \
|
||||
ARRAY_SIZE(thermal_resources))
|
||||
|
||||
static struct sh_timer_config cmt00_platform_data __initdata = {
|
||||
static const struct sh_timer_config cmt00_platform_data __initconst = {
|
||||
.name = "CMT00",
|
||||
.timer_bit = 0,
|
||||
.clockevent_rating = 80,
|
||||
};
|
||||
|
||||
static struct resource cmt00_resources[] __initdata = {
|
||||
static const struct resource cmt00_resources[] __initconst = {
|
||||
DEFINE_RES_MEM(0xffca0510, 0x0c),
|
||||
DEFINE_RES_MEM(0xffca0500, 0x04),
|
||||
DEFINE_RES_IRQ(gic_spi(142)), /* CMT0_0 */
|
||||
|
@ -202,72 +202,7 @@ void __init r8a7790_add_standard_devices(void)
|
|||
r8a7790_register_thermal();
|
||||
}
|
||||
|
||||
#define MODEMR 0xe6160060
|
||||
|
||||
u32 __init r8a7790_read_mode_pins(void)
|
||||
{
|
||||
void __iomem *modemr = ioremap_nocache(MODEMR, 4);
|
||||
u32 mode;
|
||||
|
||||
BUG_ON(!modemr);
|
||||
mode = ioread32(modemr);
|
||||
iounmap(modemr);
|
||||
|
||||
return mode;
|
||||
}
|
||||
|
||||
#define CNTCR 0
|
||||
#define CNTFID0 0x20
|
||||
|
||||
void __init r8a7790_timer_init(void)
|
||||
{
|
||||
#ifdef CONFIG_ARM_ARCH_TIMER
|
||||
u32 mode = r8a7790_read_mode_pins();
|
||||
void __iomem *base;
|
||||
int extal_mhz = 0;
|
||||
u32 freq;
|
||||
|
||||
/* At Linux boot time the r8a7790 arch timer comes up
|
||||
* with the counter disabled. Moreover, it may also report
|
||||
* a potentially incorrect fixed 13 MHz frequency. To be
|
||||
* correct these registers need to be updated to use the
|
||||
* frequency EXTAL / 2 which can be determined by the MD pins.
|
||||
*/
|
||||
|
||||
switch (mode & (MD(14) | MD(13))) {
|
||||
case 0:
|
||||
extal_mhz = 15;
|
||||
break;
|
||||
case MD(13):
|
||||
extal_mhz = 20;
|
||||
break;
|
||||
case MD(14):
|
||||
extal_mhz = 26;
|
||||
break;
|
||||
case MD(13) | MD(14):
|
||||
extal_mhz = 30;
|
||||
break;
|
||||
}
|
||||
|
||||
/* The arch timer frequency equals EXTAL / 2 */
|
||||
freq = extal_mhz * (1000000 / 2);
|
||||
|
||||
/* Remap "armgcnt address map" space */
|
||||
base = ioremap(0xe6080000, PAGE_SIZE);
|
||||
|
||||
/* Update registers with correct frequency */
|
||||
iowrite32(freq, base + CNTFID0);
|
||||
asm volatile("mcr p15, 0, %0, c14, c0, 0" : : "r" (freq));
|
||||
|
||||
/* make sure arch timer is started by setting bit 0 of CNTCR */
|
||||
iowrite32(1, base + CNTCR);
|
||||
iounmap(base);
|
||||
#endif /* CONFIG_ARM_ARCH_TIMER */
|
||||
|
||||
clocksource_of_init();
|
||||
}
|
||||
|
||||
void __init r8a7790_init_delay(void)
|
||||
void __init r8a7790_init_early(void)
|
||||
{
|
||||
#ifndef CONFIG_ARM_ARCH_TIMER
|
||||
shmobile_setup_delay(1300, 2, 4); /* Cortex-A15 @ 1300MHz */
|
||||
|
@ -276,14 +211,15 @@ void __init r8a7790_init_delay(void)
|
|||
|
||||
#ifdef CONFIG_USE_OF
|
||||
|
||||
static const char *r8a7790_boards_compat_dt[] __initdata = {
|
||||
static const char * const r8a7790_boards_compat_dt[] __initconst = {
|
||||
"renesas,r8a7790",
|
||||
NULL,
|
||||
};
|
||||
|
||||
DT_MACHINE_START(R8A7790_DT, "Generic R8A7790 (Flattened Device Tree)")
|
||||
.init_early = r8a7790_init_delay,
|
||||
.init_time = r8a7790_timer_init,
|
||||
.smp = smp_ops(r8a7790_smp_ops),
|
||||
.init_early = r8a7790_init_early,
|
||||
.init_time = rcar_gen2_timer_init,
|
||||
.dt_compat = r8a7790_boards_compat_dt,
|
||||
MACHINE_END
|
||||
#endif /* CONFIG_USE_OF */
|
||||
|
|
|
@ -22,11 +22,13 @@
|
|||
#include <linux/irq.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/platform_data/irq-renesas-irqc.h>
|
||||
#include <linux/serial_sci.h>
|
||||
#include <linux/sh_timer.h>
|
||||
#include <mach/common.h>
|
||||
#include <mach/irqs.h>
|
||||
#include <mach/r8a7791.h>
|
||||
#include <mach/rcar-gen2.h>
|
||||
#include <asm/mach/arch.h>
|
||||
|
||||
#define SCIF_COMMON(scif_type, baseaddr, irq) \
|
||||
|
@ -109,6 +111,31 @@ static const struct resource cmt00_resources[] __initconst = {
|
|||
&cmt##idx##_platform_data, \
|
||||
sizeof(struct sh_timer_config))
|
||||
|
||||
static struct renesas_irqc_config irqc0_data = {
|
||||
.irq_base = irq_pin(0), /* IRQ0 -> IRQ9 */
|
||||
};
|
||||
|
||||
static struct resource irqc0_resources[] = {
|
||||
DEFINE_RES_MEM(0xe61c0000, 0x200), /* IRQC Event Detector Block_0 */
|
||||
DEFINE_RES_IRQ(gic_spi(0)), /* IRQ0 */
|
||||
DEFINE_RES_IRQ(gic_spi(1)), /* IRQ1 */
|
||||
DEFINE_RES_IRQ(gic_spi(2)), /* IRQ2 */
|
||||
DEFINE_RES_IRQ(gic_spi(3)), /* IRQ3 */
|
||||
DEFINE_RES_IRQ(gic_spi(12)), /* IRQ4 */
|
||||
DEFINE_RES_IRQ(gic_spi(13)), /* IRQ5 */
|
||||
DEFINE_RES_IRQ(gic_spi(14)), /* IRQ6 */
|
||||
DEFINE_RES_IRQ(gic_spi(15)), /* IRQ7 */
|
||||
DEFINE_RES_IRQ(gic_spi(16)), /* IRQ8 */
|
||||
DEFINE_RES_IRQ(gic_spi(17)), /* IRQ9 */
|
||||
};
|
||||
|
||||
#define r8a7791_register_irqc(idx) \
|
||||
platform_device_register_resndata(&platform_bus, "renesas_irqc", \
|
||||
idx, irqc##idx##_resources, \
|
||||
ARRAY_SIZE(irqc##idx##_resources), \
|
||||
&irqc##idx##_data, \
|
||||
sizeof(struct renesas_irqc_config))
|
||||
|
||||
void __init r8a7791_add_dt_devices(void)
|
||||
{
|
||||
r8a7791_register_scif(SCIFA0);
|
||||
|
@ -129,6 +156,12 @@ void __init r8a7791_add_dt_devices(void)
|
|||
r8a7791_register_cmt(00);
|
||||
}
|
||||
|
||||
void __init r8a7791_add_standard_devices(void)
|
||||
{
|
||||
r8a7791_add_dt_devices();
|
||||
r8a7791_register_irqc(0);
|
||||
}
|
||||
|
||||
void __init r8a7791_init_early(void)
|
||||
{
|
||||
#ifndef CONFIG_ARM_ARCH_TIMER
|
||||
|
@ -143,7 +176,9 @@ static const char *r8a7791_boards_compat_dt[] __initdata = {
|
|||
};
|
||||
|
||||
DT_MACHINE_START(R8A7791_DT, "Generic R8A7791 (Flattened Device Tree)")
|
||||
.smp = smp_ops(r8a7791_smp_ops),
|
||||
.init_early = r8a7791_init_early,
|
||||
.init_time = rcar_gen2_timer_init,
|
||||
.dt_compat = r8a7791_boards_compat_dt,
|
||||
MACHINE_END
|
||||
#endif /* CONFIG_USE_OF */
|
||||
|
|
91
arch/arm/mach-shmobile/setup-rcar-gen2.c
Normal file
91
arch/arm/mach-shmobile/setup-rcar-gen2.c
Normal file
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* R-Car Generation 2 support
|
||||
*
|
||||
* Copyright (C) 2013 Renesas Solutions Corp.
|
||||
* Copyright (C) 2013 Magnus Damm
|
||||
*
|
||||
* 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; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <linux/clocksource.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <mach/common.h>
|
||||
#include <mach/rcar-gen2.h>
|
||||
#include <asm/mach/arch.h>
|
||||
|
||||
#define MODEMR 0xe6160060
|
||||
|
||||
u32 __init rcar_gen2_read_mode_pins(void)
|
||||
{
|
||||
void __iomem *modemr = ioremap_nocache(MODEMR, 4);
|
||||
u32 mode;
|
||||
|
||||
BUG_ON(!modemr);
|
||||
mode = ioread32(modemr);
|
||||
iounmap(modemr);
|
||||
|
||||
return mode;
|
||||
}
|
||||
|
||||
#define CNTCR 0
|
||||
#define CNTFID0 0x20
|
||||
|
||||
void __init rcar_gen2_timer_init(void)
|
||||
{
|
||||
#ifdef CONFIG_ARM_ARCH_TIMER
|
||||
u32 mode = rcar_gen2_read_mode_pins();
|
||||
void __iomem *base;
|
||||
int extal_mhz = 0;
|
||||
u32 freq;
|
||||
|
||||
/* At Linux boot time the r8a7790 arch timer comes up
|
||||
* with the counter disabled. Moreover, it may also report
|
||||
* a potentially incorrect fixed 13 MHz frequency. To be
|
||||
* correct these registers need to be updated to use the
|
||||
* frequency EXTAL / 2 which can be determined by the MD pins.
|
||||
*/
|
||||
|
||||
switch (mode & (MD(14) | MD(13))) {
|
||||
case 0:
|
||||
extal_mhz = 15;
|
||||
break;
|
||||
case MD(13):
|
||||
extal_mhz = 20;
|
||||
break;
|
||||
case MD(14):
|
||||
extal_mhz = 26;
|
||||
break;
|
||||
case MD(13) | MD(14):
|
||||
extal_mhz = 30;
|
||||
break;
|
||||
}
|
||||
|
||||
/* The arch timer frequency equals EXTAL / 2 */
|
||||
freq = extal_mhz * (1000000 / 2);
|
||||
|
||||
/* Remap "armgcnt address map" space */
|
||||
base = ioremap(0xe6080000, PAGE_SIZE);
|
||||
|
||||
/* Update registers with correct frequency */
|
||||
iowrite32(freq, base + CNTFID0);
|
||||
asm volatile("mcr p15, 0, %0, c14, c0, 0" : : "r" (freq));
|
||||
|
||||
/* make sure arch timer is started by setting bit 0 of CNTCR */
|
||||
iowrite32(1, base + CNTCR);
|
||||
iounmap(base);
|
||||
#endif /* CONFIG_ARM_ARCH_TIMER */
|
||||
|
||||
clocksource_of_init();
|
||||
}
|
|
@ -34,12 +34,6 @@
|
|||
|
||||
static int emev2_boot_secondary(unsigned int cpu, struct task_struct *idle)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = shmobile_smp_scu_boot_secondary(cpu, idle);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
arch_send_wakeup_ipi_mask(cpumask_of(cpu_logical_map(cpu)));
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -87,10 +87,6 @@ static int r8a7779_boot_secondary(unsigned int cpu, struct task_struct *idle)
|
|||
unsigned int lcpu = cpu_logical_map(cpu);
|
||||
int ret;
|
||||
|
||||
ret = shmobile_smp_scu_boot_secondary(cpu, idle);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (lcpu < ARRAY_SIZE(r8a7779_ch_cpu))
|
||||
ch = r8a7779_ch_cpu[lcpu];
|
||||
|
||||
|
|
67
arch/arm/mach-shmobile/smp-r8a7790.c
Normal file
67
arch/arm/mach-shmobile/smp-r8a7790.c
Normal file
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* SMP support for r8a7790
|
||||
*
|
||||
* Copyright (C) 2012-2013 Renesas Solutions Corp.
|
||||
* Copyright (C) 2012 Takashi Yoshii <takashi.yoshii.ze@renesas.com>
|
||||
*
|
||||
* 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; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/smp.h>
|
||||
#include <linux/io.h>
|
||||
#include <asm/smp_plat.h>
|
||||
#include <mach/common.h>
|
||||
|
||||
#define RST 0xe6160000
|
||||
#define CA15BAR 0x0020
|
||||
#define CA7BAR 0x0030
|
||||
#define CA15RESCNT 0x0040
|
||||
#define CA7RESCNT 0x0044
|
||||
#define MERAM 0xe8080000
|
||||
|
||||
static void __init r8a7790_smp_prepare_cpus(unsigned int max_cpus)
|
||||
{
|
||||
void __iomem *p;
|
||||
u32 bar;
|
||||
|
||||
/* let APMU code install data related to shmobile_boot_vector */
|
||||
shmobile_smp_apmu_prepare_cpus(max_cpus);
|
||||
|
||||
/* MERAM for jump stub, because BAR requires 256KB aligned address */
|
||||
p = ioremap_nocache(MERAM, shmobile_boot_size);
|
||||
memcpy_toio(p, shmobile_boot_vector, shmobile_boot_size);
|
||||
iounmap(p);
|
||||
|
||||
/* setup reset vectors */
|
||||
p = ioremap_nocache(RST, 0x63);
|
||||
bar = (MERAM >> 8) & 0xfffffc00;
|
||||
writel_relaxed(bar, p + CA15BAR);
|
||||
writel_relaxed(bar, p + CA7BAR);
|
||||
writel_relaxed(bar | 0x10, p + CA15BAR);
|
||||
writel_relaxed(bar | 0x10, p + CA7BAR);
|
||||
|
||||
/* enable clocks to all CPUs */
|
||||
writel_relaxed((readl_relaxed(p + CA15RESCNT) & ~0x0f) | 0xa5a50000,
|
||||
p + CA15RESCNT);
|
||||
writel_relaxed((readl_relaxed(p + CA7RESCNT) & ~0x0f) | 0x5a5a0000,
|
||||
p + CA7RESCNT);
|
||||
iounmap(p);
|
||||
}
|
||||
|
||||
struct smp_operations r8a7790_smp_ops __initdata = {
|
||||
.smp_prepare_cpus = r8a7790_smp_prepare_cpus,
|
||||
.smp_boot_secondary = shmobile_smp_apmu_boot_secondary,
|
||||
#ifdef CONFIG_HOTPLUG_CPU
|
||||
.cpu_disable = shmobile_smp_cpu_disable,
|
||||
.cpu_die = shmobile_smp_apmu_cpu_die,
|
||||
.cpu_kill = shmobile_smp_apmu_cpu_kill,
|
||||
#endif
|
||||
};
|
62
arch/arm/mach-shmobile/smp-r8a7791.c
Normal file
62
arch/arm/mach-shmobile/smp-r8a7791.c
Normal file
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* SMP support for r8a7791
|
||||
*
|
||||
* Copyright (C) 2013 Renesas Solutions Corp.
|
||||
* Copyright (C) 2013 Magnus Damm
|
||||
*
|
||||
* 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; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/smp.h>
|
||||
#include <linux/io.h>
|
||||
#include <asm/smp_plat.h>
|
||||
#include <mach/common.h>
|
||||
#include <mach/r8a7791.h>
|
||||
|
||||
#define RST 0xe6160000
|
||||
#define CA15BAR 0x0020
|
||||
#define CA15RESCNT 0x0040
|
||||
#define RAM 0xe6300000
|
||||
|
||||
static void __init r8a7791_smp_prepare_cpus(unsigned int max_cpus)
|
||||
{
|
||||
void __iomem *p;
|
||||
u32 bar;
|
||||
|
||||
/* let APMU code install data related to shmobile_boot_vector */
|
||||
shmobile_smp_apmu_prepare_cpus(max_cpus);
|
||||
|
||||
/* RAM for jump stub, because BAR requires 256KB aligned address */
|
||||
p = ioremap_nocache(RAM, shmobile_boot_size);
|
||||
memcpy_toio(p, shmobile_boot_vector, shmobile_boot_size);
|
||||
iounmap(p);
|
||||
|
||||
/* setup reset vectors */
|
||||
p = ioremap_nocache(RST, 0x63);
|
||||
bar = (RAM >> 8) & 0xfffffc00;
|
||||
writel_relaxed(bar, p + CA15BAR);
|
||||
writel_relaxed(bar | 0x10, p + CA15BAR);
|
||||
|
||||
/* enable clocks to all CPUs */
|
||||
writel_relaxed((readl_relaxed(p + CA15RESCNT) & ~0x0f) | 0xa5a50000,
|
||||
p + CA15RESCNT);
|
||||
iounmap(p);
|
||||
}
|
||||
|
||||
struct smp_operations r8a7791_smp_ops __initdata = {
|
||||
.smp_prepare_cpus = r8a7791_smp_prepare_cpus,
|
||||
.smp_boot_secondary = shmobile_smp_apmu_boot_secondary,
|
||||
#ifdef CONFIG_HOTPLUG_CPU
|
||||
.cpu_disable = shmobile_smp_cpu_disable,
|
||||
.cpu_die = shmobile_smp_apmu_cpu_die,
|
||||
.cpu_kill = shmobile_smp_apmu_cpu_kill,
|
||||
#endif
|
||||
};
|
|
@ -46,11 +46,6 @@ void __init sh73a0_register_twd(void)
|
|||
static int sh73a0_boot_secondary(unsigned int cpu, struct task_struct *idle)
|
||||
{
|
||||
unsigned int lcpu = cpu_logical_map(cpu);
|
||||
int ret;
|
||||
|
||||
ret = shmobile_smp_scu_boot_secondary(cpu, idle);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (((__raw_readl(PSTR) >> (4 * lcpu)) & 3) == 3)
|
||||
__raw_writel(1 << lcpu, WUPCR); /* wake up */
|
||||
|
@ -71,18 +66,11 @@ static void __init sh73a0_smp_prepare_cpus(unsigned int max_cpus)
|
|||
shmobile_smp_scu_prepare_cpus(max_cpus);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HOTPLUG_CPU
|
||||
static int sh73a0_cpu_disable(unsigned int cpu)
|
||||
{
|
||||
return 0; /* CPU0 and CPU1 supported */
|
||||
}
|
||||
#endif /* CONFIG_HOTPLUG_CPU */
|
||||
|
||||
struct smp_operations sh73a0_smp_ops __initdata = {
|
||||
.smp_prepare_cpus = sh73a0_smp_prepare_cpus,
|
||||
.smp_boot_secondary = sh73a0_boot_secondary,
|
||||
#ifdef CONFIG_HOTPLUG_CPU
|
||||
.cpu_disable = sh73a0_cpu_disable,
|
||||
.cpu_disable = shmobile_smp_cpu_disable,
|
||||
.cpu_die = shmobile_smp_scu_cpu_die,
|
||||
.cpu_kill = shmobile_smp_scu_cpu_kill,
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue