From a3b882f9867f884a995c5df12d447822426027e5 Mon Sep 17 00:00:00 2001 From: Andy Yan Date: Mon, 14 Nov 2016 20:12:35 +0800 Subject: ARM: debug: add low level debug uart for rv1108 RK1108 UARTs are Synopsis DesignWare 8250 compatible. Only with different register addresses. Signed-off-by: Andy Yan Tested-by: Jacob Chen [rk1108->rv1108 rename] Signed-off-by: Heiko Stuebner --- arch/arm/Kconfig.debug | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index 426d2716f55d..b3677d1d07fc 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug @@ -776,6 +776,30 @@ choice their output to the standard serial port on the RealView PB1176 platform. + config DEBUG_RV1108_UART0 + bool "Kernel low-level debugging messages via Rockchip RV1108 UART0" + depends on ARCH_ROCKCHIP + select DEBUG_UART_8250 + help + Say Y here if you want kernel low-level debugging support + on Rockchip RV1108 based platforms. + + config DEBUG_RV1108_UART1 + bool "Kernel low-level debugging messages via Rockchip RV1108 UART1" + depends on ARCH_ROCKCHIP + select DEBUG_UART_8250 + help + Say Y here if you want kernel low-level debugging support + on Rockchip RV1108 based platforms. + + config DEBUG_RV1108_UART2 + bool "Kernel low-level debugging messages via Rockchip RV1108 UART2" + depends on ARCH_ROCKCHIP + select DEBUG_UART_8250 + help + Say Y here if you want kernel low-level debugging support + on Rockchip RV1108 based platforms. + config DEBUG_RK29_UART0 bool "Kernel low-level debugging messages via Rockchip RK29 UART0" depends on ARCH_ROCKCHIP @@ -1465,6 +1489,9 @@ config DEBUG_UART_PHYS default 0x10126000 if DEBUG_RK3X_UART1 default 0x101f1000 if DEBUG_VERSATILE default 0x101fb000 if DEBUG_NOMADIK_UART + default 0x10210000 if DEBUG_RV1108_UART2 + default 0x10220000 if DEBUG_RV1108_UART1 + default 0x10230000 if DEBUG_RV1108_UART0 default 0x11002000 if DEBUG_MT8127_UART0 default 0x11006000 if DEBUG_MT6589_UART0 default 0x11009000 if DEBUG_MT8135_UART3 @@ -1563,6 +1590,9 @@ config DEBUG_UART_PHYS config DEBUG_UART_VIRT hex "Virtual base address of debug UART" + default 0xc881f000 if DEBUG_RV1108_UART2 + default 0xc8821000 if DEBUG_RV1108_UART1 + default 0xc8912000 if DEBUG_RV1108_UART0 default 0xe0000a00 if DEBUG_NETX_UART default 0xe0010fe0 if ARCH_RPC default 0xf0000be0 if ARCH_EBSA110 -- cgit From 51f6bfc78beaaa4c42bd2ab394e2550285caab0c Mon Sep 17 00:00:00 2001 From: Andy Yan Date: Mon, 14 Nov 2016 20:15:47 +0800 Subject: ARM: rockchip: enable support for RV1108 SoC Add a rockchip,rv1108 compatible. Signed-off-by: Andy Yan [rk1108->rv1108 rename] Signed-off-by: Heiko Stuebner --- arch/arm/mach-rockchip/rockchip.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-rockchip/rockchip.c b/arch/arm/mach-rockchip/rockchip.c index ef0500a4c8ad..927cf563ea47 100644 --- a/arch/arm/mach-rockchip/rockchip.c +++ b/arch/arm/mach-rockchip/rockchip.c @@ -70,6 +70,7 @@ static const char * const rockchip_board_dt_compat[] = { "rockchip,rk3188", "rockchip,rk3228", "rockchip,rk3288", + "rockchip,rv1108", NULL, }; -- cgit From 24a0f5c539f944248cbb2e3502830dcb7fd2a96e Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Tue, 27 Sep 2016 12:29:50 +0200 Subject: ARM: at91: pm: Add sama5d2 backup mode The sama5d2 has a mode were it is possible to cut power to the SoC while keeping the RAM in self refresh. Resuming from that mode needs support in the firmware/bootloader. Signed-off-by: Alexandre Belloni Acked-by: Wenyou Yang --- arch/arm/mach-at91/generic.h | 2 + arch/arm/mach-at91/pm.c | 109 ++++++++++++++++++++++++++++++++++- arch/arm/mach-at91/pm.h | 4 ++ arch/arm/mach-at91/pm_data-offsets.c | 3 + arch/arm/mach-at91/pm_suspend.S | 73 +++++++++++++++++------ arch/arm/mach-at91/sama5.c | 19 +++++- 6 files changed, 187 insertions(+), 23 deletions(-) diff --git a/arch/arm/mach-at91/generic.h b/arch/arm/mach-at91/generic.h index f1ead0f13c19..e2bd17237964 100644 --- a/arch/arm/mach-at91/generic.h +++ b/arch/arm/mach-at91/generic.h @@ -15,10 +15,12 @@ extern void __init at91rm9200_pm_init(void); extern void __init at91sam9_pm_init(void); extern void __init sama5_pm_init(void); +extern void __init sama5d2_pm_init(void); #else static inline void __init at91rm9200_pm_init(void) { } static inline void __init at91sam9_pm_init(void) { } static inline void __init sama5_pm_init(void) { } +static inline void __init sama5d2_pm_init(void) { } #endif #endif /* _AT91_GENERIC_H */ diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index 2cd27c830ab6..d138d19fa9f0 100644 --- a/arch/arm/mach-at91/pm.c +++ b/arch/arm/mach-at91/pm.c @@ -22,6 +22,7 @@ #include #include #include +#include #include "generic.h" #include "pm.h" @@ -58,6 +59,14 @@ static int at91_pm_valid_state(suspend_state_t state) } } +static int canary = 0xA5A5A5A5; + +static struct at91_pm_bu { + int suspended; + unsigned long reserved; + phys_addr_t canary; + phys_addr_t resume; +} *pm_bu; static suspend_state_t target_state; @@ -123,15 +132,39 @@ static void (*at91_suspend_sram_fn)(struct at91_pm_data *); extern void at91_pm_suspend_in_sram(struct at91_pm_data *pm_data); extern u32 at91_pm_suspend_in_sram_sz; -static void at91_pm_suspend(suspend_state_t state) +static int at91_suspend_finish(unsigned long val) { - pm_data.mode = (state == PM_SUSPEND_MEM) ? AT91_PM_SLOW_CLOCK : 0; - flush_cache_all(); outer_disable(); at91_suspend_sram_fn(&pm_data); + return 0; +} + +static void at91_pm_suspend(suspend_state_t state) +{ + if (pm_data.deepest_state == AT91_PM_BACKUP) + if (state == PM_SUSPEND_MEM) + pm_data.mode = AT91_PM_BACKUP; + else + pm_data.mode = AT91_PM_SLOW_CLOCK; + else + pm_data.mode = (state == PM_SUSPEND_MEM) ? AT91_PM_SLOW_CLOCK : 0; + + if (pm_data.mode == AT91_PM_BACKUP) { + pm_bu->suspended = 1; + + cpu_suspend(0, at91_suspend_finish); + + /* The SRAM is lost between suspend cycles */ + at91_suspend_sram_fn = fncpy(at91_suspend_sram_fn, + &at91_pm_suspend_in_sram, + at91_pm_suspend_in_sram_sz); + } else { + at91_suspend_finish(0); + } + outer_resume(); } @@ -436,6 +469,70 @@ static void __init at91_pm_sram_init(void) &at91_pm_suspend_in_sram, at91_pm_suspend_in_sram_sz); } +static void __init at91_pm_backup_init(void) +{ + struct gen_pool *sram_pool; + struct device_node *np; + struct platform_device *pdev = NULL; + + pm_bu = NULL; + + np = of_find_compatible_node(NULL, NULL, "atmel,sama5d2-shdwc"); + if (!np) { + pr_warn("%s: failed to find shdwc!\n", __func__); + return; + } + + pm_data.shdwc = of_iomap(np, 0); + of_node_put(np); + + np = of_find_compatible_node(NULL, NULL, "atmel,sama5d2-sfrbu"); + if (!np) { + pr_warn("%s: failed to find sfrbu!\n", __func__); + goto sfrbu_fail; + } + + pm_data.sfrbu = of_iomap(np, 0); + of_node_put(np); + pm_bu = NULL; + + np = of_find_compatible_node(NULL, NULL, "atmel,sama5d2-securam"); + if (!np) + goto securam_fail; + + pdev = of_find_device_by_node(np); + of_node_put(np); + if (!pdev) { + pr_warn("%s: failed to find securam device!\n", __func__); + goto securam_fail; + } + + sram_pool = gen_pool_get(&pdev->dev, NULL); + if (!sram_pool) { + pr_warn("%s: securam pool unavailable!\n", __func__); + goto securam_fail; + } + + pm_bu = (void *)gen_pool_alloc(sram_pool, sizeof(struct at91_pm_bu)); + if (!pm_bu) { + pr_warn("%s: unable to alloc securam!\n", __func__); + goto securam_fail; + } + + pm_bu->suspended = 0; + pm_bu->canary = virt_to_phys(&canary); + pm_bu->resume = virt_to_phys(cpu_resume); + + return; + +sfrbu_fail: + iounmap(pm_data.shdwc); + pm_data.shdwc = NULL; +securam_fail: + iounmap(pm_data.sfrbu); + pm_data.sfrbu = NULL; +} + struct pmc_info { unsigned long uhp_udp_mask; }; @@ -510,3 +607,9 @@ void __init sama5_pm_init(void) at91_dt_ramc(); at91_pm_init(NULL); } + +void __init sama5d2_pm_init(void) +{ + at91_pm_backup_init(); + sama5_pm_init(); +} diff --git a/arch/arm/mach-at91/pm.h b/arch/arm/mach-at91/pm.h index fc0f7d048187..d9c6612ef62f 100644 --- a/arch/arm/mach-at91/pm.h +++ b/arch/arm/mach-at91/pm.h @@ -22,6 +22,7 @@ #define AT91_MEMCTRL_DDRSDR 2 #define AT91_PM_SLOW_CLOCK 0x01 +#define AT91_PM_BACKUP 0x02 #ifndef __ASSEMBLY__ struct at91_pm_data { @@ -30,6 +31,9 @@ struct at91_pm_data { unsigned long uhp_udp_mask; unsigned int memctrl; unsigned int mode; + void __iomem *shdwc; + void __iomem *sfrbu; + unsigned int deepest_state; }; #endif diff --git a/arch/arm/mach-at91/pm_data-offsets.c b/arch/arm/mach-at91/pm_data-offsets.c index 30302cb16df0..c0a73e62b725 100644 --- a/arch/arm/mach-at91/pm_data-offsets.c +++ b/arch/arm/mach-at91/pm_data-offsets.c @@ -9,5 +9,8 @@ int main(void) DEFINE(PM_DATA_RAMC1, offsetof(struct at91_pm_data, ramc[1])); DEFINE(PM_DATA_MEMCTRL, offsetof(struct at91_pm_data, memctrl)); DEFINE(PM_DATA_MODE, offsetof(struct at91_pm_data, mode)); + DEFINE(PM_DATA_SHDWC, offsetof(struct at91_pm_data, shdwc)); + DEFINE(PM_DATA_SFRBU, offsetof(struct at91_pm_data, sfrbu)); + return 0; } diff --git a/arch/arm/mach-at91/pm_suspend.S b/arch/arm/mach-at91/pm_suspend.S index 96781daa671a..daca91feea6a 100644 --- a/arch/arm/mach-at91/pm_suspend.S +++ b/arch/arm/mach-at91/pm_suspend.S @@ -97,15 +97,61 @@ ENTRY(at91_pm_suspend_in_sram) str tmp1, .memtype ldr tmp1, [r0, #PM_DATA_MODE] str tmp1, .pm_mode + /* Both ldrne below are here to preload their address in the TLB */ + ldr tmp1, [r0, #PM_DATA_SHDWC] + str tmp1, .shdwc + cmp tmp1, #0 + ldrne tmp2, [tmp1, #0] + ldr tmp1, [r0, #PM_DATA_SFRBU] + str tmp1, .sfr + cmp tmp1, #0 + ldrne tmp2, [tmp1, #0x10] /* Active the self-refresh mode */ mov r0, #SRAMC_SELF_FRESH_ACTIVE bl at91_sramc_self_refresh ldr r0, .pm_mode - tst r0, #AT91_PM_SLOW_CLOCK - beq skip_disable_main_clock + cmp r0, #AT91_PM_SLOW_CLOCK + beq slow_clock + cmp r0, #AT91_PM_BACKUP + beq backup_mode + /* Wait for interrupt */ + ldr pmc, .pmc_base + at91_cpu_idle + b exit_suspend + +slow_clock: + bl at91_slowck_mode + b exit_suspend +backup_mode: + bl at91_backup_mode + b exit_suspend + +exit_suspend: + /* Exit the self-refresh mode */ + mov r0, #SRAMC_SELF_FRESH_EXIT + bl at91_sramc_self_refresh + + /* Restore registers, and return */ + ldmfd sp!, {r4 - r12, pc} +ENDPROC(at91_pm_suspend_in_sram) + +ENTRY(at91_backup_mode) + /*BUMEN*/ + ldr r0, .sfr + mov tmp1, #0x1 + str tmp1, [r0, #0x10] + + /* Shutdown */ + ldr r0, .shdwc + mov tmp1, #0xA5000000 + add tmp1, tmp1, #0x1 + str tmp1, [r0, #0] +ENDPROC(at91_backup_mode) + +ENTRY(at91_slowck_mode) ldr pmc, .pmc_base /* Save Master clock setting */ @@ -134,18 +180,9 @@ ENTRY(at91_pm_suspend_in_sram) orr tmp1, tmp1, #AT91_PMC_KEY str tmp1, [pmc, #AT91_CKGR_MOR] -skip_disable_main_clock: - ldr pmc, .pmc_base - /* Wait for interrupt */ at91_cpu_idle - ldr r0, .pm_mode - tst r0, #AT91_PM_SLOW_CLOCK - beq skip_enable_main_clock - - ldr pmc, .pmc_base - /* Turn on the main oscillator */ ldr tmp1, [pmc, #AT91_CKGR_MOR] orr tmp1, tmp1, #AT91_PMC_MOSCEN @@ -174,14 +211,8 @@ skip_disable_main_clock: wait_mckrdy -skip_enable_main_clock: - /* Exit the self-refresh mode */ - mov r0, #SRAMC_SELF_FRESH_EXIT - bl at91_sramc_self_refresh - - /* Restore registers, and return */ - ldmfd sp!, {r4 - r12, pc} -ENDPROC(at91_pm_suspend_in_sram) + mov pc, lr +ENDPROC(at91_slowck_mode) /* * void at91_sramc_self_refresh(unsigned int is_active) @@ -314,6 +345,10 @@ ENDPROC(at91_sramc_self_refresh) .word 0 .sramc1_base: .word 0 +.shdwc: + .word 0 +.sfr: + .word 0 .memtype: .word 0 .pm_mode: diff --git a/arch/arm/mach-at91/sama5.c b/arch/arm/mach-at91/sama5.c index 6d157d0ead8e..3d0bf95a56ae 100644 --- a/arch/arm/mach-at91/sama5.c +++ b/arch/arm/mach-at91/sama5.c @@ -34,7 +34,6 @@ DT_MACHINE_START(sama5_dt, "Atmel SAMA5") MACHINE_END static const char *const sama5_alt_dt_board_compat[] __initconst = { - "atmel,sama5d2", "atmel,sama5d4", NULL }; @@ -45,3 +44,21 @@ DT_MACHINE_START(sama5_alt_dt, "Atmel SAMA5") .dt_compat = sama5_alt_dt_board_compat, .l2c_aux_mask = ~0UL, MACHINE_END + +static void __init sama5d2_init(void) +{ + of_platform_default_populate(NULL, NULL, NULL); + sama5d2_pm_init(); +} + +static const char *const sama5d2_compat[] __initconst = { + "atmel,sama5d2", + NULL +}; + +DT_MACHINE_START(sama5d2, "Atmel SAMA5") + /* Maintainer: Atmel */ + .init_machine = sama5d2_init, + .dt_compat = sama5d2_compat, + .l2c_aux_mask = ~0UL, +MACHINE_END -- cgit From 7693e18e8c2e2f3188f69bd572ff77dac481da6e Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Wed, 26 Apr 2017 16:31:03 +0200 Subject: ARM: at91: pm: allow selecting standby and suspend modes While we can only select between "standby" and "mem" states for power management, the atmel platforms can actually support more modes. For both standby and mem, allow selecting which mode will be used using the atmel.pm_modes kernel parameter. By default, keep the current modes. Signed-off-by: Alexandre Belloni Acked-by: Wenyou Yang --- arch/arm/mach-at91/pm.c | 110 +++++++++++++++++++++++++++++++++--------------- arch/arm/mach-at91/pm.h | 3 +- 2 files changed, 78 insertions(+), 35 deletions(-) diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index d138d19fa9f0..ef9c1d29cc67 100644 --- a/arch/arm/mach-at91/pm.c +++ b/arch/arm/mach-at91/pm.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -38,7 +39,17 @@ extern void at91_pinctrl_gpio_suspend(void); extern void at91_pinctrl_gpio_resume(void); #endif -static struct at91_pm_data pm_data; +static const match_table_t pm_modes __initconst = { + { 0, "standby" }, + { AT91_PM_SLOW_CLOCK, "ulp0" }, + { AT91_PM_BACKUP, "backup" }, + { -1, NULL }, +}; + +static struct at91_pm_data pm_data = { + .standby_mode = 0, + .suspend_mode = AT91_PM_SLOW_CLOCK, +}; #define at91_ramc_read(id, field) \ __raw_readl(pm_data.ramc[id] + field) @@ -68,14 +79,24 @@ static struct at91_pm_bu { phys_addr_t resume; } *pm_bu; -static suspend_state_t target_state; - /* * Called after processes are frozen, but before we shutdown devices. */ static int at91_pm_begin(suspend_state_t state) { - target_state = state; + switch (state) { + case PM_SUSPEND_MEM: + pm_data.mode = pm_data.suspend_mode; + break; + + case PM_SUSPEND_STANDBY: + pm_data.mode = pm_data.standby_mode; + break; + + default: + pm_data.mode = -1; + } + return 0; } @@ -124,7 +145,7 @@ static int at91_pm_verify_clocks(void) */ int at91_suspend_entering_slow_clock(void) { - return (target_state == PM_SUSPEND_MEM); + return (pm_data.mode >= AT91_PM_SLOW_CLOCK); } EXPORT_SYMBOL(at91_suspend_entering_slow_clock); @@ -144,14 +165,6 @@ static int at91_suspend_finish(unsigned long val) static void at91_pm_suspend(suspend_state_t state) { - if (pm_data.deepest_state == AT91_PM_BACKUP) - if (state == PM_SUSPEND_MEM) - pm_data.mode = AT91_PM_BACKUP; - else - pm_data.mode = AT91_PM_SLOW_CLOCK; - else - pm_data.mode = (state == PM_SUSPEND_MEM) ? AT91_PM_SLOW_CLOCK : 0; - if (pm_data.mode == AT91_PM_BACKUP) { pm_bu->suspended = 1; @@ -168,38 +181,37 @@ static void at91_pm_suspend(suspend_state_t state) outer_resume(); } +/* + * STANDBY mode has *all* drivers suspended; ignores irqs not marked as 'wakeup' + * event sources; and reduces DRAM power. But otherwise it's identical to + * PM_SUSPEND_ON: cpu idle, and nothing fancy done with main or cpu clocks. + * + * AT91_PM_SLOW_CLOCK is like STANDBY plus slow clock mode, so drivers must + * suspend more deeply, the master clock switches to the clk32k and turns off + * the main oscillator + * + * AT91_PM_BACKUP turns off the whole SoC after placing the DDR in self refresh + */ static int at91_pm_enter(suspend_state_t state) { #ifdef CONFIG_PINCTRL_AT91 at91_pinctrl_gpio_suspend(); #endif + switch (state) { - /* - * Suspend-to-RAM is like STANDBY plus slow clock mode, so - * drivers must suspend more deeply, the master clock switches - * to the clk32k and turns off the main oscillator - */ case PM_SUSPEND_MEM: + case PM_SUSPEND_STANDBY: /* * Ensure that clocks are in a valid state. */ - if (!at91_pm_verify_clocks()) + if ((pm_data.mode >= AT91_PM_SLOW_CLOCK) && + !at91_pm_verify_clocks()) goto error; at91_pm_suspend(state); break; - /* - * STANDBY mode has *all* drivers suspended; ignores irqs not - * marked as 'wakeup' event sources; and reduces DRAM power. - * But otherwise it's identical to PM_SUSPEND_ON: cpu idle, and - * nothing fancy done with main or cpu clocks. - */ - case PM_SUSPEND_STANDBY: - at91_pm_suspend(state); - break; - case PM_SUSPEND_ON: cpu_do_idle(); break; @@ -210,8 +222,6 @@ static int at91_pm_enter(suspend_state_t state) } error: - target_state = PM_SUSPEND_ON; - #ifdef CONFIG_PINCTRL_AT91 at91_pinctrl_gpio_resume(); #endif @@ -223,7 +233,6 @@ error: */ static void at91_pm_end(void) { - target_state = PM_SUSPEND_ON; } @@ -475,6 +484,10 @@ static void __init at91_pm_backup_init(void) struct device_node *np; struct platform_device *pdev = NULL; + if ((pm_data.standby_mode != AT91_PM_BACKUP) && + (pm_data.suspend_mode != AT91_PM_BACKUP)) + return; + pm_bu = NULL; np = of_find_compatible_node(NULL, NULL, "atmel,sama5d2-shdwc"); @@ -578,10 +591,14 @@ static void __init at91_pm_init(void (*pm_idle)(void)) at91_pm_sram_init(); - if (at91_suspend_sram_fn) + if (at91_suspend_sram_fn) { suspend_set_ops(&at91_pm_ops); - else + pr_info("AT91: PM: standby: %s, suspend: %s\n", + pm_modes[pm_data.standby_mode].pattern, + pm_modes[pm_data.suspend_mode].pattern); + } else { pr_info("AT91: PM not supported, due to no SRAM allocated\n"); + } } void __init at91rm9200_pm_init(void) @@ -613,3 +630,28 @@ void __init sama5d2_pm_init(void) at91_pm_backup_init(); sama5_pm_init(); } + +static int __init at91_pm_modes_select(char *str) +{ + char *s; + substring_t args[MAX_OPT_ARGS]; + int standby, suspend; + + if (!str) + return 0; + + s = strsep(&str, ","); + standby = match_token(s, pm_modes, args); + if (standby < 0) + return 0; + + suspend = match_token(str, pm_modes, args); + if (suspend < 0) + return 0; + + pm_data.standby_mode = standby; + pm_data.suspend_mode = suspend; + + return 0; +} +early_param("atmel.pm_modes", at91_pm_modes_select); diff --git a/arch/arm/mach-at91/pm.h b/arch/arm/mach-at91/pm.h index d9c6612ef62f..f95d31496f08 100644 --- a/arch/arm/mach-at91/pm.h +++ b/arch/arm/mach-at91/pm.h @@ -33,7 +33,8 @@ struct at91_pm_data { unsigned int mode; void __iomem *shdwc; void __iomem *sfrbu; - unsigned int deepest_state; + unsigned int standby_mode; + unsigned int suspend_mode; }; #endif -- cgit From 287322386d303891e9cdc81313137054da9d5467 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Wed, 26 Apr 2017 16:34:24 +0200 Subject: ARM: at91: pm: fallback to slowclock when backup mode fails If the backup sram allocation fails, ensure we can suspend by falling back to the usual slow clock mode. Signed-off-by: Alexandre Belloni Acked-by: Wenyou Yang --- arch/arm/mach-at91/pm.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index ef9c1d29cc67..fc4026478579 100644 --- a/arch/arm/mach-at91/pm.c +++ b/arch/arm/mach-at91/pm.c @@ -544,6 +544,11 @@ sfrbu_fail: securam_fail: iounmap(pm_data.sfrbu); pm_data.sfrbu = NULL; + + if (pm_data.standby_mode == AT91_PM_BACKUP) + pm_data.standby_mode = AT91_PM_SLOW_CLOCK; + if (pm_data.suspend_mode == AT91_PM_BACKUP) + pm_data.suspend_mode = AT91_PM_SLOW_CLOCK; } struct pmc_info { -- cgit From e1a9e61e141d2b61780602b0af2befd7133c0bae Mon Sep 17 00:00:00 2001 From: Dave Gerlach Date: Tue, 28 Mar 2017 20:57:54 -0500 Subject: ARM: OMAP: Wakeupgen: Add context save/restore for AM43XX AM43XX has the same wakeupgen IP as OMAP4/5. The only notable difference is the presence of 7 register banks and lack of SAR area which has been used in OMAP4/5 for saving and restoring the context around low power states. In case of AM43XX the context is saved and restored by the kernel. Introduce wakeupgen_ops so that context save and restore can be set on a per-SoC basis during init. Signed-off-by: Dave Gerlach Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/omap-wakeupgen.c | 68 ++++++++++++++++++++++++++++++++---- 1 file changed, 62 insertions(+), 6 deletions(-) diff --git a/arch/arm/mach-omap2/omap-wakeupgen.c b/arch/arm/mach-omap2/omap-wakeupgen.c index 369f95a703ac..33ed5d53fa45 100644 --- a/arch/arm/mach-omap2/omap-wakeupgen.c +++ b/arch/arm/mach-omap2/omap-wakeupgen.c @@ -58,6 +58,17 @@ static unsigned int irq_banks = DEFAULT_NR_REG_BANKS; static unsigned int max_irqs = DEFAULT_IRQS; static unsigned int omap_secure_apis; +#ifdef CONFIG_CPU_PM +static unsigned int wakeupgen_context[MAX_NR_REG_BANKS]; +#endif + +struct omap_wakeupgen_ops { + void (*save_context)(void); + void (*restore_context)(void); +}; + +static struct omap_wakeupgen_ops *wakeupgen_ops; + /* * Static helper functions. */ @@ -264,6 +275,16 @@ static inline void omap5_irq_save_context(void) } +static inline void am43xx_irq_save_context(void) +{ + u32 i; + + for (i = 0; i < irq_banks; i++) { + wakeupgen_context[i] = wakeupgen_readl(i, 0); + wakeupgen_writel(0, i, CPU0_ID); + } +} + /* * Save WakeupGen interrupt context in SAR BANK3. Restore is done by * ROM code. WakeupGen IP is integrated along with GIC to manage the @@ -280,11 +301,8 @@ static void irq_save_context(void) if (!sar_base) sar_base = omap4_get_sar_ram_base(); - - if (soc_is_omap54xx()) - omap5_irq_save_context(); - else - omap4_irq_save_context(); + if (wakeupgen_ops && wakeupgen_ops->save_context) + wakeupgen_ops->save_context(); } /* @@ -306,6 +324,20 @@ static void irq_sar_clear(void) writel_relaxed(val, sar_base + offset); } +static void am43xx_irq_restore_context(void) +{ + u32 i; + + for (i = 0; i < irq_banks; i++) + wakeupgen_writel(wakeupgen_context[i], i, CPU0_ID); +} + +static void irq_restore_context(void) +{ + if (wakeupgen_ops && wakeupgen_ops->restore_context) + wakeupgen_ops->restore_context(); +} + /* * Save GIC and Wakeupgen interrupt context using secure API * for HS/EMU devices. @@ -319,6 +351,26 @@ static void irq_save_secure_context(void) if (ret != API_HAL_RET_VALUE_OK) pr_err("GIC and Wakeupgen context save failed\n"); } + +/* Define ops for context save and restore for each SoC */ +static struct omap_wakeupgen_ops omap4_wakeupgen_ops = { + .save_context = omap4_irq_save_context, + .restore_context = irq_sar_clear, +}; + +static struct omap_wakeupgen_ops omap5_wakeupgen_ops = { + .save_context = omap5_irq_save_context, + .restore_context = irq_sar_clear, +}; + +static struct omap_wakeupgen_ops am43xx_wakeupgen_ops = { + .save_context = am43xx_irq_save_context, + .restore_context = am43xx_irq_restore_context, +}; +#else +static struct omap_wakeupgen_ops omap4_wakeupgen_ops = {}; +static struct omap_wakeupgen_ops omap5_wakeupgen_ops = {}; +static struct omap_wakeupgen_ops am43xx_wakeupgen_ops = {}; #endif #ifdef CONFIG_HOTPLUG_CPU @@ -359,7 +411,7 @@ static int irq_notifier(struct notifier_block *self, unsigned long cmd, void *v) break; case CPU_CLUSTER_PM_EXIT: if (omap_type() == OMAP2_DEVICE_TYPE_GP) - irq_sar_clear(); + irq_restore_context(); break; } return NOTIFY_OK; @@ -494,9 +546,13 @@ static int __init wakeupgen_init(struct device_node *node, irq_banks = OMAP4_NR_BANKS; max_irqs = OMAP4_NR_IRQS; omap_secure_apis = 1; + wakeupgen_ops = &omap4_wakeupgen_ops; + } else if (soc_is_omap54xx()) { + wakeupgen_ops = &omap5_wakeupgen_ops; } else if (soc_is_am43xx()) { irq_banks = AM43XX_NR_REG_BANKS; max_irqs = AM43XX_IRQS; + wakeupgen_ops = &am43xx_wakeupgen_ops; } domain = irq_domain_add_hierarchy(parent_domain, 0, max_irqs, -- cgit From 12b28ba6d6164d3aa54b7e32032bcbd9b7c2a320 Mon Sep 17 00:00:00 2001 From: Dave Gerlach Date: Tue, 28 Mar 2017 20:57:55 -0500 Subject: ARM: OMAP2+: timer: Add suspend-resume callbacks for clkevent device OMAP timer code registers two timers - one as clocksource and one as clockevent. Since AM33XX has only one usable timer in the WKUP domain one of the timers needs suspend-resume support to restore the configuration to pre-suspend state. commit adc78e6b9946 ("timekeeping: Add suspend and resume of clock event devices") introduced .suspend and .resume callbacks for clock event devices. Leverage these callbacks to have AM33XX clockevent timer behave properly across system suspend. Extend the use of the .suspend and .resume callbacks used by am335x clockevent to am437x as well. Signed-off-by: Dave Gerlach Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/timer.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c index 07dd692c4737..70670dfd7135 100644 --- a/arch/arm/mach-omap2/timer.c +++ b/arch/arm/mach-omap2/timer.c @@ -68,6 +68,9 @@ static struct omap_dm_timer clkev; static struct clock_event_device clockevent_gpt; +/* Clockevent hwmod for am335x and am437x suspend */ +static struct omap_hwmod *clockevent_gpt_hwmod; + #ifdef CONFIG_SOC_HAS_REALTIME_COUNTER static unsigned long arch_timer_freq; @@ -125,6 +128,23 @@ static int omap2_gp_timer_set_periodic(struct clock_event_device *evt) return 0; } +static void omap_clkevt_idle(struct clock_event_device *unused) +{ + if (!clockevent_gpt_hwmod) + return; + + omap_hwmod_idle(clockevent_gpt_hwmod); +} + +static void omap_clkevt_unidle(struct clock_event_device *unused) +{ + if (!clockevent_gpt_hwmod) + return; + + omap_hwmod_enable(clockevent_gpt_hwmod); + __omap_dm_timer_int_enable(&clkev, OMAP_TIMER_INT_OVERFLOW); +} + static struct clock_event_device clockevent_gpt = { .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, @@ -358,6 +378,14 @@ static void __init omap2_gp_clockevent_init(int gptimer_id, 3, /* Timer internal resynch latency */ 0xffffffff); + if (soc_is_am33xx() || soc_is_am43xx()) { + clockevent_gpt.suspend = omap_clkevt_idle; + clockevent_gpt.resume = omap_clkevt_unidle; + + clockevent_gpt_hwmod = + omap_hwmod_lookup(clockevent_gpt.name); + } + pr_info("OMAP clockevent source: %s at %lu Hz\n", clockevent_gpt.name, clkev.rate); } -- cgit From 33d3842d640e981e2c5ee772befff756b7f2d6f3 Mon Sep 17 00:00:00 2001 From: Dave Gerlach Date: Tue, 28 Mar 2017 20:57:56 -0500 Subject: ARM: OMAP2+: pm: Remove __init from omap_pm_clkdms_setup omap_pm_clkdms_setup gets called from pm init functions and now that pm33xx and pm43xx can be loaded as modules this must be kept to be called at any point during runtime. Signed-off-by: Dave Gerlach Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/pm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c index 63027e60cc20..366158a54fcd 100644 --- a/arch/arm/mach-omap2/pm.c +++ b/arch/arm/mach-omap2/pm.c @@ -71,7 +71,7 @@ void omap_pm_get_oscillator(u32 *tstart, u32 *tshut) } #endif -int __init omap_pm_clkdms_setup(struct clockdomain *clkdm, void *unused) +int omap_pm_clkdms_setup(struct clockdomain *clkdm, void *unused) { clkdm_allow_idle(clkdm); return 0; -- cgit From 27d9fa06c122b135ad7552fa3138c3b47e5776c5 Mon Sep 17 00:00:00 2001 From: Jon Mason Date: Fri, 28 Apr 2017 16:11:29 -0400 Subject: ARM: BCM: Enable thermal support for NSP SoCs Change the Northstar Plus Kconfig to select THERMAL and THERMAL_OF, which allows the ns-thermal driver to be selected via menuconfig. Signed-off-by: Jon Mason Signed-off-by: Florian Fainelli --- arch/arm/mach-bcm/Kconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/mach-bcm/Kconfig b/arch/arm/mach-bcm/Kconfig index f9389c5910e7..abfce8f29ca1 100644 --- a/arch/arm/mach-bcm/Kconfig +++ b/arch/arm/mach-bcm/Kconfig @@ -44,6 +44,8 @@ config ARCH_BCM_NSP select ARM_ERRATA_775420 select ARM_ERRATA_764369 if SMP select HAVE_SMP + select THERMAL + select THERMAL_OF help Support for Broadcom Northstar Plus SoC. Broadcom Northstar Plus family of SoCs are used for switching control -- cgit From da6ee0c300b8a38cd79e64c9b1fd1a3ba94da7b2 Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Mon, 15 May 2017 08:03:50 -0700 Subject: ARM: imx: Select GPCv2 for i.MX7 GPCv2 IP block is a part of i.MX7 SoC. Select it to make corresponding driver availible to support DT changes following this patch. Cc: yurovsky@gmail.com Cc: Dong Aisheng Cc: Sascha Hauer Cc: Fabio Estevam Cc: Rob Herring Cc: Mark Rutland Cc: Russell King Cc: devicetree@vger.kernel.org Cc: linux-kernel@vger.kernel.org Cc: linux-arm-kernel@lists.infradead.org Signed-off-by: Andrey Smirnov Signed-off-by: Shawn Guo --- arch/arm/mach-imx/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index 936c59d0e18b..782699e67600 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -536,6 +536,7 @@ config SOC_IMX7D select HAVE_IMX_ANATOP select HAVE_IMX_MMDC select HAVE_IMX_SRC + select IMX_GPCV2 help This enables support for Freescale i.MX7 Dual processor. -- cgit From f97f03578b997a8ec2b9bc4928f958a865137268 Mon Sep 17 00:00:00 2001 From: Suman Anna Date: Tue, 16 May 2017 17:13:45 -0500 Subject: ARM: davinci: da8xx: Create DSP device only when assigned memory The DSP device on Davinci platforms does not have an MMU and requires specific DDR memory to boot. This memory is reserved using the rproc_mem kernel boot parameter and is assigned to the device on non-DT boots. The remoteproc core uses the DMA API and so will fall back to assigning random memory if this memory is not assigned to the device, but the DSP remote processor boot will not be successful in such cases. So, check that memory has been reserved and assigned to the device specifically before even creating the DSP device. Signed-off-by: Suman Anna Signed-off-by: Sekhar Nori --- arch/arm/mach-davinci/devices-da8xx.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/arch/arm/mach-davinci/devices-da8xx.c b/arch/arm/mach-davinci/devices-da8xx.c index 7cf529ffbe5a..1ccf52e49886 100644 --- a/arch/arm/mach-davinci/devices-da8xx.c +++ b/arch/arm/mach-davinci/devices-da8xx.c @@ -814,6 +814,8 @@ static struct platform_device da8xx_dsp = { .resource = da8xx_rproc_resources, }; +static bool rproc_mem_inited __initdata; + #if IS_ENABLED(CONFIG_DA8XX_REMOTEPROC) static phys_addr_t rproc_base __initdata; @@ -852,6 +854,8 @@ void __init da8xx_rproc_reserve_cma(void) ret = dma_declare_contiguous(&da8xx_dsp.dev, rproc_size, rproc_base, 0); if (ret) pr_err("%s: dma_declare_contiguous failed %d\n", __func__, ret); + else + rproc_mem_inited = true; } #else @@ -866,6 +870,12 @@ int __init da8xx_register_rproc(void) { int ret; + if (!rproc_mem_inited) { + pr_warn("%s: memory not reserved for DSP, not registering DSP device\n", + __func__); + return -ENOMEM; + } + ret = platform_device_register(&da8xx_dsp); if (ret) pr_err("%s: can't register DSP device: %d\n", __func__, ret); -- cgit From 6724a05ff35f95266c5746db0d7185269eec8282 Mon Sep 17 00:00:00 2001 From: Suman Anna Date: Tue, 16 May 2017 17:13:46 -0500 Subject: ARM: davinci: da8xx: Add names to DSP IOMEM resources Add names to the IOMEM resources for the DSP device present on DA8xx SoCs. This will facilitate the driver to use the names and be agnostic of the resource order, and facilitate scalable DT support in follow-up patches. Signed-off-by: Suman Anna Signed-off-by: Sekhar Nori --- arch/arm/mach-davinci/devices-da8xx.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/mach-davinci/devices-da8xx.c b/arch/arm/mach-davinci/devices-da8xx.c index 1ccf52e49886..74c76538cda3 100644 --- a/arch/arm/mach-davinci/devices-da8xx.c +++ b/arch/arm/mach-davinci/devices-da8xx.c @@ -789,11 +789,13 @@ int __init da850_register_mmcsd1(struct davinci_mmc_config *config) static struct resource da8xx_rproc_resources[] = { { /* DSP boot address */ + .name = "host1cfg", .start = DA8XX_SYSCFG0_BASE + DA8XX_HOST1CFG_REG, .end = DA8XX_SYSCFG0_BASE + DA8XX_HOST1CFG_REG + 3, .flags = IORESOURCE_MEM, }, { /* DSP interrupt registers */ + .name = "chipsig", .start = DA8XX_SYSCFG0_BASE + DA8XX_CHIPSIG_REG, .end = DA8XX_SYSCFG0_BASE + DA8XX_CHIPSIG_REG + 7, .flags = IORESOURCE_MEM, -- cgit From 14ff86bc76be9b5c96f06ce141c8bdd612dafd64 Mon Sep 17 00:00:00 2001 From: Suman Anna Date: Tue, 16 May 2017 17:13:47 -0500 Subject: ARM: davinci: da8xx: Add DSP internal RAM memories as IOMEM resources The DSP subsystem on DA8xx has various internal RAM memories that can accessed from the ARM side. These memories can be configured to be used as either RAM or Cache. Add these memories as IOMEM resources to the DSP device so that the driver can support loading of images into internal memories. Signed-off-by: Suman Anna Signed-off-by: Sekhar Nori --- arch/arm/mach-davinci/devices-da8xx.c | 18 ++++++++++++++++++ arch/arm/mach-davinci/include/mach/da8xx.h | 5 +++++ 2 files changed, 23 insertions(+) diff --git a/arch/arm/mach-davinci/devices-da8xx.c b/arch/arm/mach-davinci/devices-da8xx.c index 74c76538cda3..22440c05d66a 100644 --- a/arch/arm/mach-davinci/devices-da8xx.c +++ b/arch/arm/mach-davinci/devices-da8xx.c @@ -800,6 +800,24 @@ static struct resource da8xx_rproc_resources[] = { .end = DA8XX_SYSCFG0_BASE + DA8XX_CHIPSIG_REG + 7, .flags = IORESOURCE_MEM, }, + { /* DSP L2 RAM */ + .name = "l2sram", + .start = DA8XX_DSP_L2_RAM_BASE, + .end = DA8XX_DSP_L2_RAM_BASE + SZ_256K - 1, + .flags = IORESOURCE_MEM, + }, + { /* DSP L1P RAM */ + .name = "l1pram", + .start = DA8XX_DSP_L1P_RAM_BASE, + .end = DA8XX_DSP_L1P_RAM_BASE + SZ_32K - 1, + .flags = IORESOURCE_MEM, + }, + { /* DSP L1D RAM */ + .name = "l1dram", + .start = DA8XX_DSP_L1D_RAM_BASE, + .end = DA8XX_DSP_L1D_RAM_BASE + SZ_32K - 1, + .flags = IORESOURCE_MEM, + }, { /* dsp irq */ .start = IRQ_DA8XX_CHIPINT0, .end = IRQ_DA8XX_CHIPINT0, diff --git a/arch/arm/mach-davinci/include/mach/da8xx.h b/arch/arm/mach-davinci/include/mach/da8xx.h index 7e464228948b..93ff1569cee5 100644 --- a/arch/arm/mach-davinci/include/mach/da8xx.h +++ b/arch/arm/mach-davinci/include/mach/da8xx.h @@ -75,6 +75,11 @@ extern unsigned int da850_max_speed; #define DA8XX_VPIF_BASE 0x01e17000 #define DA8XX_GPIO_BASE 0x01e26000 #define DA8XX_PSC1_BASE 0x01e27000 + +#define DA8XX_DSP_L2_RAM_BASE 0x11800000 +#define DA8XX_DSP_L1P_RAM_BASE (DA8XX_DSP_L2_RAM_BASE + 0x600000) +#define DA8XX_DSP_L1D_RAM_BASE (DA8XX_DSP_L2_RAM_BASE + 0x700000) + #define DA8XX_AEMIF_CS2_BASE 0x60000000 #define DA8XX_AEMIF_CS3_BASE 0x62000000 #define DA8XX_AEMIF_CTL_BASE 0x68000000 -- cgit From 44fc41f92694241917a1590eb03081a68a38f480 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 24 May 2017 17:58:34 +0200 Subject: ARM: s3c64xx: Do not select ARM_AMBA from S3C64XX_PL080 While trying a fix a build warning unrelated to s3c64xx, I ran into a circular dependency: drivers/i2c/Kconfig:7: symbol I2C is selected by FB_DDC drivers/video/fbdev/Kconfig:63: symbol FB_DDC is selected by FB_CYBER2000_DDC drivers/video/fbdev/Kconfig:381: symbol FB_CYBER2000_DDC depends on FB_CYBER2000 drivers/video/fbdev/Kconfig:369: symbol FB_CYBER2000 depends on FB drivers/video/fbdev/Kconfig:5: symbol FB is selected by DRM_KMS_FB_HELPER drivers/gpu/drm/Kconfig:72: symbol DRM_KMS_FB_HELPER is selected by DRM_KMS_CMA_HELPER drivers/gpu/drm/Kconfig:137: symbol DRM_KMS_CMA_HELPER is selected by DRM_PL111 drivers/gpu/drm/pl111/Kconfig:1: symbol DRM_PL111 depends on ARM_AMBA drivers/amba/Kconfig:1: symbol ARM_AMBA is selected by S3C64XX_PL080 arch/arm/mach-s3c64xx/Kconfig:42: symbol S3C64XX_PL080 default value contains DMADEVICES drivers/dma/Kconfig:5: symbol DMADEVICES is selected by SND_SOC_SH4_SIU sound/soc/sh/Kconfig:29: symbol SND_SOC_SH4_SIU is selected by SND_SIU_MIGOR sound/soc/sh/Kconfig:59: symbol SND_SIU_MIGOR depends on I2C The I2C and FB dependencies are hard to untangle, but I notice that S3C64XX_PL080 selecting ARM_AMBA is one piece of the puzzle that can easily be avoided, as ARCH_S3C64XX already select ARM_AMBA. Removing the redundant 'select' now can help us in the future if we run into a variation of the same dependency. Signed-off-by: Arnd Bergmann Signed-off-by: Krzysztof Kozlowski --- arch/arm/mach-s3c64xx/Kconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/mach-s3c64xx/Kconfig b/arch/arm/mach-s3c64xx/Kconfig index 459214fa20b4..5ee5ad74a3d6 100644 --- a/arch/arm/mach-s3c64xx/Kconfig +++ b/arch/arm/mach-s3c64xx/Kconfig @@ -40,7 +40,6 @@ config CPU_S3C6410 config S3C64XX_PL080 def_bool DMADEVICES - select ARM_AMBA select AMBA_PL08X config S3C64XX_SETUP_SDHCI -- cgit From f0979987c91debc7146fbe1509c2466b44cb9796 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Wed, 31 May 2017 03:06:19 +0200 Subject: ARM: at91: Documentation: add armv7m families The Atmel sams70, samv70 and samv71 are Cortex-M7 based MCUs that can run Linux (without MMU). Acked-by: Nicolas Ferre Signed-off-by: Alexandre Belloni --- Documentation/arm/Atmel/README | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/Documentation/arm/Atmel/README b/Documentation/arm/Atmel/README index 6ca78f818dbf..afb13c15389d 100644 --- a/Documentation/arm/Atmel/README +++ b/Documentation/arm/Atmel/README @@ -16,7 +16,7 @@ git branches/tags and email subject always contain this "at91" sub-string. AT91 SoCs --------- -Documentation and detailled datasheet for each product are available on +Documentation and detailed datasheet for each product are available on the Atmel website: http://www.atmel.com. Flavors: @@ -101,6 +101,42 @@ the Atmel website: http://www.atmel.com. + Datasheet http://www.atmel.com/Images/Atmel-11267-32-bit-Cortex-A5-Microcontroller-SAMA5D2_Datasheet.pdf + * ARM Cortex-M7 MCUs + - sams70 family + - sams70j19 + - sams70j20 + - sams70j21 + - sams70n19 + - sams70n20 + - sams70n21 + - sams70q19 + - sams70q20 + - sams70q21 + + Datasheet + http://www.atmel.com/Images/Atmel-11242-32-bit-Cortex-M7-Microcontroller-SAM-S70Q-SAM-S70N-SAM-S70J_Datasheet.pdf + + - samv70 family + - samv70j19 + - samv70j20 + - samv70n19 + - samv70n20 + - samv70q19 + - samv70q20 + + Datasheet + http://www.atmel.com/Images/Atmel-11297-32-bit-Cortex-M7-Microcontroller-SAM-V70Q-SAM-V70N-SAM-V70J_Datasheet.pdf + + - samv71 family + - samv71j19 + - samv71j20 + - samv71j21 + - samv71n19 + - samv71n20 + - samv71n21 + - samv71q19 + - samv71q20 + - samv71q21 + + Datasheet + http://www.atmel.com/Images/Atmel-44003-32-bit-Cortex-M7-Microcontroller-SAM-V71Q-SAM-V71N-SAM-V71J_Datasheet.pdf Linux kernel information ------------------------ -- cgit From 8a9d600a8e119373fe17555219948d8d235a62d5 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Wed, 31 May 2017 03:06:20 +0200 Subject: ARM: at91: Document armv7m compatibles Introduce necessary compatibles to describe the armv7m based SoCs. Acked-by: Nicolas Ferre Signed-off-by: Alexandre Belloni --- .../devicetree/bindings/arm/atmel-at91.txt | 30 ++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/Documentation/devicetree/bindings/arm/atmel-at91.txt b/Documentation/devicetree/bindings/arm/atmel-at91.txt index 799af90dd75b..91cb8e4f2a4f 100644 --- a/Documentation/devicetree/bindings/arm/atmel-at91.txt +++ b/Documentation/devicetree/bindings/arm/atmel-at91.txt @@ -41,6 +41,36 @@ compatible: must be one of: - "atmel,sama5d43" - "atmel,sama5d44" + * "atmel,samv7" for MCUs using a Cortex-M7, shall be extended with the specific + SoC family: + o "atmel,sams70" shall be extended with the specific MCU compatible: + - "atmel,sams70j19" + - "atmel,sams70j20" + - "atmel,sams70j21" + - "atmel,sams70n19" + - "atmel,sams70n20" + - "atmel,sams70n21" + - "atmel,sams70q19" + - "atmel,sams70q20" + - "atmel,sams70q21" + o "atmel,samv70" shall be extended with the specific MCU compatible: + - "atmel,samv70j19" + - "atmel,samv70j20" + - "atmel,samv70n19" + - "atmel,samv70n20" + - "atmel,samv70q19" + - "atmel,samv70q20" + o "atmel,samv71" shall be extended with the specific MCU compatible: + - "atmel,samv71j19" + - "atmel,samv71j20" + - "atmel,samv71j21" + - "atmel,samv71n19" + - "atmel,samv71n20" + - "atmel,samv71n21" + - "atmel,samv71q19" + - "atmel,samv71q20" + - "atmel,samv71q21" + Chipid required properties: - compatible: Should be "atmel,sama5d2-chipid" - reg : Should contain registers location and length -- cgit From 2d4c44e979eaa846dfa63717c4f4818e11161c66 Mon Sep 17 00:00:00 2001 From: Szemző András Date: Wed, 31 May 2017 03:06:21 +0200 Subject: ARM: at91: Add armv7m support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add Atmel SAME70/SAMS70/SAMV71 SoC support. Signed-off-by: Szemző András Acked-by: Nicolas Ferre Signed-off-by: Alexandre Belloni --- arch/arm/mach-at91/Kconfig | 10 +++++++++- arch/arm/mach-at91/Makefile | 1 + arch/arm/mach-at91/Makefile.boot | 3 +++ arch/arm/mach-at91/samv7.c | 25 +++++++++++++++++++++++++ 4 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 arch/arm/mach-at91/Makefile.boot create mode 100644 arch/arm/mach-at91/samv7.c diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig index 841e924143f9..2594b6a412f0 100644 --- a/arch/arm/mach-at91/Kconfig +++ b/arch/arm/mach-at91/Kconfig @@ -1,12 +1,20 @@ menuconfig ARCH_AT91 bool "Atmel SoCs" - depends on ARCH_MULTI_V4T || ARCH_MULTI_V5 || ARCH_MULTI_V7 + depends on ARCH_MULTI_V4T || ARCH_MULTI_V5 || ARCH_MULTI_V7 || ARM_SINGLE_ARMV7M select COMMON_CLK_AT91 select GPIOLIB select PINCTRL select SOC_BUS if ARCH_AT91 +config SOC_SAMV7 + bool "SAM Cortex-M7 family" if ARM_SINGLE_ARMV7M + select COMMON_CLK_AT91 + select PINCTRL_AT91 + help + Select this if you are using an SoC from Atmel's SAME7, SAMS7 or SAMV7 + families. + config SOC_SAMA5D2 bool "SAMA5D2 family" depends on ARCH_MULTI_V7 diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile index cfd8f60a9268..a189081dccc0 100644 --- a/arch/arm/mach-at91/Makefile +++ b/arch/arm/mach-at91/Makefile @@ -6,6 +6,7 @@ obj-$(CONFIG_SOC_AT91RM9200) += at91rm9200.o obj-$(CONFIG_SOC_AT91SAM9) += at91sam9.o obj-$(CONFIG_SOC_SAMA5) += sama5.o +obj-$(CONFIG_SOC_SAMV7) += samv7.o # Power Management obj-$(CONFIG_PM) += pm.o diff --git a/arch/arm/mach-at91/Makefile.boot b/arch/arm/mach-at91/Makefile.boot new file mode 100644 index 000000000000..eacfc3f5c33e --- /dev/null +++ b/arch/arm/mach-at91/Makefile.boot @@ -0,0 +1,3 @@ +# Empty file waiting for deletion once Makefile.boot isn't needed any more. +# Patch waits for application at +# http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=7889/1 . diff --git a/arch/arm/mach-at91/samv7.c b/arch/arm/mach-at91/samv7.c new file mode 100644 index 000000000000..11386f190c83 --- /dev/null +++ b/arch/arm/mach-at91/samv7.c @@ -0,0 +1,25 @@ +/* + * Setup code for SAMv7x + * + * Copyright (C) 2013 Atmel, + * 2016 Andras Szemzo + * + * Licensed under GPLv2 or later. + */ +#include +#include +#include +#include +#include +#include +#include +#include "generic.h" + +static const char *const samv7_dt_board_compat[] __initconst = { + "atmel,samv7", + NULL +}; + +DT_MACHINE_START(samv7_dt, "Atmel SAMV7") + .dt_compat = samv7_dt_board_compat, +MACHINE_END -- cgit From b2f06274337074a64ad42550f336b9f279eb835a Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Wed, 31 May 2017 03:06:22 +0200 Subject: ARM: at91: handle CONFIG_PM for armv7m configurations There is currently no PM support for samx7 but the symbol can still be selected. This avoids compilation issues. Acked-by: Nicolas Ferre Signed-off-by: Alexandre Belloni --- arch/arm/mach-at91/Kconfig | 6 ++++++ arch/arm/mach-at91/Makefile | 3 +-- arch/arm/mach-at91/samv7.c | 9 +++++++++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig index 2594b6a412f0..7497a28a79d1 100644 --- a/arch/arm/mach-at91/Kconfig +++ b/arch/arm/mach-at91/Kconfig @@ -60,6 +60,7 @@ config SOC_AT91RM9200 bool "AT91RM9200" depends on ARCH_MULTI_V4T select ATMEL_AIC_IRQ + select ATMEL_PM if PM select ATMEL_ST select CPU_ARM920T select HAVE_AT91_USB_CLK @@ -73,6 +74,7 @@ config SOC_AT91SAM9 bool "AT91SAM9" depends on ARCH_MULTI_V5 select ATMEL_AIC_IRQ + select ATMEL_PM if PM select ATMEL_SDRAMC select CPU_ARM926T select HAVE_AT91_SMD @@ -131,9 +133,13 @@ config SOC_SAM_V7 config SOC_SAMA5 bool select ATMEL_AIC5_IRQ + select ATMEL_PM if PM select ATMEL_SDRAMC select MEMORY select SOC_SAM_V7 select SRAM if PM +config ATMEL_PM + bool + endif diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile index a189081dccc0..ee34aa34cc51 100644 --- a/arch/arm/mach-at91/Makefile +++ b/arch/arm/mach-at91/Makefile @@ -9,8 +9,7 @@ obj-$(CONFIG_SOC_SAMA5) += sama5.o obj-$(CONFIG_SOC_SAMV7) += samv7.o # Power Management -obj-$(CONFIG_PM) += pm.o -obj-$(CONFIG_PM) += pm_suspend.o +obj-$(CONFIG_ATMEL_PM) += pm.o pm_suspend.o ifeq ($(CONFIG_CPU_V7),y) AFLAGS_pm_suspend.o := -march=armv7-a diff --git a/arch/arm/mach-at91/samv7.c b/arch/arm/mach-at91/samv7.c index 11386f190c83..910f0c68db62 100644 --- a/arch/arm/mach-at91/samv7.c +++ b/arch/arm/mach-at91/samv7.c @@ -15,6 +15,15 @@ #include #include "generic.h" +#ifdef CONFIG_PM +/* This function has to be defined for various drivers that are using it */ +int at91_suspend_entering_slow_clock(void) +{ + return 0; +} +EXPORT_SYMBOL(at91_suspend_entering_slow_clock); +#endif + static const char *const samv7_dt_board_compat[] __initconst = { "atmel,samv7", NULL -- cgit From 82208e7568c29aa687fd93b6702106b21a780b5b Mon Sep 17 00:00:00 2001 From: Szemző András Date: Wed, 31 May 2017 03:06:23 +0200 Subject: ARM: at91: add armv7m SoC detection MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add SAME70/V71/S70/V70 chip-ids to SoC detection. Signed-off-by: Szemző András Acked-by: Nicolas Ferre Signed-off-by: Alexandre Belloni --- drivers/soc/atmel/soc.c | 24 ++++++++++++++++++++++++ drivers/soc/atmel/soc.h | 26 ++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/drivers/soc/atmel/soc.c b/drivers/soc/atmel/soc.c index 4790094b498e..c1363c83c352 100644 --- a/drivers/soc/atmel/soc.c +++ b/drivers/soc/atmel/soc.c @@ -106,6 +106,30 @@ static const struct at91_soc __initconst socs[] = { "sama5d43", "sama5d4"), AT91_SOC(SAMA5D4_CIDR_MATCH, SAMA5D44_EXID_MATCH, "sama5d44", "sama5d4"), +#endif +#ifdef CONFIG_SOC_SAMV7 + AT91_SOC(SAME70Q21_CIDR_MATCH, SAME70Q21_EXID_MATCH, + "same70q21", "same7"), + AT91_SOC(SAME70Q20_CIDR_MATCH, SAME70Q20_EXID_MATCH, + "same70q20", "same7"), + AT91_SOC(SAME70Q19_CIDR_MATCH, SAME70Q19_EXID_MATCH, + "same70q19", "same7"), + AT91_SOC(SAMS70Q21_CIDR_MATCH, SAMS70Q21_EXID_MATCH, + "sams70q21", "sams7"), + AT91_SOC(SAMS70Q20_CIDR_MATCH, SAMS70Q20_EXID_MATCH, + "sams70q20", "sams7"), + AT91_SOC(SAMS70Q19_CIDR_MATCH, SAMS70Q19_EXID_MATCH, + "sams70q19", "sams7"), + AT91_SOC(SAMV71Q21_CIDR_MATCH, SAMV71Q21_EXID_MATCH, + "samv71q21", "samv7"), + AT91_SOC(SAMV71Q20_CIDR_MATCH, SAMV71Q20_EXID_MATCH, + "samv71q20", "samv7"), + AT91_SOC(SAMV71Q19_CIDR_MATCH, SAMV71Q19_EXID_MATCH, + "samv71q19", "samv7"), + AT91_SOC(SAMV70Q20_CIDR_MATCH, SAMV70Q20_EXID_MATCH, + "samv70q20", "samv7"), + AT91_SOC(SAMV70Q19_CIDR_MATCH, SAMV70Q19_EXID_MATCH, + "samv70q19", "samv7"), #endif { /* sentinel */ }, }; diff --git a/drivers/soc/atmel/soc.h b/drivers/soc/atmel/soc.h index 228efded5085..a90bd5b0ef8f 100644 --- a/drivers/soc/atmel/soc.h +++ b/drivers/soc/atmel/soc.h @@ -88,4 +88,30 @@ at91_soc_init(const struct at91_soc *socs); #define SAMA5D43_EXID_MATCH 0x00000003 #define SAMA5D44_EXID_MATCH 0x00000004 +#define SAME70Q21_CIDR_MATCH 0x21020e00 +#define SAME70Q21_EXID_MATCH 0x00000002 +#define SAME70Q20_CIDR_MATCH 0x21020c00 +#define SAME70Q20_EXID_MATCH 0x00000002 +#define SAME70Q19_CIDR_MATCH 0x210d0a00 +#define SAME70Q19_EXID_MATCH 0x00000002 + +#define SAMS70Q21_CIDR_MATCH 0x21120e00 +#define SAMS70Q21_EXID_MATCH 0x00000002 +#define SAMS70Q20_CIDR_MATCH 0x21120c00 +#define SAMS70Q20_EXID_MATCH 0x00000002 +#define SAMS70Q19_CIDR_MATCH 0x211d0a00 +#define SAMS70Q19_EXID_MATCH 0x00000002 + +#define SAMV71Q21_CIDR_MATCH 0x21220e00 +#define SAMV71Q21_EXID_MATCH 0x00000002 +#define SAMV71Q20_CIDR_MATCH 0x21220c00 +#define SAMV71Q20_EXID_MATCH 0x00000002 +#define SAMV71Q19_CIDR_MATCH 0x212d0a00 +#define SAMV71Q19_EXID_MATCH 0x00000002 + +#define SAMV70Q20_CIDR_MATCH 0x21320c00 +#define SAMV70Q20_EXID_MATCH 0x00000002 +#define SAMV70Q19_CIDR_MATCH 0x213d0a00 +#define SAMV70Q19_EXID_MATCH 0x00000002 + #endif /* __AT91_SOC_H */ -- cgit From 63e07c0fdc41d7d585dad72ed01856c68ce52bbe Mon Sep 17 00:00:00 2001 From: Szemző András Date: Wed, 31 May 2017 03:06:24 +0200 Subject: ARM: at91: debug: add samv7x support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add support for low level debugging on Atmel samv7x. Signed-off-by: Szemző András Acked-by: Nicolas Ferre Signed-off-by: Alexandre Belloni --- arch/arm/Kconfig.debug | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index 426d2716f55d..e10fb1842b1d 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug @@ -145,6 +145,15 @@ choice Say Y here if you want kernel low-level debugging support on the USART3 port of sama5d4. + config DEBUG_AT91_SAMV7_USART1 + bool "Kernel low-level debugging via SAMV7 USART1" + select DEBUG_AT91_UART + depends on SOC_SAMV7 + help + Say Y here if you want the debug print routines to direct + their output to the USART1 port on SAMV7 based + machines. + config DEBUG_BCM2835 bool "Kernel low-level debugging on BCM2835 PL011 UART" depends on ARCH_BCM2835 && ARCH_MULTI_V6 @@ -1481,6 +1490,7 @@ config DEBUG_UART_PHYS default 0x3f201000 if DEBUG_BCM2836 default 0x3e000000 if DEBUG_BCM_KONA_UART default 0x4000e400 if DEBUG_LL_UART_EFM32 + default 0x40028000 if DEBUG_AT91_SAMV7_USART1 default 0x40081000 if DEBUG_LPC18XX_UART0 default 0x40090000 if DEBUG_LPC32XX default 0x40100000 if DEBUG_PXA_UART1 -- cgit From 7b87fe94299c965adcab384486ee3bf82ad15f9c Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Tue, 28 Mar 2017 01:11:40 +0200 Subject: ARM: debug: qcom: add UART addresses to Kconfig help for IPQ4019 Add information about the IPQ4019 debug UART physical and virtual addresses in the DEBUG_QCOM_UARTDM Kconfig help section. Signed-off-by: Christian Lamparter Signed-off-by: Andy Gross --- arch/arm/Kconfig.debug | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index 426d2716f55d..0e5c1f9c546a 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug @@ -751,6 +751,7 @@ choice ARCH DEBUG_UART_PHYS DEBUG_UART_VIRT APQ8064 0x16640000 0xf0040000 APQ8084 0xf995e000 0xfa75e000 + IPQ4019 0x078af000 0xf78af000 MSM8X60 0x19c40000 0xf0040000 MSM8960 0x16440000 0xf0040000 MSM8974 0xf991e000 0xfa71e000 -- cgit From 8d39ff3d1696f7c6122500e21016f6837984ad8b Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Wed, 31 May 2017 15:51:30 -0700 Subject: ARM: OMAP2+: Remove unused legacy code for timer We are now booting all mach-omap2 in device tree only mode. Any code that is only called in legacy boot mode where of_have_populated_dt() is not set is safe to remove now. Reviewed-by: Sebastian Reichel Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/timer.c | 169 +++++--------------------------------------- 1 file changed, 19 insertions(+), 150 deletions(-) diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c index 07dd692c4737..e4be76016939 100644 --- a/arch/arm/mach-omap2/timer.c +++ b/arch/arm/mach-omap2/timer.c @@ -232,37 +232,27 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer, const char **timer_name, int posted) { - char name[10]; /* 10 = sizeof("gptXX_Xck0") */ const char *oh_name = NULL; struct device_node *np; struct omap_hwmod *oh; - struct resource irq, mem; struct clk *src; int r = 0; - if (of_have_populated_dt()) { - np = omap_get_timer_dt(omap_timer_match, property); - if (!np) - return -ENODEV; + np = omap_get_timer_dt(omap_timer_match, property); + if (!np) + return -ENODEV; - of_property_read_string_index(np, "ti,hwmods", 0, &oh_name); - if (!oh_name) - return -ENODEV; + of_property_read_string_index(np, "ti,hwmods", 0, &oh_name); + if (!oh_name) + return -ENODEV; - timer->irq = irq_of_parse_and_map(np, 0); - if (!timer->irq) - return -ENXIO; + timer->irq = irq_of_parse_and_map(np, 0); + if (!timer->irq) + return -ENXIO; - timer->io_base = of_iomap(np, 0); + timer->io_base = of_iomap(np, 0); - of_node_put(np); - } else { - if (omap_dm_timer_reserve_systimer(timer->id)) - return -ENODEV; - - sprintf(name, "timer%d", timer->id); - oh_name = name; - } + of_node_put(np); oh = omap_hwmod_lookup(oh_name); if (!oh) @@ -270,22 +260,6 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer, *timer_name = oh->name; - if (!of_have_populated_dt()) { - r = omap_hwmod_get_resource_byname(oh, IORESOURCE_IRQ, NULL, - &irq); - if (r) - return -ENXIO; - timer->irq = irq.start; - - r = omap_hwmod_get_resource_byname(oh, IORESOURCE_MEM, NULL, - &mem); - if (r) - return -ENXIO; - - /* Static mapping, never released */ - timer->io_base = ioremap(mem.start, mem.end - mem.start); - } - if (!timer->io_base) return -ENXIO; @@ -405,18 +379,15 @@ static int __init __maybe_unused omap2_sync32k_clocksource_init(void) const char *oh_name = "counter_32k"; /* - * If device-tree is present, then search the DT blob - * to see if the 32kHz counter is supported. + * See if the 32kHz counter is supported. */ - if (of_have_populated_dt()) { - np = omap_get_timer_dt(omap_counter_match, NULL); - if (!np) - return -ENODEV; - - of_property_read_string_index(np, "ti,hwmods", 0, &oh_name); - if (!oh_name) - return -ENODEV; - } + np = omap_get_timer_dt(omap_counter_match, NULL); + if (!np) + return -ENODEV; + + of_property_read_string_index(np, "ti,hwmods", 0, &oh_name); + if (!oh_name) + return -ENODEV; /* * First check hwmod data is available for sync32k counter @@ -434,18 +405,6 @@ static int __init __maybe_unused omap2_sync32k_clocksource_init(void) return ret; } - if (!of_have_populated_dt()) { - void __iomem *vbase; - - vbase = omap_hwmod_get_mpu_rt_va(oh); - - ret = omap_init_clocksource_32k(vbase); - if (ret) { - pr_warn("%s: failed to initialize counter_32k as a clocksource (%d)\n", - __func__, ret); - omap_hwmod_idle(oh); - } - } return ret; } @@ -660,96 +619,6 @@ void __init omap5_realtime_timer_init(void) } #endif /* CONFIG_SOC_OMAP5 || CONFIG_SOC_DRA7XX */ -/** - * omap_timer_init - build and register timer device with an - * associated timer hwmod - * @oh: timer hwmod pointer to be used to build timer device - * @user: parameter that can be passed from calling hwmod API - * - * Called by omap_hwmod_for_each_by_class to register each of the timer - * devices present in the system. The number of timer devices is known - * by parsing through the hwmod database for a given class name. At the - * end of function call memory is allocated for timer device and it is - * registered to the framework ready to be proved by the driver. - */ -static int __init omap_timer_init(struct omap_hwmod *oh, void *unused) -{ - int id; - int ret = 0; - char *name = "omap_timer"; - struct dmtimer_platform_data *pdata; - struct platform_device *pdev; - struct omap_timer_capability_dev_attr *timer_dev_attr; - - pr_debug("%s: %s\n", __func__, oh->name); - - /* on secure device, do not register secure timer */ - timer_dev_attr = oh->dev_attr; - if (omap_type() != OMAP2_DEVICE_TYPE_GP && timer_dev_attr) - if (timer_dev_attr->timer_capability == OMAP_TIMER_SECURE) - return ret; - - pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); - if (!pdata) { - pr_err("%s: No memory for [%s]\n", __func__, oh->name); - return -ENOMEM; - } - - /* - * Extract the IDs from name field in hwmod database - * and use the same for constructing ids' for the - * timer devices. In a way, we are avoiding usage of - * static variable witin the function to do the same. - * CAUTION: We have to be careful and make sure the - * name in hwmod database does not change in which case - * we might either make corresponding change here or - * switch back static variable mechanism. - */ - sscanf(oh->name, "timer%2d", &id); - - if (timer_dev_attr) - pdata->timer_capability = timer_dev_attr->timer_capability; - - pdata->timer_errata = omap_dm_timer_get_errata(); - pdata->get_context_loss_count = omap_pm_get_dev_context_loss_count; - - pdev = omap_device_build(name, id, oh, pdata, sizeof(*pdata)); - - if (IS_ERR(pdev)) { - pr_err("%s: Can't build omap_device for %s: %s.\n", - __func__, name, oh->name); - ret = -EINVAL; - } - - kfree(pdata); - - return ret; -} - -/** - * omap2_dm_timer_init - top level regular device initialization - * - * Uses dedicated hwmod api to parse through hwmod database for - * given class name and then build and register the timer device. - */ -static int __init omap2_dm_timer_init(void) -{ - int ret; - - /* If dtb is there, the devices will be created dynamically */ - if (of_have_populated_dt()) - return -ENODEV; - - ret = omap_hwmod_for_each_by_class("timer", omap_timer_init, NULL); - if (unlikely(ret)) { - pr_err("%s: device registration failed.\n", __func__); - return -EINVAL; - } - - return 0; -} -omap_arch_initcall(omap2_dm_timer_init); - /** * omap2_override_clocksource - clocksource override with user configuration * -- cgit From 138f7ca78f5a0677f591fdf23d0309c2f4774bf7 Mon Sep 17 00:00:00 2001 From: Tero Kristo Date: Wed, 31 May 2017 17:59:58 +0300 Subject: ARM: OMAP2+: timer: add support for fetching fck handle from DT The mux clock handle shall be provided via "fck" DT handle. This avoids the need to lookup the main clock via hwmod core, which will not work with the clkctrl clock support anymore; the main clock is not going to be a mux. Signed-off-by: Tero Kristo Acked-by: Tony Lindgren Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/timer.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c index 07dd692c4737..af90f95c2433 100644 --- a/arch/arm/mach-omap2/timer.c +++ b/arch/arm/mach-omap2/timer.c @@ -255,6 +255,8 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer, timer->io_base = of_iomap(np, 0); + timer->fclk = of_clk_get_by_name(np, "fck"); + of_node_put(np); } else { if (omap_dm_timer_reserve_systimer(timer->id)) @@ -292,7 +294,8 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer, omap_hwmod_setup_one(oh_name); /* After the dmtimer is using hwmod these clocks won't be needed */ - timer->fclk = clk_get(NULL, omap_hwmod_get_main_clk(oh)); + if (IS_ERR_OR_NULL(timer->fclk)) + timer->fclk = clk_get(NULL, omap_hwmod_get_main_clk(oh)); if (IS_ERR(timer->fclk)) return PTR_ERR(timer->fclk); -- cgit From 24d8d498a8703462f0141f2fcdcd325de1ab2bb8 Mon Sep 17 00:00:00 2001 From: Tero Kristo Date: Wed, 31 May 2017 17:59:59 +0300 Subject: ARM: OMAP4: hwmod_data: add opt clks for dss_hdmi and dss_venc These extra optional clocks are required as main clock for these modules are going to be routed to the main module clock. Otherwise, the hdmi / tv clocks are not going to be enabled during usage, leading to failure. Signed-off-by: Tero Kristo Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index 94f09c720f29..0855434773fa 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -775,6 +775,7 @@ static struct omap_hwmod_dma_info omap44xx_dss_hdmi_sdma_reqs[] = { static struct omap_hwmod_opt_clk dss_hdmi_opt_clks[] = { { .role = "sys_clk", .clk = "dss_sys_clk" }, + { .role = "hdmi_clk", .clk = "dss_48mhz_clk" }, }; static struct omap_hwmod omap44xx_dss_hdmi_hwmod = { @@ -785,7 +786,7 @@ static struct omap_hwmod omap44xx_dss_hdmi_hwmod = { * HDMI audio requires to use no-idle mode. Hence, * set idle mode by software. */ - .flags = HWMOD_SWSUP_SIDLE, + .flags = HWMOD_SWSUP_SIDLE | HWMOD_OPT_CLKS_NEEDED, .mpu_irqs = omap44xx_dss_hdmi_irqs, .xlate_irq = omap4_xlate_irq, .sdma_reqs = omap44xx_dss_hdmi_sdma_reqs, @@ -858,11 +859,16 @@ static struct omap_hwmod_class omap44xx_venc_hwmod_class = { }; /* dss_venc */ +static struct omap_hwmod_opt_clk dss_venc_opt_clks[] = { + { .role = "tv_clk", .clk = "dss_tv_clk" }, +}; + static struct omap_hwmod omap44xx_dss_venc_hwmod = { .name = "dss_venc", .class = &omap44xx_venc_hwmod_class, .clkdm_name = "l3_dss_clkdm", .main_clk = "dss_tv_clk", + .flags = HWMOD_OPT_CLKS_NEEDED, .prcm = { .omap4 = { .clkctrl_offs = OMAP4_CM_DSS_DSS_CLKCTRL_OFFSET, @@ -870,6 +876,8 @@ static struct omap_hwmod omap44xx_dss_venc_hwmod = { }, }, .parent_hwmod = &omap44xx_dss_hwmod, + .opt_clks = dss_venc_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(dss_venc_opt_clks), }; /* -- cgit From 90129336712c3c8dcd0d81a5dfaea52dd8391e62 Mon Sep 17 00:00:00 2001 From: Tero Kristo Date: Wed, 31 May 2017 18:00:00 +0300 Subject: ARM: OMAP2+: PRCM: store also physical addresses for instances In some cases the physical address info is needed, so store this under the existing cm*_base, prm_base and prcm_mpu_base variables. These are converted now to structs that contain both virtual and physical address base for the instance. Signed-off-by: Tero Kristo Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/cm.h | 7 +++++-- arch/arm/mach-omap2/cm2xxx_3xxx.h | 4 ++-- arch/arm/mach-omap2/cm33xx.c | 4 ++-- arch/arm/mach-omap2/cm3xxx.c | 3 ++- arch/arm/mach-omap2/cm_common.c | 31 +++++++++++++++++++------------ arch/arm/mach-omap2/cminst44xx.c | 19 ++++++++++--------- arch/arm/mach-omap2/prcm-common.h | 7 +++++++ arch/arm/mach-omap2/prcm_mpu44xx.c | 4 ++-- arch/arm/mach-omap2/prcm_mpu_44xx_54xx.h | 4 +++- arch/arm/mach-omap2/prm.h | 2 +- arch/arm/mach-omap2/prm2xxx_3xxx.h | 4 ++-- arch/arm/mach-omap2/prm33xx.c | 4 ++-- arch/arm/mach-omap2/prm3xxx.c | 2 +- arch/arm/mach-omap2/prm44xx.c | 4 ++-- arch/arm/mach-omap2/prm_common.c | 23 +++++++++++++---------- arch/arm/mach-omap2/prminst44xx.c | 16 +++++++++------- 16 files changed, 82 insertions(+), 56 deletions(-) diff --git a/arch/arm/mach-omap2/cm.h b/arch/arm/mach-omap2/cm.h index de75cbcdc9d1..e833984cc85e 100644 --- a/arch/arm/mach-omap2/cm.h +++ b/arch/arm/mach-omap2/cm.h @@ -24,8 +24,11 @@ # ifndef __ASSEMBLER__ #include -extern void __iomem *cm_base; -extern void __iomem *cm2_base; + +#include "prcm-common.h" + +extern struct omap_domain_base cm_base; +extern struct omap_domain_base cm2_base; extern void omap2_set_globals_cm(void __iomem *cm, void __iomem *cm2); # endif diff --git a/arch/arm/mach-omap2/cm2xxx_3xxx.h b/arch/arm/mach-omap2/cm2xxx_3xxx.h index 72928a3ce2aa..aa148cd57cc1 100644 --- a/arch/arm/mach-omap2/cm2xxx_3xxx.h +++ b/arch/arm/mach-omap2/cm2xxx_3xxx.h @@ -52,12 +52,12 @@ static inline u32 omap2_cm_read_mod_reg(s16 module, u16 idx) { - return readl_relaxed(cm_base + module + idx); + return readl_relaxed(cm_base.va + module + idx); } static inline void omap2_cm_write_mod_reg(u32 val, s16 module, u16 idx) { - writel_relaxed(val, cm_base + module + idx); + writel_relaxed(val, cm_base.va + module + idx); } /* Read-modify-write a register in a CM module. Caller must lock */ diff --git a/arch/arm/mach-omap2/cm33xx.c b/arch/arm/mach-omap2/cm33xx.c index 6f2d0aec0513..a9e08d89104e 100644 --- a/arch/arm/mach-omap2/cm33xx.c +++ b/arch/arm/mach-omap2/cm33xx.c @@ -50,13 +50,13 @@ /* Read a register in a CM instance */ static inline u32 am33xx_cm_read_reg(u16 inst, u16 idx) { - return readl_relaxed(cm_base + inst + idx); + return readl_relaxed(cm_base.va + inst + idx); } /* Write into a register in a CM */ static inline void am33xx_cm_write_reg(u32 val, u16 inst, u16 idx) { - writel_relaxed(val, cm_base + inst + idx); + writel_relaxed(val, cm_base.va + inst + idx); } /* Read-modify-write a register in CM */ diff --git a/arch/arm/mach-omap2/cm3xxx.c b/arch/arm/mach-omap2/cm3xxx.c index 55b046a719dc..961bc478b9de 100644 --- a/arch/arm/mach-omap2/cm3xxx.c +++ b/arch/arm/mach-omap2/cm3xxx.c @@ -669,7 +669,8 @@ static struct cm_ll_data omap3xxx_cm_ll_data = { int __init omap3xxx_cm_init(const struct omap_prcm_init_data *data) { - omap2_clk_legacy_provider_init(TI_CLKM_CM, cm_base + OMAP3430_IVA2_MOD); + omap2_clk_legacy_provider_init(TI_CLKM_CM, cm_base.va + + OMAP3430_IVA2_MOD); return cm_register(&omap3xxx_cm_ll_data); } diff --git a/arch/arm/mach-omap2/cm_common.c b/arch/arm/mach-omap2/cm_common.c index bbe41f4c9dc8..d555791cf349 100644 --- a/arch/arm/mach-omap2/cm_common.c +++ b/arch/arm/mach-omap2/cm_common.c @@ -32,10 +32,10 @@ static struct cm_ll_data null_cm_ll_data; static struct cm_ll_data *cm_ll_data = &null_cm_ll_data; /* cm_base: base virtual address of the CM IP block */ -void __iomem *cm_base; +struct omap_domain_base cm_base; /* cm2_base: base virtual address of the CM2 IP block (OMAP44xx only) */ -void __iomem *cm2_base; +struct omap_domain_base cm2_base; #define CM_NO_CLOCKS 0x1 #define CM_SINGLE_INSTANCE 0x2 @@ -49,8 +49,8 @@ void __iomem *cm2_base; */ void __init omap2_set_globals_cm(void __iomem *cm, void __iomem *cm2) { - cm_base = cm; - cm2_base = cm2; + cm_base.va = cm; + cm2_base.va = cm2; } /** @@ -315,27 +315,34 @@ int __init omap2_cm_base_init(void) struct device_node *np; const struct of_device_id *match; struct omap_prcm_init_data *data; - void __iomem *mem; + struct resource res; + int ret; + struct omap_domain_base *mem = NULL; for_each_matching_node_and_match(np, omap_cm_dt_match_table, &match) { data = (struct omap_prcm_init_data *)match->data; - mem = of_iomap(np, 0); - if (!mem) - return -ENOMEM; + ret = of_address_to_resource(np, 0, &res); + if (ret) + return ret; if (data->index == TI_CLKM_CM) - cm_base = mem + data->offset; + mem = &cm_base; if (data->index == TI_CLKM_CM2) - cm2_base = mem + data->offset; + mem = &cm2_base; + + data->mem = ioremap(res.start, resource_size(&res)); - data->mem = mem; + if (mem) { + mem->pa = res.start + data->offset; + mem->va = data->mem + data->offset; + } data->np = np; if (data->init && (data->flags & CM_SINGLE_INSTANCE || - (cm_base && cm2_base))) + (cm_base.va && cm2_base.va))) data->init(data); } diff --git a/arch/arm/mach-omap2/cminst44xx.c b/arch/arm/mach-omap2/cminst44xx.c index 2ab27ade136a..cfa10a31b953 100644 --- a/arch/arm/mach-omap2/cminst44xx.c +++ b/arch/arm/mach-omap2/cminst44xx.c @@ -55,7 +55,7 @@ #define CLKCTRL_IDLEST_INTERFACE_IDLE 0x2 #define CLKCTRL_IDLEST_DISABLED 0x3 -static void __iomem *_cm_bases[OMAP4_MAX_PRCM_PARTITIONS]; +static struct omap_domain_base _cm_bases[OMAP4_MAX_PRCM_PARTITIONS]; /** * omap_cm_base_init - Populates the cm partitions @@ -65,10 +65,11 @@ static void __iomem *_cm_bases[OMAP4_MAX_PRCM_PARTITIONS]; */ static void omap_cm_base_init(void) { - _cm_bases[OMAP4430_PRM_PARTITION] = prm_base; - _cm_bases[OMAP4430_CM1_PARTITION] = cm_base; - _cm_bases[OMAP4430_CM2_PARTITION] = cm2_base; - _cm_bases[OMAP4430_PRCM_MPU_PARTITION] = prcm_mpu_base; + memcpy(&_cm_bases[OMAP4430_PRM_PARTITION], &prm_base, sizeof(prm_base)); + memcpy(&_cm_bases[OMAP4430_CM1_PARTITION], &cm_base, sizeof(cm_base)); + memcpy(&_cm_bases[OMAP4430_CM2_PARTITION], &cm2_base, sizeof(cm2_base)); + memcpy(&_cm_bases[OMAP4430_PRCM_MPU_PARTITION], &prcm_mpu_base, + sizeof(prcm_mpu_base)); } /* Private functions */ @@ -116,8 +117,8 @@ static u32 omap4_cminst_read_inst_reg(u8 part, u16 inst, u16 idx) { BUG_ON(part >= OMAP4_MAX_PRCM_PARTITIONS || part == OMAP4430_INVALID_PRCM_PARTITION || - !_cm_bases[part]); - return readl_relaxed(_cm_bases[part] + inst + idx); + !_cm_bases[part].va); + return readl_relaxed(_cm_bases[part].va + inst + idx); } /* Write into a register in a CM instance */ @@ -125,8 +126,8 @@ static void omap4_cminst_write_inst_reg(u32 val, u8 part, u16 inst, u16 idx) { BUG_ON(part >= OMAP4_MAX_PRCM_PARTITIONS || part == OMAP4430_INVALID_PRCM_PARTITION || - !_cm_bases[part]); - writel_relaxed(val, _cm_bases[part] + inst + idx); + !_cm_bases[part].va); + writel_relaxed(val, _cm_bases[part].va + inst + idx); } /* Read-modify-write a register in CM1. Caller must lock */ diff --git a/arch/arm/mach-omap2/prcm-common.h b/arch/arm/mach-omap2/prcm-common.h index c8f590b7c32d..ee7041d523cf 100644 --- a/arch/arm/mach-omap2/prcm-common.h +++ b/arch/arm/mach-omap2/prcm-common.h @@ -526,10 +526,16 @@ struct omap_prcm_irq_setup { .priority = _priority \ } +struct omap_domain_base { + u32 pa; + void __iomem *va; +}; + /** * struct omap_prcm_init_data - PRCM driver init data * @index: clock memory mapping index to be used * @mem: IO mem pointer for this module + * @phys: IO mem physical base address for this module * @offset: module base address offset from the IO base * @flags: PRCM module init flags * @device_inst_offset: device instance offset within the module address space @@ -539,6 +545,7 @@ struct omap_prcm_irq_setup { struct omap_prcm_init_data { int index; void __iomem *mem; + u32 phys; s16 offset; u16 flags; s32 device_inst_offset; diff --git a/arch/arm/mach-omap2/prcm_mpu44xx.c b/arch/arm/mach-omap2/prcm_mpu44xx.c index cdbee6326d29..9c782f5c3f94 100644 --- a/arch/arm/mach-omap2/prcm_mpu44xx.c +++ b/arch/arm/mach-omap2/prcm_mpu44xx.c @@ -24,7 +24,7 @@ * prcm_mpu_base: the virtual address of the start of the PRCM_MPU IP * block registers */ -void __iomem *prcm_mpu_base; +struct omap_domain_base prcm_mpu_base; /* PRCM_MPU low-level functions */ @@ -58,5 +58,5 @@ u32 omap4_prcm_mpu_rmw_inst_reg_bits(u32 mask, u32 bits, s16 inst, s16 reg) */ void __init omap2_set_globals_prcm_mpu(void __iomem *prcm_mpu) { - prcm_mpu_base = prcm_mpu; + prcm_mpu_base.va = prcm_mpu; } diff --git a/arch/arm/mach-omap2/prcm_mpu_44xx_54xx.h b/arch/arm/mach-omap2/prcm_mpu_44xx_54xx.h index ca149e70bed0..f565f7f73175 100644 --- a/arch/arm/mach-omap2/prcm_mpu_44xx_54xx.h +++ b/arch/arm/mach-omap2/prcm_mpu_44xx_54xx.h @@ -24,7 +24,9 @@ #define __ARCH_ARM_MACH_OMAP2_PRCM_MPU_44XX_54XX_H #ifndef __ASSEMBLER__ -extern void __iomem *prcm_mpu_base; +#include "prcm-common.h" + +extern struct omap_domain_base prcm_mpu_base; extern u32 omap4_prcm_mpu_read_inst_reg(s16 inst, u16 idx); extern void omap4_prcm_mpu_write_inst_reg(u32 val, s16 inst, u16 idx); diff --git a/arch/arm/mach-omap2/prm.h b/arch/arm/mach-omap2/prm.h index 233bc84fbc0e..94dc3565add8 100644 --- a/arch/arm/mach-omap2/prm.h +++ b/arch/arm/mach-omap2/prm.h @@ -16,7 +16,7 @@ #include "prcm-common.h" # ifndef __ASSEMBLER__ -extern void __iomem *prm_base; +extern struct omap_domain_base prm_base; extern u16 prm_features; extern void omap2_set_globals_prm(void __iomem *prm); int omap_prcm_init(void); diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.h b/arch/arm/mach-omap2/prm2xxx_3xxx.h index f57e29b0e041..6775e10883fb 100644 --- a/arch/arm/mach-omap2/prm2xxx_3xxx.h +++ b/arch/arm/mach-omap2/prm2xxx_3xxx.h @@ -55,12 +55,12 @@ /* Power/reset management domain register get/set */ static inline u32 omap2_prm_read_mod_reg(s16 module, u16 idx) { - return readl_relaxed(prm_base + module + idx); + return readl_relaxed(prm_base.va + module + idx); } static inline void omap2_prm_write_mod_reg(u32 val, s16 module, u16 idx) { - writel_relaxed(val, prm_base + module + idx); + writel_relaxed(val, prm_base.va + module + idx); } /* Read-modify-write a register in a PRM module. Caller must lock */ diff --git a/arch/arm/mach-omap2/prm33xx.c b/arch/arm/mach-omap2/prm33xx.c index dcb5001d77da..d2c5bcabdbeb 100644 --- a/arch/arm/mach-omap2/prm33xx.c +++ b/arch/arm/mach-omap2/prm33xx.c @@ -30,13 +30,13 @@ /* Read a register in a PRM instance */ static u32 am33xx_prm_read_reg(s16 inst, u16 idx) { - return readl_relaxed(prm_base + inst + idx); + return readl_relaxed(prm_base.va + inst + idx); } /* Write into a register in a PRM instance */ static void am33xx_prm_write_reg(u32 val, s16 inst, u16 idx) { - writel_relaxed(val, prm_base + inst + idx); + writel_relaxed(val, prm_base.va + inst + idx); } /* Read-modify-write a register in PRM. Caller must lock */ diff --git a/arch/arm/mach-omap2/prm3xxx.c b/arch/arm/mach-omap2/prm3xxx.c index 718981bb80cd..50291a063aab 100644 --- a/arch/arm/mach-omap2/prm3xxx.c +++ b/arch/arm/mach-omap2/prm3xxx.c @@ -676,7 +676,7 @@ static struct prm_ll_data omap3xxx_prm_ll_data = { int __init omap3xxx_prm_init(const struct omap_prcm_init_data *data) { omap2_clk_legacy_provider_init(TI_CLKM_PRM, - prm_base + OMAP3430_IVA2_MOD); + prm_base.va + OMAP3430_IVA2_MOD); if (omap3_has_io_wakeup()) prm_features |= PRM_HAS_IO_WAKEUP; diff --git a/arch/arm/mach-omap2/prm44xx.c b/arch/arm/mach-omap2/prm44xx.c index 30768003f854..090a13173589 100644 --- a/arch/arm/mach-omap2/prm44xx.c +++ b/arch/arm/mach-omap2/prm44xx.c @@ -91,13 +91,13 @@ static struct prm_reset_src_map omap44xx_prm_reset_src_map[] = { /* Read a register in a CM/PRM instance in the PRM module */ static u32 omap4_prm_read_inst_reg(s16 inst, u16 reg) { - return readl_relaxed(prm_base + inst + reg); + return readl_relaxed(prm_base.va + inst + reg); } /* Write into a register in a CM/PRM instance in the PRM module */ static void omap4_prm_write_inst_reg(u32 val, s16 inst, u16 reg) { - writel_relaxed(val, prm_base + inst + reg); + writel_relaxed(val, prm_base.va + inst + reg); } /* Read-modify-write a register in a PRM module. Caller must lock */ diff --git a/arch/arm/mach-omap2/prm_common.c b/arch/arm/mach-omap2/prm_common.c index 2b138b65129a..ae13aa710c75 100644 --- a/arch/arm/mach-omap2/prm_common.c +++ b/arch/arm/mach-omap2/prm_common.c @@ -66,7 +66,7 @@ static struct irq_chip_generic **prcm_irq_chips; static struct omap_prcm_irq_setup *prcm_irq_setup; /* prm_base: base virtual address of the PRM IP block */ -void __iomem *prm_base; +struct omap_domain_base prm_base; u16 prm_features; @@ -325,7 +325,7 @@ int omap_prcm_register_chain_handler(struct omap_prcm_irq_setup *irq_setup) for (i = 0; i < irq_setup->nr_regs; i++) { gc = irq_alloc_generic_chip("PRCM", 1, - irq_setup->base_irq + i * 32, prm_base, + irq_setup->base_irq + i * 32, prm_base.va, handle_level_irq); if (!gc) { @@ -364,7 +364,7 @@ err: */ void __init omap2_set_globals_prm(void __iomem *prm) { - prm_base = prm; + prm_base.va = prm; } /** @@ -755,19 +755,22 @@ int __init omap2_prm_base_init(void) struct device_node *np; const struct of_device_id *match; struct omap_prcm_init_data *data; - void __iomem *mem; + struct resource res; + int ret; for_each_matching_node_and_match(np, omap_prcm_dt_match_table, &match) { data = (struct omap_prcm_init_data *)match->data; - mem = of_iomap(np, 0); - if (!mem) - return -ENOMEM; + ret = of_address_to_resource(np, 0, &res); + if (ret) + return ret; - if (data->index == TI_CLKM_PRM) - prm_base = mem + data->offset; + data->mem = ioremap(res.start, resource_size(&res)); - data->mem = mem; + if (data->index == TI_CLKM_PRM) { + prm_base.va = data->mem + data->offset; + prm_base.pa = res.start + data->offset; + } data->np = np; diff --git a/arch/arm/mach-omap2/prminst44xx.c b/arch/arm/mach-omap2/prminst44xx.c index d0b15dbafa2e..48b8127b4e99 100644 --- a/arch/arm/mach-omap2/prminst44xx.c +++ b/arch/arm/mach-omap2/prminst44xx.c @@ -29,7 +29,7 @@ #include "prcm_mpu44xx.h" #include "soc.h" -static void __iomem *_prm_bases[OMAP4_MAX_PRCM_PARTITIONS]; +static struct omap_domain_base _prm_bases[OMAP4_MAX_PRCM_PARTITIONS]; static s32 prm_dev_inst = PRM_INSTANCE_UNKNOWN; @@ -41,8 +41,10 @@ static s32 prm_dev_inst = PRM_INSTANCE_UNKNOWN; */ void omap_prm_base_init(void) { - _prm_bases[OMAP4430_PRM_PARTITION] = prm_base; - _prm_bases[OMAP4430_PRCM_MPU_PARTITION] = prcm_mpu_base; + memcpy(&_prm_bases[OMAP4430_PRM_PARTITION], &prm_base, + sizeof(prm_base)); + memcpy(&_prm_bases[OMAP4430_PRCM_MPU_PARTITION], &prcm_mpu_base, + sizeof(prcm_mpu_base)); } s32 omap4_prmst_get_prm_dev_inst(void) @@ -60,8 +62,8 @@ u32 omap4_prminst_read_inst_reg(u8 part, s16 inst, u16 idx) { BUG_ON(part >= OMAP4_MAX_PRCM_PARTITIONS || part == OMAP4430_INVALID_PRCM_PARTITION || - !_prm_bases[part]); - return readl_relaxed(_prm_bases[part] + inst + idx); + !_prm_bases[part].va); + return readl_relaxed(_prm_bases[part].va + inst + idx); } /* Write into a register in a PRM instance */ @@ -69,8 +71,8 @@ void omap4_prminst_write_inst_reg(u32 val, u8 part, s16 inst, u16 idx) { BUG_ON(part >= OMAP4_MAX_PRCM_PARTITIONS || part == OMAP4430_INVALID_PRCM_PARTITION || - !_prm_bases[part]); - writel_relaxed(val, _prm_bases[part] + inst + idx); + !_prm_bases[part].va); + writel_relaxed(val, _prm_bases[part].va + inst + idx); } /* Read-modify-write a register in PRM. Caller must lock */ -- cgit From 0bf76e00e5d8410a77b07b32ac9afea61d1e0ecd Mon Sep 17 00:00:00 2001 From: Tero Kristo Date: Wed, 31 May 2017 18:00:01 +0300 Subject: ARM: omap2+: clockdomain: add clkdm_xlate_address This new function can be used to get the physical address of a clockdomain. Required for mapping the clkctrl clocks under hwmod without modification to DT data. Signed-off-by: Tero Kristo Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/clockdomain.c | 8 ++++++++ arch/arm/mach-omap2/clockdomain.h | 2 ++ 2 files changed, 10 insertions(+) diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c index b79b1ca9aee9..518926410b62 100644 --- a/arch/arm/mach-omap2/clockdomain.c +++ b/arch/arm/mach-omap2/clockdomain.c @@ -1224,6 +1224,14 @@ ccd_exit: return 0; } +u32 clkdm_xlate_address(struct clockdomain *clkdm) +{ + if (arch_clkdm->clkdm_xlate_address) + return arch_clkdm->clkdm_xlate_address(clkdm); + + return 0; +} + /** * clkdm_hwmod_enable - add an enabled downstream hwmod to this clkdm * @clkdm: struct clockdomain * diff --git a/arch/arm/mach-omap2/clockdomain.h b/arch/arm/mach-omap2/clockdomain.h index 24667a5a9dc0..827f01e2d0af 100644 --- a/arch/arm/mach-omap2/clockdomain.h +++ b/arch/arm/mach-omap2/clockdomain.h @@ -175,6 +175,7 @@ struct clkdm_ops { void (*clkdm_deny_idle)(struct clockdomain *clkdm); int (*clkdm_clk_enable)(struct clockdomain *clkdm); int (*clkdm_clk_disable)(struct clockdomain *clkdm); + u32 (*clkdm_xlate_address)(struct clockdomain *clkdm); }; int clkdm_register_platform_funcs(struct clkdm_ops *co); @@ -213,6 +214,7 @@ int clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk); int clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk); int clkdm_hwmod_enable(struct clockdomain *clkdm, struct omap_hwmod *oh); int clkdm_hwmod_disable(struct clockdomain *clkdm, struct omap_hwmod *oh); +u32 clkdm_xlate_address(struct clockdomain *clkdm); extern void __init omap242x_clockdomains_init(void); extern void __init omap243x_clockdomains_init(void); -- cgit From 308b4e381b5849c190ca4a93388c9ccfbc525e3b Mon Sep 17 00:00:00 2001 From: Tero Kristo Date: Wed, 31 May 2017 18:00:02 +0300 Subject: ARM: OMAP4: cminst: add support for clkdm_xlate_address This function gets the physical base address of a clockdomain. Signed-off-by: Tero Kristo Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/cminst44xx.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/arch/arm/mach-omap2/cminst44xx.c b/arch/arm/mach-omap2/cminst44xx.c index cfa10a31b953..8774e983bea1 100644 --- a/arch/arm/mach-omap2/cminst44xx.c +++ b/arch/arm/mach-omap2/cminst44xx.c @@ -476,6 +476,14 @@ static int omap4_clkdm_clk_disable(struct clockdomain *clkdm) return 0; } +static u32 omap4_clkdm_xlate_address(struct clockdomain *clkdm) +{ + u32 addr = _cm_bases[clkdm->prcm_partition].pa + clkdm->cm_inst + + clkdm->clkdm_offs; + + return addr; +} + struct clkdm_ops omap4_clkdm_operations = { .clkdm_add_wkdep = omap4_clkdm_add_wkup_sleep_dep, .clkdm_del_wkdep = omap4_clkdm_del_wkup_sleep_dep, @@ -491,6 +499,7 @@ struct clkdm_ops omap4_clkdm_operations = { .clkdm_deny_idle = omap4_clkdm_deny_idle, .clkdm_clk_enable = omap4_clkdm_clk_enable, .clkdm_clk_disable = omap4_clkdm_clk_disable, + .clkdm_xlate_address = omap4_clkdm_xlate_address, }; struct clkdm_ops am43xx_clkdm_operations = { @@ -500,6 +509,7 @@ struct clkdm_ops am43xx_clkdm_operations = { .clkdm_deny_idle = omap4_clkdm_deny_idle, .clkdm_clk_enable = omap4_clkdm_clk_enable, .clkdm_clk_disable = omap4_clkdm_clk_disable, + .clkdm_xlate_address = omap4_clkdm_xlate_address, }; static struct cm_ll_data omap4xxx_cm_ll_data = { -- cgit From 70f05be3213393f20f01e4d59625df7ee49fe32f Mon Sep 17 00:00:00 2001 From: Tero Kristo Date: Wed, 31 May 2017 18:00:03 +0300 Subject: ARM: OMAP2+: hwmod: populate clkctrl clocks for hwmods if available If clkctrl clocks are available on a device, populate these automatically to replace hwmod main_clk info. First, the patch parses all "ti,clkctrl" compatible nodes and maps these against existing clockdomain data. Once done, individual hwmod init routines can search for a clkctrl clock handle based on the clockdomain info and the created mapping. This patch also drops the obsolete "_mod_ck" search as the implementation required for this was not accepted usptream. Signed-off-by: Tero Kristo Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/omap_hwmod.c | 145 +++++++++++++++++++++++++++++++++++---- 1 file changed, 130 insertions(+), 15 deletions(-) diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 8bcea0d83fa0..e1107670acb6 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -141,6 +141,7 @@ #include #include #include +#include #include @@ -181,6 +182,24 @@ */ #define MOD_CLK_MAX_NAME_LEN 32 +/** + * struct clkctrl_provider - clkctrl provider mapping data + * @addr: base address for the provider + * @offset: base offset for the provider + * @clkdm: base clockdomain for provider + * @node: device node associated with the provider + * @link: list link + */ +struct clkctrl_provider { + u32 addr; + u16 offset; + struct clockdomain *clkdm; + struct device_node *node; + struct list_head link; +}; + +static LIST_HEAD(clkctrl_providers); + /** * struct omap_hwmod_soc_ops - fn ptrs for some SoC-specific operations * @enable_module: function to enable a module (via MODULEMODE) @@ -204,6 +223,8 @@ struct omap_hwmod_soc_ops { void (*update_context_lost)(struct omap_hwmod *oh); int (*get_context_lost)(struct omap_hwmod *oh); int (*disable_direct_prcm)(struct omap_hwmod *oh); + u32 (*xlate_clkctrl)(struct omap_hwmod *oh, + struct clkctrl_provider *provider); }; /* soc_ops: adapts the omap_hwmod code to the currently-booted SoC */ @@ -690,6 +711,103 @@ static int _del_initiator_dep(struct omap_hwmod *oh, struct omap_hwmod *init_oh) return clkdm_del_sleepdep(clkdm, init_clkdm); } +static const struct of_device_id ti_clkctrl_match_table[] __initconst = { + { .compatible = "ti,clkctrl" }, + { } +}; + +static int _match_clkdm(struct clockdomain *clkdm, void *user) +{ + struct clkctrl_provider *provider = user; + + if (clkdm_xlate_address(clkdm) == provider->addr) { + pr_debug("%s: Matched clkdm %s for addr %x (%s)\n", __func__, + clkdm->name, provider->addr, + provider->node->parent->name); + provider->clkdm = clkdm; + + return -1; + } + + return 0; +} + +static int _setup_clkctrl_provider(struct device_node *np) +{ + const __be32 *addrp; + struct clkctrl_provider *provider; + + provider = memblock_virt_alloc(sizeof(*provider), 0); + if (!provider) + return -ENOMEM; + + addrp = of_get_address(np, 0, NULL, NULL); + provider->addr = (u32)of_translate_address(np, addrp); + provider->offset = provider->addr & 0xff; + provider->addr &= ~0xff; + provider->node = np; + + clkdm_for_each(_match_clkdm, provider); + + if (!provider->clkdm) { + pr_err("%s: nothing matched for node %s (%x)\n", + __func__, np->parent->name, provider->addr); + memblock_free_early(__pa(provider), sizeof(*provider)); + return -EINVAL; + } + + list_add(&provider->link, &clkctrl_providers); + + return 0; +} + +static int _init_clkctrl_providers(void) +{ + struct device_node *np; + int ret = 0; + + for_each_matching_node(np, ti_clkctrl_match_table) { + ret = _setup_clkctrl_provider(np); + if (ret) + break; + } + + return ret; +} + +static u32 _omap4_xlate_clkctrl(struct omap_hwmod *oh, + struct clkctrl_provider *provider) +{ + return oh->prcm.omap4.clkctrl_offs - + provider->offset - provider->clkdm->clkdm_offs; +} + +static struct clk *_lookup_clkctrl_clk(struct omap_hwmod *oh) +{ + struct clkctrl_provider *provider; + struct clk *clk; + + if (!soc_ops.xlate_clkctrl) + return NULL; + + list_for_each_entry(provider, &clkctrl_providers, link) { + if (provider->clkdm == oh->clkdm) { + struct of_phandle_args clkspec; + + clkspec.np = provider->node; + clkspec.args_count = 2; + clkspec.args[0] = soc_ops.xlate_clkctrl(oh, provider); + clkspec.args[1] = 0; + + clk = of_clk_get_from_provider(&clkspec); + + return clk; + } + } + + return NULL; +} + /** * _init_main_clk - get a struct clk * for the the hwmod's main functional clk * @oh: struct omap_hwmod * @@ -701,22 +819,16 @@ static int _del_initiator_dep(struct omap_hwmod *oh, struct omap_hwmod *init_oh) static int _init_main_clk(struct omap_hwmod *oh) { int ret = 0; - char name[MOD_CLK_MAX_NAME_LEN]; - struct clk *clk; - static const char modck[] = "_mod_ck"; + struct clk *clk = NULL; - if (strlen(oh->name) >= MOD_CLK_MAX_NAME_LEN - strlen(modck)) - pr_warn("%s: warning: cropping name for %s\n", __func__, - oh->name); - - strlcpy(name, oh->name, MOD_CLK_MAX_NAME_LEN - strlen(modck)); - strlcat(name, modck, MOD_CLK_MAX_NAME_LEN); + clk = _lookup_clkctrl_clk(oh); - clk = clk_get(NULL, name); - if (!IS_ERR(clk)) { + if (!IS_ERR_OR_NULL(clk)) { + pr_debug("%s: mapped main_clk %s for %s\n", __func__, + __clk_get_name(clk), oh->name); + oh->main_clk = __clk_get_name(clk); oh->_clk = clk; soc_ops.disable_direct_prcm(oh); - oh->main_clk = kstrdup(name, GFP_KERNEL); } else { if (!oh->main_clk) return 0; @@ -1482,13 +1594,13 @@ static int _init_clkdm(struct omap_hwmod *oh) * _init_clocks - clk_get() all clocks associated with this hwmod. Retrieve as * well the clockdomain. * @oh: struct omap_hwmod * - * @data: not used; pass NULL + * @np: device_node mapped to this hwmod * * Called by omap_hwmod_setup_*() (after omap2_clk_init()). * Resolves all clock names embedded in the hwmod. Returns 0 on * success, or a negative error code on failure. */ -static int _init_clocks(struct omap_hwmod *oh, void *data) +static int _init_clocks(struct omap_hwmod *oh, struct device_node *np) { int ret = 0; @@ -2360,7 +2472,7 @@ static int __init _init(struct omap_hwmod *oh, void *data) return 0; } - r = _init_clocks(oh, NULL); + r = _init_clocks(oh, np); if (r < 0) { WARN(1, "omap_hwmod: %s: couldn't init clocks\n", oh->name); return -EINVAL; @@ -3722,6 +3834,7 @@ void __init omap_hwmod_init(void) soc_ops.update_context_lost = _omap4_update_context_lost; soc_ops.get_context_lost = _omap4_get_context_lost; soc_ops.disable_direct_prcm = _omap4_disable_direct_prcm; + soc_ops.xlate_clkctrl = _omap4_xlate_clkctrl; } else if (cpu_is_ti814x() || cpu_is_ti816x() || soc_is_am33xx() || soc_is_am43xx()) { soc_ops.enable_module = _omap4_enable_module; @@ -3736,6 +3849,8 @@ void __init omap_hwmod_init(void) WARN(1, "omap_hwmod: unknown SoC type\n"); } + _init_clkctrl_providers(); + inited = true; } -- cgit From b3ea575770c7eeb259c77b6861cd14d00eb309df Mon Sep 17 00:00:00 2001 From: Leonard Crestez Date: Tue, 6 Jun 2017 20:50:42 +0300 Subject: ARM: imx: Add MXC_CPU_IMX6ULL and cpu_is_imx6ull Support for imx6ull is already present but it's based on of_machine_is_compatible("fsl,imx6ull") checks. Add it to the MXC_CPU_* enumeration as well. This also fixes /sys/devices/soc0/soc_id reading "Unknown". Signed-off-by: Leonard Crestez Reviewed-by: Fabio Estevam Signed-off-by: Shawn Guo --- arch/arm/mach-imx/cpu.c | 3 +++ arch/arm/mach-imx/mxc.h | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/arch/arm/mach-imx/cpu.c b/arch/arm/mach-imx/cpu.c index b3347d32349f..94906ed49392 100644 --- a/arch/arm/mach-imx/cpu.c +++ b/arch/arm/mach-imx/cpu.c @@ -131,6 +131,9 @@ struct device * __init imx_soc_device_init(void) case MXC_CPU_IMX6UL: soc_id = "i.MX6UL"; break; + case MXC_CPU_IMX6ULL: + soc_id = "i.MX6ULL"; + break; case MXC_CPU_IMX7D: soc_id = "i.MX7D"; break; diff --git a/arch/arm/mach-imx/mxc.h b/arch/arm/mach-imx/mxc.h index 34f2ff62583c..e00d6260c3df 100644 --- a/arch/arm/mach-imx/mxc.h +++ b/arch/arm/mach-imx/mxc.h @@ -39,6 +39,7 @@ #define MXC_CPU_IMX6SX 0x62 #define MXC_CPU_IMX6Q 0x63 #define MXC_CPU_IMX6UL 0x64 +#define MXC_CPU_IMX6ULL 0x65 #define MXC_CPU_IMX7D 0x72 #define IMX_DDR_TYPE_LPDDR2 1 @@ -73,6 +74,11 @@ static inline bool cpu_is_imx6ul(void) return __mxc_cpu_type == MXC_CPU_IMX6UL; } +static inline bool cpu_is_imx6ull(void) +{ + return __mxc_cpu_type == MXC_CPU_IMX6ULL; +} + static inline bool cpu_is_imx6q(void) { return __mxc_cpu_type == MXC_CPU_IMX6Q; -- cgit From bf5a01d7c50fb0c4e1c3d320d670bad252d50bcb Mon Sep 17 00:00:00 2001 From: Leonard Crestez Date: Tue, 6 Jun 2017 20:50:43 +0300 Subject: ARM: imx6ull: Make suspend/resume work like on 6ul Suspend and resume on imx6ull is currenty not working because of some missed checks where behavior should match imx6ul. Signed-off-by: Leonard Crestez Reviewed-by: Fabio Estevam Signed-off-by: Shawn Guo --- arch/arm/mach-imx/pm-imx6.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-imx/pm-imx6.c b/arch/arm/mach-imx/pm-imx6.c index e61b1d1027e1..ecdf071653d4 100644 --- a/arch/arm/mach-imx/pm-imx6.c +++ b/arch/arm/mach-imx/pm-imx6.c @@ -295,7 +295,8 @@ int imx6_set_lpm(enum mxc_cpu_pwr_mode mode) val &= ~BM_CLPCR_SBYOS; if (cpu_is_imx6sl()) val |= BM_CLPCR_BYPASS_PMIC_READY; - if (cpu_is_imx6sl() || cpu_is_imx6sx() || cpu_is_imx6ul()) + if (cpu_is_imx6sl() || cpu_is_imx6sx() || cpu_is_imx6ul() || + cpu_is_imx6ull()) val |= BM_CLPCR_BYP_MMDC_CH0_LPM_HS; else val |= BM_CLPCR_BYP_MMDC_CH1_LPM_HS; @@ -312,7 +313,8 @@ int imx6_set_lpm(enum mxc_cpu_pwr_mode mode) val |= BM_CLPCR_SBYOS; if (cpu_is_imx6sl() || cpu_is_imx6sx()) val |= BM_CLPCR_BYPASS_PMIC_READY; - if (cpu_is_imx6sl() || cpu_is_imx6sx() || cpu_is_imx6ul()) + if (cpu_is_imx6sl() || cpu_is_imx6sx() || cpu_is_imx6ul() || + cpu_is_imx6ull()) val |= BM_CLPCR_BYP_MMDC_CH0_LPM_HS; else val |= BM_CLPCR_BYP_MMDC_CH1_LPM_HS; -- cgit From d27a30bbc8b0c84a4cc922b201f9e85e9a2de741 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Thu, 1 Jun 2017 21:48:11 +0200 Subject: ARM: OMAP1: DMA: Improve a size determination in omap1_system_dma_init() Replace the specification of a data structure by a pointer dereference as the parameter for the operator "sizeof" to make the corresponding size determination a bit safer according to the Linux coding style convention. Signed-off-by: Markus Elfring Signed-off-by: Tony Lindgren --- arch/arm/mach-omap1/dma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-omap1/dma.c b/arch/arm/mach-omap1/dma.c index c821c1d5610e..823dba3dc033 100644 --- a/arch/arm/mach-omap1/dma.c +++ b/arch/arm/mach-omap1/dma.c @@ -339,7 +339,7 @@ static int __init omap1_system_dma_init(void) goto exit_iounmap; } - d = kzalloc(sizeof(struct omap_dma_dev_attr), GFP_KERNEL); + d = kzalloc(sizeof(*d), GFP_KERNEL); if (!d) { dev_err(&pdev->dev, "%s: Unable to allocate 'd' for %s\n", __func__, pdev->name); -- cgit From 61ee221ee45bc10d9115ba6ce8862ee62289a98f Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Thu, 1 Jun 2017 21:54:36 +0200 Subject: ARM: OMAP1: DMA: Delete an error message for a failed memory allocation in omap1_system_dma_init() Omit an extra message for a memory allocation failure in this function. This issue was detected by using the Coccinelle software. Link: http://events.linuxfoundation.org/sites/events/files/slides/LCJ16-Refactor_Strings-WSang_0.pdf Signed-off-by: Markus Elfring Signed-off-by: Tony Lindgren --- arch/arm/mach-omap1/dma.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/arm/mach-omap1/dma.c b/arch/arm/mach-omap1/dma.c index 823dba3dc033..c545b4e01d53 100644 --- a/arch/arm/mach-omap1/dma.c +++ b/arch/arm/mach-omap1/dma.c @@ -341,8 +341,6 @@ static int __init omap1_system_dma_init(void) d = kzalloc(sizeof(*d), GFP_KERNEL); if (!d) { - dev_err(&pdev->dev, "%s: Unable to allocate 'd' for %s\n", - __func__, pdev->name); ret = -ENOMEM; goto exit_iounmap; } -- cgit From 2abe5b343dc790cc577700b07ca8d10fed62ae0e Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Thu, 1 Jun 2017 22:00:21 +0200 Subject: ARM: OMAP1: DMA: Delete an unnecessary return statement in omap1_show_dma_caps() The script "checkpatch.pl" pointed information out like the following. WARNING: void function return statements are not generally useful Thus remove such a statement in the affected function. Signed-off-by: Markus Elfring Signed-off-by: Tony Lindgren --- arch/arm/mach-omap1/dma.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/mach-omap1/dma.c b/arch/arm/mach-omap1/dma.c index c545b4e01d53..52d7eda1adec 100644 --- a/arch/arm/mach-omap1/dma.c +++ b/arch/arm/mach-omap1/dma.c @@ -240,7 +240,6 @@ static void omap1_show_dma_caps(void) w |= 1 << 3; dma_write(w, GSCR, 0); } - return; } static unsigned configure_dma_errata(void) -- cgit From a9e317c388d48da80fc266f06dc6298cbd790b8c Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Thu, 1 Jun 2017 22:04:29 +0200 Subject: ARM: OMAP1: Delete an error message for a failed memory allocation in omap1_dm_timer_init() Omit an extra message for a memory allocation failure in this function. This issue was detected by using the Coccinelle software. Link: http://events.linuxfoundation.org/sites/events/files/slides/LCJ16-Refactor_Strings-WSang_0.pdf Signed-off-by: Markus Elfring Signed-off-by: Tony Lindgren --- arch/arm/mach-omap1/timer.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/arm/mach-omap1/timer.c b/arch/arm/mach-omap1/timer.c index 06c5ba7574a5..637f8c9d9f10 100644 --- a/arch/arm/mach-omap1/timer.c +++ b/arch/arm/mach-omap1/timer.c @@ -134,8 +134,6 @@ static int __init omap1_dm_timer_init(void) pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); if (!pdata) { - dev_err(&pdev->dev, "%s: Failed to allocate pdata.\n", - __func__); ret = -ENOMEM; goto err_free_pdata; } -- cgit From 764e4ef0a8871339eeddaf27ccc47aeeea28b974 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Thu, 1 Jun 2017 22:17:03 +0200 Subject: ARM: OMAP1: Fix a typo in a comment line Adjust a line in this description for the software module. Signed-off-by: Markus Elfring Signed-off-by: Tony Lindgren --- arch/arm/mach-omap1/timer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-omap1/timer.c b/arch/arm/mach-omap1/timer.c index 637f8c9d9f10..8fb1ec6fa999 100644 --- a/arch/arm/mach-omap1/timer.c +++ b/arch/arm/mach-omap1/timer.c @@ -3,7 +3,7 @@ * * Contains first level initialization routines which internally * generates timer device information and registers with linux - * device model. It also has low level function to chnage the timer + * device model. It also has a low level function to change the timer * input clock source. * * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ -- cgit From 99b3587debacd24b30ecfae5ae59ed7a5070528b Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Wed, 31 May 2017 15:51:29 -0700 Subject: ARM: OMAP2+: Remove unused legacy code for opp We are now booting all mach-omap2 in device tree only mode. Any code that is only called in legacy boot mode where of_have_populated_dt() is not set is safe to remove now. Note that the volt_data is still being used. Reviewed-by: Sebastian Reichel Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/Makefile | 1 - arch/arm/mach-omap2/opp.c | 104 ------------------------------------- arch/arm/mach-omap2/opp3xxx_data.c | 86 ------------------------------ arch/arm/mach-omap2/opp4xxx_data.c | 79 ---------------------------- 4 files changed, 270 deletions(-) delete mode 100644 arch/arm/mach-omap2/opp.c diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index c89757abb0ae..deb6c33a7bd0 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -69,7 +69,6 @@ obj-$(CONFIG_ARCH_OMAP2) += sdrc2xxx.o # OPP table initialization ifeq ($(CONFIG_PM_OPP),y) -obj-y += opp.o obj-$(CONFIG_ARCH_OMAP3) += opp3xxx_data.o obj-$(CONFIG_ARCH_OMAP4) += opp4xxx_data.o endif diff --git a/arch/arm/mach-omap2/opp.c b/arch/arm/mach-omap2/opp.c deleted file mode 100644 index a358a07e18f2..000000000000 --- a/arch/arm/mach-omap2/opp.c +++ /dev/null @@ -1,104 +0,0 @@ -/* - * OMAP SoC specific OPP wrapper function - * - * Copyright (C) 2009-2010 Texas Instruments Incorporated - http://www.ti.com/ - * Nishanth Menon - * Kevin Hilman - * Copyright (C) 2010 Nokia Corporation. - * Eduardo Valentin - * - * 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. - * - * This program is distributed "as is" WITHOUT ANY WARRANTY of any - * kind, whether express or implied; without even the implied warranty - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ -#include -#include -#include -#include - -#include "omap_device.h" - -#include "omap_opp_data.h" - -/* Temp variable to allow multiple calls */ -static u8 __initdata omap_table_init; - -/** - * omap_init_opp_table() - Initialize opp table as per the CPU type - * @opp_def: opp default list for this silicon - * @opp_def_size: number of opp entries for this silicon - * - * Register the initial OPP table with the OPP library based on the CPU - * type. This is meant to be used only by SoC specific registration. - */ -int __init omap_init_opp_table(struct omap_opp_def *opp_def, - u32 opp_def_size) -{ - int i, r; - - if (of_have_populated_dt()) - return -EINVAL; - - if (!opp_def || !opp_def_size) { - pr_err("%s: invalid params!\n", __func__); - return -EINVAL; - } - - /* - * Initialize only if not already initialized even if the previous - * call failed, because, no reason we'd succeed again. - */ - if (omap_table_init) - return -EEXIST; - omap_table_init = 1; - - /* Lets now register with OPP library */ - for (i = 0; i < opp_def_size; i++, opp_def++) { - struct omap_hwmod *oh; - struct device *dev; - - if (!opp_def->hwmod_name) { - pr_err("%s: NULL name of omap_hwmod, failing [%d].\n", - __func__, i); - return -EINVAL; - } - - if (!strncmp(opp_def->hwmod_name, "mpu", 3)) { - /* - * All current OMAPs share voltage rail and - * clock source, so CPU0 is used to represent - * the MPU-SS. - */ - dev = get_cpu_device(0); - } else { - oh = omap_hwmod_lookup(opp_def->hwmod_name); - if (!oh || !oh->od) { - pr_debug("%s: no hwmod or odev for %s, [%d] cannot add OPPs.\n", - __func__, opp_def->hwmod_name, i); - continue; - } - dev = &oh->od->pdev->dev; - } - - r = dev_pm_opp_add(dev, opp_def->freq, opp_def->u_volt); - if (r) { - dev_err(dev, "%s: add OPP %ld failed for %s [%d] result=%d\n", - __func__, opp_def->freq, - opp_def->hwmod_name, i, r); - } else { - if (!opp_def->default_available) - r = dev_pm_opp_disable(dev, opp_def->freq); - if (r) - dev_err(dev, "%s: disable %ld failed for %s [%d] result=%d\n", - __func__, opp_def->freq, - opp_def->hwmod_name, i, r); - } - } - - return 0; -} diff --git a/arch/arm/mach-omap2/opp3xxx_data.c b/arch/arm/mach-omap2/opp3xxx_data.c index fc67add76444..c2d459f5b0da 100644 --- a/arch/arm/mach-omap2/opp3xxx_data.c +++ b/arch/arm/mach-omap2/opp3xxx_data.c @@ -83,89 +83,3 @@ struct omap_volt_data omap36xx_vddcore_volt_data[] = { VOLT_DATA_DEFINE(OMAP3630_VDD_CORE_OPP100_UV, OMAP3630_CONTROL_FUSE_OPP100_VDD2, 0xf9, 0x16), VOLT_DATA_DEFINE(0, 0, 0, 0), }; - -/* OPP data */ - -static struct omap_opp_def __initdata omap34xx_opp_def_list[] = { - /* MPU OPP1 */ - OPP_INITIALIZER("mpu", true, 125000000, OMAP3430_VDD_MPU_OPP1_UV), - /* MPU OPP2 */ - OPP_INITIALIZER("mpu", true, 250000000, OMAP3430_VDD_MPU_OPP2_UV), - /* MPU OPP3 */ - OPP_INITIALIZER("mpu", true, 500000000, OMAP3430_VDD_MPU_OPP3_UV), - /* MPU OPP4 */ - OPP_INITIALIZER("mpu", true, 550000000, OMAP3430_VDD_MPU_OPP4_UV), - /* MPU OPP5 */ - OPP_INITIALIZER("mpu", true, 600000000, OMAP3430_VDD_MPU_OPP5_UV), - - /* - * L3 OPP1 - 41.5 MHz is disabled because: The voltage for that OPP is - * almost the same than the one at 83MHz thus providing very little - * gain for the power point of view. In term of energy it will even - * increase the consumption due to the very negative performance - * impact that frequency will do to the MPU and the whole system in - * general. - */ - OPP_INITIALIZER("l3_main", false, 41500000, OMAP3430_VDD_CORE_OPP1_UV), - /* L3 OPP2 */ - OPP_INITIALIZER("l3_main", true, 83000000, OMAP3430_VDD_CORE_OPP2_UV), - /* L3 OPP3 */ - OPP_INITIALIZER("l3_main", true, 166000000, OMAP3430_VDD_CORE_OPP3_UV), - - /* DSP OPP1 */ - OPP_INITIALIZER("iva", true, 90000000, OMAP3430_VDD_MPU_OPP1_UV), - /* DSP OPP2 */ - OPP_INITIALIZER("iva", true, 180000000, OMAP3430_VDD_MPU_OPP2_UV), - /* DSP OPP3 */ - OPP_INITIALIZER("iva", true, 360000000, OMAP3430_VDD_MPU_OPP3_UV), - /* DSP OPP4 */ - OPP_INITIALIZER("iva", true, 400000000, OMAP3430_VDD_MPU_OPP4_UV), - /* DSP OPP5 */ - OPP_INITIALIZER("iva", true, 430000000, OMAP3430_VDD_MPU_OPP5_UV), -}; - -static struct omap_opp_def __initdata omap36xx_opp_def_list[] = { - /* MPU OPP1 - OPP50 */ - OPP_INITIALIZER("mpu", true, 300000000, OMAP3630_VDD_MPU_OPP50_UV), - /* MPU OPP2 - OPP100 */ - OPP_INITIALIZER("mpu", true, 600000000, OMAP3630_VDD_MPU_OPP100_UV), - /* MPU OPP3 - OPP-Turbo */ - OPP_INITIALIZER("mpu", false, 800000000, OMAP3630_VDD_MPU_OPP120_UV), - /* MPU OPP4 - OPP-SB */ - OPP_INITIALIZER("mpu", false, 1000000000, OMAP3630_VDD_MPU_OPP1G_UV), - - /* L3 OPP1 - OPP50 */ - OPP_INITIALIZER("l3_main", true, 100000000, OMAP3630_VDD_CORE_OPP50_UV), - /* L3 OPP2 - OPP100, OPP-Turbo, OPP-SB */ - OPP_INITIALIZER("l3_main", true, 200000000, OMAP3630_VDD_CORE_OPP100_UV), - - /* DSP OPP1 - OPP50 */ - OPP_INITIALIZER("iva", true, 260000000, OMAP3630_VDD_MPU_OPP50_UV), - /* DSP OPP2 - OPP100 */ - OPP_INITIALIZER("iva", true, 520000000, OMAP3630_VDD_MPU_OPP100_UV), - /* DSP OPP3 - OPP-Turbo */ - OPP_INITIALIZER("iva", false, 660000000, OMAP3630_VDD_MPU_OPP120_UV), - /* DSP OPP4 - OPP-SB */ - OPP_INITIALIZER("iva", false, 800000000, OMAP3630_VDD_MPU_OPP1G_UV), -}; - -/** - * omap3_opp_init() - initialize omap3 opp table - */ -int __init omap3_opp_init(void) -{ - int r = -ENODEV; - - if (!cpu_is_omap34xx()) - return r; - - if (cpu_is_omap3630()) - r = omap_init_opp_table(omap36xx_opp_def_list, - ARRAY_SIZE(omap36xx_opp_def_list)); - else - r = omap_init_opp_table(omap34xx_opp_def_list, - ARRAY_SIZE(omap34xx_opp_def_list)); - - return r; -} -omap_device_initcall(omap3_opp_init); diff --git a/arch/arm/mach-omap2/opp4xxx_data.c b/arch/arm/mach-omap2/opp4xxx_data.c index 1ef7a3e5ce4a..adea43ea1c60 100644 --- a/arch/arm/mach-omap2/opp4xxx_data.c +++ b/arch/arm/mach-omap2/opp4xxx_data.c @@ -63,29 +63,6 @@ struct omap_volt_data omap443x_vdd_core_volt_data[] = { VOLT_DATA_DEFINE(0, 0, 0, 0), }; - -static struct omap_opp_def __initdata omap443x_opp_def_list[] = { - /* MPU OPP1 - OPP50 */ - OPP_INITIALIZER("mpu", true, 300000000, OMAP4430_VDD_MPU_OPP50_UV), - /* MPU OPP2 - OPP100 */ - OPP_INITIALIZER("mpu", true, 600000000, OMAP4430_VDD_MPU_OPP100_UV), - /* MPU OPP3 - OPP-Turbo */ - OPP_INITIALIZER("mpu", true, 800000000, OMAP4430_VDD_MPU_OPPTURBO_UV), - /* MPU OPP4 - OPP-SB */ - OPP_INITIALIZER("mpu", true, 1008000000, OMAP4430_VDD_MPU_OPPNITRO_UV), - /* L3 OPP1 - OPP50 */ - OPP_INITIALIZER("l3_main_1", true, 100000000, OMAP4430_VDD_CORE_OPP50_UV), - /* L3 OPP2 - OPP100, OPP-Turbo, OPP-SB */ - OPP_INITIALIZER("l3_main_1", true, 200000000, OMAP4430_VDD_CORE_OPP100_UV), - /* IVA OPP1 - OPP50 */ - OPP_INITIALIZER("iva", true, 133000000, OMAP4430_VDD_IVA_OPP50_UV), - /* IVA OPP2 - OPP100 */ - OPP_INITIALIZER("iva", true, 266100000, OMAP4430_VDD_IVA_OPP100_UV), - /* IVA OPP3 - OPP-Turbo */ - OPP_INITIALIZER("iva", false, 332000000, OMAP4430_VDD_IVA_OPPTURBO_UV), - /* TODO: add DSP, aess, fdif, gpu */ -}; - #define OMAP4460_VDD_MPU_OPP50_UV 1025000 #define OMAP4460_VDD_MPU_OPP100_UV 1200000 #define OMAP4460_VDD_MPU_OPPTURBO_UV 1313000 @@ -122,59 +99,3 @@ struct omap_volt_data omap446x_vdd_core_volt_data[] = { VOLT_DATA_DEFINE(OMAP4460_VDD_CORE_OPP100_OV_UV, OMAP44XX_CONTROL_FUSE_CORE_OPP100OV, 0xf9, 0x16), VOLT_DATA_DEFINE(0, 0, 0, 0), }; - -static struct omap_opp_def __initdata omap446x_opp_def_list[] = { - /* MPU OPP1 - OPP50 */ - OPP_INITIALIZER("mpu", true, 350000000, OMAP4460_VDD_MPU_OPP50_UV), - /* MPU OPP2 - OPP100 */ - OPP_INITIALIZER("mpu", true, 700000000, OMAP4460_VDD_MPU_OPP100_UV), - /* MPU OPP3 - OPP-Turbo */ - OPP_INITIALIZER("mpu", true, 920000000, OMAP4460_VDD_MPU_OPPTURBO_UV), - /* - * MPU OPP4 - OPP-Nitro + Disabled as the reference schematics - * recommends TPS623631 - confirm and enable the opp in board file - * XXX: May be we should enable these based on mpu capability and - * Exception board files disable it... - */ - OPP_INITIALIZER("mpu", false, 1200000000, OMAP4460_VDD_MPU_OPPNITRO_UV), - /* MPU OPP4 - OPP-Nitro SpeedBin */ - OPP_INITIALIZER("mpu", false, 1500000000, OMAP4460_VDD_MPU_OPPNITRO_UV), - /* L3 OPP1 - OPP50 */ - OPP_INITIALIZER("l3_main_1", true, 100000000, OMAP4460_VDD_CORE_OPP50_UV), - /* L3 OPP2 - OPP100 */ - OPP_INITIALIZER("l3_main_1", true, 200000000, OMAP4460_VDD_CORE_OPP100_UV), - /* IVA OPP1 - OPP50 */ - OPP_INITIALIZER("iva", true, 133000000, OMAP4460_VDD_IVA_OPP50_UV), - /* IVA OPP2 - OPP100 */ - OPP_INITIALIZER("iva", true, 266100000, OMAP4460_VDD_IVA_OPP100_UV), - /* - * IVA OPP3 - OPP-Turbo + Disabled as the reference schematics - * recommends Phoenix VCORE2 which can supply only 600mA - so the ones - * above this OPP frequency, even though OMAP is capable, should be - * enabled by board file which is sure of the chip power capability - */ - OPP_INITIALIZER("iva", false, 332000000, OMAP4460_VDD_IVA_OPPTURBO_UV), - /* IVA OPP4 - OPP-Nitro */ - OPP_INITIALIZER("iva", false, 430000000, OMAP4460_VDD_IVA_OPPNITRO_UV), - /* IVA OPP5 - OPP-Nitro SpeedBin*/ - OPP_INITIALIZER("iva", false, 500000000, OMAP4460_VDD_IVA_OPPNITRO_UV), - - /* TODO: add DSP, aess, fdif, gpu */ -}; - -/** - * omap4_opp_init() - initialize omap4 opp table - */ -int __init omap4_opp_init(void) -{ - int r = -ENODEV; - - if (cpu_is_omap443x()) - r = omap_init_opp_table(omap443x_opp_def_list, - ARRAY_SIZE(omap443x_opp_def_list)); - else if (cpu_is_omap446x()) - r = omap_init_opp_table(omap446x_opp_def_list, - ARRAY_SIZE(omap446x_opp_def_list)); - return r; -} -omap_device_initcall(omap4_opp_init); -- cgit From 7bd6934477413753eacbcab8aeb2df7eb84f2867 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Wed, 31 May 2017 15:51:31 -0700 Subject: ARM: OMAP2+: Remove unused legacy code for PMU We are now booting all mach-omap2 in device tree only mode. Any code that is only called in legacy boot mode where of_have_populated_dt() is not set is safe to remove now. Reviewed-by: Sebastian Reichel Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/Makefile | 3 -- arch/arm/mach-omap2/pmu.c | 97 -------------------------------------------- 2 files changed, 100 deletions(-) delete mode 100644 arch/arm/mach-omap2/pmu.c diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index deb6c33a7bd0..779fb1f680b3 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -219,9 +219,6 @@ obj-$(CONFIG_ARCH_OMAP4) += omap_hwmod_44xx_data.o obj-$(CONFIG_SOC_OMAP5) += omap_hwmod_54xx_data.o obj-$(CONFIG_SOC_DRA7XX) += omap_hwmod_7xx_data.o -# EMU peripherals -obj-$(CONFIG_HW_PERF_EVENTS) += pmu.o - # OMAP2420 MSDI controller integration support ("MMC") obj-$(CONFIG_SOC_OMAP2420) += msdi.o diff --git a/arch/arm/mach-omap2/pmu.c b/arch/arm/mach-omap2/pmu.c deleted file mode 100644 index d2adfebd3b3f..000000000000 --- a/arch/arm/mach-omap2/pmu.c +++ /dev/null @@ -1,97 +0,0 @@ -/* - * OMAP2 ARM Performance Monitoring Unit (PMU) Support - * - * Copyright (C) 2012 Texas Instruments, Inc. - * - * Contacts: - * Jon Hunter - * - * 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; either version 2 of the License, or - * (at your option) any later version. - */ -#include - -#include - -#include "soc.h" -#include "omap_hwmod.h" -#include "omap_device.h" - -static char *omap2_pmu_oh_names[] = {"mpu"}; -static char *omap3_pmu_oh_names[] = {"mpu", "debugss"}; -static char *omap4430_pmu_oh_names[] = {"l3_main_3", "l3_instr", "debugss"}; -static struct platform_device *omap_pmu_dev; - -/** - * omap2_init_pmu - creates and registers PMU platform device - * @oh_num: Number of OMAP HWMODs required to create PMU device - * @oh_names: Array of OMAP HWMODS names required to create PMU device - * - * Uses OMAP HWMOD framework to create and register an ARM PMU device - * from a list of HWMOD names passed. Currently supports OMAP2, OMAP3 - * and OMAP4 devices. - */ -static int __init omap2_init_pmu(unsigned oh_num, char *oh_names[]) -{ - int i; - struct omap_hwmod *oh[3]; - char *dev_name = cpu_architecture() == CPU_ARCH_ARMv6 ? - "armv6-pmu" : "armv7-pmu"; - - if ((!oh_num) || (oh_num > 3)) - return -EINVAL; - - for (i = 0; i < oh_num; i++) { - oh[i] = omap_hwmod_lookup(oh_names[i]); - if (!oh[i]) { - pr_err("Could not look up %s hwmod\n", oh_names[i]); - return -ENODEV; - } - } - - omap_pmu_dev = omap_device_build_ss(dev_name, -1, oh, oh_num, NULL, 0); - WARN(IS_ERR(omap_pmu_dev), "Can't build omap_device for %s.\n", - dev_name); - - return PTR_ERR_OR_ZERO(omap_pmu_dev); -} - -static int __init omap_init_pmu(void) -{ - unsigned oh_num; - char **oh_names; - - /* XXX Remove this check when the CTI driver is available */ - if (cpu_is_omap443x()) { - pr_info("ARM PMU: not yet supported on OMAP4430 due to missing CTI driver\n"); - return 0; - } - - if (of_have_populated_dt()) - return 0; - - /* - * To create an ARM-PMU device the following HWMODs - * are required for the various OMAP2+ devices. - * - * OMAP24xx: mpu - * OMAP3xxx: mpu, debugss - * OMAP4430: l3_main_3, l3_instr, debugss - * OMAP4460/70: mpu, debugss - */ - if (cpu_is_omap443x()) { - oh_num = ARRAY_SIZE(omap4430_pmu_oh_names); - oh_names = omap4430_pmu_oh_names; - } else if (cpu_is_omap34xx() || cpu_is_omap44xx()) { - oh_num = ARRAY_SIZE(omap3_pmu_oh_names); - oh_names = omap3_pmu_oh_names; - } else { - oh_num = ARRAY_SIZE(omap2_pmu_oh_names); - oh_names = omap2_pmu_oh_names; - } - - return omap2_init_pmu(oh_num, oh_names); -} -omap_subsys_initcall(omap_init_pmu); -- cgit From 6f3ab009a178098e834d9e060f03e1232bb449c1 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Wed, 31 May 2017 15:51:32 -0700 Subject: ARM: OMAP2+: Remove unused legacy code for device init We are now booting all mach-omap2 in device tree only mode. Any code that is only called in legacy boot mode where of_have_populated_dt() is not set is safe to remove now. Note that omap_init_sti() won't do anything so we can remove omap2_init_devices() as pointed out by Sebastian Reichel . Reviewed-by: Sebastian Reichel Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/devices.c | 175 ------------------------------------------ 1 file changed, 175 deletions(-) diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c index 473951203104..93057fb65f44 100644 --- a/arch/arm/mach-omap2/devices.c +++ b/arch/arm/mach-omap2/devices.c @@ -36,130 +36,6 @@ #define L3_MODULES_MAX_LEN 12 #define L3_MODULES 3 -static int __init omap3_l3_init(void) -{ - struct omap_hwmod *oh; - struct platform_device *pdev; - char oh_name[L3_MODULES_MAX_LEN]; - - /* - * To avoid code running on other OMAPs in - * multi-omap builds - */ - if (!(cpu_is_omap34xx()) || of_have_populated_dt()) - return -ENODEV; - - snprintf(oh_name, L3_MODULES_MAX_LEN, "l3_main"); - - oh = omap_hwmod_lookup(oh_name); - - if (!oh) - pr_err("could not look up %s\n", oh_name); - - pdev = omap_device_build("omap_l3_smx", 0, oh, NULL, 0); - - WARN(IS_ERR(pdev), "could not build omap_device for %s\n", oh_name); - - return PTR_ERR_OR_ZERO(pdev); -} -omap_postcore_initcall(omap3_l3_init); - -static inline void omap_init_sti(void) {} - -#if IS_ENABLED(CONFIG_SPI_OMAP24XX) - -#include - -static int __init omap_mcspi_init(struct omap_hwmod *oh, void *unused) -{ - struct platform_device *pdev; - char *name = "omap2_mcspi"; - struct omap2_mcspi_platform_config *pdata; - static int spi_num; - struct omap2_mcspi_dev_attr *mcspi_attrib = oh->dev_attr; - - pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); - if (!pdata) { - pr_err("Memory allocation for McSPI device failed\n"); - return -ENOMEM; - } - - pdata->num_cs = mcspi_attrib->num_chipselect; - switch (oh->class->rev) { - case OMAP2_MCSPI_REV: - case OMAP3_MCSPI_REV: - pdata->regs_offset = 0; - break; - case OMAP4_MCSPI_REV: - pdata->regs_offset = OMAP4_MCSPI_REG_OFFSET; - break; - default: - pr_err("Invalid McSPI Revision value\n"); - kfree(pdata); - return -EINVAL; - } - - spi_num++; - pdev = omap_device_build(name, spi_num, oh, pdata, sizeof(*pdata)); - WARN(IS_ERR(pdev), "Can't build omap_device for %s:%s\n", - name, oh->name); - kfree(pdata); - return 0; -} - -static void omap_init_mcspi(void) -{ - omap_hwmod_for_each_by_class("mcspi", omap_mcspi_init, NULL); -} - -#else -static inline void omap_init_mcspi(void) {} -#endif - -/** - * omap_init_rng - bind the RNG hwmod to the RNG omap_device - * - * Bind the RNG hwmod to the RNG omap_device. No return value. - */ -static void __init omap_init_rng(void) -{ - struct omap_hwmod *oh; - struct platform_device *pdev; - - oh = omap_hwmod_lookup("rng"); - if (!oh) - return; - - pdev = omap_device_build("omap_rng", -1, oh, NULL, 0); - WARN(IS_ERR(pdev), "Can't build omap_device for omap_rng\n"); -} - -static void __init omap_init_sham(void) -{ - struct omap_hwmod *oh; - struct platform_device *pdev; - - oh = omap_hwmod_lookup("sham"); - if (!oh) - return; - - pdev = omap_device_build("omap-sham", -1, oh, NULL, 0); - WARN(IS_ERR(pdev), "Can't build omap_device for omap-sham\n"); -} - -static void __init omap_init_aes(void) -{ - struct omap_hwmod *oh; - struct platform_device *pdev; - - oh = omap_hwmod_lookup("aes"); - if (!oh) - return; - - pdev = omap_device_build("omap-aes", -1, oh, NULL, 0); - WARN(IS_ERR(pdev), "Can't build omap_device for omap-aes\n"); -} - /*-------------------------------------------------------------------------*/ #if IS_ENABLED(CONFIG_VIDEO_OMAP2_VOUT) @@ -185,54 +61,3 @@ int __init omap_init_vout(void) #else int __init omap_init_vout(void) { return 0; } #endif - -/*-------------------------------------------------------------------------*/ - -static int __init omap2_init_devices(void) -{ - /* Enable dummy states for those platforms without pinctrl support */ - if (!of_have_populated_dt()) - pinctrl_provide_dummies(); - - /* If dtb is there, the devices will be created dynamically */ - if (!of_have_populated_dt()) { - /* - * please keep these calls, and their implementations above, - * in alphabetical order so they're easier to sort through. - */ - omap_init_mcspi(); - omap_init_sham(); - omap_init_aes(); - omap_init_rng(); - } - omap_init_sti(); - - return 0; -} -omap_arch_initcall(omap2_init_devices); - -static int __init omap_gpmc_init(void) -{ - struct omap_hwmod *oh; - struct platform_device *pdev; - char *oh_name = "gpmc"; - - /* - * if the board boots up with a populated DT, do not - * manually add the device from this initcall - */ - if (of_have_populated_dt()) - return -ENODEV; - - oh = omap_hwmod_lookup(oh_name); - if (!oh) { - pr_err("Could not look up %s\n", oh_name); - return -ENODEV; - } - - pdev = omap_device_build("omap-gpmc", -1, oh, NULL, 0); - WARN(IS_ERR(pdev), "could not build omap_device for %s\n", oh_name); - - return PTR_ERR_OR_ZERO(pdev); -} -omap_postcore_initcall(omap_gpmc_init); -- cgit From 1a61a2a5a6476c9053a6c50265ded7f1387960fb Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Sat, 3 Jun 2017 17:24:27 +0200 Subject: ARM: OMAP2+: Delete an error message for a failed memory allocation in two functions Omit an extra message for a memory allocation failure in these functions. This issue was detected by using the Coccinelle software. Link: http://events.linuxfoundation.org/sites/events/files/slides/LCJ16-Refactor_Strings-WSang_0.pdf Signed-off-by: Markus Elfring Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/hsmmc.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c index cb754c46747e..be517b048762 100644 --- a/arch/arm/mach-omap2/hsmmc.c +++ b/arch/arm/mach-omap2/hsmmc.c @@ -153,7 +153,6 @@ static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c, hc_name = kzalloc(sizeof(char) * (HSMMC_NAME_LEN + 1), GFP_KERNEL); if (!hc_name) { - pr_err("Cannot allocate memory for controller slot name\n"); kfree(hc_name); return -ENOMEM; } @@ -315,10 +314,8 @@ static void __init omap_hsmmc_init_one(struct omap2_hsmmc_info *hsmmcinfo, int res; mmc_data = kzalloc(sizeof(*mmc_data), GFP_KERNEL); - if (!mmc_data) { - pr_err("Cannot allocate memory for mmc device!\n"); + if (!mmc_data) return; - } res = omap_hsmmc_pdata_init(hsmmcinfo, mmc_data); if (res < 0) -- cgit From 1dfb5b59d6571104eff6629a0e73a6af347a3226 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Sat, 3 Jun 2017 19:02:24 +0200 Subject: ARM: OMAP2+: Improve a size determination in sr_dev_init() Replace the specification of a data structure by a pointer dereference as the parameter for the operator "sizeof" to make the corresponding size determination a bit safer according to the Linux coding style convention. Signed-off-by: Markus Elfring Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/sr_device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-omap2/sr_device.c b/arch/arm/mach-omap2/sr_device.c index d7cff2632d1e..01df4907c0e3 100644 --- a/arch/arm/mach-omap2/sr_device.c +++ b/arch/arm/mach-omap2/sr_device.c @@ -102,7 +102,7 @@ static int __init sr_dev_init(struct omap_hwmod *oh, void *user) char *name = "smartreflex"; static int i; - sr_data = kzalloc(sizeof(struct omap_sr_data), GFP_KERNEL); + sr_data = kzalloc(sizeof(*sr_data), GFP_KERNEL); if (!sr_data) { pr_err("%s: Unable to allocate memory for %s sr_data\n", __func__, oh->name); -- cgit From 6b72de4d331f058dbd8fa327f1e5d0a729583f56 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Sat, 3 Jun 2017 19:09:07 +0200 Subject: ARM: OMAP2+: Use kcalloc() in sr_set_nvalues() * A multiplication for the size determination of a memory allocation indicated that an array data structure should be processed. Thus use the corresponding function "kcalloc". This issue was detected by using the Coccinelle software. * Replace the specification of a data structure by a pointer dereference to make the corresponding size determination a bit safer according to the Linux coding style convention. Signed-off-by: Markus Elfring Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/sr_device.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/arch/arm/mach-omap2/sr_device.c b/arch/arm/mach-omap2/sr_device.c index 01df4907c0e3..65775c6e8c27 100644 --- a/arch/arm/mach-omap2/sr_device.c +++ b/arch/arm/mach-omap2/sr_device.c @@ -44,9 +44,7 @@ static void __init sr_set_nvalues(struct omap_volt_data *volt_data, while (volt_data[count].volt_nominal) count++; - nvalue_table = kzalloc(sizeof(struct omap_sr_nvalue_table)*count, - GFP_KERNEL); - + nvalue_table = kcalloc(count, sizeof(*nvalue_table), GFP_KERNEL); if (!nvalue_table) { pr_err("OMAP: SmartReflex: cannot allocate memory for n-value table\n"); return; -- cgit From c76e4d2e50068ddd82fe18f86d05a33733877059 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Sat, 3 Jun 2017 19:16:27 +0200 Subject: ARM: OMAP2+: SmartReflex: Delete an error message for a failed memory allocation in two functions Omit an extra message for a memory allocation failure in these functions. This issue was detected by using the Coccinelle software. Link: http://events.linuxfoundation.org/sites/events/files/slides/LCJ16-Refactor_Strings-WSang_0.pdf Signed-off-by: Markus Elfring Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/sr_device.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/arch/arm/mach-omap2/sr_device.c b/arch/arm/mach-omap2/sr_device.c index 65775c6e8c27..eef6935e0403 100644 --- a/arch/arm/mach-omap2/sr_device.c +++ b/arch/arm/mach-omap2/sr_device.c @@ -45,10 +45,8 @@ static void __init sr_set_nvalues(struct omap_volt_data *volt_data, count++; nvalue_table = kcalloc(count, sizeof(*nvalue_table), GFP_KERNEL); - if (!nvalue_table) { - pr_err("OMAP: SmartReflex: cannot allocate memory for n-value table\n"); + if (!nvalue_table) return; - } for (i = 0, j = 0; i < count; i++) { u32 v; @@ -101,11 +99,8 @@ static int __init sr_dev_init(struct omap_hwmod *oh, void *user) static int i; sr_data = kzalloc(sizeof(*sr_data), GFP_KERNEL); - if (!sr_data) { - pr_err("%s: Unable to allocate memory for %s sr_data\n", - __func__, oh->name); + if (!sr_data) return -ENOMEM; - } sr_dev_attr = (struct omap_smartreflex_dev_attr *)oh->dev_attr; if (!sr_dev_attr || !sr_dev_attr->sensor_voltdm_name) { -- cgit From 48f6693790aa899c813a83f12be1d723849dc3a2 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Wed, 31 May 2017 15:51:33 -0700 Subject: ARM: OMAP2+: Remove unused legacy code for McBSP We are now booting all mach-omap2 in device tree only mode. Any code that is only called in legacy boot mode where of_have_populated_dt() is not set is safe to remove now. Acked-by: Peter Ujfalusi Reviewed-by: Sebastian Reichel Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/mcbsp.c | 70 --------------------------------------------- 1 file changed, 70 deletions(-) diff --git a/arch/arm/mach-omap2/mcbsp.c b/arch/arm/mach-omap2/mcbsp.c index fc04be74e064..4acc0dae27e0 100644 --- a/arch/arm/mach-omap2/mcbsp.c +++ b/arch/arm/mach-omap2/mcbsp.c @@ -53,73 +53,3 @@ void __init omap3_mcbsp_init_pdata_callback( pdata->force_ick_on = omap3_mcbsp_force_ick_on; } - -static int __init omap_init_mcbsp(struct omap_hwmod *oh, void *unused) -{ - int id, count = 1; - char *name = "omap-mcbsp"; - struct omap_hwmod *oh_device[2]; - struct omap_mcbsp_platform_data *pdata = NULL; - struct platform_device *pdev; - - sscanf(oh->name, "mcbsp%d", &id); - - pdata = kzalloc(sizeof(struct omap_mcbsp_platform_data), GFP_KERNEL); - if (!pdata) { - pr_err("%s: No memory for mcbsp\n", __func__); - return -ENOMEM; - } - - pdata->reg_step = 4; - if (oh->class->rev < MCBSP_CONFIG_TYPE2) { - pdata->reg_size = 2; - } else { - pdata->reg_size = 4; - pdata->has_ccr = true; - } - - if (oh->class->rev == MCBSP_CONFIG_TYPE2) { - /* The FIFO has 128 locations */ - pdata->buffer_size = 0x80; - } else if (oh->class->rev == MCBSP_CONFIG_TYPE3) { - if (id == 2) - /* The FIFO has 1024 + 256 locations */ - pdata->buffer_size = 0x500; - else - /* The FIFO has 128 locations */ - pdata->buffer_size = 0x80; - } else if (oh->class->rev == MCBSP_CONFIG_TYPE4) { - /* The FIFO has 128 locations for all instances */ - pdata->buffer_size = 0x80; - } - - if (oh->class->rev >= MCBSP_CONFIG_TYPE3) - pdata->has_wakeup = true; - - oh_device[0] = oh; - - if (oh->dev_attr) { - oh_device[1] = omap_hwmod_lookup(( - (struct omap_mcbsp_dev_attr *)(oh->dev_attr))->sidetone); - pdata->force_ick_on = omap3_mcbsp_force_ick_on; - count++; - } - pdev = omap_device_build_ss(name, id, oh_device, count, pdata, - sizeof(*pdata)); - kfree(pdata); - if (IS_ERR(pdev)) { - pr_err("%s: Can't build omap_device for %s:%s.\n", __func__, - name, oh->name); - return PTR_ERR(pdev); - } - return 0; -} - -static int __init omap2_mcbsp_init(void) -{ - if (!of_have_populated_dt()) - omap_hwmod_for_each_by_class("mcbsp", omap_init_mcbsp, NULL); - - return 0; -} -omap_arch_initcall(omap2_mcbsp_init); -- cgit From 58a641c827e2ef75b93bf799b05be28eb20cca23 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Wed, 31 May 2017 15:51:34 -0700 Subject: ARM: OMAP2+: Remove unused legacy code for io.c We are now booting all mach-omap2 in device tree only mode. Any code that is only called in legacy boot mode where of_have_populated_dt() is not set is safe to remove now. Reviewed-by: Sebastian Reichel Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/io.c | 59 ++++++++++++------------------------------------ 1 file changed, 14 insertions(+), 45 deletions(-) diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c index 5aafb8449c40..1d739d1a0a65 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c @@ -493,67 +493,39 @@ void __init omap3_init_early(void) omap2_set_globals_tap(OMAP343X_CLASS, OMAP2_L4_IO_ADDRESS(0x4830A000)); omap2_set_globals_sdrc(OMAP2_L3_IO_ADDRESS(OMAP343X_SDRC_BASE), OMAP2_L3_IO_ADDRESS(OMAP343X_SMS_BASE)); - /* XXX: remove these once OMAP3 is DT only */ - if (!of_have_populated_dt()) { - omap2_set_globals_control( - OMAP2_L4_IO_ADDRESS(OMAP343X_CTRL_BASE)); - omap2_set_globals_prm(OMAP2_L4_IO_ADDRESS(OMAP3430_PRM_BASE)); - omap2_set_globals_cm(OMAP2_L4_IO_ADDRESS(OMAP3430_CM_BASE), - NULL); - } omap2_control_base_init(); omap3xxx_check_revision(); omap3xxx_check_features(); omap2_prcm_base_init(); - /* XXX: remove these once OMAP3 is DT only */ - if (!of_have_populated_dt()) { - omap3xxx_prm_init(NULL); - omap3xxx_cm_init(NULL); - } omap3xxx_voltagedomains_init(); omap3xxx_powerdomains_init(); omap3xxx_clockdomains_init(); omap3xxx_hwmod_init(); omap_hwmod_init_postsetup(); - if (!of_have_populated_dt()) { - omap3_control_legacy_iomap_init(); - if (soc_is_am35xx()) - omap_clk_soc_init = am35xx_clk_legacy_init; - else if (cpu_is_omap3630()) - omap_clk_soc_init = omap36xx_clk_legacy_init; - else if (omap_rev() == OMAP3430_REV_ES1_0) - omap_clk_soc_init = omap3430es1_clk_legacy_init; - else - omap_clk_soc_init = omap3430_clk_legacy_init; - } } void __init omap3430_init_early(void) { omap3_init_early(); - if (of_have_populated_dt()) - omap_clk_soc_init = omap3430_dt_clk_init; + omap_clk_soc_init = omap3430_dt_clk_init; } void __init omap35xx_init_early(void) { omap3_init_early(); - if (of_have_populated_dt()) - omap_clk_soc_init = omap3430_dt_clk_init; + omap_clk_soc_init = omap3430_dt_clk_init; } void __init omap3630_init_early(void) { omap3_init_early(); - if (of_have_populated_dt()) - omap_clk_soc_init = omap3630_dt_clk_init; + omap_clk_soc_init = omap3630_dt_clk_init; } void __init am35xx_init_early(void) { omap3_init_early(); - if (of_have_populated_dt()) - omap_clk_soc_init = am35xx_dt_clk_init; + omap_clk_soc_init = am35xx_dt_clk_init; } void __init omap3_init_late(void) @@ -628,8 +600,7 @@ void __init ti816x_init_early(void) ti816x_clockdomains_init(); dm816x_hwmod_init(); omap_hwmod_init_postsetup(); - if (of_have_populated_dt()) - omap_clk_soc_init = dm816x_dt_clk_init; + omap_clk_soc_init = dm816x_dt_clk_init; } #endif @@ -785,21 +756,19 @@ int __init omap_clk_init(void) omap2_clk_setup_ll_ops(); - if (of_have_populated_dt()) { - ret = omap_control_init(); - if (ret) - return ret; + ret = omap_control_init(); + if (ret) + return ret; - ret = omap_prcm_init(); - if (ret) - return ret; + ret = omap_prcm_init(); + if (ret) + return ret; - of_clk_init(NULL); + of_clk_init(NULL); - ti_dt_clk_init_retry_clks(); + ti_dt_clk_init_retry_clks(); - ti_dt_clockdomains_setup(); - } + ti_dt_clockdomains_setup(); ret = omap_clk_soc_init(); -- cgit From 2a26d31b1bae5d07b97fc05755053295da686ec7 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Wed, 31 May 2017 15:51:36 -0700 Subject: ARM: OMAP2+: Remove unused legacy code for PRM We are now booting all mach-omap2 in device tree only mode. Any code that is only called in legacy boot mode where of_have_populated_dt() is not set is safe to remove now. Reviewed-by: Sebastian Reichel Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/prm3xxx.c | 17 +++++------- arch/arm/mach-omap2/prm44xx.c | 59 ---------------------------------------- arch/arm/mach-omap2/prm_common.c | 9 ++---- 3 files changed, 10 insertions(+), 75 deletions(-) diff --git a/arch/arm/mach-omap2/prm3xxx.c b/arch/arm/mach-omap2/prm3xxx.c index 718981bb80cd..395cf43b5c5e 100644 --- a/arch/arm/mach-omap2/prm3xxx.c +++ b/arch/arm/mach-omap2/prm3xxx.c @@ -690,6 +690,8 @@ static const struct of_device_id omap3_prm_dt_match_table[] = { static int omap3xxx_prm_late_init(void) { + struct device_node *np; + int irq_num; int ret; if (!(prm_features & PRM_HAS_IO_WAKEUP)) @@ -702,16 +704,11 @@ static int omap3xxx_prm_late_init(void) omap3_prcm_irq_setup.reconfigure_io_chain = omap3430_pre_es3_1_reconfigure_io_chain; - if (of_have_populated_dt()) { - struct device_node *np; - int irq_num; - - np = of_find_matching_node(NULL, omap3_prm_dt_match_table); - if (np) { - irq_num = of_irq_get(np, 0); - if (irq_num >= 0) - omap3_prcm_irq_setup.irq = irq_num; - } + np = of_find_matching_node(NULL, omap3_prm_dt_match_table); + if (np) { + irq_num = of_irq_get(np, 0); + if (irq_num >= 0) + omap3_prcm_irq_setup.irq = irq_num; } omap3xxx_prm_enable_io_wakeup(); diff --git a/arch/arm/mach-omap2/prm44xx.c b/arch/arm/mach-omap2/prm44xx.c index 30768003f854..b045f974dc47 100644 --- a/arch/arm/mach-omap2/prm44xx.c +++ b/arch/arm/mach-omap2/prm44xx.c @@ -336,27 +336,6 @@ static void omap44xx_prm_reconfigure_io_chain(void) return; } -/** - * omap44xx_prm_enable_io_wakeup - enable wakeup events from I/O wakeup latches - * - * Activates the I/O wakeup event latches and allows events logged by - * those latches to signal a wakeup event to the PRCM. For I/O wakeups - * to occur, WAKEUPENABLE bits must be set in the pad mux registers, and - * omap44xx_prm_reconfigure_io_chain() must be called. No return value. - */ -static void __init omap44xx_prm_enable_io_wakeup(void) -{ - s32 inst = omap4_prmst_get_prm_dev_inst(); - - if (inst == PRM_INSTANCE_UNKNOWN) - return; - - omap4_prm_rmw_inst_reg_bits(OMAP4430_GLOBAL_WUEN_MASK, - OMAP4430_GLOBAL_WUEN_MASK, - inst, - omap4_prcm_irq_setup.pm_ctrl); -} - /** * omap44xx_prm_read_reset_sources - return the last SoC reset source * @@ -689,8 +668,6 @@ struct pwrdm_ops omap4_pwrdm_operations = { .pwrdm_has_voltdm = omap4_check_vcvp, }; -static int omap44xx_prm_late_init(void); - /* * XXX document */ @@ -698,7 +675,6 @@ static struct prm_ll_data omap44xx_prm_ll_data = { .read_reset_sources = &omap44xx_prm_read_reset_sources, .was_any_context_lost_old = &omap44xx_prm_was_any_context_lost_old, .clear_context_loss_flags_old = &omap44xx_prm_clear_context_loss_flags_old, - .late_init = &omap44xx_prm_late_init, .assert_hardreset = omap4_prminst_assert_hardreset, .deassert_hardreset = omap4_prminst_deassert_hardreset, .is_hardreset_asserted = omap4_prminst_is_hardreset_asserted, @@ -735,41 +711,6 @@ int __init omap44xx_prm_init(const struct omap_prcm_init_data *data) return prm_register(&omap44xx_prm_ll_data); } -static int omap44xx_prm_late_init(void) -{ - int irq_num; - - if (!(prm_features & PRM_HAS_IO_WAKEUP)) - return 0; - - /* OMAP4+ is DT only now */ - if (!of_have_populated_dt()) - return 0; - - irq_num = of_irq_get(prm_init_data->np, 0); - /* - * Already have OMAP4 IRQ num. For all other platforms, we need - * IRQ numbers from DT - */ - if (irq_num < 0 && !(prm_init_data->flags & PRM_IRQ_DEFAULT)) { - if (irq_num == -EPROBE_DEFER) - return irq_num; - - /* Have nothing to do */ - return 0; - } - - /* Once OMAP4 DT is filled as well */ - if (irq_num >= 0) { - omap4_prcm_irq_setup.irq = irq_num; - omap4_prcm_irq_setup.xlate_irq = NULL; - } - - omap44xx_prm_enable_io_wakeup(); - - return omap_prcm_register_chain_handler(&omap4_prcm_irq_setup); -} - static void __exit omap44xx_prm_exit(void) { prm_unregister(&omap44xx_prm_ll_data); diff --git a/arch/arm/mach-omap2/prm_common.c b/arch/arm/mach-omap2/prm_common.c index 2b138b65129a..538980ee20d4 100644 --- a/arch/arm/mach-omap2/prm_common.c +++ b/arch/arm/mach-omap2/prm_common.c @@ -267,10 +267,9 @@ int omap_prcm_register_chain_handler(struct omap_prcm_irq_setup *irq_setup) { int nr_regs; u32 mask[OMAP_PRCM_MAX_NR_PENDING_REG]; - int offset, i; + int offset, i, irq; struct irq_chip_generic *gc; struct irq_chip_type *ct; - unsigned int irq; if (!irq_setup) return -EINVAL; @@ -344,10 +343,8 @@ int omap_prcm_register_chain_handler(struct omap_prcm_irq_setup *irq_setup) prcm_irq_chips[i] = gc; } - if (of_have_populated_dt()) { - int irq = omap_prcm_event_to_irq("io"); - omap_pcs_legacy_init(irq, irq_setup->reconfigure_io_chain); - } + irq = omap_prcm_event_to_irq("io"); + omap_pcs_legacy_init(irq, irq_setup->reconfigure_io_chain); return 0; -- cgit From 1aa8f0cb19e59a0def9925d401d628c1846c3270 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Wed, 31 May 2017 15:51:37 -0700 Subject: ARM: OMAP2+: Remove unused legacy code for interconnects We are now booting all mach-omap2 in device tree only mode. Any code that is only called in legacy boot mode where of_have_populated_dt() is not set is safe to remove now. Reviewed-by: Sebastian Reichel Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/omap_device.c | 5 +---- arch/arm/mach-omap2/omap_hwmod.c | 23 ++++++++++------------- arch/arm/mach-omap2/omap_hwmod_3xxx_data.c | 3 +-- 3 files changed, 12 insertions(+), 19 deletions(-) diff --git a/arch/arm/mach-omap2/omap_device.c b/arch/arm/mach-omap2/omap_device.c index f989145480c8..ef9ffb8ac912 100644 --- a/arch/arm/mach-omap2/omap_device.c +++ b/arch/arm/mach-omap2/omap_device.c @@ -65,7 +65,7 @@ static void _add_clkdev(struct omap_device *od, const char *clk_alias, r = clk_get_sys(NULL, clk_name); - if (IS_ERR(r) && of_have_populated_dt()) { + if (IS_ERR(r)) { struct of_phandle_args clkspec; clkspec.np = of_find_node_by_name(NULL, clk_name); @@ -953,9 +953,6 @@ static int __init omap_device_late_init(void) { bus_for_each_dev(&platform_bus_type, NULL, NULL, omap_device_late_idle); - WARN(!of_have_populated_dt(), - "legacy booting deprecated, please update to boot with .dts\n"); - return 0; } omap_late_initcall_sync(omap_device_late_init); diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 8bcea0d83fa0..0f7afdaf80d3 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -2334,24 +2334,21 @@ static int __init _init(struct omap_hwmod *oh, void *data) { int r, index; struct device_node *np = NULL; + struct device_node *bus; if (oh->_state != _HWMOD_STATE_REGISTERED) return 0; - if (of_have_populated_dt()) { - struct device_node *bus; - - bus = of_find_node_by_name(NULL, "ocp"); - if (!bus) - return -ENODEV; + bus = of_find_node_by_name(NULL, "ocp"); + if (!bus) + return -ENODEV; - r = of_dev_hwmod_lookup(bus, oh, &index, &np); - if (r) - pr_debug("omap_hwmod: %s missing dt data\n", oh->name); - else if (np && index) - pr_warn("omap_hwmod: %s using broken dt data from %s\n", - oh->name, np->name); - } + r = of_dev_hwmod_lookup(bus, oh, &index, &np); + if (r) + pr_debug("omap_hwmod: %s missing dt data\n", oh->name); + else if (np && index) + pr_warn("omap_hwmod: %s using broken dt data from %s\n", + oh->name, np->name); r = _init_mpu_rt_base(oh, NULL, index, np); if (r < 0) { diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c index 1c6ca4d5fa2d..c3276436b0ae 100644 --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c @@ -3204,8 +3204,7 @@ int __init omap3xxx_hwmod_init(void) * If DT information is missing, enable them only for GP devices. */ - if (of_have_populated_dt()) - bus = of_find_node_by_name(NULL, "ocp"); + bus = of_find_node_by_name(NULL, "ocp"); if (h_sham && omap3xxx_hwmod_is_hs_ip_block_usable(bus, "sham")) { r = omap_hwmod_register_links(h_sham); -- cgit From 279ebec8f4721d6d3eaacfa218110df508618e2c Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Wed, 31 May 2017 15:51:38 -0700 Subject: ARM: OMAP2+: Remove unused legacy code for watchdog We are now booting all mach-omap2 in device tree only mode. Any code that is only called in legacy boot mode where of_have_populated_dt() is not set is safe to remove now. Reviewed-by: Sebastian Reichel Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/wd_timer.c | 28 ---------------------------- 1 file changed, 28 deletions(-) diff --git a/arch/arm/mach-omap2/wd_timer.c b/arch/arm/mach-omap2/wd_timer.c index ff0a68cf7439..0084b6c77cf1 100644 --- a/arch/arm/mach-omap2/wd_timer.c +++ b/arch/arm/mach-omap2/wd_timer.c @@ -102,31 +102,3 @@ int omap2_wd_timer_reset(struct omap_hwmod *oh) return (c == MAX_MODULE_SOFTRESET_WAIT) ? -ETIMEDOUT : omap2_wd_timer_disable(oh); } - -static int __init omap_init_wdt(void) -{ - int id = -1; - struct platform_device *pdev; - struct omap_hwmod *oh; - char *oh_name = "wd_timer2"; - char *dev_name = "omap_wdt"; - struct omap_wd_timer_platform_data pdata; - - if (!cpu_class_is_omap2() || of_have_populated_dt()) - return 0; - - oh = omap_hwmod_lookup(oh_name); - if (!oh) { - pr_err("Could not look up wd_timer%d hwmod\n", id); - return -EINVAL; - } - - pdata.read_reset_sources = prm_read_reset_sources; - - pdev = omap_device_build(dev_name, id, oh, &pdata, - sizeof(struct omap_wd_timer_platform_data)); - WARN(IS_ERR(pdev), "Can't build omap_device for %s:%s.\n", - dev_name, oh->name); - return 0; -} -omap_subsys_initcall(omap_init_wdt); -- cgit From 0e78b1218df37f1a1834dff853d967444e332bab Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Wed, 31 May 2017 15:51:39 -0700 Subject: ARM: OMAP2+: Remove unused legacy code for n8x0 We are now booting all mach-omap2 in device tree only mode. Any code that is only called in legacy boot mode where of_have_populated_dt() is not set is safe to remove now. Reviewed-by: Sebastian Reichel [tony@atomide.com: left out probe changes to avoid merge conflict] Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/board-n8x0.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/arch/arm/mach-omap2/board-n8x0.c b/arch/arm/mach-omap2/board-n8x0.c index 91272db09fa3..20f25539d572 100644 --- a/arch/arm/mach-omap2/board-n8x0.c +++ b/arch/arm/mach-omap2/board-n8x0.c @@ -53,14 +53,12 @@ static u32 board_caps; static void board_check_revision(void) { - if (of_have_populated_dt()) { - if (of_machine_is_compatible("nokia,n800")) - board_caps = NOKIA_N800; - else if (of_machine_is_compatible("nokia,n810")) - board_caps = NOKIA_N810; - else if (of_machine_is_compatible("nokia,n810-wimax")) - board_caps = NOKIA_N810_WIMAX; - } + if (of_machine_is_compatible("nokia,n800")) + board_caps = NOKIA_N800; + else if (of_machine_is_compatible("nokia,n810")) + board_caps = NOKIA_N810; + else if (of_machine_is_compatible("nokia,n810-wimax")) + board_caps = NOKIA_N810_WIMAX; if (!board_caps) pr_err("Unknown board\n"); -- cgit From 2dda2de5a1e1684aa4d31d0c2db42f6446a76a86 Mon Sep 17 00:00:00 2001 From: Martin Blumenstingl Date: Sun, 4 Jun 2017 20:33:40 +0200 Subject: arm: meson: select the clock controller for Meson8 Select COMMON_CLK_MESON8B also for MACH_MESON8 since the Meson8b clock controller driver can also be used on Meson8 SoCs now that we have a separate compatible for it. Signed-off-by: Martin Blumenstingl Acked-by: Jerome Brunet Signed-off-by: Kevin Hilman --- arch/arm/mach-meson/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-meson/Kconfig b/arch/arm/mach-meson/Kconfig index b6e3acc63e14..ee30511849ca 100644 --- a/arch/arm/mach-meson/Kconfig +++ b/arch/arm/mach-meson/Kconfig @@ -21,6 +21,7 @@ config MACH_MESON8 bool "Amlogic Meson8 SoCs support" default ARCH_MESON select MESON6_TIMER + select COMMON_CLK_MESON8B config MACH_MESON8B bool "Amlogic Meson8b SoCs support" -- cgit From be36e000bc2d28512721c6e09c3df920b1bfad5e Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 9 Jun 2017 12:18:02 +0200 Subject: ARM: at91: fix at91_suspend_entering_slow_clock link error When CONFIG_ARCH_AT91 is enabled, but none of the specific SoC support is in use, some at91 specific drivers fail to link: drivers/tty/serial/atmel_serial.o: In function `atmel_serial_suspend': atmel_serial.c:(.text.atmel_serial_suspend+0x1e): undefined reference to `at91_suspend_entering_slow_clock' drivers/usb/host/ohci-at91.o: In function `ohci_hcd_at91_drv_suspend': ohci-at91.c:(.text.ohci_hcd_at91_drv_suspend+0x12): undefined reference to `at91_suspend_entering_slow_clock' drivers/usb/gadget/udc/at91_udc.o: In function `at91udc_suspend': at91_udc.c:(.text.at91udc_suspend+0x26): undefined reference to `at91_suspend_entering_slow_clock' This changes the at91_suspend_entering_slow_clock hack once more, adding an alternative inline implementation that is used exactly in those cases that don't provide the normal implementation. Fixes: c1892c2379d2 ("ARM: at91: handle CONFIG_PM for armv7m configurations") Signed-off-by: Arnd Bergmann Signed-off-by: Alexandre Belloni --- arch/arm/mach-at91/samv7.c | 9 --------- include/linux/platform_data/atmel.h | 7 +++++++ 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/arch/arm/mach-at91/samv7.c b/arch/arm/mach-at91/samv7.c index 910f0c68db62..11386f190c83 100644 --- a/arch/arm/mach-at91/samv7.c +++ b/arch/arm/mach-at91/samv7.c @@ -15,15 +15,6 @@ #include #include "generic.h" -#ifdef CONFIG_PM -/* This function has to be defined for various drivers that are using it */ -int at91_suspend_entering_slow_clock(void) -{ - return 0; -} -EXPORT_SYMBOL(at91_suspend_entering_slow_clock); -#endif - static const char *const samv7_dt_board_compat[] __initconst = { "atmel,samv7", NULL diff --git a/include/linux/platform_data/atmel.h b/include/linux/platform_data/atmel.h index 3c8825b67298..7b6dce7d6d33 100644 --- a/include/linux/platform_data/atmel.h +++ b/include/linux/platform_data/atmel.h @@ -52,6 +52,13 @@ struct atmel_uart_data { }; /* FIXME: this needs a better location, but gets stuff building again */ +#ifdef CONFIG_ATMEL_PM extern int at91_suspend_entering_slow_clock(void); +#else +static inline int at91_suspend_entering_slow_clock(void) +{ + return 0; +} +#endif #endif /* __ATMEL_H__ */ -- cgit From 8a3d809373c6790b3958f74fa5640aedd4e804dd Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Tue, 13 Jun 2017 14:51:07 +0200 Subject: ARM: at91: remove atmel_nand_data Since AVR32 is gone and the driver rework, struct atmel_nand_data is not used anywhere. Acked-by: Boris Brezillon Signed-off-by: Alexandre Belloni --- include/linux/platform_data/atmel.h | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/include/linux/platform_data/atmel.h b/include/linux/platform_data/atmel.h index 7b6dce7d6d33..70c5c766628e 100644 --- a/include/linux/platform_data/atmel.h +++ b/include/linux/platform_data/atmel.h @@ -7,8 +7,6 @@ #ifndef __ATMEL_H__ #define __ATMEL_H__ -#include -#include #include /* Compact Flash */ @@ -23,25 +21,6 @@ struct at91_cf_data { #define AT91_IDE_SWAP_A0_A2 0x02 }; - /* NAND / SmartMedia */ -struct atmel_nand_data { - int enable_pin; /* chip enable */ - int det_pin; /* card detect */ - int rdy_pin; /* ready/busy */ - u8 rdy_pin_active_low; /* rdy_pin value is inverted */ - u8 ale; /* address line number connected to ALE */ - u8 cle; /* address line number connected to CLE */ - u8 bus_width_16; /* buswidth is 16 bit */ - u8 ecc_mode; /* ecc mode */ - u8 on_flash_bbt; /* bbt on flash */ - struct mtd_partition *parts; - unsigned int num_parts; - bool has_dma; /* support dma transfer */ - - /* default is false, only for at32ap7000 chip is true */ - bool need_reset_workaround; -}; - /* Serial */ struct atmel_uart_data { int num; /* port num */ -- cgit From 7ade445c26269d5af6c34ee50be97d54a3992d02 Mon Sep 17 00:00:00 2001 From: Petr Cvek Date: Mon, 13 Mar 2017 09:05:49 +0100 Subject: ARM: pxa: magician: Add support for ADS7846 touchscreen This patch adds a support for ADS7846 touchscreen driver. The basic functionality was tested, x_plate_ohms and y_plate_ohms were physically measured. The value pressure_max was empirically set to match the measured range, which is affected by x_plate_ohms and ADS samples. The value of keep_vref_on should be set. A tested model (T-Mobile MDA Compact PM10A) doesn't seem to use Vref pin as the input from an external source. On this model the unset keep_vref_on cause high jitter of measured values. SPI framing pin (gpio_cs) must be used in GPIO mode due to an incompatible autoframing of PXA27x controller and ADS7846 device. Signed-off-by: Petr Cvek Signed-off-by: Robert Jarzmik --- arch/arm/mach-pxa/include/mach/magician.h | 1 + arch/arm/mach-pxa/magician.c | 84 ++++++++++++++++++++++++++++++- 2 files changed, 84 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-pxa/include/mach/magician.h b/arch/arm/mach-pxa/include/mach/magician.h index 5f6b850ebe33..c48b54d0f331 100644 --- a/arch/arm/mach-pxa/include/mach/magician.h +++ b/arch/arm/mach-pxa/include/mach/magician.h @@ -24,6 +24,7 @@ #define GPIO10_MAGICIAN_GSM_IRQ 10 #define GPIO11_MAGICIAN_GSM_OUT1 11 #define GPIO13_MAGICIAN_CPLD_IRQ 13 +#define GPIO14_MAGICIAN_TSC2046_CS 14 #define GPIO18_MAGICIAN_UNKNOWN 18 #define GPIO22_MAGICIAN_VIBRA_EN 22 #define GPIO26_MAGICIAN_GSM_POWER 26 diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c index b413e36506af..7f3566c93733 100644 --- a/arch/arm/mach-pxa/magician.c +++ b/arch/arm/mach-pxa/magician.c @@ -54,6 +54,10 @@ #include "devices.h" #include "generic.h" +#include +#include +#include + static unsigned long magician_pin_config[] __initdata = { /* SDRAM and Static Memory I/O Signals */ @@ -85,7 +89,7 @@ static unsigned long magician_pin_config[] __initdata = { /* SSP 2 TSC2046 touchscreen */ GPIO19_SSP2_SCLK, - GPIO14_SSP2_SFRM, + MFP_CFG_OUT(GPIO14, AF0, DRIVE_HIGH), /* frame as GPIO */ GPIO89_SSP2_TXD, GPIO88_SSP2_RXD, @@ -674,6 +678,37 @@ static struct platform_device bq24022 = { }, }; +/* + * fixed regulator for ads7846 + */ + +static struct regulator_consumer_supply ads7846_supply = + REGULATOR_SUPPLY("vcc", "spi2.0"); + +static struct regulator_init_data vads7846_regulator = { + .constraints = { + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = 1, + .consumer_supplies = &ads7846_supply, +}; + +static struct fixed_voltage_config vads7846 = { + .supply_name = "vads7846", + .microvolts = 3300000, /* probably */ + .gpio = -EINVAL, + .startup_delay = 0, + .init_data = &vads7846_regulator, +}; + +static struct platform_device vads7846_device = { + .name = "reg-fixed-voltage", + .id = -1, + .dev = { + .platform_data = &vads7846, + }, +}; + /* * Vcore regulator MAX1587A */ @@ -851,6 +886,49 @@ static struct i2c_pxa_platform_data magician_i2c_power_info = { .fast_mode = 1, }; +/* + * Touchscreen + */ + +static struct ads7846_platform_data ads7846_pdata = { + .model = 7846, + .x_plate_ohms = 317, + .y_plate_ohms = 500, + .pressure_max = 1023, /* with x plate ohms it will overflow 255 */ + .debounce_max = 3, /* first readout is always bad */ + .debounce_tol = 30, + .debounce_rep = 0, + .gpio_pendown = GPIO115_MAGICIAN_nPEN_IRQ, + .keep_vref_on = 1, + .wakeup = true, + .vref_delay_usecs = 100, + .penirq_recheck_delay_usecs = 100, +}; + +struct pxa2xx_spi_chip tsc2046_chip_info = { + .tx_threshold = 1, + .rx_threshold = 2, + .timeout = 64, + /* NOTICE must be GPIO, incompatibility with hw PXA SPI framing */ + .gpio_cs = GPIO14_MAGICIAN_TSC2046_CS, +}; + +static struct pxa2xx_spi_master magician_spi_info = { + .num_chipselect = 1, + .enable_dma = 1, +}; + +static struct spi_board_info ads7846_spi_board_info[] __initdata = { + { + .modalias = "ads7846", + .bus_num = 2, + .max_speed_hz = 2500000, + .platform_data = &ads7846_pdata, + .controller_data = &tsc2046_chip_info, + .irq = PXA_GPIO_TO_IRQ(GPIO115_MAGICIAN_nPEN_IRQ), + }, +}; + /* * Platform devices */ @@ -865,6 +943,7 @@ static struct platform_device *devices[] __initdata = { &power_supply, &strataflash, &leds_gpio, + &vads7846_device, }; static struct gpio magician_global_gpios[] = { @@ -922,6 +1001,9 @@ static void __init magician_init(void) } else pr_err("LCD detection: CPLD mapping failed\n"); + pxa2xx_set_spi_info(2, &magician_spi_info); + spi_register_board_info(ARRAY_AND_SIZE(ads7846_spi_board_info)); + regulator_register_always_on(0, "power", pwm_backlight_supply, ARRAY_SIZE(pwm_backlight_supply), 5000000); -- cgit From c276557de3087ef67ad1aec4222f9f8b1d005f80 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Sat, 3 Jun 2017 21:34:48 +0200 Subject: ARM: pxa: Delete an error message for a failed memory allocation in pxa_pm_init() Omit an extra message for a memory allocation failure in this function. This issue was detected by using the Coccinelle software. Link: http://events.linuxfoundation.org/sites/events/files/slides/LCJ16-Refactor_Strings-WSang_0.pdf Signed-off-by: Markus Elfring Signed-off-by: Robert Jarzmik --- arch/arm/mach-pxa/pm.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/arch/arm/mach-pxa/pm.c b/arch/arm/mach-pxa/pm.c index e7450fb49d24..f2237f471750 100644 --- a/arch/arm/mach-pxa/pm.c +++ b/arch/arm/mach-pxa/pm.c @@ -107,10 +107,8 @@ static int __init pxa_pm_init(void) sleep_save = kmalloc_array(pxa_cpu_pm_fns->save_count, sizeof(*sleep_save), GFP_KERNEL); - if (!sleep_save) { - printk(KERN_ERR "failed to alloc memory for pm save\n"); + if (!sleep_save) return -ENOMEM; - } suspend_set_ops(&pxa_pm_ops); return 0; -- cgit From 361f7cc7f33607489bea815f9148e8e9a13ea673 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Sat, 3 Jun 2017 21:43:11 +0200 Subject: ARM: pxa: Improve a size determination in pxa3xx_u2d_probe() Replace the specification of a data structure by a pointer dereference as the parameter for the operator "sizeof" to make the corresponding size determination a bit safer according to the Linux coding style convention. Signed-off-by: Markus Elfring Signed-off-by: Robert Jarzmik --- arch/arm/mach-pxa/pxa3xx-ulpi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-pxa/pxa3xx-ulpi.c b/arch/arm/mach-pxa/pxa3xx-ulpi.c index eba595fac8ca..13f9909ac8bf 100644 --- a/arch/arm/mach-pxa/pxa3xx-ulpi.c +++ b/arch/arm/mach-pxa/pxa3xx-ulpi.c @@ -286,7 +286,7 @@ static int pxa3xx_u2d_probe(struct platform_device *pdev) struct resource *r; int err; - u2d = kzalloc(sizeof(struct pxa3xx_u2d_ulpi), GFP_KERNEL); + u2d = kzalloc(sizeof(*u2d), GFP_KERNEL); if (!u2d) { dev_err(&pdev->dev, "failed to allocate memory\n"); return -ENOMEM; -- cgit From ce3de60ff92ba5e4d65f1c1ce07460795e3a6157 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Sat, 3 Jun 2017 21:46:26 +0200 Subject: ARM: pxa: Delete an error message for a failed memory allocation in pxa3xx_u2d_probe() Omit an extra message for a memory allocation failure in this function. This issue was detected by using the Coccinelle software. Link: http://events.linuxfoundation.org/sites/events/files/slides/LCJ16-Refactor_Strings-WSang_0.pdf Signed-off-by: Markus Elfring Signed-off-by: Robert Jarzmik --- arch/arm/mach-pxa/pxa3xx-ulpi.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/arch/arm/mach-pxa/pxa3xx-ulpi.c b/arch/arm/mach-pxa/pxa3xx-ulpi.c index 13f9909ac8bf..60cb59a7ebd1 100644 --- a/arch/arm/mach-pxa/pxa3xx-ulpi.c +++ b/arch/arm/mach-pxa/pxa3xx-ulpi.c @@ -287,10 +287,8 @@ static int pxa3xx_u2d_probe(struct platform_device *pdev) int err; u2d = kzalloc(sizeof(*u2d), GFP_KERNEL); - if (!u2d) { - dev_err(&pdev->dev, "failed to allocate memory\n"); + if (!u2d) return -ENOMEM; - } u2d->clk = clk_get(&pdev->dev, NULL); if (IS_ERR(u2d->clk)) { -- cgit From 9a9ded89ad9ca46382a4ea63f36f830bccfab4ec Mon Sep 17 00:00:00 2001 From: Sebastian Reichel Date: Tue, 13 Jun 2017 11:28:45 +0200 Subject: ARM: OMAP4: hwmod data: add aes1 This fixes the following error during kernel boot: platform 4b501000.aes: Cannot lookup hwmod 'aes1' Unfortunately the AES module is only documented partly in the OMAP4430 TRM. I found an old patch from Joel, which I took over and updated for currently mainline. Signed-off-by: Joel Fernandes Signed-off-by: Sebastian Reichel Acked-by: Tero Kristo Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 41 ++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index 0855434773fa..7833caf277b6 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -960,6 +960,46 @@ static struct omap_hwmod omap44xx_emif2_hwmod = { }, }; +/* + Crypto modules AES0/1 belong to: + PD_L4_PER power domain + CD_L4_SEC clock domain + On the L3, the AES modules are mapped to + L3_CLK2: Peripherals and multimedia sub clock domain +*/ +static struct omap_hwmod_class_sysconfig omap44xx_aes_sysc = { + .rev_offs = 0x80, + .sysc_offs = 0x84, + .syss_offs = 0x88, + .sysc_flags = SYSS_HAS_RESET_STATUS, +}; + +static struct omap_hwmod_class omap44xx_aes_hwmod_class = { + .name = "aes", + .sysc = &omap44xx_aes_sysc, +}; + +static struct omap_hwmod omap44xx_aes1_hwmod = { + .name = "aes1", + .class = &omap44xx_aes_hwmod_class, + .clkdm_name = "l4_secure_clkdm", + .main_clk = "l3_div_ck", + .prcm = { + .omap4 = { + .context_offs = OMAP4_RM_L4SEC_AES1_CONTEXT_OFFSET, + .clkctrl_offs = OMAP4_CM_L4SEC_AES1_CLKCTRL_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +static struct omap_hwmod_ocp_if omap44xx_l3_main_2__aes1 = { + .master = &omap44xx_l4_per_hwmod, + .slave = &omap44xx_aes1_hwmod, + .clk = "l3_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + /* * 'fdif' class * face detection hw accelerator module @@ -4801,6 +4841,7 @@ static struct omap_hwmod_ocp_if *omap44xx_hwmod_ocp_ifs[] __initdata = { &omap44xx_l4_abe__wd_timer3_dma, &omap44xx_mpu__emif1, &omap44xx_mpu__emif2, + &omap44xx_l3_main_2__aes1, NULL, }; -- cgit From 478523dd0341df5833b9f51cae3f9a7c3d20e6bb Mon Sep 17 00:00:00 2001 From: Sebastian Reichel Date: Tue, 13 Jun 2017 11:28:46 +0200 Subject: ARM: OMAP4: hwmod data: add aes2 This adds the hwmod entry for the second AES module available on OMAP4. Signed-off-by: Sebastian Reichel Acked-by: Tero Kristo Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index 7833caf277b6..e1b085977049 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -1000,6 +1000,27 @@ static struct omap_hwmod_ocp_if omap44xx_l3_main_2__aes1 = { .user = OCP_USER_MPU | OCP_USER_SDMA, }; +static struct omap_hwmod omap44xx_aes2_hwmod = { + .name = "aes2", + .class = &omap44xx_aes_hwmod_class, + .clkdm_name = "l4_secure_clkdm", + .main_clk = "l3_div_ck", + .prcm = { + .omap4 = { + .context_offs = OMAP4_RM_L4SEC_AES2_CONTEXT_OFFSET, + .clkctrl_offs = OMAP4_CM_L4SEC_AES2_CLKCTRL_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +static struct omap_hwmod_ocp_if omap44xx_l3_main_2__aes2 = { + .master = &omap44xx_l4_per_hwmod, + .slave = &omap44xx_aes2_hwmod, + .clk = "l3_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + /* * 'fdif' class * face detection hw accelerator module @@ -4842,6 +4863,7 @@ static struct omap_hwmod_ocp_if *omap44xx_hwmod_ocp_ifs[] __initdata = { &omap44xx_mpu__emif1, &omap44xx_mpu__emif2, &omap44xx_l3_main_2__aes1, + &omap44xx_l3_main_2__aes2, NULL, }; -- cgit From ebea90df78c1f290529e18b85c19653e131954de Mon Sep 17 00:00:00 2001 From: Sebastian Reichel Date: Tue, 13 Jun 2017 11:28:47 +0200 Subject: ARM: OMAP4: hwmod data: add des This fixes the following error during kernel boot: platform 480a5000.des: Cannot lookup hwmod 'des' Unfortunately the DES module is only documented partly in the OMAP4430 TRM. I found an old patch from Joel, which I took over and updated for currently mainline. Signed-off-by: Joel Fernandes Signed-off-by: Sebastian Reichel Acked-by: Tero Kristo Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 37 ++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index e1b085977049..ef4389ce65fe 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -1021,6 +1021,42 @@ static struct omap_hwmod_ocp_if omap44xx_l3_main_2__aes2 = { .user = OCP_USER_MPU | OCP_USER_SDMA, }; +/* + * 'des' class for DES3DES module + */ +static struct omap_hwmod_class_sysconfig omap44xx_des_sysc = { + .rev_offs = 0x30, + .sysc_offs = 0x34, + .syss_offs = 0x38, + .sysc_flags = SYSS_HAS_RESET_STATUS, +}; + +static struct omap_hwmod_class omap44xx_des_hwmod_class = { + .name = "des", + .sysc = &omap44xx_des_sysc, +}; + +static struct omap_hwmod omap44xx_des_hwmod = { + .name = "des", + .class = &omap44xx_des_hwmod_class, + .clkdm_name = "l4_secure_clkdm", + .main_clk = "l3_div_ck", + .prcm = { + .omap4 = { + .context_offs = OMAP4_RM_L4SEC_DES3DES_CONTEXT_OFFSET, + .clkctrl_offs = OMAP4_CM_L4SEC_DES3DES_CLKCTRL_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +struct omap_hwmod_ocp_if omap44xx_l3_main_2__des = { + .master = &omap44xx_l3_main_2_hwmod, + .slave = &omap44xx_des_hwmod, + .clk = "l3_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + /* * 'fdif' class * face detection hw accelerator module @@ -4864,6 +4900,7 @@ static struct omap_hwmod_ocp_if *omap44xx_hwmod_ocp_ifs[] __initdata = { &omap44xx_mpu__emif2, &omap44xx_l3_main_2__aes1, &omap44xx_l3_main_2__aes2, + &omap44xx_l3_main_2__des, NULL, }; -- cgit From 1df5eaa6bced2d8a9de305d4a5f587adf57ddf35 Mon Sep 17 00:00:00 2001 From: Tero Kristo Date: Tue, 13 Jun 2017 16:45:50 +0300 Subject: ARM: OMAP4: hwmod_data: add SHAM crypto accelerator OMAP4 SoC contains SHAM crypto hardware accelerator. Add hwmod data for this IP so that it can be utilized by crypto frameworks. Signed-off-by: Tero Kristo Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 36 ++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index ef4389ce65fe..3e2d792fd9df 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -880,6 +880,33 @@ static struct omap_hwmod omap44xx_dss_venc_hwmod = { .opt_clks_cnt = ARRAY_SIZE(dss_venc_opt_clks), }; +/* sha0 HIB2 (the 'P' (public) device) */ +static struct omap_hwmod_class_sysconfig omap44xx_sha0_sysc = { + .rev_offs = 0x100, + .sysc_offs = 0x110, + .syss_offs = 0x114, + .sysc_flags = SYSS_HAS_RESET_STATUS, +}; + +static struct omap_hwmod_class omap44xx_sha0_hwmod_class = { + .name = "sham", + .sysc = &omap44xx_sha0_sysc, +}; + +struct omap_hwmod omap44xx_sha0_hwmod = { + .name = "sham", + .class = &omap44xx_sha0_hwmod_class, + .clkdm_name = "l4_secure_clkdm", + .main_clk = "l3_div_ck", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_L4SEC_SHA2MD51_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L4SEC_SHA2MD51_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + /* * 'elm' class * bch error location module @@ -3987,6 +4014,14 @@ static struct omap_hwmod_ocp_if omap44xx_l4_per__dss_venc = { .user = OCP_USER_MPU, }; +/* l3_main_2 -> sham */ +static struct omap_hwmod_ocp_if omap44xx_l3_main_2__sha0 = { + .master = &omap44xx_l3_main_2_hwmod, + .slave = &omap44xx_sha0_hwmod, + .clk = "l3_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + /* l4_per -> elm */ static struct omap_hwmod_ocp_if omap44xx_l4_per__elm = { .master = &omap44xx_l4_per_hwmod, @@ -4901,6 +4936,7 @@ static struct omap_hwmod_ocp_if *omap44xx_hwmod_ocp_ifs[] __initdata = { &omap44xx_l3_main_2__aes1, &omap44xx_l3_main_2__aes2, &omap44xx_l3_main_2__des, + &omap44xx_l3_main_2__sha0, NULL, }; -- cgit From fd8cf827d8a635df3dad46773ad828ce4c93d95b Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 12 Jun 2017 11:23:46 +0200 Subject: ARM: shmobile: pm-rmobile: Use GENPD_FLAG_ALWAYS_ON Improve handling of always-on PM domains by using the GENPD_FLAG_ALWAYS_ON flag introduced in commit ffaa42e8a40b7f10 ("PM / Domains: Enable users of genpd to specify always on PM domains"). Note that the PM domain containing the serial console is still handled locally. Signed-off-by: Geert Uytterhoeven Reviewed-by: Ulf Hansson Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/pm-rmobile.c | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/arch/arm/mach-shmobile/pm-rmobile.c b/arch/arm/mach-shmobile/pm-rmobile.c index 45a195501b78..699429f28b73 100644 --- a/arch/arm/mach-shmobile/pm-rmobile.c +++ b/arch/arm/mach-shmobile/pm-rmobile.c @@ -130,7 +130,7 @@ static void rmobile_init_pm_domain(struct rmobile_pm_domain *rmobile_pd) struct generic_pm_domain *genpd = &rmobile_pd->genpd; struct dev_power_governor *gov = rmobile_pd->gov; - genpd->flags = GENPD_FLAG_PM_CLK; + genpd->flags |= GENPD_FLAG_PM_CLK; genpd->dev_ops.active_wakeup = rmobile_pd_active_wakeup; genpd->power_off = rmobile_pd_power_down; genpd->power_on = rmobile_pd_power_up; @@ -140,14 +140,6 @@ static void rmobile_init_pm_domain(struct rmobile_pm_domain *rmobile_pd) pm_genpd_init(genpd, gov ? : &simple_qos_governor, false); } -static int rmobile_pd_suspend_busy(void) -{ - /* - * This domain should not be turned off. - */ - return -EBUSY; -} - static int rmobile_pd_suspend_console(void) { /* @@ -260,8 +252,7 @@ static void __init rmobile_setup_pm_domain(struct device_node *np, * only be turned off if the CPU is not in use. */ pr_debug("PM domain %s contains CPU\n", name); - pd->gov = &pm_domain_always_on_gov; - pd->suspend = rmobile_pd_suspend_busy; + pd->genpd.flags |= GENPD_FLAG_ALWAYS_ON; break; case PD_CONSOLE: @@ -277,8 +268,7 @@ static void __init rmobile_setup_pm_domain(struct device_node *np, * is not in use. */ pr_debug("PM domain %s contains Coresight-ETM\n", name); - pd->gov = &pm_domain_always_on_gov; - pd->suspend = rmobile_pd_suspend_busy; + pd->genpd.flags |= GENPD_FLAG_ALWAYS_ON; break; case PD_MEMCTL: @@ -287,8 +277,7 @@ static void __init rmobile_setup_pm_domain(struct device_node *np, * should only be turned off if memory is not in use. */ pr_debug("PM domain %s contains MEMCTL\n", name); - pd->gov = &pm_domain_always_on_gov; - pd->suspend = rmobile_pd_suspend_busy; + pd->genpd.flags |= GENPD_FLAG_ALWAYS_ON; break; case PD_NORMAL: -- cgit From 231ce279e6e37960f8c61d99f86e4937733ed96b Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Fri, 9 Jun 2017 10:21:10 -0700 Subject: ARM: davinci: fix const warnings After VPIF was converted to enable getting subdevs from DT, the pdata is no longer const, so remove these to avoid compiler warnings. Signed-off-by: Kevin Hilman [nsekhar@ti.com: minor commit message fixup] Signed-off-by: Sekhar Nori --- arch/arm/mach-davinci/board-dm646x-evm.c | 4 ++-- arch/arm/mach-davinci/pdata-quirks.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/arm/mach-davinci/board-dm646x-evm.c b/arch/arm/mach-davinci/board-dm646x-evm.c index cb176826d1cb..055e947a6a39 100644 --- a/arch/arm/mach-davinci/board-dm646x-evm.c +++ b/arch/arm/mach-davinci/board-dm646x-evm.c @@ -641,7 +641,7 @@ static struct vpif_subdev_info vpif_capture_sdev_info[] = { }, }; -static const struct vpif_input dm6467_ch0_inputs[] = { +static struct vpif_input dm6467_ch0_inputs[] = { { .input = { .index = 0, @@ -656,7 +656,7 @@ static const struct vpif_input dm6467_ch0_inputs[] = { }, }; -static const struct vpif_input dm6467_ch1_inputs[] = { +static struct vpif_input dm6467_ch1_inputs[] = { { .input = { .index = 0, diff --git a/arch/arm/mach-davinci/pdata-quirks.c b/arch/arm/mach-davinci/pdata-quirks.c index 329f5402ad1d..4858b1cdf31b 100644 --- a/arch/arm/mach-davinci/pdata-quirks.c +++ b/arch/arm/mach-davinci/pdata-quirks.c @@ -33,7 +33,7 @@ static struct tvp514x_platform_data tvp5146_pdata = { #define TVP514X_STD_ALL (V4L2_STD_NTSC | V4L2_STD_PAL) -static const struct vpif_input da850_ch0_inputs[] = { +static struct vpif_input da850_ch0_inputs[] = { { .input = { .index = 0, @@ -48,7 +48,7 @@ static const struct vpif_input da850_ch0_inputs[] = { }, }; -static const struct vpif_input da850_ch1_inputs[] = { +static struct vpif_input da850_ch1_inputs[] = { { .input = { .index = 0, -- cgit From 4435f5dc5cf7b919c96ae0b283d3cca77d069682 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 26 Feb 2017 12:07:00 +0900 Subject: ARM: prima2: remove redundant select CPU_V7 , Barry Song , linux-kernel@vger.kernel.org ARCH_ATLAS7 resides in "if ARCH_SIRF ... end", and ARCH_SIRF depends on ARCH_MULTI_V7, which selects CPU_V7. Signed-off-by: Masahiro Yamada Signed-off-by: Olof Johansson --- arch/arm/mach-prima2/Kconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/mach-prima2/Kconfig b/arch/arm/mach-prima2/Kconfig index 85e874a97337..7426211bddaf 100644 --- a/arch/arm/mach-prima2/Kconfig +++ b/arch/arm/mach-prima2/Kconfig @@ -27,7 +27,6 @@ config ARCH_ATLAS7 bool "CSR SiRFSoC ATLAS7 ARM Cortex A7 Platform" default y select ARM_GIC - select CPU_V7 select ATLAS7_TIMER select HAVE_ARM_SCU if SMP select HAVE_SMP -- cgit From d28bcd53fa90549e00f7dbcdfc885dfe8409e8a2 Mon Sep 17 00:00:00 2001 From: Alexandre TORGUE Date: Mon, 12 Jun 2017 14:22:45 +0200 Subject: ARM: stm32: Introduce MACH_STM32F469 flag This patch introduces the MACH_STM32F469 to make possible to only select STM32F469 pinctrl driver By default, all the MACH_STM32Fxxx flags will be set with STM32 defconfig. Signed-off-by: Alexandre TORGUE Signed-off-by: Olof Johansson --- arch/arm/mach-stm32/Kconfig | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/arm/mach-stm32/Kconfig b/arch/arm/mach-stm32/Kconfig index 2d1419eb0896..0d1889bbde58 100644 --- a/arch/arm/mach-stm32/Kconfig +++ b/arch/arm/mach-stm32/Kconfig @@ -15,6 +15,11 @@ config MACH_STM32F429 depends on ARCH_STM32 default y +config MACH_STM32F469 + bool "STMicrolectronics STM32F469" + depends on ARCH_STM32 + default y + config MACH_STM32F746 bool "STMicrolectronics STM32F746" depends on ARCH_STM32 -- cgit From 139358be24e526bc8d050e319cdd4e2d1941503e Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Tue, 9 May 2017 08:20:03 -0500 Subject: ARM: socfpga: Increase max number of GPIOs Increase the maximum number of GPIOs on SoCFPGA as this platform can have many GPIO controllers in the FPGA part. Signed-off-by: Marek Vasut Signed-off-by: Dinh Nguyen --- arch/arm/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 4c1a35f15838..108c203a8b29 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1460,6 +1460,7 @@ config ARM_PSCI # selected platforms. config ARCH_NR_GPIO int + default 2048 if ARCH_SOCFPGA default 1024 if ARCH_BRCMSTB || ARCH_SHMOBILE || ARCH_TEGRA || \ ARCH_ZYNQ default 512 if ARCH_EXYNOS || ARCH_KEYSTONE || SOC_OMAP5 || \ -- cgit From 6bb8536cba152edee005668bc57cfe6198b73f0f Mon Sep 17 00:00:00 2001 From: Andreas Färber Date: Wed, 15 Feb 2017 11:03:22 +0100 Subject: ARM: Prepare Actions Semi S500 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add ARCH_ACTIONS and mach-actions/owl.c for "actions,s500". Signed-off-by: Andreas Färber --- arch/arm/Kconfig | 2 ++ arch/arm/Makefile | 1 + arch/arm/mach-actions/Kconfig | 15 +++++++++++++++ arch/arm/mach-actions/Makefile | 1 + arch/arm/mach-actions/owl.c | 28 ++++++++++++++++++++++++++++ 5 files changed, 47 insertions(+) create mode 100644 arch/arm/mach-actions/Kconfig create mode 100644 arch/arm/mach-actions/Makefile create mode 100644 arch/arm/mach-actions/owl.c diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 4c1a35f15838..869c3f98f7a2 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -711,6 +711,8 @@ config ARCH_VIRT # source "arch/arm/mach-mvebu/Kconfig" +source "arch/arm/mach-actions/Kconfig" + source "arch/arm/mach-alpine/Kconfig" source "arch/arm/mach-artpec/Kconfig" diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 65f4e2a4eb94..47d3a1ab08d2 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -151,6 +151,7 @@ textofs-$(CONFIG_ARCH_AXXIA) := 0x00308000 # Machine directory name. This list is sorted alphanumerically # by CONFIG_* macro name. +machine-$(CONFIG_ARCH_ACTIONS) += actions machine-$(CONFIG_ARCH_ALPINE) += alpine machine-$(CONFIG_ARCH_ARTPEC) += artpec machine-$(CONFIG_ARCH_AT91) += at91 diff --git a/arch/arm/mach-actions/Kconfig b/arch/arm/mach-actions/Kconfig new file mode 100644 index 000000000000..717adc1630a1 --- /dev/null +++ b/arch/arm/mach-actions/Kconfig @@ -0,0 +1,15 @@ +menuconfig ARCH_ACTIONS + bool "Actions Semi SoCs" + depends on ARCH_MULTI_V7 + select ARM_AMBA + select ARM_GIC + select ARM_GLOBAL_TIMER + select CACHE_L2X0 + select CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK + select COMMON_CLK + select GENERIC_IRQ_CHIP + select HAVE_ARM_SCU if SMP + select HAVE_ARM_TWD if SMP + select OWL_TIMER + help + This enables support for the Actions Semiconductor S500 SoC family. diff --git a/arch/arm/mach-actions/Makefile b/arch/arm/mach-actions/Makefile new file mode 100644 index 000000000000..561b0f39e3f8 --- /dev/null +++ b/arch/arm/mach-actions/Makefile @@ -0,0 +1 @@ +obj-y += owl.o diff --git a/arch/arm/mach-actions/owl.c b/arch/arm/mach-actions/owl.c new file mode 100644 index 000000000000..4ac4a860f3d6 --- /dev/null +++ b/arch/arm/mach-actions/owl.c @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2017 Andreas Färber + * + * 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; either version 2 of the License, or + * (at your option) any later version. + * + * 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 +#include + +static const char * const owl_dt_compat[] = { + "actions,s500", + NULL +}; + +DT_MACHINE_START(OWL, "Actions Semi Owl platform") + .dt_compat = owl_dt_compat, + .l2c_aux_val = 0, + .l2c_aux_mask = ~0, +MACHINE_END -- cgit From 872d1ba47bdc0d96f74a0172c226c81555b27b29 Mon Sep 17 00:00:00 2001 From: Andreas Färber Date: Wed, 22 Feb 2017 04:33:34 +0100 Subject: MAINTAINERS: Add Actions Semi Owl section MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add myself as maintainer. Signed-off-by: Andreas Färber --- MAINTAINERS | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index f7d568b8f133..9a554b684935 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1037,6 +1037,18 @@ S: Maintained F: drivers/amba/ F: include/linux/amba/bus.h +ARM/ACTIONS SEMI ARCHITECTURE +M: Andreas Färber +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) +S: Maintained +N: owl +F: arch/arm/mach-actions/ +F: arch/arm/boot/dts/owl-* +F: arch/arm64/boot/dts/actions/ +F: drivers/clocksource/owl-* +F: Documentation/devicetree/bindings/arm/actions.txt +F: Documentation/devicetree/bindings/timer/actions,owl-timer.txt + ARM/ADS SPHERE MACHINE SUPPORT M: Lennert Buytenhek L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) -- cgit From 172067e0bc8721af3e8626596f91b03f691e88a8 Mon Sep 17 00:00:00 2001 From: Andreas Färber Date: Sun, 26 Feb 2017 17:25:21 +0100 Subject: ARM: owl: Implement CPU enable-method for S500 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Allow to bring up CPU1. Based on LeMaker linux-actions tree. Signed-off-by: Andreas Färber --- arch/arm/mach-actions/Makefile | 3 + arch/arm/mach-actions/headsmp.S | 68 ++++++++++++++++ arch/arm/mach-actions/platsmp.c | 166 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 237 insertions(+) create mode 100644 arch/arm/mach-actions/headsmp.S create mode 100644 arch/arm/mach-actions/platsmp.c diff --git a/arch/arm/mach-actions/Makefile b/arch/arm/mach-actions/Makefile index 561b0f39e3f8..eeb3896e4952 100644 --- a/arch/arm/mach-actions/Makefile +++ b/arch/arm/mach-actions/Makefile @@ -1 +1,4 @@ obj-y += owl.o +obj-${CONFIG_SMP} += platsmp.o headsmp.o + +AFLAGS_headsmp.o := -Wa,-march=armv7-a diff --git a/arch/arm/mach-actions/headsmp.S b/arch/arm/mach-actions/headsmp.S new file mode 100644 index 000000000000..dc4832fc101a --- /dev/null +++ b/arch/arm/mach-actions/headsmp.S @@ -0,0 +1,68 @@ +/* + * Copyright 2012 Actions Semi Inc. + * Author: Actions Semi, 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 the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include + +ENTRY(owl_v7_invalidate_l1) + mov r0, #0 + mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache + mcr p15, 2, r0, c0, c0, 0 + mrc p15, 1, r0, c0, c0, 0 + + ldr r1, =0x7fff + and r2, r1, r0, lsr #13 + + ldr r1, =0x3ff + + and r3, r1, r0, lsr #3 @ NumWays - 1 + add r2, r2, #1 @ NumSets + + and r0, r0, #0x7 + add r0, r0, #4 @ SetShift + + clz r1, r3 @ WayShift + add r4, r3, #1 @ NumWays +1: sub r2, r2, #1 @ NumSets-- + mov r3, r4 @ Temp = NumWays +2: subs r3, r3, #1 @ Temp-- + mov r5, r3, lsl r1 + mov r6, r2, lsl r0 + orr r5, r5, r6 @ Reg = (Temp< +#include +#include +#include +#include +#include +#include +#include + +#define OWL_CPU1_ADDR 0x50 +#define OWL_CPU1_FLAG 0x5c + +#define OWL_CPUx_FLAG_BOOT 0x55aa + +static void __iomem *scu_base_addr; +static void __iomem *timer_base_addr; +static int ncores; + +static DEFINE_SPINLOCK(boot_lock); + +static void write_pen_release(int val) +{ + pen_release = val; + smp_wmb(); + __cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release)); + outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1)); +} + +static void s500_smp_secondary_init(unsigned int cpu) +{ + /* + * let the primary processor know we're out of the + * pen, then head off into the C entry point + */ + write_pen_release(-1); + + spin_lock(&boot_lock); + spin_unlock(&boot_lock); +} + +void owl_secondary_startup(void); + +static int s500_wakeup_secondary(unsigned int cpu) +{ + if (cpu > 3) + return -EINVAL; + + switch (cpu) { + case 2: + case 3: + /* CPU2/3 are power-gated */ + return -EINVAL; + } + + /* wait for CPUx to run to WFE instruction */ + udelay(200); + + writel(virt_to_phys(owl_secondary_startup), + timer_base_addr + OWL_CPU1_ADDR + (cpu - 1) * 4); + writel(OWL_CPUx_FLAG_BOOT, + timer_base_addr + OWL_CPU1_FLAG + (cpu - 1) * 4); + + dsb_sev(); + mb(); + + return 0; +} + +static int s500_smp_boot_secondary(unsigned int cpu, struct task_struct *idle) +{ + unsigned long timeout; + int ret; + + ret = s500_wakeup_secondary(cpu); + if (ret) + return ret; + + udelay(10); + + spin_lock(&boot_lock); + + /* + * The secondary processor is waiting to be released from + * the holding pen - release it, then wait for it to flag + * that it has been released by resetting pen_release. + */ + write_pen_release(cpu_logical_map(cpu)); + smp_send_reschedule(cpu); + + timeout = jiffies + (1 * HZ); + while (time_before(jiffies, timeout)) { + if (pen_release == -1) + break; + } + + writel(0, timer_base_addr + OWL_CPU1_ADDR + (cpu - 1) * 4); + writel(0, timer_base_addr + OWL_CPU1_FLAG + (cpu - 1) * 4); + + spin_unlock(&boot_lock); + + return pen_release != -1 ? -ENOSYS : 0; +} + +static void __init s500_smp_prepare_cpus(unsigned int max_cpus) +{ + struct device_node *node; + + node = of_find_compatible_node(NULL, NULL, "actions,s500-timer"); + if (!node) { + pr_err("%s: missing timer\n", __func__); + return; + } + + timer_base_addr = of_iomap(node, 0); + if (!timer_base_addr) { + pr_err("%s: could not map timer registers\n", __func__); + return; + } + + if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9) { + node = of_find_compatible_node(NULL, NULL, "arm,cortex-a9-scu"); + if (!node) { + pr_err("%s: missing scu\n", __func__); + return; + } + + scu_base_addr = of_iomap(node, 0); + if (!scu_base_addr) { + pr_err("%s: could not map scu registers\n", __func__); + return; + } + + /* + * While the number of cpus is gathered from dt, also get the + * number of cores from the scu to verify this value when + * booting the cores. + */ + ncores = scu_get_core_count(scu_base_addr); + pr_debug("%s: ncores %d\n", __func__, ncores); + + scu_enable(scu_base_addr); + } +} + +static const struct smp_operations s500_smp_ops __initconst = { + .smp_prepare_cpus = s500_smp_prepare_cpus, + .smp_secondary_init = s500_smp_secondary_init, + .smp_boot_secondary = s500_smp_boot_secondary, +}; +CPU_METHOD_OF_DECLARE(s500_smp, "actions,s500-smp", &s500_smp_ops); -- cgit From ba2694def2361d9b8d944f6df4aa077ad7290746 Mon Sep 17 00:00:00 2001 From: Andreas Färber Date: Tue, 6 Jun 2017 00:51:56 +0200 Subject: MAINTAINERS: Update Actions Semi section with SPS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add file patterns to cover the SPS power domain driver and DT binding. Signed-off-by: Andreas Färber --- MAINTAINERS | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 9a554b684935..8e2831878365 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1046,7 +1046,11 @@ F: arch/arm/mach-actions/ F: arch/arm/boot/dts/owl-* F: arch/arm64/boot/dts/actions/ F: drivers/clocksource/owl-* +F: drivers/soc/actions/ +F: include/dt-bindings/power/owl-* +F: include/linux/soc/actions/ F: Documentation/devicetree/bindings/arm/actions.txt +F: Documentation/devicetree/bindings/power/actions,owl-sps.txt F: Documentation/devicetree/bindings/timer/actions,owl-timer.txt ARM/ADS SPHERE MACHINE SUPPORT -- cgit From 4ca3fbd981efde78e64643672d493b4ede458e72 Mon Sep 17 00:00:00 2001 From: Andreas Färber Date: Mon, 27 Feb 2017 23:13:48 +0100 Subject: dt-bindings: power: Add Owl SPS power domains MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Define power domains for all non-reserved S500 power gates. Acked-by: Rob Herring Signed-off-by: Andreas Färber --- .../devicetree/bindings/power/actions,owl-sps.txt | 17 +++++++++++++++++ include/dt-bindings/power/owl-s500-powergate.h | 19 +++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 Documentation/devicetree/bindings/power/actions,owl-sps.txt create mode 100644 include/dt-bindings/power/owl-s500-powergate.h diff --git a/Documentation/devicetree/bindings/power/actions,owl-sps.txt b/Documentation/devicetree/bindings/power/actions,owl-sps.txt new file mode 100644 index 000000000000..007b9a7ae723 --- /dev/null +++ b/Documentation/devicetree/bindings/power/actions,owl-sps.txt @@ -0,0 +1,17 @@ +Actions Semi Owl Smart Power System (SPS) + +Required properties: +- compatible : "actions,s500-sps" for S500 +- reg : Offset and length of the register set for the device. +- #power-domain-cells : Must be 1. + See macros in: + include/dt-bindings/power/owl-s500-powergate.h for S500 + + +Example: + + sps: power-controller@b01b0100 { + compatible = "actions,s500-sps"; + reg = <0xb01b0100 0x100>; + #power-domain-cells = <1>; + }; diff --git a/include/dt-bindings/power/owl-s500-powergate.h b/include/dt-bindings/power/owl-s500-powergate.h new file mode 100644 index 000000000000..0a1c451865ea --- /dev/null +++ b/include/dt-bindings/power/owl-s500-powergate.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2017 Andreas Färber + * + * SPDX-License-Identifier: (GPL-2.0+ OR MIT) + */ +#ifndef DT_BINDINGS_POWER_OWL_S500_POWERGATE_H +#define DT_BINDINGS_POWER_OWL_S500_POWERGATE_H + +#define S500_PD_VDE 0 +#define S500_PD_VCE_SI 1 +#define S500_PD_USB2_1 2 +#define S500_PD_CPU2 3 +#define S500_PD_CPU3 4 +#define S500_PD_DMA 5 +#define S500_PD_DS 6 +#define S500_PD_USB3 7 +#define S500_PD_USB2_0 8 + +#endif -- cgit From aa9f800ded78d530bb07104a4745e95af723abf6 Mon Sep 17 00:00:00 2001 From: Andreas Färber Date: Sun, 26 Feb 2017 04:09:57 +0100 Subject: soc: actions: Add Owl SPS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implement S500 Smart Power System power-gating. For now flag PD_CPU2 and PD_CPU3 as always-on. Based on LeMaker linux-actions tree. Signed-off-by: Andreas Färber --- drivers/soc/Kconfig | 1 + drivers/soc/Makefile | 1 + drivers/soc/actions/Kconfig | 12 ++ drivers/soc/actions/Makefile | 1 + drivers/soc/actions/owl-sps.c | 252 ++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 267 insertions(+) create mode 100644 drivers/soc/actions/Kconfig create mode 100644 drivers/soc/actions/Makefile create mode 100644 drivers/soc/actions/owl-sps.c diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig index 309643fe35f9..a63eb0ffba98 100644 --- a/drivers/soc/Kconfig +++ b/drivers/soc/Kconfig @@ -1,5 +1,6 @@ menu "SOC (System On Chip) specific Drivers" +source "drivers/soc/actions/Kconfig" source "drivers/soc/atmel/Kconfig" source "drivers/soc/bcm/Kconfig" source "drivers/soc/fsl/Kconfig" diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile index 824b44281efa..a3b27a33c309 100644 --- a/drivers/soc/Makefile +++ b/drivers/soc/Makefile @@ -2,6 +2,7 @@ # Makefile for the Linux Kernel SOC specific device drivers. # +obj-$(CONFIG_ARCH_ACTIONS) += actions/ obj-$(CONFIG_ARCH_AT91) += atmel/ obj-y += bcm/ obj-$(CONFIG_ARCH_DOVE) += dove/ diff --git a/drivers/soc/actions/Kconfig b/drivers/soc/actions/Kconfig new file mode 100644 index 000000000000..bdf827d5ce78 --- /dev/null +++ b/drivers/soc/actions/Kconfig @@ -0,0 +1,12 @@ +if ARCH_ACTIONS || COMPILE_TEST + +config OWL_PM_DOMAINS + bool "Actions Semi SPS power domains" + depends on PM + select PM_GENERIC_DOMAINS + help + Say 'y' here to enable support for Smart Power System (SPS) + power-gating on Actions Semiconductor S500 SoC. + If unsure, say 'n'. + +endif diff --git a/drivers/soc/actions/Makefile b/drivers/soc/actions/Makefile new file mode 100644 index 000000000000..720c34ed16e4 --- /dev/null +++ b/drivers/soc/actions/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_OWL_PM_DOMAINS) += owl-sps.o diff --git a/drivers/soc/actions/owl-sps.c b/drivers/soc/actions/owl-sps.c new file mode 100644 index 000000000000..8abb72f01929 --- /dev/null +++ b/drivers/soc/actions/owl-sps.c @@ -0,0 +1,252 @@ +/* + * Actions Semi Owl Smart Power System (SPS) + * + * Copyright 2012 Actions Semi Inc. + * Author: Actions Semi, Inc. + * + * Copyright (c) 2017 Andreas Färber + * + * 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; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include +#include + +#define OWL_SPS_PG_CTL 0x0 + +struct owl_sps_domain_info { + const char *name; + int pwr_bit; + int ack_bit; + unsigned int genpd_flags; +}; + +struct owl_sps_info { + unsigned num_domains; + const struct owl_sps_domain_info *domains; +}; + +struct owl_sps { + struct device *dev; + const struct owl_sps_info *info; + void __iomem *base; + struct genpd_onecell_data genpd_data; + struct generic_pm_domain *domains[]; +}; + +#define to_owl_pd(gpd) container_of(gpd, struct owl_sps_domain, genpd) + +struct owl_sps_domain { + struct generic_pm_domain genpd; + const struct owl_sps_domain_info *info; + struct owl_sps *sps; +}; + +static int owl_sps_set_power(struct owl_sps_domain *pd, bool enable) +{ + u32 val, pwr_mask, ack_mask; + int timeout; + bool ack; + + ack_mask = BIT(pd->info->ack_bit); + pwr_mask = BIT(pd->info->pwr_bit); + val = readl(pd->sps->base + OWL_SPS_PG_CTL); + ack = val & ack_mask; + + if (ack == enable) + return 0; + + if (enable) + val |= pwr_mask; + else + val &= ~pwr_mask; + + writel(val, pd->sps->base + OWL_SPS_PG_CTL); + + for (timeout = 5000; timeout > 0; timeout -= 50) { + val = readl(pd->sps->base + OWL_SPS_PG_CTL); + if ((val & ack_mask) == (enable ? ack_mask : 0)) + break; + udelay(50); + } + if (timeout <= 0) + return -ETIMEDOUT; + + udelay(10); + + return 0; +} + +static int owl_sps_power_on(struct generic_pm_domain *domain) +{ + struct owl_sps_domain *pd = to_owl_pd(domain); + + dev_dbg(pd->sps->dev, "%s power on", pd->info->name); + + return owl_sps_set_power(pd, true); +} + +static int owl_sps_power_off(struct generic_pm_domain *domain) +{ + struct owl_sps_domain *pd = to_owl_pd(domain); + + dev_dbg(pd->sps->dev, "%s power off", pd->info->name); + + return owl_sps_set_power(pd, false); +} + +static int owl_sps_init_domain(struct owl_sps *sps, int index) +{ + struct owl_sps_domain *pd; + + pd = devm_kzalloc(sps->dev, sizeof(*pd), GFP_KERNEL); + if (!pd) + return -ENOMEM; + + pd->info = &sps->info->domains[index]; + pd->sps = sps; + + pd->genpd.name = pd->info->name; + pd->genpd.power_on = owl_sps_power_on; + pd->genpd.power_off = owl_sps_power_off; + pd->genpd.flags = pd->info->genpd_flags; + pm_genpd_init(&pd->genpd, NULL, false); + + sps->genpd_data.domains[index] = &pd->genpd; + + return 0; +} + +static int owl_sps_probe(struct platform_device *pdev) +{ + const struct of_device_id *match; + const struct owl_sps_info *sps_info; + struct owl_sps *sps; + int i, ret; + + if (!pdev->dev.of_node) { + dev_err(&pdev->dev, "no device node\n"); + return -ENODEV; + } + + match = of_match_device(pdev->dev.driver->of_match_table, &pdev->dev); + if (!match || !match->data) { + dev_err(&pdev->dev, "unknown compatible or missing data\n"); + return -EINVAL; + } + + sps_info = match->data; + + sps = devm_kzalloc(&pdev->dev, sizeof(*sps) + + sps_info->num_domains * sizeof(sps->domains[0]), + GFP_KERNEL); + if (!sps) + return -ENOMEM; + + sps->base = of_io_request_and_map(pdev->dev.of_node, 0, "owl-sps"); + if (IS_ERR(sps->base)) { + dev_err(&pdev->dev, "failed to map sps registers\n"); + return PTR_ERR(sps->base); + } + + sps->dev = &pdev->dev; + sps->info = sps_info; + sps->genpd_data.domains = sps->domains; + sps->genpd_data.num_domains = sps_info->num_domains; + + for (i = 0; i < sps_info->num_domains; i++) { + ret = owl_sps_init_domain(sps, i); + if (ret) + return ret; + } + + ret = of_genpd_add_provider_onecell(pdev->dev.of_node, &sps->genpd_data); + if (ret) { + dev_err(&pdev->dev, "failed to add provider (%d)", ret); + return ret; + } + + return 0; +} + +static const struct owl_sps_domain_info s500_sps_domains[] = { + [S500_PD_VDE] = { + .name = "VDE", + .pwr_bit = 0, + .ack_bit = 16, + }, + [S500_PD_VCE_SI] = { + .name = "VCE_SI", + .pwr_bit = 1, + .ack_bit = 17, + }, + [S500_PD_USB2_1] = { + .name = "USB2_1", + .pwr_bit = 2, + .ack_bit = 18, + }, + [S500_PD_CPU2] = { + .name = "CPU2", + .pwr_bit = 5, + .ack_bit = 21, + .genpd_flags = GENPD_FLAG_ALWAYS_ON, + }, + [S500_PD_CPU3] = { + .name = "CPU3", + .pwr_bit = 6, + .ack_bit = 22, + .genpd_flags = GENPD_FLAG_ALWAYS_ON, + }, + [S500_PD_DMA] = { + .name = "DMA", + .pwr_bit = 8, + .ack_bit = 12, + }, + [S500_PD_DS] = { + .name = "DS", + .pwr_bit = 9, + .ack_bit = 13, + }, + [S500_PD_USB3] = { + .name = "USB3", + .pwr_bit = 10, + .ack_bit = 14, + }, + [S500_PD_USB2_0] = { + .name = "USB2_0", + .pwr_bit = 11, + .ack_bit = 15, + }, +}; + +static const struct owl_sps_info s500_sps_info = { + .num_domains = ARRAY_SIZE(s500_sps_domains), + .domains = s500_sps_domains, +}; + +static const struct of_device_id owl_sps_of_matches[] = { + { .compatible = "actions,s500-sps", .data = &s500_sps_info }, + { } +}; + +static struct platform_driver owl_sps_platform_driver = { + .probe = owl_sps_probe, + .driver = { + .name = "owl-sps", + .of_match_table = owl_sps_of_matches, + .suppress_bind_attrs = true, + }, +}; + +static int __init owl_sps_init(void) +{ + return platform_driver_register(&owl_sps_platform_driver); +} +postcore_initcall(owl_sps_init); -- cgit From 6932ec60cc0a71689150b16b71427cfdc6575602 Mon Sep 17 00:00:00 2001 From: Andreas Färber Date: Mon, 5 Jun 2017 21:04:21 +0200 Subject: soc: actions: owl-sps: Factor out owl_sps_set_pg() for power-gating MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Allow the SMP code to reuse PM domain code for CPU2/CPU3 wakeup. Signed-off-by: Andreas Färber --- drivers/soc/actions/Kconfig | 4 +++ drivers/soc/actions/Makefile | 1 + drivers/soc/actions/owl-sps-helper.c | 51 ++++++++++++++++++++++++++++++++++++ drivers/soc/actions/owl-sps.c | 34 +++--------------------- include/linux/soc/actions/owl-sps.h | 11 ++++++++ 5 files changed, 70 insertions(+), 31 deletions(-) create mode 100644 drivers/soc/actions/owl-sps-helper.c create mode 100644 include/linux/soc/actions/owl-sps.h diff --git a/drivers/soc/actions/Kconfig b/drivers/soc/actions/Kconfig index bdf827d5ce78..9d68b5a771c3 100644 --- a/drivers/soc/actions/Kconfig +++ b/drivers/soc/actions/Kconfig @@ -1,8 +1,12 @@ if ARCH_ACTIONS || COMPILE_TEST +config OWL_PM_DOMAINS_HELPER + bool + config OWL_PM_DOMAINS bool "Actions Semi SPS power domains" depends on PM + select OWL_PM_DOMAINS_HELPER select PM_GENERIC_DOMAINS help Say 'y' here to enable support for Smart Power System (SPS) diff --git a/drivers/soc/actions/Makefile b/drivers/soc/actions/Makefile index 720c34ed16e4..1e101b06bab1 100644 --- a/drivers/soc/actions/Makefile +++ b/drivers/soc/actions/Makefile @@ -1 +1,2 @@ +obj-$(CONFIG_OWL_PM_DOMAINS_HELPER) += owl-sps-helper.o obj-$(CONFIG_OWL_PM_DOMAINS) += owl-sps.o diff --git a/drivers/soc/actions/owl-sps-helper.c b/drivers/soc/actions/owl-sps-helper.c new file mode 100644 index 000000000000..9d7a2c2b44ec --- /dev/null +++ b/drivers/soc/actions/owl-sps-helper.c @@ -0,0 +1,51 @@ +/* + * Actions Semi Owl Smart Power System (SPS) shared helpers + * + * Copyright 2012 Actions Semi Inc. + * Author: Actions Semi, Inc. + * + * Copyright (c) 2017 Andreas Färber + * + * 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; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include + +#define OWL_SPS_PG_CTL 0x0 + +int owl_sps_set_pg(void __iomem *base, u32 pwr_mask, u32 ack_mask, bool enable) +{ + u32 val; + bool ack; + int timeout; + + val = readl(base + OWL_SPS_PG_CTL); + ack = val & ack_mask; + if (ack == enable) + return 0; + + if (enable) + val |= pwr_mask; + else + val &= ~pwr_mask; + + writel(val, base + OWL_SPS_PG_CTL); + + for (timeout = 5000; timeout > 0; timeout -= 50) { + val = readl(base + OWL_SPS_PG_CTL); + if ((val & ack_mask) == (enable ? ack_mask : 0)) + break; + udelay(50); + } + if (timeout <= 0) + return -ETIMEDOUT; + + udelay(10); + + return 0; +} +EXPORT_SYMBOL_GPL(owl_sps_set_pg); diff --git a/drivers/soc/actions/owl-sps.c b/drivers/soc/actions/owl-sps.c index 8abb72f01929..875225bfa21c 100644 --- a/drivers/soc/actions/owl-sps.c +++ b/drivers/soc/actions/owl-sps.c @@ -12,15 +12,12 @@ * option) any later version. */ -#include -#include #include #include #include +#include #include -#define OWL_SPS_PG_CTL 0x0 - struct owl_sps_domain_info { const char *name; int pwr_bit; @@ -51,37 +48,12 @@ struct owl_sps_domain { static int owl_sps_set_power(struct owl_sps_domain *pd, bool enable) { - u32 val, pwr_mask, ack_mask; - int timeout; - bool ack; + u32 pwr_mask, ack_mask; ack_mask = BIT(pd->info->ack_bit); pwr_mask = BIT(pd->info->pwr_bit); - val = readl(pd->sps->base + OWL_SPS_PG_CTL); - ack = val & ack_mask; - - if (ack == enable) - return 0; - - if (enable) - val |= pwr_mask; - else - val &= ~pwr_mask; - - writel(val, pd->sps->base + OWL_SPS_PG_CTL); - for (timeout = 5000; timeout > 0; timeout -= 50) { - val = readl(pd->sps->base + OWL_SPS_PG_CTL); - if ((val & ack_mask) == (enable ? ack_mask : 0)) - break; - udelay(50); - } - if (timeout <= 0) - return -ETIMEDOUT; - - udelay(10); - - return 0; + return owl_sps_set_pg(pd->sps->base, pwr_mask, ack_mask, enable); } static int owl_sps_power_on(struct generic_pm_domain *domain) diff --git a/include/linux/soc/actions/owl-sps.h b/include/linux/soc/actions/owl-sps.h new file mode 100644 index 000000000000..33d0dbeceb55 --- /dev/null +++ b/include/linux/soc/actions/owl-sps.h @@ -0,0 +1,11 @@ +/* + * Copyright (c) 2017 Andreas Färber + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#ifndef SOC_ACTIONS_OWL_SPS_H +#define SOC_ACTIONS_OWL_SPS_H + +int owl_sps_set_pg(void __iomem *base, u32 pwr_mask, u32 ack_mask, bool enable); + +#endif -- cgit From b6a0e18ca690c2398661c42b942187621ab77e36 Mon Sep 17 00:00:00 2001 From: Andreas Färber Date: Tue, 28 Feb 2017 01:08:37 +0100 Subject: ARM: owl: smp: Implement SPS power-gating for CPU2 and CPU3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bring up the two remaining CPUs by calling into PM domain code. Signed-off-by: Andreas Färber --- arch/arm/mach-actions/Kconfig | 1 + arch/arm/mach-actions/platsmp.c | 36 ++++++++++++++++++++++++++++++++++-- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-actions/Kconfig b/arch/arm/mach-actions/Kconfig index 717adc1630a1..ad9c5c89c683 100644 --- a/arch/arm/mach-actions/Kconfig +++ b/arch/arm/mach-actions/Kconfig @@ -10,6 +10,7 @@ menuconfig ARCH_ACTIONS select GENERIC_IRQ_CHIP select HAVE_ARM_SCU if SMP select HAVE_ARM_TWD if SMP + select OWL_PM_DOMAINS_HELPER select OWL_TIMER help This enables support for the Actions Semiconductor S500 SoC family. diff --git a/arch/arm/mach-actions/platsmp.c b/arch/arm/mach-actions/platsmp.c index 9d3601ebe535..b4806ce0e9bb 100644 --- a/arch/arm/mach-actions/platsmp.c +++ b/arch/arm/mach-actions/platsmp.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -28,7 +29,13 @@ #define OWL_CPUx_FLAG_BOOT 0x55aa +#define OWL_SPS_PG_CTL_PWR_CPU2 BIT(5) +#define OWL_SPS_PG_CTL_PWR_CPU3 BIT(6) +#define OWL_SPS_PG_CTL_ACK_CPU2 BIT(21) +#define OWL_SPS_PG_CTL_ACK_CPU3 BIT(22) + static void __iomem *scu_base_addr; +static void __iomem *sps_base_addr; static void __iomem *timer_base_addr; static int ncores; @@ -58,14 +65,27 @@ void owl_secondary_startup(void); static int s500_wakeup_secondary(unsigned int cpu) { + int ret; + if (cpu > 3) return -EINVAL; + /* The generic PM domain driver is not available this early. */ switch (cpu) { case 2: + ret = owl_sps_set_pg(sps_base_addr, + OWL_SPS_PG_CTL_PWR_CPU2, + OWL_SPS_PG_CTL_ACK_CPU2, true); + if (ret) + return ret; + break; case 3: - /* CPU2/3 are power-gated */ - return -EINVAL; + ret = owl_sps_set_pg(sps_base_addr, + OWL_SPS_PG_CTL_PWR_CPU3, + OWL_SPS_PG_CTL_ACK_CPU3, true); + if (ret) + return ret; + break; } /* wait for CPUx to run to WFE instruction */ @@ -133,6 +153,18 @@ static void __init s500_smp_prepare_cpus(unsigned int max_cpus) return; } + node = of_find_compatible_node(NULL, NULL, "actions,s500-sps"); + if (!node) { + pr_err("%s: missing sps\n", __func__); + return; + } + + sps_base_addr = of_iomap(node, 0); + if (!sps_base_addr) { + pr_err("%s: could not map sps registers\n", __func__); + return; + } + if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9) { node = of_find_compatible_node(NULL, NULL, "arm,cortex-a9-scu"); if (!node) { -- cgit From eb3827457ab0e151b79798b07072c70f5c83809d Mon Sep 17 00:00:00 2001 From: Andreas Färber Date: Sat, 1 Jul 2017 23:41:00 +0200 Subject: ARM: owl: Drop custom machine MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rely on the fallback to "Generic DT based system". This change is visible in /proc/cpuinfo. Cc: Arnd Bergmann Signed-off-by: Andreas Färber Signed-off-by: Arnd Bergmann --- arch/arm/mach-actions/Makefile | 1 - arch/arm/mach-actions/owl.c | 28 ---------------------------- 2 files changed, 29 deletions(-) delete mode 100644 arch/arm/mach-actions/owl.c diff --git a/arch/arm/mach-actions/Makefile b/arch/arm/mach-actions/Makefile index eeb3896e4952..c0f116241da7 100644 --- a/arch/arm/mach-actions/Makefile +++ b/arch/arm/mach-actions/Makefile @@ -1,4 +1,3 @@ -obj-y += owl.o obj-${CONFIG_SMP} += platsmp.o headsmp.o AFLAGS_headsmp.o := -Wa,-march=armv7-a diff --git a/arch/arm/mach-actions/owl.c b/arch/arm/mach-actions/owl.c deleted file mode 100644 index 4ac4a860f3d6..000000000000 --- a/arch/arm/mach-actions/owl.c +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 2017 Andreas Färber - * - * 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; either version 2 of the License, or - * (at your option) any later version. - * - * 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 -#include - -static const char * const owl_dt_compat[] = { - "actions,s500", - NULL -}; - -DT_MACHINE_START(OWL, "Actions Semi Owl platform") - .dt_compat = owl_dt_compat, - .l2c_aux_val = 0, - .l2c_aux_mask = ~0, -MACHINE_END -- cgit From 18cfd9429d8a82c49add8f3ca9d366599bfcac45 Mon Sep 17 00:00:00 2001 From: Andreas Färber Date: Sat, 1 Jul 2017 23:29:30 +0200 Subject: ARM: owl: smp: Drop bogus holding pen MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The S500 SoC can start secondary CPUs without busy-looping for pen_release, so simplify the SMP code compared to the LeMaker kernel tree. Fixes: 172067e0bc87 ("ARM: owl: Implement CPU enable-method for S500") Suggested-by: Arnd Bergmann Cc: David Liu Signed-off-by: Andreas Färber Signed-off-by: Arnd Bergmann --- arch/arm/mach-actions/headsmp.S | 20 ++------------------ arch/arm/mach-actions/platsmp.c | 29 +---------------------------- 2 files changed, 3 insertions(+), 46 deletions(-) diff --git a/arch/arm/mach-actions/headsmp.S b/arch/arm/mach-actions/headsmp.S index dc4832fc101a..65f53bdb69e7 100644 --- a/arch/arm/mach-actions/headsmp.S +++ b/arch/arm/mach-actions/headsmp.S @@ -2,6 +2,8 @@ * Copyright 2012 Actions Semi Inc. * Author: Actions Semi, Inc. * + * Copyright (c) 2017 Andreas Färber + * * 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; either version 2 of the License, or (at your @@ -46,23 +48,5 @@ ENTRY(owl_v7_invalidate_l1) ENDPROC(owl_v7_invalidate_l1) ENTRY(owl_secondary_startup) - mrc p15, 0, r0, c0, c0, 5 - and r0, r0, #0xf - adr r4, 1f - ldmia r4, {r5, r6} - sub r4, r4, r5 - add r6, r6, r4 -pen: - ldr r7, [r6] - cmp r7, r0 - bne pen - - /* - * we've been released from the holding pen: secondary_stack - * should now contain the SVC stack for this core - */ bl owl_v7_invalidate_l1 b secondary_startup - -1: .long . - .long pen_release diff --git a/arch/arm/mach-actions/platsmp.c b/arch/arm/mach-actions/platsmp.c index b4806ce0e9bb..12a9e331b432 100644 --- a/arch/arm/mach-actions/platsmp.c +++ b/arch/arm/mach-actions/platsmp.c @@ -41,26 +41,6 @@ static int ncores; static DEFINE_SPINLOCK(boot_lock); -static void write_pen_release(int val) -{ - pen_release = val; - smp_wmb(); - __cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release)); - outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1)); -} - -static void s500_smp_secondary_init(unsigned int cpu) -{ - /* - * let the primary processor know we're out of the - * pen, then head off into the C entry point - */ - write_pen_release(-1); - - spin_lock(&boot_lock); - spin_unlock(&boot_lock); -} - void owl_secondary_startup(void); static int s500_wakeup_secondary(unsigned int cpu) @@ -115,12 +95,6 @@ static int s500_smp_boot_secondary(unsigned int cpu, struct task_struct *idle) spin_lock(&boot_lock); - /* - * The secondary processor is waiting to be released from - * the holding pen - release it, then wait for it to flag - * that it has been released by resetting pen_release. - */ - write_pen_release(cpu_logical_map(cpu)); smp_send_reschedule(cpu); timeout = jiffies + (1 * HZ); @@ -134,7 +108,7 @@ static int s500_smp_boot_secondary(unsigned int cpu, struct task_struct *idle) spin_unlock(&boot_lock); - return pen_release != -1 ? -ENOSYS : 0; + return 0; } static void __init s500_smp_prepare_cpus(unsigned int max_cpus) @@ -192,7 +166,6 @@ static void __init s500_smp_prepare_cpus(unsigned int max_cpus) static const struct smp_operations s500_smp_ops __initconst = { .smp_prepare_cpus = s500_smp_prepare_cpus, - .smp_secondary_init = s500_smp_secondary_init, .smp_boot_secondary = s500_smp_boot_secondary, }; CPU_METHOD_OF_DECLARE(s500_smp, "actions,s500-smp", &s500_smp_ops); -- cgit