From patchwork Mon Jun 13 13:32:47 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AngeloGioacchino Del Regno X-Patchwork-Id: 12879560 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id B4038C43334 for ; Mon, 13 Jun 2022 13:33:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=jXl3rQFVb7DkEVgqzmFKsKRUY5uT0j6D4ia3MMYjA7o=; b=JVGuPvZbUwvB4u 02qI/QbjtyEEHK41JSVS7saxhlW3c/TLWVhL5hfh4qz8avaMjEHXAV6SBe4j/xGzzkERIcLPP/M5u 3TYHEaoTj47eyn4rkwftme54vib7qFTt1t18W8757MCXS2EbHDEguf7h5JGHVJV1xpq2LgM1Lrg4v Xpz6WA1MAPD7qC3Uyvd/6rj68d+y0e6O+bqo+AJVA5mU8nwDEXkj1/oUOHKzyiCmLw1bfMzvns6Z5 4J1uDczwfvnEZsJUnI3f+y/2u+xTdtNLhVs0A9ozrCjYKyotsv4wBjMP94HPoIb32dE0/aQG5DYxH NiVv6nFq53MSYRsRKp/w==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1o0kBu-003r2F-6e; Mon, 13 Jun 2022 13:33:14 +0000 Received: from madras.collabora.co.uk ([46.235.227.172]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1o0kBd-003qwF-T3; Mon, 13 Jun 2022 13:32:59 +0000 Received: from IcarusMOD.eternityproject.eu (2-237-20-237.ip236.fastwebnet.it [2.237.20.237]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: kholk11) by madras.collabora.co.uk (Postfix) with ESMTPSA id 23588660166D; Mon, 13 Jun 2022 14:32:52 +0100 (BST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1655127173; bh=gVWwzUQD324E96x3GSZda+R9Ken/Uibhk/lfU0iPevc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=XJOOV77jjkflxdGsyyJLt7ZrYkEM03BToAtLPYnQmOnFDw7OPVAXOJD1QZXtae7bp t4TGVcR9vy5u4WP63KT6ejtNVQCjRO43LW6PchZ5RMGKQe+vvOlNE+He7whta7bwE6 09NrJk43y9wJcobqcZX6TlMv6hk1cWr5zKXLrPt9o3+Fn4LvgI9C+C5xSkaqjl5/+x 0txuRNo3PNU2MKMCqMCaJOkx6r2NtrKBwKVd1Rdi0obfVyR4tRFLZHDyrj5U8xxObk jSfOZk7G/Nk+lqDb60bceejNcmgRsszudT2p6Q+33jB0f9TjIZ0BrQJEaxKj9xGfnt 0f9WCnELdu1eg== From: AngeloGioacchino Del Regno To: daniel.lezcano@linaro.org Cc: tglx@linutronix.de, robh+dt@kernel.org, krzysztof.kozlowski+dt@linaro.org, matthias.bgg@gmail.com, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org, konrad.dybcio@somainline.org, marijn.suijten@somainline.org, martin.botka@somainline.org, ~postmarketos/upstreaming@lists.sr.ht, phone-devel@vger.kernel.org, paul.bouchara@somainline.org, AngeloGioacchino Del Regno , Rob Herring Subject: [PATCH v3 1/2] dt-bindings: timer: mediatek: Add CPUX System Timer and MT6795 compatible Date: Mon, 13 Jun 2022 15:32:47 +0200 Message-Id: <20220613133248.34652-2-angelogioacchino.delregno@collabora.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220613133248.34652-1-angelogioacchino.delregno@collabora.com> References: <20220613133248.34652-1-angelogioacchino.delregno@collabora.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220613_063258_125703_FAC084FB X-CRM114-Status: UNSURE ( 9.54 ) X-CRM114-Notice: Please train this message. X-BeenThere: linux-mediatek@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "Linux-mediatek" Errors-To: linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org Document the "CPUXGPT" CPU General Purpose Timer, used as ARM/ARM64 System Timer on MediaTek platforms and add the MT6795 compatible for it. Signed-off-by: AngeloGioacchino Del Regno Acked-by: Rob Herring Reviewed-by: Matthias Brugger --- .../devicetree/bindings/timer/mediatek,mtk-timer.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt b/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt index 6f1f9dba6e88..f1c848af91d3 100644 --- a/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt +++ b/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt @@ -1,7 +1,8 @@ MediaTek Timers --------------- -MediaTek SoCs have two different timers on different platforms, +MediaTek SoCs have different timers on different platforms, +- CPUX (ARM/ARM64 System Timer) - GPT (General Purpose Timer) - SYST (System Timer) @@ -29,6 +30,9 @@ Required properties: * "mediatek,mt7629-timer" for MT7629 compatible timers (SYST) * "mediatek,mt6765-timer" for MT6765 and all above compatible timers (SYST) + For those SoCs that use CPUX + * "mediatek,mt6795-systimer" for MT6795 compatible timers (CPUX) + - reg: Should contain location and length for timer register. - clocks: Should contain system clock. From patchwork Mon Jun 13 13:32:48 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AngeloGioacchino Del Regno X-Patchwork-Id: 12879561 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 00D64C433EF for ; Mon, 13 Jun 2022 13:33:30 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=wV+FUP9ft5648Afd4fwXg/LWOY5nOGCEiZCiPbA/IYI=; b=YjhmhqanMehYkY EwuLjIKTKylqYzpO7C5AaAKe/aBrP5hLlWYMgS+JieMIAcuBXxCSGeClhVbOCx9CuH+6vGPWjZO4N H4Pb4KB87NV7OMn76DepKGGVv3Zz8b5pmG3TkzdmCCEKfegrjmImisYJGT1dCmJVF1ge3j8boYwMD 6jPrHPUFO66yeaEc31vKmXM7Dr1sax6gQmyCZB1Vv6NFQmK/UnPqylyA+1eh0LBNNPSjRsUYYDevG 0h5SBm3RYQsyxmW+24zNK3PnVzT5tdrPyQ7Wjawbuv/arNOfbVdYM8NB4A1ZUKN3qpwo9y6le4Gsy OyEDVrgAnYUwf0lwuZtw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1o0kC4-003r6M-1T; Mon, 13 Jun 2022 13:33:24 +0000 Received: from madras.collabora.co.uk ([46.235.227.172]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1o0kBd-003qwY-T5; Mon, 13 Jun 2022 13:32:59 +0000 Received: from IcarusMOD.eternityproject.eu (2-237-20-237.ip236.fastwebnet.it [2.237.20.237]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: kholk11) by madras.collabora.co.uk (Postfix) with ESMTPSA id 28CC6660166E; Mon, 13 Jun 2022 14:32:53 +0100 (BST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1655127174; bh=XC6mbmI2Sdraxdxu+7GeoF3Pci77VFnyTCm4GVX4HXA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=FiDOMNHdykH0Qx4WRodEeUDtufIXcYwVE/dENbHY4b7AT/BsD9w5ffUL717d9O9lD ecOgkFyFsb+xRE4tGK9fJ4r6i9JYLnFTBZxi5RzGd5axThIxcxY2hVFs8jemsEtZZn JaRsJMWOpbx2rDjzZAwq1C2DoRbv0Ml4zqMMvBrhgD9mi/TxHSH6ht1jcMsqKDxrG5 Gj4ana9j2NQFpq/uN/lPc1a+OOS3BQkr2mEWNW53SKa4FrpHqf2Yi3tzQTI5BZXRz0 JA3fkkjoYrZRJ+CG8V/McuMxBDZxw1bewjf/cCSyI1mMusQ0kx5xNZTdH2xSSUvw1w JqjRENC51ZFkQ== From: AngeloGioacchino Del Regno To: daniel.lezcano@linaro.org Cc: tglx@linutronix.de, robh+dt@kernel.org, krzysztof.kozlowski+dt@linaro.org, matthias.bgg@gmail.com, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org, konrad.dybcio@somainline.org, marijn.suijten@somainline.org, martin.botka@somainline.org, ~postmarketos/upstreaming@lists.sr.ht, phone-devel@vger.kernel.org, paul.bouchara@somainline.org, AngeloGioacchino Del Regno Subject: [PATCH v3 2/2] clocksource/drivers/timer-mediatek: Implement CPUXGPT timers Date: Mon, 13 Jun 2022 15:32:48 +0200 Message-Id: <20220613133248.34652-3-angelogioacchino.delregno@collabora.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220613133248.34652-1-angelogioacchino.delregno@collabora.com> References: <20220613133248.34652-1-angelogioacchino.delregno@collabora.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220613_063258_294780_208CFD5B X-CRM114-Status: GOOD ( 25.70 ) X-BeenThere: linux-mediatek@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "Linux-mediatek" Errors-To: linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org Some MediaTek platforms with a buggy TrustZone ATF firmware will not initialize the AArch64 System Timer correctly: in these cases, the System Timer address is correctly programmed, as well as the CNTFRQ_EL0 register (reading 13MHz, as it should be), but the assigned hardware timers are never started before (or after) booting Linux. In this condition, any call to function get_cycles() will be returning zero, as CNTVCT_EL0 will always read zero. One common critical symptom of that is trying to use the udelay() function (calling __delay()), which executes the following loop: start = get_cycles(); while ((get_cycles() - start) < cycles) cpu_relax(); which, when CNTVCT_EL0 always reads zero, translates to: while((0 - 0) < 0) ==> while(0 < 0) ... generating an infinite loop, even though zero is never less than zero, but always equal to it (this has to be researched, but it's out of the scope of this commit). To fix this issue on the affected MediaTek platforms, the solution is to simply start the timers that are designed to be System Timer(s). These timers, downstream, are called "CPUXGPT" and there is one timer per CPU core; luckily, it is not necessary to set a start bit on each CPUX General Purpose Timer, but it's conveniently enough to: - Set the clock divider (input = 26MHz, divider = 2, output = 13MHz); - Set the ENABLE bit on a global register (starts all CPUX timers). The only small hurdle with this setup is that it's all done through the MCUSYS wrapper, where it is needed, for each read or write, to select a register address (by writing it to an index register) and then to perform any R/W on a "CON" register. For example, writing "0x1" to the CPUXGPT register offset 0x4: - Write 0x4 to mcusys INDEX register - Write 0x1 to mcusys CON register Reading from CPUXGPT register offset 0x4: - Write 0x4 to mcusys INDEX register - Read mcusys CON register. Finally, starting this timer makes platforms affected by this issue to work correctly. Signed-off-by: AngeloGioacchino Del Regno Reviewed-by: Matthias Brugger --- drivers/clocksource/timer-mediatek.c | 119 +++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) diff --git a/drivers/clocksource/timer-mediatek.c b/drivers/clocksource/timer-mediatek.c index 7bcb4a3f26fb..a3e90047f9ac 100644 --- a/drivers/clocksource/timer-mediatek.c +++ b/drivers/clocksource/timer-mediatek.c @@ -22,6 +22,19 @@ #define TIMER_SYNC_TICKS (3) +/* cpux mcusys wrapper */ +#define CPUX_CON_REG 0x0 +#define CPUX_IDX_REG 0x4 + +/* cpux */ +#define CPUX_IDX_GLOBAL_CTRL 0x0 + #define CPUX_ENABLE BIT(0) + #define CPUX_CLK_DIV_MASK GENMASK(10, 8) + #define CPUX_CLK_DIV1 BIT(8) + #define CPUX_CLK_DIV2 BIT(9) + #define CPUX_CLK_DIV4 BIT(10) +#define CPUX_IDX_GLOBAL_IRQ 0x30 + /* gpt */ #define GPT_IRQ_EN_REG 0x00 #define GPT_IRQ_ENABLE(val) BIT((val) - 1) @@ -72,6 +85,57 @@ static void __iomem *gpt_sched_reg __read_mostly; +static u32 mtk_cpux_readl(u32 reg_idx, struct timer_of *to) +{ + writel(reg_idx, timer_of_base(to) + CPUX_IDX_REG); + return readl(timer_of_base(to) + CPUX_CON_REG); +} + +static void mtk_cpux_writel(u32 val, u32 reg_idx, struct timer_of *to) +{ + writel(reg_idx, timer_of_base(to) + CPUX_IDX_REG); + writel(val, timer_of_base(to) + CPUX_CON_REG); +} + +static void mtk_cpux_disable_irq(struct timer_of *to) +{ + const unsigned long *irq_mask = cpumask_bits(cpu_possible_mask); + u32 val; + + val = mtk_cpux_readl(CPUX_IDX_GLOBAL_IRQ, to); + val &= ~(*irq_mask); + mtk_cpux_writel(val, CPUX_IDX_GLOBAL_IRQ, to); +} + +static void mtk_cpux_enable_irq(struct timer_of *to) +{ + const unsigned long *irq_mask = cpumask_bits(cpu_possible_mask); + u32 val; + + val = mtk_cpux_readl(CPUX_IDX_GLOBAL_IRQ, to); + val |= *irq_mask; + mtk_cpux_writel(val, CPUX_IDX_GLOBAL_IRQ, to); +} + +static int mtk_cpux_clkevt_shutdown(struct clock_event_device *clkevt) +{ + /* Clear any irq */ + mtk_cpux_disable_irq(to_timer_of(clkevt)); + + /* + * Disabling CPUXGPT timer will crash the platform, especially + * if Trusted Firmware is using it (usually, for sleep states), + * so we only mask the IRQ and call it a day. + */ + return 0; +} + +static int mtk_cpux_clkevt_resume(struct clock_event_device *clkevt) +{ + mtk_cpux_enable_irq(to_timer_of(clkevt)); + return 0; +} + static void mtk_syst_ack_irq(struct timer_of *to) { /* Clear and disable interrupt */ @@ -281,6 +345,60 @@ static struct timer_of to = { }, }; +static int __init mtk_cpux_init(struct device_node *node) +{ + static struct timer_of to_cpux; + u32 freq, val; + int ret; + + /* + * There are per-cpu interrupts for the CPUX General Purpose Timer + * but since this timer feeds the AArch64 System Timer we can rely + * on the CPU timer PPIs as well, so we don't declare TIMER_OF_IRQ. + */ + to_cpux.flags = TIMER_OF_BASE | TIMER_OF_CLOCK; + to_cpux.clkevt.name = "mtk-cpuxgpt"; + to_cpux.clkevt.rating = 10; + to_cpux.clkevt.cpumask = cpu_possible_mask; + to_cpux.clkevt.set_state_shutdown = mtk_cpux_clkevt_shutdown; + to_cpux.clkevt.tick_resume = mtk_cpux_clkevt_resume; + + /* If this fails, bad things are about to happen... */ + ret = timer_of_init(node, &to_cpux); + if (ret) { + WARN(1, "Cannot start CPUX timers.\n"); + return ret; + } + + /* + * Check if we're given a clock with the right frequency for this + * timer, otherwise warn but keep going with the setup anyway, as + * that makes it possible to still boot the kernel, even though + * it may not work correctly (random lockups, etc). + * The reason behind this is that having an early UART may not be + * possible for everyone and this gives a chance to retrieve kmsg + * for eventual debugging even on consumer devices. + */ + freq = timer_of_rate(&to_cpux); + if (freq > 13000000) + WARN(1, "Requested unsupported timer frequency %u\n", freq); + + /* Clock input is 26MHz, set DIV2 to achieve 13MHz clock */ + val = mtk_cpux_readl(CPUX_IDX_GLOBAL_CTRL, &to_cpux); + val &= ~CPUX_CLK_DIV_MASK; + val |= CPUX_CLK_DIV2; + mtk_cpux_writel(val, CPUX_IDX_GLOBAL_CTRL, &to_cpux); + + /* Enable all CPUXGPT timers */ + val = mtk_cpux_readl(CPUX_IDX_GLOBAL_CTRL, &to_cpux); + mtk_cpux_writel(val | CPUX_ENABLE, CPUX_IDX_GLOBAL_CTRL, &to_cpux); + + clockevents_config_and_register(&to_cpux.clkevt, timer_of_rate(&to_cpux), + TIMER_SYNC_TICKS, 0xffffffff); + + return 0; +} + static int __init mtk_syst_init(struct device_node *node) { int ret; @@ -339,3 +457,4 @@ static int __init mtk_gpt_init(struct device_node *node) } TIMER_OF_DECLARE(mtk_mt6577, "mediatek,mt6577-timer", mtk_gpt_init); TIMER_OF_DECLARE(mtk_mt6765, "mediatek,mt6765-timer", mtk_syst_init); +TIMER_OF_DECLARE(mtk_mt6795, "mediatek,mt6795-systimer", mtk_cpux_init);