From nobody Wed Nov 27 21:38:52 2024 Received: from gate2.alliedtelesis.co.nz (gate2.alliedtelesis.co.nz [202.36.163.20]) (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 D9F218BEE for ; Tue, 8 Oct 2024 00:23:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=202.36.163.20 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728347003; cv=none; b=V+/z/2kkd+GVCdS2ypjW7hyaWnoYhRRGE9MMRkr9DaiA/cHaPcE6+NU163SY4MLUdXOTCUeWCw9yR82ZbbAudUp/C8+yVeM1GSGuuCdFHBvsMJEnUn65TaCa3mLfLHPhqs6vd/p03AIqdHEYAD5N5EI/ZZsPOq4/xX11GQrJvJQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728347003; c=relaxed/simple; bh=70pgbID7KJjs3Pi1xZSu8sfymNQK5fE3VqHOaP8Akmw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=GppnW7hlpwvSJjppuXdZ7FiW6U5E7mhQxmAOysGP9hELOlFBCiVOXhzGpyD2ZHCNmaP7NpajYaV5xnyCT/766pLBXwEML13FgUcpvdsf/4A50OloeoylvTusy4Pg+v70Q+kq8cLmwI2Tcs5YlcDgpHEi7mjPwgQmI8wRfavHqRI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=alliedtelesis.co.nz; spf=pass smtp.mailfrom=alliedtelesis.co.nz; dkim=pass (2048-bit key) header.d=alliedtelesis.co.nz header.i=@alliedtelesis.co.nz header.b=RSF/+Gpe; arc=none smtp.client-ip=202.36.163.20 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=alliedtelesis.co.nz Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=alliedtelesis.co.nz Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=alliedtelesis.co.nz header.i=@alliedtelesis.co.nz header.b="RSF/+Gpe" Received: from svr-chch-seg1.atlnz.lc (mmarshal3.atlnz.lc [10.32.18.43]) (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) (Client did not present a certificate) by gate2.alliedtelesis.co.nz (Postfix) with ESMTPS id C223A2C0E2B; Tue, 8 Oct 2024 13:23:11 +1300 (NZDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=alliedtelesis.co.nz; s=mail181024; t=1728346991; bh=gjZS9Diq05TzQ1FpgZmaT4xdTf72iJglnanMipfthQ8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=RSF/+GpeSEn1oTVzCuwNUPyw5e/SrLiAZlE8Hi8DK1crU7Ow3j58i/3ganewKJy2i 4FjfiMOMpQPy463QGhcRtfNUXkQKpSrGjfZspco3ldKf6nQqHWhkTii9rJzS4Ojk96 bBv1ZxFQBkjVnsZ/pKT4GnbDgWSaB9SWluSztiN6hhMfUkxzNs8UtZCyA8GcqYdqPX LuI7BgzYBtqTUpBUHlgBpZR+cR9T76UnetJ4S6xnasxMWNq2a5k01qbb5cg3pakQFD UbV2zE/Qp5zHt3e+cogbRx5S3oDn+q8bky3mUHTDXcDSBGrzZp66+/iB3n7JU2EJuM taG70m7fgFihw== Received: from pat.atlnz.lc (Not Verified[10.32.16.33]) by svr-chch-seg1.atlnz.lc with Trustwave SEG (v8,2,6,11305) id ; Tue, 08 Oct 2024 13:23:11 +1300 Received: from chrisp-dl.ws.atlnz.lc (chrisp-dl.ws.atlnz.lc [10.33.22.30]) by pat.atlnz.lc (Postfix) with ESMTP id 7A9B313EE4F; Tue, 8 Oct 2024 13:23:11 +1300 (NZDT) Received: by chrisp-dl.ws.atlnz.lc (Postfix, from userid 1030) id 7692B280493; Tue, 8 Oct 2024 13:23:11 +1300 (NZDT) From: Chris Packham To: broonie@kernel.org, robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org, tsbogend@alpha.franken.de Cc: linux-spi@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mips@vger.kernel.org, Chris Packham Subject: [PATCH v2 1/3] dt-bindings: spi: Add realtek,rtl9300-snand Date: Tue, 8 Oct 2024 13:23:05 +1300 Message-ID: <20241008002308.1149983-2-chris.packham@alliedtelesis.co.nz> X-Mailer: git-send-email 2.46.2 In-Reply-To: <20241008002308.1149983-1-chris.packham@alliedtelesis.co.nz> References: <20241008002308.1149983-1-chris.packham@alliedtelesis.co.nz> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-SEG-SpamProfiler-Analysis: v=2.4 cv=Id0kWnqa c=1 sm=1 tr=0 ts=67047b6f a=KLBiSEs5mFS1a/PbTCJxuA==:117 a=DAUX931o1VcA:10 a=gEfo2CItAAAA:8 a=LDMcNrMx3qfY-b3KP34A:9 a=3ZKOabzyN94A:10 a=oGKThFDb_VfU6udzmvRc:22 a=sptkURWiP4Gy88Gu7hUp:22 X-SEG-SpamProfiler-Score: 0 x-atlnz-ls: pat Content-Type: text/plain; charset="utf-8" Add a dtschema for the SPI-NAND controller on the RTL9300 SoCs. The controller supports * Serial/Dual/Quad data with * PIO and DMA data read/write operation * Configurable flash access timing Signed-off-by: Chris Packham --- Notes: Changes in v2: - Add clocks - For now I've kept realtek,rtl9300-snand to identify the IP block used in the various rtl930x chips. If the consensus is to drop this I can send a v3 with an updated driver to add the chip specific complatible= s. .../bindings/spi/realtek,rtl9300-snand.yaml | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 Documentation/devicetree/bindings/spi/realtek,rtl9300-s= nand.yaml diff --git a/Documentation/devicetree/bindings/spi/realtek,rtl9300-snand.ya= ml b/Documentation/devicetree/bindings/spi/realtek,rtl9300-snand.yaml new file mode 100644 index 000000000000..2d01464e85e5 --- /dev/null +++ b/Documentation/devicetree/bindings/spi/realtek,rtl9300-snand.yaml @@ -0,0 +1,69 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/spi/realtek,rtl9300-snand.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: SPI-NAND Flash Controller for Realtek RTL9300 SoCs + +maintainers: + - Chris Packham + +description: + The Realtek RTL9300 SoCs have a built in SPI-NAND controller. It supports + typical SPI-NAND page cache operations in single, dual or quad IO mode. + +properties: + compatible: + items: + - enum: + - realtek,rtl9301-snand + - realtek,rtl9302b-snand + - realtek,rtl9302c-snand + - realtek,rtl9303-snand + - const: realtek,rtl9300-snand + + reg: + items: + - description: SPI NAND controller registers address and size + + interrupts: + items: + - description: SPI NAND controller interrupt + + clocks: + items: + - description: SPI NAND controller reference clock + + clock-names: + items: + - const: spi + +required: + - compatible + - reg + - interrupts + - clocks + +allOf: + - $ref: /schemas/spi/spi-controller.yaml# + +unevaluatedProperties: false + +examples: + - | + spi@1a400 { + compatible =3D "realtek,rtl9302c-snand", "realtek,rtl9300-snand"; + reg =3D <0x1a400 0x44>; + interrupt-parent =3D <&intc>; + interrupts =3D <19>; + clocks =3D <&lx_clk>; + clock-names =3D "spi"; + #address-cells =3D <1>; + #size-cells =3D <0>; + + flash@0 { + compatible =3D "spi-nand"; + reg =3D <0>; + }; + }; --=20 2.46.2 From nobody Wed Nov 27 21:38:52 2024 Received: from gate2.alliedtelesis.co.nz (gate2.alliedtelesis.co.nz [202.36.163.20]) (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 D3E2D6AA1 for ; Tue, 8 Oct 2024 00:23:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=202.36.163.20 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728347003; cv=none; b=YnfWAznEsPFM4CsfNZD/3di3891CHh0SWoxe/fd6LkDDa7uKK0LiMJy5aWyRj/McfrGkr3e4PATyZWmgPoL7kqhP/rTG7m7OKS1FmiS6euyTuejvb5fbVRPpFXsdveZLhbGcpbHO80kds1RN1ojfyBo7YXNndKFIxsMMpmAX6Eg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728347003; c=relaxed/simple; bh=6hBTDwBX6MCmQTdb42KrluuQyLLql5YNUCfvUVximnw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=SIeQk1PgyBvCjY9QrG4lOqwZCYEx6UaMteqtN+qgPZmFmmcVvwo4bNKq2GexLCPguPTBGYiqNybxDQaQqYoVc9xlPBmxR4moqvHkOwFLIKcI7YEPK9AHefwrGuIduD2Yyy54cju8Di8GcQhsVvoJ1NQTVuTg4kgDXzL5gwDxNSw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=alliedtelesis.co.nz; spf=pass smtp.mailfrom=alliedtelesis.co.nz; dkim=pass (2048-bit key) header.d=alliedtelesis.co.nz header.i=@alliedtelesis.co.nz header.b=S48yTgNv; arc=none smtp.client-ip=202.36.163.20 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=alliedtelesis.co.nz Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=alliedtelesis.co.nz Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=alliedtelesis.co.nz header.i=@alliedtelesis.co.nz header.b="S48yTgNv" Received: from svr-chch-seg1.atlnz.lc (mmarshal3.atlnz.lc [10.32.18.43]) (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) (Client did not present a certificate) by gate2.alliedtelesis.co.nz (Postfix) with ESMTPS id C91AC2C0E2E; Tue, 8 Oct 2024 13:23:11 +1300 (NZDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=alliedtelesis.co.nz; s=mail181024; t=1728346991; bh=SZ7c3erouMvte9rgED8yAdmiWojhyvlAdBzVJLCSjkU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=S48yTgNv69NnwtE+G03wUxGS1liBNnOtqmIk1cm9aW7oKsSNfVNlHahyb0qgBvPdf WqaJqdVwNQMj/v9gZPD3haRtjMbzJg3yyza3OHBl65Dldu38hCtBwjXFK8iZcqVDNA CdDmLQywtHEjqlRfzzM/PA28KPHdeU5YBxuCuyi2uYqOuFerUXoaLeb2fl9KUuqMTE fy0FJEj4ipTsmugNhB7LXTPMpfiKJSjpURLsjZ+aC3Qsaqgzj7wh4augg+Y5xiDPdc pUEn7WPg+uLl3C095NhxHGyD7kWcHopg5dpzEOcWNNIOfp3EU/GNqESssuu2L3RDMd mzIjpu2Wskkgw== Received: from pat.atlnz.lc (Not Verified[10.32.16.33]) by svr-chch-seg1.atlnz.lc with Trustwave SEG (v8,2,6,11305) id ; Tue, 08 Oct 2024 13:23:11 +1300 Received: from chrisp-dl.ws.atlnz.lc (chrisp-dl.ws.atlnz.lc [10.33.22.30]) by pat.atlnz.lc (Postfix) with ESMTP id 8087F13EE9B; Tue, 8 Oct 2024 13:23:11 +1300 (NZDT) Received: by chrisp-dl.ws.atlnz.lc (Postfix, from userid 1030) id 7C493280493; Tue, 8 Oct 2024 13:23:11 +1300 (NZDT) From: Chris Packham To: broonie@kernel.org, robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org, tsbogend@alpha.franken.de Cc: linux-spi@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mips@vger.kernel.org, Chris Packham Subject: [PATCH v2 2/3] mips: dts: realtek: Add SPI NAND controller Date: Tue, 8 Oct 2024 13:23:06 +1300 Message-ID: <20241008002308.1149983-3-chris.packham@alliedtelesis.co.nz> X-Mailer: git-send-email 2.46.2 In-Reply-To: <20241008002308.1149983-1-chris.packham@alliedtelesis.co.nz> References: <20241008002308.1149983-1-chris.packham@alliedtelesis.co.nz> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-SEG-SpamProfiler-Analysis: v=2.4 cv=Id0kWnqa c=1 sm=1 tr=0 ts=67047b6f a=KLBiSEs5mFS1a/PbTCJxuA==:117 a=DAUX931o1VcA:10 a=ykNALThPr6q2DDJ0DJYA:9 a=3ZKOabzyN94A:10 X-SEG-SpamProfiler-Score: 0 x-atlnz-ls: pat Content-Type: text/plain; charset="utf-8" Add the SPI-NAND controller on the RTL9300 family of devices. This supports serial/dual/quad data width and DMA for read/program operations. Signed-off-by: Chris Packham --- Notes: Changes in v2: - Add clocks arch/mips/boot/dts/realtek/rtl930x.dtsi | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/arch/mips/boot/dts/realtek/rtl930x.dtsi b/arch/mips/boot/dts/r= ealtek/rtl930x.dtsi index f271940f82be..23256376991f 100644 --- a/arch/mips/boot/dts/realtek/rtl930x.dtsi +++ b/arch/mips/boot/dts/realtek/rtl930x.dtsi @@ -32,6 +32,8 @@ lx_clk: clock-175mhz { }; =20 &soc { + ranges =3D <0x0 0x18000000 0x20000>; + intc: interrupt-controller@3000 { compatible =3D "realtek,rtl9300-intc", "realtek,rtl-intc"; reg =3D <0x3000 0x18>, <0x3018 0x18>; @@ -59,6 +61,18 @@ timer0: timer@3200 { interrupts =3D <7>, <8>, <9>, <10>, <11>; clocks =3D <&lx_clk>; }; + + snand: spi@1a400 { + compatible =3D "realtek,rtl9302c-snand", "realtek,rtl9300-snand"; + reg =3D <0x1a400 0x44>; + interrupt-parent =3D <&intc>; + interrupts =3D <19>; + clocks =3D <&lx_clk>; + clock-names =3D "spi"; + #address-cells =3D <1>; + #size-cells =3D <0>; + status =3D "disabled"; + }; }; =20 &uart0 { --=20 2.46.2 From nobody Wed Nov 27 21:38:52 2024 Received: from gate2.alliedtelesis.co.nz (gate2.alliedtelesis.co.nz [202.36.163.20]) (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 D3DD933F6 for ; Tue, 8 Oct 2024 00:23:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=202.36.163.20 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728347002; cv=none; b=qKJoM6dpY33Sgqcy9ggB62oJEnf03x7ubvkdXcTXgyOHhMOAUCh1gUi6+9Je8Rce0qt2IiPcSwFHEQRm8syuU8kOs4DoO9YO9cpKBVzL/hSGoWiKxpPOneQxqjGC3f+WuYHMj13bX5SVbp2zh2f7bCWZYlIPJO8du+3yfzqrPzk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728347002; c=relaxed/simple; bh=q5DGo28dae4xX9aC5Op0xocDPglM9LxVXvRcKA8y5kc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=GaCmkqDTlZ67Bo9h52R+V73FTxHqeO57mBo3sUtIIT+b62HZjxFjmHcDpN2aQtZRSL/anCC8wYC35R4kECIvQcvqSRRvZiwtriONuR2+rCLOWKcOFo+d9vNrUH72lxVujGv3FUfJIfT4npQH87Lh+X/EurQZIA6hClTaD5eQffM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=alliedtelesis.co.nz; spf=pass smtp.mailfrom=alliedtelesis.co.nz; dkim=pass (2048-bit key) header.d=alliedtelesis.co.nz header.i=@alliedtelesis.co.nz header.b=CqCPZaty; arc=none smtp.client-ip=202.36.163.20 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=alliedtelesis.co.nz Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=alliedtelesis.co.nz Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=alliedtelesis.co.nz header.i=@alliedtelesis.co.nz header.b="CqCPZaty" Received: from svr-chch-seg1.atlnz.lc (mmarshal3.atlnz.lc [10.32.18.43]) (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) (Client did not present a certificate) by gate2.alliedtelesis.co.nz (Postfix) with ESMTPS id D6EE92C0E31; Tue, 8 Oct 2024 13:23:11 +1300 (NZDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=alliedtelesis.co.nz; s=mail181024; t=1728346991; bh=zaMNTpDf4mmEXkwlqcPYTQxe8d/XOzSJj3y9ga1Qv/g=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=CqCPZatyKcLbgKLutR2fkwdFwYDxAtBknmGf8jY6gRlC4/y9aOq9fD3oNxVOdXy6Q OSHi55apMJzEeIu3foXVaCjc5N91q5o4WxaQalBjkT6IUb4PAFDkOYMwDiBsZOVtF+ 8Ot4mEdx6k91W+H/auTzdyl7iFX7Xq/OxpzzEEWtcLyfGWU3iytF8ED6EacO84bzZ2 /NJl3j7QuvSlTDvYch5hdFsgk18cay8sYEaBhxK/jAaWJNAY6gNPlreesx/tQwA4n0 Ez19FJxOLNg9GPGhi199i/yTNs0yt/7oV8cnKkN/mIyTyRjmUF6NxJyCmLrOZFnQa1 khXJ2hTM2FKkw== Received: from pat.atlnz.lc (Not Verified[10.32.16.33]) by svr-chch-seg1.atlnz.lc with Trustwave SEG (v8,2,6,11305) id ; Tue, 08 Oct 2024 13:23:11 +1300 Received: from chrisp-dl.ws.atlnz.lc (chrisp-dl.ws.atlnz.lc [10.33.22.30]) by pat.atlnz.lc (Postfix) with ESMTP id 8287013ED7B; Tue, 8 Oct 2024 13:23:11 +1300 (NZDT) Received: by chrisp-dl.ws.atlnz.lc (Postfix, from userid 1030) id 80AFF280B5B; Tue, 8 Oct 2024 13:23:11 +1300 (NZDT) From: Chris Packham To: broonie@kernel.org, robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org, tsbogend@alpha.franken.de Cc: linux-spi@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mips@vger.kernel.org, Chris Packham Subject: [PATCH v2 3/3] spi: spi-mem: Add Realtek SPI-NAND controller Date: Tue, 8 Oct 2024 13:23:07 +1300 Message-ID: <20241008002308.1149983-4-chris.packham@alliedtelesis.co.nz> X-Mailer: git-send-email 2.46.2 In-Reply-To: <20241008002308.1149983-1-chris.packham@alliedtelesis.co.nz> References: <20241008002308.1149983-1-chris.packham@alliedtelesis.co.nz> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-SEG-SpamProfiler-Analysis: v=2.4 cv=Id0kWnqa c=1 sm=1 tr=0 ts=67047b6f a=KLBiSEs5mFS1a/PbTCJxuA==:117 a=DAUX931o1VcA:10 a=n9Sqmae0AAAA:8 a=VwQbUJbxAAAA:8 a=gda5hHJ6RUSo0eTSPEEA:9 a=3ZKOabzyN94A:10 a=UmAUUZEt6-oIqEbegvw9:22 X-SEG-SpamProfiler-Score: 0 x-atlnz-ls: pat Content-Type: text/plain; charset="utf-8" Add a driver for the SPI-NAND controller on the RTL9300 family of devices. The controller supports * Serial/Dual/Quad data with * PIO and DMA data read/write operation * Configurable flash access timing There is a separate ECC controller on the RTL9300 which isn't currently supported (instead we rely on the on-die ECC supported by most SPI-NAND chips). Signed-off-by: Chris Packham --- Notes: Changes in v2: - Spell my own name correctly - Remove unecessary rtl_snand_adjust_op_size() MAINTAINERS | 6 + drivers/spi/Kconfig | 11 + drivers/spi/Makefile | 1 + drivers/spi/spi-realtek-rtl-snand.c | 402 ++++++++++++++++++++++++++++ 4 files changed, 420 insertions(+) create mode 100644 drivers/spi/spi-realtek-rtl-snand.c diff --git a/MAINTAINERS b/MAINTAINERS index f328373463b0..21ebff0ac7b5 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -19272,6 +19272,12 @@ S: Maintained F: Documentation/devicetree/bindings/net/dsa/realtek.yaml F: drivers/net/dsa/realtek/* =20 +REALTEK SPI-NAND +M: Chris Packham +S: Maintained +F: Documentation/devicetree/bindings/spi/realtek,rtl9300-snand.yaml +F: drivers/spi/spi-realtek-rtl-snand.c + REALTEK WIRELESS DRIVER (rtlwifi family) M: Ping-Ke Shih L: linux-wireless@vger.kernel.org diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index ec1550c698d5..33228a607c4b 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -843,6 +843,17 @@ config SPI_PXA2XX config SPI_PXA2XX_PCI def_tristate SPI_PXA2XX && PCI && COMMON_CLK =20 +config SPI_REALTEK_SNAND + tristate "Realtek SPI-NAND Flash Controller" + depends on MACH_REALTEK_RTL || COMPILE_TEST + select REGMAP + help + This enables support for the SPI-NAND Flash controller on + Realtek SoCs. + + This driver does not support generic SPI. The implementation + only supports the spi-mem interface. + config SPI_ROCKCHIP tristate "Rockchip SPI controller driver" depends on ARCH_ROCKCHIP || COMPILE_TEST diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index a9b1bc259b68..9a3338236645 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -119,6 +119,7 @@ obj-$(CONFIG_SPI_ROCKCHIP) +=3D spi-rockchip.o obj-$(CONFIG_SPI_ROCKCHIP_SFC) +=3D spi-rockchip-sfc.o obj-$(CONFIG_SPI_RB4XX) +=3D spi-rb4xx.o obj-$(CONFIG_MACH_REALTEK_RTL) +=3D spi-realtek-rtl.o +obj-$(CONFIG_SPI_REALTEK_SNAND) +=3D spi-realtek-rtl-snand.o obj-$(CONFIG_SPI_RPCIF) +=3D spi-rpc-if.o obj-$(CONFIG_SPI_RSPI) +=3D spi-rspi.o obj-$(CONFIG_SPI_RZV2M_CSI) +=3D spi-rzv2m-csi.o diff --git a/drivers/spi/spi-realtek-rtl-snand.c b/drivers/spi/spi-realtek-= rtl-snand.c new file mode 100644 index 000000000000..a8a6fecd46de --- /dev/null +++ b/drivers/spi/spi-realtek-rtl-snand.c @@ -0,0 +1,402 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include +#include +#include +#include +#include +#include +#include +#include + +#define SNAFCFR 0x00 +#define SNAFCFR_DMA_IE BIT(20) +#define SNAFCCR 0x04 +#define SNAFWCMR 0x08 +#define SNAFRCMR 0x0c +#define SNAFRDR 0x10 +#define SNAFWDR 0x14 +#define SNAFDTR 0x18 +#define SNAFDRSAR 0x1c +#define SNAFDIR 0x20 +#define SNAFDIR_DMA_IP BIT(0) +#define SNAFDLR 0x24 +#define SNAFSR 0x40 +#define SNAFSR_NFCOS BIT(3) +#define SNAFSR_NFDRS BIT(2) +#define SNAFSR_NFDWS BIT(1) + +#define CMR_LEN(len) ((len) - 1) +#define CMR_WID(width) (((width) >> 1) << 28) + +struct rtl_snand { + struct device *dev; + struct regmap *regmap; + struct completion comp; +}; + +static irqreturn_t rtl_snand_irq(int irq, void *data) +{ + struct rtl_snand *snand =3D data; + u32 val =3D 0; + + regmap_read(snand->regmap, SNAFSR, &val); + if (val & (SNAFSR_NFCOS | SNAFSR_NFDRS | SNAFSR_NFDWS)) + return IRQ_NONE; + + regmap_write(snand->regmap, SNAFDIR, SNAFDIR_DMA_IP); + complete(&snand->comp); + + return IRQ_HANDLED; +} + +static bool rtl_snand_supports_op(struct spi_mem *mem, + const struct spi_mem_op *op) +{ + if (!spi_mem_default_supports_op(mem, op)) + return false; + if (op->cmd.nbytes !=3D 1 || op->cmd.buswidth !=3D 1) + return false; + return true; +} + +static void rtl_snand_set_cs(struct rtl_snand *snand, int cs, bool active) +{ + u32 val; + + if (active) + val =3D ~(1 << (4 * cs)); + else + val =3D ~0; + + regmap_write(snand->regmap, SNAFCCR, val); +} + +static int rtl_snand_wait_ready(struct rtl_snand *snand) +{ + u32 val; + + return regmap_read_poll_timeout(snand->regmap, SNAFSR, val, !(val & SNAFS= R_NFCOS), + 0, 2 * USEC_PER_MSEC); +} + +static int rtl_snand_xfer_head(struct rtl_snand *snand, int cs, const stru= ct spi_mem_op *op) +{ + int ret; + u32 val, len =3D 0; + + rtl_snand_set_cs(snand, cs, true); + + val =3D op->cmd.opcode << 24; + len =3D 1; + if (op->addr.nbytes && op->addr.buswidth =3D=3D 1) { + val |=3D op->addr.val << ((3 - op->addr.nbytes) * 8); + len +=3D op->addr.nbytes; + } + + ret =3D rtl_snand_wait_ready(snand); + if (ret) + return ret; + + ret =3D regmap_write(snand->regmap, SNAFWCMR, CMR_LEN(len)); + if (ret) + return ret; + + ret =3D regmap_write(snand->regmap, SNAFWDR, val); + if (ret) + return ret; + + ret =3D rtl_snand_wait_ready(snand); + if (ret) + return ret; + + if (op->addr.buswidth > 1) { + val =3D op->addr.val << ((3 - op->addr.nbytes) * 8); + len =3D op->addr.nbytes; + + ret =3D regmap_write(snand->regmap, SNAFWCMR, + CMR_WID(op->addr.buswidth) | CMR_LEN(len)); + if (ret) + return ret; + + ret =3D regmap_write(snand->regmap, SNAFWDR, val); + if (ret) + return ret; + + ret =3D rtl_snand_wait_ready(snand); + if (ret) + return ret; + } + + if (op->dummy.nbytes) { + val =3D 0; + + ret =3D regmap_write(snand->regmap, SNAFWCMR, + CMR_WID(op->dummy.buswidth) | CMR_LEN(op->dummy.nbytes)); + if (ret) + return ret; + + ret =3D regmap_write(snand->regmap, SNAFWDR, val); + if (ret) + return ret; + + ret =3D rtl_snand_wait_ready(snand); + if (ret) + return ret; + } + + return 0; +} + +static void rtl_snand_xfer_tail(struct rtl_snand *snand, int cs) +{ + rtl_snand_set_cs(snand, cs, false); +} + +static int rtl_snand_xfer(struct rtl_snand *snand, int cs, const struct sp= i_mem_op *op) +{ + unsigned int pos, nbytes; + int ret; + u32 val, len =3D 0; + + ret =3D rtl_snand_xfer_head(snand, cs, op); + if (ret) + goto out_deselect; + + if (op->data.dir =3D=3D SPI_MEM_DATA_IN) { + pos =3D 0; + len =3D op->data.nbytes; + + while (pos < len) { + nbytes =3D len - pos; + if (nbytes > 4) + nbytes =3D 4; + + ret =3D rtl_snand_wait_ready(snand); + if (ret) + goto out_deselect; + + ret =3D regmap_write(snand->regmap, SNAFRCMR, + CMR_WID(op->data.buswidth) | CMR_LEN(nbytes)); + if (ret) + goto out_deselect; + + ret =3D rtl_snand_wait_ready(snand); + if (ret) + goto out_deselect; + + ret =3D regmap_read(snand->regmap, SNAFRDR, &val); + if (ret) + goto out_deselect; + + memcpy(op->data.buf.in + pos, &val, nbytes); + + pos +=3D nbytes; + } + } else if (op->data.dir =3D=3D SPI_MEM_DATA_OUT) { + pos =3D 0; + len =3D op->data.nbytes; + + while (pos < len) { + nbytes =3D len - pos; + if (nbytes > 4) + nbytes =3D 4; + + memcpy(&val, op->data.buf.out + pos, nbytes); + + pos +=3D nbytes; + + ret =3D regmap_write(snand->regmap, SNAFWCMR, CMR_LEN(nbytes)); + if (ret) + goto out_deselect; + + ret =3D regmap_write(snand->regmap, SNAFWDR, val); + if (ret) + goto out_deselect; + + ret =3D rtl_snand_wait_ready(snand); + if (ret) + goto out_deselect; + } + } + +out_deselect: + rtl_snand_xfer_tail(snand, cs); + + if (ret) + dev_err(snand->dev, "transfer failed %d\n", ret); + + return ret; +} + +static int rtl_snand_dma_xfer(struct rtl_snand *snand, int cs, const struc= t spi_mem_op *op) +{ + int ret; + dma_addr_t buf_dma; + enum dma_data_direction dir; + u32 trig; + + ret =3D rtl_snand_xfer_head(snand, cs, op); + if (ret) + goto out_deselect; + + if (op->data.dir =3D=3D SPI_MEM_DATA_IN) { + dir =3D DMA_FROM_DEVICE; + trig =3D 0; + } else if (op->data.dir =3D=3D SPI_MEM_DATA_OUT) { + dir =3D DMA_TO_DEVICE; + trig =3D 1; + } else { + ret =3D -EOPNOTSUPP; + goto out_deselect; + } + + buf_dma =3D dma_map_single(snand->dev, op->data.buf.in, op->data.nbytes, = dir); + ret =3D dma_mapping_error(snand->dev, buf_dma); + if (ret) + goto out_deselect; + + ret =3D regmap_write(snand->regmap, SNAFDIR, SNAFDIR_DMA_IP); + if (ret) + goto out_unmap; + + ret =3D regmap_update_bits(snand->regmap, SNAFCFR, SNAFCFR_DMA_IE, SNAFCF= R_DMA_IE); + if (ret) + goto out_unmap; + + reinit_completion(&snand->comp); + + ret =3D regmap_write(snand->regmap, SNAFDRSAR, buf_dma); + if (ret) + goto out_disable_int; + + ret =3D regmap_write(snand->regmap, SNAFDLR, + CMR_WID(op->data.buswidth) | (op->data.nbytes & 0xffff)); + if (ret) + goto out_disable_int; + + ret =3D regmap_write(snand->regmap, SNAFDTR, trig); + if (ret) + goto out_disable_int; + + if (!wait_for_completion_timeout(&snand->comp, usecs_to_jiffies(20000))) + ret =3D -ETIMEDOUT; + + if (ret) + goto out_disable_int; + +out_disable_int: + regmap_update_bits(snand->regmap, SNAFCFR, SNAFCFR_DMA_IE, 0); +out_unmap: + dma_unmap_single(snand->dev, buf_dma, op->data.nbytes, dir); +out_deselect: + rtl_snand_xfer_tail(snand, cs); + + if (ret) + dev_err(snand->dev, "transfer failed %d\n", ret); + + return ret; +} + +static bool rtl_snand_dma_op(const struct spi_mem_op *op) +{ + switch (op->data.dir) { + case SPI_MEM_DATA_IN: + case SPI_MEM_DATA_OUT: + return op->data.nbytes > 32; + default: + return false; + } +} + +static int rtl_snand_exec_op(struct spi_mem *mem, const struct spi_mem_op = *op) +{ + struct rtl_snand *snand =3D spi_controller_get_devdata(mem->spi->controll= er); + int cs =3D spi_get_chipselect(mem->spi, 0); + + dev_dbg(snand->dev, "cs %d op cmd %02x %d:%d, dummy %d:%d, addr %08llx@%d= :%d, data %d:%d\n", + cs, op->cmd.opcode, + op->cmd.buswidth, op->cmd.nbytes, op->dummy.buswidth, + op->dummy.nbytes, op->addr.val, op->addr.buswidth, + op->addr.nbytes, op->data.buswidth, op->data.nbytes); + + if (rtl_snand_dma_op(op)) + return rtl_snand_dma_xfer(snand, cs, op); + else + return rtl_snand_xfer(snand, cs, op); +} + +static const struct spi_controller_mem_ops rtl_snand_mem_ops =3D { + .supports_op =3D rtl_snand_supports_op, + .exec_op =3D rtl_snand_exec_op, +}; + +static const struct of_device_id rtl_snand_match[] =3D { + { .compatible =3D "realtek,rtl9300-snand" }, + {}, +}; +MODULE_DEVICE_TABLE(of, rtl_snand_match); + +static int rtl_snand_probe(struct platform_device *pdev) +{ + struct rtl_snand *snand; + struct device *dev =3D &pdev->dev; + struct spi_controller *ctrl; + void __iomem *base; + const struct regmap_config rc =3D { + .reg_bits =3D 32, + .val_bits =3D 32, + .reg_stride =3D 4, + .cache_type =3D REGCACHE_NONE, + }; + int irq, ret; + + ctrl =3D devm_spi_alloc_host(dev, sizeof(*snand)); + if (!ctrl) + return -ENOMEM; + + snand =3D spi_controller_get_devdata(ctrl); + snand->dev =3D dev; + + base =3D devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(base)) + return PTR_ERR(base); + + snand->regmap =3D devm_regmap_init_mmio(dev, base, &rc); + if (IS_ERR(snand->regmap)) + return PTR_ERR(snand->regmap); + + init_completion(&snand->comp); + + irq =3D platform_get_irq(pdev, 0); + if (irq < 0) + return irq; + + ret =3D dma_set_mask(snand->dev, DMA_BIT_MASK(32)); + if (ret) + return dev_err_probe(dev, ret, "failed to set DMA mask\n"); + + ret =3D devm_request_irq(dev, irq, rtl_snand_irq, 0, "rtl-snand", snand); + if (ret) + return dev_err_probe(dev, ret, "failed to request irq\n"); + + ctrl->num_chipselect =3D 2; + ctrl->mem_ops =3D &rtl_snand_mem_ops; + ctrl->bits_per_word_mask =3D SPI_BPW_MASK(8); + ctrl->mode_bits =3D SPI_RX_DUAL | SPI_RX_QUAD | SPI_TX_DUAL | SPI_TX_QUAD; + device_set_node(&ctrl->dev, dev_fwnode(dev)); + + return devm_spi_register_controller(dev, ctrl); +} + +static struct platform_driver rtl_snand_driver =3D { + .driver =3D { + .name =3D "realtek-rtl-snand", + .of_match_table =3D rtl_snand_match, + }, + .probe =3D rtl_snand_probe, +}; +module_platform_driver(rtl_snand_driver); + +MODULE_DESCRIPTION("Realtek SPI-NAND Flash Controller Driver"); +MODULE_LICENSE("GPL"); --=20 2.46.2