848 lines
24 KiB
Diff
848 lines
24 KiB
Diff
From a71fb1ef5b28f73ef42f4becc2c3fcb944797348 Mon Sep 17 00:00:00 2001
|
|
From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
|
|
Date: Thu, 4 May 2023 23:06:41 +0300
|
|
Subject: [PATCH 1/9] dt-bindings: nvmem: Convert rockchip-otp.txt to dt-schema
|
|
|
|
Convert the Rockchip OTP memory bindings to dt-schema.
|
|
|
|
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
|
|
Reviewed-by: Heiko Stuebner <heiko@sntech.de>
|
|
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
|
|
---
|
|
.../bindings/nvmem/rockchip,otp.yaml | 82 +++++++++++++++++++
|
|
.../bindings/nvmem/rockchip-otp.txt | 25 ------
|
|
2 files changed, 82 insertions(+), 25 deletions(-)
|
|
create mode 100644 Documentation/devicetree/bindings/nvmem/rockchip,otp.yaml
|
|
delete mode 100644 Documentation/devicetree/bindings/nvmem/rockchip-otp.txt
|
|
|
|
diff --git a/Documentation/devicetree/bindings/nvmem/rockchip,otp.yaml b/Documentation/devicetree/bindings/nvmem/rockchip,otp.yaml
|
|
new file mode 100644
|
|
index 000000000000..4cd425ae2823
|
|
--- /dev/null
|
|
+++ b/Documentation/devicetree/bindings/nvmem/rockchip,otp.yaml
|
|
@@ -0,0 +1,82 @@
|
|
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
|
+%YAML 1.2
|
|
+---
|
|
+$id: http://devicetree.org/schemas/nvmem/rockchip,otp.yaml#
|
|
+$schema: http://devicetree.org/meta-schemas/core.yaml#
|
|
+
|
|
+title: Rockchip internal OTP (One Time Programmable) memory
|
|
+
|
|
+maintainers:
|
|
+ - Heiko Stuebner <heiko@sntech.de>
|
|
+
|
|
+allOf:
|
|
+ - $ref: nvmem.yaml#
|
|
+
|
|
+properties:
|
|
+ compatible:
|
|
+ enum:
|
|
+ - rockchip,px30-otp
|
|
+ - rockchip,rk3308-otp
|
|
+
|
|
+ reg:
|
|
+ maxItems: 1
|
|
+
|
|
+ clocks:
|
|
+ maxItems: 3
|
|
+
|
|
+ clock-names:
|
|
+ items:
|
|
+ - const: otp
|
|
+ - const: apb_pclk
|
|
+ - const: phy
|
|
+
|
|
+ resets:
|
|
+ maxItems: 1
|
|
+
|
|
+ reset-names:
|
|
+ items:
|
|
+ - const: phy
|
|
+
|
|
+required:
|
|
+ - compatible
|
|
+ - reg
|
|
+ - clocks
|
|
+ - clock-names
|
|
+ - resets
|
|
+ - reset-names
|
|
+
|
|
+unevaluatedProperties: false
|
|
+
|
|
+examples:
|
|
+ - |
|
|
+ #include <dt-bindings/clock/px30-cru.h>
|
|
+
|
|
+ soc {
|
|
+ #address-cells = <2>;
|
|
+ #size-cells = <2>;
|
|
+
|
|
+ otp: efuse@ff290000 {
|
|
+ compatible = "rockchip,px30-otp";
|
|
+ reg = <0x0 0xff290000 0x0 0x4000>;
|
|
+ clocks = <&cru SCLK_OTP_USR>, <&cru PCLK_OTP_NS>,
|
|
+ <&cru PCLK_OTP_PHY>;
|
|
+ clock-names = "otp", "apb_pclk", "phy";
|
|
+ resets = <&cru SRST_OTP_PHY>;
|
|
+ reset-names = "phy";
|
|
+ #address-cells = <1>;
|
|
+ #size-cells = <1>;
|
|
+
|
|
+ cpu_id: id@7 {
|
|
+ reg = <0x07 0x10>;
|
|
+ };
|
|
+
|
|
+ cpu_leakage: cpu-leakage@17 {
|
|
+ reg = <0x17 0x1>;
|
|
+ };
|
|
+
|
|
+ performance: performance@1e {
|
|
+ reg = <0x1e 0x1>;
|
|
+ bits = <4 3>;
|
|
+ };
|
|
+ };
|
|
+ };
|
|
diff --git a/Documentation/devicetree/bindings/nvmem/rockchip-otp.txt b/Documentation/devicetree/bindings/nvmem/rockchip-otp.txt
|
|
deleted file mode 100644
|
|
index 40f649f7c2e5..000000000000
|
|
--- a/Documentation/devicetree/bindings/nvmem/rockchip-otp.txt
|
|
+++ /dev/null
|
|
@@ -1,25 +0,0 @@
|
|
-Rockchip internal OTP (One Time Programmable) memory device tree bindings
|
|
-
|
|
-Required properties:
|
|
-- compatible: Should be one of the following.
|
|
- - "rockchip,px30-otp" - for PX30 SoCs.
|
|
- - "rockchip,rk3308-otp" - for RK3308 SoCs.
|
|
-- reg: Should contain the registers location and size
|
|
-- clocks: Must contain an entry for each entry in clock-names.
|
|
-- clock-names: Should be "otp", "apb_pclk" and "phy".
|
|
-- resets: Must contain an entry for each entry in reset-names.
|
|
- See ../../reset/reset.txt for details.
|
|
-- reset-names: Should be "phy".
|
|
-
|
|
-See nvmem.txt for more information.
|
|
-
|
|
-Example:
|
|
- otp: otp@ff290000 {
|
|
- compatible = "rockchip,px30-otp";
|
|
- reg = <0x0 0xff290000 0x0 0x4000>;
|
|
- #address-cells = <1>;
|
|
- #size-cells = <1>;
|
|
- clocks = <&cru SCLK_OTP_USR>, <&cru PCLK_OTP_NS>,
|
|
- <&cru PCLK_OTP_PHY>;
|
|
- clock-names = "otp", "apb_pclk", "phy";
|
|
- };
|
|
--
|
|
2.41.0
|
|
|
|
|
|
From 3282bc8fec63200ed6a3c485bb39b3c094117209 Mon Sep 17 00:00:00 2001
|
|
From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
|
|
Date: Thu, 4 May 2023 23:06:42 +0300
|
|
Subject: [PATCH 2/9] dt-bindings: nvmem: rockchip,otp: Add compatible for
|
|
RK3588
|
|
|
|
Document the OTP memory found on Rockchip RK3588 SoC.
|
|
|
|
Since RK3588 uses different clocks & resets configurations than PX30 /
|
|
RK3308, provide the required changes in the binding to be able to handle
|
|
both variants.
|
|
|
|
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
|
|
Reviewed-by: Heiko Stuebner <heiko@sntech.de>
|
|
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
|
|
---
|
|
.../bindings/nvmem/rockchip,otp.yaml | 54 ++++++++++++++++---
|
|
1 file changed, 47 insertions(+), 7 deletions(-)
|
|
|
|
diff --git a/Documentation/devicetree/bindings/nvmem/rockchip,otp.yaml b/Documentation/devicetree/bindings/nvmem/rockchip,otp.yaml
|
|
index 4cd425ae2823..9c6eff788928 100644
|
|
--- a/Documentation/devicetree/bindings/nvmem/rockchip,otp.yaml
|
|
+++ b/Documentation/devicetree/bindings/nvmem/rockchip,otp.yaml
|
|
@@ -9,33 +9,35 @@ title: Rockchip internal OTP (One Time Programmable) memory
|
|
maintainers:
|
|
- Heiko Stuebner <heiko@sntech.de>
|
|
|
|
-allOf:
|
|
- - $ref: nvmem.yaml#
|
|
-
|
|
properties:
|
|
compatible:
|
|
enum:
|
|
- rockchip,px30-otp
|
|
- rockchip,rk3308-otp
|
|
+ - rockchip,rk3588-otp
|
|
|
|
reg:
|
|
maxItems: 1
|
|
|
|
clocks:
|
|
- maxItems: 3
|
|
+ minItems: 3
|
|
+ maxItems: 4
|
|
|
|
clock-names:
|
|
+ minItems: 3
|
|
items:
|
|
- const: otp
|
|
- const: apb_pclk
|
|
- const: phy
|
|
+ - const: arb
|
|
|
|
resets:
|
|
- maxItems: 1
|
|
+ minItems: 1
|
|
+ maxItems: 3
|
|
|
|
reset-names:
|
|
- items:
|
|
- - const: phy
|
|
+ minItems: 1
|
|
+ maxItems: 3
|
|
|
|
required:
|
|
- compatible
|
|
@@ -45,6 +47,44 @@ required:
|
|
- resets
|
|
- reset-names
|
|
|
|
+allOf:
|
|
+ - $ref: nvmem.yaml#
|
|
+
|
|
+ - if:
|
|
+ properties:
|
|
+ compatible:
|
|
+ contains:
|
|
+ enum:
|
|
+ - rockchip,px30-otp
|
|
+ - rockchip,rk3308-otp
|
|
+ then:
|
|
+ properties:
|
|
+ clocks:
|
|
+ maxItems: 3
|
|
+ resets:
|
|
+ maxItems: 1
|
|
+ reset-names:
|
|
+ items:
|
|
+ - const: phy
|
|
+
|
|
+ - if:
|
|
+ properties:
|
|
+ compatible:
|
|
+ contains:
|
|
+ enum:
|
|
+ - rockchip,rk3588-otp
|
|
+ then:
|
|
+ properties:
|
|
+ clocks:
|
|
+ minItems: 4
|
|
+ resets:
|
|
+ minItems: 3
|
|
+ reset-names:
|
|
+ items:
|
|
+ - const: otp
|
|
+ - const: apb
|
|
+ - const: arb
|
|
+
|
|
unevaluatedProperties: false
|
|
|
|
examples:
|
|
--
|
|
2.41.0
|
|
|
|
|
|
From e4131e9dc168176bf647116e998f34e53cf7233f Mon Sep 17 00:00:00 2001
|
|
From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
|
|
Date: Thu, 4 May 2023 23:06:43 +0300
|
|
Subject: [PATCH 3/9] nvmem: rockchip-otp: Add clks and reg_read to
|
|
rockchip_data
|
|
|
|
In preparation to support new Rockchip OTP memory devices with different
|
|
clock configurations and register layout, extend rockchip_data struct
|
|
with the related members: clks, num_clks, reg_read.
|
|
|
|
Additionally, to avoid managing redundant driver data, drop num_clks
|
|
member from rockchip_otp struct and update all references to point to
|
|
the equivalent member in rockchip_data.
|
|
|
|
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
|
|
Tested-by: Vincent Legoll <vincent.legoll@gmail.com>
|
|
Reviewed-by: Heiko Stuebner <heiko@sntech.de>
|
|
---
|
|
drivers/nvmem/rockchip-otp.c | 79 ++++++++++++++++++++++--------------
|
|
1 file changed, 49 insertions(+), 30 deletions(-)
|
|
|
|
diff --git a/drivers/nvmem/rockchip-otp.c b/drivers/nvmem/rockchip-otp.c
|
|
index 9f53bcce2f87..b5a84b379da4 100644
|
|
--- a/drivers/nvmem/rockchip-otp.c
|
|
+++ b/drivers/nvmem/rockchip-otp.c
|
|
@@ -54,21 +54,19 @@
|
|
|
|
#define OTPC_TIMEOUT 10000
|
|
|
|
+struct rockchip_data {
|
|
+ int size;
|
|
+ const char * const *clks;
|
|
+ int num_clks;
|
|
+ nvmem_reg_read_t reg_read;
|
|
+};
|
|
+
|
|
struct rockchip_otp {
|
|
struct device *dev;
|
|
void __iomem *base;
|
|
- struct clk_bulk_data *clks;
|
|
- int num_clks;
|
|
+ struct clk_bulk_data *clks;
|
|
struct reset_control *rst;
|
|
-};
|
|
-
|
|
-/* list of required clocks */
|
|
-static const char * const rockchip_otp_clocks[] = {
|
|
- "otp", "apb_pclk", "phy",
|
|
-};
|
|
-
|
|
-struct rockchip_data {
|
|
- int size;
|
|
+ const struct rockchip_data *data;
|
|
};
|
|
|
|
static int rockchip_otp_reset(struct rockchip_otp *otp)
|
|
@@ -132,29 +130,23 @@ static int rockchip_otp_ecc_enable(struct rockchip_otp *otp, bool enable)
|
|
return ret;
|
|
}
|
|
|
|
-static int rockchip_otp_read(void *context, unsigned int offset,
|
|
- void *val, size_t bytes)
|
|
+static int px30_otp_read(void *context, unsigned int offset,
|
|
+ void *val, size_t bytes)
|
|
{
|
|
struct rockchip_otp *otp = context;
|
|
u8 *buf = val;
|
|
- int ret = 0;
|
|
-
|
|
- ret = clk_bulk_prepare_enable(otp->num_clks, otp->clks);
|
|
- if (ret < 0) {
|
|
- dev_err(otp->dev, "failed to prepare/enable clks\n");
|
|
- return ret;
|
|
- }
|
|
+ int ret;
|
|
|
|
ret = rockchip_otp_reset(otp);
|
|
if (ret) {
|
|
dev_err(otp->dev, "failed to reset otp phy\n");
|
|
- goto disable_clks;
|
|
+ return ret;
|
|
}
|
|
|
|
ret = rockchip_otp_ecc_enable(otp, false);
|
|
if (ret < 0) {
|
|
dev_err(otp->dev, "rockchip_otp_ecc_enable err\n");
|
|
- goto disable_clks;
|
|
+ return ret;
|
|
}
|
|
|
|
writel(OTPC_USE_USER | OTPC_USE_USER_MASK, otp->base + OTPC_USER_CTRL);
|
|
@@ -174,8 +166,28 @@ static int rockchip_otp_read(void *context, unsigned int offset,
|
|
|
|
read_end:
|
|
writel(0x0 | OTPC_USE_USER_MASK, otp->base + OTPC_USER_CTRL);
|
|
-disable_clks:
|
|
- clk_bulk_disable_unprepare(otp->num_clks, otp->clks);
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+static int rockchip_otp_read(void *context, unsigned int offset,
|
|
+ void *val, size_t bytes)
|
|
+{
|
|
+ struct rockchip_otp *otp = context;
|
|
+ int ret;
|
|
+
|
|
+ if (!otp->data || !otp->data->reg_read)
|
|
+ return -EINVAL;
|
|
+
|
|
+ ret = clk_bulk_prepare_enable(otp->data->num_clks, otp->clks);
|
|
+ if (ret < 0) {
|
|
+ dev_err(otp->dev, "failed to prepare/enable clks\n");
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
+ ret = otp->data->reg_read(context, offset, val, bytes);
|
|
+
|
|
+ clk_bulk_disable_unprepare(otp->data->num_clks, otp->clks);
|
|
|
|
return ret;
|
|
}
|
|
@@ -189,8 +201,15 @@ static struct nvmem_config otp_config = {
|
|
.reg_read = rockchip_otp_read,
|
|
};
|
|
|
|
+static const char * const px30_otp_clocks[] = {
|
|
+ "otp", "apb_pclk", "phy",
|
|
+};
|
|
+
|
|
static const struct rockchip_data px30_data = {
|
|
.size = 0x40,
|
|
+ .clks = px30_otp_clocks,
|
|
+ .num_clks = ARRAY_SIZE(px30_otp_clocks),
|
|
+ .reg_read = px30_otp_read,
|
|
};
|
|
|
|
static const struct of_device_id rockchip_otp_match[] = {
|
|
@@ -225,21 +244,21 @@ static int rockchip_otp_probe(struct platform_device *pdev)
|
|
if (!otp)
|
|
return -ENOMEM;
|
|
|
|
+ otp->data = data;
|
|
otp->dev = dev;
|
|
otp->base = devm_platform_ioremap_resource(pdev, 0);
|
|
if (IS_ERR(otp->base))
|
|
return PTR_ERR(otp->base);
|
|
|
|
- otp->num_clks = ARRAY_SIZE(rockchip_otp_clocks);
|
|
- otp->clks = devm_kcalloc(dev, otp->num_clks,
|
|
- sizeof(*otp->clks), GFP_KERNEL);
|
|
+ otp->clks = devm_kcalloc(dev, data->num_clks, sizeof(*otp->clks),
|
|
+ GFP_KERNEL);
|
|
if (!otp->clks)
|
|
return -ENOMEM;
|
|
|
|
- for (i = 0; i < otp->num_clks; ++i)
|
|
- otp->clks[i].id = rockchip_otp_clocks[i];
|
|
+ for (i = 0; i < data->num_clks; ++i)
|
|
+ otp->clks[i].id = data->clks[i];
|
|
|
|
- ret = devm_clk_bulk_get(dev, otp->num_clks, otp->clks);
|
|
+ ret = devm_clk_bulk_get(dev, data->num_clks, otp->clks);
|
|
if (ret)
|
|
return ret;
|
|
|
|
--
|
|
2.41.0
|
|
|
|
|
|
From a0cad270a253d54eaea3643f9d8426dbb436ec2c Mon Sep 17 00:00:00 2001
|
|
From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
|
|
Date: Thu, 4 May 2023 23:06:44 +0300
|
|
Subject: [PATCH 4/9] nvmem: rockchip-otp: Generalize
|
|
rockchip_otp_wait_status()
|
|
|
|
In preparation to support additional Rockchip OTP memory devices with
|
|
different register layout, generalize rockchip_otp_wait_status() to
|
|
accept a new parameter for specifying the offset of the status register.
|
|
|
|
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
|
|
Tested-by: Vincent Legoll <vincent.legoll@gmail.com>
|
|
Reviewed-by: Heiko Stuebner <heiko@sntech.de>
|
|
---
|
|
drivers/nvmem/rockchip-otp.c | 11 ++++++-----
|
|
1 file changed, 6 insertions(+), 5 deletions(-)
|
|
|
|
diff --git a/drivers/nvmem/rockchip-otp.c b/drivers/nvmem/rockchip-otp.c
|
|
index b5a84b379da4..b62e001f9116 100644
|
|
--- a/drivers/nvmem/rockchip-otp.c
|
|
+++ b/drivers/nvmem/rockchip-otp.c
|
|
@@ -90,18 +90,19 @@ static int rockchip_otp_reset(struct rockchip_otp *otp)
|
|
return 0;
|
|
}
|
|
|
|
-static int rockchip_otp_wait_status(struct rockchip_otp *otp, u32 flag)
|
|
+static int rockchip_otp_wait_status(struct rockchip_otp *otp,
|
|
+ unsigned int reg, u32 flag)
|
|
{
|
|
u32 status = 0;
|
|
int ret;
|
|
|
|
- ret = readl_poll_timeout_atomic(otp->base + OTPC_INT_STATUS, status,
|
|
+ ret = readl_poll_timeout_atomic(otp->base + reg, status,
|
|
(status & flag), 1, OTPC_TIMEOUT);
|
|
if (ret)
|
|
return ret;
|
|
|
|
/* clean int status */
|
|
- writel(flag, otp->base + OTPC_INT_STATUS);
|
|
+ writel(flag, otp->base + reg);
|
|
|
|
return 0;
|
|
}
|
|
@@ -123,7 +124,7 @@ static int rockchip_otp_ecc_enable(struct rockchip_otp *otp, bool enable)
|
|
|
|
writel(SBPI_ENABLE_MASK | SBPI_ENABLE, otp->base + OTPC_SBPI_CTRL);
|
|
|
|
- ret = rockchip_otp_wait_status(otp, OTPC_SBPI_DONE);
|
|
+ ret = rockchip_otp_wait_status(otp, OTPC_INT_STATUS, OTPC_SBPI_DONE);
|
|
if (ret < 0)
|
|
dev_err(otp->dev, "timeout during ecc_enable\n");
|
|
|
|
@@ -156,7 +157,7 @@ static int px30_otp_read(void *context, unsigned int offset,
|
|
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);
|
|
+ ret = rockchip_otp_wait_status(otp, OTPC_INT_STATUS, OTPC_USER_DONE);
|
|
if (ret < 0) {
|
|
dev_err(otp->dev, "timeout during read setup\n");
|
|
goto read_end;
|
|
--
|
|
2.41.0
|
|
|
|
|
|
From f993ae18db25b7033c4453225d4063775048d9e0 Mon Sep 17 00:00:00 2001
|
|
From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
|
|
Date: Thu, 4 May 2023 23:06:45 +0300
|
|
Subject: [PATCH 5/9] nvmem: rockchip-otp: Use
|
|
devm_reset_control_array_get_exclusive()
|
|
|
|
In preparation to support new Rockchip OTP memory devices having
|
|
specific reset configurations, switch devm_reset_control_get() to
|
|
devm_reset_control_array_get_exclusive().
|
|
|
|
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
|
|
Tested-by: Vincent Legoll <vincent.legoll@gmail.com>
|
|
Reviewed-by: Heiko Stuebner <heiko@sntech.de>
|
|
---
|
|
drivers/nvmem/rockchip-otp.c | 2 +-
|
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
|
|
diff --git a/drivers/nvmem/rockchip-otp.c b/drivers/nvmem/rockchip-otp.c
|
|
index b62e001f9116..439aea1f8874 100644
|
|
--- a/drivers/nvmem/rockchip-otp.c
|
|
+++ b/drivers/nvmem/rockchip-otp.c
|
|
@@ -263,7 +263,7 @@ static int rockchip_otp_probe(struct platform_device *pdev)
|
|
if (ret)
|
|
return ret;
|
|
|
|
- otp->rst = devm_reset_control_get(dev, "phy");
|
|
+ otp->rst = devm_reset_control_array_get_exclusive(dev);
|
|
if (IS_ERR(otp->rst))
|
|
return PTR_ERR(otp->rst);
|
|
|
|
--
|
|
2.41.0
|
|
|
|
|
|
From 1db5714fc59aa0b0b829155493389429cc497ddb Mon Sep 17 00:00:00 2001
|
|
From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
|
|
Date: Thu, 4 May 2023 23:06:46 +0300
|
|
Subject: [PATCH 6/9] nvmem: rockchip-otp: Improve probe error handling
|
|
|
|
Enhance error handling in the probe function by making use of
|
|
dev_err_probe(), which ensures the error code is always printed, in
|
|
addition to the specified error message.
|
|
|
|
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
|
|
Tested-by: Vincent Legoll <vincent.legoll@gmail.com>
|
|
Reviewed-by: Heiko Stuebner <heiko@sntech.de>
|
|
---
|
|
drivers/nvmem/rockchip-otp.c | 21 ++++++++++++---------
|
|
1 file changed, 12 insertions(+), 9 deletions(-)
|
|
|
|
diff --git a/drivers/nvmem/rockchip-otp.c b/drivers/nvmem/rockchip-otp.c
|
|
index 439aea1f8874..84bf956cc4e1 100644
|
|
--- a/drivers/nvmem/rockchip-otp.c
|
|
+++ b/drivers/nvmem/rockchip-otp.c
|
|
@@ -235,10 +235,8 @@ static int rockchip_otp_probe(struct platform_device *pdev)
|
|
int ret, i;
|
|
|
|
data = of_device_get_match_data(dev);
|
|
- if (!data) {
|
|
- dev_err(dev, "failed to get match data\n");
|
|
- return -EINVAL;
|
|
- }
|
|
+ if (!data)
|
|
+ return dev_err_probe(dev, -EINVAL, "failed to get match data\n");
|
|
|
|
otp = devm_kzalloc(&pdev->dev, sizeof(struct rockchip_otp),
|
|
GFP_KERNEL);
|
|
@@ -249,7 +247,8 @@ static int rockchip_otp_probe(struct platform_device *pdev)
|
|
otp->dev = dev;
|
|
otp->base = devm_platform_ioremap_resource(pdev, 0);
|
|
if (IS_ERR(otp->base))
|
|
- return PTR_ERR(otp->base);
|
|
+ return dev_err_probe(dev, PTR_ERR(otp->base),
|
|
+ "failed to ioremap resource\n");
|
|
|
|
otp->clks = devm_kcalloc(dev, data->num_clks, sizeof(*otp->clks),
|
|
GFP_KERNEL);
|
|
@@ -261,18 +260,22 @@ static int rockchip_otp_probe(struct platform_device *pdev)
|
|
|
|
ret = devm_clk_bulk_get(dev, data->num_clks, otp->clks);
|
|
if (ret)
|
|
- return ret;
|
|
+ return dev_err_probe(dev, ret, "failed to get clocks\n");
|
|
|
|
otp->rst = devm_reset_control_array_get_exclusive(dev);
|
|
if (IS_ERR(otp->rst))
|
|
- return PTR_ERR(otp->rst);
|
|
+ return dev_err_probe(dev, PTR_ERR(otp->rst),
|
|
+ "failed to get resets\n");
|
|
|
|
otp_config.size = data->size;
|
|
otp_config.priv = otp;
|
|
otp_config.dev = dev;
|
|
- nvmem = devm_nvmem_register(dev, &otp_config);
|
|
|
|
- return PTR_ERR_OR_ZERO(nvmem);
|
|
+ nvmem = devm_nvmem_register(dev, &otp_config);
|
|
+ if (IS_ERR(nvmem))
|
|
+ return dev_err_probe(dev, PTR_ERR(nvmem),
|
|
+ "failed to register nvmem device\n");
|
|
+ return 0;
|
|
}
|
|
|
|
static struct platform_driver rockchip_otp_driver = {
|
|
--
|
|
2.41.0
|
|
|
|
|
|
From a3266c7a0d896cd793a070b18fd456c9dfcf48f6 Mon Sep 17 00:00:00 2001
|
|
From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
|
|
Date: Thu, 4 May 2023 23:06:47 +0300
|
|
Subject: [PATCH 7/9] nvmem: rockchip-otp: Add support for RK3588
|
|
|
|
Add support for the OTP memory device found on the Rockchip RK3588 SoC.
|
|
|
|
While here, remove the unnecessary 'void *' casts in the OF device ID
|
|
table.
|
|
|
|
Co-developed-by: Finley Xiao <finley.xiao@rock-chips.com>
|
|
Signed-off-by: Finley Xiao <finley.xiao@rock-chips.com>
|
|
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
|
|
Tested-by: Vincent Legoll <vincent.legoll@gmail.com>
|
|
Reviewed-by: Heiko Stuebner <heiko@sntech.de>
|
|
---
|
|
drivers/nvmem/rockchip-otp.c | 78 +++++++++++++++++++++++++++++++++++-
|
|
1 file changed, 76 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/drivers/nvmem/rockchip-otp.c b/drivers/nvmem/rockchip-otp.c
|
|
index 84bf956cc4e1..cb9aa5428350 100644
|
|
--- a/drivers/nvmem/rockchip-otp.c
|
|
+++ b/drivers/nvmem/rockchip-otp.c
|
|
@@ -54,6 +54,19 @@
|
|
|
|
#define OTPC_TIMEOUT 10000
|
|
|
|
+/* RK3588 Register */
|
|
+#define RK3588_OTPC_AUTO_CTRL 0x04
|
|
+#define RK3588_OTPC_AUTO_EN 0x08
|
|
+#define RK3588_OTPC_INT_ST 0x84
|
|
+#define RK3588_OTPC_DOUT0 0x20
|
|
+#define RK3588_NO_SECURE_OFFSET 0x300
|
|
+#define RK3588_NBYTES 4
|
|
+#define RK3588_BURST_NUM 1
|
|
+#define RK3588_BURST_SHIFT 8
|
|
+#define RK3588_ADDR_SHIFT 16
|
|
+#define RK3588_AUTO_EN BIT(0)
|
|
+#define RK3588_RD_DONE BIT(1)
|
|
+
|
|
struct rockchip_data {
|
|
int size;
|
|
const char * const *clks;
|
|
@@ -171,6 +184,52 @@ static int px30_otp_read(void *context, unsigned int offset,
|
|
return ret;
|
|
}
|
|
|
|
+static int rk3588_otp_read(void *context, unsigned int offset,
|
|
+ void *val, size_t bytes)
|
|
+{
|
|
+ struct rockchip_otp *otp = context;
|
|
+ unsigned int addr_start, addr_end, addr_len;
|
|
+ int ret, i = 0;
|
|
+ u32 data;
|
|
+ u8 *buf;
|
|
+
|
|
+ addr_start = round_down(offset, RK3588_NBYTES) / RK3588_NBYTES;
|
|
+ addr_end = round_up(offset + bytes, RK3588_NBYTES) / RK3588_NBYTES;
|
|
+ addr_len = addr_end - addr_start;
|
|
+ addr_start += RK3588_NO_SECURE_OFFSET;
|
|
+
|
|
+ buf = kzalloc(array_size(addr_len, RK3588_NBYTES), GFP_KERNEL);
|
|
+ if (!buf)
|
|
+ return -ENOMEM;
|
|
+
|
|
+ while (addr_len--) {
|
|
+ writel((addr_start << RK3588_ADDR_SHIFT) |
|
|
+ (RK3588_BURST_NUM << RK3588_BURST_SHIFT),
|
|
+ otp->base + RK3588_OTPC_AUTO_CTRL);
|
|
+ writel(RK3588_AUTO_EN, otp->base + RK3588_OTPC_AUTO_EN);
|
|
+
|
|
+ ret = rockchip_otp_wait_status(otp, RK3588_OTPC_INT_ST,
|
|
+ RK3588_RD_DONE);
|
|
+ if (ret < 0) {
|
|
+ dev_err(otp->dev, "timeout during read setup\n");
|
|
+ goto read_end;
|
|
+ }
|
|
+
|
|
+ data = readl(otp->base + RK3588_OTPC_DOUT0);
|
|
+ memcpy(&buf[i], &data, RK3588_NBYTES);
|
|
+
|
|
+ i += RK3588_NBYTES;
|
|
+ addr_start++;
|
|
+ }
|
|
+
|
|
+ memcpy(val, buf + offset % RK3588_NBYTES, bytes);
|
|
+
|
|
+read_end:
|
|
+ kfree(buf);
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
static int rockchip_otp_read(void *context, unsigned int offset,
|
|
void *val, size_t bytes)
|
|
{
|
|
@@ -213,14 +272,29 @@ static const struct rockchip_data px30_data = {
|
|
.reg_read = px30_otp_read,
|
|
};
|
|
|
|
+static const char * const rk3588_otp_clocks[] = {
|
|
+ "otp", "apb_pclk", "phy", "arb",
|
|
+};
|
|
+
|
|
+static const struct rockchip_data rk3588_data = {
|
|
+ .size = 0x400,
|
|
+ .clks = rk3588_otp_clocks,
|
|
+ .num_clks = ARRAY_SIZE(rk3588_otp_clocks),
|
|
+ .reg_read = rk3588_otp_read,
|
|
+};
|
|
+
|
|
static const struct of_device_id rockchip_otp_match[] = {
|
|
{
|
|
.compatible = "rockchip,px30-otp",
|
|
- .data = (void *)&px30_data,
|
|
+ .data = &px30_data,
|
|
},
|
|
{
|
|
.compatible = "rockchip,rk3308-otp",
|
|
- .data = (void *)&px30_data,
|
|
+ .data = &px30_data,
|
|
+ },
|
|
+ {
|
|
+ .compatible = "rockchip,rk3588-otp",
|
|
+ .data = &rk3588_data,
|
|
},
|
|
{ /* sentinel */ },
|
|
};
|
|
--
|
|
2.41.0
|
|
|
|
|
|
From 4e3178487898d3e21deb144dfa967b4f8c71c8f3 Mon Sep 17 00:00:00 2001
|
|
From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
|
|
Date: Thu, 4 May 2023 23:06:48 +0300
|
|
Subject: [PATCH 8/9] arm64: dts: rockchip: Add rk3588 OTP node
|
|
|
|
Add DT node for Rockchip RK3588/RK3588S OTP memory.
|
|
|
|
Co-developed-by: Finley Xiao <finley.xiao@rock-chips.com>
|
|
Signed-off-by: Finley Xiao <finley.xiao@rock-chips.com>
|
|
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
|
|
Tested-by: Vincent Legoll <vincent.legoll@gmail.com>
|
|
---
|
|
arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 54 +++++++++++++++++++++++
|
|
1 file changed, 54 insertions(+)
|
|
|
|
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
|
|
index 7b93abd8f65c..977ed617f59e 100644
|
|
--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
|
|
+++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
|
|
@@ -1841,6 +1841,60 @@ spi4: spi@fecb0000 {
|
|
status = "disabled";
|
|
};
|
|
|
|
+ otp: efuse@fecc0000 {
|
|
+ compatible = "rockchip,rk3588-otp";
|
|
+ reg = <0x0 0xfecc0000 0x0 0x400>;
|
|
+ clocks = <&cru CLK_OTPC_NS>, <&cru PCLK_OTPC_NS>,
|
|
+ <&cru CLK_OTP_PHY_G>, <&cru CLK_OTPC_ARB>;
|
|
+ clock-names = "otp", "apb_pclk", "phy", "arb";
|
|
+ resets = <&cru SRST_OTPC_NS>, <&cru SRST_P_OTPC_NS>,
|
|
+ <&cru SRST_OTPC_ARB>;
|
|
+ reset-names = "otp", "apb", "arb";
|
|
+ #address-cells = <1>;
|
|
+ #size-cells = <1>;
|
|
+
|
|
+ cpu_code: cpu-code@2 {
|
|
+ reg = <0x02 0x2>;
|
|
+ };
|
|
+
|
|
+ otp_id: id@7 {
|
|
+ reg = <0x07 0x10>;
|
|
+ };
|
|
+
|
|
+ otp_cpu_version: cpu-version@1c {
|
|
+ reg = <0x1c 0x1>;
|
|
+ bits = <3 3>;
|
|
+ };
|
|
+
|
|
+ cpub0_leakage: cpu-leakage@17 {
|
|
+ reg = <0x17 0x1>;
|
|
+ };
|
|
+
|
|
+ cpub1_leakage: cpu-leakage@18 {
|
|
+ reg = <0x18 0x1>;
|
|
+ };
|
|
+
|
|
+ cpul_leakage: cpu-leakage@19 {
|
|
+ reg = <0x19 0x1>;
|
|
+ };
|
|
+
|
|
+ log_leakage: log-leakage@1a {
|
|
+ reg = <0x1a 0x1>;
|
|
+ };
|
|
+
|
|
+ gpu_leakage: gpu-leakage@1b {
|
|
+ reg = <0x1b 0x1>;
|
|
+ };
|
|
+
|
|
+ npu_leakage: npu-leakage@28 {
|
|
+ reg = <0x28 0x1>;
|
|
+ };
|
|
+
|
|
+ codec_leakage: codec-leakage@29 {
|
|
+ reg = <0x29 0x1>;
|
|
+ };
|
|
+ };
|
|
+
|
|
dmac2: dma-controller@fed10000 {
|
|
compatible = "arm,pl330", "arm,primecell";
|
|
reg = <0x0 0xfed10000 0x0 0x4000>;
|
|
--
|
|
2.41.0
|
|
|
|
|
|
From 39e135bbe54da0a6ddf98d183c0b4f3f248b17b1 Mon Sep 17 00:00:00 2001
|
|
From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
|
|
Date: Sun, 4 Jun 2023 20:13:45 +0300
|
|
Subject: [PATCH 9/9] arm64: defconfig: Enable Rockchip OTP memory driver
|
|
|
|
The Rockchip one-time programmable memory driver provides access to
|
|
various SoC specific information, e.g. leakage currents of the
|
|
CPU/GPU/NPU components found on a RK3588 SoC.
|
|
|
|
Enable the driver as built-in to allow client device drivers (e.g.
|
|
cpufreq) to access the required data for proper settings adjustment.
|
|
|
|
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
|
|
---
|
|
arch/arm64/configs/defconfig | 1 +
|
|
1 file changed, 1 insertion(+)
|
|
|
|
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
|
|
index a24609e14d50..6ef220d383d3 100644
|
|
--- a/arch/arm64/configs/defconfig
|
|
+++ b/arch/arm64/configs/defconfig
|
|
@@ -1385,6 +1385,7 @@ CONFIG_NVMEM_MTK_EFUSE=y
|
|
CONFIG_NVMEM_QCOM_QFPROM=y
|
|
CONFIG_NVMEM_RMEM=m
|
|
CONFIG_NVMEM_ROCKCHIP_EFUSE=y
|
|
+CONFIG_NVMEM_ROCKCHIP_OTP=y
|
|
CONFIG_NVMEM_SNVS_LPGPR=y
|
|
CONFIG_NVMEM_SPMI_SDAM=m
|
|
CONFIG_NVMEM_SUNXI_SID=y
|
|
--
|
|
2.41.0
|
|
|