169d5fd8fSJohnny Huang /* 269d5fd8fSJohnny Huang * This program is distributed in the hope that it will be useful, 369d5fd8fSJohnny Huang * but WITHOUT ANY WARRANTY; without even the implied warranty of 469d5fd8fSJohnny Huang * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 569d5fd8fSJohnny Huang * GNU General Public License for more details. 669d5fd8fSJohnny Huang * 769d5fd8fSJohnny Huang * You should have received a copy of the GNU General Public License 869d5fd8fSJohnny Huang * along with this program; if not, write to the Free Software 969d5fd8fSJohnny Huang * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 1069d5fd8fSJohnny Huang */ 114c1c9b35SJohnny Huang #include <stdlib.h> 1269d5fd8fSJohnny Huang #include <common.h> 1369d5fd8fSJohnny Huang #include <console.h> 1469d5fd8fSJohnny Huang #include <bootretry.h> 1569d5fd8fSJohnny Huang #include <cli.h> 1669d5fd8fSJohnny Huang #include <command.h> 1769d5fd8fSJohnny Huang #include <console.h> 184c1c9b35SJohnny Huang #include <malloc.h> 1969d5fd8fSJohnny Huang #include <inttypes.h> 2069d5fd8fSJohnny Huang #include <mapmem.h> 2169d5fd8fSJohnny Huang #include <asm/io.h> 2269d5fd8fSJohnny Huang #include <linux/compiler.h> 2369d5fd8fSJohnny Huang 2469d5fd8fSJohnny Huang DECLARE_GLOBAL_DATA_PTR; 2569d5fd8fSJohnny Huang 2669d5fd8fSJohnny Huang #define OTP_PASSWD 0x349fe38a 2769d5fd8fSJohnny Huang #define RETRY 3 28a6d0d645SJohnny Huang #define OTP_REGION_STRAP 1 29a6d0d645SJohnny Huang #define OTP_REGION_CONF 2 30a6d0d645SJohnny Huang #define OTP_REGION_DATA 3 31a6d0d645SJohnny Huang #define OTP_REGION_ALL 4 3269d5fd8fSJohnny Huang 332a856b9aSJohnny Huang #define OTP_USAGE -1 342a856b9aSJohnny Huang #define OTP_FAILURE -2 352a856b9aSJohnny Huang #define OTP_SUCCESS 0 362a856b9aSJohnny Huang 37a6af4a17SJohnny Huang #define OTP_PROG_SKIP 1 38a6af4a17SJohnny Huang 3966f2f8e5SJohnny Huang #define DISABLE_SECREG_PROG(x) (x & 0x1) 4066f2f8e5SJohnny Huang #define ENABLE_SEC_BOOT(x) ((x >> 1) & 0x1) 4166f2f8e5SJohnny Huang #define INIT_PROG_DONE(x) ((x >> 2) & 0x1) 4266f2f8e5SJohnny Huang #define ENABLE_USERREG_ECC(x) ((x >> 3) & 0x1) 4366f2f8e5SJohnny Huang #define ENABLE_SECREG_ECC(x) ((x >> 4) & 0x1) 4466f2f8e5SJohnny Huang #define DISABLE_LOW_SEC_KEY(x) ((x >> 5) & 0x1) 4566f2f8e5SJohnny Huang #define IGNORE_SEC_BOOT_HWSTRAP(x) ((x >> 6) & 0x1) 4666f2f8e5SJohnny Huang #define SEC_BOOT_MDOES(x) ((x >> 7) & 0x1) 47e1f9e54eSJohnny Huang #define SEC_MODE1 0x0 48e1f9e54eSJohnny Huang #define SEC_MODE2 0x1 49e1f9e54eSJohnny Huang #define OTP_BIT_CELL_MODES(x) ((x >> 8) & 0x3) 50e1f9e54eSJohnny Huang #define SINGLE_CELL_MODE 0x0 51e1f9e54eSJohnny Huang #define DIFFERENTIAL_MODE 0x1 52e1f9e54eSJohnny Huang #define DIFFERENTIAL_REDUDANT_MODE 0x2 53e1f9e54eSJohnny Huang #define CRYPTO_MODES(x) ((x >> 10) & 0x3) 54e1f9e54eSJohnny Huang #define CRYPTO_RSA1024 0x0 55e1f9e54eSJohnny Huang #define CRYPTO_RSA2048 0x1 56e1f9e54eSJohnny Huang #define CRYPTO_RSA3072 0x2 57e1f9e54eSJohnny Huang #define CRYPTO_RSA4096 0x3 58e1f9e54eSJohnny Huang #define HASH_MODES(x) ((x >> 12) & 0x3) 59e1f9e54eSJohnny Huang #define HASH_SAH224 0x0 60e1f9e54eSJohnny Huang #define HASH_SAH256 0x1 61e1f9e54eSJohnny Huang #define HASH_SAH384 0x2 62e1f9e54eSJohnny Huang #define HASH_SAH512 0x3 63e1f9e54eSJohnny Huang #define SECREG_SIZE(x) ((x >> 16) & 0x3f) 6466f2f8e5SJohnny Huang #define WRITE_PROTECT_SECREG(x) ((x >> 22) & 0x1) 6566f2f8e5SJohnny Huang #define WRITE_PROTECT_USERREG(x) ((x >> 23) & 0x1) 6666f2f8e5SJohnny Huang #define WRITE_PROTECT_CONFREG(x) ((x >> 24) & 0x1) 6766f2f8e5SJohnny Huang #define WRITE_PROTECT_STRAPREG(x) ((x >> 25) & 0x1) 6866f2f8e5SJohnny Huang #define ENABLE_COPY_TO_SRAM(x) ((x >> 26) & 0x1) 6966f2f8e5SJohnny Huang #define ENABLE_IMAGE_ENC(x) ((x >> 27) & 0x1) 7066f2f8e5SJohnny Huang #define WRITE_PROTECT_KEY_RETIRE(x) ((x >> 29) & 0x1) 7166f2f8e5SJohnny Huang #define ENABLE_SIPROM_RED(x) ((x >> 30) & 0x1) 7266f2f8e5SJohnny Huang #define ENABLE_SIPROM_MLOCK(x) ((x >> 31) & 0x1) 73e1f9e54eSJohnny Huang 74e1f9e54eSJohnny Huang #define VENDER_ID(x) (x & 0xFFFF) 75e1f9e54eSJohnny Huang #define KEY_REVISION(x) ((x >> 16) & 0xFFFF) 76e1f9e54eSJohnny Huang 77e1f9e54eSJohnny Huang #define SEC_BOOT_HEADER_OFFSET(x) (x & 0xFFFF) 78e1f9e54eSJohnny Huang 79e1f9e54eSJohnny Huang #define KEYS_VALID_BITS(x) (x & 0xff) 80e1f9e54eSJohnny Huang #define KEYS_RETIRE_BITS(x) ((x >> 16) & 0xff) 814c1c9b35SJohnny Huang 8276d13988SJohnny Huang #define ENABLE_SECURE_BOOT(x) (x & 0x1) 8376d13988SJohnny Huang #define BOOT_FROM_EMMC(x) ((x >> 1) & 0x1) 8476d13988SJohnny Huang #define BOOT_FROM_DEBUG_SPI(x) ((x >> 2) & 0x1) 8576d13988SJohnny Huang #define DISABLE_ARM_CM3(x) ((x >> 3) & 0x1) 8676d13988SJohnny Huang #define VGA_EXPANSION_ROM(x) ((x >> 4) & 0x1) 8776d13988SJohnny Huang #define MAC1_RMII_MODE(x) ((x >> 5) & 0x1) 8876d13988SJohnny Huang #define MAC2_RMII_MODE(x) ((x >> 6) & 0x1) 8976d13988SJohnny Huang #define CPU_FREQUENCY(x) ((x >> 7) & 0x7) 9076d13988SJohnny Huang #define HCLK_RATIO(x) ((x >> 10) & 0x3) 9176d13988SJohnny Huang #define VGA_MEMORY_SIZE(x) ((x >> 12) & 0x3) 9276d13988SJohnny Huang #define VGA_CLASS_CODE(x) ((x >> 17) & 0x1) 9376d13988SJohnny Huang #define DISABLE_DEBUG0(x) ((x >> 18) & 0x1) 9476d13988SJohnny Huang #define BOOT_FROM_EMMC_SPEED_MDOE(x) ((x >> 19) & 0x1) 9576d13988SJohnny Huang #define DISABLE_PCIE_EHCI(x) ((x >> 20) & 0x1) 9676d13988SJohnny Huang #define DISABLE_VGA_XDMA(x) ((x >> 21) & 0x1) 9776d13988SJohnny Huang #define DISABLE_DEDICATED_BMC_FUNCTION(x) ((x >> 22) & 0x1) 9876d13988SJohnny Huang #define DEDICATE_ROOT_COMPLEX_RELAX(x) ((x >> 23) & 0x1) 9976d13988SJohnny Huang #define SELECT_DRAM_TYPES(x) ((x >> 24) & 0x1) 10076d13988SJohnny Huang #define MAC3_RMII_MODE(x) (x & 0x1) 10176d13988SJohnny Huang #define MAC4_RMII_MODE(x) ((x >> 1) & 0x1) 10276d13988SJohnny Huang #define SIO_CONF_ADDR(x) ((x >> 2) & 0x1) 10376d13988SJohnny Huang #define DISABLE_SIO(x) ((x >> 3) & 0x1) 10476d13988SJohnny Huang #define DISABLE_DEBUG1(x) ((x >> 4) & 0x1) 10576d13988SJohnny Huang #define ENABLE_ACPI(x) ((x >> 5) & 0x1) 10676d13988SJohnny Huang #define SELECT_LPC(x) ((x >> 6) & 0x1) 10776d13988SJohnny Huang #define ENABLE_SAFS(x) ((x >> 7) & 0x1) 10876d13988SJohnny Huang #define ENABLE_SPI_3B4B_AUTO(x) ((x >> 10) & 0x1) 10976d13988SJohnny Huang #define ENABLE_BOOT_SPI_ABR(x) ((x >> 11) & 0x1) 11076d13988SJohnny Huang #define BOOT_SPI_ABR_MODE(x) ((x >> 12) & 0x1) 11176d13988SJohnny Huang #define BOOT_SPI_FLASH_SIZE(x) ((x >> 13) & 0x7) 11276d13988SJohnny Huang #define ENABLE_HOST_SPI_ABR(x) ((x >> 16) & 0x1) 11376d13988SJohnny Huang #define EBABLE_HOST_SPI_ABR_SEL_PIN(x) ((x >> 17) & 0x1) 11476d13988SJohnny Huang #define HOST_SPI_ABR_MODE(x) ((x >> 18) & 0x1) 11576d13988SJohnny Huang #define HOST_SPI_FLASH_SIZE(x) ((x >> 19) & 0x7) 11676d13988SJohnny Huang #define ENABLE_BOOT_SPI_AUX_CONTROL_PIN(x) ((x >> 22) & 0x1) 11776d13988SJohnny Huang #define BOOT_SPI_CRTM_SIZE(x) ((x >> 23) & 0x3) 11876d13988SJohnny Huang #define HOST_SPI_CRTM_SIZE(x) ((x >> 25) & 0x3) 11976d13988SJohnny Huang #define ENABLE_HOST_SPI_AUX_CONTROL_PIN(x) ((x >> 27) & 0x1) 12076d13988SJohnny Huang #define ENABLE_GPIO_PASS_THROUGH(x) ((x >> 28) & 0x1) 12176d13988SJohnny Huang #define DISABLE_LOW_SECURITY_KEY(x) ((x >> 29) & 0x1) 12276d13988SJohnny Huang #define ENABLE_DEDICATE_GPIO_STRAP(x) ((x >> 30) & 0x1) 12376d13988SJohnny Huang 12476d13988SJohnny Huang 1254c1c9b35SJohnny Huang #define PBSTR "||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||" 1264c1c9b35SJohnny Huang #define PBWIDTH 60 1274c1c9b35SJohnny Huang 1284c1c9b35SJohnny Huang void printProgress(int numerator, int denominator, char *format, ...) 1294c1c9b35SJohnny Huang { 1304c1c9b35SJohnny Huang int val = numerator * 100 / denominator; 1314c1c9b35SJohnny Huang int lpad = numerator * PBWIDTH / denominator; 1324c1c9b35SJohnny Huang int rpad = PBWIDTH - lpad; 1334c1c9b35SJohnny Huang char buffer[256]; 1344c1c9b35SJohnny Huang va_list aptr; 1354c1c9b35SJohnny Huang 1364c1c9b35SJohnny Huang va_start(aptr, format); 1374c1c9b35SJohnny Huang vsprintf(buffer, format, aptr); 1384c1c9b35SJohnny Huang va_end(aptr); 1394c1c9b35SJohnny Huang 1404c1c9b35SJohnny Huang printf("\r%3d%% [%.*s%*s] %s", val, lpad, PBSTR, rpad, "", buffer); 1414c1c9b35SJohnny Huang if (numerator == denominator) 1424c1c9b35SJohnny Huang printf("\n"); 1434c1c9b35SJohnny Huang } 1444c1c9b35SJohnny Huang 14566f2f8e5SJohnny Huang struct otpstrap_status { 14669d5fd8fSJohnny Huang int value; 14769d5fd8fSJohnny Huang int option_array[7]; 14869d5fd8fSJohnny Huang int remain_times; 14969d5fd8fSJohnny Huang int writeable_option; 15069d5fd8fSJohnny Huang int protected; 15169d5fd8fSJohnny Huang }; 15269d5fd8fSJohnny Huang 15366f2f8e5SJohnny Huang struct otpconf_parse { 15466f2f8e5SJohnny Huang int dw_offset; 15566f2f8e5SJohnny Huang int bit; 15666f2f8e5SJohnny Huang int length; 15766f2f8e5SJohnny Huang int value; 15866f2f8e5SJohnny Huang int keep; 15966f2f8e5SJohnny Huang char status[80]; 16066f2f8e5SJohnny Huang }; 16166f2f8e5SJohnny Huang 16276d13988SJohnny Huang struct otpstrap_parse { 16376d13988SJohnny Huang int bit; 16476d13988SJohnny Huang int length; 16576d13988SJohnny Huang int value; 16676d13988SJohnny Huang int keep; 16776d13988SJohnny Huang int protect; 16876d13988SJohnny Huang char status[80]; 16976d13988SJohnny Huang }; 17076d13988SJohnny Huang 1712a856b9aSJohnny Huang static void otp_read_data(uint32_t offset, uint32_t *data) 17269d5fd8fSJohnny Huang { 17369d5fd8fSJohnny Huang writel(offset, 0x1e6f2010); //Read address 17469d5fd8fSJohnny Huang writel(0x23b1e361, 0x1e6f2004); //trigger read 17569d5fd8fSJohnny Huang udelay(2); 17669d5fd8fSJohnny Huang data[0] = readl(0x1e6f2020); 17769d5fd8fSJohnny Huang data[1] = readl(0x1e6f2024); 17869d5fd8fSJohnny Huang } 17969d5fd8fSJohnny Huang 1802a856b9aSJohnny Huang static void otp_read_config(uint32_t offset, uint32_t *data) 18169d5fd8fSJohnny Huang { 18269d5fd8fSJohnny Huang int config_offset; 18369d5fd8fSJohnny Huang 18469d5fd8fSJohnny Huang config_offset = 0x800; 18569d5fd8fSJohnny Huang config_offset |= (offset / 8) * 0x200; 18669d5fd8fSJohnny Huang config_offset |= (offset % 8) * 0x2; 18769d5fd8fSJohnny Huang 18869d5fd8fSJohnny Huang writel(config_offset, 0x1e6f2010); //Read address 18969d5fd8fSJohnny Huang writel(0x23b1e361, 0x1e6f2004); //trigger read 19069d5fd8fSJohnny Huang udelay(2); 19169d5fd8fSJohnny Huang data[0] = readl(0x1e6f2020); 19269d5fd8fSJohnny Huang } 19369d5fd8fSJohnny Huang 19469d5fd8fSJohnny Huang static int otp_print_config(uint32_t offset, int dw_count) 19569d5fd8fSJohnny Huang { 19669d5fd8fSJohnny Huang int i; 19769d5fd8fSJohnny Huang uint32_t ret[1]; 19869d5fd8fSJohnny Huang 19969d5fd8fSJohnny Huang if (offset + dw_count > 32) 2002a856b9aSJohnny Huang return OTP_USAGE; 20169d5fd8fSJohnny Huang for (i = offset; i < offset + dw_count; i ++) { 20269d5fd8fSJohnny Huang otp_read_config(i, ret); 203a6af4a17SJohnny Huang printf("OTPCFG%X: %08X\n", i, ret[0]); 20469d5fd8fSJohnny Huang } 20569d5fd8fSJohnny Huang printf("\n"); 2062a856b9aSJohnny Huang return OTP_SUCCESS; 20769d5fd8fSJohnny Huang } 20869d5fd8fSJohnny Huang 20969d5fd8fSJohnny Huang static int otp_print_data(uint32_t offset, int dw_count) 21069d5fd8fSJohnny Huang { 21169d5fd8fSJohnny Huang int i; 21269d5fd8fSJohnny Huang uint32_t ret[2]; 21369d5fd8fSJohnny Huang 21469d5fd8fSJohnny Huang if (offset + dw_count > 2048 || offset % 4 != 0) 2152a856b9aSJohnny Huang return OTP_USAGE; 21669d5fd8fSJohnny Huang for (i = offset; i < offset + dw_count; i += 2) { 21769d5fd8fSJohnny Huang otp_read_data(i, ret); 21869d5fd8fSJohnny Huang if (i % 4 == 0) 21969d5fd8fSJohnny Huang printf("%03X: %08X %08X ", i * 4, ret[0], ret[1]); 22069d5fd8fSJohnny Huang else 22169d5fd8fSJohnny Huang printf("%08X %08X\n", ret[0], ret[1]); 22269d5fd8fSJohnny Huang 22369d5fd8fSJohnny Huang } 22469d5fd8fSJohnny Huang printf("\n"); 2252a856b9aSJohnny Huang return OTP_SUCCESS; 22669d5fd8fSJohnny Huang } 22769d5fd8fSJohnny Huang 22869d5fd8fSJohnny Huang static int otp_compare(uint32_t otp_addr, uint32_t addr) 22969d5fd8fSJohnny Huang { 23069d5fd8fSJohnny Huang uint32_t ret; 23169d5fd8fSJohnny Huang uint32_t *buf; 23269d5fd8fSJohnny Huang 23369d5fd8fSJohnny Huang buf = map_physmem(addr, 16, MAP_WRBACK); 23469d5fd8fSJohnny Huang printf("%08X\n", buf[0]); 23569d5fd8fSJohnny Huang printf("%08X\n", buf[1]); 23669d5fd8fSJohnny Huang printf("%08X\n", buf[2]); 23769d5fd8fSJohnny Huang printf("%08X\n", buf[3]); 23869d5fd8fSJohnny Huang writel(otp_addr, 0x1e6f2010); //Compare address 23969d5fd8fSJohnny Huang writel(buf[0], 0x1e6f2020); //Compare data 1 24069d5fd8fSJohnny Huang writel(buf[1], 0x1e6f2024); //Compare data 2 24169d5fd8fSJohnny Huang writel(buf[2], 0x1e6f2028); //Compare data 3 24269d5fd8fSJohnny Huang writel(buf[3], 0x1e6f202c); //Compare data 4 24369d5fd8fSJohnny Huang writel(0x23b1e363, 0x1e6f2004); //Compare command 24469d5fd8fSJohnny Huang udelay(10); 24569d5fd8fSJohnny Huang ret = readl(0x1e6f2014); //Compare command 24669d5fd8fSJohnny Huang if (ret & 0x1) 24769d5fd8fSJohnny Huang return 0; 24869d5fd8fSJohnny Huang else 24969d5fd8fSJohnny Huang return -1; 25069d5fd8fSJohnny Huang } 25169d5fd8fSJohnny Huang 25269d5fd8fSJohnny Huang static void otp_write(uint32_t otp_addr, uint32_t data) 25369d5fd8fSJohnny Huang { 25469d5fd8fSJohnny Huang writel(otp_addr, 0x1e6f2010); //write address 25569d5fd8fSJohnny Huang writel(data, 0x1e6f2020); //write data 25669d5fd8fSJohnny Huang writel(0x23b1e362, 0x1e6f2004); //write command 25769d5fd8fSJohnny Huang udelay(100); 25869d5fd8fSJohnny Huang } 25969d5fd8fSJohnny Huang 26069d5fd8fSJohnny Huang static void otp_prog(uint32_t otp_addr, uint32_t prog_bit) 26169d5fd8fSJohnny Huang { 26269d5fd8fSJohnny Huang writel(otp_addr, 0x1e6f2010); //write address 26369d5fd8fSJohnny Huang writel(prog_bit, 0x1e6f2020); //write data 26469d5fd8fSJohnny Huang writel(0x23b1e364, 0x1e6f2004); //write command 26569d5fd8fSJohnny Huang udelay(85); 26669d5fd8fSJohnny Huang } 26769d5fd8fSJohnny Huang 268a6d0d645SJohnny Huang static int verify_bit(uint32_t otp_addr, int bit_offset, int value) 26969d5fd8fSJohnny Huang { 27069d5fd8fSJohnny Huang int ret; 27169d5fd8fSJohnny Huang 27269d5fd8fSJohnny Huang writel(otp_addr, 0x1e6f2010); //Read address 27369d5fd8fSJohnny Huang writel(0x23b1e361, 0x1e6f2004); //trigger read 27469d5fd8fSJohnny Huang udelay(2); 27569d5fd8fSJohnny Huang ret = readl(0x1e6f2020); 276a6d0d645SJohnny Huang // printf("verify_bit = %x\n", ret); 27769d5fd8fSJohnny Huang if (((ret >> bit_offset) & 1) == value) 27869d5fd8fSJohnny Huang return 0; 27969d5fd8fSJohnny Huang else 28069d5fd8fSJohnny Huang return -1; 28169d5fd8fSJohnny Huang } 28269d5fd8fSJohnny Huang 283d90825e2SJohnny Huang static uint32_t verify_dw(uint32_t otp_addr, uint32_t *value, uint32_t *keep, uint32_t *compare, int size) 2844c1c9b35SJohnny Huang { 2854c1c9b35SJohnny Huang uint32_t ret[2]; 2864c1c9b35SJohnny Huang 2874c1c9b35SJohnny Huang otp_addr &= ~(1 << 15); 2884c1c9b35SJohnny Huang 2894c1c9b35SJohnny Huang if (otp_addr % 2 == 0) 2904c1c9b35SJohnny Huang writel(otp_addr, 0x1e6f2010); //Read address 2914c1c9b35SJohnny Huang else 2924c1c9b35SJohnny Huang writel(otp_addr - 1, 0x1e6f2010); //Read address 2934c1c9b35SJohnny Huang writel(0x23b1e361, 0x1e6f2004); //trigger read 2944c1c9b35SJohnny Huang udelay(2); 2954c1c9b35SJohnny Huang ret[0] = readl(0x1e6f2020); 2964c1c9b35SJohnny Huang ret[1] = readl(0x1e6f2024); 2974c1c9b35SJohnny Huang if (size == 1) { 2984c1c9b35SJohnny Huang if (otp_addr % 2 == 0) { 2994c1c9b35SJohnny Huang // printf("check %x : %x = %x\n", otp_addr, ret[0], value[0]); 300d90825e2SJohnny Huang if ((value[0] & ~keep[0]) == (ret[0] & ~keep[0])) { 3014c1c9b35SJohnny Huang compare[0] = 0; 3024c1c9b35SJohnny Huang return 0; 3034c1c9b35SJohnny Huang } else { 3044c1c9b35SJohnny Huang compare[0] = value[0] ^ ret[0]; 3054c1c9b35SJohnny Huang return -1; 3064c1c9b35SJohnny Huang } 3074c1c9b35SJohnny Huang 3084c1c9b35SJohnny Huang } else { 3094c1c9b35SJohnny Huang // printf("check %x : %x = %x\n", otp_addr, ret[1], value[0]); 310d90825e2SJohnny Huang if ((value[0] & ~keep[0]) == (ret[1] & ~keep[0])) { 3114c1c9b35SJohnny Huang compare[0] = ~0; 3124c1c9b35SJohnny Huang return 0; 3134c1c9b35SJohnny Huang } else { 314d90825e2SJohnny Huang compare[0] = ~(value[0] ^ ret[1]); 3154c1c9b35SJohnny Huang return -1; 3164c1c9b35SJohnny Huang } 3174c1c9b35SJohnny Huang } 3184c1c9b35SJohnny Huang } else if (size == 2) { 3194c1c9b35SJohnny Huang // otp_addr should be even 320d90825e2SJohnny Huang if ((value[0] & ~keep[0]) == (ret[0] & ~keep[0]) && (value[1] & ~keep[1]) == (ret[1] & ~keep[1])) { 3214c1c9b35SJohnny Huang // printf("check[0] %x : %x = %x\n", otp_addr, ret[0], value[0]); 3224c1c9b35SJohnny Huang // printf("check[1] %x : %x = %x\n", otp_addr, ret[1], value[1]); 3234c1c9b35SJohnny Huang compare[0] = 0; 3244c1c9b35SJohnny Huang compare[1] = ~0; 3254c1c9b35SJohnny Huang return 0; 3264c1c9b35SJohnny Huang } else { 3274c1c9b35SJohnny Huang // printf("check[0] %x : %x = %x\n", otp_addr, ret[0], value[0]); 3284c1c9b35SJohnny Huang // printf("check[1] %x : %x = %x\n", otp_addr, ret[1], value[1]); 3294c1c9b35SJohnny Huang compare[0] = value[0] ^ ret[0]; 3304c1c9b35SJohnny Huang compare[1] = ~(value[1] ^ ret[1]); 3314c1c9b35SJohnny Huang return -1; 3324c1c9b35SJohnny Huang } 3334c1c9b35SJohnny Huang } else { 3344c1c9b35SJohnny Huang return -1; 3354c1c9b35SJohnny Huang } 3364c1c9b35SJohnny Huang } 3374c1c9b35SJohnny Huang 3387e22f42dSJohnny Huang static void otp_soak(int soak) 339d90825e2SJohnny Huang { 340d90825e2SJohnny Huang if (soak) { 341d90825e2SJohnny Huang otp_write(0x3000, 0x4021); // Write MRA 342d90825e2SJohnny Huang otp_write(0x5000, 0x1027); // Write MRB 343d90825e2SJohnny Huang otp_write(0x1000, 0x4820); // Write MR 344d90825e2SJohnny Huang writel(0x041930d4, 0x1e602008); //soak program 345d90825e2SJohnny Huang } else { 346d90825e2SJohnny Huang otp_write(0x3000, 0x4061); // Write MRA 347d90825e2SJohnny Huang otp_write(0x5000, 0x302f); // Write MRB 348d90825e2SJohnny Huang otp_write(0x1000, 0x4020); // Write MR 349d90825e2SJohnny Huang writel(0x04190760, 0x1e602008); //normal program 350d90825e2SJohnny Huang } 351d90825e2SJohnny Huang } 352d90825e2SJohnny Huang 353d90825e2SJohnny Huang static void otp_prog_dw(uint32_t value, uint32_t keep, uint32_t prog_address) 354d90825e2SJohnny Huang { 355d90825e2SJohnny Huang int j, bit_value, prog_bit; 356d90825e2SJohnny Huang 357d90825e2SJohnny Huang for (j = 0; j < 32; j++) { 358d90825e2SJohnny Huang if ((keep >> j) & 0x1) 359d90825e2SJohnny Huang continue; 360d90825e2SJohnny Huang bit_value = (value >> j) & 0x1; 361d90825e2SJohnny Huang if (prog_address % 2 == 0) { 362d90825e2SJohnny Huang if (bit_value) 363d90825e2SJohnny Huang prog_bit = ~(0x1 << j); 364d90825e2SJohnny Huang else 365d90825e2SJohnny Huang continue; 366d90825e2SJohnny Huang } else { 367d90825e2SJohnny Huang prog_address |= 1 << 15; 368d90825e2SJohnny Huang if (bit_value) 369d90825e2SJohnny Huang continue; 370d90825e2SJohnny Huang else 371d90825e2SJohnny Huang prog_bit = 0x1 << j; 372d90825e2SJohnny Huang } 373d90825e2SJohnny Huang otp_prog(prog_address, prog_bit); 374d90825e2SJohnny Huang } 375d90825e2SJohnny Huang } 376d90825e2SJohnny Huang 37776d13988SJohnny Huang 37876d13988SJohnny Huang static void otp_strp_status(struct otpstrap_status *otpstrap) 37976d13988SJohnny Huang { 38076d13988SJohnny Huang uint32_t OTPSTRAP_RAW[2]; 38176d13988SJohnny Huang int i, j; 38276d13988SJohnny Huang 38376d13988SJohnny Huang for (j = 0; j < 64; j++) { 38476d13988SJohnny Huang otpstrap[j].value = 0; 38576d13988SJohnny Huang otpstrap[j].remain_times = 7; 38676d13988SJohnny Huang otpstrap[j].writeable_option = -1; 38776d13988SJohnny Huang otpstrap[j].protected = 0; 38876d13988SJohnny Huang } 38976d13988SJohnny Huang 39076d13988SJohnny Huang for (i = 16; i < 30; i += 2) { 39176d13988SJohnny Huang int option = (i - 16) / 2; 39276d13988SJohnny Huang otp_read_config(i, &OTPSTRAP_RAW[0]); 39376d13988SJohnny Huang otp_read_config(i + 1, &OTPSTRAP_RAW[1]); 39476d13988SJohnny Huang for (j = 0; j < 32; j++) { 39576d13988SJohnny Huang char bit_value = ((OTPSTRAP_RAW[0] >> j) & 0x1); 39676d13988SJohnny Huang if ((bit_value == 0) && (otpstrap[j].writeable_option == -1)) { 39776d13988SJohnny Huang otpstrap[j].writeable_option = option; 39876d13988SJohnny Huang } 39976d13988SJohnny Huang if (bit_value == 1) 40076d13988SJohnny Huang otpstrap[j].remain_times --; 40176d13988SJohnny Huang otpstrap[j].value ^= bit_value; 40276d13988SJohnny Huang otpstrap[j].option_array[option] = bit_value; 40376d13988SJohnny Huang } 40476d13988SJohnny Huang for (j = 32; j < 64; j++) { 40576d13988SJohnny Huang char bit_value = ((OTPSTRAP_RAW[1] >> (j - 32)) & 0x1); 40676d13988SJohnny Huang if ((bit_value == 0) && (otpstrap[j].writeable_option == -1)) { 40776d13988SJohnny Huang otpstrap[j].writeable_option = option; 40876d13988SJohnny Huang } 40976d13988SJohnny Huang if (bit_value == 1) 41076d13988SJohnny Huang otpstrap[j].remain_times --; 41176d13988SJohnny Huang otpstrap[j].value ^= bit_value; 41276d13988SJohnny Huang otpstrap[j].option_array[option] = bit_value; 41376d13988SJohnny Huang } 41476d13988SJohnny Huang } 41576d13988SJohnny Huang otp_read_config(30, &OTPSTRAP_RAW[0]); 41676d13988SJohnny Huang otp_read_config(31, &OTPSTRAP_RAW[1]); 41776d13988SJohnny Huang for (j = 0; j < 32; j++) { 41876d13988SJohnny Huang if (((OTPSTRAP_RAW[0] >> j) & 0x1) == 1) 41976d13988SJohnny Huang otpstrap[j].protected = 1; 42076d13988SJohnny Huang } 42176d13988SJohnny Huang for (j = 32; j < 64; j++) { 42276d13988SJohnny Huang if (((OTPSTRAP_RAW[1] >> (j - 32)) & 0x1) == 1) 42376d13988SJohnny Huang otpstrap[j].protected = 1; 42476d13988SJohnny Huang } 42576d13988SJohnny Huang } 42676d13988SJohnny Huang 42766f2f8e5SJohnny Huang static int otp_conf_parse(uint32_t *OTPCFG, struct otpconf_parse *conf_parse) 42869d5fd8fSJohnny Huang { 4294c1c9b35SJohnny Huang int tmp, i; 43066f2f8e5SJohnny Huang int k = 0; 4314c1c9b35SJohnny Huang int pass = 0; 432442839bbSJohnny Huang uint32_t *OTPCFG_KEEP = &OTPCFG[12]; 43369d5fd8fSJohnny Huang 43466f2f8e5SJohnny Huang conf_parse[k].dw_offset = 0; 43566f2f8e5SJohnny Huang conf_parse[k].bit = 0; 43666f2f8e5SJohnny Huang conf_parse[k].length = 1; 43766f2f8e5SJohnny Huang conf_parse[k].value = DISABLE_SECREG_PROG(OTPCFG[0]); 43866f2f8e5SJohnny Huang if (DISABLE_SECREG_PROG(OTPCFG_KEEP[0])) { 43966f2f8e5SJohnny Huang conf_parse[k].keep = 1; 44066f2f8e5SJohnny Huang strcpy(conf_parse[k].status, "Skip"); 441442839bbSJohnny Huang } else { 44266f2f8e5SJohnny Huang if (DISABLE_SECREG_PROG(OTPCFG[0])) 44366f2f8e5SJohnny Huang strcpy(conf_parse[k].status, 44466f2f8e5SJohnny Huang "Disable Secure Region programming"); 44569d5fd8fSJohnny Huang else 44666f2f8e5SJohnny Huang strcpy(conf_parse[k].status, 44766f2f8e5SJohnny Huang "Enable Secure Region programming"); 448442839bbSJohnny Huang } 449442839bbSJohnny Huang 45066f2f8e5SJohnny Huang k++; 45166f2f8e5SJohnny Huang conf_parse[k].dw_offset = 0; 45266f2f8e5SJohnny Huang conf_parse[k].bit = 1; 45366f2f8e5SJohnny Huang conf_parse[k].length = 1; 45466f2f8e5SJohnny Huang conf_parse[k].value = ENABLE_SEC_BOOT(OTPCFG[0]); 45566f2f8e5SJohnny Huang if (ENABLE_SEC_BOOT(OTPCFG_KEEP[0])) { 45666f2f8e5SJohnny Huang conf_parse[k].keep = 1; 45766f2f8e5SJohnny Huang strcpy(conf_parse[k].status, "Skip"); 458442839bbSJohnny Huang } else { 45966f2f8e5SJohnny Huang if (ENABLE_SEC_BOOT(OTPCFG[0])) 46066f2f8e5SJohnny Huang strcpy(conf_parse[k].status, 46166f2f8e5SJohnny Huang "Enable Secure Boot"); 46269d5fd8fSJohnny Huang else 46366f2f8e5SJohnny Huang strcpy(conf_parse[k].status, 46466f2f8e5SJohnny Huang "Disable Secure Boot"); 465442839bbSJohnny Huang } 466442839bbSJohnny Huang 46766f2f8e5SJohnny Huang k++; 46866f2f8e5SJohnny Huang conf_parse[k].dw_offset = 0; 46966f2f8e5SJohnny Huang conf_parse[k].bit = 3; 47066f2f8e5SJohnny Huang conf_parse[k].length = 1; 47166f2f8e5SJohnny Huang conf_parse[k].value = ENABLE_USERREG_ECC(OTPCFG[0]); 47266f2f8e5SJohnny Huang if (ENABLE_USERREG_ECC(OTPCFG_KEEP[0])) { 47366f2f8e5SJohnny Huang conf_parse[k].keep = 1; 47466f2f8e5SJohnny Huang strcpy(conf_parse[k].status, "Skip"); 475442839bbSJohnny Huang } else { 47666f2f8e5SJohnny Huang if (ENABLE_USERREG_ECC(OTPCFG[0])) 47766f2f8e5SJohnny Huang strcpy(conf_parse[k].status, 47866f2f8e5SJohnny Huang "User region ECC enable"); 47969d5fd8fSJohnny Huang else 48066f2f8e5SJohnny Huang strcpy(conf_parse[k].status, 48166f2f8e5SJohnny Huang "User region ECC disable"); 482442839bbSJohnny Huang } 483442839bbSJohnny Huang 48466f2f8e5SJohnny Huang k++; 48566f2f8e5SJohnny Huang conf_parse[k].dw_offset = 0; 48666f2f8e5SJohnny Huang conf_parse[k].bit = 4; 48766f2f8e5SJohnny Huang conf_parse[k].length = 1; 48866f2f8e5SJohnny Huang conf_parse[k].value = ENABLE_SECREG_ECC(OTPCFG[0]); 48966f2f8e5SJohnny Huang if (ENABLE_SECREG_ECC(OTPCFG_KEEP[0])) { 49066f2f8e5SJohnny Huang conf_parse[k].keep = 1; 49166f2f8e5SJohnny Huang strcpy(conf_parse[k].status, "Skip"); 492442839bbSJohnny Huang } else { 49366f2f8e5SJohnny Huang if (ENABLE_SECREG_ECC(OTPCFG[0])) 49466f2f8e5SJohnny Huang strcpy(conf_parse[k].status, 49566f2f8e5SJohnny Huang "Secure Region ECC enable"); 49669d5fd8fSJohnny Huang else 49766f2f8e5SJohnny Huang strcpy(conf_parse[k].status, 49866f2f8e5SJohnny Huang "Secure Region ECC disable"); 499442839bbSJohnny Huang } 500442839bbSJohnny Huang 50166f2f8e5SJohnny Huang k++; 50266f2f8e5SJohnny Huang conf_parse[k].dw_offset = 0; 50366f2f8e5SJohnny Huang conf_parse[k].bit = 5; 50466f2f8e5SJohnny Huang conf_parse[k].length = 1; 50566f2f8e5SJohnny Huang conf_parse[k].value = DISABLE_LOW_SEC_KEY(OTPCFG[0]); 50666f2f8e5SJohnny Huang if (DISABLE_LOW_SEC_KEY(OTPCFG_KEEP[0])) { 50766f2f8e5SJohnny Huang conf_parse[k].keep = 1; 50866f2f8e5SJohnny Huang strcpy(conf_parse[k].status, "Skip"); 509442839bbSJohnny Huang } else { 51066f2f8e5SJohnny Huang if (DISABLE_LOW_SEC_KEY(OTPCFG[0])) 51166f2f8e5SJohnny Huang strcpy(conf_parse[k].status, 51266f2f8e5SJohnny Huang "Disable low security key"); 51369d5fd8fSJohnny Huang else 51466f2f8e5SJohnny Huang strcpy(conf_parse[k].status, 51566f2f8e5SJohnny Huang "Enable low security key"); 516442839bbSJohnny Huang } 517442839bbSJohnny Huang 51866f2f8e5SJohnny Huang k++; 51966f2f8e5SJohnny Huang conf_parse[k].dw_offset = 0; 52066f2f8e5SJohnny Huang conf_parse[k].bit = 6; 52166f2f8e5SJohnny Huang conf_parse[k].length = 1; 52266f2f8e5SJohnny Huang conf_parse[k].value = IGNORE_SEC_BOOT_HWSTRAP(OTPCFG[0]); 52366f2f8e5SJohnny Huang if (IGNORE_SEC_BOOT_HWSTRAP(OTPCFG_KEEP[0])) { 52466f2f8e5SJohnny Huang conf_parse[k].keep = 1; 52566f2f8e5SJohnny Huang strcpy(conf_parse[k].status, "Skip"); 526442839bbSJohnny Huang } else { 52766f2f8e5SJohnny Huang if (IGNORE_SEC_BOOT_HWSTRAP(OTPCFG[0])) 52866f2f8e5SJohnny Huang strcpy(conf_parse[k].status, 52966f2f8e5SJohnny Huang "Ignore Secure Boot hardware strap"); 53069d5fd8fSJohnny Huang else 53166f2f8e5SJohnny Huang strcpy(conf_parse[k].status, 53266f2f8e5SJohnny Huang "Do not ignore Secure Boot hardware strap"); 533442839bbSJohnny Huang } 534442839bbSJohnny Huang 53566f2f8e5SJohnny Huang k++; 53666f2f8e5SJohnny Huang conf_parse[k].dw_offset = 0; 53766f2f8e5SJohnny Huang conf_parse[k].bit = 7; 53866f2f8e5SJohnny Huang conf_parse[k].length = 1; 53966f2f8e5SJohnny Huang conf_parse[k].value = SEC_BOOT_MDOES(OTPCFG[0]); 54066f2f8e5SJohnny Huang if (SEC_BOOT_MDOES(OTPCFG_KEEP[0])) { 54166f2f8e5SJohnny Huang conf_parse[k].keep = 1; 54266f2f8e5SJohnny Huang strcpy(conf_parse[k].status, "Skip"); 543442839bbSJohnny Huang } else { 54466f2f8e5SJohnny Huang if (SEC_BOOT_MDOES(OTPCFG[0])) 54566f2f8e5SJohnny Huang strcpy(conf_parse[k].status, 54666f2f8e5SJohnny Huang "Secure Boot Mode: 1"); 547e1f9e54eSJohnny Huang else 54866f2f8e5SJohnny Huang strcpy(conf_parse[k].status, 54966f2f8e5SJohnny Huang "Secure Boot Mode: 2"); 550442839bbSJohnny Huang } 551442839bbSJohnny Huang 55266f2f8e5SJohnny Huang k++; 55366f2f8e5SJohnny Huang conf_parse[k].dw_offset = 0; 55466f2f8e5SJohnny Huang conf_parse[k].bit = 8; 55566f2f8e5SJohnny Huang conf_parse[k].length = 2; 55666f2f8e5SJohnny Huang conf_parse[k].value = OTP_BIT_CELL_MODES(OTPCFG[0]); 557442839bbSJohnny Huang if (OTP_BIT_CELL_MODES(OTPCFG_KEEP[0]) == 0x3) { 55866f2f8e5SJohnny Huang conf_parse[k].keep = 1; 55966f2f8e5SJohnny Huang strcpy(conf_parse[k].status, "Skip"); 56066f2f8e5SJohnny Huang } else if (OTP_BIT_CELL_MODES(OTPCFG_KEEP[0]) == 0) { 56166f2f8e5SJohnny Huang strcpy(conf_parse[k].status, "OTP bit cell mode : "); 56266f2f8e5SJohnny Huang if (conf_parse[k].value == SINGLE_CELL_MODE) { 56366f2f8e5SJohnny Huang strcat(conf_parse[k].status, 56466f2f8e5SJohnny Huang "Single cell mode (recommended)"); 56566f2f8e5SJohnny Huang } else if (conf_parse[k].value == DIFFERENTIAL_MODE) { 56666f2f8e5SJohnny Huang strcat(conf_parse[k].status, 56766f2f8e5SJohnny Huang "Differnetial mode"); 56866f2f8e5SJohnny Huang } else if (conf_parse[k].value == DIFFERENTIAL_REDUDANT_MODE) { 56966f2f8e5SJohnny Huang strcat(conf_parse[k].status, 57066f2f8e5SJohnny Huang "Differential-redundant mode"); 571442839bbSJohnny Huang } else { 57266f2f8e5SJohnny Huang strcat(conf_parse[k].status, 57366f2f8e5SJohnny Huang "Value error"); 57469d5fd8fSJohnny Huang return -1; 57569d5fd8fSJohnny Huang } 57666f2f8e5SJohnny Huang } else { 57766f2f8e5SJohnny Huang strcpy(conf_parse[k].status, "Keep mask error!"); 57866f2f8e5SJohnny Huang return -1; 579442839bbSJohnny Huang } 58066f2f8e5SJohnny Huang 58166f2f8e5SJohnny Huang k++; 58266f2f8e5SJohnny Huang conf_parse[k].dw_offset = 0; 58366f2f8e5SJohnny Huang conf_parse[k].bit = 10; 58466f2f8e5SJohnny Huang conf_parse[k].length = 2; 58566f2f8e5SJohnny Huang conf_parse[k].value = CRYPTO_MODES(OTPCFG[0]); 586442839bbSJohnny Huang if (CRYPTO_MODES(OTPCFG_KEEP[0]) == 0x3) { 58766f2f8e5SJohnny Huang conf_parse[k].keep = 1; 58866f2f8e5SJohnny Huang strcpy(conf_parse[k].status, "Skip"); 58966f2f8e5SJohnny Huang } else if (CRYPTO_MODES(OTPCFG_KEEP[0]) == 0) { 59066f2f8e5SJohnny Huang strcpy(conf_parse[k].status, "RSA mode : "); 59166f2f8e5SJohnny Huang if (conf_parse[k].value == CRYPTO_RSA1024) { 59266f2f8e5SJohnny Huang strcat(conf_parse[k].status, 59366f2f8e5SJohnny Huang "RSA1024"); 59466f2f8e5SJohnny Huang } else if (conf_parse[k].value == CRYPTO_RSA2048) { 59566f2f8e5SJohnny Huang strcat(conf_parse[k].status, 59666f2f8e5SJohnny Huang "RSA2048"); 59766f2f8e5SJohnny Huang } else if (conf_parse[k].value == CRYPTO_RSA3072) { 59866f2f8e5SJohnny Huang strcat(conf_parse[k].status, 59966f2f8e5SJohnny Huang "RSA3072"); 600442839bbSJohnny Huang } else { 60166f2f8e5SJohnny Huang strcat(conf_parse[k].status, 60266f2f8e5SJohnny Huang "RSA4096"); 60366f2f8e5SJohnny Huang } 60469d5fd8fSJohnny Huang } else { 60566f2f8e5SJohnny Huang strcpy(conf_parse[k].status, "Keep mask error!"); 60666f2f8e5SJohnny Huang return -1; 60769d5fd8fSJohnny Huang } 60866f2f8e5SJohnny Huang 60966f2f8e5SJohnny Huang k++; 61066f2f8e5SJohnny Huang conf_parse[k].dw_offset = 0; 61166f2f8e5SJohnny Huang conf_parse[k].bit = 12; 61266f2f8e5SJohnny Huang conf_parse[k].length = 2; 61366f2f8e5SJohnny Huang conf_parse[k].value = HASH_MODES(OTPCFG[0]); 614442839bbSJohnny Huang if (HASH_MODES(OTPCFG_KEEP[0]) == 0x3) { 61566f2f8e5SJohnny Huang conf_parse[k].keep = 1; 61666f2f8e5SJohnny Huang strcpy(conf_parse[k].status, "Skip"); 61766f2f8e5SJohnny Huang } else if (HASH_MODES(OTPCFG_KEEP[0]) == 0) { 61866f2f8e5SJohnny Huang strcpy(conf_parse[k].status, "SHA mode : "); 61966f2f8e5SJohnny Huang if (conf_parse[k].value == HASH_SAH224) { 62066f2f8e5SJohnny Huang strcat(conf_parse[k].status, 62166f2f8e5SJohnny Huang "SHA224"); 62266f2f8e5SJohnny Huang } else if (conf_parse[k].value == HASH_SAH256) { 62366f2f8e5SJohnny Huang strcat(conf_parse[k].status, 62466f2f8e5SJohnny Huang "SHA256"); 62566f2f8e5SJohnny Huang } else if (conf_parse[k].value == HASH_SAH384) { 62666f2f8e5SJohnny Huang strcat(conf_parse[k].status, 62766f2f8e5SJohnny Huang "SHA384"); 628442839bbSJohnny Huang } else { 62966f2f8e5SJohnny Huang strcat(conf_parse[k].status, 63066f2f8e5SJohnny Huang "SHA512"); 63169d5fd8fSJohnny Huang } 63266f2f8e5SJohnny Huang } else { 63366f2f8e5SJohnny Huang strcpy(conf_parse[k].status, "Keep mask error!"); 63466f2f8e5SJohnny Huang return -1; 635442839bbSJohnny Huang } 63669d5fd8fSJohnny Huang 63766f2f8e5SJohnny Huang k++; 63866f2f8e5SJohnny Huang conf_parse[k].dw_offset = 0; 63966f2f8e5SJohnny Huang conf_parse[k].bit = 16; 64066f2f8e5SJohnny Huang conf_parse[k].length = 6; 64166f2f8e5SJohnny Huang conf_parse[k].value = SECREG_SIZE(OTPCFG[0]); 642442839bbSJohnny Huang if (SECREG_SIZE(OTPCFG_KEEP[0]) == 0x3f) { 64366f2f8e5SJohnny Huang conf_parse[k].keep = 1; 64466f2f8e5SJohnny Huang strcpy(conf_parse[k].status, "Skip"); 64566f2f8e5SJohnny Huang } else if (SECREG_SIZE(OTPCFG_KEEP[0]) == 0) { 64666f2f8e5SJohnny Huang sprintf(conf_parse[k].status, 64766f2f8e5SJohnny Huang "Secure Region size (DW): 0x%x", SECREG_SIZE(OTPCFG[0])); 648442839bbSJohnny Huang } else { 64966f2f8e5SJohnny Huang strcpy(conf_parse[k].status, "Keep mask error!"); 65066f2f8e5SJohnny Huang return -1; 651442839bbSJohnny Huang } 65269d5fd8fSJohnny Huang 65366f2f8e5SJohnny Huang k++; 65466f2f8e5SJohnny Huang conf_parse[k].dw_offset = 0; 65566f2f8e5SJohnny Huang conf_parse[k].bit = 22; 65666f2f8e5SJohnny Huang conf_parse[k].length = 1; 65766f2f8e5SJohnny Huang conf_parse[k].value = WRITE_PROTECT_SECREG(OTPCFG[0]); 65866f2f8e5SJohnny Huang if (WRITE_PROTECT_SECREG(OTPCFG_KEEP[0])) { 65966f2f8e5SJohnny Huang conf_parse[k].keep = 1; 66066f2f8e5SJohnny Huang strcpy(conf_parse[k].status, "Skip"); 661442839bbSJohnny Huang } else { 66266f2f8e5SJohnny Huang if (WRITE_PROTECT_SECREG(OTPCFG[0])) 66366f2f8e5SJohnny Huang strcpy(conf_parse[k].status, 66466f2f8e5SJohnny Huang "Secure Region : Write Protect"); 66569d5fd8fSJohnny Huang else 66666f2f8e5SJohnny Huang strcpy(conf_parse[k].status, 66766f2f8e5SJohnny Huang "Secure Region : Writable"); 668442839bbSJohnny Huang } 669442839bbSJohnny Huang 67066f2f8e5SJohnny Huang k++; 67166f2f8e5SJohnny Huang conf_parse[k].dw_offset = 0; 67266f2f8e5SJohnny Huang conf_parse[k].bit = 23; 67366f2f8e5SJohnny Huang conf_parse[k].length = 1; 67466f2f8e5SJohnny Huang conf_parse[k].value = WRITE_PROTECT_USERREG(OTPCFG[0]); 67566f2f8e5SJohnny Huang if (WRITE_PROTECT_USERREG(OTPCFG_KEEP[0])) { 67666f2f8e5SJohnny Huang conf_parse[k].keep = 1; 67766f2f8e5SJohnny Huang strcpy(conf_parse[k].status, "Skip"); 678442839bbSJohnny Huang } else { 67966f2f8e5SJohnny Huang if (WRITE_PROTECT_USERREG(OTPCFG[0])) 68066f2f8e5SJohnny Huang strcpy(conf_parse[k].status, 68166f2f8e5SJohnny Huang "User Region : Write Protect"); 68269d5fd8fSJohnny Huang else 68366f2f8e5SJohnny Huang strcpy(conf_parse[k].status, 68466f2f8e5SJohnny Huang "User Region : Writable"); 685442839bbSJohnny Huang } 686442839bbSJohnny Huang 68766f2f8e5SJohnny Huang k++; 68866f2f8e5SJohnny Huang conf_parse[k].dw_offset = 0; 68966f2f8e5SJohnny Huang conf_parse[k].bit = 24; 69066f2f8e5SJohnny Huang conf_parse[k].length = 1; 69166f2f8e5SJohnny Huang conf_parse[k].value = WRITE_PROTECT_CONFREG(OTPCFG[0]); 69266f2f8e5SJohnny Huang if (WRITE_PROTECT_CONFREG(OTPCFG_KEEP[0])) { 69366f2f8e5SJohnny Huang conf_parse[k].keep = 1; 69466f2f8e5SJohnny Huang strcpy(conf_parse[k].status, "Skip"); 695442839bbSJohnny Huang } else { 69666f2f8e5SJohnny Huang if (WRITE_PROTECT_CONFREG(OTPCFG[0])) 69766f2f8e5SJohnny Huang strcpy(conf_parse[k].status, 69866f2f8e5SJohnny Huang "Configure Region : Write Protect"); 69969d5fd8fSJohnny Huang else 70066f2f8e5SJohnny Huang strcpy(conf_parse[k].status, 70166f2f8e5SJohnny Huang "Configure Region : Writable"); 702442839bbSJohnny Huang } 703442839bbSJohnny Huang 70466f2f8e5SJohnny Huang k++; 70566f2f8e5SJohnny Huang conf_parse[k].dw_offset = 0; 70666f2f8e5SJohnny Huang conf_parse[k].bit = 25; 70766f2f8e5SJohnny Huang conf_parse[k].length = 1; 70866f2f8e5SJohnny Huang conf_parse[k].value = WRITE_PROTECT_STRAPREG(OTPCFG[0]); 70966f2f8e5SJohnny Huang if (WRITE_PROTECT_STRAPREG(OTPCFG_KEEP[0])) { 71066f2f8e5SJohnny Huang conf_parse[k].keep = 1; 71166f2f8e5SJohnny Huang strcpy(conf_parse[k].status, "Skip"); 712442839bbSJohnny Huang } else { 71366f2f8e5SJohnny Huang if (WRITE_PROTECT_STRAPREG(OTPCFG[0])) 71466f2f8e5SJohnny Huang strcpy(conf_parse[k].status, 71566f2f8e5SJohnny Huang "OTP strap Region : Write Protect"); 71669d5fd8fSJohnny Huang else 71766f2f8e5SJohnny Huang strcpy(conf_parse[k].status, 71866f2f8e5SJohnny Huang "OTP strap Region : Writable"); 719442839bbSJohnny Huang } 720442839bbSJohnny Huang 72166f2f8e5SJohnny Huang k++; 72266f2f8e5SJohnny Huang conf_parse[k].dw_offset = 0; 72366f2f8e5SJohnny Huang conf_parse[k].bit = 26; 72466f2f8e5SJohnny Huang conf_parse[k].length = 1; 72566f2f8e5SJohnny Huang conf_parse[k].value = ENABLE_COPY_TO_SRAM(OTPCFG[0]); 72666f2f8e5SJohnny Huang if (ENABLE_COPY_TO_SRAM(OTPCFG_KEEP[0])) { 72766f2f8e5SJohnny Huang conf_parse[k].keep = 1; 72866f2f8e5SJohnny Huang strcpy(conf_parse[k].status, "Skip"); 729442839bbSJohnny Huang } else { 73066f2f8e5SJohnny Huang if (ENABLE_COPY_TO_SRAM(OTPCFG[0])) 73166f2f8e5SJohnny Huang strcpy(conf_parse[k].status, 73266f2f8e5SJohnny Huang "Copy Boot Image to Internal SRAM"); 73369d5fd8fSJohnny Huang else 73466f2f8e5SJohnny Huang strcpy(conf_parse[k].status, 73566f2f8e5SJohnny Huang "Disable Copy Boot Image to Internal SRAM"); 736442839bbSJohnny Huang } 73766f2f8e5SJohnny Huang 73866f2f8e5SJohnny Huang k++; 73966f2f8e5SJohnny Huang conf_parse[k].dw_offset = 0; 74066f2f8e5SJohnny Huang conf_parse[k].bit = 27; 74166f2f8e5SJohnny Huang conf_parse[k].length = 1; 74266f2f8e5SJohnny Huang conf_parse[k].value = ENABLE_IMAGE_ENC(OTPCFG[0]); 74366f2f8e5SJohnny Huang if (ENABLE_IMAGE_ENC(OTPCFG_KEEP[0])) { 74466f2f8e5SJohnny Huang conf_parse[k].keep = 1; 74566f2f8e5SJohnny Huang strcpy(conf_parse[k].status, "Skip"); 746442839bbSJohnny Huang } else { 74766f2f8e5SJohnny Huang if (ENABLE_IMAGE_ENC(OTPCFG[0])) 74866f2f8e5SJohnny Huang strcpy(conf_parse[k].status, 74966f2f8e5SJohnny Huang "Enable image encryption"); 75069d5fd8fSJohnny Huang else 75166f2f8e5SJohnny Huang strcpy(conf_parse[k].status, 75266f2f8e5SJohnny Huang "Disable image encryption"); 753442839bbSJohnny Huang } 754442839bbSJohnny Huang 75566f2f8e5SJohnny Huang k++; 75666f2f8e5SJohnny Huang conf_parse[k].dw_offset = 0; 75766f2f8e5SJohnny Huang conf_parse[k].bit = 29; 75866f2f8e5SJohnny Huang conf_parse[k].length = 1; 75966f2f8e5SJohnny Huang conf_parse[k].value = WRITE_PROTECT_KEY_RETIRE(OTPCFG[0]); 76066f2f8e5SJohnny Huang if (WRITE_PROTECT_KEY_RETIRE(OTPCFG_KEEP[0])) { 76166f2f8e5SJohnny Huang conf_parse[k].keep = 1; 76266f2f8e5SJohnny Huang strcpy(conf_parse[k].status, "Skip"); 763442839bbSJohnny Huang } else { 76466f2f8e5SJohnny Huang if (WRITE_PROTECT_KEY_RETIRE(OTPCFG[0])) 76566f2f8e5SJohnny Huang strcpy(conf_parse[k].status, 76666f2f8e5SJohnny Huang "OTP key retire Region : Write Protect"); 76769d5fd8fSJohnny Huang else 76866f2f8e5SJohnny Huang strcpy(conf_parse[k].status, 76966f2f8e5SJohnny Huang "OTP key retire Region : Writable"); 770442839bbSJohnny Huang } 771442839bbSJohnny Huang 77266f2f8e5SJohnny Huang k++; 77366f2f8e5SJohnny Huang conf_parse[k].dw_offset = 0; 77466f2f8e5SJohnny Huang conf_parse[k].bit = 30; 77566f2f8e5SJohnny Huang conf_parse[k].length = 1; 77666f2f8e5SJohnny Huang conf_parse[k].value = ENABLE_SIPROM_RED(OTPCFG[0]); 77766f2f8e5SJohnny Huang if (ENABLE_SIPROM_RED(OTPCFG_KEEP[0])) { 77866f2f8e5SJohnny Huang conf_parse[k].keep = 1; 77966f2f8e5SJohnny Huang strcpy(conf_parse[k].status, "Skip"); 780442839bbSJohnny Huang } else { 78166f2f8e5SJohnny Huang if (ENABLE_SIPROM_RED(OTPCFG[0])) 78266f2f8e5SJohnny Huang strcpy(conf_parse[k].status, 78366f2f8e5SJohnny Huang "SIPROM RED_EN redundancy repair enable"); 78469d5fd8fSJohnny Huang else 78566f2f8e5SJohnny Huang strcpy(conf_parse[k].status, 78666f2f8e5SJohnny Huang "SIPROM RED_EN redundancy repair disable"); 787442839bbSJohnny Huang } 788442839bbSJohnny Huang 78966f2f8e5SJohnny Huang k++; 79066f2f8e5SJohnny Huang conf_parse[k].dw_offset = 0; 79166f2f8e5SJohnny Huang conf_parse[k].bit = 31; 79266f2f8e5SJohnny Huang conf_parse[k].length = 1; 79366f2f8e5SJohnny Huang conf_parse[k].value = ENABLE_SIPROM_MLOCK(OTPCFG[0]); 79466f2f8e5SJohnny Huang if (ENABLE_SIPROM_MLOCK(OTPCFG_KEEP[0])) { 79566f2f8e5SJohnny Huang conf_parse[k].keep = 1; 79666f2f8e5SJohnny Huang strcpy(conf_parse[k].status, "Skip"); 797442839bbSJohnny Huang } else { 79866f2f8e5SJohnny Huang if (ENABLE_SIPROM_MLOCK(OTPCFG[0])) 79966f2f8e5SJohnny Huang strcpy(conf_parse[k].status, 80066f2f8e5SJohnny Huang "SIPROM Mlock memory lock enable"); 80169d5fd8fSJohnny Huang else 80266f2f8e5SJohnny Huang strcpy(conf_parse[k].status, 80366f2f8e5SJohnny Huang "SIPROM Mlock memory lock disable"); 804442839bbSJohnny Huang } 80569d5fd8fSJohnny Huang 80666f2f8e5SJohnny Huang k++; 80766f2f8e5SJohnny Huang conf_parse[k].dw_offset = 2; 80866f2f8e5SJohnny Huang conf_parse[k].bit = 0; 80966f2f8e5SJohnny Huang conf_parse[k].length = 16; 81066f2f8e5SJohnny Huang conf_parse[k].value = VENDER_ID(OTPCFG[2]); 81166f2f8e5SJohnny Huang if (VENDER_ID(OTPCFG_KEEP[2]) == 0xffff) { 81266f2f8e5SJohnny Huang conf_parse[k].keep = 1; 81366f2f8e5SJohnny Huang strcpy(conf_parse[k].status, "Skip"); 81466f2f8e5SJohnny Huang } else if (VENDER_ID(OTPCFG_KEEP[2]) == 0) { 81566f2f8e5SJohnny Huang sprintf(conf_parse[k].status, 81666f2f8e5SJohnny Huang "Vender ID : 0x%x", VENDER_ID(OTPCFG[2])); 817442839bbSJohnny Huang } else { 81866f2f8e5SJohnny Huang strcpy(conf_parse[k].status, "Keep mask error!"); 81966f2f8e5SJohnny Huang return -1; 820442839bbSJohnny Huang } 82169d5fd8fSJohnny Huang 82266f2f8e5SJohnny Huang k++; 82366f2f8e5SJohnny Huang conf_parse[k].dw_offset = 2; 82466f2f8e5SJohnny Huang conf_parse[k].bit = 16; 82566f2f8e5SJohnny Huang conf_parse[k].length = 16; 82666f2f8e5SJohnny Huang conf_parse[k].value = KEY_REVISION(OTPCFG[2]); 82766f2f8e5SJohnny Huang if (KEY_REVISION(OTPCFG_KEEP[2]) == 0xffff) { 82866f2f8e5SJohnny Huang conf_parse[k].keep = 1; 82966f2f8e5SJohnny Huang strcpy(conf_parse[k].status, "Skip"); 83066f2f8e5SJohnny Huang } else if (KEY_REVISION(OTPCFG_KEEP[2]) == 0) { 83166f2f8e5SJohnny Huang sprintf(conf_parse[k].status, 83266f2f8e5SJohnny Huang "Key Revision : 0x%x", KEY_REVISION(OTPCFG[2])); 833442839bbSJohnny Huang } else { 83466f2f8e5SJohnny Huang strcpy(conf_parse[k].status, "Keep mask error!"); 83566f2f8e5SJohnny Huang return -1; 83666f2f8e5SJohnny Huang } 83766f2f8e5SJohnny Huang 83866f2f8e5SJohnny Huang k++; 83966f2f8e5SJohnny Huang conf_parse[k].dw_offset = 3; 84066f2f8e5SJohnny Huang conf_parse[k].bit = 0; 84166f2f8e5SJohnny Huang conf_parse[k].length = 16; 84266f2f8e5SJohnny Huang conf_parse[k].value = SEC_BOOT_HEADER_OFFSET(OTPCFG[3]); 84366f2f8e5SJohnny Huang if (SEC_BOOT_HEADER_OFFSET(OTPCFG_KEEP[3]) == 0xffff) { 84466f2f8e5SJohnny Huang conf_parse[k].keep = 1; 84566f2f8e5SJohnny Huang strcpy(conf_parse[k].status, "Skip"); 84666f2f8e5SJohnny Huang } else if (SEC_BOOT_HEADER_OFFSET(OTPCFG_KEEP[3]) == 0) { 84766f2f8e5SJohnny Huang sprintf(conf_parse[k].status, 84866f2f8e5SJohnny Huang "Secure boot header offset : 0x%x", 849e1f9e54eSJohnny Huang SEC_BOOT_HEADER_OFFSET(OTPCFG[3])); 85066f2f8e5SJohnny Huang } else { 85166f2f8e5SJohnny Huang strcpy(conf_parse[k].status, "Keep mask error!"); 85266f2f8e5SJohnny Huang return -1; 853442839bbSJohnny Huang } 85469d5fd8fSJohnny Huang 85566f2f8e5SJohnny Huang k++; 85666f2f8e5SJohnny Huang conf_parse[k].dw_offset = 4; 85766f2f8e5SJohnny Huang conf_parse[k].bit = 0; 85866f2f8e5SJohnny Huang conf_parse[k].length = 8; 85966f2f8e5SJohnny Huang conf_parse[k].value = KEYS_VALID_BITS(OTPCFG[4]); 86066f2f8e5SJohnny Huang if (KEYS_VALID_BITS(OTPCFG_KEEP[4]) == 0xff) { 86166f2f8e5SJohnny Huang conf_parse[k].keep = 1; 86266f2f8e5SJohnny Huang strcpy(conf_parse[k].status, "Skip"); 86366f2f8e5SJohnny Huang } else if (KEYS_VALID_BITS(OTPCFG_KEEP[4]) == 0) { 864e1f9e54eSJohnny Huang tmp = KEYS_VALID_BITS(OTPCFG[4]); 865e1f9e54eSJohnny Huang if (tmp != 0) { 86669d5fd8fSJohnny Huang for (i = 0; i < 7; i++) { 86769d5fd8fSJohnny Huang if (tmp == (1 << i)) { 868e1f9e54eSJohnny Huang pass = i + 1; 86969d5fd8fSJohnny Huang } 87069d5fd8fSJohnny Huang } 871e1f9e54eSJohnny Huang } else { 872e1f9e54eSJohnny Huang pass = 0; 873e1f9e54eSJohnny Huang } 87466f2f8e5SJohnny Huang sprintf(conf_parse[k].status, 87566f2f8e5SJohnny Huang "Keys valid : %d", pass); 876442839bbSJohnny Huang } else { 87766f2f8e5SJohnny Huang strcpy(conf_parse[k].status, "Keep mask error!"); 87866f2f8e5SJohnny Huang return -1; 87966f2f8e5SJohnny Huang } 88066f2f8e5SJohnny Huang 88166f2f8e5SJohnny Huang k++; 88266f2f8e5SJohnny Huang conf_parse[k].dw_offset = 4; 88366f2f8e5SJohnny Huang conf_parse[k].bit = 16; 88466f2f8e5SJohnny Huang conf_parse[k].length = 8; 88566f2f8e5SJohnny Huang conf_parse[k].value = KEYS_RETIRE_BITS(OTPCFG[4]); 88666f2f8e5SJohnny Huang if (KEYS_RETIRE_BITS(OTPCFG_KEEP[4]) == 0xff) { 88766f2f8e5SJohnny Huang conf_parse[k].keep = 1; 88866f2f8e5SJohnny Huang strcpy(conf_parse[k].status, "Skip"); 88966f2f8e5SJohnny Huang } else if (KEYS_RETIRE_BITS(OTPCFG_KEEP[4]) == 0) { 890e1f9e54eSJohnny Huang tmp = KEYS_RETIRE_BITS(OTPCFG[4]); 891e1f9e54eSJohnny Huang if (tmp != 0) { 89269d5fd8fSJohnny Huang for (i = 0; i < 7; i++) { 89369d5fd8fSJohnny Huang if (tmp == (1 << i)) { 894e1f9e54eSJohnny Huang pass = i + 1; 89569d5fd8fSJohnny Huang } 89669d5fd8fSJohnny Huang } 897e1f9e54eSJohnny Huang } else { 898e1f9e54eSJohnny Huang pass = 0; 89969d5fd8fSJohnny Huang } 90066f2f8e5SJohnny Huang sprintf(conf_parse[k].status, 90166f2f8e5SJohnny Huang "Keys Retire ID : %d", pass); 90266f2f8e5SJohnny Huang } else { 90366f2f8e5SJohnny Huang strcpy(conf_parse[k].status, "Keep mask error!"); 90466f2f8e5SJohnny Huang return -1; 905442839bbSJohnny Huang } 90666f2f8e5SJohnny Huang 90766f2f8e5SJohnny Huang k++; 90866f2f8e5SJohnny Huang conf_parse[k].dw_offset = 5; 90966f2f8e5SJohnny Huang conf_parse[k].bit = 0; 91066f2f8e5SJohnny Huang conf_parse[k].length = 32; 91166f2f8e5SJohnny Huang conf_parse[k].value = OTPCFG[5]; 912442839bbSJohnny Huang if (OTPCFG_KEEP[5] == 0xFFFFFFFF) { 91366f2f8e5SJohnny Huang conf_parse[k].keep = 1; 91466f2f8e5SJohnny Huang strcpy(conf_parse[k].status, "Skip"); 91566f2f8e5SJohnny Huang } else if (OTPCFG_KEEP[5] == 0) { 91666f2f8e5SJohnny Huang sprintf(conf_parse[k].status, 91766f2f8e5SJohnny Huang "User define data, random number low : 0x%x", OTPCFG[5]); 918442839bbSJohnny Huang } else { 91966f2f8e5SJohnny Huang strcpy(conf_parse[k].status, "Keep mask error!"); 92066f2f8e5SJohnny Huang return -1; 921442839bbSJohnny Huang } 92269d5fd8fSJohnny Huang 92366f2f8e5SJohnny Huang k++; 92466f2f8e5SJohnny Huang conf_parse[k].dw_offset = 6; 92566f2f8e5SJohnny Huang conf_parse[k].bit = 0; 92666f2f8e5SJohnny Huang conf_parse[k].length = 32; 92766f2f8e5SJohnny Huang conf_parse[k].value = OTPCFG[6]; 928442839bbSJohnny Huang if (OTPCFG_KEEP[6] == 0xFFFFFFFF) { 92966f2f8e5SJohnny Huang conf_parse[k].keep = 1; 93066f2f8e5SJohnny Huang strcpy(conf_parse[k].status, "Skip"); 93166f2f8e5SJohnny Huang } else if (OTPCFG_KEEP[6] == 0) { 93266f2f8e5SJohnny Huang sprintf(conf_parse[k].status, 93366f2f8e5SJohnny Huang "User define data, random number high : 0x%x", OTPCFG[6]); 934442839bbSJohnny Huang } else { 93566f2f8e5SJohnny Huang strcpy(conf_parse[k].status, "Keep mask error!"); 93666f2f8e5SJohnny Huang return -1; 937442839bbSJohnny Huang } 93869d5fd8fSJohnny Huang 93966f2f8e5SJohnny Huang k++; 94066f2f8e5SJohnny Huang conf_parse[k].dw_offset = 8; 94166f2f8e5SJohnny Huang conf_parse[k].bit = 0; 94266f2f8e5SJohnny Huang conf_parse[k].length = 32; 94366f2f8e5SJohnny Huang conf_parse[k].value = OTPCFG[8]; 944442839bbSJohnny Huang if (OTPCFG_KEEP[8] == 0xFFFFFFFF) { 94566f2f8e5SJohnny Huang conf_parse[k].keep = 1; 94666f2f8e5SJohnny Huang strcpy(conf_parse[k].status, "Skip"); 94766f2f8e5SJohnny Huang } else if (OTPCFG_KEEP[8] == 0) { 94866f2f8e5SJohnny Huang sprintf(conf_parse[k].status, 94966f2f8e5SJohnny Huang "Redundancy Repair : 0x%x", OTPCFG[8]); 950442839bbSJohnny Huang } else { 95166f2f8e5SJohnny Huang strcpy(conf_parse[k].status, "Keep mask error!"); 95266f2f8e5SJohnny Huang return -1; 953442839bbSJohnny Huang } 95469d5fd8fSJohnny Huang 95566f2f8e5SJohnny Huang k++; 95666f2f8e5SJohnny Huang conf_parse[k].dw_offset = 10; 95766f2f8e5SJohnny Huang conf_parse[k].bit = 0; 95866f2f8e5SJohnny Huang conf_parse[k].length = 32; 95966f2f8e5SJohnny Huang conf_parse[k].value = OTPCFG[10]; 960442839bbSJohnny Huang if (OTPCFG_KEEP[10] == 0xFFFFFFFF) { 96166f2f8e5SJohnny Huang conf_parse[k].keep = 1; 96266f2f8e5SJohnny Huang strcpy(conf_parse[k].status, "Skip"); 96366f2f8e5SJohnny Huang } else if (OTPCFG_KEEP[10] == 0) { 96466f2f8e5SJohnny Huang sprintf(conf_parse[k].status, 96566f2f8e5SJohnny Huang "Manifest ID low : 0x%x", OTPCFG[10]); 966442839bbSJohnny Huang } else { 96766f2f8e5SJohnny Huang strcpy(conf_parse[k].status, "Keep mask error!"); 96866f2f8e5SJohnny Huang return -1; 969442839bbSJohnny Huang } 97069d5fd8fSJohnny Huang 97166f2f8e5SJohnny Huang k++; 97266f2f8e5SJohnny Huang conf_parse[k].dw_offset = 11; 97366f2f8e5SJohnny Huang conf_parse[k].bit = 0; 97466f2f8e5SJohnny Huang conf_parse[k].length = 32; 97566f2f8e5SJohnny Huang conf_parse[k].value = OTPCFG[11]; 976442839bbSJohnny Huang if (OTPCFG_KEEP[11] == 0xFFFFFFFF) { 97766f2f8e5SJohnny Huang conf_parse[k].keep = 1; 97866f2f8e5SJohnny Huang strcpy(conf_parse[k].status, "Skip"); 97966f2f8e5SJohnny Huang } else if (OTPCFG_KEEP[11] == 0) { 98066f2f8e5SJohnny Huang sprintf(conf_parse[k].status, 98166f2f8e5SJohnny Huang "Manifest ID high : 0x%x", OTPCFG[11]); 982442839bbSJohnny Huang } else { 98366f2f8e5SJohnny Huang strcpy(conf_parse[k].status, "Keep mask error!"); 98466f2f8e5SJohnny Huang return -1; 985442839bbSJohnny Huang } 986442839bbSJohnny Huang 98766f2f8e5SJohnny Huang return k + 1; 98869d5fd8fSJohnny Huang 98969d5fd8fSJohnny Huang } 99069d5fd8fSJohnny Huang 99176d13988SJohnny Huang static int otp_strap_parse(uint32_t *OTPSTRAP, 99276d13988SJohnny Huang struct otpstrap_parse *strap_parse) 99376d13988SJohnny Huang { 99476d13988SJohnny Huang int k = 0; 99576d13988SJohnny Huang uint32_t *OTPSTRAP_KEEP = &OTPSTRAP[2]; 99676d13988SJohnny Huang uint32_t *OTPSTRAP_PRO = &OTPSTRAP[4]; 99776d13988SJohnny Huang 99876d13988SJohnny Huang strap_parse[k].bit = 0; 99976d13988SJohnny Huang strap_parse[k].length = 1; 100076d13988SJohnny Huang strap_parse[k].value = ENABLE_SECURE_BOOT(OTPSTRAP[0]); 100176d13988SJohnny Huang strap_parse[k].protect = ENABLE_SECURE_BOOT(OTPSTRAP_PRO[0]); 100276d13988SJohnny Huang if (ENABLE_SECURE_BOOT(OTPSTRAP_KEEP[0])) { 100376d13988SJohnny Huang strap_parse[k].keep = 1; 100476d13988SJohnny Huang strcpy(strap_parse[k].status, "Skip"); 100576d13988SJohnny Huang } else { 100676d13988SJohnny Huang if (ENABLE_SECURE_BOOT(OTPSTRAP[0])) 100776d13988SJohnny Huang strcpy(strap_parse[k].status, 100876d13988SJohnny Huang "Enable secure boot"); 100976d13988SJohnny Huang else 101076d13988SJohnny Huang strcpy(strap_parse[k].status, 101176d13988SJohnny Huang "Disable secure boot"); 101276d13988SJohnny Huang } 101376d13988SJohnny Huang 101476d13988SJohnny Huang k++; 101576d13988SJohnny Huang strap_parse[k].bit = 1; 101676d13988SJohnny Huang strap_parse[k].length = 1; 101776d13988SJohnny Huang strap_parse[k].value = BOOT_FROM_EMMC(OTPSTRAP[0]); 101876d13988SJohnny Huang strap_parse[k].protect = BOOT_FROM_EMMC(OTPSTRAP_PRO[0]); 101976d13988SJohnny Huang if (BOOT_FROM_EMMC(OTPSTRAP_KEEP[0])) { 102076d13988SJohnny Huang strap_parse[k].keep = 1; 102176d13988SJohnny Huang strcpy(strap_parse[k].status, "Skip"); 102276d13988SJohnny Huang } else { 102376d13988SJohnny Huang if (BOOT_FROM_EMMC(OTPSTRAP[0])) 102476d13988SJohnny Huang strcpy(strap_parse[k].status, 102576d13988SJohnny Huang "Enable boot from eMMC"); 102676d13988SJohnny Huang else 102776d13988SJohnny Huang strcpy(strap_parse[k].status, 102876d13988SJohnny Huang "Disable boot from eMMC"); 102976d13988SJohnny Huang } 103076d13988SJohnny Huang 103176d13988SJohnny Huang k++; 103276d13988SJohnny Huang strap_parse[k].bit = 2; 103376d13988SJohnny Huang strap_parse[k].length = 1; 103476d13988SJohnny Huang strap_parse[k].value = BOOT_FROM_DEBUG_SPI(OTPSTRAP[0]); 103576d13988SJohnny Huang strap_parse[k].protect = BOOT_FROM_DEBUG_SPI(OTPSTRAP_PRO[0]); 103676d13988SJohnny Huang if (BOOT_FROM_DEBUG_SPI(OTPSTRAP_KEEP[0])) { 103776d13988SJohnny Huang strap_parse[k].keep = 1; 103876d13988SJohnny Huang strcpy(strap_parse[k].status, "Skip"); 103976d13988SJohnny Huang } else { 104076d13988SJohnny Huang if (BOOT_FROM_DEBUG_SPI(OTPSTRAP[0])) 104176d13988SJohnny Huang strcpy(strap_parse[k].status, 104276d13988SJohnny Huang "Enable Boot from debug SPI"); 104376d13988SJohnny Huang else 104476d13988SJohnny Huang strcpy(strap_parse[k].status, 104576d13988SJohnny Huang "Disable Boot from debug SPI"); 104676d13988SJohnny Huang } 104776d13988SJohnny Huang 104876d13988SJohnny Huang k++; 104976d13988SJohnny Huang strap_parse[k].bit = 3; 105076d13988SJohnny Huang strap_parse[k].length = 1; 105176d13988SJohnny Huang strap_parse[k].value = DISABLE_ARM_CM3(OTPSTRAP[0]); 105276d13988SJohnny Huang strap_parse[k].protect = DISABLE_ARM_CM3(OTPSTRAP_PRO[0]); 105376d13988SJohnny Huang if (DISABLE_ARM_CM3(OTPSTRAP_KEEP[0])) { 105476d13988SJohnny Huang strap_parse[k].keep = 1; 105576d13988SJohnny Huang strcpy(strap_parse[k].status, "Skip"); 105676d13988SJohnny Huang } else { 105776d13988SJohnny Huang if (DISABLE_ARM_CM3(OTPSTRAP[0])) 105876d13988SJohnny Huang strcpy(strap_parse[k].status, 105976d13988SJohnny Huang "Disable ARM CM3"); 106076d13988SJohnny Huang else 106176d13988SJohnny Huang strcpy(strap_parse[k].status, 106276d13988SJohnny Huang "Enable ARM CM3"); 106376d13988SJohnny Huang } 106476d13988SJohnny Huang 106576d13988SJohnny Huang k++; 106676d13988SJohnny Huang strap_parse[k].bit = 4; 106776d13988SJohnny Huang strap_parse[k].length = 1; 106876d13988SJohnny Huang strap_parse[k].value = VGA_EXPANSION_ROM(OTPSTRAP[0]); 106976d13988SJohnny Huang strap_parse[k].protect = VGA_EXPANSION_ROM(OTPSTRAP_PRO[0]); 107076d13988SJohnny Huang if (VGA_EXPANSION_ROM(OTPSTRAP_KEEP[0])) { 107176d13988SJohnny Huang strap_parse[k].keep = 1; 107276d13988SJohnny Huang strcpy(strap_parse[k].status, "Skip"); 107376d13988SJohnny Huang } else { 107476d13988SJohnny Huang if (VGA_EXPANSION_ROM(OTPSTRAP[0])) 107576d13988SJohnny Huang strcpy(strap_parse[k].status, 107676d13988SJohnny Huang "Enable dedicated VGA BIOS ROM"); 107776d13988SJohnny Huang else 107876d13988SJohnny Huang strcpy(strap_parse[k].status, 107976d13988SJohnny Huang "No VGA BISO ROM, VGA BIOS is merged in the system BIOS"); 108076d13988SJohnny Huang } 108176d13988SJohnny Huang 108276d13988SJohnny Huang k++; 108376d13988SJohnny Huang strap_parse[k].bit = 5; 108476d13988SJohnny Huang strap_parse[k].length = 1; 108576d13988SJohnny Huang strap_parse[k].value = MAC1_RMII_MODE(OTPSTRAP[0]); 108676d13988SJohnny Huang strap_parse[k].protect = MAC1_RMII_MODE(OTPSTRAP_PRO[0]); 108776d13988SJohnny Huang if (MAC1_RMII_MODE(OTPSTRAP_KEEP[0])) { 108876d13988SJohnny Huang strap_parse[k].keep = 1; 108976d13988SJohnny Huang strcpy(strap_parse[k].status, "Skip"); 109076d13988SJohnny Huang } else { 109176d13988SJohnny Huang if (MAC1_RMII_MODE(OTPSTRAP[0])) 109276d13988SJohnny Huang strcpy(strap_parse[k].status, 109376d13988SJohnny Huang "MAC 1 : RGMII"); 109476d13988SJohnny Huang else 109576d13988SJohnny Huang strcpy(strap_parse[k].status, 109676d13988SJohnny Huang "MAC 1 : RMII/NCSI"); 109776d13988SJohnny Huang } 109876d13988SJohnny Huang 109976d13988SJohnny Huang k++; 110076d13988SJohnny Huang strap_parse[k].bit = 6; 110176d13988SJohnny Huang strap_parse[k].length = 1; 110276d13988SJohnny Huang strap_parse[k].value = MAC2_RMII_MODE(OTPSTRAP[0]); 110376d13988SJohnny Huang strap_parse[k].protect = MAC2_RMII_MODE(OTPSTRAP_PRO[0]); 110476d13988SJohnny Huang if (MAC2_RMII_MODE(OTPSTRAP_KEEP[0])) { 110576d13988SJohnny Huang strap_parse[k].keep = 1; 110676d13988SJohnny Huang strcpy(strap_parse[k].status, "Skip"); 110776d13988SJohnny Huang } else { 110876d13988SJohnny Huang if (MAC2_RMII_MODE(OTPSTRAP[0])) 110976d13988SJohnny Huang strcpy(strap_parse[k].status, 111076d13988SJohnny Huang "MAC 2 : RGMII"); 111176d13988SJohnny Huang else 111276d13988SJohnny Huang strcpy(strap_parse[k].status, 111376d13988SJohnny Huang "MAC 2 : RMII/NCSI"); 111476d13988SJohnny Huang } 111576d13988SJohnny Huang 111676d13988SJohnny Huang k++; 111776d13988SJohnny Huang strap_parse[k].bit = 7; 111876d13988SJohnny Huang strap_parse[k].length = 3; 111976d13988SJohnny Huang strap_parse[k].value = CPU_FREQUENCY(OTPSTRAP[0]); 112076d13988SJohnny Huang strap_parse[k].protect = CPU_FREQUENCY(OTPSTRAP_PRO[0]); 112176d13988SJohnny Huang if (CPU_FREQUENCY(OTPSTRAP_KEEP[0]) == 0x7) { 112276d13988SJohnny Huang strap_parse[k].keep = 1; 112376d13988SJohnny Huang strcpy(strap_parse[k].status, "Skip"); 112476d13988SJohnny Huang } else if (CPU_FREQUENCY(OTPSTRAP_KEEP[0]) == 0) { 112576d13988SJohnny Huang if (CPU_FREQUENCY(OTPSTRAP[0]) == 0) { 112676d13988SJohnny Huang strcpy(strap_parse[k].status, 112776d13988SJohnny Huang "CPU Frequency : 1GHz"); 112876d13988SJohnny Huang } else if (CPU_FREQUENCY(OTPSTRAP[0]) == 1) { 112976d13988SJohnny Huang strcpy(strap_parse[k].status, 113076d13988SJohnny Huang "CPU Frequency : 800MHz"); 113176d13988SJohnny Huang } else if (CPU_FREQUENCY(OTPSTRAP[0]) == 2) { 113276d13988SJohnny Huang strcpy(strap_parse[k].status, 113376d13988SJohnny Huang "CPU Frequency : 1.2GHz"); 113476d13988SJohnny Huang } else if (CPU_FREQUENCY(OTPSTRAP[0]) == 3) { 113576d13988SJohnny Huang strcpy(strap_parse[k].status, 113676d13988SJohnny Huang "CPU Frequency : 1.4GHz"); 113776d13988SJohnny Huang } else { 113876d13988SJohnny Huang strcpy(strap_parse[k].status, 113976d13988SJohnny Huang "CPU Frequency : error"); 114076d13988SJohnny Huang return -1; 114176d13988SJohnny Huang } 114276d13988SJohnny Huang } else { 114376d13988SJohnny Huang strcpy(strap_parse[k].status, "Keep mask error!"); 114476d13988SJohnny Huang return -1; 114576d13988SJohnny Huang } 114676d13988SJohnny Huang 114776d13988SJohnny Huang k++; 114876d13988SJohnny Huang strap_parse[k].bit = 10; 114976d13988SJohnny Huang strap_parse[k].length = 2; 115076d13988SJohnny Huang strap_parse[k].value = HCLK_RATIO(OTPSTRAP[0]); 115176d13988SJohnny Huang strap_parse[k].protect = HCLK_RATIO(OTPSTRAP_PRO[0]); 115276d13988SJohnny Huang if (HCLK_RATIO(OTPSTRAP_KEEP[0]) == 0x3) { 115376d13988SJohnny Huang strap_parse[k].keep = 1; 115476d13988SJohnny Huang strcpy(strap_parse[k].status, "Skip"); 115576d13988SJohnny Huang } else if (HCLK_RATIO(OTPSTRAP_KEEP[0]) == 0) { 115676d13988SJohnny Huang if (HCLK_RATIO(OTPSTRAP[0]) == 0) { 115776d13988SJohnny Huang strcpy(strap_parse[k].status, 115876d13988SJohnny Huang "HCLK ratio AXI:AHB = 2:1"); 115976d13988SJohnny Huang } else if (HCLK_RATIO(OTPSTRAP[0]) == 1) { 116076d13988SJohnny Huang strcpy(strap_parse[k].status, 116176d13988SJohnny Huang "HCLK ratio AXI:AHB = 2:1"); 116276d13988SJohnny Huang } else if (HCLK_RATIO(OTPSTRAP[0]) == 2) { 116376d13988SJohnny Huang strcpy(strap_parse[k].status, 116476d13988SJohnny Huang "HCLK ratio AXI:AHB = 3:1"); 116576d13988SJohnny Huang } else if (HCLK_RATIO(OTPSTRAP[0]) == 3) { 116676d13988SJohnny Huang strcpy(strap_parse[k].status, 116776d13988SJohnny Huang "HCLK ratio AXI:AHB = 4:1"); 116876d13988SJohnny Huang } 116976d13988SJohnny Huang } else { 117076d13988SJohnny Huang strcpy(strap_parse[k].status, "Keep mask error!"); 117176d13988SJohnny Huang return -1; 117276d13988SJohnny Huang } 117376d13988SJohnny Huang 117476d13988SJohnny Huang k++; 117576d13988SJohnny Huang strap_parse[k].bit = 12; 117676d13988SJohnny Huang strap_parse[k].length = 2; 117776d13988SJohnny Huang strap_parse[k].value = VGA_MEMORY_SIZE(OTPSTRAP[0]); 117876d13988SJohnny Huang strap_parse[k].protect = VGA_MEMORY_SIZE(OTPSTRAP_PRO[0]); 117976d13988SJohnny Huang if (VGA_MEMORY_SIZE(OTPSTRAP_KEEP[0]) == 0x3) { 118076d13988SJohnny Huang strap_parse[k].keep = 1; 118176d13988SJohnny Huang strcpy(strap_parse[k].status, "Skip"); 118276d13988SJohnny Huang } else if (VGA_MEMORY_SIZE(OTPSTRAP_KEEP[0]) == 0) { 118376d13988SJohnny Huang if (VGA_MEMORY_SIZE(OTPSTRAP[0]) == 0) { 118476d13988SJohnny Huang strcpy(strap_parse[k].status, 118576d13988SJohnny Huang "VGA memory size : 8MB"); 118676d13988SJohnny Huang } else if (VGA_MEMORY_SIZE(OTPSTRAP[0]) == 1) { 118776d13988SJohnny Huang strcpy(strap_parse[k].status, 118876d13988SJohnny Huang "VGA memory size : 16MB"); 118976d13988SJohnny Huang } else if (VGA_MEMORY_SIZE(OTPSTRAP[0]) == 2) { 119076d13988SJohnny Huang strcpy(strap_parse[k].status, 119176d13988SJohnny Huang "VGA memory size : 32MB"); 119276d13988SJohnny Huang } else if (VGA_MEMORY_SIZE(OTPSTRAP[0]) == 3) { 119376d13988SJohnny Huang strcpy(strap_parse[k].status, 119476d13988SJohnny Huang "VGA memory size : 64MB"); 119576d13988SJohnny Huang } 119676d13988SJohnny Huang } else { 119776d13988SJohnny Huang strcpy(strap_parse[k].status, "Keep mask error!"); 119876d13988SJohnny Huang return -1; 119976d13988SJohnny Huang } 120076d13988SJohnny Huang 120176d13988SJohnny Huang k++; 120276d13988SJohnny Huang strap_parse[k].bit = 17; 120376d13988SJohnny Huang strap_parse[k].length = 1; 120476d13988SJohnny Huang strap_parse[k].value = VGA_CLASS_CODE(OTPSTRAP[0]); 120576d13988SJohnny Huang strap_parse[k].protect = VGA_CLASS_CODE(OTPSTRAP_PRO[0]); 120676d13988SJohnny Huang if (VGA_CLASS_CODE(OTPSTRAP_KEEP[0])) { 120776d13988SJohnny Huang strap_parse[k].keep = 1; 120876d13988SJohnny Huang strcpy(strap_parse[k].status, "Skip"); 120976d13988SJohnny Huang } else { 121076d13988SJohnny Huang if (VGA_CLASS_CODE(OTPSTRAP[0])) 121176d13988SJohnny Huang strcpy(strap_parse[k].status, 121276d13988SJohnny Huang "VGA class code : Class Code for VGA device"); 121376d13988SJohnny Huang else 121476d13988SJohnny Huang strcpy(strap_parse[k].status, 121576d13988SJohnny Huang "VGA class code : Class Code for video device"); 121676d13988SJohnny Huang } 121776d13988SJohnny Huang 121876d13988SJohnny Huang k++; 121976d13988SJohnny Huang strap_parse[k].bit = 18; 122076d13988SJohnny Huang strap_parse[k].length = 1; 122176d13988SJohnny Huang strap_parse[k].value = DISABLE_DEBUG0(OTPSTRAP[0]); 122276d13988SJohnny Huang strap_parse[k].protect = DISABLE_DEBUG0(OTPSTRAP_PRO[0]); 122376d13988SJohnny Huang if (DISABLE_DEBUG0(OTPSTRAP_KEEP[0])) { 122476d13988SJohnny Huang strap_parse[k].keep = 1; 122576d13988SJohnny Huang strcpy(strap_parse[k].status, "Skip"); 122676d13988SJohnny Huang } else { 122776d13988SJohnny Huang if (DISABLE_DEBUG0(OTPSTRAP[0])) 122876d13988SJohnny Huang strcpy(strap_parse[k].status, 122976d13988SJohnny Huang "Disable debug interfaces 0"); 123076d13988SJohnny Huang else 123176d13988SJohnny Huang strcpy(strap_parse[k].status, 123276d13988SJohnny Huang "Enable debug interfaces 0"); 123376d13988SJohnny Huang } 123476d13988SJohnny Huang 123576d13988SJohnny Huang k++; 123676d13988SJohnny Huang strap_parse[k].bit = 19; 123776d13988SJohnny Huang strap_parse[k].length = 1; 123876d13988SJohnny Huang strap_parse[k].value = BOOT_FROM_EMMC_SPEED_MDOE(OTPSTRAP[0]); 123976d13988SJohnny Huang strap_parse[k].protect = BOOT_FROM_EMMC_SPEED_MDOE(OTPSTRAP_PRO[0]); 124076d13988SJohnny Huang if (BOOT_FROM_EMMC_SPEED_MDOE(OTPSTRAP_KEEP[0])) { 124176d13988SJohnny Huang strap_parse[k].keep = 1; 124276d13988SJohnny Huang strcpy(strap_parse[k].status, "Skip"); 124376d13988SJohnny Huang } else { 124476d13988SJohnny Huang if (BOOT_FROM_EMMC_SPEED_MDOE(OTPSTRAP[0])) 124576d13988SJohnny Huang strcpy(strap_parse[k].status, 124676d13988SJohnny Huang "Boot from emmc mode : Normal eMMC speed"); 124776d13988SJohnny Huang else 124876d13988SJohnny Huang strcpy(strap_parse[k].status, 124976d13988SJohnny Huang "Boot from emmc mode : High eMMC speed"); 125076d13988SJohnny Huang } 125176d13988SJohnny Huang 125276d13988SJohnny Huang k++; 125376d13988SJohnny Huang strap_parse[k].bit = 20; 125476d13988SJohnny Huang strap_parse[k].length = 1; 125576d13988SJohnny Huang strap_parse[k].value = DISABLE_PCIE_EHCI(OTPSTRAP[0]); 125676d13988SJohnny Huang strap_parse[k].protect = DISABLE_PCIE_EHCI(OTPSTRAP_PRO[0]); 125776d13988SJohnny Huang if (DISABLE_PCIE_EHCI(OTPSTRAP_KEEP[0])) { 125876d13988SJohnny Huang strap_parse[k].keep = 1; 125976d13988SJohnny Huang strcpy(strap_parse[k].status, "Skip"); 126076d13988SJohnny Huang } else { 126176d13988SJohnny Huang if (DISABLE_PCIE_EHCI(OTPSTRAP[0])) 126276d13988SJohnny Huang strcpy(strap_parse[k].status, 126376d13988SJohnny Huang "Disable Pcie EHCI device"); 126476d13988SJohnny Huang else 126576d13988SJohnny Huang strcpy(strap_parse[k].status, 126676d13988SJohnny Huang "Enable Pcie EHCI device"); 126776d13988SJohnny Huang } 126876d13988SJohnny Huang 126976d13988SJohnny Huang k++; 127076d13988SJohnny Huang strap_parse[k].bit = 21; 127176d13988SJohnny Huang strap_parse[k].length = 1; 127276d13988SJohnny Huang strap_parse[k].value = DISABLE_VGA_XDMA(OTPSTRAP[0]); 127376d13988SJohnny Huang strap_parse[k].protect = DISABLE_VGA_XDMA(OTPSTRAP_PRO[0]); 127476d13988SJohnny Huang if (DISABLE_VGA_XDMA(OTPSTRAP_KEEP[0])) { 127576d13988SJohnny Huang strap_parse[k].keep = 1; 127676d13988SJohnny Huang strcpy(strap_parse[k].status, "Skip"); 127776d13988SJohnny Huang } else { 127876d13988SJohnny Huang if (DISABLE_VGA_XDMA(OTPSTRAP[0])) 127976d13988SJohnny Huang strcpy(strap_parse[k].status, 128076d13988SJohnny Huang "Disable VGA XDMA function"); 128176d13988SJohnny Huang else 128276d13988SJohnny Huang strcpy(strap_parse[k].status, 128376d13988SJohnny Huang "Enable VGA XDMA function"); 128476d13988SJohnny Huang } 128576d13988SJohnny Huang 128676d13988SJohnny Huang k++; 128776d13988SJohnny Huang strap_parse[k].bit = 22; 128876d13988SJohnny Huang strap_parse[k].length = 1; 128976d13988SJohnny Huang strap_parse[k].value = DISABLE_DEDICATED_BMC_FUNCTION(OTPSTRAP[0]); 129076d13988SJohnny Huang strap_parse[k].protect = DISABLE_DEDICATED_BMC_FUNCTION(OTPSTRAP_PRO[0]); 129176d13988SJohnny Huang if (DISABLE_DEDICATED_BMC_FUNCTION(OTPSTRAP_KEEP[0])) { 129276d13988SJohnny Huang strap_parse[k].keep = 1; 129376d13988SJohnny Huang strcpy(strap_parse[k].status, "Skip"); 129476d13988SJohnny Huang } else { 129576d13988SJohnny Huang if (DISABLE_DEDICATED_BMC_FUNCTION(OTPSTRAP[0])) 129676d13988SJohnny Huang strcpy(strap_parse[k].status, 129776d13988SJohnny Huang "Disable dedicated BMC functions for non-BMC application"); 129876d13988SJohnny Huang else 129976d13988SJohnny Huang strcpy(strap_parse[k].status, 130076d13988SJohnny Huang "Normal BMC mode"); 130176d13988SJohnny Huang } 130276d13988SJohnny Huang 130376d13988SJohnny Huang k++; 130476d13988SJohnny Huang strap_parse[k].bit = 23; 130576d13988SJohnny Huang strap_parse[k].length = 1; 130676d13988SJohnny Huang strap_parse[k].value = DEDICATE_ROOT_COMPLEX_RELAX(OTPSTRAP[0]); 130776d13988SJohnny Huang strap_parse[k].protect = DEDICATE_ROOT_COMPLEX_RELAX(OTPSTRAP_PRO[0]); 130876d13988SJohnny Huang if (DEDICATE_ROOT_COMPLEX_RELAX(OTPSTRAP_KEEP[0])) { 130976d13988SJohnny Huang strap_parse[k].keep = 1; 131076d13988SJohnny Huang strcpy(strap_parse[k].status, "Skip"); 131176d13988SJohnny Huang } else { 131276d13988SJohnny Huang if (DEDICATE_ROOT_COMPLEX_RELAX(OTPSTRAP[0])) 131376d13988SJohnny Huang strcpy(strap_parse[k].status, 131476d13988SJohnny Huang "SSPRST# pin is for PCIE root complex dedicated reset pin"); 131576d13988SJohnny Huang else 131676d13988SJohnny Huang strcpy(strap_parse[k].status, 131776d13988SJohnny Huang "SSPRST# pin is for secondary processor dedicated reset pin"); 131876d13988SJohnny Huang } 131976d13988SJohnny Huang 132076d13988SJohnny Huang k++; 132176d13988SJohnny Huang strap_parse[k].bit = 24; 132276d13988SJohnny Huang strap_parse[k].length = 1; 132376d13988SJohnny Huang strap_parse[k].value = SELECT_DRAM_TYPES(OTPSTRAP[0]); 132476d13988SJohnny Huang strap_parse[k].protect = SELECT_DRAM_TYPES(OTPSTRAP_PRO[0]); 132576d13988SJohnny Huang if (SELECT_DRAM_TYPES(OTPSTRAP_KEEP[0])) { 132676d13988SJohnny Huang strap_parse[k].keep = 1; 132776d13988SJohnny Huang strcpy(strap_parse[k].status, "Skip"); 132876d13988SJohnny Huang } else { 132976d13988SJohnny Huang if (SELECT_DRAM_TYPES(OTPSTRAP[0])) 133076d13988SJohnny Huang strcpy(strap_parse[k].status, 133176d13988SJohnny Huang "DRAM types : DDR4"); 133276d13988SJohnny Huang else 133376d13988SJohnny Huang strcpy(strap_parse[k].status, 133476d13988SJohnny Huang "DRAM types : DDR3"); 133576d13988SJohnny Huang } 133676d13988SJohnny Huang 133776d13988SJohnny Huang k++; 133876d13988SJohnny Huang strap_parse[k].bit = 32; 133976d13988SJohnny Huang strap_parse[k].length = 1; 134076d13988SJohnny Huang strap_parse[k].value = MAC3_RMII_MODE(OTPSTRAP[1]); 134176d13988SJohnny Huang strap_parse[k].protect = MAC3_RMII_MODE(OTPSTRAP_PRO[1]); 134276d13988SJohnny Huang if (MAC3_RMII_MODE(OTPSTRAP_KEEP[1])) { 134376d13988SJohnny Huang strap_parse[k].keep = 1; 134476d13988SJohnny Huang strcpy(strap_parse[k].status, "Skip"); 134576d13988SJohnny Huang } else { 134676d13988SJohnny Huang if (MAC3_RMII_MODE(OTPSTRAP[1])) 134776d13988SJohnny Huang strcpy(strap_parse[k].status, 134876d13988SJohnny Huang "MAC 3 : RGMII"); 134976d13988SJohnny Huang else 135076d13988SJohnny Huang strcpy(strap_parse[k].status, 135176d13988SJohnny Huang "MAC 3 : RMII/NCSI"); 135276d13988SJohnny Huang } 135376d13988SJohnny Huang 135476d13988SJohnny Huang k++; 135576d13988SJohnny Huang strap_parse[k].bit = 33; 135676d13988SJohnny Huang strap_parse[k].length = 1; 135776d13988SJohnny Huang strap_parse[k].value = MAC4_RMII_MODE(OTPSTRAP[1]); 135876d13988SJohnny Huang strap_parse[k].protect = MAC4_RMII_MODE(OTPSTRAP_PRO[1]); 135976d13988SJohnny Huang if (MAC4_RMII_MODE(OTPSTRAP_KEEP[1])) { 136076d13988SJohnny Huang strap_parse[k].keep = 1; 136176d13988SJohnny Huang strcpy(strap_parse[k].status, "Skip"); 136276d13988SJohnny Huang } else { 136376d13988SJohnny Huang if (MAC4_RMII_MODE(OTPSTRAP[1])) 136476d13988SJohnny Huang strcpy(strap_parse[k].status, 136576d13988SJohnny Huang "MAC 4 : RGMII"); 136676d13988SJohnny Huang else 136776d13988SJohnny Huang strcpy(strap_parse[k].status, 136876d13988SJohnny Huang "MAC 4 : RMII/NCSI"); 136976d13988SJohnny Huang } 137076d13988SJohnny Huang 137176d13988SJohnny Huang k++; 137276d13988SJohnny Huang strap_parse[k].bit = 34; 137376d13988SJohnny Huang strap_parse[k].length = 1; 137476d13988SJohnny Huang strap_parse[k].value = SIO_CONF_ADDR(OTPSTRAP[1]); 137576d13988SJohnny Huang strap_parse[k].protect = SIO_CONF_ADDR(OTPSTRAP_PRO[1]); 137676d13988SJohnny Huang if (SIO_CONF_ADDR(OTPSTRAP_KEEP[1])) { 137776d13988SJohnny Huang strap_parse[k].keep = 1; 137876d13988SJohnny Huang strcpy(strap_parse[k].status, "Skip"); 137976d13988SJohnny Huang } else { 138076d13988SJohnny Huang if (SIO_CONF_ADDR(OTPSTRAP[1])) 138176d13988SJohnny Huang strcpy(strap_parse[k].status, 138276d13988SJohnny Huang "SuperIO configuration address : 0x4E"); 138376d13988SJohnny Huang else 138476d13988SJohnny Huang strcpy(strap_parse[k].status, 138576d13988SJohnny Huang "SuperIO configuration address : 0x2E"); 138676d13988SJohnny Huang } 138776d13988SJohnny Huang 138876d13988SJohnny Huang k++; 138976d13988SJohnny Huang strap_parse[k].bit = 35; 139076d13988SJohnny Huang strap_parse[k].length = 1; 139176d13988SJohnny Huang strap_parse[k].value = DISABLE_SIO(OTPSTRAP[1]); 139276d13988SJohnny Huang strap_parse[k].protect = DISABLE_SIO(OTPSTRAP_PRO[1]); 139376d13988SJohnny Huang if (DISABLE_SIO(OTPSTRAP_KEEP[1])) { 139476d13988SJohnny Huang strap_parse[k].keep = 1; 139576d13988SJohnny Huang strcpy(strap_parse[k].status, "Skip"); 139676d13988SJohnny Huang } else { 139776d13988SJohnny Huang if (DISABLE_SIO(OTPSTRAP[1])) 139876d13988SJohnny Huang strcpy(strap_parse[k].status, 139976d13988SJohnny Huang "Disable LPC to decode SuperIO"); 140076d13988SJohnny Huang else 140176d13988SJohnny Huang strcpy(strap_parse[k].status, 140276d13988SJohnny Huang "Enable LPC to decode SuperIO"); 140376d13988SJohnny Huang } 140476d13988SJohnny Huang 140576d13988SJohnny Huang k++; 140676d13988SJohnny Huang strap_parse[k].bit = 36; 140776d13988SJohnny Huang strap_parse[k].length = 1; 140876d13988SJohnny Huang strap_parse[k].value = DISABLE_DEBUG1(OTPSTRAP[1]); 140976d13988SJohnny Huang strap_parse[k].protect = DISABLE_DEBUG1(OTPSTRAP_PRO[1]); 141076d13988SJohnny Huang if (DISABLE_DEBUG1(OTPSTRAP_KEEP[1])) { 141176d13988SJohnny Huang strap_parse[k].keep = 1; 141276d13988SJohnny Huang strcpy(strap_parse[k].status, "Skip"); 141376d13988SJohnny Huang } else { 141476d13988SJohnny Huang if (DISABLE_DEBUG1(OTPSTRAP[1])) 141576d13988SJohnny Huang strcpy(strap_parse[k].status, 141676d13988SJohnny Huang "Disable debug interfaces 1"); 141776d13988SJohnny Huang else 141876d13988SJohnny Huang strcpy(strap_parse[k].status, 141976d13988SJohnny Huang "Enable debug interfaces 1"); 142076d13988SJohnny Huang } 142176d13988SJohnny Huang 142276d13988SJohnny Huang k++; 142376d13988SJohnny Huang strap_parse[k].bit = 37; 142476d13988SJohnny Huang strap_parse[k].length = 1; 142576d13988SJohnny Huang strap_parse[k].value = ENABLE_ACPI(OTPSTRAP[1]); 142676d13988SJohnny Huang strap_parse[k].protect = ENABLE_ACPI(OTPSTRAP_PRO[1]); 142776d13988SJohnny Huang if (ENABLE_ACPI(OTPSTRAP_KEEP[1])) { 142876d13988SJohnny Huang strap_parse[k].keep = 1; 142976d13988SJohnny Huang strcpy(strap_parse[k].status, "Skip"); 143076d13988SJohnny Huang } else { 143176d13988SJohnny Huang if (ENABLE_ACPI(OTPSTRAP[1])) 143276d13988SJohnny Huang strcpy(strap_parse[k].status, 143376d13988SJohnny Huang "Enable ACPI function"); 143476d13988SJohnny Huang else 143576d13988SJohnny Huang strcpy(strap_parse[k].status, 143676d13988SJohnny Huang "Disable ACPI function"); 143776d13988SJohnny Huang } 143876d13988SJohnny Huang 143976d13988SJohnny Huang k++; 144076d13988SJohnny Huang strap_parse[k].bit = 38; 144176d13988SJohnny Huang strap_parse[k].length = 1; 144276d13988SJohnny Huang strap_parse[k].value = SELECT_LPC(OTPSTRAP[1]); 144376d13988SJohnny Huang strap_parse[k].protect = SELECT_LPC(OTPSTRAP_PRO[1]); 144476d13988SJohnny Huang if (SELECT_LPC(OTPSTRAP_KEEP[1])) { 144576d13988SJohnny Huang strap_parse[k].keep = 1; 144676d13988SJohnny Huang strcpy(strap_parse[k].status, "Skip"); 144776d13988SJohnny Huang } else { 144876d13988SJohnny Huang if (SELECT_LPC(OTPSTRAP[1])) 144976d13988SJohnny Huang strcpy(strap_parse[k].status, 145076d13988SJohnny Huang "Enable LPC mode"); 145176d13988SJohnny Huang else 145276d13988SJohnny Huang strcpy(strap_parse[k].status, 145376d13988SJohnny Huang "Enable eSPI mode"); 145476d13988SJohnny Huang } 145576d13988SJohnny Huang 145676d13988SJohnny Huang k++; 145776d13988SJohnny Huang strap_parse[k].bit = 39; 145876d13988SJohnny Huang strap_parse[k].length = 1; 145976d13988SJohnny Huang strap_parse[k].value = ENABLE_SAFS(OTPSTRAP[1]); 146076d13988SJohnny Huang strap_parse[k].protect = ENABLE_SAFS(OTPSTRAP_PRO[1]); 146176d13988SJohnny Huang if (ENABLE_SAFS(OTPSTRAP_KEEP[1])) { 146276d13988SJohnny Huang strap_parse[k].keep = 1; 146376d13988SJohnny Huang strcpy(strap_parse[k].status, "Skip"); 146476d13988SJohnny Huang } else { 146576d13988SJohnny Huang if (ENABLE_SAFS(OTPSTRAP[1])) 146676d13988SJohnny Huang strcpy(strap_parse[k].status, 146776d13988SJohnny Huang "Enable SAFS mode"); 146876d13988SJohnny Huang else 146976d13988SJohnny Huang strcpy(strap_parse[k].status, 147076d13988SJohnny Huang "Enable SAFS mode"); 147176d13988SJohnny Huang } 147276d13988SJohnny Huang 147376d13988SJohnny Huang k++; 147476d13988SJohnny Huang strap_parse[k].bit = 42; 147576d13988SJohnny Huang strap_parse[k].length = 1; 147676d13988SJohnny Huang strap_parse[k].value = ENABLE_SPI_3B4B_AUTO(OTPSTRAP[1]); 147776d13988SJohnny Huang strap_parse[k].protect = ENABLE_SPI_3B4B_AUTO(OTPSTRAP_PRO[1]); 147876d13988SJohnny Huang if (ENABLE_SPI_3B4B_AUTO(OTPSTRAP_KEEP[1])) { 147976d13988SJohnny Huang strap_parse[k].keep = 1; 148076d13988SJohnny Huang strcpy(strap_parse[k].status, "Skip"); 148176d13988SJohnny Huang } else { 148276d13988SJohnny Huang if (ENABLE_SPI_3B4B_AUTO(OTPSTRAP[1])) 148376d13988SJohnny Huang strcpy(strap_parse[k].status, 148476d13988SJohnny Huang "Enable boot SPI 3B/4B address mode auto detection"); 148576d13988SJohnny Huang else 148676d13988SJohnny Huang strcpy(strap_parse[k].status, 148776d13988SJohnny Huang "Disable boot SPI 3B/4B address mode auto detection"); 148876d13988SJohnny Huang } 148976d13988SJohnny Huang 149076d13988SJohnny Huang k++; 149176d13988SJohnny Huang strap_parse[k].bit = 43; 149276d13988SJohnny Huang strap_parse[k].length = 1; 149376d13988SJohnny Huang strap_parse[k].value = ENABLE_BOOT_SPI_ABR(OTPSTRAP[1]); 149476d13988SJohnny Huang strap_parse[k].protect = ENABLE_BOOT_SPI_ABR(OTPSTRAP_PRO[1]); 149576d13988SJohnny Huang if (ENABLE_BOOT_SPI_ABR(OTPSTRAP_KEEP[1])) { 149676d13988SJohnny Huang strap_parse[k].keep = 1; 149776d13988SJohnny Huang strcpy(strap_parse[k].status, "Skip"); 149876d13988SJohnny Huang } else { 149976d13988SJohnny Huang if (ENABLE_BOOT_SPI_ABR(OTPSTRAP[1])) 150076d13988SJohnny Huang strcpy(strap_parse[k].status, 150176d13988SJohnny Huang "Enable boot SPI ABR"); 150276d13988SJohnny Huang else 150376d13988SJohnny Huang strcpy(strap_parse[k].status, 150476d13988SJohnny Huang "Disable boot SPI ABR"); 150576d13988SJohnny Huang } 150676d13988SJohnny Huang 150776d13988SJohnny Huang k++; 150876d13988SJohnny Huang strap_parse[k].bit = 44; 150976d13988SJohnny Huang strap_parse[k].length = 1; 151076d13988SJohnny Huang strap_parse[k].value = BOOT_SPI_ABR_MODE(OTPSTRAP[1]); 151176d13988SJohnny Huang strap_parse[k].protect = BOOT_SPI_ABR_MODE(OTPSTRAP_PRO[1]); 151276d13988SJohnny Huang if (BOOT_SPI_ABR_MODE(OTPSTRAP_KEEP[1])) { 151376d13988SJohnny Huang strap_parse[k].keep = 1; 151476d13988SJohnny Huang strcpy(strap_parse[k].status, "Skip"); 151576d13988SJohnny Huang } else { 151676d13988SJohnny Huang if (BOOT_SPI_ABR_MODE(OTPSTRAP[1])) 151776d13988SJohnny Huang strcpy(strap_parse[k].status, 151876d13988SJohnny Huang "Boot SPI ABR mode : single SPI flash"); 151976d13988SJohnny Huang else 152076d13988SJohnny Huang strcpy(strap_parse[k].status, 152176d13988SJohnny Huang "Boot SPI ABR mode : dual SPI flash"); 152276d13988SJohnny Huang } 152376d13988SJohnny Huang 152476d13988SJohnny Huang k++; 152576d13988SJohnny Huang strap_parse[k].bit = 45; 152676d13988SJohnny Huang strap_parse[k].length = 3; 152776d13988SJohnny Huang strap_parse[k].value = BOOT_SPI_FLASH_SIZE(OTPSTRAP[1]); 152876d13988SJohnny Huang strap_parse[k].protect = BOOT_SPI_FLASH_SIZE(OTPSTRAP_PRO[1]); 152976d13988SJohnny Huang if (BOOT_SPI_FLASH_SIZE(OTPSTRAP_KEEP[1]) == 0x7) { 153076d13988SJohnny Huang strap_parse[k].keep = 1; 153176d13988SJohnny Huang strcpy(strap_parse[k].status, "Skip"); 153276d13988SJohnny Huang } else if (BOOT_SPI_FLASH_SIZE(OTPSTRAP_KEEP[1]) == 0) { 153376d13988SJohnny Huang if (BOOT_SPI_FLASH_SIZE(OTPSTRAP[1]) == 0) { 153476d13988SJohnny Huang strcpy(strap_parse[k].status, 153576d13988SJohnny Huang "Boot SPI flash size : no define size"); 153676d13988SJohnny Huang } else if (BOOT_SPI_FLASH_SIZE(OTPSTRAP[1]) == 1) { 153776d13988SJohnny Huang strcpy(strap_parse[k].status, 153876d13988SJohnny Huang "Boot SPI flash size : 2MB"); 153976d13988SJohnny Huang } else if (BOOT_SPI_FLASH_SIZE(OTPSTRAP[1]) == 2) { 154076d13988SJohnny Huang strcpy(strap_parse[k].status, 154176d13988SJohnny Huang "Boot SPI flash size : 4MB"); 154276d13988SJohnny Huang } else if (BOOT_SPI_FLASH_SIZE(OTPSTRAP[1]) == 3) { 154376d13988SJohnny Huang strcpy(strap_parse[k].status, 154476d13988SJohnny Huang "Boot SPI flash size : 8MB"); 154576d13988SJohnny Huang } else if (BOOT_SPI_FLASH_SIZE(OTPSTRAP[1]) == 4) { 154676d13988SJohnny Huang strcpy(strap_parse[k].status, 154776d13988SJohnny Huang "Boot SPI flash size : 16MB"); 154876d13988SJohnny Huang } else if (BOOT_SPI_FLASH_SIZE(OTPSTRAP[1]) == 5) { 154976d13988SJohnny Huang strcpy(strap_parse[k].status, 155076d13988SJohnny Huang "Boot SPI flash size : 32MB"); 155176d13988SJohnny Huang } else if (BOOT_SPI_FLASH_SIZE(OTPSTRAP[1]) == 6) { 155276d13988SJohnny Huang strcpy(strap_parse[k].status, 155376d13988SJohnny Huang "Boot SPI flash size : 64MB"); 155476d13988SJohnny Huang } else if (BOOT_SPI_FLASH_SIZE(OTPSTRAP[1]) == 7) { 155576d13988SJohnny Huang strcpy(strap_parse[k].status, 155676d13988SJohnny Huang "Boot SPI flash size : 128MB"); 155776d13988SJohnny Huang } 155876d13988SJohnny Huang } else { 155976d13988SJohnny Huang strcpy(strap_parse[k].status, "Keep mask error!"); 156076d13988SJohnny Huang return -1; 156176d13988SJohnny Huang } 156276d13988SJohnny Huang 156376d13988SJohnny Huang k++; 156476d13988SJohnny Huang strap_parse[k].bit = 48; 156576d13988SJohnny Huang strap_parse[k].length = 1; 156676d13988SJohnny Huang strap_parse[k].value = ENABLE_HOST_SPI_ABR(OTPSTRAP[1]); 156776d13988SJohnny Huang strap_parse[k].protect = ENABLE_HOST_SPI_ABR(OTPSTRAP_PRO[1]); 156876d13988SJohnny Huang if (ENABLE_HOST_SPI_ABR(OTPSTRAP_KEEP[1])) { 156976d13988SJohnny Huang strap_parse[k].keep = 1; 157076d13988SJohnny Huang strcpy(strap_parse[k].status, "Skip"); 157176d13988SJohnny Huang } else { 157276d13988SJohnny Huang if (ENABLE_HOST_SPI_ABR(OTPSTRAP[1])) 157376d13988SJohnny Huang strcpy(strap_parse[k].status, 157476d13988SJohnny Huang "Enable host SPI ABR"); 157576d13988SJohnny Huang else 157676d13988SJohnny Huang strcpy(strap_parse[k].status, 157776d13988SJohnny Huang "Disable host SPI ABR"); 157876d13988SJohnny Huang } 157976d13988SJohnny Huang 158076d13988SJohnny Huang k++; 158176d13988SJohnny Huang strap_parse[k].bit = 49; 158276d13988SJohnny Huang strap_parse[k].length = 1; 158376d13988SJohnny Huang strap_parse[k].value = EBABLE_HOST_SPI_ABR_SEL_PIN(OTPSTRAP[1]); 158476d13988SJohnny Huang strap_parse[k].protect = EBABLE_HOST_SPI_ABR_SEL_PIN(OTPSTRAP_PRO[1]); 158576d13988SJohnny Huang if (EBABLE_HOST_SPI_ABR_SEL_PIN(OTPSTRAP_KEEP[1])) { 158676d13988SJohnny Huang strap_parse[k].keep = 1; 158776d13988SJohnny Huang strcpy(strap_parse[k].status, "Skip"); 158876d13988SJohnny Huang } else { 158976d13988SJohnny Huang if (EBABLE_HOST_SPI_ABR_SEL_PIN(OTPSTRAP[1])) 159076d13988SJohnny Huang strcpy(strap_parse[k].status, 159176d13988SJohnny Huang "Enable host SPI ABR mode select pin"); 159276d13988SJohnny Huang else 159376d13988SJohnny Huang strcpy(strap_parse[k].status, 159476d13988SJohnny Huang "Disable host SPI ABR mode select pin"); 159576d13988SJohnny Huang } 159676d13988SJohnny Huang 159776d13988SJohnny Huang k++; 159876d13988SJohnny Huang strap_parse[k].bit = 50; 159976d13988SJohnny Huang strap_parse[k].length = 1; 160076d13988SJohnny Huang strap_parse[k].value = HOST_SPI_ABR_MODE(OTPSTRAP[1]); 160176d13988SJohnny Huang strap_parse[k].protect = HOST_SPI_ABR_MODE(OTPSTRAP_PRO[1]); 160276d13988SJohnny Huang if (HOST_SPI_ABR_MODE(OTPSTRAP_KEEP[1])) { 160376d13988SJohnny Huang strap_parse[k].keep = 1; 160476d13988SJohnny Huang strcpy(strap_parse[k].status, "Skip"); 160576d13988SJohnny Huang } else { 160676d13988SJohnny Huang if (HOST_SPI_ABR_MODE(OTPSTRAP[1])) 160776d13988SJohnny Huang strcpy(strap_parse[k].status, 160876d13988SJohnny Huang "Host SPI ABR mode : single SPI flash"); 160976d13988SJohnny Huang else 161076d13988SJohnny Huang strcpy(strap_parse[k].status, 161176d13988SJohnny Huang "Host SPI ABR mode : dual SPI flash"); 161276d13988SJohnny Huang } 161376d13988SJohnny Huang 161476d13988SJohnny Huang k++; 161576d13988SJohnny Huang strap_parse[k].bit = 51; 161676d13988SJohnny Huang strap_parse[k].length = 3; 161776d13988SJohnny Huang strap_parse[k].value = HOST_SPI_FLASH_SIZE(OTPSTRAP[1]); 161876d13988SJohnny Huang strap_parse[k].protect = HOST_SPI_FLASH_SIZE(OTPSTRAP_PRO[1]); 161976d13988SJohnny Huang if (HOST_SPI_FLASH_SIZE(OTPSTRAP_KEEP[1]) == 0x7) { 162076d13988SJohnny Huang strap_parse[k].keep = 1; 162176d13988SJohnny Huang strcpy(strap_parse[k].status, "Skip"); 162276d13988SJohnny Huang } else if (HOST_SPI_FLASH_SIZE(OTPSTRAP_KEEP[1]) == 0) { 162376d13988SJohnny Huang if (HOST_SPI_FLASH_SIZE(OTPSTRAP[1]) == 0) { 162476d13988SJohnny Huang strcpy(strap_parse[k].status, 162576d13988SJohnny Huang "Host SPI flash size : no define size"); 162676d13988SJohnny Huang } else if (HOST_SPI_FLASH_SIZE(OTPSTRAP[1]) == 1) { 162776d13988SJohnny Huang strcpy(strap_parse[k].status, 162876d13988SJohnny Huang "Host SPI flash size : 2MB"); 162976d13988SJohnny Huang } else if (HOST_SPI_FLASH_SIZE(OTPSTRAP[1]) == 2) { 163076d13988SJohnny Huang strcpy(strap_parse[k].status, 163176d13988SJohnny Huang "Host SPI flash size : 4MB"); 163276d13988SJohnny Huang } else if (HOST_SPI_FLASH_SIZE(OTPSTRAP[1]) == 3) { 163376d13988SJohnny Huang strcpy(strap_parse[k].status, 163476d13988SJohnny Huang "Host SPI flash size : 8MB"); 163576d13988SJohnny Huang } else if (HOST_SPI_FLASH_SIZE(OTPSTRAP[1]) == 4) { 163676d13988SJohnny Huang strcpy(strap_parse[k].status, 163776d13988SJohnny Huang "Host SPI flash size : 16MB"); 163876d13988SJohnny Huang } else if (HOST_SPI_FLASH_SIZE(OTPSTRAP[1]) == 5) { 163976d13988SJohnny Huang strcpy(strap_parse[k].status, 164076d13988SJohnny Huang "Host SPI flash size : 32MB"); 164176d13988SJohnny Huang } else if (HOST_SPI_FLASH_SIZE(OTPSTRAP[1]) == 6) { 164276d13988SJohnny Huang strcpy(strap_parse[k].status, 164376d13988SJohnny Huang "Host SPI flash size : 64MB"); 164476d13988SJohnny Huang } else if (HOST_SPI_FLASH_SIZE(OTPSTRAP[1]) == 7) { 164576d13988SJohnny Huang strcpy(strap_parse[k].status, 164676d13988SJohnny Huang "Host SPI flash size : 128MB"); 164776d13988SJohnny Huang } 164876d13988SJohnny Huang } else { 164976d13988SJohnny Huang strcpy(strap_parse[k].status, "Keep mask error!"); 165076d13988SJohnny Huang return -1; 165176d13988SJohnny Huang } 165276d13988SJohnny Huang 165376d13988SJohnny Huang k++; 165476d13988SJohnny Huang strap_parse[k].bit = 54; 165576d13988SJohnny Huang strap_parse[k].length = 1; 165676d13988SJohnny Huang strap_parse[k].value = ENABLE_BOOT_SPI_AUX_CONTROL_PIN(OTPSTRAP[1]); 165776d13988SJohnny Huang strap_parse[k].protect = ENABLE_BOOT_SPI_AUX_CONTROL_PIN(OTPSTRAP_PRO[1]); 165876d13988SJohnny Huang if (ENABLE_BOOT_SPI_AUX_CONTROL_PIN(OTPSTRAP_KEEP[1])) { 165976d13988SJohnny Huang strap_parse[k].keep = 1; 166076d13988SJohnny Huang strcpy(strap_parse[k].status, "Skip"); 166176d13988SJohnny Huang } else { 166276d13988SJohnny Huang if (ENABLE_BOOT_SPI_AUX_CONTROL_PIN(OTPSTRAP[1])) 166376d13988SJohnny Huang strcpy(strap_parse[k].status, 166476d13988SJohnny Huang "Enable boot SPI auxiliary control pins"); 166576d13988SJohnny Huang else 166676d13988SJohnny Huang strcpy(strap_parse[k].status, 166776d13988SJohnny Huang "Disable boot SPI auxiliary control pins"); 166876d13988SJohnny Huang } 166976d13988SJohnny Huang 167076d13988SJohnny Huang k++; 167176d13988SJohnny Huang strap_parse[k].bit = 55; 167276d13988SJohnny Huang strap_parse[k].length = 2; 167376d13988SJohnny Huang strap_parse[k].value = BOOT_SPI_CRTM_SIZE(OTPSTRAP[1]); 167476d13988SJohnny Huang strap_parse[k].protect = BOOT_SPI_CRTM_SIZE(OTPSTRAP_PRO[1]); 167576d13988SJohnny Huang if (BOOT_SPI_CRTM_SIZE(OTPSTRAP_KEEP[0]) == 0x3) { 167676d13988SJohnny Huang strap_parse[k].keep = 1; 167776d13988SJohnny Huang strcpy(strap_parse[k].status, "Skip"); 167876d13988SJohnny Huang } else if (BOOT_SPI_CRTM_SIZE(OTPSTRAP_KEEP[0]) == 0) { 167976d13988SJohnny Huang if (BOOT_SPI_CRTM_SIZE(OTPSTRAP[0]) == 0) { 168076d13988SJohnny Huang strcpy(strap_parse[k].status, 168176d13988SJohnny Huang "Boot SPI CRTM size : disable CRTM"); 168276d13988SJohnny Huang } else if (BOOT_SPI_CRTM_SIZE(OTPSTRAP[0]) == 1) { 168376d13988SJohnny Huang strcpy(strap_parse[k].status, 168476d13988SJohnny Huang "Boot SPI CRTM size : 256KB"); 168576d13988SJohnny Huang } else if (BOOT_SPI_CRTM_SIZE(OTPSTRAP[0]) == 2) { 168676d13988SJohnny Huang strcpy(strap_parse[k].status, 168776d13988SJohnny Huang "Boot SPI CRTM size : 512KB"); 168876d13988SJohnny Huang } else if (BOOT_SPI_CRTM_SIZE(OTPSTRAP[0]) == 3) { 168976d13988SJohnny Huang strcpy(strap_parse[k].status, 169076d13988SJohnny Huang "Boot SPI CRTM size : 1MB"); 169176d13988SJohnny Huang } 169276d13988SJohnny Huang } else { 169376d13988SJohnny Huang strcpy(strap_parse[k].status, "Keep mask error!"); 169476d13988SJohnny Huang return -1; 169576d13988SJohnny Huang } 169676d13988SJohnny Huang 169776d13988SJohnny Huang k++; 169876d13988SJohnny Huang strap_parse[k].bit = 57; 169976d13988SJohnny Huang strap_parse[k].length = 2; 170076d13988SJohnny Huang strap_parse[k].value = HOST_SPI_CRTM_SIZE(OTPSTRAP[1]); 170176d13988SJohnny Huang strap_parse[k].protect = HOST_SPI_CRTM_SIZE(OTPSTRAP_PRO[1]); 170276d13988SJohnny Huang if (HOST_SPI_CRTM_SIZE(OTPSTRAP_KEEP[0]) == 0x3) { 170376d13988SJohnny Huang strap_parse[k].keep = 1; 170476d13988SJohnny Huang strcpy(strap_parse[k].status, "Skip"); 170576d13988SJohnny Huang } else if (HOST_SPI_CRTM_SIZE(OTPSTRAP_KEEP[0]) == 0) { 170676d13988SJohnny Huang if (HOST_SPI_CRTM_SIZE(OTPSTRAP[0]) == 0) { 170776d13988SJohnny Huang strcpy(strap_parse[k].status, 170876d13988SJohnny Huang "Host SPI CRTM size : disable CRTM"); 170976d13988SJohnny Huang } else if (HOST_SPI_CRTM_SIZE(OTPSTRAP[0]) == 1) { 171076d13988SJohnny Huang strcpy(strap_parse[k].status, 171176d13988SJohnny Huang "Host SPI CRTM size : 256KB"); 171276d13988SJohnny Huang } else if (HOST_SPI_CRTM_SIZE(OTPSTRAP[0]) == 2) { 171376d13988SJohnny Huang strcpy(strap_parse[k].status, 171476d13988SJohnny Huang "Host SPI CRTM size : 512KB"); 171576d13988SJohnny Huang } else if (HOST_SPI_CRTM_SIZE(OTPSTRAP[0]) == 3) { 171676d13988SJohnny Huang strcpy(strap_parse[k].status, 171776d13988SJohnny Huang "Host SPI CRTM size : 1MB"); 171876d13988SJohnny Huang } 171976d13988SJohnny Huang } else { 172076d13988SJohnny Huang strcpy(strap_parse[k].status, "Keep mask error!"); 172176d13988SJohnny Huang return -1; 172276d13988SJohnny Huang } 172376d13988SJohnny Huang 172476d13988SJohnny Huang k++; 172576d13988SJohnny Huang strap_parse[k].bit = 59; 172676d13988SJohnny Huang strap_parse[k].length = 1; 172776d13988SJohnny Huang strap_parse[k].value = ENABLE_HOST_SPI_AUX_CONTROL_PIN(OTPSTRAP[1]); 172876d13988SJohnny Huang strap_parse[k].protect = ENABLE_HOST_SPI_AUX_CONTROL_PIN(OTPSTRAP_PRO[1]); 172976d13988SJohnny Huang if (ENABLE_HOST_SPI_AUX_CONTROL_PIN(OTPSTRAP_KEEP[1])) { 173076d13988SJohnny Huang strap_parse[k].keep = 1; 173176d13988SJohnny Huang strcpy(strap_parse[k].status, "Skip"); 173276d13988SJohnny Huang } else { 173376d13988SJohnny Huang if (ENABLE_HOST_SPI_AUX_CONTROL_PIN(OTPSTRAP[1])) 173476d13988SJohnny Huang strcpy(strap_parse[k].status, 173576d13988SJohnny Huang "Enable host SPI auxiliary control pins"); 173676d13988SJohnny Huang else 173776d13988SJohnny Huang strcpy(strap_parse[k].status, 173876d13988SJohnny Huang "Disable host SPI auxiliary control pins"); 173976d13988SJohnny Huang } 174076d13988SJohnny Huang 174176d13988SJohnny Huang k++; 174276d13988SJohnny Huang strap_parse[k].bit = 60; 174376d13988SJohnny Huang strap_parse[k].length = 1; 174476d13988SJohnny Huang strap_parse[k].value = ENABLE_GPIO_PASS_THROUGH(OTPSTRAP[1]); 174576d13988SJohnny Huang strap_parse[k].protect = ENABLE_GPIO_PASS_THROUGH(OTPSTRAP_PRO[1]); 174676d13988SJohnny Huang if (ENABLE_GPIO_PASS_THROUGH(OTPSTRAP_KEEP[1])) { 174776d13988SJohnny Huang strap_parse[k].keep = 1; 174876d13988SJohnny Huang strcpy(strap_parse[k].status, "Skip"); 174976d13988SJohnny Huang } else { 175076d13988SJohnny Huang if (ENABLE_GPIO_PASS_THROUGH(OTPSTRAP[1])) 175176d13988SJohnny Huang strcpy(strap_parse[k].status, 175276d13988SJohnny Huang "Enable GPIO pass through"); 175376d13988SJohnny Huang else 175476d13988SJohnny Huang strcpy(strap_parse[k].status, 175576d13988SJohnny Huang "Disable GPIO pass through"); 175676d13988SJohnny Huang } 175776d13988SJohnny Huang 175876d13988SJohnny Huang k++; 175976d13988SJohnny Huang strap_parse[k].bit = 61; 176076d13988SJohnny Huang strap_parse[k].length = 1; 176176d13988SJohnny Huang strap_parse[k].value = DISABLE_LOW_SECURITY_KEY(OTPSTRAP[1]); 176276d13988SJohnny Huang strap_parse[k].protect = DISABLE_LOW_SECURITY_KEY(OTPSTRAP_PRO[1]); 176376d13988SJohnny Huang if (DISABLE_LOW_SECURITY_KEY(OTPSTRAP_KEEP[1])) { 176476d13988SJohnny Huang strap_parse[k].keep = 1; 176576d13988SJohnny Huang strcpy(strap_parse[k].status, "Skip"); 176676d13988SJohnny Huang } else { 176776d13988SJohnny Huang if (DISABLE_LOW_SECURITY_KEY(OTPSTRAP[1])) 176876d13988SJohnny Huang strcpy(strap_parse[k].status, 176976d13988SJohnny Huang "Disable low security secure boot key"); 177076d13988SJohnny Huang else 177176d13988SJohnny Huang strcpy(strap_parse[k].status, 177276d13988SJohnny Huang "Enable low security secure boot key"); 177376d13988SJohnny Huang } 177476d13988SJohnny Huang 177576d13988SJohnny Huang k++; 177676d13988SJohnny Huang strap_parse[k].bit = 62; 177776d13988SJohnny Huang strap_parse[k].length = 1; 177876d13988SJohnny Huang strap_parse[k].value = ENABLE_DEDICATE_GPIO_STRAP(OTPSTRAP[1]); 177976d13988SJohnny Huang strap_parse[k].protect = ENABLE_DEDICATE_GPIO_STRAP(OTPSTRAP_PRO[1]); 178076d13988SJohnny Huang if (ENABLE_DEDICATE_GPIO_STRAP(OTPSTRAP_KEEP[1])) { 178176d13988SJohnny Huang strap_parse[k].keep = 1; 178276d13988SJohnny Huang strcpy(strap_parse[k].status, "Skip"); 178376d13988SJohnny Huang } else { 178476d13988SJohnny Huang if (ENABLE_DEDICATE_GPIO_STRAP(OTPSTRAP[1])) 178576d13988SJohnny Huang strcpy(strap_parse[k].status, 178676d13988SJohnny Huang "Enable dedicate GPIO strap pins"); 178776d13988SJohnny Huang else 178876d13988SJohnny Huang strcpy(strap_parse[k].status, 178976d13988SJohnny Huang "Disable dedicate GPIO strap pins"); 179076d13988SJohnny Huang } 179176d13988SJohnny Huang 179276d13988SJohnny Huang return k + 1; 179376d13988SJohnny Huang } 179466f2f8e5SJohnny Huang 179566f2f8e5SJohnny Huang static int otp_print_conf_info(uint32_t *OTPCFG) 179666f2f8e5SJohnny Huang { 179766f2f8e5SJohnny Huang struct otpconf_parse conf_parse[60]; 179866f2f8e5SJohnny Huang int length; 179966f2f8e5SJohnny Huang int i; 180066f2f8e5SJohnny Huang 180166f2f8e5SJohnny Huang length = otp_conf_parse(OTPCFG, conf_parse); 180266f2f8e5SJohnny Huang 180366f2f8e5SJohnny Huang if (length <= 0) 180466f2f8e5SJohnny Huang return OTP_FAILURE; 180566f2f8e5SJohnny Huang 1806737ed20bSJohnny Huang printf("DW BIT Value Description\n"); 180766f2f8e5SJohnny Huang printf("__________________________________________________________________________\n"); 180866f2f8e5SJohnny Huang for (i = 0; i < length; i++) { 180966f2f8e5SJohnny Huang printf("%-4d", conf_parse[i].dw_offset); 181066f2f8e5SJohnny Huang if (conf_parse[i].length == 1) { 181166f2f8e5SJohnny Huang printf("%-8d", conf_parse[i].bit); 181266f2f8e5SJohnny Huang } else { 181366f2f8e5SJohnny Huang printf("%-2d:%-5d", 181466f2f8e5SJohnny Huang conf_parse[i].bit + conf_parse[i].length - 1, 181566f2f8e5SJohnny Huang conf_parse[i].bit); 181666f2f8e5SJohnny Huang } 181766f2f8e5SJohnny Huang printf("0x%-10x", conf_parse[i].value); 181866f2f8e5SJohnny Huang printf("%s\n", conf_parse[i].status); 181966f2f8e5SJohnny Huang } 182066f2f8e5SJohnny Huang return OTP_SUCCESS; 182166f2f8e5SJohnny Huang } 182266f2f8e5SJohnny Huang 182366f2f8e5SJohnny Huang static void otp_info_config(void) 182466f2f8e5SJohnny Huang { 182566f2f8e5SJohnny Huang uint32_t OTPCFG[24]; 182666f2f8e5SJohnny Huang int i; 182766f2f8e5SJohnny Huang 182866f2f8e5SJohnny Huang for (i = 0; i < 12; i++) 182966f2f8e5SJohnny Huang otp_read_config(i, &OTPCFG[i]); 183066f2f8e5SJohnny Huang 183166f2f8e5SJohnny Huang for (i = 12; i < 24; i++) 183266f2f8e5SJohnny Huang OTPCFG[i] = 0; 183366f2f8e5SJohnny Huang 183466f2f8e5SJohnny Huang otp_print_conf_info(OTPCFG); 183566f2f8e5SJohnny Huang } 183666f2f8e5SJohnny Huang 183776d13988SJohnny Huang static int otp_print_strap_info(uint32_t *OTPSTRAP) 183876d13988SJohnny Huang { 183976d13988SJohnny Huang struct otpstrap_parse strap_parse[60]; 184076d13988SJohnny Huang int length; 184176d13988SJohnny Huang int i; 184276d13988SJohnny Huang 184376d13988SJohnny Huang length = otp_strap_parse(OTPSTRAP, strap_parse); 184476d13988SJohnny Huang 184576d13988SJohnny Huang if (length <= 0) 184676d13988SJohnny Huang return OTP_FAILURE; 184776d13988SJohnny Huang 1848737ed20bSJohnny Huang printf("BIT Value Protect Description\n"); 184976d13988SJohnny Huang printf("__________________________________________________________________________________________\n"); 185076d13988SJohnny Huang for (i = 0; i < length; i++) { 185176d13988SJohnny Huang if (strap_parse[i].length == 1) { 185276d13988SJohnny Huang printf("%-8d", strap_parse[i].bit); 185376d13988SJohnny Huang } else { 185476d13988SJohnny Huang printf("%-2d:%-5d", 185576d13988SJohnny Huang strap_parse[i].bit + strap_parse[i].length - 1, 185676d13988SJohnny Huang strap_parse[i].bit); 185776d13988SJohnny Huang } 185876d13988SJohnny Huang printf("0x%-10x", strap_parse[i].value); 185976d13988SJohnny Huang printf("0x%-10x", strap_parse[i].protect); 186076d13988SJohnny Huang printf("%s\n", strap_parse[i].status); 186176d13988SJohnny Huang } 186276d13988SJohnny Huang return OTP_SUCCESS; 186376d13988SJohnny Huang } 186476d13988SJohnny Huang 186576d13988SJohnny Huang static void otp_info_strap(void) 186676d13988SJohnny Huang { 186776d13988SJohnny Huang struct otpstrap_status strap_status[64]; 186876d13988SJohnny Huang uint32_t OTPSTRAP[6]; 186976d13988SJohnny Huang int i; 187076d13988SJohnny Huang 187176d13988SJohnny Huang 187276d13988SJohnny Huang otp_strp_status(strap_status); 187376d13988SJohnny Huang 187476d13988SJohnny Huang for (i = 0; i < 6; i++) 187576d13988SJohnny Huang OTPSTRAP[i] = 0; 187676d13988SJohnny Huang for (i = 0; i < 32; i++) { 187776d13988SJohnny Huang OTPSTRAP[0] |= (strap_status[i].value & 0x1) << i; 187876d13988SJohnny Huang OTPSTRAP[4] |= (strap_status[i].protected & 0x1) << i; 187976d13988SJohnny Huang } 188076d13988SJohnny Huang for (i = 0; i < 32; i++) { 188176d13988SJohnny Huang OTPSTRAP[1] |= (strap_status[i + 32].value & 0x1) << i; 188276d13988SJohnny Huang OTPSTRAP[5] |= (strap_status[i + 32].protected & 0x1) << i; 188376d13988SJohnny Huang } 188476d13988SJohnny Huang 188576d13988SJohnny Huang otp_print_strap_info(OTPSTRAP); 188676d13988SJohnny Huang } 188776d13988SJohnny Huang 188869d5fd8fSJohnny Huang static void buf_print(char *buf, int len) 188969d5fd8fSJohnny Huang { 189069d5fd8fSJohnny Huang int i; 189169d5fd8fSJohnny Huang printf(" 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F\n"); 189269d5fd8fSJohnny Huang for (i = 0; i < len; i++) { 189369d5fd8fSJohnny Huang if (i % 16 == 0) { 189469d5fd8fSJohnny Huang printf("%04X: ", i); 189569d5fd8fSJohnny Huang } 189669d5fd8fSJohnny Huang printf("%02X ", buf[i]); 189769d5fd8fSJohnny Huang if ((i + 1) % 16 == 0) { 189869d5fd8fSJohnny Huang printf("\n"); 189969d5fd8fSJohnny Huang } 190069d5fd8fSJohnny Huang } 190169d5fd8fSJohnny Huang } 190269d5fd8fSJohnny Huang 1903*7f795e57SJohnny Huang static int otp_print_data_info(uint32_t *buf) 190469d5fd8fSJohnny Huang { 190569d5fd8fSJohnny Huang int key_id, key_offset, last, key_type, key_length, exp_length; 190669d5fd8fSJohnny Huang char *byte_buf; 190769d5fd8fSJohnny Huang int i = 0, len = 0; 190869d5fd8fSJohnny Huang byte_buf = (char *)buf; 190969d5fd8fSJohnny Huang while (1) { 191069d5fd8fSJohnny Huang key_id = buf[i] & 0x7; 191169d5fd8fSJohnny Huang key_offset = buf[i] & 0x1ff8; 191269d5fd8fSJohnny Huang last = (buf[i] >> 13) & 1; 191369d5fd8fSJohnny Huang key_type = (buf[i] >> 14) & 0xf; 191469d5fd8fSJohnny Huang key_length = (buf[i] >> 18) & 0x3; 191569d5fd8fSJohnny Huang exp_length = (buf[i] >> 20) & 0xfff; 1916*7f795e57SJohnny Huang printf("\nKey[%d]:\n", i); 191769d5fd8fSJohnny Huang printf("Key Type: "); 191869d5fd8fSJohnny Huang switch (key_type) { 191969d5fd8fSJohnny Huang case 0: 192069d5fd8fSJohnny Huang printf("AES-256 as OEM platform key for image encryption/decryption\n"); 192169d5fd8fSJohnny Huang break; 192269d5fd8fSJohnny Huang case 1: 192369d5fd8fSJohnny Huang printf("AES-256 as secret vault key\n"); 192469d5fd8fSJohnny Huang break; 192569d5fd8fSJohnny Huang case 4: 192669d5fd8fSJohnny Huang printf("HMAC as encrypted OEM HMAC keys in Mode 1\n"); 192769d5fd8fSJohnny Huang break; 192869d5fd8fSJohnny Huang case 8: 192969d5fd8fSJohnny Huang printf("RSA-public as OEM DSS public keys in Mode 2\n"); 193069d5fd8fSJohnny Huang break; 193169d5fd8fSJohnny Huang case 9: 193269d5fd8fSJohnny Huang printf("RSA-public as SOC public key\n"); 193369d5fd8fSJohnny Huang break; 193469d5fd8fSJohnny Huang case 10: 193569d5fd8fSJohnny Huang printf("RSA-public as AES key decryption key\n"); 193669d5fd8fSJohnny Huang break; 193769d5fd8fSJohnny Huang case 13: 193869d5fd8fSJohnny Huang printf("RSA-private as SOC private key\n"); 193969d5fd8fSJohnny Huang break; 194069d5fd8fSJohnny Huang case 14: 194169d5fd8fSJohnny Huang printf("RSA-private as AES key decryption key\n"); 194269d5fd8fSJohnny Huang break; 194369d5fd8fSJohnny Huang default: 194469d5fd8fSJohnny Huang printf("key_type error: %x\n", key_type); 194569d5fd8fSJohnny Huang return -1; 194669d5fd8fSJohnny Huang } 194769d5fd8fSJohnny Huang if (key_type == 4) { 194869d5fd8fSJohnny Huang printf("HMAC SHA Type: "); 194969d5fd8fSJohnny Huang switch (key_length) { 195069d5fd8fSJohnny Huang case 0: 195169d5fd8fSJohnny Huang printf("HMAC(SHA224)\n"); 195269d5fd8fSJohnny Huang break; 195369d5fd8fSJohnny Huang case 1: 195469d5fd8fSJohnny Huang printf("HMAC(SHA256)\n"); 195569d5fd8fSJohnny Huang break; 195669d5fd8fSJohnny Huang case 2: 195769d5fd8fSJohnny Huang printf("HMAC(SHA384)\n"); 195869d5fd8fSJohnny Huang break; 195969d5fd8fSJohnny Huang case 3: 196069d5fd8fSJohnny Huang printf("HMAC(SHA512)\n"); 196169d5fd8fSJohnny Huang break; 196269d5fd8fSJohnny Huang } 1963cd1610b4SJohnny Huang } else if (key_type != 0 && key_type != 1) { 196469d5fd8fSJohnny Huang printf("RSA SHA Type: "); 196569d5fd8fSJohnny Huang switch (key_length) { 196669d5fd8fSJohnny Huang case 0: 196769d5fd8fSJohnny Huang printf("RSA1024\n"); 196869d5fd8fSJohnny Huang len = 0x100; 196969d5fd8fSJohnny Huang break; 197069d5fd8fSJohnny Huang case 1: 197169d5fd8fSJohnny Huang printf("RSA2048\n"); 197269d5fd8fSJohnny Huang len = 0x200; 197369d5fd8fSJohnny Huang break; 197469d5fd8fSJohnny Huang case 2: 197569d5fd8fSJohnny Huang printf("RSA3072\n"); 197669d5fd8fSJohnny Huang len = 0x300; 197769d5fd8fSJohnny Huang break; 197869d5fd8fSJohnny Huang case 3: 197969d5fd8fSJohnny Huang printf("RSA4096\n"); 198069d5fd8fSJohnny Huang len = 0x400; 198169d5fd8fSJohnny Huang break; 198269d5fd8fSJohnny Huang } 198369d5fd8fSJohnny Huang printf("RSA exponent bit length: %d\n", exp_length); 198469d5fd8fSJohnny Huang } 198569d5fd8fSJohnny Huang if (key_type == 4 || key_type == 8) 198669d5fd8fSJohnny Huang printf("Key Number ID: %d\n", key_id); 198769d5fd8fSJohnny Huang printf("Key Value:\n"); 198869d5fd8fSJohnny Huang if (key_type == 4) { 198969d5fd8fSJohnny Huang buf_print(&byte_buf[key_offset], 0x40); 199069d5fd8fSJohnny Huang } else if (key_type == 0 || key_type == 1) { 199169d5fd8fSJohnny Huang printf("AES Key:\n"); 199269d5fd8fSJohnny Huang buf_print(&byte_buf[key_offset], 0x20); 199369d5fd8fSJohnny Huang printf("AES IV:\n"); 199469d5fd8fSJohnny Huang buf_print(&byte_buf[key_offset + 0x20], 0x10); 199569d5fd8fSJohnny Huang 199669d5fd8fSJohnny Huang } else { 199769d5fd8fSJohnny Huang printf("RSA mod:\n"); 199869d5fd8fSJohnny Huang buf_print(&byte_buf[key_offset], len / 2); 199969d5fd8fSJohnny Huang printf("RSA exp:\n"); 200069d5fd8fSJohnny Huang buf_print(&byte_buf[key_offset + (len / 2)], len / 2); 200169d5fd8fSJohnny Huang } 200269d5fd8fSJohnny Huang if (last) 200369d5fd8fSJohnny Huang break; 200469d5fd8fSJohnny Huang i++; 200569d5fd8fSJohnny Huang } 200669d5fd8fSJohnny Huang return 0; 200769d5fd8fSJohnny Huang } 200869d5fd8fSJohnny Huang 2009a6d0d645SJohnny Huang static int otp_prog_conf(uint32_t *buf) 201069d5fd8fSJohnny Huang { 2011a6d0d645SJohnny Huang int i, k; 2012d90825e2SJohnny Huang int pass = 0; 2013d90825e2SJohnny Huang int soak = 0; 2014a6d0d645SJohnny Huang uint32_t prog_address; 2015a6d0d645SJohnny Huang uint32_t data[12]; 2016a6d0d645SJohnny Huang uint32_t compare[2]; 2017d90825e2SJohnny Huang uint32_t *buf_keep = &buf[12]; 2018d90825e2SJohnny Huang uint32_t data_masked; 2019d90825e2SJohnny Huang uint32_t buf_masked; 202069d5fd8fSJohnny Huang 2021a6d0d645SJohnny Huang printf("Read OTP Config Region:\n"); 2022a6d0d645SJohnny Huang 2023a6d0d645SJohnny Huang printProgress(0, 12, ""); 2024a6d0d645SJohnny Huang for (i = 0; i < 12 ; i ++) { 2025a6d0d645SJohnny Huang printProgress(i + 1, 12, ""); 202669d5fd8fSJohnny Huang prog_address = 0x800; 2027a6d0d645SJohnny Huang prog_address |= (i / 8) * 0x200; 2028a6d0d645SJohnny Huang prog_address |= (i % 8) * 0x2; 2029a6d0d645SJohnny Huang otp_read_data(prog_address, &data[i]); 2030a6d0d645SJohnny Huang } 2031a6d0d645SJohnny Huang 2032a6d0d645SJohnny Huang printf("Check writable...\n"); 2033a6d0d645SJohnny Huang for (i = 0; i < 12; i++) { 2034d90825e2SJohnny Huang data_masked = data[i] & ~buf_keep[i]; 2035d90825e2SJohnny Huang buf_masked = buf[i] & ~buf_keep[i]; 2036d90825e2SJohnny Huang if (data_masked == buf_masked) 203769d5fd8fSJohnny Huang continue; 2038d90825e2SJohnny Huang if ((data_masked | buf_masked) == buf_masked) { 2039a6d0d645SJohnny Huang continue; 2040a6d0d645SJohnny Huang } else { 2041a6d0d645SJohnny Huang printf("Input image can't program into OTP, please check.\n"); 2042a6af4a17SJohnny Huang printf("OTPCFG[%X] = %x\n", i, data[i]); 2043a6af4a17SJohnny Huang printf("Input [%X] = %x\n", i, buf[i]); 2044a6af4a17SJohnny Huang printf("Mask [%X] = %x\n", i, ~buf_keep[i]); 20452a856b9aSJohnny Huang return OTP_FAILURE; 2046a6d0d645SJohnny Huang } 2047a6d0d645SJohnny Huang } 2048a6d0d645SJohnny Huang 2049a6d0d645SJohnny Huang printf("Start Programing...\n"); 2050a6d0d645SJohnny Huang printProgress(0, 12, ""); 2051d90825e2SJohnny Huang otp_soak(0); 2052a6d0d645SJohnny Huang for (i = 0; i < 12; i++) { 2053d90825e2SJohnny Huang data_masked = data[i] & ~buf_keep[i]; 2054d90825e2SJohnny Huang buf_masked = buf[i] & ~buf_keep[i]; 2055a6d0d645SJohnny Huang prog_address = 0x800; 2056a6d0d645SJohnny Huang prog_address |= (i / 8) * 0x200; 2057a6d0d645SJohnny Huang prog_address |= (i % 8) * 0x2; 2058d90825e2SJohnny Huang if (data_masked == buf_masked) { 2059a6d0d645SJohnny Huang printProgress(i + 1, 12, "[%03X]=%08X HIT", prog_address, buf[i]); 2060a6d0d645SJohnny Huang continue; 2061a6d0d645SJohnny Huang } 2062d90825e2SJohnny Huang if (soak) { 2063d90825e2SJohnny Huang soak = 0; 2064d90825e2SJohnny Huang otp_soak(0); 2065d90825e2SJohnny Huang } 2066a6d0d645SJohnny Huang printProgress(i + 1, 12, "[%03X]=%08X ", prog_address, buf[i]); 2067a6d0d645SJohnny Huang 2068d90825e2SJohnny Huang otp_prog_dw(buf[i], buf_keep[i], prog_address); 2069a6d0d645SJohnny Huang 207069d5fd8fSJohnny Huang pass = 0; 207169d5fd8fSJohnny Huang for (k = 0; k < RETRY; k++) { 2072d90825e2SJohnny Huang if (verify_dw(prog_address, &buf[i], &buf_keep[i], compare, 1) != 0) { 2073d90825e2SJohnny Huang if (soak == 0) { 2074d90825e2SJohnny Huang soak = 1; 2075d90825e2SJohnny Huang otp_soak(1); 2076d90825e2SJohnny Huang } 2077a6d0d645SJohnny Huang otp_prog_dw(compare[0], prog_address, 1); 2078a6d0d645SJohnny Huang } else { 207969d5fd8fSJohnny Huang pass = 1; 208069d5fd8fSJohnny Huang break; 208169d5fd8fSJohnny Huang } 208269d5fd8fSJohnny Huang } 2083a6d0d645SJohnny Huang } 2084a6d0d645SJohnny Huang 208569d5fd8fSJohnny Huang if (!pass) 20862a856b9aSJohnny Huang return OTP_FAILURE; 2087a6d0d645SJohnny Huang 20882a856b9aSJohnny Huang return OTP_SUCCESS; 2089d90825e2SJohnny Huang 209069d5fd8fSJohnny Huang } 209169d5fd8fSJohnny Huang 209269d5fd8fSJohnny Huang 209376d13988SJohnny Huang static int otp_strap_image_confirm(uint32_t *buf) 209469d5fd8fSJohnny Huang { 209569d5fd8fSJohnny Huang int i; 209669d5fd8fSJohnny Huang uint32_t *strap_keep = buf + 2; 209769d5fd8fSJohnny Huang uint32_t *strap_protect = buf + 4; 209869d5fd8fSJohnny Huang int bit, pbit, kbit; 209969d5fd8fSJohnny Huang int fail = 0; 2100a6af4a17SJohnny Huang int skip = -1; 210166f2f8e5SJohnny Huang struct otpstrap_status otpstrap[64]; 210269d5fd8fSJohnny Huang 210369d5fd8fSJohnny Huang otp_strp_status(otpstrap); 210469d5fd8fSJohnny Huang for (i = 0; i < 64; i++) { 210569d5fd8fSJohnny Huang if (i < 32) { 210669d5fd8fSJohnny Huang bit = (buf[0] >> i) & 0x1; 210769d5fd8fSJohnny Huang kbit = (strap_keep[0] >> i) & 0x1; 210869d5fd8fSJohnny Huang pbit = (strap_protect[0] >> i) & 0x1; 210969d5fd8fSJohnny Huang } else { 211069d5fd8fSJohnny Huang bit = (buf[1] >> (i - 32)) & 0x1; 211169d5fd8fSJohnny Huang kbit = (strap_keep[1] >> (i - 32)) & 0x1; 211269d5fd8fSJohnny Huang pbit = (strap_protect[1] >> (i - 32)) & 0x1; 211369d5fd8fSJohnny Huang } 211469d5fd8fSJohnny Huang 211569d5fd8fSJohnny Huang if (kbit == 1) { 211669d5fd8fSJohnny Huang continue; 211769d5fd8fSJohnny Huang } else { 2118a6af4a17SJohnny Huang printf("OTPSTRAP[%X]:\n", i); 211969d5fd8fSJohnny Huang } 212069d5fd8fSJohnny Huang if (bit == otpstrap[i].value) { 212169d5fd8fSJohnny Huang printf(" The value is same as before, skip it.\n"); 2122a6af4a17SJohnny Huang if (skip == -1) 2123a6af4a17SJohnny Huang skip = 1; 212469d5fd8fSJohnny Huang continue; 2125a6af4a17SJohnny Huang } else { 2126a6af4a17SJohnny Huang skip = 0; 212769d5fd8fSJohnny Huang } 212869d5fd8fSJohnny Huang if (otpstrap[i].protected == 1) { 212969d5fd8fSJohnny Huang printf(" This bit is protected and is not writable\n"); 213069d5fd8fSJohnny Huang fail = 1; 213169d5fd8fSJohnny Huang continue; 213269d5fd8fSJohnny Huang } 213369d5fd8fSJohnny Huang if (otpstrap[i].remain_times == 0) { 2134a6af4a17SJohnny Huang printf(" This bit is no remaining times to write.\n"); 213569d5fd8fSJohnny Huang fail = 1; 213669d5fd8fSJohnny Huang continue; 213769d5fd8fSJohnny Huang } 213869d5fd8fSJohnny Huang if (pbit == 1) { 213969d5fd8fSJohnny Huang printf(" This bit will be protected and become non-writable.\n"); 214069d5fd8fSJohnny Huang } 2141a6af4a17SJohnny Huang printf(" Write 1 to OTPSTRAP[%X] OPTION[%X], that value becomes from %d to %d.\n", i, otpstrap[i].writeable_option + 1, otpstrap[i].value, otpstrap[i].value ^ 1); 214269d5fd8fSJohnny Huang } 214369d5fd8fSJohnny Huang if (fail == 1) 2144a6af4a17SJohnny Huang return OTP_FAILURE; 2145a6af4a17SJohnny Huang else if (skip == 1) 2146a6af4a17SJohnny Huang return OTP_PROG_SKIP; 21477e22f42dSJohnny Huang 21487e22f42dSJohnny Huang return 0; 214969d5fd8fSJohnny Huang } 215069d5fd8fSJohnny Huang 21512a856b9aSJohnny Huang static int otp_print_strap(int start, int count) 215269d5fd8fSJohnny Huang { 215369d5fd8fSJohnny Huang int i, j; 215466f2f8e5SJohnny Huang struct otpstrap_status otpstrap[64]; 215569d5fd8fSJohnny Huang 21562a856b9aSJohnny Huang if (start < 0 || start > 64) 21572a856b9aSJohnny Huang return OTP_USAGE; 21582a856b9aSJohnny Huang 21592a856b9aSJohnny Huang if ((start + count) < 0 || (start + count) > 64) 21602a856b9aSJohnny Huang return OTP_USAGE; 21612a856b9aSJohnny Huang 216269d5fd8fSJohnny Huang otp_strp_status(otpstrap); 216369d5fd8fSJohnny Huang 2164737ed20bSJohnny Huang printf("BIT Value Avaliable Status\n"); 2165737ed20bSJohnny Huang printf("______________________________________________________________________\n"); 2166737ed20bSJohnny Huang 2167cd1610b4SJohnny Huang for (i = start; i < start + count; i++) { 2168737ed20bSJohnny Huang printf("%-5d", i); 2169737ed20bSJohnny Huang printf("%-7d", otpstrap[i].value); 2170737ed20bSJohnny Huang for (j = 0; j < 7; j++) 2171737ed20bSJohnny Huang printf("%d ", otpstrap[i].option_array[j]); 2172737ed20bSJohnny Huang printf(" "); 217369d5fd8fSJohnny Huang if (otpstrap[i].protected == 1) { 2174737ed20bSJohnny Huang printf("protected and not writable"); 217569d5fd8fSJohnny Huang } else { 2176737ed20bSJohnny Huang printf("not protected "); 217769d5fd8fSJohnny Huang if (otpstrap[i].remain_times == 0) { 2178737ed20bSJohnny Huang printf("and no remaining times to write."); 217969d5fd8fSJohnny Huang } else { 2180737ed20bSJohnny Huang printf("and still can write %d times", otpstrap[i].remain_times); 218169d5fd8fSJohnny Huang } 218269d5fd8fSJohnny Huang } 2183737ed20bSJohnny Huang printf("\n"); 218469d5fd8fSJohnny Huang } 21852a856b9aSJohnny Huang 21862a856b9aSJohnny Huang return OTP_SUCCESS; 218769d5fd8fSJohnny Huang } 218869d5fd8fSJohnny Huang 218969d5fd8fSJohnny Huang static int otp_prog_strap(uint32_t *buf) 219069d5fd8fSJohnny Huang { 219169d5fd8fSJohnny Huang int i, j; 219269d5fd8fSJohnny Huang uint32_t *strap_keep = buf + 2; 219369d5fd8fSJohnny Huang uint32_t *strap_protect = buf + 4; 219469d5fd8fSJohnny Huang uint32_t prog_bit, prog_address; 219569d5fd8fSJohnny Huang int bit, pbit, kbit, offset; 219669d5fd8fSJohnny Huang int fail = 0; 21977e22f42dSJohnny Huang int pass = 0; 21987e22f42dSJohnny Huang int soak = 0; 219966f2f8e5SJohnny Huang struct otpstrap_status otpstrap[64]; 220069d5fd8fSJohnny Huang 2201*7f795e57SJohnny Huang printf("Read OTP Strap Region:\n"); 220269d5fd8fSJohnny Huang otp_strp_status(otpstrap); 220369d5fd8fSJohnny Huang 2204*7f795e57SJohnny Huang printf("Check writable...\n"); 2205*7f795e57SJohnny Huang if (otp_strap_image_confirm(buf) == OTP_FAILURE) { 2206*7f795e57SJohnny Huang printf("Input image can't program into OTP, please check.\n"); 2207*7f795e57SJohnny Huang return OTP_FAILURE; 2208*7f795e57SJohnny Huang } 22097e22f42dSJohnny Huang 2210*7f795e57SJohnny Huang otp_soak(0); 221169d5fd8fSJohnny Huang for (i = 0; i < 64; i++) { 22124c1c9b35SJohnny Huang printProgress(i + 1, 64, ""); 221369d5fd8fSJohnny Huang prog_address = 0x800; 221469d5fd8fSJohnny Huang if (i < 32) { 221569d5fd8fSJohnny Huang offset = i; 221669d5fd8fSJohnny Huang bit = (buf[0] >> offset) & 0x1; 221769d5fd8fSJohnny Huang kbit = (strap_keep[0] >> offset) & 0x1; 221869d5fd8fSJohnny Huang pbit = (strap_protect[0] >> offset) & 0x1; 221969d5fd8fSJohnny Huang prog_address |= ((otpstrap[i].writeable_option * 2 + 16) / 8) * 0x200; 222069d5fd8fSJohnny Huang prog_address |= ((otpstrap[i].writeable_option * 2 + 16) % 8) * 0x2; 222169d5fd8fSJohnny Huang 222269d5fd8fSJohnny Huang } else { 222369d5fd8fSJohnny Huang offset = (i - 32); 222469d5fd8fSJohnny Huang bit = (buf[1] >> offset) & 0x1; 222569d5fd8fSJohnny Huang kbit = (strap_keep[1] >> offset) & 0x1; 222669d5fd8fSJohnny Huang pbit = (strap_protect[1] >> offset) & 0x1; 222769d5fd8fSJohnny Huang prog_address |= ((otpstrap[i].writeable_option * 2 + 17) / 8) * 0x200; 222869d5fd8fSJohnny Huang prog_address |= ((otpstrap[i].writeable_option * 2 + 17) % 8) * 0x2; 222969d5fd8fSJohnny Huang } 223069d5fd8fSJohnny Huang prog_bit = ~(0x1 << offset); 223169d5fd8fSJohnny Huang 223269d5fd8fSJohnny Huang if (kbit == 1) { 223369d5fd8fSJohnny Huang continue; 223469d5fd8fSJohnny Huang } 223569d5fd8fSJohnny Huang if (bit == otpstrap[i].value) { 223669d5fd8fSJohnny Huang continue; 223769d5fd8fSJohnny Huang } 223869d5fd8fSJohnny Huang if (otpstrap[i].protected == 1) { 223969d5fd8fSJohnny Huang fail = 1; 224069d5fd8fSJohnny Huang continue; 224169d5fd8fSJohnny Huang } 224269d5fd8fSJohnny Huang if (otpstrap[i].remain_times == 0) { 224369d5fd8fSJohnny Huang fail = 1; 224469d5fd8fSJohnny Huang continue; 224569d5fd8fSJohnny Huang } 22467e22f42dSJohnny Huang 22477e22f42dSJohnny Huang if (soak) { 224869d5fd8fSJohnny Huang soak = 0; 22497e22f42dSJohnny Huang otp_soak(0); 22507e22f42dSJohnny Huang } 22517e22f42dSJohnny Huang 22527e22f42dSJohnny Huang otp_prog(prog_address, prog_bit); 22537e22f42dSJohnny Huang 22547e22f42dSJohnny Huang pass = 0; 22557e22f42dSJohnny Huang 225669d5fd8fSJohnny Huang for (j = 0; j < RETRY; j++) { 2257a6d0d645SJohnny Huang if (verify_bit(prog_address, offset, 1) == 0) { 225869d5fd8fSJohnny Huang pass = 1; 225969d5fd8fSJohnny Huang break; 226069d5fd8fSJohnny Huang } 22617e22f42dSJohnny Huang if (soak == 0) { 226269d5fd8fSJohnny Huang soak = 1; 22637e22f42dSJohnny Huang otp_soak(1); 22644b65a65dSJohnny Huang } 226569d5fd8fSJohnny Huang otp_prog(prog_address, prog_bit); 226669d5fd8fSJohnny Huang } 226769d5fd8fSJohnny Huang if (!pass) 22682a856b9aSJohnny Huang return OTP_FAILURE; 226969d5fd8fSJohnny Huang 227069d5fd8fSJohnny Huang if (pbit == 0) 227169d5fd8fSJohnny Huang continue; 227269d5fd8fSJohnny Huang prog_address = 0x800; 227369d5fd8fSJohnny Huang if (i < 32) 227469d5fd8fSJohnny Huang prog_address |= 0x60c; 227569d5fd8fSJohnny Huang else 227669d5fd8fSJohnny Huang prog_address |= 0x60e; 227769d5fd8fSJohnny Huang 22787e22f42dSJohnny Huang 22797e22f42dSJohnny Huang if (soak) { 22807e22f42dSJohnny Huang soak = 0; 22817e22f42dSJohnny Huang otp_soak(0); 22827e22f42dSJohnny Huang } 22837e22f42dSJohnny Huang 22847e22f42dSJohnny Huang otp_prog(prog_address, prog_bit); 22857e22f42dSJohnny Huang 22867e22f42dSJohnny Huang pass = 0; 22877e22f42dSJohnny Huang 228869d5fd8fSJohnny Huang for (j = 0; j < RETRY; j++) { 22897e22f42dSJohnny Huang 2290a6d0d645SJohnny Huang if (verify_bit(prog_address, offset, 1) == 0) { 229169d5fd8fSJohnny Huang pass = 1; 229269d5fd8fSJohnny Huang break; 229369d5fd8fSJohnny Huang } 22947e22f42dSJohnny Huang if (soak == 0) { 229569d5fd8fSJohnny Huang soak = 1; 22967e22f42dSJohnny Huang otp_soak(1); 229769d5fd8fSJohnny Huang } 229869d5fd8fSJohnny Huang otp_prog(prog_address, prog_bit); 229969d5fd8fSJohnny Huang } 230069d5fd8fSJohnny Huang if (!pass) 23012a856b9aSJohnny Huang return OTP_FAILURE; 230269d5fd8fSJohnny Huang 230369d5fd8fSJohnny Huang } 230469d5fd8fSJohnny Huang if (fail == 1) 23052a856b9aSJohnny Huang return OTP_FAILURE; 230669d5fd8fSJohnny Huang else 23072a856b9aSJohnny Huang return OTP_SUCCESS; 230869d5fd8fSJohnny Huang 230969d5fd8fSJohnny Huang } 231069d5fd8fSJohnny Huang 2311cd1610b4SJohnny Huang static void otp_prog_bit(uint32_t value, uint32_t prog_address, uint32_t bit_offset, int soak) 2312cd1610b4SJohnny Huang { 2313cd1610b4SJohnny Huang int prog_bit; 2314cd1610b4SJohnny Huang 23157e22f42dSJohnny Huang otp_soak(soak); 23167e22f42dSJohnny Huang 2317cd1610b4SJohnny Huang if (prog_address % 2 == 0) { 2318cd1610b4SJohnny Huang if (value) 2319cd1610b4SJohnny Huang prog_bit = ~(0x1 << bit_offset); 2320cd1610b4SJohnny Huang else 2321cd1610b4SJohnny Huang return; 2322cd1610b4SJohnny Huang } else { 2323cd1610b4SJohnny Huang prog_address |= 1 << 15; 2324cd1610b4SJohnny Huang if (!value) 2325cd1610b4SJohnny Huang prog_bit = 0x1 << bit_offset; 2326cd1610b4SJohnny Huang else 2327cd1610b4SJohnny Huang return; 2328cd1610b4SJohnny Huang } 2329cd1610b4SJohnny Huang otp_prog(prog_address, prog_bit); 2330cd1610b4SJohnny Huang } 2331cd1610b4SJohnny Huang 2332d90825e2SJohnny Huang static int otp_prog_data(uint32_t *buf) 23334c1c9b35SJohnny Huang { 23344c1c9b35SJohnny Huang int i, k; 23354c1c9b35SJohnny Huang int pass; 2336d90825e2SJohnny Huang int soak = 0; 23374c1c9b35SJohnny Huang uint32_t prog_address; 2338d90825e2SJohnny Huang uint32_t data[2048]; 23394c1c9b35SJohnny Huang uint32_t compare[2]; 2340d90825e2SJohnny Huang uint32_t *buf_keep = &buf[2048]; 23414c1c9b35SJohnny Huang 2342d90825e2SJohnny Huang uint32_t data0_masked; 2343d90825e2SJohnny Huang uint32_t data1_masked; 2344d90825e2SJohnny Huang uint32_t buf0_masked; 2345d90825e2SJohnny Huang uint32_t buf1_masked; 23464c1c9b35SJohnny Huang 23474c1c9b35SJohnny Huang printf("Read OTP Data:\n"); 23484c1c9b35SJohnny Huang 2349d90825e2SJohnny Huang printProgress(0, 2048, ""); 2350d90825e2SJohnny Huang for (i = 0; i < 2048 ; i += 2) { 2351d90825e2SJohnny Huang printProgress(i + 2, 2048, ""); 2352d90825e2SJohnny Huang otp_read_data(i, &data[i]); 23534c1c9b35SJohnny Huang } 2354d90825e2SJohnny Huang 23554c1c9b35SJohnny Huang 23564c1c9b35SJohnny Huang printf("Check writable...\n"); 2357d90825e2SJohnny Huang for (i = 0; i < 2048; i++) { 2358d90825e2SJohnny Huang data0_masked = data[i] & ~buf_keep[i]; 2359d90825e2SJohnny Huang buf0_masked = buf[i] & ~buf_keep[i]; 2360d90825e2SJohnny Huang if (data0_masked == buf0_masked) 23614c1c9b35SJohnny Huang continue; 2362d90825e2SJohnny Huang if (i % 2 == 0) { 2363d90825e2SJohnny Huang if ((data0_masked | buf0_masked) == buf0_masked) { 23644c1c9b35SJohnny Huang continue; 23654c1c9b35SJohnny Huang } else { 23664c1c9b35SJohnny Huang printf("Input image can't program into OTP, please check.\n"); 2367d90825e2SJohnny Huang printf("OTP_ADDR[%x] = %x\n", i, data[i]); 23684c1c9b35SJohnny Huang printf("Input [%x] = %x\n", i, buf[i]); 2369d90825e2SJohnny Huang printf("Mask [%x] = %x\n", i, ~buf_keep[i]); 23702a856b9aSJohnny Huang return OTP_FAILURE; 237169d5fd8fSJohnny Huang } 2372d90825e2SJohnny Huang } else { 2373d90825e2SJohnny Huang if ((data0_masked & buf0_masked) == buf0_masked) { 2374d90825e2SJohnny Huang continue; 2375d90825e2SJohnny Huang } else { 2376d90825e2SJohnny Huang printf("Input image can't program into OTP, please check.\n"); 2377d90825e2SJohnny Huang printf("OTP_ADDR[%x] = %x\n", i, data[i]); 2378d90825e2SJohnny Huang printf("Input [%x] = %x\n", i, buf[i]); 2379d90825e2SJohnny Huang printf("Mask [%x] = %x\n", i, ~buf_keep[i]); 23802a856b9aSJohnny Huang return OTP_FAILURE; 2381d90825e2SJohnny Huang } 2382d90825e2SJohnny Huang } 2383d90825e2SJohnny Huang } 238469d5fd8fSJohnny Huang 2385d90825e2SJohnny Huang printf("Start Programing...\n"); 2386d90825e2SJohnny Huang printProgress(0, 2048, ""); 2387d90825e2SJohnny Huang 2388d90825e2SJohnny Huang for (i = 0; i < 2048; i += 2) { 2389d90825e2SJohnny Huang prog_address = i; 2390d90825e2SJohnny Huang data0_masked = data[i] & ~buf_keep[i]; 2391d90825e2SJohnny Huang buf0_masked = buf[i] & ~buf_keep[i]; 2392d90825e2SJohnny Huang data1_masked = data[i + 1] & ~buf_keep[i + 1]; 2393d90825e2SJohnny Huang buf1_masked = buf[i + 1] & ~buf_keep[i + 1]; 2394d90825e2SJohnny Huang if ((data0_masked == buf0_masked) && (data1_masked == buf1_masked)) { 2395d90825e2SJohnny Huang printProgress(i + 2, 2048, "[%03X]=%08X HIT;[%03X]=%08X HIT", prog_address, buf[i], prog_address + 1, buf[i + 1]); 2396d90825e2SJohnny Huang continue; 2397d90825e2SJohnny Huang } 2398d90825e2SJohnny Huang if (soak) { 2399d90825e2SJohnny Huang soak = 0; 2400d90825e2SJohnny Huang otp_soak(0); 2401d90825e2SJohnny Huang } 2402d90825e2SJohnny Huang if (data1_masked == buf1_masked) { 2403d90825e2SJohnny Huang printProgress(i + 2, 2048, "[%03X]=%08X ;[%03X]=%08X HIT", prog_address, buf[i], prog_address + 1, buf[i + 1]); 2404d90825e2SJohnny Huang otp_prog_dw(buf[i], buf_keep[i], prog_address); 2405d90825e2SJohnny Huang } else if (data0_masked == buf0_masked) { 2406d90825e2SJohnny Huang printProgress(i + 2, 2048, "[%03X]=%08X HIT;[%03X]=%08X ", prog_address, buf[i], prog_address + 1, buf[i + 1]); 2407d90825e2SJohnny Huang otp_prog_dw(buf[i + 1], buf_keep[i + 1], prog_address + 1); 2408d90825e2SJohnny Huang } else { 2409d90825e2SJohnny Huang printProgress(i + 2, 2048, "[%03X]=%08X ;[%03X]=%08X ", prog_address, buf[i], prog_address + 1, buf[i + 1]); 2410d90825e2SJohnny Huang otp_prog_dw(buf[i], buf_keep[i], prog_address); 2411d90825e2SJohnny Huang otp_prog_dw(buf[i + 1], buf_keep[i + 1], prog_address + 1); 2412d90825e2SJohnny Huang } 2413d90825e2SJohnny Huang 2414d90825e2SJohnny Huang pass = 0; 2415d90825e2SJohnny Huang for (k = 0; k < RETRY; k++) { 2416d90825e2SJohnny Huang if (verify_dw(prog_address, &buf[i], &buf_keep[i], compare, 2) != 0) { 2417d90825e2SJohnny Huang if (soak == 0) { 2418d90825e2SJohnny Huang soak = 1; 2419d90825e2SJohnny Huang otp_soak(1); 2420d90825e2SJohnny Huang } 2421d90825e2SJohnny Huang if (compare[0] != 0) { 2422d90825e2SJohnny Huang otp_prog_dw(compare[0], buf_keep[i], prog_address); 2423d90825e2SJohnny Huang } 2424d90825e2SJohnny Huang if (compare[1] != ~0) { 2425d90825e2SJohnny Huang otp_prog_dw(compare[1], buf_keep[i], prog_address + 1); 2426d90825e2SJohnny Huang } 2427d90825e2SJohnny Huang } else { 2428d90825e2SJohnny Huang pass = 1; 2429d90825e2SJohnny Huang break; 2430d90825e2SJohnny Huang } 2431d90825e2SJohnny Huang } 2432d90825e2SJohnny Huang 2433d90825e2SJohnny Huang if (!pass) 24342a856b9aSJohnny Huang return OTP_FAILURE; 2435d90825e2SJohnny Huang } 24362a856b9aSJohnny Huang return OTP_SUCCESS; 2437d90825e2SJohnny Huang 2438d90825e2SJohnny Huang } 2439d90825e2SJohnny Huang 2440d90825e2SJohnny Huang static int do_otp_prog(int addr, int byte_size, int nconfirm) 244169d5fd8fSJohnny Huang { 244269d5fd8fSJohnny Huang int ret; 2443d90825e2SJohnny Huang int mode; 244469d5fd8fSJohnny Huang uint32_t *buf; 2445d90825e2SJohnny Huang uint32_t *data_region = NULL; 2446d90825e2SJohnny Huang uint32_t *conf_region = NULL; 2447d90825e2SJohnny Huang uint32_t *strap_region = NULL; 244869d5fd8fSJohnny Huang 2449d90825e2SJohnny Huang buf = map_physmem(addr, byte_size, MAP_WRBACK); 245069d5fd8fSJohnny Huang if (!buf) { 245169d5fd8fSJohnny Huang puts("Failed to map physical memory\n"); 24522a856b9aSJohnny Huang return OTP_FAILURE; 245369d5fd8fSJohnny Huang } 2454d90825e2SJohnny Huang 2455d90825e2SJohnny Huang if (((buf[0] >> 29) & 0x7) == 0x7) { 2456d90825e2SJohnny Huang mode = OTP_REGION_ALL; 2457d90825e2SJohnny Huang conf_region = &buf[1]; 2458d90825e2SJohnny Huang strap_region = &buf[25]; 2459d90825e2SJohnny Huang data_region = &buf[31]; 2460d90825e2SJohnny Huang } else { 2461d90825e2SJohnny Huang if (buf[0] & BIT(29)) { 2462d90825e2SJohnny Huang mode = OTP_REGION_DATA; 2463d90825e2SJohnny Huang data_region = &buf[31]; 2464d90825e2SJohnny Huang } 2465d90825e2SJohnny Huang if (buf[0] & BIT(30)) { 2466d90825e2SJohnny Huang mode = OTP_REGION_CONF; 2467d90825e2SJohnny Huang strap_region = &buf[25]; 2468d90825e2SJohnny Huang } 2469d90825e2SJohnny Huang if (buf[0] & BIT(31)) { 2470d90825e2SJohnny Huang mode = OTP_REGION_STRAP; 2471d90825e2SJohnny Huang conf_region = &buf[1]; 2472d90825e2SJohnny Huang } 2473d90825e2SJohnny Huang } 247469d5fd8fSJohnny Huang if (!nconfirm) { 2475a6d0d645SJohnny Huang if (mode == OTP_REGION_CONF) { 2476*7f795e57SJohnny Huang printf("\nOTP configuration region :\n"); 247766f2f8e5SJohnny Huang if (otp_print_conf_info(conf_region) < 0) { 247869d5fd8fSJohnny Huang printf("OTP config error, please check.\n"); 24792a856b9aSJohnny Huang return OTP_FAILURE; 248069d5fd8fSJohnny Huang } 2481a6d0d645SJohnny Huang } else if (mode == OTP_REGION_DATA) { 2482*7f795e57SJohnny Huang printf("\nOTP data region :\n"); 2483*7f795e57SJohnny Huang if (otp_print_data_info(data_region) < 0) { 248469d5fd8fSJohnny Huang printf("OTP data error, please check.\n"); 24852a856b9aSJohnny Huang return OTP_FAILURE; 248669d5fd8fSJohnny Huang } 2487a6d0d645SJohnny Huang } else if (mode == OTP_REGION_STRAP) { 2488*7f795e57SJohnny Huang printf("\nOTP strap region :\n"); 2489*7f795e57SJohnny Huang if (otp_print_strap_info(strap_region) < 0) { 249069d5fd8fSJohnny Huang printf("OTP strap error, please check.\n"); 24912a856b9aSJohnny Huang return OTP_FAILURE; 249269d5fd8fSJohnny Huang } 2493a6d0d645SJohnny Huang } else if (mode == OTP_REGION_ALL) { 2494*7f795e57SJohnny Huang printf("\nOTP configuration region :\n"); 249566f2f8e5SJohnny Huang if (otp_print_conf_info(conf_region) < 0) { 249669d5fd8fSJohnny Huang printf("OTP config error, please check.\n"); 24972a856b9aSJohnny Huang return OTP_FAILURE; 249869d5fd8fSJohnny Huang } 2499*7f795e57SJohnny Huang printf("\nOTP strap region :\n"); 2500*7f795e57SJohnny Huang if (otp_print_strap_info(strap_region) < 0) { 250169d5fd8fSJohnny Huang printf("OTP strap error, please check.\n"); 25022a856b9aSJohnny Huang return OTP_FAILURE; 250369d5fd8fSJohnny Huang } 2504*7f795e57SJohnny Huang printf("\nOTP data region :\n"); 2505*7f795e57SJohnny Huang if (otp_print_data_info(data_region) < 0) { 250669d5fd8fSJohnny Huang printf("OTP data error, please check.\n"); 25072a856b9aSJohnny Huang return OTP_FAILURE; 250869d5fd8fSJohnny Huang } 250969d5fd8fSJohnny Huang } 251069d5fd8fSJohnny Huang printf("type \"YES\" (no quotes) to continue:\n"); 251169d5fd8fSJohnny Huang if (!confirm_yesno()) { 251269d5fd8fSJohnny Huang printf(" Aborting\n"); 25132a856b9aSJohnny Huang return OTP_FAILURE; 251469d5fd8fSJohnny Huang } 251569d5fd8fSJohnny Huang } 2516a6d0d645SJohnny Huang if (mode == OTP_REGION_CONF) { 2517d90825e2SJohnny Huang return otp_prog_conf(conf_region); 2518a6d0d645SJohnny Huang } else if (mode == OTP_REGION_STRAP) { 2519d90825e2SJohnny Huang return otp_prog_strap(strap_region); 2520a6d0d645SJohnny Huang } else if (mode == OTP_REGION_DATA) { 2521d90825e2SJohnny Huang return otp_prog_data(data_region); 2522a6d0d645SJohnny Huang } else if (mode == OTP_REGION_ALL) { 252369d5fd8fSJohnny Huang printf("programing data region ... "); 2524d90825e2SJohnny Huang ret = otp_prog_data(data_region); 25252a856b9aSJohnny Huang if (ret != 0) { 252669d5fd8fSJohnny Huang printf("Error\n"); 252769d5fd8fSJohnny Huang return ret; 252869d5fd8fSJohnny Huang } else { 252969d5fd8fSJohnny Huang printf("Done\n"); 253069d5fd8fSJohnny Huang } 253169d5fd8fSJohnny Huang printf("programing strap region ... "); 2532d90825e2SJohnny Huang ret = otp_prog_strap(strap_region); 25332a856b9aSJohnny Huang if (ret != 0) { 253469d5fd8fSJohnny Huang printf("Error\n"); 253569d5fd8fSJohnny Huang return ret; 253669d5fd8fSJohnny Huang } else { 253769d5fd8fSJohnny Huang printf("Done\n"); 253869d5fd8fSJohnny Huang } 253969d5fd8fSJohnny Huang printf("programing configuration region ... "); 2540d90825e2SJohnny Huang ret = otp_prog_conf(conf_region); 25412a856b9aSJohnny Huang if (ret != 0) { 254269d5fd8fSJohnny Huang printf("Error\n"); 254369d5fd8fSJohnny Huang return ret; 254469d5fd8fSJohnny Huang } 254569d5fd8fSJohnny Huang printf("Done\n"); 25462a856b9aSJohnny Huang return OTP_SUCCESS; 254769d5fd8fSJohnny Huang } 2548cd1610b4SJohnny Huang 25492a856b9aSJohnny Huang return OTP_USAGE; 25502a856b9aSJohnny Huang } 25512a856b9aSJohnny Huang 25522a856b9aSJohnny Huang static int do_otp_prog_bit(int mode, int otp_dw_offset, int bit_offset, int value, int nconfirm) 2553cd1610b4SJohnny Huang { 2554a6af4a17SJohnny Huang uint32_t read[2]; 2555cd1610b4SJohnny Huang uint32_t strap_buf[6]; 2556d90825e2SJohnny Huang uint32_t prog_address = 0; 255766f2f8e5SJohnny Huang struct otpstrap_status otpstrap[64]; 2558cd1610b4SJohnny Huang int otp_bit; 2559cd1610b4SJohnny Huang int i; 2560cd1610b4SJohnny Huang int pass; 2561a6af4a17SJohnny Huang int ret; 2562cd1610b4SJohnny Huang 2563cd1610b4SJohnny Huang switch (mode) { 2564a6d0d645SJohnny Huang case OTP_REGION_CONF: 2565a6af4a17SJohnny Huang otp_read_config(otp_dw_offset, read); 2566cd1610b4SJohnny Huang prog_address = 0x800; 2567cd1610b4SJohnny Huang prog_address |= (otp_dw_offset / 8) * 0x200; 2568cd1610b4SJohnny Huang prog_address |= (otp_dw_offset % 8) * 0x2; 2569a6af4a17SJohnny Huang otp_bit = (read[0] >> bit_offset) & 0x1; 2570cd1610b4SJohnny Huang if (otp_bit == value) { 2571a6af4a17SJohnny Huang printf("OTPCFG%X[%X] = %d\n", otp_dw_offset, bit_offset, value); 2572cd1610b4SJohnny Huang printf("No need to program\n"); 25732a856b9aSJohnny Huang return OTP_SUCCESS; 2574cd1610b4SJohnny Huang } 2575cd1610b4SJohnny Huang if (otp_bit == 1 && value == 0) { 2576a6af4a17SJohnny Huang printf("OTPCFG%X[%X] = 1\n", otp_dw_offset, bit_offset); 2577cd1610b4SJohnny Huang printf("OTP is programed, which can't be clean\n"); 25782a856b9aSJohnny Huang return OTP_FAILURE; 2579cd1610b4SJohnny Huang } 2580a6af4a17SJohnny Huang printf("Program OTPCFG%X[%X] to 1\n", otp_dw_offset, bit_offset); 2581cd1610b4SJohnny Huang break; 2582a6d0d645SJohnny Huang case OTP_REGION_DATA: 2583cd1610b4SJohnny Huang prog_address = otp_dw_offset; 2584cd1610b4SJohnny Huang 2585cd1610b4SJohnny Huang if (otp_dw_offset % 2 == 0) { 2586a6af4a17SJohnny Huang otp_read_data(otp_dw_offset, read); 2587a6af4a17SJohnny Huang otp_bit = (read[0] >> bit_offset) & 0x1; 2588cd1610b4SJohnny Huang } else { 2589a6af4a17SJohnny Huang otp_read_data(otp_dw_offset - 1, read); 2590a6af4a17SJohnny Huang otp_bit = (read[1] >> bit_offset) & 0x1; 2591cd1610b4SJohnny Huang } 2592cd1610b4SJohnny Huang if (otp_bit == value) { 2593a6af4a17SJohnny Huang printf("OTPDATA%X[%X] = %d\n", otp_dw_offset, bit_offset, value); 2594cd1610b4SJohnny Huang printf("No need to program\n"); 25952a856b9aSJohnny Huang return OTP_SUCCESS; 2596cd1610b4SJohnny Huang } 2597cd1610b4SJohnny Huang if (otp_bit == 1 && value == 0) { 2598a6af4a17SJohnny Huang printf("OTPDATA%X[%X] = 1\n", otp_dw_offset, bit_offset); 2599cd1610b4SJohnny Huang printf("OTP is programed, which can't be clean\n"); 26002a856b9aSJohnny Huang return OTP_FAILURE; 2601cd1610b4SJohnny Huang } 2602a6af4a17SJohnny Huang printf("Program OTPDATA%X[%X] to 1\n", otp_dw_offset, bit_offset); 2603cd1610b4SJohnny Huang break; 2604a6d0d645SJohnny Huang case OTP_REGION_STRAP: 2605cd1610b4SJohnny Huang otp_strp_status(otpstrap); 2606cd1610b4SJohnny Huang otp_print_strap(bit_offset, 1); 2607cd1610b4SJohnny Huang if (bit_offset < 32) { 2608cd1610b4SJohnny Huang strap_buf[0] = value << bit_offset; 2609cd1610b4SJohnny Huang strap_buf[2] = ~BIT(bit_offset); 2610cd1610b4SJohnny Huang strap_buf[3] = ~0; 2611cd1610b4SJohnny Huang strap_buf[5] = 0; 26122a856b9aSJohnny Huang // if (protect) 26132a856b9aSJohnny Huang // strap_buf[4] = BIT(bit_offset); 26142a856b9aSJohnny Huang // else 26152a856b9aSJohnny Huang // strap_buf[4] = 0; 2616cd1610b4SJohnny Huang } else { 2617cd1610b4SJohnny Huang strap_buf[1] = value << (bit_offset - 32); 2618cd1610b4SJohnny Huang strap_buf[2] = ~0; 2619cd1610b4SJohnny Huang strap_buf[3] = ~BIT(bit_offset - 32); 2620cd1610b4SJohnny Huang strap_buf[4] = 0; 26212a856b9aSJohnny Huang // if (protect) 26222a856b9aSJohnny Huang // strap_buf[5] = BIT(bit_offset - 32); 26232a856b9aSJohnny Huang // else 26242a856b9aSJohnny Huang // strap_buf[5] = 0; 2625cd1610b4SJohnny Huang } 262676d13988SJohnny Huang ret = otp_strap_image_confirm(strap_buf); 2627a6af4a17SJohnny Huang if (ret == OTP_FAILURE) 26282a856b9aSJohnny Huang return OTP_FAILURE; 2629a6af4a17SJohnny Huang else if (ret == OTP_PROG_SKIP) 2630a6af4a17SJohnny Huang return OTP_SUCCESS; 2631a6af4a17SJohnny Huang 2632cd1610b4SJohnny Huang break; 2633cd1610b4SJohnny Huang } 2634cd1610b4SJohnny Huang 2635cd1610b4SJohnny Huang if (!nconfirm) { 2636cd1610b4SJohnny Huang printf("type \"YES\" (no quotes) to continue:\n"); 2637cd1610b4SJohnny Huang if (!confirm_yesno()) { 2638cd1610b4SJohnny Huang printf(" Aborting\n"); 26392a856b9aSJohnny Huang return OTP_FAILURE; 2640cd1610b4SJohnny Huang } 2641cd1610b4SJohnny Huang } 2642cd1610b4SJohnny Huang 2643cd1610b4SJohnny Huang switch (mode) { 2644a6d0d645SJohnny Huang case OTP_REGION_STRAP: 2645cd1610b4SJohnny Huang return otp_prog_strap(strap_buf); 2646a6d0d645SJohnny Huang case OTP_REGION_CONF: 2647a6d0d645SJohnny Huang case OTP_REGION_DATA: 2648cd1610b4SJohnny Huang otp_prog_bit(value, prog_address, bit_offset, 0); 2649cd1610b4SJohnny Huang pass = -1; 2650cd1610b4SJohnny Huang for (i = 0; i < RETRY; i++) { 2651a6d0d645SJohnny Huang if (verify_bit(prog_address, bit_offset, value) != 0) { 2652cd1610b4SJohnny Huang otp_prog_bit(value, prog_address, bit_offset, 1); 2653cd1610b4SJohnny Huang } else { 2654cd1610b4SJohnny Huang pass = 0; 2655cd1610b4SJohnny Huang break; 2656cd1610b4SJohnny Huang } 2657cd1610b4SJohnny Huang } 26582a856b9aSJohnny Huang if (pass == 0) 26592a856b9aSJohnny Huang return OTP_SUCCESS; 2660cd1610b4SJohnny Huang } 2661cd1610b4SJohnny Huang 26622a856b9aSJohnny Huang return OTP_USAGE; 2663cd1610b4SJohnny Huang } 2664cd1610b4SJohnny Huang 26652a856b9aSJohnny Huang static int do_otpread(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) 266669d5fd8fSJohnny Huang { 26672a856b9aSJohnny Huang uint32_t offset, count; 26682a856b9aSJohnny Huang int ret; 266969d5fd8fSJohnny Huang 26702a856b9aSJohnny Huang if (argc == 4) { 26712a856b9aSJohnny Huang offset = simple_strtoul(argv[2], NULL, 16); 26722a856b9aSJohnny Huang count = simple_strtoul(argv[3], NULL, 16); 26732a856b9aSJohnny Huang } else if (argc == 3) { 26742a856b9aSJohnny Huang offset = simple_strtoul(argv[2], NULL, 16); 26752a856b9aSJohnny Huang count = 1; 26762a856b9aSJohnny Huang } else { 267769d5fd8fSJohnny Huang return CMD_RET_USAGE; 267869d5fd8fSJohnny Huang } 267969d5fd8fSJohnny Huang 268069d5fd8fSJohnny Huang 26812a856b9aSJohnny Huang if (!strcmp(argv[1], "conf")) { 268269d5fd8fSJohnny Huang writel(OTP_PASSWD, 0x1e6f2000); //password 26832a856b9aSJohnny Huang ret = otp_print_config(offset, count); 26842a856b9aSJohnny Huang } else if (!strcmp(argv[1], "data")) { 26852a856b9aSJohnny Huang writel(OTP_PASSWD, 0x1e6f2000); //password 26862a856b9aSJohnny Huang ret = otp_print_data(offset, count); 26872a856b9aSJohnny Huang } else if (!strcmp(argv[1], "strap")) { 26882a856b9aSJohnny Huang writel(OTP_PASSWD, 0x1e6f2000); //password 26892a856b9aSJohnny Huang ret = otp_print_strap(offset, count); 26902a856b9aSJohnny Huang } else { 26912a856b9aSJohnny Huang return CMD_RET_USAGE; 269269d5fd8fSJohnny Huang } 269369d5fd8fSJohnny Huang 26942a856b9aSJohnny Huang if (ret == OTP_SUCCESS) 26952a856b9aSJohnny Huang return CMD_RET_SUCCESS; 26962a856b9aSJohnny Huang else 26972a856b9aSJohnny Huang return CMD_RET_USAGE; 26982a856b9aSJohnny Huang 26992a856b9aSJohnny Huang } 27002a856b9aSJohnny Huang 27012a856b9aSJohnny Huang static int do_otpprog(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) 27022a856b9aSJohnny Huang { 27032a856b9aSJohnny Huang phys_addr_t addr; 27042a856b9aSJohnny Huang uint32_t byte_size; 27052a856b9aSJohnny Huang int ret; 27062a856b9aSJohnny Huang 27072a856b9aSJohnny Huang if (argc == 4) { 27082a856b9aSJohnny Huang if (strcmp(argv[1], "f")) 27092a856b9aSJohnny Huang return CMD_RET_USAGE; 27102a856b9aSJohnny Huang addr = simple_strtoul(argv[2], NULL, 16); 27112a856b9aSJohnny Huang byte_size = simple_strtoul(argv[3], NULL, 16); 271269d5fd8fSJohnny Huang writel(OTP_PASSWD, 0x1e6f2000); //password 27132a856b9aSJohnny Huang ret = do_otp_prog(addr, byte_size, 1); 27142a856b9aSJohnny Huang } else if (argc == 3) { 27152a856b9aSJohnny Huang addr = simple_strtoul(argv[1], NULL, 16); 27162a856b9aSJohnny Huang byte_size = simple_strtoul(argv[2], NULL, 16); 27172a856b9aSJohnny Huang writel(OTP_PASSWD, 0x1e6f2000); //password 27182a856b9aSJohnny Huang ret = do_otp_prog(addr, byte_size, 0); 27192a856b9aSJohnny Huang } else { 27202a856b9aSJohnny Huang return CMD_RET_USAGE; 27212a856b9aSJohnny Huang } 27222a856b9aSJohnny Huang 27232a856b9aSJohnny Huang if (ret == OTP_SUCCESS) 27242a856b9aSJohnny Huang return CMD_RET_SUCCESS; 27252a856b9aSJohnny Huang else if (ret == OTP_FAILURE) 27262a856b9aSJohnny Huang return CMD_RET_FAILURE; 27272a856b9aSJohnny Huang else 27282a856b9aSJohnny Huang return CMD_RET_USAGE; 27292a856b9aSJohnny Huang } 27302a856b9aSJohnny Huang 27312a856b9aSJohnny Huang static int do_otppb(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) 27322a856b9aSJohnny Huang { 27332a856b9aSJohnny Huang int mode = 0; 27342a856b9aSJohnny Huang int nconfirm = 0; 27352a856b9aSJohnny Huang int otp_addr = 0; 27362a856b9aSJohnny Huang int bit_offset; 27372a856b9aSJohnny Huang int value; 27382a856b9aSJohnny Huang int ret; 27392a856b9aSJohnny Huang 27402a856b9aSJohnny Huang if (argc != 4 && argc != 5 && argc != 6) 27412a856b9aSJohnny Huang return CMD_RET_USAGE; 27422a856b9aSJohnny Huang 27432a856b9aSJohnny Huang /* Drop the pb cmd */ 27442a856b9aSJohnny Huang argc--; 27452a856b9aSJohnny Huang argv++; 27462a856b9aSJohnny Huang 27472a856b9aSJohnny Huang if (!strcmp(argv[0], "conf")) 2748a6d0d645SJohnny Huang mode = OTP_REGION_CONF; 27492a856b9aSJohnny Huang else if (!strcmp(argv[0], "strap")) 2750a6d0d645SJohnny Huang mode = OTP_REGION_STRAP; 27512a856b9aSJohnny Huang else if (!strcmp(argv[0], "data")) 2752a6d0d645SJohnny Huang mode = OTP_REGION_DATA; 2753cd1610b4SJohnny Huang else 27542a856b9aSJohnny Huang return CMD_RET_USAGE; 27552a856b9aSJohnny Huang 27562a856b9aSJohnny Huang /* Drop the region cmd */ 27572a856b9aSJohnny Huang argc--; 27582a856b9aSJohnny Huang argv++; 27592a856b9aSJohnny Huang 27602a856b9aSJohnny Huang if (!strcmp(argv[0], "f")) { 2761cd1610b4SJohnny Huang nconfirm = 1; 27622a856b9aSJohnny Huang /* Drop the force option */ 27632a856b9aSJohnny Huang argc--; 27642a856b9aSJohnny Huang argv++; 27652a856b9aSJohnny Huang } 2766cd1610b4SJohnny Huang 2767a6d0d645SJohnny Huang if (mode == OTP_REGION_STRAP) { 27682a856b9aSJohnny Huang bit_offset = simple_strtoul(argv[0], NULL, 16); 27692a856b9aSJohnny Huang value = simple_strtoul(argv[1], NULL, 16); 2770cd1610b4SJohnny Huang if (bit_offset >= 64) 27712a856b9aSJohnny Huang return CMD_RET_USAGE; 2772cd1610b4SJohnny Huang } else { 27732a856b9aSJohnny Huang otp_addr = simple_strtoul(argv[0], NULL, 16); 27742a856b9aSJohnny Huang bit_offset = simple_strtoul(argv[1], NULL, 16); 27752a856b9aSJohnny Huang value = simple_strtoul(argv[2], NULL, 16); 2776cd1610b4SJohnny Huang if (bit_offset >= 32) 27772a856b9aSJohnny Huang return CMD_RET_USAGE; 2778cd1610b4SJohnny Huang } 2779cd1610b4SJohnny Huang if (value != 0 && value != 1) 27802a856b9aSJohnny Huang return CMD_RET_USAGE; 2781cd1610b4SJohnny Huang 2782cd1610b4SJohnny Huang writel(OTP_PASSWD, 0x1e6f2000); //password 27832a856b9aSJohnny Huang ret = do_otp_prog_bit(mode, otp_addr, bit_offset, value, nconfirm); 27842a856b9aSJohnny Huang 27852a856b9aSJohnny Huang if (ret == OTP_SUCCESS) 27862a856b9aSJohnny Huang return CMD_RET_SUCCESS; 27872a856b9aSJohnny Huang else if (ret == OTP_FAILURE) 27882a856b9aSJohnny Huang return CMD_RET_FAILURE; 27892a856b9aSJohnny Huang else 27902a856b9aSJohnny Huang return CMD_RET_USAGE; 27912a856b9aSJohnny Huang } 27922a856b9aSJohnny Huang 27932a856b9aSJohnny Huang static int do_otpcmp(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) 27942a856b9aSJohnny Huang { 27952a856b9aSJohnny Huang phys_addr_t addr; 27962a856b9aSJohnny Huang int otp_addr = 0; 27972a856b9aSJohnny Huang 27982a856b9aSJohnny Huang if (argc != 3) 27992a856b9aSJohnny Huang return CMD_RET_USAGE; 28002a856b9aSJohnny Huang 280169d5fd8fSJohnny Huang writel(OTP_PASSWD, 0x1e6f2000); //password 28022a856b9aSJohnny Huang addr = simple_strtoul(argv[1], NULL, 16); 28032a856b9aSJohnny Huang otp_addr = simple_strtoul(argv[2], NULL, 16); 28042a856b9aSJohnny Huang if (otp_compare(otp_addr, addr) == 0) { 280569d5fd8fSJohnny Huang printf("Compare pass\n"); 28062a856b9aSJohnny Huang return CMD_RET_SUCCESS; 280769d5fd8fSJohnny Huang } else { 280869d5fd8fSJohnny Huang printf("Compare fail\n"); 28092a856b9aSJohnny Huang return CMD_RET_FAILURE; 281069d5fd8fSJohnny Huang } 281169d5fd8fSJohnny Huang } 281269d5fd8fSJohnny Huang 281366f2f8e5SJohnny Huang static int do_otpinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) 281466f2f8e5SJohnny Huang { 281566f2f8e5SJohnny Huang if (argc != 2) 281666f2f8e5SJohnny Huang return CMD_RET_USAGE; 281766f2f8e5SJohnny Huang 281866f2f8e5SJohnny Huang 281966f2f8e5SJohnny Huang if (!strcmp(argv[1], "conf")) { 282066f2f8e5SJohnny Huang writel(OTP_PASSWD, 0x1e6f2000); //password 282166f2f8e5SJohnny Huang otp_info_config(); 282266f2f8e5SJohnny Huang } else if (!strcmp(argv[1], "strap")) { 282366f2f8e5SJohnny Huang writel(OTP_PASSWD, 0x1e6f2000); //password 282476d13988SJohnny Huang otp_info_strap(); 282566f2f8e5SJohnny Huang } else { 282666f2f8e5SJohnny Huang return CMD_RET_USAGE; 282766f2f8e5SJohnny Huang } 282866f2f8e5SJohnny Huang 282966f2f8e5SJohnny Huang return CMD_RET_SUCCESS; 283066f2f8e5SJohnny Huang } 283166f2f8e5SJohnny Huang 2832737ed20bSJohnny Huang static int do_otpprotect(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) 2833737ed20bSJohnny Huang { 2834737ed20bSJohnny Huang int input; 2835737ed20bSJohnny Huang int bit_offset; 2836737ed20bSJohnny Huang int prog_address; 2837737ed20bSJohnny Huang int pass; 2838737ed20bSJohnny Huang int i; 2839737ed20bSJohnny Huang if (argc != 3 && argc != 2) 2840737ed20bSJohnny Huang return CMD_RET_USAGE; 2841737ed20bSJohnny Huang 2842737ed20bSJohnny Huang if (!strcmp(argv[0], "f")) { 2843737ed20bSJohnny Huang input = simple_strtoul(argv[2], NULL, 16); 2844737ed20bSJohnny Huang } else { 2845737ed20bSJohnny Huang input = simple_strtoul(argv[1], NULL, 16); 2846737ed20bSJohnny Huang printf("OTPSTRAP[%d] will be protected\n", input); 2847737ed20bSJohnny Huang printf("type \"YES\" (no quotes) to continue:\n"); 2848737ed20bSJohnny Huang if (!confirm_yesno()) { 2849737ed20bSJohnny Huang printf(" Aborting\n"); 2850737ed20bSJohnny Huang return CMD_RET_FAILURE; 2851737ed20bSJohnny Huang } 2852737ed20bSJohnny Huang } 2853737ed20bSJohnny Huang 2854737ed20bSJohnny Huang prog_address = 0x800; 2855737ed20bSJohnny Huang if (input < 32) { 2856737ed20bSJohnny Huang bit_offset = input; 2857737ed20bSJohnny Huang prog_address |= 0x60c; 2858737ed20bSJohnny Huang } else if (input < 64) { 2859737ed20bSJohnny Huang bit_offset = input - 32; 2860737ed20bSJohnny Huang prog_address |= 0x60e; 2861737ed20bSJohnny Huang } else { 2862737ed20bSJohnny Huang return CMD_RET_USAGE; 2863737ed20bSJohnny Huang } 2864737ed20bSJohnny Huang 2865737ed20bSJohnny Huang if (verify_bit(prog_address, bit_offset, 1) == 0) { 2866737ed20bSJohnny Huang printf("OTPSTRAP[%d] already protected\n", input); 2867737ed20bSJohnny Huang } 2868737ed20bSJohnny Huang otp_prog_bit(1, prog_address, bit_offset, 0); 2869737ed20bSJohnny Huang pass = -1; 2870737ed20bSJohnny Huang for (i = 0; i < RETRY; i++) { 2871737ed20bSJohnny Huang if (verify_bit(prog_address, bit_offset, 1) != 0) { 2872737ed20bSJohnny Huang otp_prog_bit(1, prog_address, bit_offset, 1); 2873737ed20bSJohnny Huang } else { 2874737ed20bSJohnny Huang pass = 0; 2875737ed20bSJohnny Huang break; 2876737ed20bSJohnny Huang } 2877737ed20bSJohnny Huang } 2878737ed20bSJohnny Huang if (pass == 0) { 2879737ed20bSJohnny Huang printf("OTPSTRAP[%d] is protected\n", input); 2880737ed20bSJohnny Huang return CMD_RET_SUCCESS; 2881737ed20bSJohnny Huang } 2882737ed20bSJohnny Huang 2883737ed20bSJohnny Huang printf("Protect OTPSTRAP[%d] fail\n", input); 2884737ed20bSJohnny Huang return CMD_RET_FAILURE; 2885737ed20bSJohnny Huang 2886737ed20bSJohnny Huang } 28872a856b9aSJohnny Huang static cmd_tbl_t cmd_otp[] = { 28882a856b9aSJohnny Huang U_BOOT_CMD_MKENT(read, 4, 0, do_otpread, "", ""), 2889737ed20bSJohnny Huang U_BOOT_CMD_MKENT(info, 2, 0, do_otpinfo, "", ""), 28902a856b9aSJohnny Huang U_BOOT_CMD_MKENT(prog, 4, 0, do_otpprog, "", ""), 28912a856b9aSJohnny Huang U_BOOT_CMD_MKENT(pb, 6, 0, do_otppb, "", ""), 2892737ed20bSJohnny Huang U_BOOT_CMD_MKENT(protect, 3, 0, do_otpprotect, "", ""), 28932a856b9aSJohnny Huang U_BOOT_CMD_MKENT(cmp, 3, 0, do_otpcmp, "", ""), 28942a856b9aSJohnny Huang }; 28952a856b9aSJohnny Huang 28962a856b9aSJohnny Huang static int do_ast_otp(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) 28972a856b9aSJohnny Huang { 28982a856b9aSJohnny Huang cmd_tbl_t *cp; 28992a856b9aSJohnny Huang 29002a856b9aSJohnny Huang cp = find_cmd_tbl(argv[1], cmd_otp, ARRAY_SIZE(cmd_otp)); 29012a856b9aSJohnny Huang 2902737ed20bSJohnny Huang /* Drop the otp command */ 29032a856b9aSJohnny Huang argc--; 29042a856b9aSJohnny Huang argv++; 29052a856b9aSJohnny Huang 29062a856b9aSJohnny Huang if (cp == NULL || argc > cp->maxargs) 29072a856b9aSJohnny Huang return CMD_RET_USAGE; 29082a856b9aSJohnny Huang if (flag == CMD_FLAG_REPEAT && !cmd_is_repeatable(cp)) 29092a856b9aSJohnny Huang return CMD_RET_SUCCESS; 29102a856b9aSJohnny Huang 29112a856b9aSJohnny Huang return cp->cmd(cmdtp, flag, argc, argv); 291269d5fd8fSJohnny Huang } 291369d5fd8fSJohnny Huang 291469d5fd8fSJohnny Huang U_BOOT_CMD( 291569d5fd8fSJohnny Huang otp, 7, 0, do_ast_otp, 291669d5fd8fSJohnny Huang "ASPEED One-Time-Programmable sub-system", 29172a856b9aSJohnny Huang "read conf|data <otp_dw_offset> <dw_count>\n" 29182a856b9aSJohnny Huang "otp read strap <strap_bit_offset> <bit_count>\n" 291976d13988SJohnny Huang "otp info conf|strap\n" 2920d90825e2SJohnny Huang "otp prog [f] <addr> <byte_size>\n" 2921cd1610b4SJohnny Huang "otp pb conf|data [f] <otp_dw_offset> <bit_offset> <value>\n" 2922737ed20bSJohnny Huang "otp pb strap [f] <bit_offset> <value>\n" 2923737ed20bSJohnny Huang "otp protect [f] <bit_offset>\n" 29242a856b9aSJohnny Huang "otp cmp <addr> <otp_dw_offset>\n" 292569d5fd8fSJohnny Huang ); 2926