From: Heiko Stuebner <heiko@sntech.de>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH 07/12] misc: add driver for the Rockchip otp controller
Date: Fri, 25 Oct 2019 01:27:58 +0200 [thread overview]
Message-ID: <20191024232803.10338-8-heiko@sntech.de> (raw)
In-Reply-To: <20191024232803.10338-1-heiko@sntech.de>
From: Finley Xiao <finley.xiao@rock-chips.com>
Newer Rockchip socs like the px30 use a different ip block to handle
one-time-programmable memory, so add a misc driver for it as well.
Signed-off-by: Finley Xiao <finley.xiao@rock-chips.com>
Signed-off-by: Heiko Stuebner <heiko.stuebner@theobroma-systems.com>
---
drivers/misc/Kconfig | 9 ++
drivers/misc/Makefile | 1 +
drivers/misc/rockchip-otp.c | 176 ++++++++++++++++++++++++++++++++++++
3 files changed, 186 insertions(+)
create mode 100644 drivers/misc/rockchip-otp.c
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 8037b6ee2d..d68b24e6ec 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -59,6 +59,15 @@ config ROCKCHIP_EFUSE
extended (by porting the read function from the Linux kernel sources)
to support other recent Rockchip devices.
+config ROCKCHIP_OTP
+ bool "Rockchip OTP Support"
+ depends on MISC
+ help
+ Enable (read-only) access for the one-time-programmable memory block
+ found in Rockchip SoCs: accesses can either be made using byte
+ addressing and a length or through child-nodes that are generated
+ based on the e-fuse map retrieved from the DTS.
+
config VEXPRESS_CONFIG
bool "Enable support for Arm Versatile Express config bus"
depends on MISC
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 509c588582..b172567297 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -52,6 +52,7 @@ obj-$(CONFIG_PCA9551_LED) += pca9551_led.o
obj-$(CONFIG_$(SPL_)PWRSEQ) += pwrseq-uclass.o
obj-$(CONFIG_QFW) += qfw.o
obj-$(CONFIG_ROCKCHIP_EFUSE) += rockchip-efuse.o
+obj-$(CONFIG_ROCKCHIP_OTP) += rockchip-otp.o
obj-$(CONFIG_SANDBOX) += swap_case.o
obj-$(CONFIG_SANDBOX) += syscon_sandbox.o misc_sandbox.o
obj-$(CONFIG_SMSC_LPC47M) += smsc_lpc47m.o
diff --git a/drivers/misc/rockchip-otp.c b/drivers/misc/rockchip-otp.c
new file mode 100644
index 0000000000..bdd443b3db
--- /dev/null
+++ b/drivers/misc/rockchip-otp.c
@@ -0,0 +1,176 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <command.h>
+#include <dm.h>
+#include <linux/bitops.h>
+#include <linux/delay.h>
+#include <misc.h>
+
+/* OTP Register Offsets */
+#define OTPC_SBPI_CTRL 0x0020
+#define OTPC_SBPI_CMD_VALID_PRE 0x0024
+#define OTPC_SBPI_CS_VALID_PRE 0x0028
+#define OTPC_SBPI_STATUS 0x002C
+#define OTPC_USER_CTRL 0x0100
+#define OTPC_USER_ADDR 0x0104
+#define OTPC_USER_ENABLE 0x0108
+#define OTPC_USER_QP 0x0120
+#define OTPC_USER_Q 0x0124
+#define OTPC_INT_STATUS 0x0304
+#define OTPC_SBPI_CMD0_OFFSET 0x1000
+#define OTPC_SBPI_CMD1_OFFSET 0x1004
+
+/* OTP Register bits and masks */
+#define OTPC_USER_ADDR_MASK GENMASK(31, 16)
+#define OTPC_USE_USER BIT(0)
+#define OTPC_USE_USER_MASK GENMASK(16, 16)
+#define OTPC_USER_FSM_ENABLE BIT(0)
+#define OTPC_USER_FSM_ENABLE_MASK GENMASK(16, 16)
+#define OTPC_SBPI_DONE BIT(1)
+#define OTPC_USER_DONE BIT(2)
+
+#define SBPI_DAP_ADDR 0x02
+#define SBPI_DAP_ADDR_SHIFT 8
+#define SBPI_DAP_ADDR_MASK GENMASK(31, 24)
+#define SBPI_CMD_VALID_MASK GENMASK(31, 16)
+#define SBPI_DAP_CMD_WRF 0xC0
+#define SBPI_DAP_REG_ECC 0x3A
+#define SBPI_ECC_ENABLE 0x00
+#define SBPI_ECC_DISABLE 0x09
+#define SBPI_ENABLE BIT(0)
+#define SBPI_ENABLE_MASK GENMASK(16, 16)
+
+#define OTPC_TIMEOUT 10000
+
+struct rockchip_otp_platdata {
+ void __iomem *base;
+ unsigned long secure_conf_base;
+ unsigned long otp_mask_base;
+};
+
+static int rockchip_otp_wait_status(struct rockchip_otp_platdata *otp,
+ u32 flag)
+{
+ int delay = OTPC_TIMEOUT;
+
+ while (!(readl(otp->base + OTPC_INT_STATUS) & flag)) {
+ udelay(1);
+ delay--;
+ if (delay <= 0) {
+ printf("%s: wait init status timeout\n", __func__);
+ return -ETIMEDOUT;
+ }
+ }
+
+ /* clean int status */
+ writel(flag, otp->base + OTPC_INT_STATUS);
+
+ return 0;
+}
+
+static int rockchip_otp_ecc_enable(struct rockchip_otp_platdata *otp,
+ bool enable)
+{
+ int ret = 0;
+
+ writel(SBPI_DAP_ADDR_MASK | (SBPI_DAP_ADDR << SBPI_DAP_ADDR_SHIFT),
+ otp->base + OTPC_SBPI_CTRL);
+
+ writel(SBPI_CMD_VALID_MASK | 0x1, otp->base + OTPC_SBPI_CMD_VALID_PRE);
+ writel(SBPI_DAP_CMD_WRF | SBPI_DAP_REG_ECC,
+ otp->base + OTPC_SBPI_CMD0_OFFSET);
+
+ if (enable)
+ writel(SBPI_ECC_ENABLE, otp->base + OTPC_SBPI_CMD1_OFFSET);
+ else
+ writel(SBPI_ECC_DISABLE, otp->base + OTPC_SBPI_CMD1_OFFSET);
+
+ writel(SBPI_ENABLE_MASK | SBPI_ENABLE, otp->base + OTPC_SBPI_CTRL);
+
+ ret = rockchip_otp_wait_status(otp, OTPC_SBPI_DONE);
+ if (ret < 0)
+ printf("%s timeout during ecc_enable\n", __func__);
+
+ return ret;
+}
+
+static int rockchip_px30_otp_read(struct udevice *dev, int offset,
+ void *buf, int size)
+{
+ struct rockchip_otp_platdata *otp = dev_get_platdata(dev);
+ u8 *buffer = buf;
+ int ret = 0;
+
+ ret = rockchip_otp_ecc_enable(otp, false);
+ if (ret < 0) {
+ printf("%s rockchip_otp_ecc_enable err\n", __func__);
+ return ret;
+ }
+
+ writel(OTPC_USE_USER | OTPC_USE_USER_MASK, otp->base + OTPC_USER_CTRL);
+ udelay(5);
+ while (size--) {
+ writel(offset++ | OTPC_USER_ADDR_MASK,
+ otp->base + OTPC_USER_ADDR);
+ writel(OTPC_USER_FSM_ENABLE | OTPC_USER_FSM_ENABLE_MASK,
+ otp->base + OTPC_USER_ENABLE);
+
+ ret = rockchip_otp_wait_status(otp, OTPC_USER_DONE);
+ if (ret < 0) {
+ printf("%s timeout during read setup\n", __func__);
+ goto read_end;
+ }
+
+ *buffer++ = readb(otp->base + OTPC_USER_Q);
+ }
+
+read_end:
+ writel(0x0 | OTPC_USE_USER_MASK, otp->base + OTPC_USER_CTRL);
+
+ return ret;
+}
+
+static int rockchip_otp_read(struct udevice *dev, int offset,
+ void *buf, int size)
+{
+ return rockchip_px30_otp_read(dev, offset, buf, size);
+}
+
+static const struct misc_ops rockchip_otp_ops = {
+ .read = rockchip_otp_read,
+};
+
+static int rockchip_otp_ofdata_to_platdata(struct udevice *dev)
+{
+ struct rockchip_otp_platdata *otp = dev_get_platdata(dev);
+
+ otp->base = dev_read_addr_ptr(dev);
+
+ return 0;
+}
+
+static const struct udevice_id rockchip_otp_ids[] = {
+ {
+ .compatible = "rockchip,px30-otp",
+ .data = (ulong)&rockchip_px30_otp_read,
+ },
+ {
+ .compatible = "rockchip,rk3308-otp",
+ .data = (ulong)&rockchip_px30_otp_read,
+ },
+ {}
+};
+
+U_BOOT_DRIVER(rockchip_otp) = {
+ .name = "rockchip_otp",
+ .id = UCLASS_MISC,
+ .of_match = rockchip_otp_ids,
+ .ops = &rockchip_otp_ops,
+ .ofdata_to_platdata = rockchip_otp_ofdata_to_platdata,
+ .platdata_auto_alloc_size = sizeof(struct rockchip_otp_platdata),
+};
--
2.23.0
next prev parent reply other threads:[~2019-10-24 23:27 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-10-24 23:27 [U-Boot] [PATCH 00/12] rockchip: add support for px30 Heiko Stuebner
2019-10-24 23:27 ` [U-Boot] [PATCH 01/12] spl: separate SPL_FRAMEWORK config for spl and tpl Heiko Stuebner
2019-10-25 1:55 ` Kever Yang
2019-10-24 23:27 ` [U-Boot] [PATCH 02/12] rockchip: add core px30 headers Heiko Stuebner
2019-10-25 2:04 ` Kever Yang
2019-10-24 23:27 ` [U-Boot] [PATCH 03/12] pinctrl: rockchip: add px30 pinctrl driver Heiko Stuebner
2019-10-25 2:07 ` Kever Yang
2019-10-24 23:27 ` [U-Boot] [PATCH 04/12] rockchip: clk: add px30 clock driver Heiko Stuebner
2019-10-24 23:27 ` [U-Boot] [PATCH 05/12] net: gmac_rockchip: add support for px30 Heiko Stuebner
2019-10-25 2:09 ` Kever Yang
2019-10-24 23:27 ` [U-Boot] [PATCH 06/12] rockchip: mkimage: " Heiko Stuebner
2019-10-25 2:09 ` Kever Yang
2019-10-24 23:27 ` Heiko Stuebner [this message]
2019-10-25 2:10 ` [U-Boot] [PATCH 07/12] misc: add driver for the Rockchip otp controller Kever Yang
2019-10-24 23:27 ` [U-Boot] [PATCH 08/12] rockchip: misc: read cpuid either from efuse or otp Heiko Stuebner
2019-10-25 2:11 ` Kever Yang
2019-10-24 23:28 ` [U-Boot] [PATCH 09/12] rockchip: ram: add dm-based sdram driver Heiko Stuebner
2019-10-24 23:28 ` [U-Boot] [PATCH 10/12] rockchip: add px30 devicetrees Heiko Stuebner
2019-10-25 2:39 ` Kever Yang
2019-10-24 23:28 ` [U-Boot] [PATCH 11/12] rockchip: add px30 architecture core Heiko Stuebner
2019-10-25 2:49 ` Kever Yang
2019-10-25 7:47 ` Heiko Stübner
2019-11-10 14:13 ` Kever Yang
2019-11-10 14:46 ` Heiko Stuebner
2019-10-24 23:28 ` [U-Boot] [PATCH 12/12] rockchip: add px30-evb board Heiko Stuebner
2019-10-25 2:51 ` Kever Yang
2019-10-25 1:44 ` [U-Boot] [PATCH 00/12] rockchip: add support for px30 Kever Yang
2019-11-18 2:57 ` Kever Yang
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20191024232803.10338-8-heiko@sntech.de \
--to=heiko@sntech.de \
--cc=u-boot@lists.denx.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.