From nobody Tue Apr 7 03:53:41 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0BD8AC54EE9 for ; Fri, 2 Sep 2022 06:41:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235500AbiIBGl5 (ORCPT ); Fri, 2 Sep 2022 02:41:57 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41658 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235127AbiIBGly (ORCPT ); Fri, 2 Sep 2022 02:41:54 -0400 Received: from esa.microchip.iphmx.com (esa.microchip.iphmx.com [68.232.154.123]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6B0306D9FE; Thu, 1 Sep 2022 23:41:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1662100913; x=1693636913; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=cXQT/Je2kt0cVSQZEufYezV+FLuHgFiRg9o4FJ46qtM=; b=Pbr82TZXZCqsmgQ2hFAYIzkezKl9fucgvNlhL4K71INq7dVN4mnAOpZF 8ahgyaHttKx918AZCvXAvtgy8GpHRUMNQ8cOGQk9vzqnj/ptyX7j9NkO2 Va8/9K1hI6JHeZm9jnzfTidZryhENapvidYUiKC7yLzGCjn7glNKgHWcz myNpGHn172+LoNMQBXtCi1C1cMjYf4amZThYa376xoDuMj0jQhRiGPKrJ jgR7FzHwfp0GUPZgNwyb3riOXZ5p5t2qZp+bhvMu8GxOhVU7j/KASKix+ ZUTpHl0/GpMVnpJtWRbdlzkYcnAr+qs8WpjdCYzbMpYBwI4z9lMQHxkcd A==; X-IronPort-AV: E=Sophos;i="5.93,283,1654585200"; d="scan'208";a="175326229" Received: from unknown (HELO email.microchip.com) ([170.129.1.10]) by esa2.microchip.iphmx.com with ESMTP/TLS/AES256-SHA256; 01 Sep 2022 23:41:52 -0700 Received: from chn-vm-ex04.mchp-main.com (10.10.85.152) by chn-vm-ex03.mchp-main.com (10.10.85.151) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.12; Thu, 1 Sep 2022 23:41:52 -0700 Received: from soft-dev3-1.microsemi.net (10.10.115.15) by chn-vm-ex04.mchp-main.com (10.10.85.152) with Microsoft SMTP Server id 15.1.2507.12 via Frontend Transport; Thu, 1 Sep 2022 23:41:50 -0700 From: Horatiu Vultur To: , CC: , , , , "Horatiu Vultur" , Krzysztof Kozlowski Subject: [PATCH v5 1/2] dt-bindings: lan9662-otpc: document Lan9662 OTPC Date: Fri, 2 Sep 2022 08:45:39 +0200 Message-ID: <20220902064540.484967-2-horatiu.vultur@microchip.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20220902064540.484967-1-horatiu.vultur@microchip.com> References: <20220902064540.484967-1-horatiu.vultur@microchip.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Document Lan9662 OTP controller. Reviewed-by: Krzysztof Kozlowski Signed-off-by: Horatiu Vultur --- .../nvmem/microchip,lan9662-otpc.yaml | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 Documentation/devicetree/bindings/nvmem/microchip,lan96= 62-otpc.yaml diff --git a/Documentation/devicetree/bindings/nvmem/microchip,lan9662-otpc= .yaml b/Documentation/devicetree/bindings/nvmem/microchip,lan9662-otpc.yaml new file mode 100644 index 000000000000..f97c6beb4766 --- /dev/null +++ b/Documentation/devicetree/bindings/nvmem/microchip,lan9662-otpc.yaml @@ -0,0 +1,45 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/nvmem/microchip,lan9662-otpc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Microchip LAN9662 OTP Controller (OTPC) + +maintainers: + - Horatiu Vultur + +description: | + OTP controller drives a NVMEM memory where system specific data + (e.g. hardware configuration settings, chip identifiers) or + user specific data could be stored. + +allOf: + - $ref: nvmem.yaml# + +properties: + compatible: + oneOf: + - items: + - const: microchip,lan9668-otpc + - const: microchip,lan9662-otpc + - enum: + - microchip,lan9662-otpc + + reg: + maxItems: 1 + +required: + - compatible + - reg + +unevaluatedProperties: false + +examples: + - | + otpc: otp@e0021000 { + compatible =3D "microchip,lan9662-otpc"; + reg =3D <0xe0021000 0x300>; + }; + +... --=20 2.33.0 From nobody Tue Apr 7 03:53:41 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E32BAC6FA81 for ; Fri, 2 Sep 2022 06:42:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235507AbiIBGmC (ORCPT ); Fri, 2 Sep 2022 02:42:02 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41730 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235497AbiIBGl4 (ORCPT ); Fri, 2 Sep 2022 02:41:56 -0400 Received: from esa.microchip.iphmx.com (esa.microchip.iphmx.com [68.232.153.233]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 75B3A71BCE; Thu, 1 Sep 2022 23:41:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1662100916; x=1693636916; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=NX1eyNaQr4+ALgShy2RcwVdH16jqwIgGKyV7rd+hiNk=; b=j9dvIli9uvjDIeAo9rtRhnA3wPIiaNsMSeXS3Z76PIN+bDrLM/JNRXoD 9g9iIvEAGFhIz5ZOFharoNxbEeMYzsIQbpInoLQMvJYxkZ2b6FlXiNA2V 3wUv8r6DclL1W8Js81szO//By5vX4bDbTJjrBHRRh/0dYHanX6ZxsaLV/ bARa7EDzU0qeqKxyZp8bCTocVt+8cltKRs6yt04cSO9KC0BW22VG9MEbD /tO3oOZzCCxa2SDilGRYvKGo72risxbgx9U/JYr0CwWO9VxVQQUgBrTI6 agnKcesG/sSIrud7IdTPp9mzn+GeQoxXyCfoKuifRsZlsNFOGQrxA4alf g==; X-IronPort-AV: E=Sophos;i="5.93,283,1654585200"; d="scan'208";a="178752440" Received: from unknown (HELO email.microchip.com) ([170.129.1.10]) by esa5.microchip.iphmx.com with ESMTP/TLS/AES256-SHA256; 01 Sep 2022 23:41:55 -0700 Received: from chn-vm-ex04.mchp-main.com (10.10.85.152) by chn-vm-ex04.mchp-main.com (10.10.85.152) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.12; Thu, 1 Sep 2022 23:41:53 -0700 Received: from soft-dev3-1.microsemi.net (10.10.115.15) by chn-vm-ex04.mchp-main.com (10.10.85.152) with Microsoft SMTP Server id 15.1.2507.12 via Frontend Transport; Thu, 1 Sep 2022 23:41:52 -0700 From: Horatiu Vultur To: , CC: , , , , "Horatiu Vultur" Subject: [PATCH v5 2/2] nvmem: lan9662-otp: add support Date: Fri, 2 Sep 2022 08:45:40 +0200 Message-ID: <20220902064540.484967-3-horatiu.vultur@microchip.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20220902064540.484967-1-horatiu.vultur@microchip.com> References: <20220902064540.484967-1-horatiu.vultur@microchip.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Add support for OTP controller available on LAN9662. The OTPC controls the access to a non-volatile memory. The size of the memory is 8KB. The OTPC can access the memory based on an offset. Implement both the read and the write functionality. Signed-off-by: Horatiu Vultur --- drivers/nvmem/Kconfig | 8 ++ drivers/nvmem/Makefile | 2 + drivers/nvmem/lan9662-otpc.c | 222 +++++++++++++++++++++++++++++++++++ 3 files changed, 232 insertions(+) create mode 100644 drivers/nvmem/lan9662-otpc.c diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig index 967d0084800e..9399445a2f4c 100644 --- a/drivers/nvmem/Kconfig +++ b/drivers/nvmem/Kconfig @@ -84,6 +84,14 @@ config NVMEM_LPC18XX_OTP To compile this driver as a module, choose M here: the module will be called nvmem_lpc18xx_otp. =20 +config NVMEM_LAN9662_OTPC + tristate "Microchip LAN9662 OTP controller support" + depends on SOC_LAN966 || COMPILE_TEST + depends on HAS_IOMEM + help + This driver enables the OTP controller available on Microchip LAN9662 + SoCs. It controls the access to the OTP memory connected to it. + config NVMEM_MXS_OCOTP tristate "Freescale MXS On-Chip OTP Memory Support" depends on ARCH_MXS || COMPILE_TEST diff --git a/drivers/nvmem/Makefile b/drivers/nvmem/Makefile index 00e136a0a123..e1baface2c53 100644 --- a/drivers/nvmem/Makefile +++ b/drivers/nvmem/Makefile @@ -21,6 +21,8 @@ obj-$(CONFIG_NVMEM_LPC18XX_EEPROM) +=3D nvmem_lpc18xx_eep= rom.o nvmem_lpc18xx_eeprom-y :=3D lpc18xx_eeprom.o obj-$(CONFIG_NVMEM_LPC18XX_OTP) +=3D nvmem_lpc18xx_otp.o nvmem_lpc18xx_otp-y :=3D lpc18xx_otp.o +obj-$(CONFIG_NVMEM_LAN9662_OTPC) +=3D nvmem-lan9662-otpc.o +nvmem-lan9662-otpc-y :=3D lan9662-otpc.o obj-$(CONFIG_NVMEM_MXS_OCOTP) +=3D nvmem-mxs-ocotp.o nvmem-mxs-ocotp-y :=3D mxs-ocotp.o obj-$(CONFIG_NVMEM_NINTENDO_OTP) +=3D nvmem-nintendo-otp.o diff --git a/drivers/nvmem/lan9662-otpc.c b/drivers/nvmem/lan9662-otpc.c new file mode 100644 index 000000000000..f6732fd216d8 --- /dev/null +++ b/drivers/nvmem/lan9662-otpc.c @@ -0,0 +1,222 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include +#include +#include +#include +#include + +#define OTP_OTP_PWR_DN(t) (t + 0x00) +#define OTP_OTP_PWR_DN_OTP_PWRDN_N BIT(0) +#define OTP_OTP_ADDR_HI(t) (t + 0x04) +#define OTP_OTP_ADDR_LO(t) (t + 0x08) +#define OTP_OTP_PRGM_DATA(t) (t + 0x10) +#define OTP_OTP_PRGM_MODE(t) (t + 0x14) +#define OTP_OTP_PRGM_MODE_OTP_PGM_MODE_BYTE BIT(0) +#define OTP_OTP_RD_DATA(t) (t + 0x18) +#define OTP_OTP_FUNC_CMD(t) (t + 0x20) +#define OTP_OTP_FUNC_CMD_OTP_PROGRAM BIT(1) +#define OTP_OTP_FUNC_CMD_OTP_READ BIT(0) +#define OTP_OTP_CMD_GO(t) (t + 0x28) +#define OTP_OTP_CMD_GO_OTP_GO BIT(0) +#define OTP_OTP_PASS_FAIL(t) (t + 0x2c) +#define OTP_OTP_PASS_FAIL_OTP_READ_PROHIBITED BIT(3) +#define OTP_OTP_PASS_FAIL_OTP_WRITE_PROHIBITED BIT(2) +#define OTP_OTP_PASS_FAIL_OTP_FAIL BIT(0) +#define OTP_OTP_STATUS(t) (t + 0x30) +#define OTP_OTP_STATUS_OTP_CPUMPEN BIT(1) +#define OTP_OTP_STATUS_OTP_BUSY BIT(0) + +#define OTP_MEM_SIZE 8192 +#define OTP_SLEEP_US 10 +#define OTP_TIMEOUT_US 500000 + +struct lan9662_otp { + struct device *dev; + void __iomem *base; +}; + +static bool lan9662_otp_wait_flag_clear(void __iomem *reg, u32 flag) +{ + u32 val; + + return readl_poll_timeout(reg, val, !(val & flag), + OTP_SLEEP_US, OTP_TIMEOUT_US); +} + +static int lan9662_otp_power(struct lan9662_otp *otp, bool up) +{ + void __iomem *pwrdn =3D OTP_OTP_PWR_DN(otp->base); + + if (up) { + writel(readl(pwrdn) & ~OTP_OTP_PWR_DN_OTP_PWRDN_N, pwrdn); + if (lan9662_otp_wait_flag_clear(OTP_OTP_STATUS(otp->base), + OTP_OTP_STATUS_OTP_CPUMPEN)) + return -ETIMEDOUT; + } else { + writel(readl(pwrdn) | OTP_OTP_PWR_DN_OTP_PWRDN_N, pwrdn); + } + + return 0; +} + +static int lan9662_otp_execute(struct lan9662_otp *otp) +{ + if (lan9662_otp_wait_flag_clear(OTP_OTP_CMD_GO(otp->base), + OTP_OTP_CMD_GO_OTP_GO)) + return -ETIMEDOUT; + + if (lan9662_otp_wait_flag_clear(OTP_OTP_STATUS(otp->base), + OTP_OTP_STATUS_OTP_BUSY)) + return -ETIMEDOUT; + + return 0; +} + +static void lan9662_otp_set_address(struct lan9662_otp *otp, u32 offset) +{ + writel(0xff & (offset >> 8), OTP_OTP_ADDR_HI(otp->base)); + writel(0xff & offset, OTP_OTP_ADDR_LO(otp->base)); +} + +static int lan9662_otp_read_byte(struct lan9662_otp *otp, u32 offset, u8 *= dst) +{ + u32 pass; + int rc; + + lan9662_otp_set_address(otp, offset); + writel(OTP_OTP_FUNC_CMD_OTP_READ, OTP_OTP_FUNC_CMD(otp->base)); + writel(OTP_OTP_CMD_GO_OTP_GO, OTP_OTP_CMD_GO(otp->base)); + rc =3D lan9662_otp_execute(otp); + if (!rc) { + pass =3D readl(OTP_OTP_PASS_FAIL(otp->base)); + if (pass & OTP_OTP_PASS_FAIL_OTP_READ_PROHIBITED) + return -EACCES; + *dst =3D (u8) readl(OTP_OTP_RD_DATA(otp->base)); + } + return rc; +} + +static int lan9662_otp_write_byte(struct lan9662_otp *otp, u32 offset, u8 = data) +{ + u32 pass; + int rc; + + lan9662_otp_set_address(otp, offset); + writel(OTP_OTP_PRGM_MODE_OTP_PGM_MODE_BYTE, OTP_OTP_PRGM_MODE(otp->base)); + writel(data, OTP_OTP_PRGM_DATA(otp->base)); + writel(OTP_OTP_FUNC_CMD_OTP_PROGRAM, OTP_OTP_FUNC_CMD(otp->base)); + writel(OTP_OTP_CMD_GO_OTP_GO, OTP_OTP_CMD_GO(otp->base)); + + rc =3D lan9662_otp_execute(otp); + if (!rc) { + pass =3D readl(OTP_OTP_PASS_FAIL(otp->base)); + if (pass & OTP_OTP_PASS_FAIL_OTP_WRITE_PROHIBITED) + return -EACCES; + if (pass & OTP_OTP_PASS_FAIL_OTP_FAIL) + return -EIO; + } + return rc; +} + +static int lan9662_otp_read(void *context, unsigned int offset, + void *_val, size_t bytes) +{ + struct lan9662_otp *otp =3D context; + u8 *val =3D _val; + uint8_t data; + int i, rc =3D 0; + + lan9662_otp_power(otp, true); + for (i =3D 0; i < bytes; i++) { + rc =3D lan9662_otp_read_byte(otp, offset + i, &data); + if (rc < 0) + break; + *val++ =3D data; + } + lan9662_otp_power(otp, false); + + return rc; +} + +static int lan9662_otp_write(void *context, unsigned int offset, + void *_val, size_t bytes) +{ + struct lan9662_otp *otp =3D context; + u8 *val =3D _val; + u8 data, newdata; + int i, rc =3D 0; + + lan9662_otp_power(otp, true); + for (i =3D 0; i < bytes; i++) { + /* Skip zero bytes */ + if (val[i]) { + rc =3D lan9662_otp_read_byte(otp, offset + i, &data); + if (rc < 0) + break; + + newdata =3D data | val[i]; + if (newdata =3D=3D data) + continue; + + rc =3D lan9662_otp_write_byte(otp, offset + i, + newdata); + if (rc < 0) + break; + } + } + lan9662_otp_power(otp, false); + + return rc; +} + +static struct nvmem_config otp_config =3D { + .name =3D "lan9662-otp", + .stride =3D 1, + .word_size =3D 1, + .reg_read =3D lan9662_otp_read, + .reg_write =3D lan9662_otp_write, + .size =3D OTP_MEM_SIZE, +}; + +static int lan9662_otp_probe(struct platform_device *pdev) +{ + struct device *dev =3D &pdev->dev; + struct nvmem_device *nvmem; + struct lan9662_otp *otp; + + otp =3D devm_kzalloc(&pdev->dev, sizeof(*otp), GFP_KERNEL); + if (!otp) + return -ENOMEM; + + otp->dev =3D dev; + otp->base =3D devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(otp->base)) + return PTR_ERR(otp->base); + + otp_config.priv =3D otp; + otp_config.dev =3D dev; + + nvmem =3D devm_nvmem_register(dev, &otp_config); + + return PTR_ERR_OR_ZERO(nvmem); +} + +static const struct of_device_id lan9662_otp_match[] =3D { + { .compatible =3D "microchip,lan9662-otp", }, + { }, +}; +MODULE_DEVICE_TABLE(of, lan9662_otp_match); + +static struct platform_driver lan9662_otp_driver =3D { + .probe =3D lan9662_otp_probe, + .driver =3D { + .name =3D "lan9662-otp", + .of_match_table =3D lan9662_otp_match, + }, +}; +module_platform_driver(lan9662_otp_driver); + +MODULE_AUTHOR("Horatiu Vultur "); +MODULE_DESCRIPTION("lan9662 OTP driver"); +MODULE_LICENSE("GPL"); --=20 2.33.0