From nobody Mon Dec 15 21:27:43 2025 Received: from sender4-op-o16.zoho.com (sender4-op-o16.zoho.com [136.143.188.16]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A36FE1E0B9C; Sat, 19 Apr 2025 17:10:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=pass smtp.client-ip=136.143.188.16 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1745082651; cv=pass; b=HoRxZPFOlbNr3qe3mE7w3Nu9sCUNrRVWfs9KMvE0CibLEExaJM/WImbxGMrN24q5zMN8T68A1YgIQbHkWDnikpEPB+6K0iT6rHkDi5eQQcuqTiBWk/i3tk7yp3vt+Tdme02fzN89f0xaMqxF7mlmJaLR2kpGd8DwNOkpDZ/uAyQ= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1745082651; c=relaxed/simple; bh=xhweuvJS9YG88uSyt4vYb/tYoFw89Fgj4UMJwesoxG4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=SJn4gSJyHu1rPs0nJWS2+uzhWuKZbD7GLnllvtatd53v8wbcYw4a8OgH+UgZYYUxKCBnRF7GihZGnPCGvIscunL+XVg2MgQqjBul8vVdtr08jIt5c97gebblqaYpaH2f3tpRV1hDeTw9l0O3cBv+kAsSGP61FDDH+0RKSV43Bcw= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pigmoral.tech; spf=pass smtp.mailfrom=pigmoral.tech; dkim=pass (1024-bit key) header.d=pigmoral.tech header.i=junhui.liu@pigmoral.tech header.b=CZxN4Jfe; arc=pass smtp.client-ip=136.143.188.16 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pigmoral.tech Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pigmoral.tech Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=pigmoral.tech header.i=junhui.liu@pigmoral.tech header.b="CZxN4Jfe" ARC-Seal: i=1; a=rsa-sha256; t=1745082634; cv=none; d=zohomail.com; s=zohoarc; b=joKrV7XlET0fd9uSj9IicBLj26EIkBtng2SXtalHHWslW2WCL+wOwHc0cpRLgsRtRecoy067EEp1yVktpOHnoJWEd6HofuR0pR6BubnJTK9h4ErcMBWLh8giqMEC3TSyWmKedAiJzl5hKyQm3Jt8zwZScvQb6JWxmzHWOcRQX3g= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1745082634; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:MIME-Version:Message-ID:References:Subject:Subject:To:To:Message-Id:Reply-To; bh=UcvSXdnii1Lwhw7SPpHVTM5IQQa5XSKg4ecZK5XrX3A=; b=Mgc5QppazgXTJIkRvo7M3t4+UFFfSf9phpJok/pf1+//kZCtA19IT5CDKIHcGw53RQxuzv3EFH/CePuxzcoOUyVf2q8G3PmnrH7QTkcw0jlHS3vQTmNXy3i2cUsltf5iotXDhSd3mE3bc5NhWjU5N1ciIpscuEY0kU9ls6pSIMg= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass header.i=pigmoral.tech; spf=pass smtp.mailfrom=junhui.liu@pigmoral.tech; dmarc=pass header.from= DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; t=1745082634; s=zmail; d=pigmoral.tech; i=junhui.liu@pigmoral.tech; h=From:From:Date:Date:Subject:Subject:MIME-Version:Content-Type:Content-Transfer-Encoding:Message-Id:Message-Id:References:In-Reply-To:To:To:Cc:Cc:Reply-To; bh=UcvSXdnii1Lwhw7SPpHVTM5IQQa5XSKg4ecZK5XrX3A=; b=CZxN4Jfe6UW3waCqjUc/C1s1FCsiJnbivbpho/HSfDbryxcCrzK2Q0M/1Fj+BeHF rJA+8dsTgwJAKfd+D0OVNtFM9H7I3kdQoo4VVvOiPybx4eOrnJsgwFJlxyHqMiEQhC+ IBydA8emwhT2Gc1DPdMfQU+mDf3tSjo5lzSu9sTk= Received: by mx.zohomail.com with SMTPS id 1745082627676970.1168526296; Sat, 19 Apr 2025 10:10:27 -0700 (PDT) From: Junhui Liu Date: Sun, 20 Apr 2025 01:09:44 +0800 Subject: [PATCH v2 1/2] dt-bindings: reset: add support for canaan,k230-rst Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250420-k230-reset-v2-1-f1b4a016e438@pigmoral.tech> References: <20250420-k230-reset-v2-0-f1b4a016e438@pigmoral.tech> In-Reply-To: <20250420-k230-reset-v2-0-f1b4a016e438@pigmoral.tech> To: Philipp Zabel , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Junhui Liu Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-riscv@lists.infradead.org, Conor Dooley X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1745082602; l=4258; i=junhui.liu@pigmoral.tech; s=20250223; h=from:subject:message-id; bh=xhweuvJS9YG88uSyt4vYb/tYoFw89Fgj4UMJwesoxG4=; b=ZTMMoleqczN1XxhDnHt+k5wyAcQGXb0JNWzzpcsqG0g7P+NV6WxSDSp9VLkjD4YkfdnlRw9Wd CFqqA6V/T9tB/AgO9yHtxCNtGAmCBk+BgOmKNWH5MT5+x+pikZFRSIT X-Developer-Key: i=junhui.liu@pigmoral.tech; a=ed25519; pk=ZRZkOjG47iI+To+oAo2R4KIpMwtz8r0TffJ5/nO2tcg= X-ZohoMailClient: External Introduces a reset controller driver for the Kendryte K230 SoC, resposible for managing the reset functionality of the CPUs and various sub-modules. Signed-off-by: Junhui Liu Reviewed-by: Conor Dooley --- .../devicetree/bindings/reset/canaan,k230-rst.yaml | 39 ++++++++++ include/dt-bindings/reset/canaan,k230-rst.h | 90 ++++++++++++++++++= ++++ 2 files changed, 129 insertions(+) diff --git a/Documentation/devicetree/bindings/reset/canaan,k230-rst.yaml b= /Documentation/devicetree/bindings/reset/canaan,k230-rst.yaml new file mode 100644 index 0000000000000000000000000000000000000000..d352d0e12d8106a232bb5e6d7e1= 38697d2106937 --- /dev/null +++ b/Documentation/devicetree/bindings/reset/canaan,k230-rst.yaml @@ -0,0 +1,39 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/reset/canaan,k230-rst.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Canaan Kendryte K230 Reset Controller + +maintainers: + - Junhui Liu + +description: + The Canaan Kendryte K230 reset controller is part of the SoC's system + controller and controls the reset registers for CPUs and various periphe= rals. + +properties: + compatible: + const: canaan,k230-rst + + reg: + maxItems: 1 + + '#reset-cells': + const: 1 + +required: + - compatible + - reg + - '#reset-cells' + +additionalProperties: false + +examples: + - | + reset-controller@91101000 { + compatible =3D "canaan,k230-rst"; + reg =3D <0x91101000 0x1000>; + #reset-cells =3D <1>; + }; diff --git a/include/dt-bindings/reset/canaan,k230-rst.h b/include/dt-bindi= ngs/reset/canaan,k230-rst.h new file mode 100644 index 0000000000000000000000000000000000000000..53e3fd8177071aef8983c631706= d67ac86ab645b --- /dev/null +++ b/include/dt-bindings/reset/canaan,k230-rst.h @@ -0,0 +1,90 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2023-2024 Canaan Bright Sight Co., Ltd + * Copyright (C) 2024-2025 Junhui Liu + */ +#ifndef _DT_BINDINGS_CANAAN_K230_RST_H_ +#define _DT_BINDINGS_CANAAN_K230_RST_H_ + +#define RST_CPU0 0 +#define RST_CPU1 1 +#define RST_CPU0_FLUSH 2 +#define RST_CPU1_FLUSH 3 +#define RST_AI 4 +#define RST_VPU 5 +#define RST_HS 6 +#define RST_HS_AHB 7 +#define RST_SDIO0 8 +#define RST_SDIO1 9 +#define RST_SDIO_AXI 10 +#define RST_USB0 11 +#define RST_USB1 12 +#define RST_USB0_AHB 13 +#define RST_USB1_AHB 14 +#define RST_SPI0 15 +#define RST_SPI1 16 +#define RST_SPI2 17 +#define RST_SEC 18 +#define RST_PDMA 19 +#define RST_SDMA 20 +#define RST_DECOMPRESS 21 +#define RST_SRAM 22 +#define RST_SHRM_AXIM 23 +#define RST_SHRM_AXIS 24 +#define RST_NONAI2D 25 +#define RST_MCTL 26 +#define RST_ISP 27 +#define RST_ISP_DW 28 +#define RST_DPU 29 +#define RST_DISP 30 +#define RST_GPU 31 +#define RST_AUDIO 32 +#define RST_TIMER0 33 +#define RST_TIMER1 34 +#define RST_TIMER2 35 +#define RST_TIMER3 36 +#define RST_TIMER4 37 +#define RST_TIMER5 38 +#define RST_TIMER_APB 39 +#define RST_HDI 40 +#define RST_WDT0 41 +#define RST_WDT1 42 +#define RST_WDT0_APB 43 +#define RST_WDT1_APB 44 +#define RST_TS_APB 45 +#define RST_MAILBOX 46 +#define RST_STC 47 +#define RST_PMU 48 +#define RST_LS_APB 49 +#define RST_UART0 50 +#define RST_UART1 51 +#define RST_UART2 52 +#define RST_UART3 53 +#define RST_UART4 54 +#define RST_I2C0 55 +#define RST_I2C1 56 +#define RST_I2C2 57 +#define RST_I2C3 58 +#define RST_I2C4 59 +#define RST_JAMLINK0_APB 60 +#define RST_JAMLINK1_APB 61 +#define RST_JAMLINK2_APB 62 +#define RST_JAMLINK3_APB 63 +#define RST_CODEC_APB 64 +#define RST_GPIO_DB 65 +#define RST_GPIO_APB 66 +#define RST_ADC 67 +#define RST_ADC_APB 68 +#define RST_PWM_APB 69 +#define RST_SHRM_APB 70 +#define RST_CSI0 71 +#define RST_CSI1 72 +#define RST_CSI2 73 +#define RST_CSI_DPHY 74 +#define RST_ISP_AHB 75 +#define RST_M0 76 +#define RST_M1 77 +#define RST_M2 78 +#define RST_SPI2AXI 79 + +#endif --=20 2.49.0 From nobody Mon Dec 15 21:27:43 2025 Received: from sender3-op-o16.zoho.com (sender3-op-o16.zoho.com [136.143.184.16]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4266E1DF256; Sat, 19 Apr 2025 17:10:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=pass smtp.client-ip=136.143.184.16 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1745082658; cv=pass; b=FNFBtiyHrBy4MT8/nZcrjeK7xUyu5MIWYhKT5eA+7wj7/DH1e+hTDHIkuIpZuA9VO5dHbYb4K5yF7+jh4FiiA4Lv4z8TOmaRKJl45o2YfAhWySJ0/7zLzyrgGadJDMt57A1fqRK6JH/UAkrGVJlZnfun5UE1A5D95QuHelIHN84= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1745082658; c=relaxed/simple; bh=IXcNKCatrHhTiqbJ0SwW7TrfDdv/86SxWEW4C3QNSBY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=cd+/zltCr/vNmWSnOS1RDMo+AVK6hdP2Sq+B5+D0ZVtuKOnqap1yQ5P16bTmhApVCx3nRGIqVWIKnC/h0HcgCqwBGbouCJbdAEAZt4eTJrKzqtagtGYNK6YUnU6qfSpiW5v/O1Sr60tCMkhrz8Bz1xSfnAZNo7P03hQNCVZbcwo= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pigmoral.tech; spf=pass smtp.mailfrom=pigmoral.tech; dkim=pass (1024-bit key) header.d=pigmoral.tech header.i=junhui.liu@pigmoral.tech header.b=i0y64G6O; arc=pass smtp.client-ip=136.143.184.16 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pigmoral.tech Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pigmoral.tech Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=pigmoral.tech header.i=junhui.liu@pigmoral.tech header.b="i0y64G6O" ARC-Seal: i=1; a=rsa-sha256; t=1745082638; cv=none; d=zohomail.com; s=zohoarc; b=EBwDctke/BB3WJSW0NfUWl8LZ1KFv10ivICU2hr6w+/ACWnBY++wvxjWpEYZc88zKFx7vBNHTXtl/91d9I1mLQiIcitlxgSrAHhJGt244j0meOlvvBkaq5bISr2dijfgyzqYffLZAXg3xz8yX37E+98hwqmA0yvYZ3SBt1nxfYc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1745082638; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:MIME-Version:Message-ID:References:Subject:Subject:To:To:Message-Id:Reply-To; bh=z6lbpBwuT8dpWkOtT1bf+/GXQeO+N6nZNuynlhhf5xI=; b=TNrOOMcEfUyvMI+xMOCl2Z4S2kDn0rpgHzynyKSZFsKDuI/nUb6Ud5258Taq89qbt49QoxoBrB9t3+gypn/4axVdFbp2gmRO5rAIXdNGJDbVI6oA2IL5xUqnCXTp4AWBha9MCyPWGZbL3aRtQweWhuYujJxReamtTuxvMHvFSH4= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass header.i=pigmoral.tech; spf=pass smtp.mailfrom=junhui.liu@pigmoral.tech; dmarc=pass header.from= DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; t=1745082638; s=zmail; d=pigmoral.tech; i=junhui.liu@pigmoral.tech; h=From:From:Date:Date:Subject:Subject:MIME-Version:Content-Type:Content-Transfer-Encoding:Message-Id:Message-Id:References:In-Reply-To:To:To:Cc:Cc:Reply-To; bh=z6lbpBwuT8dpWkOtT1bf+/GXQeO+N6nZNuynlhhf5xI=; b=i0y64G6OsY6a68HixkWUnidNVX2N5lz0/SCcsy8n5FUFlTLcKGr2vtLGGcBbZeQ4 7AB/BCx8KlMzDgWAZCALki/1rAL24Yt02Db4iCG2BieRM3jWtmKUxpRrbhZxlm/WQKX q5+nT/K5Llct4f+AaGrJjpGYWGlo7kdxQr8Q7rUU= Received: by mx.zohomail.com with SMTPS id 1745082636652767.5095650284132; Sat, 19 Apr 2025 10:10:36 -0700 (PDT) From: Junhui Liu Date: Sun, 20 Apr 2025 01:09:45 +0800 Subject: [PATCH v2 2/2] reset: canaan: add reset driver for Kendryte K230 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250420-k230-reset-v2-2-f1b4a016e438@pigmoral.tech> References: <20250420-k230-reset-v2-0-f1b4a016e438@pigmoral.tech> In-Reply-To: <20250420-k230-reset-v2-0-f1b4a016e438@pigmoral.tech> To: Philipp Zabel , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Junhui Liu Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-riscv@lists.infradead.org X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1745082602; l=15740; i=junhui.liu@pigmoral.tech; s=20250223; h=from:subject:message-id; bh=IXcNKCatrHhTiqbJ0SwW7TrfDdv/86SxWEW4C3QNSBY=; b=Idb+EnWqgKYbdZ5Aqpq7HxIhuq1rfF5aICVukcL31uQ1Xab1QbPcby7ElqVBHdWrUzjEEJ4c4 kPFwJqUj805DOwm+Af35i51KtgwRO7pdHFWqc0N22Id2yAhk2BcDa4o X-Developer-Key: i=junhui.liu@pigmoral.tech; a=ed25519; pk=ZRZkOjG47iI+To+oAo2R4KIpMwtz8r0TffJ5/nO2tcg= X-ZohoMailClient: External Add support for the resets on Canaan Kendryte K230 SoC. The driver support CPU0, CPU1, L2 cache flush, hardware auto clear and software clear resets. Signed-off-by: Junhui Liu --- The reset management module in the K230 SoC also provides reset time control registers. For RST_TYPE_CPU0, RST_TYPE_CPU1 and RST_TYPE_SW_DONE, the time period when reset is applyed/removed but the clock is stopped can be set up to 15*0.25 =3D 3.75 us. For some RST_TYPE_HW_DONE cases, the time period can be set up to 255*0.25 =3D 63.75 us. For RST_TYPE_FLUSH, the reset bit will automatically cleared by hardware when flush done. Although the current reset driver does not support configuration of reset time registers, delay has been added to the assert, deassert and reset functions to accommodate the longest reset time. Besides, although some reset types have done bits, the reference manual does not explicitly indicate whether the hardware removes reset or the clock stop time period has passed when done bits toggle. Therefore, I think it is a safer way to keep delay for reset types with done bits. link: https://kendryte-download.canaan-creative.com/developer/k230/HDK/K230= %E7%A1%AC%E4%BB%B6%E6%96%87%E6%A1%A3/K230_Technical_Reference_Manual_V0.3.1= _20241118.pdf --- drivers/reset/Kconfig | 9 ++ drivers/reset/Makefile | 1 + drivers/reset/reset-k230.c | 355 +++++++++++++++++++++++++++++++++++++++++= ++++ 3 files changed, 365 insertions(+) diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index 99f6f9784e6865faddf8621ccfca095778c4dc47..248138ffba3bfbf859c74ba1aed= 7ba2f72819f7a 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -140,6 +140,15 @@ config RESET_K210 Say Y if you want to control reset signals provided by this controller. =20 +config RESET_K230 + tristate "Reset controller driver for Canaan Kendryte K230 SoC" + depends on ARCH_CANAAN || COMPILE_TEST + depends on OF + help + Support for the Canaan Kendryte K230 RISC-V SoC reset controller. + Say Y if you want to control reset signals provided by this + controller. + config RESET_LANTIQ bool "Lantiq XWAY Reset Driver" if COMPILE_TEST default SOC_TYPE_XWAY diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile index 31f9904d13f9c3a107fc1ee1ec9f9baba016d101..13fe94531bea1eb91268b1804e1= 321b167815a4b 100644 --- a/drivers/reset/Makefile +++ b/drivers/reset/Makefile @@ -20,6 +20,7 @@ obj-$(CONFIG_RESET_IMX7) +=3D reset-imx7.o obj-$(CONFIG_RESET_IMX8MP_AUDIOMIX) +=3D reset-imx8mp-audiomix.o obj-$(CONFIG_RESET_INTEL_GW) +=3D reset-intel-gw.o obj-$(CONFIG_RESET_K210) +=3D reset-k210.o +obj-$(CONFIG_RESET_K230) +=3D reset-k230.o obj-$(CONFIG_RESET_LANTIQ) +=3D reset-lantiq.o obj-$(CONFIG_RESET_LPC18XX) +=3D reset-lpc18xx.o obj-$(CONFIG_RESET_MCHP_SPARX5) +=3D reset-microchip-sparx5.o diff --git a/drivers/reset/reset-k230.c b/drivers/reset/reset-k230.c new file mode 100644 index 0000000000000000000000000000000000000000..492d2274893675b0ff1967426c8= fa9e75aed1791 --- /dev/null +++ b/drivers/reset/reset-k230.c @@ -0,0 +1,355 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2016-2017 Linaro Ltd. + * Copyright (C) 2022-2024 Canaan Bright Sight Co., Ltd + * Copyright (C) 2024-2025 Junhui Liu + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/** + * enum k230_rst_type - K230 reset types + * @RST_TYPE_CPU0: Reset type for CPU0 + * Automatically clears, has write enable and done bit, active high + * @RST_TYPE_CPU1: Reset type for CPU1 + * Manually clears, has write enable and done bit, active high + * @RST_TYPE_FLUSH: Reset type for CPU L2 cache flush + * Automatically clears, has write enable, no done bit, active high + * @RST_TYPE_HW_DONE: Reset type for hardware auto clear + * Automatically clears, no write enable, has done bit, active high + * @RST_TYPE_SW_DONE: Reset type for software manual clear + * Manually clears, no write enable and done bit, + * active high if ID is RST_SPI2AXI, otherwise active low + */ +enum k230_rst_type { + RST_TYPE_CPU0, + RST_TYPE_CPU1, + RST_TYPE_FLUSH, + RST_TYPE_HW_DONE, + RST_TYPE_SW_DONE, +}; + +struct k230_rst_map { + u32 offset; + enum k230_rst_type type; + u32 done; + u32 reset; +}; + +struct k230_rst { + struct reset_controller_dev rcdev; + struct device *dev; + void __iomem *base; + spinlock_t lock; +}; + +static const struct k230_rst_map k230_resets[] =3D { + [RST_CPU0] =3D { 0x4, RST_TYPE_CPU0, BIT(12), BIT(0) }, + [RST_CPU1] =3D { 0xc, RST_TYPE_CPU1, BIT(12), BIT(0) }, + [RST_CPU0_FLUSH] =3D { 0x4, RST_TYPE_FLUSH, 0, BIT(4) }, + [RST_CPU1_FLUSH] =3D { 0xc, RST_TYPE_FLUSH, 0, BIT(4) }, + [RST_AI] =3D { 0x14, RST_TYPE_HW_DONE, BIT(31), BIT(0) }, + [RST_VPU] =3D { 0x1c, RST_TYPE_HW_DONE, BIT(31), BIT(0) }, + [RST_HS] =3D { 0x2c, RST_TYPE_HW_DONE, BIT(4), BIT(0) }, + [RST_HS_AHB] =3D { 0x2c, RST_TYPE_HW_DONE, BIT(5), BIT(1) }, + [RST_SDIO0] =3D { 0x34, RST_TYPE_HW_DONE, BIT(28), BIT(0) }, + [RST_SDIO1] =3D { 0x34, RST_TYPE_HW_DONE, BIT(29), BIT(1) }, + [RST_SDIO_AXI] =3D { 0x34, RST_TYPE_HW_DONE, BIT(30), BIT(2) }, + [RST_USB0] =3D { 0x3c, RST_TYPE_HW_DONE, BIT(28), BIT(0) }, + [RST_USB1] =3D { 0x3c, RST_TYPE_HW_DONE, BIT(29), BIT(1) }, + [RST_USB0_AHB] =3D { 0x3c, RST_TYPE_HW_DONE, BIT(30), BIT(0) }, + [RST_USB1_AHB] =3D { 0x3c, RST_TYPE_HW_DONE, BIT(31), BIT(1) }, + [RST_SPI0] =3D { 0x44, RST_TYPE_HW_DONE, BIT(28), BIT(0) }, + [RST_SPI1] =3D { 0x44, RST_TYPE_HW_DONE, BIT(29), BIT(1) }, + [RST_SPI2] =3D { 0x44, RST_TYPE_HW_DONE, BIT(30), BIT(2) }, + [RST_SEC] =3D { 0x4c, RST_TYPE_HW_DONE, BIT(31), BIT(0) }, + [RST_PDMA] =3D { 0x54, RST_TYPE_HW_DONE, BIT(28), BIT(0) }, + [RST_SDMA] =3D { 0x54, RST_TYPE_HW_DONE, BIT(29), BIT(1) }, + [RST_DECOMPRESS] =3D { 0x5c, RST_TYPE_HW_DONE, BIT(31), BIT(0) }, + [RST_SRAM] =3D { 0x64, RST_TYPE_HW_DONE, BIT(28), BIT(0) }, + [RST_SHRM_AXIM] =3D { 0x64, RST_TYPE_HW_DONE, BIT(30), BIT(2) }, + [RST_SHRM_AXIS] =3D { 0x64, RST_TYPE_HW_DONE, BIT(31), BIT(3) }, + [RST_NONAI2D] =3D { 0x6c, RST_TYPE_HW_DONE, BIT(31), BIT(0) }, + [RST_MCTL] =3D { 0x74, RST_TYPE_HW_DONE, BIT(31), BIT(0) }, + [RST_ISP] =3D { 0x80, RST_TYPE_HW_DONE, BIT(29), BIT(6) }, + [RST_ISP_DW] =3D { 0x80, RST_TYPE_HW_DONE, BIT(28), BIT(5) }, + [RST_DPU] =3D { 0x88, RST_TYPE_HW_DONE, BIT(31), BIT(0) }, + [RST_DISP] =3D { 0x90, RST_TYPE_HW_DONE, BIT(31), BIT(0) }, + [RST_GPU] =3D { 0x98, RST_TYPE_HW_DONE, BIT(31), BIT(0) }, + [RST_AUDIO] =3D { 0xa4, RST_TYPE_HW_DONE, BIT(31), BIT(0) }, + [RST_TIMER0] =3D { 0x20, RST_TYPE_SW_DONE, 0, BIT(0) }, + [RST_TIMER1] =3D { 0x20, RST_TYPE_SW_DONE, 0, BIT(1) }, + [RST_TIMER2] =3D { 0x20, RST_TYPE_SW_DONE, 0, BIT(2) }, + [RST_TIMER3] =3D { 0x20, RST_TYPE_SW_DONE, 0, BIT(3) }, + [RST_TIMER4] =3D { 0x20, RST_TYPE_SW_DONE, 0, BIT(4) }, + [RST_TIMER5] =3D { 0x20, RST_TYPE_SW_DONE, 0, BIT(5) }, + [RST_TIMER_APB] =3D { 0x20, RST_TYPE_SW_DONE, 0, BIT(6) }, + [RST_HDI] =3D { 0x20, RST_TYPE_SW_DONE, 0, BIT(7) }, + [RST_WDT0] =3D { 0x20, RST_TYPE_SW_DONE, 0, BIT(12) }, + [RST_WDT1] =3D { 0x20, RST_TYPE_SW_DONE, 0, BIT(13) }, + [RST_WDT0_APB] =3D { 0x20, RST_TYPE_SW_DONE, 0, BIT(14) }, + [RST_WDT1_APB] =3D { 0x20, RST_TYPE_SW_DONE, 0, BIT(15) }, + [RST_TS_APB] =3D { 0x20, RST_TYPE_SW_DONE, 0, BIT(16) }, + [RST_MAILBOX] =3D { 0x20, RST_TYPE_SW_DONE, 0, BIT(17) }, + [RST_STC] =3D { 0x20, RST_TYPE_SW_DONE, 0, BIT(18) }, + [RST_PMU] =3D { 0x20, RST_TYPE_SW_DONE, 0, BIT(19) }, + [RST_LS_APB] =3D { 0x24, RST_TYPE_SW_DONE, 0, BIT(0) }, + [RST_UART0] =3D { 0x24, RST_TYPE_SW_DONE, 0, BIT(1) }, + [RST_UART1] =3D { 0x24, RST_TYPE_SW_DONE, 0, BIT(2) }, + [RST_UART2] =3D { 0x24, RST_TYPE_SW_DONE, 0, BIT(3) }, + [RST_UART3] =3D { 0x24, RST_TYPE_SW_DONE, 0, BIT(4) }, + [RST_UART4] =3D { 0x24, RST_TYPE_SW_DONE, 0, BIT(5) }, + [RST_I2C0] =3D { 0x24, RST_TYPE_SW_DONE, 0, BIT(6) }, + [RST_I2C1] =3D { 0x24, RST_TYPE_SW_DONE, 0, BIT(7) }, + [RST_I2C2] =3D { 0x24, RST_TYPE_SW_DONE, 0, BIT(8) }, + [RST_I2C3] =3D { 0x24, RST_TYPE_SW_DONE, 0, BIT(9) }, + [RST_I2C4] =3D { 0x24, RST_TYPE_SW_DONE, 0, BIT(10) }, + [RST_JAMLINK0_APB] =3D { 0x24, RST_TYPE_SW_DONE, 0, BIT(11) }, + [RST_JAMLINK1_APB] =3D { 0x24, RST_TYPE_SW_DONE, 0, BIT(12) }, + [RST_JAMLINK2_APB] =3D { 0x24, RST_TYPE_SW_DONE, 0, BIT(13) }, + [RST_JAMLINK3_APB] =3D { 0x24, RST_TYPE_SW_DONE, 0, BIT(14) }, + [RST_CODEC_APB] =3D { 0x24, RST_TYPE_SW_DONE, 0, BIT(17) }, + [RST_GPIO_DB] =3D { 0x24, RST_TYPE_SW_DONE, 0, BIT(18) }, + [RST_GPIO_APB] =3D { 0x24, RST_TYPE_SW_DONE, 0, BIT(19) }, + [RST_ADC] =3D { 0x24, RST_TYPE_SW_DONE, 0, BIT(20) }, + [RST_ADC_APB] =3D { 0x24, RST_TYPE_SW_DONE, 0, BIT(21) }, + [RST_PWM_APB] =3D { 0x24, RST_TYPE_SW_DONE, 0, BIT(22) }, + [RST_SHRM_APB] =3D { 0x64, RST_TYPE_SW_DONE, 0, BIT(1) }, + [RST_CSI0] =3D { 0x80, RST_TYPE_SW_DONE, 0, BIT(0) }, + [RST_CSI1] =3D { 0x80, RST_TYPE_SW_DONE, 0, BIT(1) }, + [RST_CSI2] =3D { 0x80, RST_TYPE_SW_DONE, 0, BIT(2) }, + [RST_CSI_DPHY] =3D { 0x80, RST_TYPE_SW_DONE, 0, BIT(3) }, + [RST_ISP_AHB] =3D { 0x80, RST_TYPE_SW_DONE, 0, BIT(4) }, + [RST_M0] =3D { 0x80, RST_TYPE_SW_DONE, 0, BIT(7) }, + [RST_M1] =3D { 0x80, RST_TYPE_SW_DONE, 0, BIT(8) }, + [RST_M2] =3D { 0x80, RST_TYPE_SW_DONE, 0, BIT(9) }, + [RST_SPI2AXI] =3D { 0xa8, RST_TYPE_SW_DONE, 0, BIT(0) } +}; + +static inline struct k230_rst *to_k230_rst(struct reset_controller_dev *rc= dev) +{ + return container_of(rcdev, struct k230_rst, rcdev); +} + +static void k230_rst_clear_done(struct k230_rst *rstc, unsigned long id, + bool write_en) +{ + const struct k230_rst_map *rmap =3D &k230_resets[id]; + u32 reg; + + guard(spinlock_irqsave)(&rstc->lock); + + reg =3D readl(rstc->base + rmap->offset); + reg |=3D rmap->done; /* write 1 to clear */ + if (write_en) + reg |=3D rmap->done << 16; + writel(reg, rstc->base + rmap->offset); +} + +static int k230_rst_wait_and_clear_done(struct k230_rst *rstc, unsigned lo= ng id, + bool write_en) +{ + const struct k230_rst_map *rmap =3D &k230_resets[id]; + u32 reg; + int ret; + + ret =3D readl_poll_timeout(rstc->base + rmap->offset, reg, + reg & rmap->done, 10, 1000); + if (ret) { + dev_err(rstc->dev, "Wait for reset done timeout\n"); + return ret; + } + + k230_rst_clear_done(rstc, id, write_en); + + return 0; +} + +static void k230_rst_update(struct k230_rst *rstc, unsigned long id, + bool assert, bool write_en, bool active_low) +{ + const struct k230_rst_map *rmap =3D &k230_resets[id]; + u32 reg; + + guard(spinlock_irqsave)(&rstc->lock); + + reg =3D readl(rstc->base + rmap->offset); + if (assert ^ active_low) + reg |=3D rmap->reset; + else + reg &=3D ~rmap->reset; + if (write_en) + reg |=3D rmap->reset << 16; + writel(reg, rstc->base + rmap->offset); +} + +static int k230_rst_assert(struct reset_controller_dev *rcdev, unsigned lo= ng id) +{ + struct k230_rst *rstc =3D to_k230_rst(rcdev); + + switch (k230_resets[id].type) { + case RST_TYPE_CPU1: + k230_rst_update(rstc, id, true, true, false); + break; + case RST_TYPE_SW_DONE: + k230_rst_update(rstc, id, true, false, + id =3D=3D RST_SPI2AXI ? false : true); + break; + case RST_TYPE_CPU0: + case RST_TYPE_FLUSH: + case RST_TYPE_HW_DONE: + return -EOPNOTSUPP; + } + + /* + * The time period when reset is applied but the clock is stopped for + * RST_TYPE_CPU1 and RST_TYPE_SW_DONE can be set up to 3.75us. Delay + * 10us to ensure proper reset timing. + */ + udelay(10); + + return 0; +} + +static int k230_rst_deassert(struct reset_controller_dev *rcdev, + unsigned long id) +{ + struct k230_rst *rstc =3D to_k230_rst(rcdev); + int ret =3D 0; + + switch (k230_resets[id].type) { + case RST_TYPE_CPU1: + k230_rst_update(rstc, id, false, true, false); + ret =3D k230_rst_wait_and_clear_done(rstc, id, true); + break; + case RST_TYPE_SW_DONE: + k230_rst_update(rstc, id, false, false, + id =3D=3D RST_SPI2AXI ? false : true); + break; + case RST_TYPE_CPU0: + case RST_TYPE_FLUSH: + case RST_TYPE_HW_DONE: + return -EOPNOTSUPP; + } + + /* + * The time period when reset is removed but the clock is stopped for + * RST_TYPE_CPU1 and RST_TYPE_SW_DONE can be set up to 3.75us. Delay + * 10us to ensure proper reset timing. + */ + udelay(10); + + return ret; +} + +static int k230_rst_reset(struct reset_controller_dev *rcdev, unsigned lon= g id) +{ + struct k230_rst *rstc =3D to_k230_rst(rcdev); + const struct k230_rst_map *rmap =3D &k230_resets[id]; + u32 reg; + int ret =3D 0; + + switch (rmap->type) { + case RST_TYPE_CPU0: + k230_rst_clear_done(rstc, id, true); + k230_rst_update(rstc, id, true, true, false); + ret =3D k230_rst_wait_and_clear_done(rstc, id, true); + + /* + * The time period when reset is applied and removed but the + * clock is stopped for RST_TYPE_CPU0 can be set up to 7.5us. + * Delay 10us to ensure proper reset timing. + */ + udelay(10); + + break; + case RST_TYPE_FLUSH: + k230_rst_update(rstc, id, true, true, false); + + /* Wait flush request bit auto cleared by hardware */ + ret =3D readl_poll_timeout(rstc->base + rmap->offset, reg, + !(reg & rmap->reset), 10, 1000); + if (ret) + dev_err(rstc->dev, "Wait for flush done timeout\n"); + + break; + case RST_TYPE_HW_DONE: + k230_rst_clear_done(rstc, id, false); + k230_rst_update(rstc, id, true, false, false); + ret =3D k230_rst_wait_and_clear_done(rstc, id, false); + + /* + * The time period when reset is applied and removed but the + * clock is stopped for RST_TYPE_HW_DONE can be set up to + * 127.5us. Delay 200us to ensure proper reset timing. + */ + udelay(200); + + break; + case RST_TYPE_CPU1: + case RST_TYPE_SW_DONE: + k230_rst_assert(rcdev, id); + ret =3D k230_rst_deassert(rcdev, id); + break; + } + + return ret; +} + +static const struct reset_control_ops k230_rst_ops =3D { + .reset =3D k230_rst_reset, + .assert =3D k230_rst_assert, + .deassert =3D k230_rst_deassert, +}; + +static int k230_rst_probe(struct platform_device *pdev) +{ + struct device *dev =3D &pdev->dev; + struct k230_rst *rstc; + + rstc =3D devm_kzalloc(dev, sizeof(*rstc), GFP_KERNEL); + if (!rstc) + return -ENOMEM; + + rstc->base =3D devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(rstc->base)) + return PTR_ERR(rstc->base); + + spin_lock_init(&rstc->lock); + + rstc->dev =3D dev; + rstc->rcdev.owner =3D THIS_MODULE; + rstc->rcdev.ops =3D &k230_rst_ops; + rstc->rcdev.nr_resets =3D ARRAY_SIZE(k230_resets); + rstc->rcdev.of_node =3D dev->of_node; + + return devm_reset_controller_register(dev, &rstc->rcdev); +} + +static const struct of_device_id k230_rst_match[] =3D { + { .compatible =3D "canaan,k230-rst", }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, k230_rst_match); + +static struct platform_driver k230_rst_driver =3D { + .probe =3D k230_rst_probe, + .driver =3D { + .name =3D "k230-rst", + .of_match_table =3D k230_rst_match, + } +}; +module_platform_driver(k230_rst_driver); + +MODULE_AUTHOR("Junhui Liu "); +MODULE_DESCRIPTION("Canaan K230 reset driver"); +MODULE_LICENSE("GPL"); --=20 2.49.0