From patchwork Tue Dec 19 14:54:00 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xingyu Wu X-Patchwork-Id: 181032 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:24d3:b0:fb:cd0c:d3e with SMTP id r19csp1991989dyi; Tue, 19 Dec 2023 06:55:23 -0800 (PST) X-Google-Smtp-Source: AGHT+IHQhnzpUjdbM5RrftJZ/2cVf2lx6tB2MvcIZm+U0tAlz0FriSaIoe+E6lcdV9WfEfabR9k5 X-Received: by 2002:ac2:58cf:0:b0:50e:376f:2dc3 with SMTP id u15-20020ac258cf000000b0050e376f2dc3mr1796893lfo.106.1702997723216; Tue, 19 Dec 2023 06:55:23 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1702997723; cv=none; d=google.com; s=arc-20160816; b=izzLgZmz8nUM1q0er1qDI7DvntX8Zi+UTXWmg5HPw2i1Z4f+hQykNlzGe4AIQ/hZGu nRLOkvQ+BwLxf+7EakbERvZhMXyOAQsoqeUQWuok6PcoF2sQgfUsBqk55FPZ13WxM4yI Va7VAhWD+8WfUMAFwVPsbn07XC0C/SxsC+uTU+v1fC2RLR7q9jFQjIHmS0LQR2WO3jvR /G7PhsDPWMZloyrZWGym7EolgvtrJ71moVe5d144wSBTY/qVlqGhvKYH2jZe1ghN7QFl PRH8Vn4McZLXTHJch8iKU9zA+nXBwg6eix0xTOeXp9GE9fmFQicAw7GbhuulwYGy5CPT pyyQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from; bh=cFqq/jTNYcSre/gxYJKS/1wJEkfgKmaq3hitPixQ/HQ=; fh=6IUnnv9uwkBrfAtoVniyYWJWHbkQfzj6U5gW0z7Gy4M=; b=jpzys+ROywn8uJYpUeo18cbjYXU9V4UTeyDk1+W1kq7qyl88K0NH+3tP28hzV9lOB+ RujITJiPcVQo2OSNj9b5i5XLnkGUhaSJeHm9I5V6/spMaQHzGWcoDtBsvQyPyDrmqeTY EFZpDsAZkrViD+5994i/K9MjRAmldOtVVMHrDMlRxxnGNqQyhKTTLPOQH4Ds+EbyTIZM cy3soaZqXMFL7Uz1zA5qPCMl2yY1SVcv1F5cjLXt1GZ5Z2ksWEQoq0xWFYUh3kYmkq82 VEdpfdgL4dghXpHA4r+KxgrTZ09MsJDBRJynNo6vjJA58/oA9PeUB0464lewR0PJTo1x g7EA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel+bounces-5420-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) smtp.mailfrom="linux-kernel+bounces-5420-ouuuleilei=gmail.com@vger.kernel.org" Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [147.75.80.249]) by mx.google.com with ESMTPS id i10-20020a0564020f0a00b00553a683dce3si371292eda.255.2023.12.19.06.55.23 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 19 Dec 2023 06:55:23 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-5420-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) client-ip=147.75.80.249; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel+bounces-5420-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) smtp.mailfrom="linux-kernel+bounces-5420-ouuuleilei=gmail.com@vger.kernel.org" Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by am.mirrors.kernel.org (Postfix) with ESMTPS id C5ADF1F21F4C for ; Tue, 19 Dec 2023 14:55:22 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 2D2A01D555; Tue, 19 Dec 2023 14:54:21 +0000 (UTC) X-Original-To: linux-kernel@vger.kernel.org Received: from ex01.ufhost.com (ex01.ufhost.com [61.152.239.75]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1646D1CA82; Tue, 19 Dec 2023 14:54:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=starfivetech.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=starfivetech.com Received: from EXMBX165.cuchost.com (unknown [175.102.18.54]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "EXMBX165", Issuer "EXMBX165" (not verified)) by ex01.ufhost.com (Postfix) with ESMTP id 51A0B24E24D; Tue, 19 Dec 2023 22:54:04 +0800 (CST) Received: from EXMBX061.cuchost.com (172.16.6.61) by EXMBX165.cuchost.com (172.16.6.75) with Microsoft SMTP Server (TLS) id 15.0.1497.42; Tue, 19 Dec 2023 22:54:04 +0800 Received: from localhost.localdomain (113.72.145.47) by EXMBX061.cuchost.com (172.16.6.61) with Microsoft SMTP Server (TLS) id 15.0.1497.42; Tue, 19 Dec 2023 22:54:03 +0800 From: Xingyu Wu To: Daniel Lezcano , Thomas Gleixner , Emil Renner Berthing , Christophe JAILLET CC: , , "Rob Herring" , Krzysztof Kozlowski , Paul Walmsley , Palmer Dabbelt , Albert Ou , Philipp Zabel , Walker Chen , Xingyu Wu , , Conor Dooley Subject: [PATCH v8 1/3] dt-bindings: timer: Add timer for StarFive JH7110 SoC Date: Tue, 19 Dec 2023 22:54:00 +0800 Message-ID: <20231219145402.7879-2-xingyu.wu@starfivetech.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20231219145402.7879-1-xingyu.wu@starfivetech.com> References: <20231219145402.7879-1-xingyu.wu@starfivetech.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: EXCAS061.cuchost.com (172.16.6.21) To EXMBX061.cuchost.com (172.16.6.61) X-YovoleRuleAgent: yovoleflag X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1785722540705211080 X-GMAIL-MSGID: 1785722540705211080 Add bindings for the timer on the JH7110 RISC-V SoC by StarFive Technology Ltd. Reviewed-by: Krzysztof Kozlowski Signed-off-by: Xingyu Wu --- .../bindings/timer/starfive,jh7110-timer.yaml | 96 +++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 Documentation/devicetree/bindings/timer/starfive,jh7110-timer.yaml diff --git a/Documentation/devicetree/bindings/timer/starfive,jh7110-timer.yaml b/Documentation/devicetree/bindings/timer/starfive,jh7110-timer.yaml new file mode 100644 index 000000000000..9a2dac11eb06 --- /dev/null +++ b/Documentation/devicetree/bindings/timer/starfive,jh7110-timer.yaml @@ -0,0 +1,96 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/timer/starfive,jh7110-timer.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: StarFive JH7110 Timer + +maintainers: + - Xingyu Wu + - Samin Guo + +description: + This timer has four free-running 32 bit counters in StarFive JH7110 SoC. + And each channel(counter) triggers an interrupt when timeout. They support + one-shot mode and continuous-run mode. + +properties: + compatible: + const: starfive,jh7110-timer + + reg: + maxItems: 1 + + interrupts: + items: + - description: channel 0 + - description: channel 1 + - description: channel 2 + - description: channel 3 + + clocks: + items: + - description: timer APB + - description: channel 0 + - description: channel 1 + - description: channel 2 + - description: channel 3 + + clock-names: + items: + - const: apb + - const: ch0 + - const: ch1 + - const: ch2 + - const: ch3 + + resets: + items: + - description: timer APB + - description: channel 0 + - description: channel 1 + - description: channel 2 + - description: channel 3 + + reset-names: + items: + - const: apb + - const: ch0 + - const: ch1 + - const: ch2 + - const: ch3 + +required: + - compatible + - reg + - interrupts + - clocks + - clock-names + - resets + - reset-names + +additionalProperties: false + +examples: + - | + timer@13050000 { + compatible = "starfive,jh7110-timer"; + reg = <0x13050000 0x10000>; + interrupts = <69>, <70>, <71> ,<72>; + clocks = <&clk 124>, + <&clk 125>, + <&clk 126>, + <&clk 127>, + <&clk 128>; + clock-names = "apb", "ch0", "ch1", + "ch2", "ch3"; + resets = <&rst 117>, + <&rst 118>, + <&rst 119>, + <&rst 120>, + <&rst 121>; + reset-names = "apb", "ch0", "ch1", + "ch2", "ch3"; + }; + From patchwork Tue Dec 19 14:54:01 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xingyu Wu X-Patchwork-Id: 181030 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:24d3:b0:fb:cd0c:d3e with SMTP id r19csp1991921dyi; Tue, 19 Dec 2023 06:55:17 -0800 (PST) X-Google-Smtp-Source: AGHT+IHWRVKzXHCK500tN6xqiCzjya7mwxgeU0uRGnkIXJNQqcIBdTNKtUp4AX5Bo/tjzytQCKBs X-Received: by 2002:a05:622a:24b:b0:425:4043:41ca with SMTP id c11-20020a05622a024b00b00425404341camr25810879qtx.118.1702997716978; Tue, 19 Dec 2023 06:55:16 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1702997716; cv=none; d=google.com; s=arc-20160816; b=KxHL4CvlykAybc5fqRe+Slbgsg4CzVmmGFMz5HYnQnRu54+rmZhXwo3kcXBxhJzwoT Yt4Cvwr0/7JSI2QQr1ZcV4qXxwnzGfXnK9o1/gLwmvFULWzzz/OquPzsFnS9FqDJc2in r1JzuZL96RuiOdNKMKBBwtXlTcEeGkf8Opuj5yfpFSa2z9Pyhl+TDg3AHtW0wu+XAuRy h68t+VJEkDhSiOsVO2rTNS6cwmXUZbYVEWqlxxQCXYZt5OqDv8koN0nA4wFI+EtHF/Lz 3xs1UWRsC1VDjz02QdSCmpT4tasd58WwFdmP9FKlrf7L5L0JWgUikSPNAtXqANKT9oeK R0ZA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from; bh=pCsC3VUMMNr2+6WoHIJkW+Dtyoh9/sX6vGub4IIK8/g=; fh=6IUnnv9uwkBrfAtoVniyYWJWHbkQfzj6U5gW0z7Gy4M=; b=PJMu/SKmE6sYFrdeR2OpBMj2Rhhl+a8bA2UKkBEJIDqq4vwHaUPXXpdmBSbFfY7+oT e5UlOGOxv8YDHBa/cIowK1tzs8fSCmvGdsX9FDyPnQFyHOyz6hfiEBgO2cLospx+34rQ MhFogPqqAJWVUxQav/uFl7zbEZkuIKCJipgDSZDgqnre4aiAzqeZude4ThklAX1cJ15O ZOq6NaqLZ7PD6iSTIw9AyROKAJM2Q0vFPq+2vHKXBF4dr0gUKh5q+BAPBpztc+7RW5TA NvAiQ46teQo1jB+cwYWX2ST2SQpJIA5AhJ2/ixJ5Cfxlsd8aa1QajZTvjoKornP+OdIm CoPA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel+bounces-5419-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-5419-ouuuleilei=gmail.com@vger.kernel.org" Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [2604:1380:45d1:ec00::1]) by mx.google.com with ESMTPS id fc13-20020a05622a488d00b004236e29618bsi28119438qtb.323.2023.12.19.06.55.16 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 19 Dec 2023 06:55:16 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-5419-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) client-ip=2604:1380:45d1:ec00::1; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel+bounces-5419-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-5419-ouuuleilei=gmail.com@vger.kernel.org" Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ny.mirrors.kernel.org (Postfix) with ESMTPS id A47E41C210AF for ; Tue, 19 Dec 2023 14:55:16 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id BE5AB1D53F; Tue, 19 Dec 2023 14:54:20 +0000 (UTC) X-Original-To: linux-kernel@vger.kernel.org Received: from ex01.ufhost.com (ex01.ufhost.com [61.152.239.75]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4274E1C688; Tue, 19 Dec 2023 14:54:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=starfivetech.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=starfivetech.com Received: from EXMBX166.cuchost.com (unknown [175.102.18.54]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "EXMBX166", Issuer "EXMBX166" (not verified)) by ex01.ufhost.com (Postfix) with ESMTP id 1604424E27A; Tue, 19 Dec 2023 22:54:05 +0800 (CST) Received: from EXMBX061.cuchost.com (172.16.6.61) by EXMBX166.cuchost.com (172.16.6.76) with Microsoft SMTP Server (TLS) id 15.0.1497.42; Tue, 19 Dec 2023 22:54:04 +0800 Received: from localhost.localdomain (113.72.145.47) by EXMBX061.cuchost.com (172.16.6.61) with Microsoft SMTP Server (TLS) id 15.0.1497.42; Tue, 19 Dec 2023 22:54:04 +0800 From: Xingyu Wu To: Daniel Lezcano , Thomas Gleixner , Emil Renner Berthing , Christophe JAILLET CC: , , "Rob Herring" , Krzysztof Kozlowski , Paul Walmsley , Palmer Dabbelt , Albert Ou , Philipp Zabel , Walker Chen , Xingyu Wu , , Conor Dooley Subject: [PATCH v8 2/3] clocksource: Add JH7110 timer driver Date: Tue, 19 Dec 2023 22:54:01 +0800 Message-ID: <20231219145402.7879-3-xingyu.wu@starfivetech.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20231219145402.7879-1-xingyu.wu@starfivetech.com> References: <20231219145402.7879-1-xingyu.wu@starfivetech.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: EXCAS061.cuchost.com (172.16.6.21) To EXMBX061.cuchost.com (172.16.6.61) X-YovoleRuleAgent: yovoleflag X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1785722533597554811 X-GMAIL-MSGID: 1785722533597554811 Add timer driver for the StarFive JH7110 SoC and select it by CONFIG_SOC_STARFIVE. This timer has four free-running and independent 32-bit counters. Each channel(counter) can trigger an interrupt when timeout even CPU is sleeping. So this timer is used as global timer and register clockevent for each CPU core after riscv-timer registration on the StarFive JH7110 SoC. Signed-off-by: Xingyu Wu --- MAINTAINERS | 7 + arch/riscv/Kconfig.socs | 1 + drivers/clocksource/Kconfig | 9 + drivers/clocksource/Makefile | 1 + drivers/clocksource/timer-jh7110.c | 360 +++++++++++++++++++++++++++++ include/linux/cpuhotplug.h | 1 + 6 files changed, 379 insertions(+) create mode 100644 drivers/clocksource/timer-jh7110.c diff --git a/MAINTAINERS b/MAINTAINERS index 9104430e148e..fe0e803606a5 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -20617,6 +20617,13 @@ S: Maintained F: Documentation/devicetree/bindings/sound/starfive,jh7110-tdm.yaml F: sound/soc/starfive/jh7110_tdm.c +STARFIVE JH7110 TIMER DRIVER +M: Samin Guo +M: Xingyu Wu +S: Supported +F: Documentation/devicetree/bindings/timer/starfive,jh7110-timer.yaml +F: drivers/clocksource/timer-jh7110.c + STARFIVE JH71X0 CLOCK DRIVERS M: Emil Renner Berthing M: Hal Feng diff --git a/arch/riscv/Kconfig.socs b/arch/riscv/Kconfig.socs index e08e91c49abe..e986590f40b0 100644 --- a/arch/riscv/Kconfig.socs +++ b/arch/riscv/Kconfig.socs @@ -35,6 +35,7 @@ config SOC_STARFIVE select PINCTRL select RESET_CONTROLLER select ARM_AMBA + select STARFIVE_JH7110_TIMER help This enables support for StarFive SoC platform hardware. diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index 34faa0320ece..3f273f07a258 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig @@ -641,6 +641,15 @@ config RISCV_TIMER is accessed via both the SBI and the rdcycle instruction. This is required for all RISC-V systems. +config STARFIVE_JH7110_TIMER + bool "Timer for the STARFIVE JH7110 SoC" if COMPILE_TEST + select TIMER_OF + select CLKSRC_MMIO + help + This enables the timer for StarFive JH7110 SoC. On RISC-V platform, + the system has started RISCV_TIMER, but you can also use this timer + which can provide four channels of higher rating on the JH7110 SoC. + config CLINT_TIMER bool "CLINT Timer for the RISC-V platform" if COMPILE_TEST depends on GENERIC_SCHED_CLOCK && RISCV diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile index 4bb856e4df55..8dc2f0ea2d0f 100644 --- a/drivers/clocksource/Makefile +++ b/drivers/clocksource/Makefile @@ -80,6 +80,7 @@ obj-$(CONFIG_INGENIC_TIMER) += ingenic-timer.o obj-$(CONFIG_CLKSRC_ST_LPC) += clksrc_st_lpc.o obj-$(CONFIG_X86_NUMACHIP) += numachip.o obj-$(CONFIG_RISCV_TIMER) += timer-riscv.o +obj-$(CONFIG_STARFIVE_JH7110_TIMER) += timer-jh7110.o obj-$(CONFIG_CLINT_TIMER) += timer-clint.o obj-$(CONFIG_CSKY_MP_TIMER) += timer-mp-csky.o obj-$(CONFIG_GX6605S_TIMER) += timer-gx6605s.o diff --git a/drivers/clocksource/timer-jh7110.c b/drivers/clocksource/timer-jh7110.c new file mode 100644 index 000000000000..bd93e71969c2 --- /dev/null +++ b/drivers/clocksource/timer-jh7110.c @@ -0,0 +1,360 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Starfive JH7110 Timer driver + * + * Copyright (C) 2023 StarFive Technology Co., Ltd. + * + * This timer has four free-running and independent 32-bit counters and runs in 24MHz + * clock on the StarFive JH7110 SoC. Each channel(counter) can trigger an interrupt + * when timeout even CPU is sleeping. They support one-shot mode and continuous-run mode. + * + * Each channel is used as a global timer that serves each cpu core: + * JH7110 Timer Channel 0 -- CPU 0 + * JH7110 Timer Channel 1 -- CPU 1 + * JH7110 Timer Channel 2 -- CPU 2 + * JH7110 Timer Channel 3 -- CPU 3 + */ + +#include +#include +#include +#include +#include +#include +#include + +/* Bias: Ch0-0x0, Ch1-0x40, Ch2-0x80, and so on. */ +#define JH7110_TIMER_CH_LEN 0x40 +#define JH7110_TIMER_CH_BASE(x) ((x) * JH7110_TIMER_CH_LEN) +#define JH7110_TIMER_CH_MAX 4 + +#define JH7110_DELAY_US 0 +#define JH7110_TIMEOUT_US 10000 +#define JH7110_CLOCKEVENT_RATING 300 +#define JH7110_TIMER_MAX_TICKS 0xffffffff +#define JH7110_TIMER_MIN_TICKS 0xf + +#define JH7110_TIMER_INT_STATUS 0x00 /* + * RO[0:4]: Interrupt Status for channel0~4 + * Only valid on the JH7110_TIMER_CH_BASE(0) + */ +#define JH7110_TIMER_CTL 0x04 /* RW[0]: 0-continuous run, 1-single run */ +#define JH7110_TIMER_LOAD 0x08 /* RW: load value to counter */ +#define JH7110_TIMER_ENABLE 0x10 /* RW[0]: timer enable register */ +#define JH7110_TIMER_RELOAD 0x14 /* RW: write 1 or 0 both reload counter */ +#define JH7110_TIMER_VALUE 0x18 /* RO: timer value register */ +#define JH7110_TIMER_INT_CLR 0x20 /* RW: timer interrupt clear register */ +#define JH7110_TIMER_INT_MASK 0x24 /* RW[0]: timer interrupt mask register */ + +#define JH7110_TIMER_RELOAD_VALID 0 +#define JH7110_TIMER_INT_CLR_ENA BIT(0) +#define JH7110_TIMER_INT_CLR_AVA_MASK BIT(1) + +#define JH7110_PERCPU_GET_CLKEVT (&jh7110_timer_info.clkevt[smp_processor_id()]) + +struct jh7110_clkevt { + struct clk *clk; + struct reset_control *rst; + void __iomem *base; + u32 reload_val; + int irq; + char name[sizeof("jh7110-timer.chX")]; +}; + +struct jh7110_timer_priv { + struct reset_control *prst; + struct device *dev; + struct jh7110_clkevt clkevt[JH7110_TIMER_CH_MAX]; +}; + +/* 0:continuous-run mode, 1:single-run mode */ +enum jh7110_timer_mode { + JH7110_TIMER_MODE_CONTIN, + JH7110_TIMER_MODE_SINGLE, +}; + +/* Interrupt Mask, 0:Unmask, 1:Mask */ +enum jh7110_timer_int_mask { + JH7110_TIMER_INT_ENA, + JH7110_TIMER_INT_DIS, +}; + +enum jh7110_timer_enable { + JH7110_TIMER_DIS, + JH7110_TIMER_ENA, +}; + +static struct jh7110_timer_priv jh7110_timer_info; + +/* + * BIT(0): Read value represent channel int status. + * Write 1 to this bit to clear interrupt. Write 0 has no effects. + * BIT(1): "1" means that it is clearing interrupt. BIT(0) can not be written. + */ +static int jh7110_timer_int_is_clearing(struct jh7110_clkevt *clkevt) +{ + u32 value; + + /* Waiting interrupt can be cleared */ + return readl_poll_timeout_atomic(clkevt->base + JH7110_TIMER_INT_CLR, value, + !(value & JH7110_TIMER_INT_CLR_AVA_MASK), + JH7110_DELAY_US, JH7110_TIMEOUT_US); +} + +static int jh7110_timer_start(struct jh7110_clkevt *clkevt) +{ + int ret; + + /* Disable and clear interrupt first */ + writel(JH7110_TIMER_INT_DIS, clkevt->base + JH7110_TIMER_INT_MASK); + ret = jh7110_timer_int_is_clearing(clkevt); + if (ret) + return ret; + + writel(JH7110_TIMER_INT_CLR_ENA, (clkevt->base + JH7110_TIMER_INT_CLR)); + writel(JH7110_TIMER_INT_ENA, clkevt->base + JH7110_TIMER_INT_MASK); + writel(JH7110_TIMER_ENA, clkevt->base + JH7110_TIMER_ENABLE); + + return 0; +} + +static int jh7110_timer_shutdown(struct clock_event_device *evt) +{ + struct jh7110_clkevt *clkevt = JH7110_PERCPU_GET_CLKEVT; + int ret = 0; + + writel(JH7110_TIMER_DIS, clkevt->base + JH7110_TIMER_ENABLE); + ret = jh7110_timer_int_is_clearing(clkevt); + if (!ret) + writel(JH7110_TIMER_INT_CLR_ENA, (clkevt->base + JH7110_TIMER_INT_CLR)); + + return ret; +} + +static void jh7110_timer_suspend(struct clock_event_device *evt) +{ + struct jh7110_clkevt *clkevt = JH7110_PERCPU_GET_CLKEVT; + + clkevt->reload_val = readl(clkevt->base + JH7110_TIMER_LOAD); + jh7110_timer_shutdown(evt); +} + +static int jh7110_timer_tick_resume(struct clock_event_device *evt) +{ + struct jh7110_clkevt *clkevt = JH7110_PERCPU_GET_CLKEVT; + + writel(clkevt->reload_val, clkevt->base + JH7110_TIMER_LOAD); + writel(JH7110_TIMER_RELOAD_VALID, clkevt->base + JH7110_TIMER_RELOAD); + return jh7110_timer_start(clkevt); +} + +static void jh7110_timer_resume(struct clock_event_device *evt) +{ + jh7110_timer_tick_resume(evt); +} + +/* IRQ handler for the timer */ +static irqreturn_t jh7110_timer_interrupt(int irq, void *data) +{ + struct clock_event_device *evt = data; + struct jh7110_clkevt *clkevt = &jh7110_timer_info.clkevt[0]; + u8 cpu_id = smp_processor_id(); + u32 reg = readl(clkevt->base + JH7110_TIMER_INT_STATUS); + + /* Check interrupt status and channel(cpu) ID */ + if (!(reg & BIT(cpu_id))) + return IRQ_NONE; + + clkevt = &jh7110_timer_info.clkevt[cpu_id]; + writel(JH7110_TIMER_INT_CLR_ENA, (clkevt->base + JH7110_TIMER_INT_CLR)); + + if (evt->event_handler) + evt->event_handler(evt); + + return IRQ_HANDLED; +} + +static int jh7110_timer_set_periodic(struct clock_event_device *evt) +{ + struct jh7110_clkevt *clkevt = JH7110_PERCPU_GET_CLKEVT; + + writel(JH7110_TIMER_MODE_CONTIN, clkevt->base + JH7110_TIMER_CTL); + return 0; +} + +static int jh7110_timer_set_oneshot(struct clock_event_device *evt) +{ + struct jh7110_clkevt *clkevt = JH7110_PERCPU_GET_CLKEVT; + + writel(JH7110_TIMER_MODE_SINGLE, clkevt->base + JH7110_TIMER_CTL); + return 0; +} + +static int jh7110_timer_set_next_event(unsigned long next, + struct clock_event_device *evt) +{ + struct jh7110_clkevt *clkevt = JH7110_PERCPU_GET_CLKEVT; + + writel(JH7110_TIMER_MODE_SINGLE, clkevt->base + JH7110_TIMER_CTL); + writel(next, clkevt->base + JH7110_TIMER_LOAD); + + return jh7110_timer_start(clkevt); +} + +static DEFINE_PER_CPU(struct clock_event_device, jh7110_clock_event) = { + .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, + .rating = JH7110_CLOCKEVENT_RATING, + .set_state_shutdown = jh7110_timer_shutdown, + .set_state_periodic = jh7110_timer_set_periodic, + .set_state_oneshot = jh7110_timer_set_oneshot, + .set_state_oneshot_stopped = jh7110_timer_shutdown, + .tick_resume = jh7110_timer_tick_resume, + .set_next_event = jh7110_timer_set_next_event, + .suspend = jh7110_timer_suspend, + .resume = jh7110_timer_resume, +}; + +static int jh7110_timer_starting_cpu(unsigned int cpu) +{ + struct clock_event_device *evt = per_cpu_ptr(&jh7110_clock_event, cpu); + struct jh7110_timer_priv *priv = &jh7110_timer_info; + int ret; + u32 rate; + + if (cpu >= JH7110_TIMER_CH_MAX) + return -ENOMEM; + + ret = clk_prepare_enable(priv->clkevt[cpu].clk); + if (ret) + return ret; + + ret = reset_control_deassert(priv->clkevt[cpu].rst); + if (ret) + return ret; + + rate = clk_get_rate(priv->clkevt[cpu].clk); + evt->cpumask = cpumask_of(cpu); + evt->irq = priv->clkevt[cpu].irq; + evt->name = priv->clkevt[cpu].name; + clockevents_config_and_register(evt, rate, JH7110_TIMER_MIN_TICKS, + JH7110_TIMER_MAX_TICKS); + + ret = devm_request_irq(priv->dev, evt->irq, jh7110_timer_interrupt, + IRQF_TIMER | IRQF_IRQPOLL, + evt->name, evt); + if (ret) + return ret; + + ret = irq_set_affinity(evt->irq, cpumask_of(cpu)); + if (ret) + return ret; + + /* Use one-shot mode */ + writel(JH7110_TIMER_MODE_SINGLE, (priv->clkevt[cpu].base + JH7110_TIMER_CTL)); + + return jh7110_timer_start(&priv->clkevt[cpu]); +} + +static void jh7110_timer_release(void *data) +{ + struct jh7110_timer_priv *priv = data; + int i; + + for (i = 0; i < JH7110_TIMER_CH_MAX; i++) { + /* Disable each channel of timer */ + if (priv->clkevt[i].base) + writel(JH7110_TIMER_DIS, priv->clkevt[i].base + JH7110_TIMER_ENABLE); + + /* Avoid no initialization in the loop of the probe */ + if (!IS_ERR_OR_NULL(priv->clkevt[i].rst)) + reset_control_assert(priv->clkevt[i].rst); + + if (!IS_ERR_OR_NULL(priv->clkevt[i].clk)) + clk_disable_unprepare(priv->clkevt[i].clk); + } + + reset_control_assert(priv->prst); +} + +static int jh7110_timer_probe(struct platform_device *pdev) +{ + struct jh7110_timer_priv *priv = &jh7110_timer_info; + struct jh7110_clkevt *clkevt; + struct clk *pclk; + void __iomem *base; + int ch; + int ret; + char name[sizeof("chX")]; + + base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(base)) + return dev_err_probe(&pdev->dev, PTR_ERR(base), + "failed to map registers\n"); + + priv->prst = devm_reset_control_get_exclusive(&pdev->dev, "apb"); + if (IS_ERR(priv->prst)) + return dev_err_probe(&pdev->dev, PTR_ERR(priv->prst), + "failed to get apb reset\n"); + + pclk = devm_clk_get_enabled(&pdev->dev, "apb"); + if (IS_ERR(pclk)) + return dev_err_probe(&pdev->dev, PTR_ERR(pclk), + "failed to get & enable apb clock\n"); + + ret = reset_control_deassert(priv->prst); + if (ret) + return dev_err_probe(&pdev->dev, ret, "failed to deassert apb reset\n"); + + ret = devm_add_action_or_reset(&pdev->dev, jh7110_timer_release, priv); + if (ret) + return ret; + + priv->dev = &pdev->dev; + for (ch = 0; ch < JH7110_TIMER_CH_MAX; ch++) { + clkevt = &priv->clkevt[ch]; + snprintf(name, sizeof(name), "ch%d", ch); + + clkevt->base = base + JH7110_TIMER_CH_BASE(ch); + /* Ensure timer is disabled */ + writel(JH7110_TIMER_DIS, clkevt->base + JH7110_TIMER_ENABLE); + if (!jh7110_timer_int_is_clearing(clkevt)) + writel(JH7110_TIMER_INT_CLR_ENA, (clkevt->base + JH7110_TIMER_INT_CLR)); + + clkevt->rst = devm_reset_control_get_exclusive(&pdev->dev, name); + if (IS_ERR(clkevt->rst)) + return PTR_ERR(clkevt->rst); + + clkevt->clk = devm_clk_get(&pdev->dev, name); + if (IS_ERR(clkevt->clk)) + return PTR_ERR(clkevt->clk); + + clkevt->irq = platform_get_irq(pdev, ch); + if (clkevt->irq < 0) + return clkevt->irq; + + snprintf(clkevt->name, sizeof(clkevt->name), "jh7110-timer.ch%d", ch); + } + + return cpuhp_setup_state(CPUHP_AP_JH7110_TIMER_STARTING, + "clockevents/jh7110/timer:starting", + jh7110_timer_starting_cpu, NULL); +} + +static const struct of_device_id jh7110_timer_match[] = { + { .compatible = "starfive,jh7110-timer", }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, jh7110_timer_match); + +static struct platform_driver jh7110_timer_driver = { + .probe = jh7110_timer_probe, + .driver = { + .name = "jh7110-timer", + .of_match_table = jh7110_timer_match, + }, +}; +module_platform_driver(jh7110_timer_driver); + +MODULE_AUTHOR("Xingyu Wu "); +MODULE_DESCRIPTION("StarFive JH7110 timer driver"); +MODULE_LICENSE("GPL"); diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h index efc0c0b07efb..f28a3aaf93f9 100644 --- a/include/linux/cpuhotplug.h +++ b/include/linux/cpuhotplug.h @@ -187,6 +187,7 @@ enum cpuhp_state { CPUHP_AP_CSKY_TIMER_STARTING, CPUHP_AP_TI_GP_TIMER_STARTING, CPUHP_AP_HYPERV_TIMER_STARTING, + CPUHP_AP_JH7110_TIMER_STARTING, /* Must be the last timer callback */ CPUHP_AP_DUMMY_TIMER_STARTING, CPUHP_AP_ARM_XEN_STARTING, From patchwork Tue Dec 19 14:54:02 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xingyu Wu X-Patchwork-Id: 181035 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:24d3:b0:fb:cd0c:d3e with SMTP id r19csp1994552dyi; Tue, 19 Dec 2023 06:59:50 -0800 (PST) X-Google-Smtp-Source: AGHT+IGML9USnErH105NawzLzVfSYkNShphTlrMpodn7V/d0lZCYXFs3BCwZ1LLlFGGSVzaxnOlu X-Received: by 2002:a05:6a00:1909:b0:6ce:8387:e4dd with SMTP id y9-20020a056a00190900b006ce8387e4ddmr10747692pfi.32.1702997990578; Tue, 19 Dec 2023 06:59:50 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1702997990; cv=none; d=google.com; s=arc-20160816; b=XYwo2xYvBeSMJwwrSsUJlcANEPOWYJkQ7dQtQtgNmFg1z6xpCnxcN7zloQcp8YJn22 lknGOFKXdr3Hcprpa3utQo8fConpTRGgqmarL4DEx6eoGi9mspAsUy7TXHMAYUYl/sMe dSmk6DLZNgDIihdydWemFxDGKi5a4PGwmqzsKi4M5m2epToli7gQnDaujxHDbLMGXw0o /A4GXQdlA03Fd/9O1JzDiGgSdKTZdJgcF9T7xY00mtomc2ICSJK99EfCt2OAI3iCYwPe 1UIuA2ZiHtpkmmuNpCy4ez+ceuIEd68vwPZRGjZAFelPLBrrSUYjrmOxuVcVlO+Ry2py Z0xQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from; bh=GWhSlDd6amYp0dqMBlMLTzEjgYNhTl4CRXt6TmXU7lA=; fh=6IUnnv9uwkBrfAtoVniyYWJWHbkQfzj6U5gW0z7Gy4M=; b=fC9buj9UAT1Ll45b0KPR+M1r5uIBKWetsYLkA8VcIzkRaEMA4m+VRg9/0mq9R1NLGW GpzoWj8pI7enOAeP+OCjPe6NFiAZnproIYMXq91lSa8TjdAA9wUclRWO/g8U1FA8gR+g vdrP+zrZHoSUZ/DXbOmPC/q7Lg8wWk15p7Si+/bbZnkOW7eTytrBkzdl0HduQV2i2Z95 5FIa10ZwZahyls8LIJaxCu8aBQP+sUYDzJkA4g2kylRDWegHqUiZZ9eBSMXP1Rjd7jcr gkf7SFjg4Arz12h9QXXqfpogu+YRWUn0yCTz1uUhQh1RvwywOfKNXbqFVMf4GcXule7Y rx8g== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel+bounces-5418-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-5418-ouuuleilei=gmail.com@vger.kernel.org" Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [2604:1380:45e3:2400::1]) by mx.google.com with ESMTPS id ay12-20020a056a00300c00b006d8295bf996si3138040pfb.110.2023.12.19.06.59.50 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 19 Dec 2023 06:59:50 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-5418-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) client-ip=2604:1380:45e3:2400::1; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel+bounces-5418-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-5418-ouuuleilei=gmail.com@vger.kernel.org" Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sv.mirrors.kernel.org (Postfix) with ESMTPS id 3447A2857C0 for ; Tue, 19 Dec 2023 14:54:51 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 7B8981CF83; Tue, 19 Dec 2023 14:54:19 +0000 (UTC) X-Original-To: linux-kernel@vger.kernel.org Received: from fd01.gateway.ufhost.com (fd01.gateway.ufhost.com [61.152.239.71]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6CF4E1C6BB; Tue, 19 Dec 2023 14:54:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=starfivetech.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=starfivetech.com Received: from EXMBX165.cuchost.com (unknown [175.102.18.54]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "EXMBX165", Issuer "EXMBX165" (not verified)) by fd01.gateway.ufhost.com (Postfix) with ESMTP id BCFDD7FEE; Tue, 19 Dec 2023 22:54:05 +0800 (CST) Received: from EXMBX061.cuchost.com (172.16.6.61) by EXMBX165.cuchost.com (172.16.6.75) with Microsoft SMTP Server (TLS) id 15.0.1497.42; Tue, 19 Dec 2023 22:54:05 +0800 Received: from localhost.localdomain (113.72.145.47) by EXMBX061.cuchost.com (172.16.6.61) with Microsoft SMTP Server (TLS) id 15.0.1497.42; Tue, 19 Dec 2023 22:54:04 +0800 From: Xingyu Wu To: Daniel Lezcano , Thomas Gleixner , Emil Renner Berthing , Christophe JAILLET CC: , , "Rob Herring" , Krzysztof Kozlowski , Paul Walmsley , Palmer Dabbelt , Albert Ou , Philipp Zabel , Walker Chen , Xingyu Wu , , Conor Dooley Subject: [PATCH v8 3/3] riscv: dts: jh7110: starfive: Add timer node Date: Tue, 19 Dec 2023 22:54:02 +0800 Message-ID: <20231219145402.7879-4-xingyu.wu@starfivetech.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20231219145402.7879-1-xingyu.wu@starfivetech.com> References: <20231219145402.7879-1-xingyu.wu@starfivetech.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: EXCAS061.cuchost.com (172.16.6.21) To EXMBX061.cuchost.com (172.16.6.61) X-YovoleRuleAgent: yovoleflag X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1785722821233772047 X-GMAIL-MSGID: 1785722821233772047 Add the timer node for the Starfive JH7110 SoC. Reviewed-by: Emil Renner Berthing Reviewed-by: Walker Chen Signed-off-by: Xingyu Wu --- arch/riscv/boot/dts/starfive/jh7110.dtsi | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/arch/riscv/boot/dts/starfive/jh7110.dtsi b/arch/riscv/boot/dts/starfive/jh7110.dtsi index 45213cdf50dc..46836da9940f 100644 --- a/arch/riscv/boot/dts/starfive/jh7110.dtsi +++ b/arch/riscv/boot/dts/starfive/jh7110.dtsi @@ -904,6 +904,26 @@ sysgpio: pinctrl@13040000 { #gpio-cells = <2>; }; + timer@13050000 { + compatible = "starfive,jh7110-timer"; + reg = <0x0 0x13050000 0x0 0x10000>; + interrupts = <69>, <70>, <71>, <72>; + clocks = <&syscrg JH7110_SYSCLK_TIMER_APB>, + <&syscrg JH7110_SYSCLK_TIMER0>, + <&syscrg JH7110_SYSCLK_TIMER1>, + <&syscrg JH7110_SYSCLK_TIMER2>, + <&syscrg JH7110_SYSCLK_TIMER3>; + clock-names = "apb", "ch0", "ch1", + "ch2", "ch3"; + resets = <&syscrg JH7110_SYSRST_TIMER_APB>, + <&syscrg JH7110_SYSRST_TIMER0>, + <&syscrg JH7110_SYSRST_TIMER1>, + <&syscrg JH7110_SYSRST_TIMER2>, + <&syscrg JH7110_SYSRST_TIMER3>; + reset-names = "apb", "ch0", "ch1", + "ch2", "ch3"; + }; + watchdog@13070000 { compatible = "starfive,jh7110-wdt"; reg = <0x0 0x13070000 0x0 0x10000>;