summaryrefslogtreecommitdiff
path: root/drivers/clocksource/timer-mediatek.c
AgeCommit message (Collapse)AuthorFilesLines
2022-07-16clocksource/drivers/timer-mediatek: Implement CPUXGPT timersAngeloGioacchino Del Regno1-0/+114
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 <angelogioacchino.delregno@collabora.com> Reviewed-by: Matthias Brugger <matthias.bgg@gmail.com> Link: https://lore.kernel.org/r/20220613133819.35318-3-angelogioacchino.delregno@collabora.com Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
2021-08-14clocksource/drivers/mediatek: Optimize systimer irq clear flow on shutdownFengquan Chen1-2/+6
mtk_syst_clkevt_shutdown is called after irq disabled in suspend flow, clear any pending systimer irq when shutdown to avoid suspend aborted due to timer irq pending Also as for systimer in mediatek socs, there must be firstly enable timer before clear systimer irq Fixes: e3af677607d9("clocksource/drivers/timer-mediatek: Add support for system timer") Signed-off-by: Fengquan Chen <fengquan.chen@mediatek.com> Tested-by: Hsin-Yi Wang <hsinyi@chromium.org> Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org> Link: https://lore.kernel.org/r/1617960162-1988-2-git-send-email-Fengquan.Chen@mediatek.com
2021-06-15clocksource/drivers/mediatek: Ack and disable interrupts on suspendEvan Benn1-0/+24
Interrupts are disabled during suspend before this driver disables its timers. ARM trusted firmware will abort suspend if the timer irq is pending, so ack and disable the timer interrupt during suspend. Signed-off-by: Evan Benn <evanbenn@chromium.org> Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org> Link: https://lore.kernel.org/r/20210512122528.v4.1.I1d9917047de06715da16e1620759f703fcfdcbcb@changeid
2019-10-16clocksource/drivers/mediatek: Fix error handlingFabien Parent1-8/+2
When timer_of_init fails, it cleans up after itself by undoing everything it did during the initialization function. mtk_syst_init and mtk_gpt_init both call timer_of_cleanup if timer_of_init fails. timer_of_cleanup try to release the resource taken. Since these resources have already been cleaned up by timer_of_init, we end up getting a few warnings printed: [ 0.001935] WARNING: CPU: 0 PID: 0 at __clk_put+0xe8/0x128 [ 0.002650] Modules linked in: [ 0.003058] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.19.67+ #1 [ 0.003852] Hardware name: MediaTek MT8183 (DT) [ 0.004446] pstate: 20400085 (nzCv daIf +PAN -UAO) [ 0.005073] pc : __clk_put+0xe8/0x128 [ 0.005555] lr : clk_put+0xc/0x14 [ 0.005988] sp : ffffff80090b3ea0 [ 0.006422] x29: ffffff80090b3ea0 x28: 0000000040e20018 [ 0.007121] x27: ffffffc07bfff780 x26: 0000000000000001 [ 0.007819] x25: ffffff80090bda80 x24: ffffff8008ec5828 [ 0.008517] x23: ffffff80090bd000 x22: ffffff8008d8b2e8 [ 0.009216] x21: 0000000000000001 x20: fffffffffffffdfb [ 0.009914] x19: ffffff8009166180 x18: 00000000002bffa8 [ 0.010612] x17: ffffffc012996980 x16: 0000000000000000 [ 0.011311] x15: ffffffbf004a6800 x14: 3536343038393334 [ 0.012009] x13: 2079726576652073 x12: 7eb9c62c5c38f100 [ 0.012707] x11: ffffff80090b3ba0 x10: ffffff80090b3ba0 [ 0.013405] x9 : 0000000000000004 x8 : 0000000000000040 [ 0.014103] x7 : ffffffc079400270 x6 : 0000000000000000 [ 0.014801] x5 : ffffffc079400248 x4 : 0000000000000000 [ 0.015499] x3 : 0000000000000000 x2 : 0000000000000000 [ 0.016197] x1 : ffffff80091661c0 x0 : fffffffffffffdfb [ 0.016896] Call trace: [ 0.017218] __clk_put+0xe8/0x128 [ 0.017654] clk_put+0xc/0x14 [ 0.018048] timer_of_cleanup+0x60/0x7c [ 0.018551] mtk_syst_init+0x8c/0x9c [ 0.019020] timer_probe+0x6c/0xe0 [ 0.019469] time_init+0x14/0x44 [ 0.019893] start_kernel+0x2d0/0x46c [ 0.020378] ---[ end trace 8c1efabea1267649 ]--- [ 0.020982] ------------[ cut here ]------------ [ 0.021586] Trying to vfree() nonexistent vm area ((____ptrval____)) [ 0.022427] WARNING: CPU: 0 PID: 0 at __vunmap+0xd0/0xd8 [ 0.023119] Modules linked in: [ 0.023524] CPU: 0 PID: 0 Comm: swapper/0 Tainted: G W 4.19.67+ #1 [ 0.024498] Hardware name: MediaTek MT8183 (DT) [ 0.025091] pstate: 60400085 (nZCv daIf +PAN -UAO) [ 0.025718] pc : __vunmap+0xd0/0xd8 [ 0.026176] lr : __vunmap+0xd0/0xd8 [ 0.026632] sp : ffffff80090b3e90 [ 0.027066] x29: ffffff80090b3e90 x28: 0000000040e20018 [ 0.027764] x27: ffffffc07bfff780 x26: 0000000000000001 [ 0.028462] x25: ffffff80090bda80 x24: ffffff8008ec5828 [ 0.029160] x23: ffffff80090bd000 x22: ffffff8008d8b2e8 [ 0.029858] x21: 0000000000000000 x20: 0000000000000000 [ 0.030556] x19: ffffff800800d000 x18: 00000000002bffa8 [ 0.031254] x17: 0000000000000000 x16: 0000000000000000 [ 0.031952] x15: ffffffbf004a6800 x14: 3536343038393334 [ 0.032651] x13: 2079726576652073 x12: 7eb9c62c5c38f100 [ 0.033349] x11: ffffff80090b3b40 x10: ffffff80090b3b40 [ 0.034047] x9 : 0000000000000005 x8 : 5f5f6c6176727470 [ 0.034745] x7 : 5f5f5f5f28282061 x6 : ffffff80091c86ef [ 0.035443] x5 : ffffff800852b690 x4 : 0000000000000000 [ 0.036141] x3 : 0000000000000002 x2 : 0000000000000002 [ 0.036839] x1 : 7eb9c62c5c38f100 x0 : 7eb9c62c5c38f100 [ 0.037536] Call trace: [ 0.037859] __vunmap+0xd0/0xd8 [ 0.038271] vunmap+0x24/0x30 [ 0.038664] __iounmap+0x2c/0x34 [ 0.039088] timer_of_cleanup+0x70/0x7c [ 0.039591] mtk_syst_init+0x8c/0x9c [ 0.040060] timer_probe+0x6c/0xe0 [ 0.040507] time_init+0x14/0x44 [ 0.040932] start_kernel+0x2d0/0x46c This commit remove the calls to timer_of_cleanup when timer_of_init fails since it is unnecessary and actually cause warnings to be printed. Fixes: a0858f937960 ("mediatek: Convert the driver to timer-of") Signed-off-by: Fabien Parent <fparent@baylibre.com> Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org> Link: https://lore.kernel.org/linux-arm-kernel/20190919191315.25190-1-fparent@baylibre.com/
2019-05-30treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 157Thomas Gleixner1-10/+1
Based on 3 normalized pattern(s): 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 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 [author] [kishon] [vijay] [abraham] [i] [kishon]@[ti] [com] 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 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 [author] [graeme] [gregory] [gg]@[slimlogic] [co] [uk] [author] [kishon] [vijay] [abraham] [i] [kishon]@[ti] [com] [based] [on] [twl6030]_[usb] [c] [author] [hema] [hk] [hemahk]@[ti] [com] 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 extracted by the scancode license scanner the SPDX license identifier GPL-2.0-or-later has been chosen to replace the boilerplate/reference in 1105 file(s). Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Reviewed-by: Allison Randal <allison@lohutok.net> Reviewed-by: Richard Fontana <rfontana@redhat.com> Reviewed-by: Kate Stewart <kstewart@linuxfoundation.org> Cc: linux-spdx@vger.kernel.org Link: https://lkml.kernel.org/r/20190527070033.202006027@linutronix.de Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2018-07-26clocksource/drivers/timer-mediatek: Add support for system timerStanley Chu1-1/+103
This patch adds a new "System Timer" on the Mediatek SoCs. The System Timer is introduced as an always-on timer being clockevent device for tick-broadcasting. For clock, it is driven by 13 MHz system clock. The implementation uses the system clock with no clock source divider. For interrupt, the clock event timer can be used by all cores. Signed-off-by: Stanley Chu <stanley.chu@mediatek.com> Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
2018-07-26clocksource/drivers/timer-mediatek: Convert the driver to timer-ofStanley Chu1-125/+80
Convert the driver to use the timer_of helpers. This allows to remove custom proprietary structure, factors out and simplifies the code. Signed-off-by: Stanley Chu <stanley.chu@mediatek.com> Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
2018-07-26clocksource/drivers/timer-mediatek: Use specific prefix for GPTStanley Chu1-77/+80
Use specific prefix to specify the name of supported timer hardware: "General Purpose Timer (GPT)". Signed-off-by: Stanley Chu <stanley.chu@mediatek.com> Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
2018-07-26clocksource/drivers/timer-mediatek: Rename mtk_timer to timer-mediatekStanley Chu1-0/+268
Rename mtk_timer to timer-mediatek to apply new naming convention in clocksource folder. Signed-off-by: Stanley Chu <stanley.chu@mediatek.com> Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>