build/patch/atf/atf-rockchip64/rk3328-efuse-init.patch

615 lines
18 KiB
Diff

From 03343c2a0b2ed8b85a6dce567bbe515d69f75697 Mon Sep 17 00:00:00 2001
From: Paolo Sabatino <paolo.sabatino@gmail.com>
Date: Thu, 18 Nov 2021 17:33:59 +0000
Subject: [PATCH] rk3328: add efuse initialization in ATF
---
plat/rockchip/rk3328/drivers/efuse/efuse.c | 397 +++++++++++++++++++++
plat/rockchip/rk3328/drivers/efuse/efuse.h | 142 ++++++++
plat/rockchip/rk3328/drivers/soc/soc.c | 6 +
plat/rockchip/rk3328/platform.mk | 4 +-
4 files changed, 548 insertions(+), 1 deletion(-)
create mode 100644 plat/rockchip/rk3328/drivers/efuse/efuse.c
create mode 100644 plat/rockchip/rk3328/drivers/efuse/efuse.h
diff --git a/plat/rockchip/rk3328/drivers/efuse/efuse.c b/plat/rockchip/rk3328/drivers/efuse/efuse.c
new file mode 100644
index 0000000..05bbcf4
--- /dev/null
+++ b/plat/rockchip/rk3328/drivers/efuse/efuse.c
@@ -0,0 +1,397 @@
+/*
+ * Copyright (C) 2016, Fuzhou Rockchip Electronics Co., Ltd.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+#include <platform_def.h>
+#include <efuse.h>
+#include <string.h>
+
+#define EFUSE_AUTO_MODE 1 // RK3328 wants auto mode on
+
+#define read32(reg) mmio_read_32(reg)
+#define write32(v, reg) mmio_write_32(reg, v)
+#define efuse8_read(offset) mmio_read_32(EFUSE8_BASE + offset)
+#define efuse8_write(v, offset) mmio_write_32(EFUSE8_BASE + offset, v)
+#define efuse32_read(offset) mmio_read_32(EFUSE32_BASE + offset)
+#define efuse32_write(v, offset) mmio_write_32(EFUSE32_BASE + offset, v)
+
+/* global buf to store efuse data */
+static uint32_t efuse32_buf[32] = {0};
+
+enum clk_type {
+ CLK = 0,
+ PCLK,
+};
+
+int enable_efuse_clk()
+{
+
+ uint32_t reg = 0;
+
+ reg = read32(CRU_BASE + CRU_CLKGATE_CON2);
+ /* enable efuse work clk */
+ if (reg & EFUSE_SRC_CLK_EN)
+ write32(EFUSE_SRC_CLK_EN << CRU_WRITE_MASK,
+ CRU_BASE + CRU_CLKGATE_CON2);
+
+ reg = read32(CRU_BASE + CRU_CLKGATE_CON15);
+ /* enable efuse APB clk */
+ if (reg & EFUSE_1024_PCLK_EN)
+ write32(EFUSE_1024_PCLK_EN << CRU_WRITE_MASK,
+ CRU_BASE + CRU_CLKGATE_CON15);
+
+ return reg;
+
+}
+
+/*
+static uint32_t enable_efuse_clk(int clk)
+{
+ uint32_t reg = 0;
+
+ switch (clk) {
+ case CLK:
+ reg = read32(CRU_BASE + CRU_CLKGATE_CON2);
+ // enable efuse work clk
+ if (reg & EFUSE_SRC_CLK_EN)
+ write32(EFUSE_SRC_CLK_EN << CRU_WRITE_MASK,
+ CRU_BASE + CRU_CLKGATE_CON2);
+ break;
+ case PCLK:
+ reg = read32(CRU_BASE + CRU_CLKGATE_CON15);
+ // enable efuse APB clk
+ if (reg & EFUSE_1024_PCLK_EN)
+ write32(EFUSE_1024_PCLK_EN << CRU_WRITE_MASK,
+ CRU_BASE + CRU_CLKGATE_CON15);
+ break;
+ default:
+ break;
+ }
+
+ return reg;
+}
+*/
+
+static void restore_efuse_clk(int clk, uint32_t reg)
+{
+ switch (clk) {
+ case CLK:
+ /* disable efuse work clk */
+ if (reg & EFUSE_SRC_CLK_EN)
+ write32(reg | (EFUSE_SRC_CLK_EN << CRU_WRITE_MASK),
+ CRU_BASE + CRU_CLKGATE_CON2);
+ break;
+ case PCLK:
+ /* disable efuse APB clk */
+ if (reg & EFUSE_1024_PCLK_EN)
+ write32(reg | (EFUSE_1024_PCLK_EN << CRU_WRITE_MASK),
+ CRU_BASE + CRU_CLKGATE_CON15);
+ break;
+ default:
+ return;
+ }
+}
+
+/* user mode and auto mode */
+int rk_efuse32_readregs(uint32_t addr, uint32_t length, uint32_t *buf)
+{
+ uint32_t reg0 = 0;
+ uint32_t reg1 = 0;
+
+ uint32_t efuse_base = 0;
+
+ if (addr > 31)
+ return -1;
+ if (length < 1 || length > 32)
+ return -1;
+ if (!buf)
+ return -1;
+
+ if (addr < 24) {
+ if (addr + length < 25)
+ efuse_base = EFUSE32_BASE;
+ else
+ return -1;
+ }
+ if (addr > 23) {
+ if (addr + length < 33)
+ efuse_base = EFUSE8_BASE;
+ else
+ return -1;
+ }
+
+ //reg0 = enable_efuse_clk(CLK);
+ //reg1 = enable_efuse_clk(PCLK);
+
+#if EFUSE_AUTO_MODE
+ do {
+ write32(EFUSE_AUTO_RD | EFUSE_AUTO_ENABLE |
+ ((addr & EFUSE_A_MASK) << EFUSE_A_SHIFT),
+ efuse_base + REG_EFUSE_AUTO_CTRL);
+ udelay(2);
+ while (1) {
+ if (read32(efuse_base + REG_EFUSE_INT_STATUS) & 0x01)
+ break;
+ }
+ *buf = read32(efuse_base + REG_EFUSE_DOUT);
+ write32(read32(efuse_base + REG_EFUSE_AUTO_CTRL) &
+ (~EFUSE_AUTO_ENABLE), efuse_base + REG_EFUSE_AUTO_CTRL);
+ write32(0x07, efuse_base + REG_EFUSE_INT_STATUS);
+ buf++;
+ addr++;
+
+ } while (--length);
+#else
+ /* enable read in user mode */
+ write32((read32(efuse_base + REG_EFUSE_MOD) | EFUSE_RD_ENB_USER) &
+ (~EFUSE_PG_ENB_USER), efuse_base + REG_EFUSE_MOD);
+ write32(EFUSE_CSB, efuse_base + REG_EFUSE_CTRL);
+ write32(EFUSE_LOAD | EFUSE_PGENB, efuse_base + REG_EFUSE_CTRL);
+ udelay(2);
+ do {
+ write32(read32(efuse_base + REG_EFUSE_CTRL) &
+ (~(EFUSE_A_MASK << EFUSE_A_SHIFT)),
+ efuse_base + REG_EFUSE_CTRL);
+ write32(read32(efuse_base + REG_EFUSE_CTRL) |
+ ((addr & EFUSE_A_MASK) << EFUSE_A_SHIFT),
+ efuse_base + REG_EFUSE_CTRL);
+
+ udelay(2);
+ write32(read32(efuse_base + REG_EFUSE_CTRL) |
+ EFUSE_STROBE, efuse_base + REG_EFUSE_CTRL);
+ udelay(2);
+ *buf = read32(efuse_base + REG_EFUSE_DOUT);
+ write32(read32(efuse_base + REG_EFUSE_CTRL) &
+ (~EFUSE_STROBE), efuse_base + REG_EFUSE_CTRL);
+ udelay(2);
+ buf++;
+ addr++;
+ } while (--length);
+ udelay(2);
+ write32(read32(efuse_base + REG_EFUSE_CTRL) | EFUSE_CSB,
+ efuse_base + REG_EFUSE_CTRL);
+ udelay(1);
+#endif /* EFUSE_AUTO_MODE */
+
+ restore_efuse_clk(CLK, reg0);
+ restore_efuse_clk(PCLK, reg1);
+
+ return 0;
+}
+
+/*user mode and auto mode*/
+int rk_efuse32_write(uint32_t addr, uint32_t val)
+{
+ uint32_t reg0 = 0, reg1 = 0, efuse_base = 0;
+
+ if (addr > 31)
+ return -1;
+
+ if (addr < 24)
+ efuse_base = EFUSE32_BASE;
+ if (addr > 23 && addr < 32)
+ efuse_base = EFUSE8_BASE;
+
+ //reg0 = enable_efuse_clk(CLK);
+ //reg1 = enable_efuse_clk(PCLK);
+
+#if EFUSE_AUTO_MODE
+ while (val) {
+ if (val & 0x01) {
+ write32((EFUSE_AUTO_ENABLE |
+ ((addr & EFUSE_A_MASK) << EFUSE_A_SHIFT))
+ & (~EFUSE_AUTO_RD),
+ efuse_base + REG_EFUSE_AUTO_CTRL);
+ udelay(2);
+ while (1) {
+ if (read32(efuse_base + REG_EFUSE_INT_STATUS) &
+ 0x01)
+ break;
+ }
+ write32(read32(efuse_base + REG_EFUSE_AUTO_CTRL) &
+ (~EFUSE_AUTO_ENABLE),
+ efuse_base + REG_EFUSE_AUTO_CTRL);
+ write32(0x07, efuse_base + REG_EFUSE_INT_STATUS);
+ udelay(2);
+ }
+ addr += 32;
+ val = val >> 1;
+ udelay(2);
+ }
+#else
+ /* enable program in user mode */
+ write32((read32(efuse_base + REG_EFUSE_MOD) | EFUSE_PG_ENB_USER) &
+ (~EFUSE_RD_ENB_USER), efuse_base + REG_EFUSE_MOD);
+ write32(EFUSE_CSB | EFUSE_LOAD | EFUSE_PGENB,
+ efuse_base + REG_EFUSE_CTRL);
+ write32(read32(efuse_base + REG_EFUSE_CTRL) & (~EFUSE_CSB),
+ efuse_base + REG_EFUSE_CTRL);
+ write32(read32(efuse_base + REG_EFUSE_CTRL) & (~EFUSE_PGENB) &
+ (~EFUSE_LOAD), efuse_base + REG_EFUSE_CTRL);
+ udelay(2);
+
+ while (val) {
+ if (val & 0x01) {
+ write32(read32(efuse_base + REG_EFUSE_CTRL) &
+ (~(EFUSE_A_MASK << EFUSE_A_SHIFT)),
+ efuse_base + REG_EFUSE_CTRL);
+ write32(read32(efuse_base + REG_EFUSE_CTRL) |
+ ((addr & EFUSE_A_MASK) << EFUSE_A_SHIFT),
+ efuse_base + REG_EFUSE_CTRL);
+ udelay(2);
+ write32(read32(efuse_base + REG_EFUSE_CTRL) |
+ EFUSE_STROBE, efuse_base + REG_EFUSE_CTRL);
+ udelay(10);
+ write32(read32(efuse_base + REG_EFUSE_CTRL) &
+ (~EFUSE_STROBE),
+ efuse_base + REG_EFUSE_CTRL);
+ udelay(2);
+ }
+ addr += 32;
+ val = val >> 1;
+ }
+
+ udelay(2);
+ write32(read32(efuse_base + REG_EFUSE_CTRL) | EFUSE_LOAD |
+ EFUSE_PGENB, efuse_base + REG_EFUSE_CTRL);
+ write32(read32(efuse_base + REG_EFUSE_CTRL) | EFUSE_CSB,
+ efuse_base + REG_EFUSE_CTRL);
+ udelay(1);
+#endif /* EFUSE_AUTO_MODE */
+
+ restore_efuse_clk(CLK, reg0);
+ restore_efuse_clk(PCLK, reg1);
+
+ return 0;
+}
+
+int rk_efuse32_read(uint32_t addr, uint32_t length, uint32_t *buf)
+{
+ if (!buf)
+ return -1;
+
+ if (addr > 23) {
+ if (length < 1 || length + addr > 32)
+ return -1;
+
+ memcpy(buf, efuse32_buf + addr, length * sizeof(uint32_t));
+ } else if (addr < 24) {
+ if (length < 1 || length + addr > 24)
+ return -1;
+
+ memcpy(buf, efuse32_buf + addr, length * sizeof(uint32_t));
+ }
+
+ return 0;
+}
+
+void mode_init(int sec)
+{
+ int reg;
+ uint32_t efuse_base = 0;
+
+ if (sec == 1)
+ efuse_base = EFUSE32_BASE;/*secure efuse addr*/
+ if (sec == 0)
+ efuse_base = EFUSE8_BASE;/*un_secure efsue addr*/
+
+#if EFUSE_AUTO_MODE
+ /* enable auto mode */
+ reg = read32(efuse_base + REG_EFUSE_MOD);
+ write32(reg & (~EFUSE_USER_MODE), efuse_base + REG_EFUSE_MOD);
+
+ /* enable finish & auto_s_access_ns_err & auto_ns_access_s_err int */
+ write32(0x07, efuse_base + REG_EFUSE_INT_CON);
+ write32((T_CSB_P_S << 16) | T_CSB_P_L,
+ efuse_base + REG_EFUSE_T_CSB_P);
+ write32((T_PGENB_P_S << 16) | T_PGENB_P_L,
+ efuse_base + REG_EFUSE_T_PGENB_P);
+ write32((T_LOAD_P_S << 16) | T_LOAD_P_L,
+ efuse_base + REG_EFUSE_T_LOAD_P);
+ write32((T_ADDR_P_S << 16) | T_ADDR_P_L,
+ efuse_base + REG_EFUSE_T_ADDR_P);
+ write32((T_STROBE_P_S << 16) | T_STROBE_P_L,
+ efuse_base + REG_EFUSE_T_STROBE_P);
+ write32((T_CSB_R_S << 16) | T_CSB_R_L,
+ efuse_base + REG_EFUSE_T_CSB_R);
+ write32((T_PGENB_R_S << 16) | T_PGENB_R_L,
+ efuse_base + REG_EFUSE_T_PGENB_R);
+ write32((T_LOAD_R_S << 16) | T_LOAD_R_L,
+ efuse_base + REG_EFUSE_T_LOAD_R);
+ write32((T_ADDR_R_S << 16) | T_ADDR_R_L,
+ efuse_base + REG_EFUSE_T_ADDR_R);
+ write32((T_STROBE_R_S << 16) | T_STROBE_R_L,
+ efuse_base + REG_EFUSE_T_STROBE_R);
+#else
+ reg = read32(efuse_base + REG_EFUSE_MOD);
+ write32(reg | EFUSE_USER_MODE, efuse_base + REG_EFUSE_MOD);
+#endif /* EFUSE_AUTO_MODE */
+}
+
+void rk_efuse_prog_en(int n)
+{
+ if (n == 1) {
+ write32(read32(GPIO2_BASE) & (~(0X1 << 3)), GPIO2_BASE);
+ write32((efuse_pwren | efuse_pwren << 16) |
+ ((0) << 7 | efuse_pwren << 16 << 1),
+ GRF_BASE + GRF_GPIO2A_IOMUX);
+ /*efuse program enable*/
+ write32((1 << 7) | (1 << 7 << 16), SGRF_BASE +
+ EFUSE_SGRF_SOC_CON5);
+ } else {
+ write32((0 << 7) | (1 << 7 << 16),
+ SGRF_BASE + EFUSE_SGRF_SOC_CON5);
+ write32(0 << 6 | efuse_pwren << 16 |
+ ((0) << 7 | efuse_pwren << 16 << 1),
+ GRF_BASE + GRF_GPIO2A_IOMUX);
+ write32(read32(GPIO2_BASE) | (0X1 << 3), GPIO2_BASE);
+ }
+}
+
+int rk_efuse_init(void)
+{
+ mode_init(1);
+ mode_init(0);
+
+ if (rk_efuse32_readregs(RK322XH_S_EFUSE_START,
+ RK322XH_S_EFUSE_WORDS,
+ efuse32_buf)) {
+ ERROR("read S-efuse failed!!!!\n");
+ return -1;
+ }
+
+ if (rk_efuse32_readregs(RK322XH_NS_EFUSE_START,
+ RK322XH_NS_EFUSE_WORDS,
+ efuse32_buf + RK322XH_NS_EFUSE_START)) {
+ ERROR("read NS-efuse failed!!!!\n");
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/plat/rockchip/rk3328/drivers/efuse/efuse.h b/plat/rockchip/rk3328/drivers/efuse/efuse.h
new file mode 100644
index 0000000..22275c2
--- /dev/null
+++ b/plat/rockchip/rk3328/drivers/efuse/efuse.h
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2016, Fuzhou Rockchip Electronics Co., Ltd.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef EFUSE_H
+#define EFUSE_H
+
+#include <platform_def.h>
+
+/* CRU controller register */
+#define CRU_WRITE_MASK (16)
+
+#define GRF_GPIO2A_IOMUX (0x0020)
+#define EFUSE_SGRF_SOC_CON5 (0X0014)
+
+#define CRU_CLKGATE_CON2 (0x0208)
+#define CRU_CLKGATE_CON15 (0x023C)
+#define EFUSE_SRC_CLK_EN (1 << 13)
+#define EFUSE_1024_PCLK_EN (1 << 9)
+
+#define RK322XH_S_EFUSE_START 0
+#define RK322XH_S_EFUSE_WORDS 24
+#define RK322XH_NS_EFUSE_START (RK322XH_S_EFUSE_START + RK322XH_S_EFUSE_WORDS)
+#define RK322XH_NS_EFUSE_WORDS 8
+
+/* SGRF controller register */
+#define SGRF_WRITE_MASK (16)
+
+/* eFuse controller register */
+#define CRU_CLKSEL_CON5 (0x0114)
+#define REG_EFUSE_MOD (0x0000)
+#define efuse_pwren (1 << 6)
+#define EFUSE_RD_ENB_USER (1 << 6)
+#define EFUSE_PG_ENB_USER (1 << 5)
+#define EFUSE_STROBE_POL (1 << 4)
+#define EFUSE_LOAD_POL (1 << 3)
+#define EFUSE_PGENB_POL (1 << 2)
+#define EFUSE_CSB_POL (1 << 1)
+/* 0:auto mode; 1:user mode */
+#define EFUSE_USER_MODE (1 << 0)
+
+#define REG_EFUSE_RD_MASK_S (0x0004)
+#define REG_EFUSE_PG_MASK_S (0x0008)
+
+#define REG_EFUSE_RD_MASK_NS (0x000C)
+#define REG_EFUSE_PG_MASK_NS (0x0010)
+
+#define REG_EFUSE_INT_CON (0x0014)
+#define REG_EFUSE_INT_STATUS (0x0018)
+#define REG_EFUSE_USER_CTRL (0x001C)
+#define EFUSE_A_SHIFT (16)
+#define EFUSE_A_MASK (0x3FF)
+#define EFUSE_PGENB (1 << 3) /* active low */
+#define EFUSE_LOAD (1 << 2)
+#define EFUSE_STROBE (1 << 1)
+#define EFUSE_CSB (1 << 0) /* active low */
+#define REG_EFUSE_DOUT (0x0020)
+#define REG_EFUSE_AUTO_CTRL (0x0024)
+/* 0:programming mode; 1:read mode */
+#define EFUSE_AUTO_RD (1 << 1)
+#define EFUSE_AUTO_ENABLE (1 << 0)
+
+#define EFUSE_PG_ENB_MODE (0 << 1)
+
+#define REG_EFUSE_T_CSB_P (0x0028)
+#define REG_EFUSE_T_PGENB_P (0x002C)
+#define REG_EFUSE_T_LOAD_P (0x0030)
+#define REG_EFUSE_T_ADDR_P (0x0034)
+#define REG_EFUSE_T_STROBE_P (0x0038)
+#define REG_EFUSE_T_CSB_R (0x003C)
+#define REG_EFUSE_T_PGENB_R (0x0040)
+#define REG_EFUSE_T_LOAD_R (0x0044)
+#define REG_EFUSE_T_ADDR_R (0x0048)
+#define REG_EFUSE_T_STROBE_R (0x004C)
+#define REG_EFUSE_REVISION (0x0050)
+#define REG_EFUSE_CTRL REG_EFUSE_USER_CTRL
+
+#define T_CSB_P_S 1
+#define T_PGENB_P_S 1
+#define T_LOAD_P_S 1
+#define T_ADDR_P_S 1
+#define T_STROBE_P_S 2
+#define T_CSB_P_L 241
+#define T_PGENB_P_L 241
+#define T_LOAD_P_L 241
+#define T_ADDR_P_L 241
+#define T_STROBE_P_L 240
+#define T_CSB_R_S 1
+#define T_PGENB_R_S 1
+#define T_LOAD_R_S 1
+#define T_ADDR_R_S 1
+#define T_STROBE_R_S 2
+#define T_CSB_R_L 4
+#define T_PGENB_R_L 4
+#define T_LOAD_R_L 4
+#define T_ADDR_R_L 4
+#define T_STROBE_R_L 3
+
+/*
+ * readregs function is real-time read, from the efuse hardware.
+ * read function is not real-time read, read the value stored in
+ * memory when machine starting up.
+ */
+int rk_efuse8_readregs(uint32_t addr, uint32_t length, uint8_t *buf);
+int rk_efuse8_write(uint32_t addr, uint8_t val);
+
+int rk_efuse32_readregs(uint32_t addr, uint32_t length, uint32_t *buf);
+int rk_efuse32_write(uint32_t addr, uint32_t val);
+int rk_efuse32_read(uint32_t addr, uint32_t length, uint32_t *buf);
+
+int enable_efuse_clk();
+
+void mode_init(int sec);
+void rk_efuse_prog_en(int n);
+
+int rk_efuse_init(void);
+
+#endif /* RK_EFUSE_H */
+
diff --git a/plat/rockchip/rk3328/drivers/soc/soc.c b/plat/rockchip/rk3328/drivers/soc/soc.c
index 306308f..48a001c 100644
--- a/plat/rockchip/rk3328/drivers/soc/soc.c
+++ b/plat/rockchip/rk3328/drivers/soc/soc.c
@@ -16,6 +16,7 @@
#include <plat_private.h>
#include <rk3328_def.h>
#include <soc.h>
+#include <efuse.h>
/* Table of regions to map using the MMU. */
const mmap_region_t plat_rk_mmap[] = {
@@ -153,6 +154,11 @@ void plat_rockchip_soc_init(void)
secure_timer_init();
sgrf_init();
+ mode_init(1);
+ mode_init(0);
+
+ enable_efuse_clk();
+
NOTICE("BL31:Rockchip release version: v%d.%d\n",
MAJOR_VERSION, MINOR_VERSION);
}
diff --git a/plat/rockchip/rk3328/platform.mk b/plat/rockchip/rk3328/platform.mk
index 5b4766d..4ff5a7a 100644
--- a/plat/rockchip/rk3328/platform.mk
+++ b/plat/rockchip/rk3328/platform.mk
@@ -22,6 +22,7 @@ PLAT_INCLUDES := -Idrivers/arm/gic/common/ \
-I${RK_PLAT_SOC}/ \
-I${RK_PLAT_SOC}/drivers/pmu/ \
-I${RK_PLAT_SOC}/drivers/soc/ \
+ -I${RK_PLAT_SOC}/drivers/efuse/ \
-I${RK_PLAT_SOC}/include/
RK_GIC_SOURCES := ${GICV2_SOURCES} \
@@ -54,7 +55,8 @@ BL31_SOURCES += ${RK_GIC_SOURCES} \
${RK_PLAT_COMMON}/plat_topology.c \
${RK_PLAT_COMMON}/aarch64/platform_common.c \
${RK_PLAT_SOC}/drivers/pmu/pmu.c \
- ${RK_PLAT_SOC}/drivers/soc/soc.c
+ ${RK_PLAT_SOC}/drivers/soc/soc.c \
+ ${RK_PLAT_SOC}/drivers/efuse/efuse.c
ifdef PLAT_RK_SECURE_DDR_MINILOADER
BL31_SOURCES += ${RK_PLAT_COMMON}/drivers/parameter/ddr_parameter.c
--
2.30.2