Received: by 2002:a05:6a10:f3d0:0:0:0:0 with SMTP id a16csp413181pxv; Fri, 9 Jul 2021 00:39:19 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyP1ETh0qvLxdjk2x8UXZccg9ADKax+Kbec9oL3ngHxrCZoSMDVs5AwwsWkcnkU7qRKDRXL X-Received: by 2002:a05:6602:3404:: with SMTP id n4mr8147495ioz.19.1625816358998; Fri, 09 Jul 2021 00:39:18 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1625816358; cv=none; d=google.com; s=arc-20160816; b=IaVNcLz24eCEQ1IgFT0Mb8JStHSwRXuE/IRTtFMKm7xo9xKCxnXE+BUciHCl5S6uU6 lL/vWmvzyJjkDURCP2V1bo7JtcViujPDym+RZyxTkP9zDVPHBFc6MZDyKRKJ22OPj9z5 amCTmmY6fRKHDeXM4szRqkL995o+WvPFi/rxwSTvcajbRY0WKciLVwgGmBFKjrgG1NQL qs5LBHkXSOzTHK9JJV1jst1b0wyfZLKsIHJk6oWbcEtyv/HMZkAa+L4Qac1AwLTe/FOx /JIMq3FJnZFxOirekoBmncshh9kb8GOUR/UV0XBkBXf1A1V3Z8ZRlJx/DAhFpdcIs0OK UAZQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=DW1Za5bQIxnsLcH+tJWjV3ZFInBs0kJtvN8MreBe8l0=; b=TirmMRaNqGHPuJxz1M3gG2m3AiFw6FEdfJNZe1OMlzqRLMjAbmcN0RZXlUUEFkXabX 7V7rxMtL34d4c9zJ6ql11fMGVW9flYSQrNg3JoDuSpgrO77DE8hU4+7r8PH/TkgCdNSf o3zfZWb8ujIb+dyUc24Bss54Qmj82xHsps39PKK68wkOCzX/quUucFufqzI6gGRclW4B kU8pBHFgb3cJ2IzODEOXXR8RL0HtGZvYm1FuPzdMig/Qs+/crFcJw/R8D2MWIYXXpd70 LENzirdajusUb5gISgvtTjn2uYT2tKhg5vOmRONgdIs3l/KAS1sIHp2L92RjwyXm0XTg n1EQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id r4si5173464ilt.108.2021.07.09.00.39.05; Fri, 09 Jul 2021 00:39:18 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231315AbhGIHkp (ORCPT + 99 others); Fri, 9 Jul 2021 03:40:45 -0400 Received: from muru.com ([72.249.23.125]:39314 "EHLO muru.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230526AbhGIHkp (ORCPT ); Fri, 9 Jul 2021 03:40:45 -0400 Received: from hillo.muru.com (localhost [127.0.0.1]) by muru.com (Postfix) with ESMTP id 461BD8050; Fri, 9 Jul 2021 07:38:15 +0000 (UTC) From: Tony Lindgren To: stable@vger.kernel.org Cc: linux-kernel@vger.kernel.org, linux-omap@vger.kernel.org, Daniel Lezcano , Keerthy , Tero Kristo Subject: [Backport for 4.19.y PATCH 4/4] clocksource/drivers/timer-ti-dm: Handle dra7 timer wrap errata i940 Date: Fri, 9 Jul 2021 10:37:45 +0300 Message-Id: <20210709073745.13916-4-tony@atomide.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20210709073745.13916-1-tony@atomide.com> References: <20210709073745.13916-1-tony@atomide.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org commit 25de4ce5ed02994aea8bc111d133308f6fd62566 upstream. There is a timer wrap issue on dra7 for the ARM architected timer. In a typical clock configuration the timer fails to wrap after 388 days. To work around the issue, we need to use timer-ti-dm percpu timers instead. Let's configure dmtimer3 and 4 as percpu timers by default, and warn about the issue if the dtb is not configured properly. For more information, please see the errata for "AM572x Sitara Processors Silicon Revisions 1.1, 2.0": https://www.ti.com/lit/er/sprz429m/sprz429m.pdf The concept is based on earlier reference patches done by Tero Kristo and Keerthy. Cc: Daniel Lezcano Cc: Keerthy Cc: Tero Kristo [tony@atomide.com: backported to 4.19.y] Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/dra7.dtsi | 11 ++++++ arch/arm/mach-omap2/board-generic.c | 4 +-- arch/arm/mach-omap2/timer.c | 53 ++++++++++++++++++++++++++++- drivers/clk/ti/clk-7xx.c | 1 + include/linux/cpuhotplug.h | 1 + 5 files changed, 67 insertions(+), 3 deletions(-) diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi --- a/arch/arm/boot/dts/dra7.dtsi +++ b/arch/arm/boot/dts/dra7.dtsi @@ -48,6 +48,7 @@ timer { compatible = "arm,armv7-timer"; + status = "disabled"; /* See ARM architected timer wrap erratum i940 */ interrupts = , , , @@ -910,6 +911,8 @@ reg = <0x48032000 0x80>; interrupts = ; ti,hwmods = "timer2"; + clock-names = "fck"; + clocks = <&l4per_clkctrl DRA7_TIMER2_CLKCTRL 24>; }; timer3: timer@48034000 { @@ -917,6 +920,10 @@ reg = <0x48034000 0x80>; interrupts = ; ti,hwmods = "timer3"; + clock-names = "fck"; + clocks = <&l4per_clkctrl DRA7_TIMER3_CLKCTRL 24>; + assigned-clocks = <&l4per_clkctrl DRA7_TIMER3_CLKCTRL 24>; + assigned-clock-parents = <&timer_sys_clk_div>; }; timer4: timer@48036000 { @@ -924,6 +931,10 @@ reg = <0x48036000 0x80>; interrupts = ; ti,hwmods = "timer4"; + clock-names = "fck"; + clocks = <&l4per_clkctrl DRA7_TIMER4_CLKCTRL 24>; + assigned-clocks = <&l4per_clkctrl DRA7_TIMER4_CLKCTRL 24>; + assigned-clock-parents = <&timer_sys_clk_div>; }; timer5: timer@48820000 { diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c --- a/arch/arm/mach-omap2/board-generic.c +++ b/arch/arm/mach-omap2/board-generic.c @@ -330,7 +330,7 @@ DT_MACHINE_START(DRA74X_DT, "Generic DRA74X (Flattened Device Tree)") .init_late = dra7xx_init_late, .init_irq = omap_gic_of_init, .init_machine = omap_generic_init, - .init_time = omap5_realtime_timer_init, + .init_time = omap3_gptimer_timer_init, .dt_compat = dra74x_boards_compat, .restart = omap44xx_restart, MACHINE_END @@ -353,7 +353,7 @@ DT_MACHINE_START(DRA72X_DT, "Generic DRA72X (Flattened Device Tree)") .init_late = dra7xx_init_late, .init_irq = omap_gic_of_init, .init_machine = omap_generic_init, - .init_time = omap5_realtime_timer_init, + .init_time = omap3_gptimer_timer_init, .dt_compat = dra72x_boards_compat, .restart = omap44xx_restart, MACHINE_END diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c --- a/arch/arm/mach-omap2/timer.c +++ b/arch/arm/mach-omap2/timer.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include @@ -421,6 +422,53 @@ static void __init dmtimer_clkevt_init_common(struct dmtimer_clockevent *clkevt, timer->rate); } +static DEFINE_PER_CPU(struct dmtimer_clockevent, dmtimer_percpu_timer); + +static int omap_gptimer_starting_cpu(unsigned int cpu) +{ + struct dmtimer_clockevent *clkevt = per_cpu_ptr(&dmtimer_percpu_timer, cpu); + struct clock_event_device *dev = &clkevt->dev; + struct omap_dm_timer *timer = &clkevt->timer; + + clockevents_config_and_register(dev, timer->rate, 3, ULONG_MAX); + irq_force_affinity(dev->irq, cpumask_of(cpu)); + + return 0; +} + +static int __init dmtimer_percpu_quirk_init(void) +{ + struct dmtimer_clockevent *clkevt; + struct clock_event_device *dev; + struct device_node *arm_timer; + struct omap_dm_timer *timer; + int cpu = 0; + + arm_timer = of_find_compatible_node(NULL, NULL, "arm,armv7-timer"); + if (of_device_is_available(arm_timer)) { + pr_warn_once("ARM architected timer wrap issue i940 detected\n"); + return 0; + } + + for_each_possible_cpu(cpu) { + clkevt = per_cpu_ptr(&dmtimer_percpu_timer, cpu); + dev = &clkevt->dev; + timer = &clkevt->timer; + + dmtimer_clkevt_init_common(clkevt, 0, "timer_sys_ck", + CLOCK_EVT_FEAT_ONESHOT, + cpumask_of(cpu), + "assigned-clock-parents", + 500, "percpu timer"); + } + + cpuhp_setup_state(CPUHP_AP_OMAP_DM_TIMER_STARTING, + "clockevents/omap/gptimer:starting", + omap_gptimer_starting_cpu, NULL); + + return 0; +} + /* Clocksource code */ static struct omap_dm_timer clksrc; static bool use_gptimer_clksrc __initdata; @@ -565,6 +613,9 @@ static void __init __omap_sync32k_timer_init(int clkev_nr, const char *clkev_src 3, /* Timer internal resynch latency */ 0xffffffff); + if (soc_is_dra7xx()) + dmtimer_percpu_quirk_init(); + /* Enable the use of clocksource="gp_timer" kernel parameter */ if (use_gptimer_clksrc || gptimer) omap2_gptimer_clocksource_init(clksrc_nr, clksrc_src, @@ -592,7 +643,7 @@ void __init omap3_secure_sync32k_timer_init(void) #endif /* CONFIG_ARCH_OMAP3 */ #if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_SOC_AM33XX) || \ - defined(CONFIG_SOC_AM43XX) + defined(CONFIG_SOC_AM43XX) || defined(CONFIG_SOC_DRA7XX) void __init omap3_gptimer_timer_init(void) { __omap_sync32k_timer_init(2, "timer_sys_ck", NULL, diff --git a/drivers/clk/ti/clk-7xx.c b/drivers/clk/ti/clk-7xx.c --- a/drivers/clk/ti/clk-7xx.c +++ b/drivers/clk/ti/clk-7xx.c @@ -733,6 +733,7 @@ const struct omap_clkctrl_data dra7_clkctrl_data[] __initconst = { static struct ti_dt_clk dra7xx_clks[] = { DT_CLK(NULL, "timer_32k_ck", "sys_32k_ck"), DT_CLK(NULL, "sys_clkin_ck", "timer_sys_clk_div"), + DT_CLK(NULL, "timer_sys_ck", "timer_sys_clk_div"), DT_CLK(NULL, "sys_clkin", "sys_clkin1"), DT_CLK(NULL, "atl_dpll_clk_mux", "atl_cm:0000:24"), DT_CLK(NULL, "atl_gfclk_mux", "atl_cm:0000:26"), diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h --- a/include/linux/cpuhotplug.h +++ b/include/linux/cpuhotplug.h @@ -118,6 +118,7 @@ enum cpuhp_state { CPUHP_AP_ARM_L2X0_STARTING, CPUHP_AP_EXYNOS4_MCT_TIMER_STARTING, CPUHP_AP_ARM_ARCH_TIMER_STARTING, + CPUHP_AP_OMAP_DM_TIMER_STARTING, CPUHP_AP_ARM_GLOBAL_TIMER_STARTING, CPUHP_AP_JCORE_TIMER_STARTING, CPUHP_AP_ARM_TWD_STARTING, -- 2.32.0