diff --git a/config/sources/families/include/rockchip64_common.inc b/config/sources/families/include/rockchip64_common.inc index 07a4df9ae..0e1e74ef4 100644 --- a/config/sources/families/include/rockchip64_common.inc +++ b/config/sources/families/include/rockchip64_common.inc @@ -8,6 +8,7 @@ BOOTDELAY=0 OVERLAY_PREFIX='rockchip' SERIALCON=${SERIALCON:=$([ $BRANCH == "legacy" ] && echo "ttyFIQ0:1500000" || echo "ttyS2:1500000")} GOVERNOR="ondemand" +ATFPATCHDIR='atf-rockchip64' BOOTBRANCH="tag:v2020.10" BOOTPATCHDIR="u-boot-rockchip64" PACKAGE_LIST_FAMILY="ethtool" @@ -53,7 +54,6 @@ elif [[ $BOOT_SOC == rk3399 ]]; then DDR_BLOB='rk33/rk3399_ddr_933MHz_v1.25.bin' MINILOADER_BLOB='rk33/rk3399_miniloader_v1.26.bin' BL31_BLOB='rk33/rk3399_bl31_v1.35.elf' - ATFPATCHDIR='atf-rk3399' elif [[ $BOOT_SOC == rk3399pro ]]; then diff --git a/patch/atf/atf-rk3399/add-trust-ini.patch b/patch/atf/atf-rk3399/add-trust-ini.patch deleted file mode 100644 index 528ec5570..000000000 --- a/patch/atf/atf-rk3399/add-trust-ini.patch +++ /dev/null @@ -1,21 +0,0 @@ -diff --git a/trust.ini b/trust.ini -new file mode 100644 -index 0000000..4af021a ---- /dev/null -+++ b/trust.ini -@@ -0,0 +1,15 @@ -+[VERSION] -+MAJOR=1 -+MINOR=0 -+[BL30_OPTION] -+SEC=0 -+[BL31_OPTION] -+SEC=1 -+PATH=./build/rk3399/debug/bl31/bl31.elf -+ADDR=0x10000 -+[BL32_OPTION] -+SEC=0 -+[BL33_OPTION] -+SEC=0 -+[OUTPUT] -+PATH=trust.bin diff --git a/patch/atf/atf-rk3399/enable-logging.patch b/patch/atf/atf-rockchip64/enable-logging.patch similarity index 100% rename from patch/atf/atf-rk3399/enable-logging.patch rename to patch/atf/atf-rockchip64/enable-logging.patch diff --git a/patch/atf/atf-rk3399/enable-suspend-on-pbpro.patch b/patch/atf/atf-rockchip64/enable-suspend-on-pbpro.patch similarity index 100% rename from patch/atf/atf-rk3399/enable-suspend-on-pbpro.patch rename to patch/atf/atf-rockchip64/enable-suspend-on-pbpro.patch diff --git a/patch/atf/atf-rockchip64/rk3328-efuse-init.patch b/patch/atf/atf-rockchip64/rk3328-efuse-init.patch new file mode 100644 index 000000000..ffb3d1e26 --- /dev/null +++ b/patch/atf/atf-rockchip64/rk3328-efuse-init.patch @@ -0,0 +1,598 @@ +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 ++#include ++#include ++#include ++#include ++#include ++ ++#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 ++ ++/* 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 + #include + #include ++#include + + /* 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 0219422..8c570b2 100644 +--- a/plat/rockchip/rk3328/platform.mk ++++ b/plat/rockchip/rk3328/platform.mk +@@ -20,6 +20,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 := drivers/arm/gic/common/gic_common.c \ +@@ -50,7 +51,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 + \ No newline at end of file