Merge branch 'renesas-dt' into renesas-soc-core
* 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()
This commit is contained in:
commit
15d2c83948
21
arch/arm/boot/dts/sh7372.dtsi
Normal file
21
arch/arm/boot/dts/sh7372.dtsi
Normal file
@ -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 void shmobile_earlytimer_init(void);
|
||||||
extern struct sys_timer shmobile_timer;
|
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;
|
struct twd_local_timer;
|
||||||
extern void shmobile_setup_console(void);
|
extern void shmobile_setup_console(void);
|
||||||
extern void shmobile_secondary_vector(void);
|
extern void shmobile_secondary_vector(void);
|
||||||
|
@ -142,6 +142,50 @@ static struct intc_desc p ## _desc __initdata = { \
|
|||||||
p ## _sense_registers, p ## _ack_registers) \
|
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) \
|
#define INTC_IRQ_PINS_32(p, base, vect, str) \
|
||||||
\
|
\
|
||||||
static struct resource p ## _resources[] __initdata = { \
|
static struct resource p ## _resources[] __initdata = { \
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
#define gic_spi(nr) ((nr) + 32)
|
#define gic_spi(nr) ((nr) + 32)
|
||||||
|
|
||||||
/* INTCS */
|
/* 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_VECT(n, vect) INTC_VECT((n), INTCS_VECT_BASE + (vect))
|
||||||
#define intcs_evt2irq(evt) evt2irq(INTCS_VECT_BASE + (evt))
|
#define intcs_evt2irq(evt) evt2irq(INTCS_VECT_BASE + (evt))
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
|
#include <linux/module.h>
|
||||||
#include <linux/irq.h>
|
#include <linux/irq.h>
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
#include <linux/sh_intc.h>
|
#include <linux/sh_intc.h>
|
||||||
@ -305,14 +306,16 @@ static DECLARE_INTC_DESC(intca_desc, "sh7372-intca",
|
|||||||
intca_mask_registers, intca_prio_registers,
|
intca_mask_registers, intca_prio_registers,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
INTC_IRQ_PINS_32(intca_irq_pins, 0xe6900000,
|
INTC_IRQ_PINS_16(intca_irq_pins_lo, 0xe6900000,
|
||||||
INTC_VECT, "sh7372-intca-irq-pins");
|
INTC_VECT, "sh7372-intca-irq-lo");
|
||||||
|
|
||||||
|
INTC_IRQ_PINS_16H(intca_irq_pins_hi, 0xe6900000,
|
||||||
|
INTC_VECT, "sh7372-intca-irq-hi");
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
UNUSED_INTCS = 0,
|
UNUSED_INTCS = 0,
|
||||||
ENABLED_INTCS,
|
ENABLED_INTCS,
|
||||||
|
|
||||||
INTCS,
|
|
||||||
|
|
||||||
/* interrupt sources INTCS */
|
/* interrupt sources INTCS */
|
||||||
|
|
||||||
/* IRQ0S - IRQ31S */
|
/* IRQ0S - IRQ31S */
|
||||||
@ -426,8 +429,6 @@ static struct intc_vect intcs_vectors[] = {
|
|||||||
INTCS_VECT(CPORTS2R, 0x1a20),
|
INTCS_VECT(CPORTS2R, 0x1a20),
|
||||||
/* CEC */
|
/* CEC */
|
||||||
INTCS_VECT(JPU6E, 0x1a80),
|
INTCS_VECT(JPU6E, 0x1a80),
|
||||||
|
|
||||||
INTC_VECT(INTCS, 0xf80),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct intc_group intcs_groups[] __initdata = {
|
static struct intc_group intcs_groups[] __initdata = {
|
||||||
@ -490,9 +491,6 @@ static struct intc_mask_reg intcs_mask_registers[] = {
|
|||||||
{ 0xffd5019c, 0xffd501dc, 8, /* IMR7SA3 / IMCR7SA3 */
|
{ 0xffd5019c, 0xffd501dc, 8, /* IMR7SA3 / IMCR7SA3 */
|
||||||
{ MFIS2_INTCS, CPORTS2R, 0, 0,
|
{ MFIS2_INTCS, CPORTS2R, 0, 0,
|
||||||
JPU6E, 0, 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 */
|
/* 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 __init sh7372_init_irq(void)
|
||||||
{
|
{
|
||||||
void __iomem *intevtsa;
|
void __iomem *intevtsa;
|
||||||
|
int n;
|
||||||
|
|
||||||
intcs_ffd2 = ioremap_nocache(0xffd20000, PAGE_SIZE);
|
intcs_ffd2 = ioremap_nocache(0xffd20000, PAGE_SIZE);
|
||||||
intevtsa = intcs_ffd2 + 0x100;
|
intevtsa = intcs_ffd2 + 0x100;
|
||||||
intcs_ffd5 = ioremap_nocache(0xffd50000, PAGE_SIZE);
|
intcs_ffd5 = ioremap_nocache(0xffd50000, PAGE_SIZE);
|
||||||
|
|
||||||
register_intc_controller(&intca_desc);
|
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);
|
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 */
|
/* demux using INTEVTSA */
|
||||||
irq_set_handler_data(evt2irq(0xf80), (void *)intevtsa);
|
irq_set_handler_data(n, (void *)intevtsa);
|
||||||
irq_set_chained_handler(evt2irq(0xf80), intcs_demux);
|
irq_set_chained_handler(n, intcs_demux);
|
||||||
|
|
||||||
|
/* unmask INTCS in INTAMASK */
|
||||||
|
iowrite16(0, intcs_ffd2 + 0x104);
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned short ffd2[0x200];
|
static unsigned short ffd2[0x200];
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
#include <linux/irq.h>
|
#include <linux/irq.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
|
#include <linux/of_platform.h>
|
||||||
#include <linux/uio_driver.h>
|
#include <linux/uio_driver.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
#include <linux/input.h>
|
#include <linux/input.h>
|
||||||
@ -1092,3 +1093,50 @@ void __init sh7372_add_early_devices(void)
|
|||||||
/* override timer setup with soc-specific code */
|
/* override timer setup with soc-specific code */
|
||||||
shmobile_timer.init = sh7372_earlytimer_init;
|
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/platform_device.h>
|
||||||
|
#include <linux/delay.h>
|
||||||
#include <asm/mach/time.h>
|
#include <asm/mach/time.h>
|
||||||
#include <asm/smp_twd.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)
|
static void __init shmobile_late_time_init(void)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user