diff options
Diffstat (limited to 'arch/arm/mach-omap2')
-rw-r--r-- | arch/arm/mach-omap2/Kconfig | 6 | ||||
-rw-r--r-- | arch/arm/mach-omap2/Makefile.boot | 6 | ||||
-rw-r--r-- | arch/arm/mach-omap2/omap4-common.c | 5 | ||||
-rw-r--r-- | arch/arm/mach-omap2/omap_hwmod.c | 27 | ||||
-rw-r--r-- | arch/arm/mach-omap2/timer.c | 103 |
5 files changed, 145 insertions, 2 deletions
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index 346fd26f3aa6..edc30b8b77ed 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -18,12 +18,16 @@ config ARCH_OMAP2PLUS_TYPICAL select TWL4030_CORE if ARCH_OMAP3 || ARCH_OMAP4 select TWL4030_POWER if ARCH_OMAP3 || ARCH_OMAP4 select HIGHMEM + select PINCTRL help Compile a kernel suitable for booting most boards config SOC_HAS_OMAP2_SDRC bool "OMAP2 SDRAM Controller support" +config SOC_HAS_REALTIME_COUNTER + bool "Real time free running counter" + config ARCH_OMAP2 bool "TI OMAP2" depends on ARCH_OMAP2PLUS @@ -70,6 +74,8 @@ config SOC_OMAP5 select ARM_GIC select HAVE_SMP select ARM_CPU_SUSPEND if PM + select SOC_HAS_REALTIME_COUNTER + select ARM_ARCH_TIMER comment "OMAP Core Type" depends on ARCH_OMAP2 diff --git a/arch/arm/mach-omap2/Makefile.boot b/arch/arm/mach-omap2/Makefile.boot index b03e562acc60..be0fe9226d67 100644 --- a/arch/arm/mach-omap2/Makefile.boot +++ b/arch/arm/mach-omap2/Makefile.boot @@ -1,3 +1,9 @@ zreladdr-y += 0x80008000 params_phys-y := 0x80000100 initrd_phys-y := 0x80800000 + +dtb-$(CONFIG_SOC_OMAP2420) += omap2420-h4.dtb +dtb-$(CONFIG_ARCH_OMAP3) += omap3-beagle-xm.dtb omap3-evm.dtb omap3-tobi.dtb +dtb-$(CONFIG_ARCH_OMAP4) += omap4-panda.dtb omap4-pandaES.dtb +dtb-$(CONFIG_ARCH_OMAP4) += omap4-var_som.dtb omap4-sdp.dtb +dtb-$(CONFIG_SOC_OMAP5) += omap5-evm.dtb diff --git a/arch/arm/mach-omap2/omap4-common.c b/arch/arm/mach-omap2/omap4-common.c index 9fc865502f0c..e1f289748c5d 100644 --- a/arch/arm/mach-omap2/omap4-common.c +++ b/arch/arm/mach-omap2/omap4-common.c @@ -170,7 +170,10 @@ static int __init omap_l2_cache_init(void) /* Enable PL310 L2 Cache controller */ omap_smc1(0x102, 0x1); - l2x0_init(l2cache_base, aux_ctrl, L2X0_AUX_CTRL_MASK); + if (of_have_populated_dt()) + l2x0_of_init(aux_ctrl, L2X0_AUX_CTRL_MASK); + else + l2x0_init(l2cache_base, aux_ctrl, L2X0_AUX_CTRL_MASK); /* * Override default outer_cache.disable with a OMAP4 diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 7d843cd3b33d..00c006686b0d 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -3329,6 +3329,33 @@ int omap_hwmod_fill_resources(struct omap_hwmod *oh, struct resource *res) } /** + * omap_hwmod_fill_dma_resources - fill struct resource array with dma data + * @oh: struct omap_hwmod * + * @res: pointer to the array of struct resource to fill + * + * Fill the struct resource array @res with dma resource data from the + * omap_hwmod @oh. Intended to be called by code that registers + * omap_devices. See also omap_hwmod_count_resources(). Returns the + * number of array elements filled. + */ +int omap_hwmod_fill_dma_resources(struct omap_hwmod *oh, struct resource *res) +{ + int i, sdma_reqs_cnt; + int r = 0; + + sdma_reqs_cnt = _count_sdma_reqs(oh); + for (i = 0; i < sdma_reqs_cnt; i++) { + (res + r)->name = (oh->sdma_reqs + i)->name; + (res + r)->start = (oh->sdma_reqs + i)->dma_req; + (res + r)->end = (oh->sdma_reqs + i)->dma_req; + (res + r)->flags = IORESOURCE_DMA; + r++; + } + + return r; +} + +/** * omap_hwmod_get_resource_byname - fetch IP block integration data by name * @oh: struct omap_hwmod * to operate on * @type: one of the IORESOURCE_* constants from include/linux/ioport.h diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c index 5214d5bfba27..8847d6eb2313 100644 --- a/arch/arm/mach-omap2/timer.c +++ b/arch/arm/mach-omap2/timer.c @@ -36,11 +36,13 @@ #include <linux/clocksource.h> #include <linux/clockchips.h> #include <linux/slab.h> +#include <linux/of.h> #include <asm/mach/time.h> #include <asm/smp_twd.h> #include <asm/sched_clock.h> +#include <asm/arch_timer.h> #include <plat/omap_hwmod.h> #include <plat/omap_device.h> #include <plat/dmtimer.h> @@ -71,6 +73,11 @@ #define OMAP3_SECURE_TIMER 1 #endif +#define REALTIME_COUNTER_BASE 0x48243200 +#define INCREMENTER_NUMERATOR_OFFSET 0x10 +#define INCREMENTER_DENUMERATOR_RELOAD_OFFSET 0x14 +#define NUMERATOR_DENUMERATOR_MASK 0xfffff000 + /* Clockevent code */ static struct omap_dm_timer clkev; @@ -348,6 +355,84 @@ static void __init omap2_clocksource_init(int gptimer_id, omap2_gptimer_clocksource_init(gptimer_id, fck_source); } +#ifdef CONFIG_SOC_HAS_REALTIME_COUNTER +/* + * The realtime counter also called master counter, is a free-running + * counter, which is related to real time. It produces the count used + * by the CPU local timer peripherals in the MPU cluster. The timer counts + * at a rate of 6.144 MHz. Because the device operates on different clocks + * in different power modes, the master counter shifts operation between + * clocks, adjusting the increment per clock in hardware accordingly to + * maintain a constant count rate. + */ +static void __init realtime_counter_init(void) +{ + void __iomem *base; + static struct clk *sys_clk; + unsigned long rate; + unsigned int reg, num, den; + + base = ioremap(REALTIME_COUNTER_BASE, SZ_32); + if (!base) { + pr_err("%s: ioremap failed\n", __func__); + return; + } + sys_clk = clk_get(NULL, "sys_clkin_ck"); + if (!sys_clk) { + pr_err("%s: failed to get system clock handle\n", __func__); + iounmap(base); + return; + } + + rate = clk_get_rate(sys_clk); + /* Numerator/denumerator values refer TRM Realtime Counter section */ + switch (rate) { + case 1200000: + num = 64; + den = 125; + break; + case 1300000: + num = 768; + den = 1625; + break; + case 19200000: + num = 8; + den = 25; + break; + case 2600000: + num = 384; + den = 1625; + break; + case 2700000: + num = 256; + den = 1125; + break; + case 38400000: + default: + /* Program it for 38.4 MHz */ + num = 4; + den = 25; + break; + } + + /* Program numerator and denumerator registers */ + reg = __raw_readl(base + INCREMENTER_NUMERATOR_OFFSET) & + NUMERATOR_DENUMERATOR_MASK; + reg |= num; + __raw_writel(reg, base + INCREMENTER_NUMERATOR_OFFSET); + + reg = __raw_readl(base + INCREMENTER_NUMERATOR_OFFSET) & + NUMERATOR_DENUMERATOR_MASK; + reg |= den; + __raw_writel(reg, base + INCREMENTER_DENUMERATOR_RELOAD_OFFSET); + + iounmap(base); +} +#else +static inline void __init realtime_counter_init(void) +{} +#endif + #define OMAP_SYS_TIMER_INIT(name, clkev_nr, clkev_src, \ clksrc_nr, clksrc_src) \ static void __init omap##name##_timer_init(void) \ @@ -394,6 +479,11 @@ static void __init omap4_timer_init(void) if (omap_rev() != OMAP4430_REV_ES1_0) { int err; + if (of_have_populated_dt()) { + twd_local_timer_of_register(); + return; + } + err = twd_local_timer_register(&twd_local_timer); if (err) pr_err("twd_local_timer_register failed %d\n", err); @@ -404,7 +494,18 @@ OMAP_SYS_TIMER(4) #endif #ifdef CONFIG_SOC_OMAP5 -OMAP_SYS_TIMER_INIT(5, 1, OMAP4_CLKEV_SOURCE, 2, OMAP4_MPU_SOURCE) +static void __init omap5_timer_init(void) +{ + int err; + + omap2_gp_clockevent_init(1, OMAP4_CLKEV_SOURCE); + omap2_clocksource_init(2, OMAP4_MPU_SOURCE); + realtime_counter_init(); + + err = arch_timer_of_register(); + if (err) + pr_err("%s: arch_timer_register failed %d\n", __func__, err); +} OMAP_SYS_TIMER(5) #endif |