Merge branch 'renesas/dt' into next/dt
First part of DT changes for the Renesas shmobile platform, pulled from: git://git.kernel.org/pub/scm/linux/kernel/git/rafael/renesas.git dt * renesas/dt: ARM: mach-shmobile: sh7372 generic board support via DT V2 ARM: mach-shmobile: Rework sh7372 INTCS demuxer V2 ARM: mach-shmobile: Use INTC_IRQ_PINS_16H on sh7372 ARM: mach-shmobile: Use 0x3400 as INTCS vector offset ARM: mach-shmobile: Introduce INTC_IRQ_PINS_16H ARM: mach-shmobile: Introduce shmobile_setup_delay() Signed-off-by: Arnd Bergmann <arnd@arndb.de> [olof: rebuilt branch due to drop of an early merge] Signed-off-by: Olof Johansson <olof@lixom.net>
This commit is contained in:
commit
02abb80f90
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* Device Tree Source for the sh7372 SoC
|
||||
*
|
||||
* Copyright (C) 2012 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.
|
||||
*/
|
||||
|
||||
/include/ "skeleton.dtsi"
|
||||
|
||||
/ {
|
||||
compatible = "renesas,sh7372";
|
||||
|
||||
cpus {
|
||||
cpu@0 {
|
||||
compatible = "arm,cortex-a8";
|
||||
};
|
||||
};
|
||||
};
|
|
@ -3,6 +3,8 @@
|
|||
|
||||
extern void shmobile_earlytimer_init(void);
|
||||
extern struct sys_timer shmobile_timer;
|
||||
extern void shmobile_setup_delay(unsigned int max_cpu_core_mhz,
|
||||
unsigned int mult, unsigned int div);
|
||||
struct twd_local_timer;
|
||||
void shmobile_twd_init(struct twd_local_timer *twd_local_timer);
|
||||
extern void shmobile_setup_console(void);
|
||||
|
|
|
@ -142,6 +142,50 @@ static struct intc_desc p ## _desc __initdata = { \
|
|||
p ## _sense_registers, p ## _ack_registers) \
|
||||
}
|
||||
|
||||
#define INTC_IRQ_PINS_16H(p, base, vect, str) \
|
||||
\
|
||||
static struct resource p ## _resources[] __initdata = { \
|
||||
[0] = { \
|
||||
.start = base, \
|
||||
.end = base + 0x64, \
|
||||
.flags = IORESOURCE_MEM, \
|
||||
}, \
|
||||
}; \
|
||||
\
|
||||
enum { \
|
||||
p ## _UNUSED = 0, \
|
||||
INTC_IRQ_PINS_ENUM_16H(p), \
|
||||
}; \
|
||||
\
|
||||
static struct intc_vect p ## _vectors[] __initdata = { \
|
||||
INTC_IRQ_PINS_VECT_16H(p, vect), \
|
||||
}; \
|
||||
\
|
||||
static struct intc_mask_reg p ## _mask_registers[] __initdata = { \
|
||||
INTC_IRQ_PINS_MASK_16H(p, base), \
|
||||
}; \
|
||||
\
|
||||
static struct intc_prio_reg p ## _prio_registers[] __initdata = { \
|
||||
INTC_IRQ_PINS_PRIO_16H(p, base), \
|
||||
}; \
|
||||
\
|
||||
static struct intc_sense_reg p ## _sense_registers[] __initdata = { \
|
||||
INTC_IRQ_PINS_SENSE_16H(p, base), \
|
||||
}; \
|
||||
\
|
||||
static struct intc_mask_reg p ## _ack_registers[] __initdata = { \
|
||||
INTC_IRQ_PINS_ACK_16H(p, base), \
|
||||
}; \
|
||||
\
|
||||
static struct intc_desc p ## _desc __initdata = { \
|
||||
.name = str, \
|
||||
.resource = p ## _resources, \
|
||||
.num_resources = ARRAY_SIZE(p ## _resources), \
|
||||
.hw = INTC_HW_DESC(p ## _vectors, NULL, \
|
||||
p ## _mask_registers, p ## _prio_registers, \
|
||||
p ## _sense_registers, p ## _ack_registers) \
|
||||
}
|
||||
|
||||
#define INTC_IRQ_PINS_32(p, base, vect, str) \
|
||||
\
|
||||
static struct resource p ## _resources[] __initdata = { \
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
#define gic_spi(nr) ((nr) + 32)
|
||||
|
||||
/* INTCS */
|
||||
#define INTCS_VECT_BASE 0x2200
|
||||
#define INTCS_VECT_BASE 0x3400
|
||||
#define INTCS_VECT(n, vect) INTC_VECT((n), INTCS_VECT_BASE + (vect))
|
||||
#define intcs_evt2irq(evt) evt2irq(INTCS_VECT_BASE + (evt))
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/sh_intc.h>
|
||||
|
@ -305,14 +306,16 @@ static DECLARE_INTC_DESC(intca_desc, "sh7372-intca",
|
|||
intca_mask_registers, intca_prio_registers,
|
||||
NULL);
|
||||
|
||||
INTC_IRQ_PINS_32(intca_irq_pins, 0xe6900000,
|
||||
INTC_VECT, "sh7372-intca-irq-pins");
|
||||
INTC_IRQ_PINS_16(intca_irq_pins_lo, 0xe6900000,
|
||||
INTC_VECT, "sh7372-intca-irq-lo");
|
||||
|
||||
INTC_IRQ_PINS_16H(intca_irq_pins_hi, 0xe6900000,
|
||||
INTC_VECT, "sh7372-intca-irq-hi");
|
||||
|
||||
enum {
|
||||
UNUSED_INTCS = 0,
|
||||
ENABLED_INTCS,
|
||||
|
||||
INTCS,
|
||||
|
||||
/* interrupt sources INTCS */
|
||||
|
||||
/* IRQ0S - IRQ31S */
|
||||
|
@ -426,8 +429,6 @@ static struct intc_vect intcs_vectors[] = {
|
|||
INTCS_VECT(CPORTS2R, 0x1a20),
|
||||
/* CEC */
|
||||
INTCS_VECT(JPU6E, 0x1a80),
|
||||
|
||||
INTC_VECT(INTCS, 0xf80),
|
||||
};
|
||||
|
||||
static struct intc_group intcs_groups[] __initdata = {
|
||||
|
@ -490,9 +491,6 @@ static struct intc_mask_reg intcs_mask_registers[] = {
|
|||
{ 0xffd5019c, 0xffd501dc, 8, /* IMR7SA3 / IMCR7SA3 */
|
||||
{ MFIS2_INTCS, CPORTS2R, 0, 0,
|
||||
JPU6E, 0, 0, 0 } },
|
||||
{ 0xffd20104, 0, 16, /* INTAMASK */
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, INTCS } },
|
||||
};
|
||||
|
||||
/* Priority is needed for INTCA to receive the INTCS interrupt */
|
||||
|
@ -557,18 +555,30 @@ static void __iomem *intcs_ffd5;
|
|||
void __init sh7372_init_irq(void)
|
||||
{
|
||||
void __iomem *intevtsa;
|
||||
int n;
|
||||
|
||||
intcs_ffd2 = ioremap_nocache(0xffd20000, PAGE_SIZE);
|
||||
intevtsa = intcs_ffd2 + 0x100;
|
||||
intcs_ffd5 = ioremap_nocache(0xffd50000, PAGE_SIZE);
|
||||
|
||||
register_intc_controller(&intca_desc);
|
||||
register_intc_controller(&intca_irq_pins_desc);
|
||||
register_intc_controller(&intca_irq_pins_lo_desc);
|
||||
register_intc_controller(&intca_irq_pins_hi_desc);
|
||||
register_intc_controller(&intcs_desc);
|
||||
|
||||
/* setup dummy cascade chip for INTCS */
|
||||
n = evt2irq(0xf80);
|
||||
irq_alloc_desc_at(n, numa_node_id());
|
||||
irq_set_chip_and_handler_name(n, &dummy_irq_chip,
|
||||
handle_level_irq, "level");
|
||||
set_irq_flags(n, IRQF_VALID); /* yuck */
|
||||
|
||||
/* demux using INTEVTSA */
|
||||
irq_set_handler_data(evt2irq(0xf80), (void *)intevtsa);
|
||||
irq_set_chained_handler(evt2irq(0xf80), intcs_demux);
|
||||
irq_set_handler_data(n, (void *)intevtsa);
|
||||
irq_set_chained_handler(n, intcs_demux);
|
||||
|
||||
/* unmask INTCS in INTAMASK */
|
||||
iowrite16(0, intcs_ffd2 + 0x104);
|
||||
}
|
||||
|
||||
static unsigned short ffd2[0x200];
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <linux/interrupt.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/uio_driver.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/input.h>
|
||||
|
@ -1092,3 +1093,50 @@ void __init sh7372_add_early_devices(void)
|
|||
/* override timer setup with soc-specific code */
|
||||
shmobile_timer.init = sh7372_earlytimer_init;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_USE_OF
|
||||
|
||||
void __init sh7372_add_early_devices_dt(void)
|
||||
{
|
||||
shmobile_setup_delay(800, 1, 3); /* Cortex-A8 @ 800MHz */
|
||||
|
||||
early_platform_add_devices(sh7372_early_devices,
|
||||
ARRAY_SIZE(sh7372_early_devices));
|
||||
|
||||
/* setup early console here as well */
|
||||
shmobile_setup_console();
|
||||
}
|
||||
|
||||
static const struct of_dev_auxdata sh7372_auxdata_lookup[] __initconst = {
|
||||
{ }
|
||||
};
|
||||
|
||||
void __init sh7372_add_standard_devices_dt(void)
|
||||
{
|
||||
/* clocks are setup late during boot in the case of DT */
|
||||
sh7372_clock_init();
|
||||
|
||||
platform_add_devices(sh7372_early_devices,
|
||||
ARRAY_SIZE(sh7372_early_devices));
|
||||
|
||||
of_platform_populate(NULL, of_default_bus_match_table,
|
||||
sh7372_auxdata_lookup, NULL);
|
||||
}
|
||||
|
||||
static const char *sh7372_boards_compat_dt[] __initdata = {
|
||||
"renesas,sh7372",
|
||||
NULL,
|
||||
};
|
||||
|
||||
DT_MACHINE_START(SH7372_DT, "Generic SH7372 (Flattened Device Tree)")
|
||||
.map_io = sh7372_map_io,
|
||||
.init_early = sh7372_add_early_devices_dt,
|
||||
.nr_irqs = NR_IRQS_LEGACY,
|
||||
.init_irq = sh7372_init_irq,
|
||||
.handle_irq = shmobile_handle_irq_intc,
|
||||
.init_machine = sh7372_add_standard_devices_dt,
|
||||
.timer = &shmobile_timer,
|
||||
.dt_compat = sh7372_boards_compat_dt,
|
||||
MACHINE_END
|
||||
|
||||
#endif /* CONFIG_USE_OF */
|
||||
|
|
|
@ -19,9 +19,26 @@
|
|||
*
|
||||
*/
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/delay.h>
|
||||
#include <asm/mach/time.h>
|
||||
#include <asm/smp_twd.h>
|
||||
|
||||
void __init shmobile_setup_delay(unsigned int max_cpu_core_mhz,
|
||||
unsigned int mult, unsigned int div)
|
||||
{
|
||||
/* calculate a worst-case loops-per-jiffy value
|
||||
* based on maximum cpu core mhz setting and the
|
||||
* __delay() implementation in arch/arm/lib/delay.S
|
||||
*
|
||||
* this will result in a longer delay than expected
|
||||
* when the cpu core runs on lower frequencies.
|
||||
*/
|
||||
|
||||
unsigned int value = (1000000 * mult) / (HZ * div);
|
||||
|
||||
lpj_fine = max_cpu_core_mhz * value;
|
||||
}
|
||||
|
||||
static void __init shmobile_late_time_init(void)
|
||||
{
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue