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> 23696656c6SJohnny Huang #include <u-boot/sha256.h> 2469d5fd8fSJohnny Huang 2569d5fd8fSJohnny Huang DECLARE_GLOBAL_DATA_PTR; 2669d5fd8fSJohnny Huang 2769d5fd8fSJohnny Huang #define OTP_PASSWD 0x349fe38a 2869d5fd8fSJohnny Huang #define RETRY 3 297332532cSJohnny Huang #define OTP_REGION_STRAP BIT(0) 307332532cSJohnny Huang #define OTP_REGION_CONF BIT(1) 317332532cSJohnny Huang #define OTP_REGION_DATA BIT(2) 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 399a4fe690SJohnny Huang #define OTP_KEY_TYPE_RSA 1 409a4fe690SJohnny Huang #define OTP_KEY_TYPE_AES 2 419a4fe690SJohnny Huang #define OTP_KEY_TYPE_VAULT 3 429a4fe690SJohnny Huang #define OTP_KEY_TYPE_HMAC 4 439a4fe690SJohnny Huang 449a4fe690SJohnny Huang 45a8bd6d8cSJohnny Huang #define OTP_REG_RESERVED -1 46b458cd62SJohnny Huang #define OTP_REG_VALUE -2 47b458cd62SJohnny Huang #define OTP_REG_VALID_BIT -3 4876d13988SJohnny Huang 494c1c9b35SJohnny Huang #define PBSTR "||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||" 504c1c9b35SJohnny Huang #define PBWIDTH 60 514c1c9b35SJohnny Huang 523d3688adSJohnny Huang #define OTP_BASE 0x1e6f2000 533d3688adSJohnny Huang #define OTP_PROTECT_KEY OTP_BASE 543d3688adSJohnny Huang #define OTP_COMMAND OTP_BASE + 0x4 553d3688adSJohnny Huang #define OTP_TIMING OTP_BASE + 0x8 563d3688adSJohnny Huang #define OTP_ADDR OTP_BASE + 0x10 573d3688adSJohnny Huang #define OTP_STATUS OTP_BASE + 0x14 583d3688adSJohnny Huang #define OTP_COMPARE_1 OTP_BASE + 0x20 593d3688adSJohnny Huang #define OTP_COMPARE_2 OTP_BASE + 0x24 603d3688adSJohnny Huang #define OTP_COMPARE_3 OTP_BASE + 0x28 613d3688adSJohnny Huang #define OTP_COMPARE_4 OTP_BASE + 0x2c 623d3688adSJohnny Huang 63696656c6SJohnny Huang #define OTP_MAGIC "SOCOTP" 64696656c6SJohnny Huang #define CHECKSUM_LEN 32 65696656c6SJohnny Huang #define OTP_INC_DATA (1 << 31) 66696656c6SJohnny Huang #define OTP_INC_CONFIG (1 << 30) 67696656c6SJohnny Huang #define OTP_INC_STRAP (1 << 29) 68696656c6SJohnny Huang #define OTP_ECC_EN (1 << 28) 69696656c6SJohnny Huang #define OTP_REGION_SIZE(info) ((info >> 16) & 0xffff) 70696656c6SJohnny Huang #define OTP_REGION_OFFSET(info) (info & 0xffff) 71696656c6SJohnny Huang #define OTP_IMAGE_SIZE(info) (info & 0xffff) 72696656c6SJohnny Huang 73696656c6SJohnny Huang #define OTP_AST2600A0 0 74696656c6SJohnny Huang #define OTP_AST2600A1 1 75*5fdde29fSJohnny Huang #define OTP_AST2600A2 7 // fpga 76696656c6SJohnny Huang 77696656c6SJohnny Huang struct otp_header { 78696656c6SJohnny Huang u8 otp_magic[8]; 79696656c6SJohnny Huang u8 otp_version[8]; 80696656c6SJohnny Huang u32 image_info; 81696656c6SJohnny Huang u32 data_info; 82696656c6SJohnny Huang u32 config_info; 83696656c6SJohnny Huang u32 strap_info; 84696656c6SJohnny Huang u32 checksum_offset; 85696656c6SJohnny Huang } __attribute__((packed)); 86696656c6SJohnny Huang 8766f2f8e5SJohnny Huang struct otpstrap_status { 8869d5fd8fSJohnny Huang int value; 8969d5fd8fSJohnny Huang int option_array[7]; 9069d5fd8fSJohnny Huang int remain_times; 9169d5fd8fSJohnny Huang int writeable_option; 925010032bSJohnny Huang int reg_protected; 9369d5fd8fSJohnny Huang int protected; 9469d5fd8fSJohnny Huang }; 9569d5fd8fSJohnny Huang 9666f2f8e5SJohnny Huang struct otpconf_parse { 9766f2f8e5SJohnny Huang int dw_offset; 9866f2f8e5SJohnny Huang int bit; 9966f2f8e5SJohnny Huang int length; 10066f2f8e5SJohnny Huang int value; 101696656c6SJohnny Huang int ignore; 10266f2f8e5SJohnny Huang char status[80]; 10366f2f8e5SJohnny Huang }; 10466f2f8e5SJohnny Huang 105a8bd6d8cSJohnny Huang struct otpstrap_info { 10679e42a59SJoel Stanley int8_t bit_offset; 10779e42a59SJoel Stanley int8_t length; 10879e42a59SJoel Stanley int8_t value; 10979e42a59SJoel Stanley char *information; 110a8bd6d8cSJohnny Huang }; 111a8bd6d8cSJohnny Huang 112a8bd6d8cSJohnny Huang struct otpconf_info { 11379e42a59SJoel Stanley int8_t dw_offset; 11479e42a59SJoel Stanley int8_t bit_offset; 11579e42a59SJoel Stanley int8_t length; 11679e42a59SJoel Stanley int8_t value; 11779e42a59SJoel Stanley char *information; 118a8bd6d8cSJohnny Huang }; 119a8bd6d8cSJohnny Huang 1209a4fe690SJohnny Huang struct otpkey_type { 1219a4fe690SJohnny Huang int value; 1229a4fe690SJohnny Huang int key_type; 1239a4fe690SJohnny Huang int need_id; 1249a4fe690SJohnny Huang char information[110]; 1259a4fe690SJohnny Huang }; 1269a4fe690SJohnny Huang 1279a4fe690SJohnny Huang struct otp_info_cb { 1289a4fe690SJohnny Huang int version; 12979e42a59SJoel Stanley const struct otpstrap_info *strap_info; 1309a4fe690SJohnny Huang int strap_info_len; 13179e42a59SJoel Stanley const struct otpconf_info *conf_info; 1329a4fe690SJohnny Huang int conf_info_len; 13379e42a59SJoel Stanley const struct otpkey_type *key_info; 1349a4fe690SJohnny Huang int key_info_len; 1355010032bSJohnny Huang 1369a4fe690SJohnny Huang }; 1379a4fe690SJohnny Huang 138696656c6SJohnny Huang struct otp_image_layout { 1395010032bSJohnny Huang int data_length; 1405010032bSJohnny Huang int conf_length; 1415010032bSJohnny Huang int strap_length; 142696656c6SJohnny Huang uint8_t *data; 143696656c6SJohnny Huang uint8_t *data_ignore; 144696656c6SJohnny Huang uint8_t *conf; 145696656c6SJohnny Huang uint8_t *conf_ignore; 146696656c6SJohnny Huang uint8_t *strap; 147696656c6SJohnny Huang uint8_t *strap_reg_pro; 148696656c6SJohnny Huang uint8_t *strap_pro; 149696656c6SJohnny Huang uint8_t *strap_ignore; 150696656c6SJohnny Huang }; 151696656c6SJohnny Huang 1529a4fe690SJohnny Huang static struct otp_info_cb info_cb; 1539a4fe690SJohnny Huang 15479e42a59SJoel Stanley static const struct otpstrap_info a0_strap_info[] = { 15591448c03SJohnny Huang { 0, 1, 0, "Disable secure boot" }, 15691448c03SJohnny Huang { 0, 1, 1, "Enable secure boot" }, 15791448c03SJohnny Huang { 1, 1, 0, "Disable boot from eMMC" }, 15891448c03SJohnny Huang { 1, 1, 1, "Enable boot from eMMC" }, 15991448c03SJohnny Huang { 2, 1, 0, "Disable Boot from debug SPI" }, 16091448c03SJohnny Huang { 2, 1, 1, "Enable Boot from debug SPI" }, 16191448c03SJohnny Huang { 3, 1, 0, "Enable ARM CM3" }, 16291448c03SJohnny Huang { 3, 1, 1, "Disable ARM CM3" }, 163541eb887SJohnny Huang { 4, 1, 0, "No VGA BIOS ROM, VGA BIOS is merged in the system BIOS" }, 16491448c03SJohnny Huang { 4, 1, 1, "Enable dedicated VGA BIOS ROM" }, 16591448c03SJohnny Huang { 5, 1, 0, "MAC 1 : RMII/NCSI" }, 16691448c03SJohnny Huang { 5, 1, 1, "MAC 1 : RGMII" }, 16791448c03SJohnny Huang { 6, 1, 0, "MAC 2 : RMII/NCSI" }, 16891448c03SJohnny Huang { 6, 1, 1, "MAC 2 : RGMII" }, 16991448c03SJohnny Huang { 7, 3, 0, "CPU Frequency : 1GHz" }, 17091448c03SJohnny Huang { 7, 3, 1, "CPU Frequency : 800MHz" }, 17191448c03SJohnny Huang { 7, 3, 2, "CPU Frequency : 1.2GHz" }, 17291448c03SJohnny Huang { 7, 3, 3, "CPU Frequency : 1.4GHz" }, 17391448c03SJohnny Huang { 10, 2, 0, "HCLK ratio AXI:AHB = 2:1" }, 17491448c03SJohnny Huang { 10, 2, 1, "HCLK ratio AXI:AHB = 2:1" }, 17591448c03SJohnny Huang { 10, 2, 2, "HCLK ratio AXI:AHB = 3:1" }, 17691448c03SJohnny Huang { 10, 2, 3, "HCLK ratio AXI:AHB = 4:1" }, 17791448c03SJohnny Huang { 12, 2, 0, "VGA memory size : 8MB" }, 17891448c03SJohnny Huang { 12, 2, 1, "VGA memory size : 16MB" }, 17991448c03SJohnny Huang { 12, 2, 2, "VGA memory size : 32MB" }, 18091448c03SJohnny Huang { 12, 2, 3, "VGA memory size : 64MB" }, 18191448c03SJohnny Huang { 14, 3, OTP_REG_RESERVED, "" }, 18291448c03SJohnny Huang { 17, 1, 0, "VGA class code : Class Code for video device" }, 18391448c03SJohnny Huang { 17, 1, 1, "VGA class code : Class Code for VGA device" }, 18491448c03SJohnny Huang { 18, 1, 0, "Enable debug interfaces 0" }, 18591448c03SJohnny Huang { 18, 1, 1, "Disable debug interfaces 0" }, 18691448c03SJohnny Huang { 19, 1, 0, "Boot from emmc mode : High eMMC speed" }, 18791448c03SJohnny Huang { 19, 1, 1, "Boot from emmc mode : Normal eMMC speed" }, 18891448c03SJohnny Huang { 20, 1, 0, "Enable Pcie EHCI device" }, 18991448c03SJohnny Huang { 20, 1, 1, "Disable Pcie EHCI device" }, 19091448c03SJohnny Huang { 21, 1, 0, "Enable VGA XDMA function" }, 19191448c03SJohnny Huang { 21, 1, 1, "Disable VGA XDMA function" }, 19291448c03SJohnny Huang { 22, 1, 0, "Normal BMC mode" }, 19391448c03SJohnny Huang { 22, 1, 1, "Disable dedicated BMC functions for non-BMC application" }, 19491448c03SJohnny Huang { 23, 1, 0, "SSPRST# pin is for secondary processor dedicated reset pin" }, 19591448c03SJohnny Huang { 23, 1, 1, "SSPRST# pin is for PCIE root complex dedicated reset pin" }, 19691448c03SJohnny Huang { 24, 1, 0, "DRAM types : DDR4" }, 19791448c03SJohnny Huang { 24, 1, 1, "DRAM types : DDR3" }, 19891448c03SJohnny Huang { 25, 5, OTP_REG_RESERVED, "" }, 19991448c03SJohnny Huang { 30, 2, OTP_REG_RESERVED, "" }, 20091448c03SJohnny Huang { 32, 1, 0, "MAC 3 : RMII/NCSI" }, 20191448c03SJohnny Huang { 32, 1, 1, "MAC 3 : RGMII" }, 20291448c03SJohnny Huang { 33, 1, 0, "MAC 4 : RMII/NCSI" }, 20391448c03SJohnny Huang { 33, 1, 1, "MAC 4 : RGMII" }, 20491448c03SJohnny Huang { 34, 1, 0, "SuperIO configuration address : 0x2E" }, 20591448c03SJohnny Huang { 34, 1, 1, "SuperIO configuration address : 0x4E" }, 20691448c03SJohnny Huang { 35, 1, 0, "Enable LPC to decode SuperIO" }, 20791448c03SJohnny Huang { 35, 1, 1, "Disable LPC to decode SuperIO" }, 20891448c03SJohnny Huang { 36, 1, 0, "Enable debug interfaces 1" }, 20991448c03SJohnny Huang { 36, 1, 1, "Disable debug interfaces 1" }, 21091448c03SJohnny Huang { 37, 1, 0, "Disable ACPI function" }, 21191448c03SJohnny Huang { 37, 1, 1, "Enable ACPI function" }, 21291448c03SJohnny Huang { 38, 1, 0, "Enable eSPI mode" }, 21391448c03SJohnny Huang { 38, 1, 1, "Enable LPC mode" }, 21491448c03SJohnny Huang { 39, 1, 0, "Enable SAFS mode" }, 21591448c03SJohnny Huang { 39, 1, 1, "Enable SAFS mode" }, 21691448c03SJohnny Huang { 40, 2, OTP_REG_RESERVED, "" }, 21791448c03SJohnny Huang { 42, 1, 0, "Disable boot SPI 3B/4B address mode auto detection" }, 21891448c03SJohnny Huang { 42, 1, 1, "Enable boot SPI 3B/4B address mode auto detection" }, 21991448c03SJohnny Huang { 43, 1, 0, "Disable boot SPI ABR" }, 22091448c03SJohnny Huang { 43, 1, 1, "Enable boot SPI ABR" }, 22191448c03SJohnny Huang { 44, 1, 0, "Boot SPI ABR mode : dual SPI flash" }, 22291448c03SJohnny Huang { 44, 1, 1, "Boot SPI ABR mode : single SPI flash" }, 22391448c03SJohnny Huang { 45, 3, 0, "Boot SPI flash size : no define size" }, 22491448c03SJohnny Huang { 45, 3, 1, "Boot SPI flash size : 2MB" }, 22591448c03SJohnny Huang { 45, 3, 2, "Boot SPI flash size : 4MB" }, 22691448c03SJohnny Huang { 45, 3, 3, "Boot SPI flash size : 8MB" }, 22791448c03SJohnny Huang { 45, 3, 4, "Boot SPI flash size : 16MB" }, 22891448c03SJohnny Huang { 45, 3, 5, "Boot SPI flash size : 32MB" }, 22991448c03SJohnny Huang { 45, 3, 6, "Boot SPI flash size : 64MB" }, 23091448c03SJohnny Huang { 45, 3, 7, "Boot SPI flash size : 128MB" }, 23191448c03SJohnny Huang { 48, 1, 0, "Disable host SPI ABR" }, 23291448c03SJohnny Huang { 48, 1, 1, "Enable host SPI ABR" }, 23391448c03SJohnny Huang { 49, 1, 0, "Disable host SPI ABR mode select pin" }, 23491448c03SJohnny Huang { 49, 1, 1, "Enable host SPI ABR mode select pin" }, 23591448c03SJohnny Huang { 50, 1, 0, "Host SPI ABR mode : dual SPI flash" }, 23691448c03SJohnny Huang { 50, 1, 1, "Host SPI ABR mode : single SPI flash" }, 23791448c03SJohnny Huang { 51, 3, 0, "Host SPI flash size : no define size" }, 23891448c03SJohnny Huang { 51, 3, 1, "Host SPI flash size : 2MB" }, 23991448c03SJohnny Huang { 51, 3, 2, "Host SPI flash size : 4MB" }, 24091448c03SJohnny Huang { 51, 3, 3, "Host SPI flash size : 8MB" }, 24191448c03SJohnny Huang { 51, 3, 4, "Host SPI flash size : 16MB" }, 24291448c03SJohnny Huang { 51, 3, 5, "Host SPI flash size : 32MB" }, 24391448c03SJohnny Huang { 51, 3, 6, "Host SPI flash size : 64MB" }, 24491448c03SJohnny Huang { 51, 3, 7, "Host SPI flash size : 128MB" }, 24591448c03SJohnny Huang { 54, 1, 0, "Disable boot SPI auxiliary control pins" }, 24691448c03SJohnny Huang { 54, 1, 1, "Enable boot SPI auxiliary control pins" }, 24791448c03SJohnny Huang { 55, 2, 0, "Boot SPI CRTM size : disable CRTM" }, 24891448c03SJohnny Huang { 55, 2, 1, "Boot SPI CRTM size : 256KB" }, 24991448c03SJohnny Huang { 55, 2, 2, "Boot SPI CRTM size : 512KB" }, 25091448c03SJohnny Huang { 55, 2, 3, "Boot SPI CRTM size : 1MB" }, 25191448c03SJohnny Huang { 57, 2, 0, "Host SPI CRTM size : disable CRTM" }, 25291448c03SJohnny Huang { 57, 2, 1, "Host SPI CRTM size : 256KB" }, 25391448c03SJohnny Huang { 57, 2, 2, "Host SPI CRTM size : 512KB" }, 25491448c03SJohnny Huang { 57, 2, 3, "Host SPI CRTM size : 1MB" }, 25591448c03SJohnny Huang { 59, 1, 0, "Disable host SPI auxiliary control pins" }, 25691448c03SJohnny Huang { 59, 1, 1, "Enable host SPI auxiliary control pins" }, 25791448c03SJohnny Huang { 60, 1, 0, "Disable GPIO pass through" }, 25891448c03SJohnny Huang { 60, 1, 1, "Enable GPIO pass through" }, 25991448c03SJohnny Huang { 61, 1, 0, "Enable low security secure boot key" }, 26091448c03SJohnny Huang { 61, 1, 1, "Disable low security secure boot key" }, 26191448c03SJohnny Huang { 62, 1, 0, "Disable dedicate GPIO strap pins" }, 26291448c03SJohnny Huang { 62, 1, 1, "Enable dedicate GPIO strap pins" }, 26391448c03SJohnny Huang { 63, 1, OTP_REG_RESERVED, "" } 26476d13988SJohnny Huang }; 2659a4fe690SJohnny Huang 26679e42a59SJoel Stanley static const struct otpstrap_info a1_strap_info[] = { 2673cb28812SJohnny Huang { 0, 1, 0, "Disable secure boot" }, 2683cb28812SJohnny Huang { 0, 1, 1, "Enable secure boot" }, 2693cb28812SJohnny Huang { 1, 1, 0, "Disable boot from eMMC" }, 2703cb28812SJohnny Huang { 1, 1, 1, "Enable boot from eMMC" }, 2713cb28812SJohnny Huang { 2, 1, 0, "Disable Boot from debug SPI" }, 2723cb28812SJohnny Huang { 2, 1, 1, "Enable Boot from debug SPI" }, 2733cb28812SJohnny Huang { 3, 1, 0, "Enable ARM CM3" }, 2743cb28812SJohnny Huang { 3, 1, 1, "Disable ARM CM3" }, 2753cb28812SJohnny Huang { 4, 1, 0, "No VGA BIOS ROM, VGA BIOS is merged in the system BIOS" }, 2763cb28812SJohnny Huang { 4, 1, 1, "Enable dedicated VGA BIOS ROM" }, 2773cb28812SJohnny Huang { 5, 1, 0, "MAC 1 : RMII/NCSI" }, 2783cb28812SJohnny Huang { 5, 1, 1, "MAC 1 : RGMII" }, 2793cb28812SJohnny Huang { 6, 1, 0, "MAC 2 : RMII/NCSI" }, 2803cb28812SJohnny Huang { 6, 1, 1, "MAC 2 : RGMII" }, 281e1a7245eSJohnny Huang { 7, 3, 0, "CPU Frequency : 1.2GHz" }, 282e1a7245eSJohnny Huang { 7, 3, 1, "CPU Frequency : 1.6MHz" }, 2833cb28812SJohnny Huang { 7, 3, 2, "CPU Frequency : 1.2GHz" }, 284e1a7245eSJohnny Huang { 7, 3, 3, "CPU Frequency : 1.6GHz" }, 285e1a7245eSJohnny Huang { 7, 3, 4, "CPU Frequency : 800MHz" }, 286e1a7245eSJohnny Huang { 7, 3, 5, "CPU Frequency : 800MHz" }, 287e1a7245eSJohnny Huang { 7, 3, 6, "CPU Frequency : 800MHz" }, 288e1a7245eSJohnny Huang { 7, 3, 7, "CPU Frequency : 800MHz" }, 2893cb28812SJohnny Huang { 10, 2, 0, "HCLK ratio AXI:AHB = 2:1" }, 2903cb28812SJohnny Huang { 10, 2, 1, "HCLK ratio AXI:AHB = 2:1" }, 2913cb28812SJohnny Huang { 10, 2, 2, "HCLK ratio AXI:AHB = 3:1" }, 2923cb28812SJohnny Huang { 10, 2, 3, "HCLK ratio AXI:AHB = 4:1" }, 2933cb28812SJohnny Huang { 12, 2, 0, "VGA memory size : 8MB" }, 2943cb28812SJohnny Huang { 12, 2, 1, "VGA memory size : 16MB" }, 2953cb28812SJohnny Huang { 12, 2, 2, "VGA memory size : 32MB" }, 2963cb28812SJohnny Huang { 12, 2, 3, "VGA memory size : 64MB" }, 2973cb28812SJohnny Huang { 14, 3, OTP_REG_RESERVED, "" }, 2983cb28812SJohnny Huang { 17, 1, 0, "VGA class code : Class Code for video device" }, 2993cb28812SJohnny Huang { 17, 1, 1, "VGA class code : Class Code for VGA device" }, 3003cb28812SJohnny Huang { 18, 1, 0, "Enable debug interfaces 0" }, 3013cb28812SJohnny Huang { 18, 1, 1, "Disable debug interfaces 0" }, 3023cb28812SJohnny Huang { 19, 1, 0, "Boot from emmc mode : High eMMC speed" }, 3033cb28812SJohnny Huang { 19, 1, 1, "Boot from emmc mode : Normal eMMC speed" }, 3043cb28812SJohnny Huang { 20, 1, 0, "Disable Pcie EHCI device" }, 3053cb28812SJohnny Huang { 20, 1, 1, "Enable Pcie EHCI device" }, 3063cb28812SJohnny Huang { 21, 1, 0, "Enable VGA XDMA function" }, 3073cb28812SJohnny Huang { 21, 1, 1, "Disable VGA XDMA function" }, 3083cb28812SJohnny Huang { 22, 1, 0, "Normal BMC mode" }, 3093cb28812SJohnny Huang { 22, 1, 1, "Disable dedicated BMC functions for non-BMC application" }, 3103cb28812SJohnny Huang { 23, 1, 0, "SSPRST# pin is for secondary processor dedicated reset pin" }, 3113cb28812SJohnny Huang { 23, 1, 1, "SSPRST# pin is for PCIE root complex dedicated reset pin" }, 3123cb28812SJohnny Huang { 24, 1, 0, "Enable watchdog to reset full chip" }, 3133cb28812SJohnny Huang { 24, 1, 1, "Disable watchdog to reset full chip" }, 3143cb28812SJohnny Huang { 25, 5, OTP_REG_RESERVED, "" }, 3153cb28812SJohnny Huang { 30, 2, OTP_REG_RESERVED, "" }, 3163cb28812SJohnny Huang { 32, 1, 0, "MAC 3 : RMII/NCSI" }, 3173cb28812SJohnny Huang { 32, 1, 1, "MAC 3 : RGMII" }, 3183cb28812SJohnny Huang { 33, 1, 0, "MAC 4 : RMII/NCSI" }, 3193cb28812SJohnny Huang { 33, 1, 1, "MAC 4 : RGMII" }, 3203cb28812SJohnny Huang { 34, 1, 0, "SuperIO configuration address : 0x2E" }, 3213cb28812SJohnny Huang { 34, 1, 1, "SuperIO configuration address : 0x4E" }, 3223cb28812SJohnny Huang { 35, 1, 0, "Enable LPC to decode SuperIO" }, 3233cb28812SJohnny Huang { 35, 1, 1, "Disable LPC to decode SuperIO" }, 3243cb28812SJohnny Huang { 36, 1, 0, "Enable debug interfaces 1" }, 3253cb28812SJohnny Huang { 36, 1, 1, "Disable debug interfaces 1" }, 3263cb28812SJohnny Huang { 37, 1, 0, "Disable ACPI function" }, 3273cb28812SJohnny Huang { 37, 1, 1, "Enable ACPI function" }, 3283cb28812SJohnny Huang { 38, 1, 0, "Enable eSPI mode" }, 3293cb28812SJohnny Huang { 38, 1, 1, "Enable LPC mode" }, 3303cb28812SJohnny Huang { 39, 1, 0, "Enable SAFS mode" }, 3313cb28812SJohnny Huang { 39, 1, 1, "Enable SAFS mode" }, 3323cb28812SJohnny Huang { 40, 2, OTP_REG_RESERVED, "" }, 3333cb28812SJohnny Huang { 42, 1, 0, "Disable boot SPI 3B/4B address mode auto detection" }, 3343cb28812SJohnny Huang { 42, 1, 1, "Enable boot SPI 3B/4B address mode auto detection" }, 3353cb28812SJohnny Huang { 43, 1, 0, "Disable boot SPI ABR" }, 3363cb28812SJohnny Huang { 43, 1, 1, "Enable boot SPI ABR" }, 3373cb28812SJohnny Huang { 44, 1, 0, "Boot SPI ABR mode : dual SPI flash" }, 3383cb28812SJohnny Huang { 44, 1, 1, "Boot SPI ABR mode : single SPI flash" }, 3393cb28812SJohnny Huang { 45, 3, 0, "Boot SPI flash size : no define size" }, 3403cb28812SJohnny Huang { 45, 3, 1, "Boot SPI flash size : 2MB" }, 3413cb28812SJohnny Huang { 45, 3, 2, "Boot SPI flash size : 4MB" }, 3423cb28812SJohnny Huang { 45, 3, 3, "Boot SPI flash size : 8MB" }, 3433cb28812SJohnny Huang { 45, 3, 4, "Boot SPI flash size : 16MB" }, 3443cb28812SJohnny Huang { 45, 3, 5, "Boot SPI flash size : 32MB" }, 3453cb28812SJohnny Huang { 45, 3, 6, "Boot SPI flash size : 64MB" }, 3463cb28812SJohnny Huang { 45, 3, 7, "Boot SPI flash size : 128MB" }, 3473cb28812SJohnny Huang { 48, 1, 0, "Disable host SPI ABR" }, 3483cb28812SJohnny Huang { 48, 1, 1, "Enable host SPI ABR" }, 3493cb28812SJohnny Huang { 49, 1, 0, "Disable host SPI ABR mode select pin" }, 3503cb28812SJohnny Huang { 49, 1, 1, "Enable host SPI ABR mode select pin" }, 3513cb28812SJohnny Huang { 50, 1, 0, "Host SPI ABR mode : dual SPI flash" }, 3523cb28812SJohnny Huang { 50, 1, 1, "Host SPI ABR mode : single SPI flash" }, 3533cb28812SJohnny Huang { 51, 3, 0, "Host SPI flash size : no define size" }, 3543cb28812SJohnny Huang { 51, 3, 1, "Host SPI flash size : 2MB" }, 3553cb28812SJohnny Huang { 51, 3, 2, "Host SPI flash size : 4MB" }, 3563cb28812SJohnny Huang { 51, 3, 3, "Host SPI flash size : 8MB" }, 3573cb28812SJohnny Huang { 51, 3, 4, "Host SPI flash size : 16MB" }, 3583cb28812SJohnny Huang { 51, 3, 5, "Host SPI flash size : 32MB" }, 3593cb28812SJohnny Huang { 51, 3, 6, "Host SPI flash size : 64MB" }, 3603cb28812SJohnny Huang { 51, 3, 7, "Host SPI flash size : 128MB" }, 3613cb28812SJohnny Huang { 54, 1, 0, "Disable boot SPI auxiliary control pins" }, 3623cb28812SJohnny Huang { 54, 1, 1, "Enable boot SPI auxiliary control pins" }, 3633cb28812SJohnny Huang { 55, 2, 0, "Boot SPI CRTM size : disable CRTM" }, 3643cb28812SJohnny Huang { 55, 2, 1, "Boot SPI CRTM size : 256KB" }, 3653cb28812SJohnny Huang { 55, 2, 2, "Boot SPI CRTM size : 512KB" }, 3663cb28812SJohnny Huang { 55, 2, 3, "Boot SPI CRTM size : 1MB" }, 3673cb28812SJohnny Huang { 57, 2, 0, "Host SPI CRTM size : disable CRTM" }, 3683cb28812SJohnny Huang { 57, 2, 1, "Host SPI CRTM size : 256KB" }, 3693cb28812SJohnny Huang { 57, 2, 2, "Host SPI CRTM size : 512KB" }, 3703cb28812SJohnny Huang { 57, 2, 3, "Host SPI CRTM size : 1MB" }, 3713cb28812SJohnny Huang { 59, 1, 0, "Disable host SPI auxiliary control pins" }, 3723cb28812SJohnny Huang { 59, 1, 1, "Enable host SPI auxiliary control pins" }, 3733cb28812SJohnny Huang { 60, 1, 0, "Disable GPIO pass through" }, 3743cb28812SJohnny Huang { 60, 1, 1, "Enable GPIO pass through" }, 3753cb28812SJohnny Huang { 61, 1, 0, "Enable low security secure boot key" }, 3763cb28812SJohnny Huang { 61, 1, 1, "Disable low security secure boot key" }, 3773cb28812SJohnny Huang { 62, 1, 0, "Disable dedicate GPIO strap pins" }, 3783cb28812SJohnny Huang { 62, 1, 1, "Enable dedicate GPIO strap pins" }, 3793cb28812SJohnny Huang { 63, 1, OTP_REG_RESERVED, "" } 3803cb28812SJohnny Huang }; 3813cb28812SJohnny Huang 382*5fdde29fSJohnny Huang static const struct otpstrap_info a2_strap_info[] = { 383*5fdde29fSJohnny Huang { 0, 1, 0, "Disable secure boot" }, 384*5fdde29fSJohnny Huang { 0, 1, 1, "Enable secure boot" }, 385*5fdde29fSJohnny Huang { 1, 1, 0, "Disable boot from eMMC" }, 386*5fdde29fSJohnny Huang { 1, 1, 1, "Enable boot from eMMC" }, 387*5fdde29fSJohnny Huang { 2, 1, 0, "Disable Boot from debug SPI" }, 388*5fdde29fSJohnny Huang { 2, 1, 1, "Enable Boot from debug SPI" }, 389*5fdde29fSJohnny Huang { 3, 1, 0, "Enable ARM CM3" }, 390*5fdde29fSJohnny Huang { 3, 1, 1, "Disable ARM CM3" }, 391*5fdde29fSJohnny Huang { 4, 1, 0, "No VGA BIOS ROM, VGA BIOS is merged in the system BIOS" }, 392*5fdde29fSJohnny Huang { 4, 1, 1, "Enable dedicated VGA BIOS ROM" }, 393*5fdde29fSJohnny Huang { 5, 1, 0, "MAC 1 : RMII/NCSI" }, 394*5fdde29fSJohnny Huang { 5, 1, 1, "MAC 1 : RGMII" }, 395*5fdde29fSJohnny Huang { 6, 1, 0, "MAC 2 : RMII/NCSI" }, 396*5fdde29fSJohnny Huang { 6, 1, 1, "MAC 2 : RGMII" }, 397*5fdde29fSJohnny Huang { 7, 3, 0, "CPU Frequency : 1.2GHz" }, 398*5fdde29fSJohnny Huang { 7, 3, 1, "CPU Frequency : 1.6MHz" }, 399*5fdde29fSJohnny Huang { 7, 3, 2, "CPU Frequency : 1.2GHz" }, 400*5fdde29fSJohnny Huang { 7, 3, 3, "CPU Frequency : 1.6GHz" }, 401*5fdde29fSJohnny Huang { 7, 3, 4, "CPU Frequency : 800MHz" }, 402*5fdde29fSJohnny Huang { 7, 3, 5, "CPU Frequency : 800MHz" }, 403*5fdde29fSJohnny Huang { 7, 3, 6, "CPU Frequency : 800MHz" }, 404*5fdde29fSJohnny Huang { 7, 3, 7, "CPU Frequency : 800MHz" }, 405*5fdde29fSJohnny Huang { 10, 2, 0, "HCLK ratio AXI:AHB = 2:1" }, 406*5fdde29fSJohnny Huang { 10, 2, 1, "HCLK ratio AXI:AHB = 2:1" }, 407*5fdde29fSJohnny Huang { 10, 2, 2, "HCLK ratio AXI:AHB = 3:1" }, 408*5fdde29fSJohnny Huang { 10, 2, 3, "HCLK ratio AXI:AHB = 4:1" }, 409*5fdde29fSJohnny Huang { 12, 2, 0, "VGA memory size : 8MB" }, 410*5fdde29fSJohnny Huang { 12, 2, 1, "VGA memory size : 16MB" }, 411*5fdde29fSJohnny Huang { 12, 2, 2, "VGA memory size : 32MB" }, 412*5fdde29fSJohnny Huang { 12, 2, 3, "VGA memory size : 64MB" }, 413*5fdde29fSJohnny Huang { 14, 3, OTP_REG_RESERVED, "" }, 414*5fdde29fSJohnny Huang { 17, 1, 0, "VGA class code : Class Code for video device" }, 415*5fdde29fSJohnny Huang { 17, 1, 1, "VGA class code : Class Code for VGA device" }, 416*5fdde29fSJohnny Huang { 18, 1, 0, "Enable debug interfaces 0" }, 417*5fdde29fSJohnny Huang { 18, 1, 1, "Disable debug interfaces 0" }, 418*5fdde29fSJohnny Huang { 19, 1, 0, "Boot from emmc mode : High eMMC speed" }, 419*5fdde29fSJohnny Huang { 19, 1, 1, "Boot from emmc mode : Normal eMMC speed" }, 420*5fdde29fSJohnny Huang { 20, 1, 0, "Disable Pcie EHCI device" }, 421*5fdde29fSJohnny Huang { 20, 1, 1, "Enable Pcie EHCI device" }, 422*5fdde29fSJohnny Huang { 21, 1, 0, "Enable VGA XDMA function" }, 423*5fdde29fSJohnny Huang { 21, 1, 1, "Disable VGA XDMA function" }, 424*5fdde29fSJohnny Huang { 22, 1, 0, "Normal BMC mode" }, 425*5fdde29fSJohnny Huang { 22, 1, 1, "Disable dedicated BMC functions for non-BMC application" }, 426*5fdde29fSJohnny Huang { 23, 1, 0, "SSPRST# pin is for secondary processor dedicated reset pin" }, 427*5fdde29fSJohnny Huang { 23, 1, 1, "SSPRST# pin is for PCIE root complex dedicated reset pin" }, 428*5fdde29fSJohnny Huang { 24, 1, 0, "Enable watchdog to reset full chip" }, 429*5fdde29fSJohnny Huang { 24, 1, 1, "Disable watchdog to reset full chip" }, 430*5fdde29fSJohnny Huang { 25, 5, OTP_REG_RESERVED, "" }, 431*5fdde29fSJohnny Huang { 30, 2, OTP_REG_RESERVED, "" }, 432*5fdde29fSJohnny Huang { 32, 1, 0, "MAC 3 : RMII/NCSI" }, 433*5fdde29fSJohnny Huang { 32, 1, 1, "MAC 3 : RGMII" }, 434*5fdde29fSJohnny Huang { 33, 1, 0, "MAC 4 : RMII/NCSI" }, 435*5fdde29fSJohnny Huang { 33, 1, 1, "MAC 4 : RGMII" }, 436*5fdde29fSJohnny Huang { 34, 1, 0, "SuperIO configuration address : 0x2E" }, 437*5fdde29fSJohnny Huang { 34, 1, 1, "SuperIO configuration address : 0x4E" }, 438*5fdde29fSJohnny Huang { 35, 1, 0, "Enable LPC to decode SuperIO" }, 439*5fdde29fSJohnny Huang { 35, 1, 1, "Disable LPC to decode SuperIO" }, 440*5fdde29fSJohnny Huang { 36, 1, 0, "Enable debug interfaces 1" }, 441*5fdde29fSJohnny Huang { 36, 1, 1, "Disable debug interfaces 1" }, 442*5fdde29fSJohnny Huang { 37, 1, 0, "Disable ACPI function" }, 443*5fdde29fSJohnny Huang { 37, 1, 1, "Enable ACPI function" }, 444*5fdde29fSJohnny Huang { 38, 1, 0, "Enable eSPI mode" }, 445*5fdde29fSJohnny Huang { 38, 1, 1, "Enable LPC mode" }, 446*5fdde29fSJohnny Huang { 39, 1, 0, "Enable SAFS mode" }, 447*5fdde29fSJohnny Huang { 39, 1, 1, "Enable SAFS mode" }, 448*5fdde29fSJohnny Huang { 40, 2, OTP_REG_RESERVED, "" }, 449*5fdde29fSJohnny Huang { 42, 1, 0, "Disable boot SPI 3B/4B address mode auto detection" }, 450*5fdde29fSJohnny Huang { 42, 1, 1, "Enable boot SPI 3B/4B address mode auto detection" }, 451*5fdde29fSJohnny Huang { 43, 1, 0, "Disable boot SPI ABR" }, 452*5fdde29fSJohnny Huang { 43, 1, 1, "Enable boot SPI ABR" }, 453*5fdde29fSJohnny Huang { 44, 1, 0, "Boot SPI ABR mode : dual SPI flash" }, 454*5fdde29fSJohnny Huang { 44, 1, 1, "Boot SPI ABR mode : single SPI flash" }, 455*5fdde29fSJohnny Huang { 45, 3, 0, "Boot SPI flash size : no define size" }, 456*5fdde29fSJohnny Huang { 45, 3, 1, "Boot SPI flash size : 2MB" }, 457*5fdde29fSJohnny Huang { 45, 3, 2, "Boot SPI flash size : 4MB" }, 458*5fdde29fSJohnny Huang { 45, 3, 3, "Boot SPI flash size : 8MB" }, 459*5fdde29fSJohnny Huang { 45, 3, 4, "Boot SPI flash size : 16MB" }, 460*5fdde29fSJohnny Huang { 45, 3, 5, "Boot SPI flash size : 32MB" }, 461*5fdde29fSJohnny Huang { 45, 3, 6, "Boot SPI flash size : 64MB" }, 462*5fdde29fSJohnny Huang { 45, 3, 7, "Boot SPI flash size : 128MB" }, 463*5fdde29fSJohnny Huang { 48, 1, 0, "Disable host SPI ABR" }, 464*5fdde29fSJohnny Huang { 48, 1, 1, "Enable host SPI ABR" }, 465*5fdde29fSJohnny Huang { 49, 1, 0, "Disable host SPI ABR mode select pin" }, 466*5fdde29fSJohnny Huang { 49, 1, 1, "Enable host SPI ABR mode select pin" }, 467*5fdde29fSJohnny Huang { 50, 1, 0, "Host SPI ABR mode : dual SPI flash" }, 468*5fdde29fSJohnny Huang { 50, 1, 1, "Host SPI ABR mode : single SPI flash" }, 469*5fdde29fSJohnny Huang { 51, 3, 0, "Host SPI flash size : no define size" }, 470*5fdde29fSJohnny Huang { 51, 3, 1, "Host SPI flash size : 2MB" }, 471*5fdde29fSJohnny Huang { 51, 3, 2, "Host SPI flash size : 4MB" }, 472*5fdde29fSJohnny Huang { 51, 3, 3, "Host SPI flash size : 8MB" }, 473*5fdde29fSJohnny Huang { 51, 3, 4, "Host SPI flash size : 16MB" }, 474*5fdde29fSJohnny Huang { 51, 3, 5, "Host SPI flash size : 32MB" }, 475*5fdde29fSJohnny Huang { 51, 3, 6, "Host SPI flash size : 64MB" }, 476*5fdde29fSJohnny Huang { 51, 3, 7, "Host SPI flash size : 128MB" }, 477*5fdde29fSJohnny Huang { 54, 1, 0, "Disable boot SPI auxiliary control pins" }, 478*5fdde29fSJohnny Huang { 54, 1, 1, "Enable boot SPI auxiliary control pins" }, 479*5fdde29fSJohnny Huang { 55, 2, 0, "Boot SPI CRTM size : disable CRTM" }, 480*5fdde29fSJohnny Huang { 55, 2, 1, "Boot SPI CRTM size : 256KB" }, 481*5fdde29fSJohnny Huang { 55, 2, 2, "Boot SPI CRTM size : 512KB" }, 482*5fdde29fSJohnny Huang { 55, 2, 3, "Boot SPI CRTM size : 1MB" }, 483*5fdde29fSJohnny Huang { 57, 2, 0, "Host SPI CRTM size : disable CRTM" }, 484*5fdde29fSJohnny Huang { 57, 2, 1, "Host SPI CRTM size : 256KB" }, 485*5fdde29fSJohnny Huang { 57, 2, 2, "Host SPI CRTM size : 512KB" }, 486*5fdde29fSJohnny Huang { 57, 2, 3, "Host SPI CRTM size : 1MB" }, 487*5fdde29fSJohnny Huang { 59, 1, 0, "Disable host SPI auxiliary control pins" }, 488*5fdde29fSJohnny Huang { 59, 1, 1, "Enable host SPI auxiliary control pins" }, 489*5fdde29fSJohnny Huang { 60, 1, 0, "Disable GPIO pass through" }, 490*5fdde29fSJohnny Huang { 60, 1, 1, "Enable GPIO pass through" }, 491*5fdde29fSJohnny Huang { 61, 1, 0, "Enable low security secure boot key" }, 492*5fdde29fSJohnny Huang { 61, 1, 1, "Disable low security secure boot key" }, 493*5fdde29fSJohnny Huang { 62, 1, 0, "Disable dedicate GPIO strap pins" }, 494*5fdde29fSJohnny Huang { 62, 1, 1, "Enable dedicate GPIO strap pins" }, 495*5fdde29fSJohnny Huang { 63, 1, OTP_REG_RESERVED, "" } 496*5fdde29fSJohnny Huang }; 497*5fdde29fSJohnny Huang 49879e42a59SJoel Stanley static const struct otpconf_info a0_conf_info[] = { 49991448c03SJohnny Huang { 0, 0, 1, 0, "Enable Secure Region programming" }, 50091448c03SJohnny Huang { 0, 0, 1, 1, "Disable Secure Region programming" }, 50191448c03SJohnny Huang { 0, 1, 1, 0, "Disable Secure Boot" }, 50291448c03SJohnny Huang { 0, 1, 1, 1, "Enable Secure Boot" }, 50391448c03SJohnny Huang { 0, 2, 1, 0, "Initialization programming not done" }, 50491448c03SJohnny Huang { 0, 2, 1, 1, "Initialization programming done" }, 50591448c03SJohnny Huang { 0, 3, 1, 0, "User region ECC disable" }, 50691448c03SJohnny Huang { 0, 3, 1, 1, "User region ECC enable" }, 50791448c03SJohnny Huang { 0, 4, 1, 0, "Secure Region ECC disable" }, 50891448c03SJohnny Huang { 0, 4, 1, 1, "Secure Region ECC enable" }, 50991448c03SJohnny Huang { 0, 5, 1, 0, "Enable low security key" }, 51091448c03SJohnny Huang { 0, 5, 1, 1, "Disable low security key" }, 51191448c03SJohnny Huang { 0, 6, 1, 0, "Do not ignore Secure Boot hardware strap" }, 51291448c03SJohnny Huang { 0, 6, 1, 1, "Ignore Secure Boot hardware strap" }, 51391448c03SJohnny Huang { 0, 7, 1, 0, "Secure Boot Mode: 1" }, 51491448c03SJohnny Huang { 0, 7, 1, 1, "Secure Boot Mode: 2" }, 51591448c03SJohnny Huang { 0, 8, 2, 0, "Single cell mode (recommended)" }, 516541eb887SJohnny Huang { 0, 8, 2, 1, "Differential mode" }, 51791448c03SJohnny Huang { 0, 8, 2, 2, "Differential-redundant mode" }, 51891448c03SJohnny Huang { 0, 10, 2, 0, "RSA mode : RSA1024" }, 51991448c03SJohnny Huang { 0, 10, 2, 1, "RSA mode : RSA2048" }, 52091448c03SJohnny Huang { 0, 10, 2, 2, "RSA mode : RSA3072" }, 52191448c03SJohnny Huang { 0, 10, 2, 3, "RSA mode : RSA4096" }, 52291448c03SJohnny Huang { 0, 12, 2, 0, "SHA mode : SHA224" }, 52391448c03SJohnny Huang { 0, 12, 2, 1, "SHA mode : SHA256" }, 52491448c03SJohnny Huang { 0, 12, 2, 2, "SHA mode : SHA384" }, 52591448c03SJohnny Huang { 0, 12, 2, 3, "SHA mode : SHA512" }, 52691448c03SJohnny Huang { 0, 14, 2, OTP_REG_RESERVED, "" }, 52791448c03SJohnny Huang { 0, 16, 6, OTP_REG_VALUE, "Secure Region size (DW): 0x%x" }, 52891448c03SJohnny Huang { 0, 22, 1, 0, "Secure Region : Writable" }, 52991448c03SJohnny Huang { 0, 22, 1, 1, "Secure Region : Write Protect" }, 53091448c03SJohnny Huang { 0, 23, 1, 0, "User Region : Writable" }, 53191448c03SJohnny Huang { 0, 23, 1, 1, "User Region : Write Protect" }, 53291448c03SJohnny Huang { 0, 24, 1, 0, "Configure Region : Writable" }, 53391448c03SJohnny Huang { 0, 24, 1, 1, "Configure Region : Write Protect" }, 53491448c03SJohnny Huang { 0, 25, 1, 0, "OTP strap Region : Writable" }, 53591448c03SJohnny Huang { 0, 25, 1, 1, "OTP strap Region : Write Protect" }, 53691448c03SJohnny Huang { 0, 26, 1, 0, "Disable Copy Boot Image to Internal SRAM" }, 53791448c03SJohnny Huang { 0, 26, 1, 1, "Copy Boot Image to Internal SRAM" }, 53891448c03SJohnny Huang { 0, 27, 1, 0, "Disable image encryption" }, 53991448c03SJohnny Huang { 0, 27, 1, 1, "Enable image encryption" }, 54091448c03SJohnny Huang { 0, 28, 1, OTP_REG_RESERVED, "" }, 54191448c03SJohnny Huang { 0, 29, 1, 0, "OTP key retire Region : Writable" }, 54291448c03SJohnny Huang { 0, 29, 1, 1, "OTP key retire Region : Write Protect" }, 5433cb28812SJohnny Huang { 0, 30, 1, 0, "Data region redundancy repair disable" }, 5443cb28812SJohnny Huang { 0, 30, 1, 1, "Data region redundancy repair enable" }, 5453cb28812SJohnny Huang { 0, 31, 1, 0, "OTP memory lock disable" }, 5463cb28812SJohnny Huang { 0, 31, 1, 1, "OTP memory lock enable" }, 5473cb28812SJohnny Huang { 2, 0, 16, OTP_REG_VALUE, "Vender ID : 0x%x" }, 5483cb28812SJohnny Huang { 2, 16, 16, OTP_REG_VALUE, "Key Revision : 0x%x" }, 5493cb28812SJohnny Huang { 3, 0, 16, OTP_REG_VALUE, "Secure boot header offset : 0x%x" }, 5503cb28812SJohnny Huang { 4, 0, 8, OTP_REG_VALID_BIT, "Keys valid : %s" }, 5513cb28812SJohnny Huang { 4, 16, 8, OTP_REG_VALID_BIT, "Keys retire : %s" }, 5523cb28812SJohnny Huang { 5, 0, 32, OTP_REG_VALUE, "User define data, random number low : 0x%x" }, 5533cb28812SJohnny Huang { 6, 0, 32, OTP_REG_VALUE, "User define data, random number high : 0x%x" }, 5543cb28812SJohnny Huang { 7, 0, 1, 0, "Force enable PCI bus to AHB bus bridge" }, 5553cb28812SJohnny Huang { 7, 0, 1, 1, "Force disable PCI bus to AHB bus bridge" }, 5563cb28812SJohnny Huang { 7, 1, 1, 0, "Force enable UART5 debug port function" }, 5573cb28812SJohnny Huang { 7, 1, 1, 1, "Force disable UART5 debug port function" }, 5583cb28812SJohnny Huang { 7, 2, 1, 0, "Force enable XDMA function" }, 5593cb28812SJohnny Huang { 7, 2, 1, 1, "Force disable XDMA function" }, 5603cb28812SJohnny Huang { 7, 3, 1, 0, "Force enable APB to PCIE device bridge" }, 5613cb28812SJohnny Huang { 7, 3, 1, 1, "Force disable APB to PCIE device bridge" }, 5623cb28812SJohnny Huang { 7, 4, 1, 0, "Force enable APB to PCIE bridge config access" }, 5633cb28812SJohnny Huang { 7, 4, 1, 1, "Force disable APB to PCIE bridge config access" }, 5643cb28812SJohnny Huang { 7, 5, 1, 0, "Force enable PCIE bus trace buffer" }, 5653cb28812SJohnny Huang { 7, 5, 1, 1, "Force disable PCIE bus trace buffer" }, 5663cb28812SJohnny Huang { 7, 6, 1, 0, "Force enable the capability for PCIE device port as a Root Complex" }, 5673cb28812SJohnny Huang { 7, 6, 1, 1, "Force disable the capability for PCIE device port as a Root Complex" }, 5683cb28812SJohnny Huang { 7, 16, 1, 0, "Force enable ESPI bus to AHB bus bridge" }, 5693cb28812SJohnny Huang { 7, 16, 1, 1, "Force disable ESPI bus to AHB bus bridge" }, 5703cb28812SJohnny Huang { 7, 17, 1, 0, "Force enable LPC bus to AHB bus bridge1" }, 5713cb28812SJohnny Huang { 7, 17, 1, 1, "Force disable LPC bus to AHB bus bridge1" }, 5723cb28812SJohnny Huang { 7, 18, 1, 0, "Force enable LPC bus to AHB bus bridge2" }, 5733cb28812SJohnny Huang { 7, 18, 1, 1, "Force disable LPC bus to AHB bus bridge2" }, 5743cb28812SJohnny Huang { 7, 19, 1, 0, "Force enable UART1 debug port function" }, 5753cb28812SJohnny Huang { 7, 19, 1, 1, "Force disable UART1 debug port function" }, 5763cb28812SJohnny Huang { 7, 31, 1, 0, "Disable chip security setting" }, 5773cb28812SJohnny Huang { 7, 31, 1, 1, "Enable chip security setting" }, 5783cb28812SJohnny Huang { 8, 0, 32, OTP_REG_VALUE, "Redundancy Repair : 0x%x" }, 5793cb28812SJohnny Huang { 10, 0, 32, OTP_REG_VALUE, "Manifest ID low : 0x%x" }, 5803cb28812SJohnny Huang { 11, 0, 32, OTP_REG_VALUE, "Manifest ID high : 0x%x" } 5813cb28812SJohnny Huang }; 5823cb28812SJohnny Huang 58379e42a59SJoel Stanley static const struct otpconf_info a1_conf_info[] = { 5843cb28812SJohnny Huang { 0, 0, 1, OTP_REG_RESERVED, "" }, 5853cb28812SJohnny Huang { 0, 1, 1, 0, "Disable Secure Boot" }, 5863cb28812SJohnny Huang { 0, 1, 1, 1, "Enable Secure Boot" }, 5873cb28812SJohnny Huang { 0, 2, 1, 0, "Initialization programming not done" }, 5883cb28812SJohnny Huang { 0, 2, 1, 1, "Initialization programming done" }, 5893cb28812SJohnny Huang { 0, 3, 1, 0, "User region ECC disable" }, 5903cb28812SJohnny Huang { 0, 3, 1, 1, "User region ECC enable" }, 5913cb28812SJohnny Huang { 0, 4, 1, 0, "Secure Region ECC disable" }, 5923cb28812SJohnny Huang { 0, 4, 1, 1, "Secure Region ECC enable" }, 5933cb28812SJohnny Huang { 0, 5, 1, 0, "Enable low security key" }, 5943cb28812SJohnny Huang { 0, 5, 1, 1, "Disable low security key" }, 5953cb28812SJohnny Huang { 0, 6, 1, 0, "Do not ignore Secure Boot hardware strap" }, 5963cb28812SJohnny Huang { 0, 6, 1, 1, "Ignore Secure Boot hardware strap" }, 5973cb28812SJohnny Huang { 0, 7, 1, 0, "Secure Boot Mode: GCM" }, 5983cb28812SJohnny Huang { 0, 7, 1, 1, "Secure Boot Mode: 2" }, 5993cb28812SJohnny Huang { 0, 8, 2, 0, "Single cell mode (recommended)" }, 6003cb28812SJohnny Huang { 0, 8, 2, 1, "Differential mode" }, 6013cb28812SJohnny Huang { 0, 8, 2, 2, "Differential-redundant mode" }, 6023cb28812SJohnny Huang { 0, 10, 2, 0, "RSA mode : RSA1024" }, 6033cb28812SJohnny Huang { 0, 10, 2, 1, "RSA mode : RSA2048" }, 6043cb28812SJohnny Huang { 0, 10, 2, 2, "RSA mode : RSA3072" }, 6053cb28812SJohnny Huang { 0, 10, 2, 3, "RSA mode : RSA4096" }, 6063cb28812SJohnny Huang { 0, 12, 2, 0, "SHA mode : SHA224" }, 6073cb28812SJohnny Huang { 0, 12, 2, 1, "SHA mode : SHA256" }, 6083cb28812SJohnny Huang { 0, 12, 2, 2, "SHA mode : SHA384" }, 6093cb28812SJohnny Huang { 0, 12, 2, 3, "SHA mode : SHA512" }, 610bb34a7bfSJohnny Huang { 0, 14, 1, 0, "Disable Patch code" }, 611bb34a7bfSJohnny Huang { 0, 14, 1, 1, "Enable Patch code" }, 612bb34a7bfSJohnny Huang { 0, 15, 1, OTP_REG_RESERVED, "" }, 6133cb28812SJohnny Huang { 0, 16, 6, OTP_REG_VALUE, "Secure Region size (DW): 0x%x" }, 6143cb28812SJohnny Huang { 0, 22, 1, 0, "Secure Region : Writable" }, 6153cb28812SJohnny Huang { 0, 22, 1, 1, "Secure Region : Write Protect" }, 6163cb28812SJohnny Huang { 0, 23, 1, 0, "User Region : Writable" }, 6173cb28812SJohnny Huang { 0, 23, 1, 1, "User Region : Write Protect" }, 6183cb28812SJohnny Huang { 0, 24, 1, 0, "Configure Region : Writable" }, 6193cb28812SJohnny Huang { 0, 24, 1, 1, "Configure Region : Write Protect" }, 6203cb28812SJohnny Huang { 0, 25, 1, 0, "OTP strap Region : Writable" }, 6213cb28812SJohnny Huang { 0, 25, 1, 1, "OTP strap Region : Write Protect" }, 6223cb28812SJohnny Huang { 0, 26, 1, 0, "Disable Copy Boot Image to Internal SRAM" }, 6233cb28812SJohnny Huang { 0, 26, 1, 1, "Copy Boot Image to Internal SRAM" }, 6243cb28812SJohnny Huang { 0, 27, 1, 0, "Disable image encryption" }, 6253cb28812SJohnny Huang { 0, 27, 1, 1, "Enable image encryption" }, 6263cb28812SJohnny Huang { 0, 28, 1, OTP_REG_RESERVED, "" }, 6273cb28812SJohnny Huang { 0, 29, 1, 0, "OTP key retire Region : Writable" }, 6283cb28812SJohnny Huang { 0, 29, 1, 1, "OTP key retire Region : Write Protect" }, 6293cb28812SJohnny Huang { 0, 30, 1, 0, "Data region redundancy repair disable" }, 6303cb28812SJohnny Huang { 0, 30, 1, 1, "Data region redundancy repair enable" }, 6313cb28812SJohnny Huang { 0, 31, 1, 0, "OTP memory lock disable" }, 6323cb28812SJohnny Huang { 0, 31, 1, 1, "OTP memory lock enable" }, 63391448c03SJohnny Huang { 2, 0, 16, OTP_REG_VALUE, "Vender ID : 0x%x" }, 63491448c03SJohnny Huang { 2, 16, 16, OTP_REG_VALUE, "Key Revision : 0x%x" }, 63591448c03SJohnny Huang { 3, 0, 16, OTP_REG_VALUE, "Secure boot header offset : 0x%x" }, 63673f11549SJohnny Huang { 4, 0, 8, OTP_REG_VALID_BIT, "Keys valid : %s" }, 63773f11549SJohnny Huang { 4, 16, 8, OTP_REG_VALID_BIT, "Keys retire : %s" }, 63891448c03SJohnny Huang { 5, 0, 32, OTP_REG_VALUE, "User define data, random number low : 0x%x" }, 63991448c03SJohnny Huang { 6, 0, 32, OTP_REG_VALUE, "User define data, random number high : 0x%x" }, 64091448c03SJohnny Huang { 7, 0, 1, 0, "Force enable PCI bus to AHB bus bridge" }, 64191448c03SJohnny Huang { 7, 0, 1, 1, "Force disable PCI bus to AHB bus bridge" }, 64291448c03SJohnny Huang { 7, 1, 1, 0, "Force enable UART5 debug port function" }, 64391448c03SJohnny Huang { 7, 1, 1, 1, "Force disable UART5 debug port function" }, 64491448c03SJohnny Huang { 7, 2, 1, 0, "Force enable XDMA function" }, 64591448c03SJohnny Huang { 7, 2, 1, 1, "Force disable XDMA function" }, 64691448c03SJohnny Huang { 7, 3, 1, 0, "Force enable APB to PCIE device bridge" }, 64791448c03SJohnny Huang { 7, 3, 1, 1, "Force disable APB to PCIE device bridge" }, 64891448c03SJohnny Huang { 7, 4, 1, 0, "Force enable APB to PCIE bridge config access" }, 64991448c03SJohnny Huang { 7, 4, 1, 1, "Force disable APB to PCIE bridge config access" }, 65091448c03SJohnny Huang { 7, 5, 1, 0, "Force enable PCIE bus trace buffer" }, 65191448c03SJohnny Huang { 7, 5, 1, 1, "Force disable PCIE bus trace buffer" }, 65291448c03SJohnny Huang { 7, 6, 1, 0, "Force enable the capability for PCIE device port as a Root Complex" }, 65391448c03SJohnny Huang { 7, 6, 1, 1, "Force disable the capability for PCIE device port as a Root Complex" }, 65491448c03SJohnny Huang { 7, 16, 1, 0, "Force enable ESPI bus to AHB bus bridge" }, 65591448c03SJohnny Huang { 7, 16, 1, 1, "Force disable ESPI bus to AHB bus bridge" }, 65691448c03SJohnny Huang { 7, 17, 1, 0, "Force enable LPC bus to AHB bus bridge1" }, 65791448c03SJohnny Huang { 7, 17, 1, 1, "Force disable LPC bus to AHB bus bridge1" }, 65891448c03SJohnny Huang { 7, 18, 1, 0, "Force enable LPC bus to AHB bus bridge2" }, 65991448c03SJohnny Huang { 7, 18, 1, 1, "Force disable LPC bus to AHB bus bridge2" }, 66091448c03SJohnny Huang { 7, 19, 1, 0, "Force enable UART1 debug port function" }, 66191448c03SJohnny Huang { 7, 19, 1, 1, "Force disable UART1 debug port function" }, 66291448c03SJohnny Huang { 7, 31, 1, 0, "Disable chip security setting" }, 66391448c03SJohnny Huang { 7, 31, 1, 1, "Enable chip security setting" }, 66491448c03SJohnny Huang { 8, 0, 32, OTP_REG_VALUE, "Redundancy Repair : 0x%x" }, 66591448c03SJohnny Huang { 10, 0, 32, OTP_REG_VALUE, "Manifest ID low : 0x%x" }, 666bb34a7bfSJohnny Huang { 11, 0, 32, OTP_REG_VALUE, "Manifest ID high : 0x%x" }, 667bb34a7bfSJohnny Huang { 14, 0, 11, OTP_REG_VALUE, "Patch code location (DW): 0x%x" }, 668bb34a7bfSJohnny Huang { 14, 11, 6, OTP_REG_VALUE, "Patch code size (DW): 0x%x" } 669b458cd62SJohnny Huang }; 6709a4fe690SJohnny Huang 671*5fdde29fSJohnny Huang static const struct otpconf_info a2_conf_info[] = { 672*5fdde29fSJohnny Huang { 0, 0, 1, OTP_REG_RESERVED, "" }, 673*5fdde29fSJohnny Huang { 0, 1, 1, 0, "Disable Secure Boot" }, 674*5fdde29fSJohnny Huang { 0, 1, 1, 1, "Enable Secure Boot" }, 675*5fdde29fSJohnny Huang { 0, 2, 1, 0, "Initialization programming not done" }, 676*5fdde29fSJohnny Huang { 0, 2, 1, 1, "Initialization programming done" }, 677*5fdde29fSJohnny Huang { 0, 3, 1, 0, "User region ECC disable" }, 678*5fdde29fSJohnny Huang { 0, 3, 1, 1, "User region ECC enable" }, 679*5fdde29fSJohnny Huang { 0, 4, 1, 0, "Secure Region ECC disable" }, 680*5fdde29fSJohnny Huang { 0, 4, 1, 1, "Secure Region ECC enable" }, 681*5fdde29fSJohnny Huang { 0, 5, 1, 0, "Enable low security key" }, 682*5fdde29fSJohnny Huang { 0, 5, 1, 1, "Disable low security key" }, 683*5fdde29fSJohnny Huang { 0, 6, 1, 0, "Do not ignore Secure Boot hardware strap" }, 684*5fdde29fSJohnny Huang { 0, 6, 1, 1, "Ignore Secure Boot hardware strap" }, 685*5fdde29fSJohnny Huang { 0, 7, 1, 0, "Secure Boot Mode: GCM" }, 686*5fdde29fSJohnny Huang { 0, 7, 1, 1, "Secure Boot Mode: 2" }, 687*5fdde29fSJohnny Huang { 0, 8, 2, 0, "Single cell mode (recommended)" }, 688*5fdde29fSJohnny Huang { 0, 8, 2, 1, "Differential mode" }, 689*5fdde29fSJohnny Huang { 0, 8, 2, 2, "Differential-redundant mode" }, 690*5fdde29fSJohnny Huang { 0, 10, 2, 0, "RSA mode : RSA1024" }, 691*5fdde29fSJohnny Huang { 0, 10, 2, 1, "RSA mode : RSA2048" }, 692*5fdde29fSJohnny Huang { 0, 10, 2, 2, "RSA mode : RSA3072" }, 693*5fdde29fSJohnny Huang { 0, 10, 2, 3, "RSA mode : RSA4096" }, 694*5fdde29fSJohnny Huang { 0, 12, 2, 0, "SHA mode : SHA224" }, 695*5fdde29fSJohnny Huang { 0, 12, 2, 1, "SHA mode : SHA256" }, 696*5fdde29fSJohnny Huang { 0, 12, 2, 2, "SHA mode : SHA384" }, 697*5fdde29fSJohnny Huang { 0, 12, 2, 3, "SHA mode : SHA512" }, 698*5fdde29fSJohnny Huang { 0, 14, 1, 0, "Disable Patch code" }, 699*5fdde29fSJohnny Huang { 0, 14, 1, 1, "Enable Patch code" }, 700*5fdde29fSJohnny Huang { 0, 15, 1, OTP_REG_RESERVED, "" }, 701*5fdde29fSJohnny Huang { 0, 16, 6, OTP_REG_VALUE, "Secure Region size (DW): 0x%x" }, 702*5fdde29fSJohnny Huang { 0, 22, 1, 0, "Secure Region : Writable" }, 703*5fdde29fSJohnny Huang { 0, 22, 1, 1, "Secure Region : Write Protect" }, 704*5fdde29fSJohnny Huang { 0, 23, 1, 0, "User Region : Writable" }, 705*5fdde29fSJohnny Huang { 0, 23, 1, 1, "User Region : Write Protect" }, 706*5fdde29fSJohnny Huang { 0, 24, 1, 0, "Configure Region : Writable" }, 707*5fdde29fSJohnny Huang { 0, 24, 1, 1, "Configure Region : Write Protect" }, 708*5fdde29fSJohnny Huang { 0, 25, 1, 0, "OTP strap Region : Writable" }, 709*5fdde29fSJohnny Huang { 0, 25, 1, 1, "OTP strap Region : Write Protect" }, 710*5fdde29fSJohnny Huang { 0, 26, 1, 0, "Disable Copy Boot Image to Internal SRAM" }, 711*5fdde29fSJohnny Huang { 0, 26, 1, 1, "Copy Boot Image to Internal SRAM" }, 712*5fdde29fSJohnny Huang { 0, 27, 1, 0, "Disable image encryption" }, 713*5fdde29fSJohnny Huang { 0, 27, 1, 1, "Enable image encryption" }, 714*5fdde29fSJohnny Huang { 0, 28, 1, OTP_REG_RESERVED, "" }, 715*5fdde29fSJohnny Huang { 0, 29, 1, 0, "OTP key retire Region : Writable" }, 716*5fdde29fSJohnny Huang { 0, 29, 1, 1, "OTP key retire Region : Write Protect" }, 717*5fdde29fSJohnny Huang { 0, 30, 1, 0, "Data region redundancy repair disable" }, 718*5fdde29fSJohnny Huang { 0, 30, 1, 1, "Data region redundancy repair enable" }, 719*5fdde29fSJohnny Huang { 0, 31, 1, 0, "OTP memory lock disable" }, 720*5fdde29fSJohnny Huang { 0, 31, 1, 1, "OTP memory lock enable" }, 721*5fdde29fSJohnny Huang { 2, 0, 16, OTP_REG_VALUE, "Vender ID : 0x%x" }, 722*5fdde29fSJohnny Huang { 2, 16, 16, OTP_REG_VALUE, "Key Revision : 0x%x" }, 723*5fdde29fSJohnny Huang { 3, 0, 16, OTP_REG_VALUE, "Secure boot header offset : 0x%x" }, 724*5fdde29fSJohnny Huang { 4, 0, 8, OTP_REG_VALID_BIT, "Keys valid : %s" }, 725*5fdde29fSJohnny Huang { 4, 16, 8, OTP_REG_VALID_BIT, "Keys retire : %s" }, 726*5fdde29fSJohnny Huang { 5, 0, 32, OTP_REG_VALUE, "User define data, random number low : 0x%x" }, 727*5fdde29fSJohnny Huang { 6, 0, 32, OTP_REG_VALUE, "User define data, random number high : 0x%x" }, 728*5fdde29fSJohnny Huang { 7, 0, 1, 0, "Force enable PCI bus to AHB bus bridge" }, 729*5fdde29fSJohnny Huang { 7, 0, 1, 1, "Force disable PCI bus to AHB bus bridge" }, 730*5fdde29fSJohnny Huang { 7, 1, 1, 0, "Force enable UART5 debug port function" }, 731*5fdde29fSJohnny Huang { 7, 1, 1, 1, "Force disable UART5 debug port function" }, 732*5fdde29fSJohnny Huang { 7, 2, 1, 0, "Force enable XDMA function" }, 733*5fdde29fSJohnny Huang { 7, 2, 1, 1, "Force disable XDMA function" }, 734*5fdde29fSJohnny Huang { 7, 3, 1, 0, "Force enable APB to PCIE device bridge" }, 735*5fdde29fSJohnny Huang { 7, 3, 1, 1, "Force disable APB to PCIE device bridge" }, 736*5fdde29fSJohnny Huang { 7, 4, 1, 0, "Force enable APB to PCIE bridge config access" }, 737*5fdde29fSJohnny Huang { 7, 4, 1, 1, "Force disable APB to PCIE bridge config access" }, 738*5fdde29fSJohnny Huang { 7, 5, 1, 0, "Force enable PCIE bus trace buffer" }, 739*5fdde29fSJohnny Huang { 7, 5, 1, 1, "Force disable PCIE bus trace buffer" }, 740*5fdde29fSJohnny Huang { 7, 6, 1, 0, "Force enable the capability for PCIE device port as a Root Complex" }, 741*5fdde29fSJohnny Huang { 7, 6, 1, 1, "Force disable the capability for PCIE device port as a Root Complex" }, 742*5fdde29fSJohnny Huang { 7, 16, 1, 0, "Force enable ESPI bus to AHB bus bridge" }, 743*5fdde29fSJohnny Huang { 7, 16, 1, 1, "Force disable ESPI bus to AHB bus bridge" }, 744*5fdde29fSJohnny Huang { 7, 17, 1, 0, "Force enable LPC bus to AHB bus bridge1" }, 745*5fdde29fSJohnny Huang { 7, 17, 1, 1, "Force disable LPC bus to AHB bus bridge1" }, 746*5fdde29fSJohnny Huang { 7, 18, 1, 0, "Force enable LPC bus to AHB bus bridge2" }, 747*5fdde29fSJohnny Huang { 7, 18, 1, 1, "Force disable LPC bus to AHB bus bridge2" }, 748*5fdde29fSJohnny Huang { 7, 19, 1, 0, "Force enable UART1 debug port function" }, 749*5fdde29fSJohnny Huang { 7, 19, 1, 1, "Force disable UART1 debug port function" }, 750*5fdde29fSJohnny Huang { 7, 31, 1, 0, "Disable chip security setting" }, 751*5fdde29fSJohnny Huang { 7, 31, 1, 1, "Enable chip security setting" }, 752*5fdde29fSJohnny Huang { 8, 0, 32, OTP_REG_VALUE, "Redundancy Repair : 0x%x" }, 753*5fdde29fSJohnny Huang { 10, 0, 32, OTP_REG_VALUE, "Manifest ID low : 0x%x" }, 754*5fdde29fSJohnny Huang { 11, 0, 32, OTP_REG_VALUE, "Manifest ID high : 0x%x" }, 755*5fdde29fSJohnny Huang { 14, 0, 11, OTP_REG_VALUE, "Patch code location (DW): 0x%x" }, 756*5fdde29fSJohnny Huang { 14, 11, 6, OTP_REG_VALUE, "Patch code size (DW): 0x%x" } 757*5fdde29fSJohnny Huang }; 758*5fdde29fSJohnny Huang 75979e42a59SJoel Stanley static const struct otpkey_type a0_key_type[] = { 7609a4fe690SJohnny Huang {0, OTP_KEY_TYPE_AES, 0, "AES-256 as OEM platform key for image encryption/decryption"}, 7619a4fe690SJohnny Huang {1, OTP_KEY_TYPE_VAULT, 0, "AES-256 as secret vault key"}, 7629a4fe690SJohnny Huang {4, OTP_KEY_TYPE_HMAC, 1, "HMAC as encrypted OEM HMAC keys in Mode 1"}, 7639a4fe690SJohnny Huang {8, OTP_KEY_TYPE_RSA, 1, "RSA-public as OEM DSS public keys in Mode 2"}, 7649a4fe690SJohnny Huang {9, OTP_KEY_TYPE_RSA, 0, "RSA-public as SOC public key"}, 7659a4fe690SJohnny Huang {10, OTP_KEY_TYPE_RSA, 0, "RSA-public as AES key decryption key"}, 7669a4fe690SJohnny Huang {13, OTP_KEY_TYPE_RSA, 0, "RSA-private as SOC private key"}, 7679a4fe690SJohnny Huang {14, OTP_KEY_TYPE_RSA, 0, "RSA-private as AES key decryption key"}, 7689a4fe690SJohnny Huang }; 7699a4fe690SJohnny Huang 77079e42a59SJoel Stanley static const struct otpkey_type a1_key_type[] = { 7719a4fe690SJohnny Huang {1, OTP_KEY_TYPE_VAULT, 0, "AES-256 as secret vault key"}, 7729a4fe690SJohnny Huang {2, OTP_KEY_TYPE_AES, 1, "AES-256 as OEM platform key for image encryption/decryption in Mode 2 or AES-256 as OEM DSS keys for Mode GCM"}, 7739a4fe690SJohnny Huang {8, OTP_KEY_TYPE_RSA, 1, "RSA-public as OEM DSS public keys in Mode 2"}, 7749a4fe690SJohnny Huang {10, OTP_KEY_TYPE_RSA, 0, "RSA-public as AES key decryption key"}, 7759a4fe690SJohnny Huang {14, OTP_KEY_TYPE_RSA, 0, "RSA-private as AES key decryption key"}, 7769a4fe690SJohnny Huang }; 7779a4fe690SJohnny Huang 778*5fdde29fSJohnny Huang static const struct otpkey_type a2_key_type[] = { 779*5fdde29fSJohnny Huang {1, OTP_KEY_TYPE_VAULT, 0, "AES-256 as secret vault key"}, 780*5fdde29fSJohnny Huang {2, OTP_KEY_TYPE_AES, 1, "AES-256 as OEM platform key for image encryption/decryption in Mode 2 or AES-256 as OEM DSS keys for Mode GCM"}, 781*5fdde29fSJohnny Huang {8, OTP_KEY_TYPE_RSA, 1, "RSA-public as OEM DSS public keys in Mode 2"}, 782*5fdde29fSJohnny Huang {10, OTP_KEY_TYPE_RSA, 0, "RSA-public as AES key decryption key"}, 783*5fdde29fSJohnny Huang {14, OTP_KEY_TYPE_RSA, 0, "RSA-private as AES key decryption key"}, 784*5fdde29fSJohnny Huang }; 785*5fdde29fSJohnny Huang 7869a4fe690SJohnny Huang static uint32_t chip_version(void) 7879a4fe690SJohnny Huang { 7889a4fe690SJohnny Huang uint32_t rev_id; 7899a4fe690SJohnny Huang 790*5fdde29fSJohnny Huang rev_id = readl(0x1e6e2014); 7919a4fe690SJohnny Huang 792*5fdde29fSJohnny Huang if ((rev_id >> 24) & 0xf != 0x5) 793*5fdde29fSJohnny Huang return -1; 794*5fdde29fSJohnny Huang 795*5fdde29fSJohnny Huang return (rev_id >> 16) & 0xf; 7969a4fe690SJohnny Huang } 7979a4fe690SJohnny Huang 7983d3688adSJohnny Huang static void wait_complete(void) 7993d3688adSJohnny Huang { 8003d3688adSJohnny Huang int reg; 8013d3688adSJohnny Huang 8023d3688adSJohnny Huang do { 8033d3688adSJohnny Huang reg = readl(OTP_STATUS); 8043d3688adSJohnny Huang } while ((reg & 0x6) != 0x6); 8053d3688adSJohnny Huang } 8063d3688adSJohnny Huang 8072a856b9aSJohnny Huang static void otp_read_data(uint32_t offset, uint32_t *data) 80869d5fd8fSJohnny Huang { 8093d3688adSJohnny Huang writel(offset, OTP_ADDR); //Read address 8103d3688adSJohnny Huang writel(0x23b1e361, OTP_COMMAND); //trigger read 8113d3688adSJohnny Huang wait_complete(); 8123d3688adSJohnny Huang data[0] = readl(OTP_COMPARE_1); 8133d3688adSJohnny Huang data[1] = readl(OTP_COMPARE_2); 81469d5fd8fSJohnny Huang } 81569d5fd8fSJohnny Huang 8162a856b9aSJohnny Huang static void otp_read_config(uint32_t offset, uint32_t *data) 81769d5fd8fSJohnny Huang { 81869d5fd8fSJohnny Huang int config_offset; 81969d5fd8fSJohnny Huang 82069d5fd8fSJohnny Huang config_offset = 0x800; 82169d5fd8fSJohnny Huang config_offset |= (offset / 8) * 0x200; 82269d5fd8fSJohnny Huang config_offset |= (offset % 8) * 0x2; 82369d5fd8fSJohnny Huang 8243d3688adSJohnny Huang writel(config_offset, OTP_ADDR); //Read address 8253d3688adSJohnny Huang writel(0x23b1e361, OTP_COMMAND); //trigger read 8263d3688adSJohnny Huang wait_complete(); 8273d3688adSJohnny Huang data[0] = readl(OTP_COMPARE_1); 82869d5fd8fSJohnny Huang } 82969d5fd8fSJohnny Huang 83069d5fd8fSJohnny Huang static int otp_print_config(uint32_t offset, int dw_count) 83169d5fd8fSJohnny Huang { 83269d5fd8fSJohnny Huang int i; 83369d5fd8fSJohnny Huang uint32_t ret[1]; 83469d5fd8fSJohnny Huang 83569d5fd8fSJohnny Huang if (offset + dw_count > 32) 8362a856b9aSJohnny Huang return OTP_USAGE; 83769d5fd8fSJohnny Huang for (i = offset; i < offset + dw_count; i ++) { 83869d5fd8fSJohnny Huang otp_read_config(i, ret); 839a6af4a17SJohnny Huang printf("OTPCFG%X: %08X\n", i, ret[0]); 84069d5fd8fSJohnny Huang } 84169d5fd8fSJohnny Huang printf("\n"); 8422a856b9aSJohnny Huang return OTP_SUCCESS; 84369d5fd8fSJohnny Huang } 84469d5fd8fSJohnny Huang 84569d5fd8fSJohnny Huang static int otp_print_data(uint32_t offset, int dw_count) 84669d5fd8fSJohnny Huang { 84769d5fd8fSJohnny Huang int i; 84869d5fd8fSJohnny Huang uint32_t ret[2]; 84969d5fd8fSJohnny Huang 85069d5fd8fSJohnny Huang if (offset + dw_count > 2048 || offset % 4 != 0) 8512a856b9aSJohnny Huang return OTP_USAGE; 85269d5fd8fSJohnny Huang for (i = offset; i < offset + dw_count; i += 2) { 85369d5fd8fSJohnny Huang otp_read_data(i, ret); 85469d5fd8fSJohnny Huang if (i % 4 == 0) 85569d5fd8fSJohnny Huang printf("%03X: %08X %08X ", i * 4, ret[0], ret[1]); 85669d5fd8fSJohnny Huang else 85769d5fd8fSJohnny Huang printf("%08X %08X\n", ret[0], ret[1]); 85869d5fd8fSJohnny Huang 85969d5fd8fSJohnny Huang } 86069d5fd8fSJohnny Huang printf("\n"); 8612a856b9aSJohnny Huang return OTP_SUCCESS; 86269d5fd8fSJohnny Huang } 86369d5fd8fSJohnny Huang 86469d5fd8fSJohnny Huang static int otp_compare(uint32_t otp_addr, uint32_t addr) 86569d5fd8fSJohnny Huang { 86669d5fd8fSJohnny Huang uint32_t ret; 86769d5fd8fSJohnny Huang uint32_t *buf; 86869d5fd8fSJohnny Huang 86969d5fd8fSJohnny Huang buf = map_physmem(addr, 16, MAP_WRBACK); 87069d5fd8fSJohnny Huang printf("%08X\n", buf[0]); 87169d5fd8fSJohnny Huang printf("%08X\n", buf[1]); 87269d5fd8fSJohnny Huang printf("%08X\n", buf[2]); 87369d5fd8fSJohnny Huang printf("%08X\n", buf[3]); 8743d3688adSJohnny Huang writel(otp_addr, OTP_ADDR); //Compare address 8753d3688adSJohnny Huang writel(buf[0], OTP_COMPARE_1); //Compare data 1 8763d3688adSJohnny Huang writel(buf[1], OTP_COMPARE_2); //Compare data 2 8773d3688adSJohnny Huang writel(buf[2], OTP_COMPARE_3); //Compare data 3 8783d3688adSJohnny Huang writel(buf[3], OTP_COMPARE_4); //Compare data 4 8793d3688adSJohnny Huang writel(0x23b1e363, OTP_COMMAND); //Compare command 8803d3688adSJohnny Huang wait_complete(); 8813d3688adSJohnny Huang ret = readl(OTP_STATUS); //Compare command 88269d5fd8fSJohnny Huang if (ret & 0x1) 88369d5fd8fSJohnny Huang return 0; 88469d5fd8fSJohnny Huang else 88569d5fd8fSJohnny Huang return -1; 88669d5fd8fSJohnny Huang } 88769d5fd8fSJohnny Huang 88869d5fd8fSJohnny Huang static void otp_write(uint32_t otp_addr, uint32_t data) 88969d5fd8fSJohnny Huang { 8903d3688adSJohnny Huang writel(otp_addr, OTP_ADDR); //write address 8913d3688adSJohnny Huang writel(data, OTP_COMPARE_1); //write data 8923d3688adSJohnny Huang writel(0x23b1e362, OTP_COMMAND); //write command 8933d3688adSJohnny Huang wait_complete(); 89469d5fd8fSJohnny Huang } 89569d5fd8fSJohnny Huang 896a6d0d645SJohnny Huang static int verify_bit(uint32_t otp_addr, int bit_offset, int value) 89769d5fd8fSJohnny Huang { 89830a8c590SJohnny Huang uint32_t ret[2]; 89969d5fd8fSJohnny Huang 90030a8c590SJohnny Huang if (otp_addr % 2 == 0) 9013d3688adSJohnny Huang writel(otp_addr, OTP_ADDR); //Read address 90230a8c590SJohnny Huang else 9033d3688adSJohnny Huang writel(otp_addr - 1, OTP_ADDR); //Read address 90430a8c590SJohnny Huang 9053d3688adSJohnny Huang writel(0x23b1e361, OTP_COMMAND); //trigger read 9063d3688adSJohnny Huang wait_complete(); 9073d3688adSJohnny Huang ret[0] = readl(OTP_COMPARE_1); 9083d3688adSJohnny Huang ret[1] = readl(OTP_COMPARE_2); 90983655e91SJohnny Huang 91030a8c590SJohnny Huang if (otp_addr % 2 == 0) { 91130a8c590SJohnny Huang if (((ret[0] >> bit_offset) & 1) == value) 91269d5fd8fSJohnny Huang return 0; 91369d5fd8fSJohnny Huang else 91469d5fd8fSJohnny Huang return -1; 91530a8c590SJohnny Huang } else { 91630a8c590SJohnny Huang if (((ret[1] >> bit_offset) & 1) == value) 91730a8c590SJohnny Huang return 0; 91830a8c590SJohnny Huang else 91930a8c590SJohnny Huang return -1; 92030a8c590SJohnny Huang } 92130a8c590SJohnny Huang 92269d5fd8fSJohnny Huang } 92369d5fd8fSJohnny Huang 924696656c6SJohnny Huang static uint32_t verify_dw(uint32_t otp_addr, uint32_t *value, uint32_t *ignore, uint32_t *compare, int size) 9254c1c9b35SJohnny Huang { 9264c1c9b35SJohnny Huang uint32_t ret[2]; 9274c1c9b35SJohnny Huang 9284c1c9b35SJohnny Huang otp_addr &= ~(1 << 15); 9294c1c9b35SJohnny Huang 9304c1c9b35SJohnny Huang if (otp_addr % 2 == 0) 9313d3688adSJohnny Huang writel(otp_addr, OTP_ADDR); //Read address 9324c1c9b35SJohnny Huang else 9333d3688adSJohnny Huang writel(otp_addr - 1, OTP_ADDR); //Read address 9343d3688adSJohnny Huang writel(0x23b1e361, OTP_COMMAND); //trigger read 9353d3688adSJohnny Huang wait_complete(); 9363d3688adSJohnny Huang ret[0] = readl(OTP_COMPARE_1); 9373d3688adSJohnny Huang ret[1] = readl(OTP_COMPARE_2); 9384c1c9b35SJohnny Huang if (size == 1) { 9394c1c9b35SJohnny Huang if (otp_addr % 2 == 0) { 9404c1c9b35SJohnny Huang // printf("check %x : %x = %x\n", otp_addr, ret[0], value[0]); 941696656c6SJohnny Huang if ((value[0] & ~ignore[0]) == (ret[0] & ~ignore[0])) { 9424c1c9b35SJohnny Huang compare[0] = 0; 9434c1c9b35SJohnny Huang return 0; 9444c1c9b35SJohnny Huang } else { 9454c1c9b35SJohnny Huang compare[0] = value[0] ^ ret[0]; 9464c1c9b35SJohnny Huang return -1; 9474c1c9b35SJohnny Huang } 9484c1c9b35SJohnny Huang 9494c1c9b35SJohnny Huang } else { 9504c1c9b35SJohnny Huang // printf("check %x : %x = %x\n", otp_addr, ret[1], value[0]); 951696656c6SJohnny Huang if ((value[0] & ~ignore[0]) == (ret[1] & ~ignore[0])) { 9524c1c9b35SJohnny Huang compare[0] = ~0; 9534c1c9b35SJohnny Huang return 0; 9544c1c9b35SJohnny Huang } else { 955d90825e2SJohnny Huang compare[0] = ~(value[0] ^ ret[1]); 9564c1c9b35SJohnny Huang return -1; 9574c1c9b35SJohnny Huang } 9584c1c9b35SJohnny Huang } 9594c1c9b35SJohnny Huang } else if (size == 2) { 9604c1c9b35SJohnny Huang // otp_addr should be even 961696656c6SJohnny Huang if ((value[0] & ~ignore[0]) == (ret[0] & ~ignore[0]) && (value[1] & ~ignore[1]) == (ret[1] & ~ignore[1])) { 9624c1c9b35SJohnny Huang // printf("check[0] %x : %x = %x\n", otp_addr, ret[0], value[0]); 9634c1c9b35SJohnny Huang // printf("check[1] %x : %x = %x\n", otp_addr, ret[1], value[1]); 9644c1c9b35SJohnny Huang compare[0] = 0; 9654c1c9b35SJohnny Huang compare[1] = ~0; 9664c1c9b35SJohnny Huang return 0; 9674c1c9b35SJohnny Huang } else { 9684c1c9b35SJohnny Huang // printf("check[0] %x : %x = %x\n", otp_addr, ret[0], value[0]); 9694c1c9b35SJohnny Huang // printf("check[1] %x : %x = %x\n", otp_addr, ret[1], value[1]); 9704c1c9b35SJohnny Huang compare[0] = value[0] ^ ret[0]; 9714c1c9b35SJohnny Huang compare[1] = ~(value[1] ^ ret[1]); 9724c1c9b35SJohnny Huang return -1; 9734c1c9b35SJohnny Huang } 9744c1c9b35SJohnny Huang } else { 9754c1c9b35SJohnny Huang return -1; 9764c1c9b35SJohnny Huang } 9774c1c9b35SJohnny Huang } 9784c1c9b35SJohnny Huang 9797e22f42dSJohnny Huang static void otp_soak(int soak) 980d90825e2SJohnny Huang { 981de6fbf1cSJohnny Huang switch (soak) { 982de6fbf1cSJohnny Huang case 0: //default 983de6fbf1cSJohnny Huang otp_write(0x3000, 0x0); // Write MRA 984de6fbf1cSJohnny Huang otp_write(0x5000, 0x0); // Write MRB 985de6fbf1cSJohnny Huang otp_write(0x1000, 0x0); // Write MR 986de6fbf1cSJohnny Huang break; 987de6fbf1cSJohnny Huang case 1: //normal program 988de6fbf1cSJohnny Huang otp_write(0x3000, 0x4021); // Write MRA 989de6fbf1cSJohnny Huang otp_write(0x5000, 0x302f); // Write MRB 990de6fbf1cSJohnny Huang otp_write(0x1000, 0x4020); // Write MR 991de6fbf1cSJohnny Huang writel(0x04190760, OTP_TIMING); 992de6fbf1cSJohnny Huang break; 993de6fbf1cSJohnny Huang case 2: //soak program 994d90825e2SJohnny Huang otp_write(0x3000, 0x4021); // Write MRA 995d90825e2SJohnny Huang otp_write(0x5000, 0x1027); // Write MRB 996d90825e2SJohnny Huang otp_write(0x1000, 0x4820); // Write MR 997de6fbf1cSJohnny Huang writel(0x041930d4, OTP_TIMING); 998de6fbf1cSJohnny Huang break; 999d90825e2SJohnny Huang } 1000de6fbf1cSJohnny Huang 10013d3688adSJohnny Huang wait_complete(); 1002d90825e2SJohnny Huang } 1003d90825e2SJohnny Huang 100483655e91SJohnny Huang static void otp_prog(uint32_t otp_addr, uint32_t prog_bit) 100583655e91SJohnny Huang { 100683655e91SJohnny Huang writel(otp_addr, OTP_ADDR); //write address 100783655e91SJohnny Huang writel(prog_bit, OTP_COMPARE_1); //write data 100883655e91SJohnny Huang writel(0x23b1e364, OTP_COMMAND); //write command 100983655e91SJohnny Huang wait_complete(); 101083655e91SJohnny Huang } 101183655e91SJohnny Huang 101283655e91SJohnny Huang static void _otp_prog_bit(uint32_t value, uint32_t prog_address, uint32_t bit_offset) 101383655e91SJohnny Huang { 101483655e91SJohnny Huang int prog_bit; 101583655e91SJohnny Huang 101683655e91SJohnny Huang if (prog_address % 2 == 0) { 101783655e91SJohnny Huang if (value) 101883655e91SJohnny Huang prog_bit = ~(0x1 << bit_offset); 101983655e91SJohnny Huang else 102083655e91SJohnny Huang return; 102183655e91SJohnny Huang } else { 102283655e91SJohnny Huang prog_address |= 1 << 15; 102383655e91SJohnny Huang if (!value) 102483655e91SJohnny Huang prog_bit = 0x1 << bit_offset; 102583655e91SJohnny Huang else 102683655e91SJohnny Huang return; 102783655e91SJohnny Huang } 102883655e91SJohnny Huang otp_prog(prog_address, prog_bit); 102983655e91SJohnny Huang } 103083655e91SJohnny Huang 103183655e91SJohnny Huang static int otp_prog_bit(uint32_t value, uint32_t prog_address, uint32_t bit_offset) 103283655e91SJohnny Huang { 103383655e91SJohnny Huang int pass; 103483655e91SJohnny Huang int i; 103583655e91SJohnny Huang 103683655e91SJohnny Huang otp_soak(1); 103783655e91SJohnny Huang _otp_prog_bit(value, prog_address, bit_offset); 103883655e91SJohnny Huang pass = 0; 103983655e91SJohnny Huang 104083655e91SJohnny Huang for (i = 0; i < RETRY; i++) { 104183655e91SJohnny Huang if (verify_bit(prog_address, bit_offset, value) != 0) { 104283655e91SJohnny Huang otp_soak(2); 104383655e91SJohnny Huang _otp_prog_bit(value, prog_address, bit_offset); 104483655e91SJohnny Huang if (verify_bit(prog_address, bit_offset, value) != 0) { 104583655e91SJohnny Huang otp_soak(1); 104683655e91SJohnny Huang } else { 104783655e91SJohnny Huang pass = 1; 104883655e91SJohnny Huang break; 104983655e91SJohnny Huang } 105083655e91SJohnny Huang } else { 105183655e91SJohnny Huang pass = 1; 105283655e91SJohnny Huang break; 105383655e91SJohnny Huang } 105483655e91SJohnny Huang } 105583655e91SJohnny Huang 105683655e91SJohnny Huang return pass; 105783655e91SJohnny Huang } 105883655e91SJohnny Huang 1059696656c6SJohnny Huang static void otp_prog_dw(uint32_t value, uint32_t ignore, uint32_t prog_address) 1060d90825e2SJohnny Huang { 1061d90825e2SJohnny Huang int j, bit_value, prog_bit; 1062d90825e2SJohnny Huang 1063d90825e2SJohnny Huang for (j = 0; j < 32; j++) { 1064696656c6SJohnny Huang if ((ignore >> j) & 0x1) 1065d90825e2SJohnny Huang continue; 1066d90825e2SJohnny Huang bit_value = (value >> j) & 0x1; 1067d90825e2SJohnny Huang if (prog_address % 2 == 0) { 1068d90825e2SJohnny Huang if (bit_value) 1069d90825e2SJohnny Huang prog_bit = ~(0x1 << j); 1070d90825e2SJohnny Huang else 1071d90825e2SJohnny Huang continue; 1072d90825e2SJohnny Huang } else { 1073d90825e2SJohnny Huang prog_address |= 1 << 15; 1074d90825e2SJohnny Huang if (bit_value) 1075d90825e2SJohnny Huang continue; 1076d90825e2SJohnny Huang else 1077d90825e2SJohnny Huang prog_bit = 0x1 << j; 1078d90825e2SJohnny Huang } 1079d90825e2SJohnny Huang otp_prog(prog_address, prog_bit); 1080d90825e2SJohnny Huang } 1081d90825e2SJohnny Huang } 1082d90825e2SJohnny Huang 108354552c69SJohnny Huang static int otp_prog_verify_2dw(uint32_t *data, uint32_t *buf, uint32_t *ignore_mask, uint32_t prog_address) 108454552c69SJohnny Huang { 108554552c69SJohnny Huang int pass; 108654552c69SJohnny Huang int i; 108754552c69SJohnny Huang uint32_t data0_masked; 108854552c69SJohnny Huang uint32_t data1_masked; 108954552c69SJohnny Huang uint32_t buf0_masked; 109054552c69SJohnny Huang uint32_t buf1_masked; 109154552c69SJohnny Huang uint32_t compare[2]; 109254552c69SJohnny Huang 109354552c69SJohnny Huang data0_masked = data[0] & ~ignore_mask[0]; 109454552c69SJohnny Huang buf0_masked = buf[0] & ~ignore_mask[0]; 109554552c69SJohnny Huang data1_masked = data[1] & ~ignore_mask[1]; 109654552c69SJohnny Huang buf1_masked = buf[1] & ~ignore_mask[1]; 109754552c69SJohnny Huang if ((data0_masked == buf0_masked) && (data1_masked == buf1_masked)) 109854552c69SJohnny Huang return 0; 109954552c69SJohnny Huang 110054552c69SJohnny Huang otp_soak(1); 110154552c69SJohnny Huang if (data0_masked != buf0_masked) 110254552c69SJohnny Huang otp_prog_dw(buf[0], ignore_mask[0], prog_address); 110354552c69SJohnny Huang if (data1_masked != buf1_masked) 110454552c69SJohnny Huang otp_prog_dw(buf[1], ignore_mask[1], prog_address + 1); 110554552c69SJohnny Huang 110654552c69SJohnny Huang pass = 0; 110754552c69SJohnny Huang for (i = 0; i < RETRY; i++) { 110854552c69SJohnny Huang if (verify_dw(prog_address, buf, ignore_mask, compare, 2) != 0) { 110954552c69SJohnny Huang otp_soak(2); 111054552c69SJohnny Huang if (compare[0] != 0) { 111154552c69SJohnny Huang otp_prog_dw(compare[0], ignore_mask[0], prog_address); 111254552c69SJohnny Huang } 111354552c69SJohnny Huang if (compare[1] != ~0) { 111454552c69SJohnny Huang otp_prog_dw(compare[1], ignore_mask[0], prog_address + 1); 111554552c69SJohnny Huang } 111654552c69SJohnny Huang if (verify_dw(prog_address, buf, ignore_mask, compare, 2) != 0) { 111754552c69SJohnny Huang otp_soak(1); 111854552c69SJohnny Huang } else { 111954552c69SJohnny Huang pass = 1; 112054552c69SJohnny Huang break; 112154552c69SJohnny Huang } 112254552c69SJohnny Huang } else { 112354552c69SJohnny Huang pass = 1; 112454552c69SJohnny Huang break; 112554552c69SJohnny Huang } 112654552c69SJohnny Huang } 112754552c69SJohnny Huang 112854552c69SJohnny Huang if (!pass) { 112954552c69SJohnny Huang otp_soak(0); 113054552c69SJohnny Huang return OTP_FAILURE; 113154552c69SJohnny Huang } 113254552c69SJohnny Huang return OTP_SUCCESS; 113354552c69SJohnny Huang } 113454552c69SJohnny Huang 1135541eb887SJohnny Huang static void otp_strap_status(struct otpstrap_status *otpstrap) 113676d13988SJohnny Huang { 113776d13988SJohnny Huang uint32_t OTPSTRAP_RAW[2]; 11385010032bSJohnny Huang int strap_end; 113976d13988SJohnny Huang int i, j; 114076d13988SJohnny Huang 11415010032bSJohnny Huang if (info_cb.version == OTP_AST2600A0) { 114276d13988SJohnny Huang for (j = 0; j < 64; j++) { 114376d13988SJohnny Huang otpstrap[j].value = 0; 114476d13988SJohnny Huang otpstrap[j].remain_times = 7; 114576d13988SJohnny Huang otpstrap[j].writeable_option = -1; 114676d13988SJohnny Huang otpstrap[j].protected = 0; 114776d13988SJohnny Huang } 11485010032bSJohnny Huang strap_end = 30; 11495010032bSJohnny Huang } else { 11505010032bSJohnny Huang for (j = 0; j < 64; j++) { 11515010032bSJohnny Huang otpstrap[j].value = 0; 11525010032bSJohnny Huang otpstrap[j].remain_times = 6; 11535010032bSJohnny Huang otpstrap[j].writeable_option = -1; 11545010032bSJohnny Huang otpstrap[j].reg_protected = 0; 11555010032bSJohnny Huang otpstrap[j].protected = 0; 11565010032bSJohnny Huang } 11575010032bSJohnny Huang strap_end = 28; 11585010032bSJohnny Huang } 115976d13988SJohnny Huang 11605010032bSJohnny Huang for (i = 16; i < strap_end; i += 2) { 116176d13988SJohnny Huang int option = (i - 16) / 2; 116276d13988SJohnny Huang otp_read_config(i, &OTPSTRAP_RAW[0]); 116376d13988SJohnny Huang otp_read_config(i + 1, &OTPSTRAP_RAW[1]); 116476d13988SJohnny Huang for (j = 0; j < 32; j++) { 116576d13988SJohnny Huang char bit_value = ((OTPSTRAP_RAW[0] >> j) & 0x1); 116676d13988SJohnny Huang if ((bit_value == 0) && (otpstrap[j].writeable_option == -1)) { 116776d13988SJohnny Huang otpstrap[j].writeable_option = option; 116876d13988SJohnny Huang } 116976d13988SJohnny Huang if (bit_value == 1) 117076d13988SJohnny Huang otpstrap[j].remain_times --; 117176d13988SJohnny Huang otpstrap[j].value ^= bit_value; 117276d13988SJohnny Huang otpstrap[j].option_array[option] = bit_value; 117376d13988SJohnny Huang } 117476d13988SJohnny Huang for (j = 32; j < 64; j++) { 117576d13988SJohnny Huang char bit_value = ((OTPSTRAP_RAW[1] >> (j - 32)) & 0x1); 117676d13988SJohnny Huang if ((bit_value == 0) && (otpstrap[j].writeable_option == -1)) { 117776d13988SJohnny Huang otpstrap[j].writeable_option = option; 117876d13988SJohnny Huang } 117976d13988SJohnny Huang if (bit_value == 1) 118076d13988SJohnny Huang otpstrap[j].remain_times --; 118176d13988SJohnny Huang otpstrap[j].value ^= bit_value; 118276d13988SJohnny Huang otpstrap[j].option_array[option] = bit_value; 118376d13988SJohnny Huang } 118476d13988SJohnny Huang } 11855010032bSJohnny Huang 11865010032bSJohnny Huang if (info_cb.version != OTP_AST2600A0) { 11875010032bSJohnny Huang otp_read_config(28, &OTPSTRAP_RAW[0]); 11885010032bSJohnny Huang otp_read_config(29, &OTPSTRAP_RAW[1]); 11895010032bSJohnny Huang for (j = 0; j < 32; j++) { 11905010032bSJohnny Huang if (((OTPSTRAP_RAW[0] >> j) & 0x1) == 1) 11915010032bSJohnny Huang otpstrap[j].reg_protected = 1; 11925010032bSJohnny Huang } 11935010032bSJohnny Huang for (j = 32; j < 64; j++) { 11945010032bSJohnny Huang if (((OTPSTRAP_RAW[1] >> (j - 32)) & 0x1) == 1) 11955010032bSJohnny Huang otpstrap[j].reg_protected = 1; 11965010032bSJohnny Huang } 11975010032bSJohnny Huang 11985010032bSJohnny Huang } 11995010032bSJohnny Huang 120076d13988SJohnny Huang otp_read_config(30, &OTPSTRAP_RAW[0]); 120176d13988SJohnny Huang otp_read_config(31, &OTPSTRAP_RAW[1]); 120276d13988SJohnny Huang for (j = 0; j < 32; j++) { 120376d13988SJohnny Huang if (((OTPSTRAP_RAW[0] >> j) & 0x1) == 1) 120476d13988SJohnny Huang otpstrap[j].protected = 1; 120576d13988SJohnny Huang } 120676d13988SJohnny Huang for (j = 32; j < 64; j++) { 120776d13988SJohnny Huang if (((OTPSTRAP_RAW[1] >> (j - 32)) & 0x1) == 1) 120876d13988SJohnny Huang otpstrap[j].protected = 1; 120976d13988SJohnny Huang } 121076d13988SJohnny Huang } 121176d13988SJohnny Huang 1212696656c6SJohnny Huang static int otp_print_conf_image(struct otp_image_layout *image_layout) 121369d5fd8fSJohnny Huang { 121479e42a59SJoel Stanley const struct otpconf_info *conf_info = info_cb.conf_info; 1215696656c6SJohnny Huang uint32_t *OTPCFG = (uint32_t *)image_layout->conf; 1216696656c6SJohnny Huang uint32_t *OTPCFG_IGNORE = (uint32_t *)image_layout->conf_ignore; 1217b458cd62SJohnny Huang uint32_t mask; 1218b458cd62SJohnny Huang uint32_t dw_offset; 1219b458cd62SJohnny Huang uint32_t bit_offset; 1220b458cd62SJohnny Huang uint32_t otp_value; 1221696656c6SJohnny Huang uint32_t otp_ignore; 1222b458cd62SJohnny Huang int fail = 0; 122373f11549SJohnny Huang char valid_bit[20]; 122466f2f8e5SJohnny Huang int i; 122573f11549SJohnny Huang int j; 122666f2f8e5SJohnny Huang 1227737ed20bSJohnny Huang printf("DW BIT Value Description\n"); 122866f2f8e5SJohnny Huang printf("__________________________________________________________________________\n"); 12293cb28812SJohnny Huang for (i = 0; i < info_cb.conf_info_len; i++) { 12303cb28812SJohnny Huang dw_offset = conf_info[i].dw_offset; 12313cb28812SJohnny Huang bit_offset = conf_info[i].bit_offset; 12323cb28812SJohnny Huang mask = BIT(conf_info[i].length) - 1; 1233b458cd62SJohnny Huang otp_value = (OTPCFG[dw_offset] >> bit_offset) & mask; 1234696656c6SJohnny Huang otp_ignore = (OTPCFG_IGNORE[dw_offset] >> bit_offset) & mask; 1235b458cd62SJohnny Huang 1236696656c6SJohnny Huang if (otp_ignore == mask) { 1237b458cd62SJohnny Huang continue; 1238696656c6SJohnny Huang } else if (otp_ignore != 0) { 1239b458cd62SJohnny Huang fail = 1; 1240b458cd62SJohnny Huang } 1241b458cd62SJohnny Huang 12423cb28812SJohnny Huang if ((otp_value != conf_info[i].value) && 12433cb28812SJohnny Huang conf_info[i].value != OTP_REG_RESERVED && 12443cb28812SJohnny Huang conf_info[i].value != OTP_REG_VALUE && 12453cb28812SJohnny Huang conf_info[i].value != OTP_REG_VALID_BIT) 1246b458cd62SJohnny Huang continue; 1247b458cd62SJohnny Huang printf("0x%-4X", dw_offset); 1248b458cd62SJohnny Huang 12493cb28812SJohnny Huang if (conf_info[i].length == 1) { 12503cb28812SJohnny Huang printf("0x%-9X", conf_info[i].bit_offset); 125166f2f8e5SJohnny Huang } else { 1252b458cd62SJohnny Huang printf("0x%-2X:0x%-4X", 12533cb28812SJohnny Huang conf_info[i].bit_offset + conf_info[i].length - 1, 12543cb28812SJohnny Huang conf_info[i].bit_offset); 125566f2f8e5SJohnny Huang } 1256b458cd62SJohnny Huang printf("0x%-10x", otp_value); 1257b458cd62SJohnny Huang 1258b458cd62SJohnny Huang if (fail) { 1259696656c6SJohnny Huang printf("Ignore mask error\n"); 1260b458cd62SJohnny Huang } else { 12613cb28812SJohnny Huang if (conf_info[i].value == OTP_REG_RESERVED) { 1262b458cd62SJohnny Huang printf("Reserved\n"); 12633cb28812SJohnny Huang } else if (conf_info[i].value == OTP_REG_VALUE) { 12643cb28812SJohnny Huang printf(conf_info[i].information, otp_value); 1265b458cd62SJohnny Huang printf("\n"); 12663cb28812SJohnny Huang } else if (conf_info[i].value == OTP_REG_VALID_BIT) { 1267b458cd62SJohnny Huang if (otp_value != 0) { 126873f11549SJohnny Huang for (j = 0; j < 7; j++) { 126973f11549SJohnny Huang if (otp_value == (1 << j)) { 127073f11549SJohnny Huang valid_bit[j * 2] = '1'; 1271b458cd62SJohnny Huang } else { 127273f11549SJohnny Huang valid_bit[j * 2] = '0'; 127373f11549SJohnny Huang } 127473f11549SJohnny Huang valid_bit[j * 2 + 1] = ' '; 127573f11549SJohnny Huang } 127673f11549SJohnny Huang valid_bit[15] = 0; 127773f11549SJohnny Huang } else { 127873f11549SJohnny Huang strcpy(valid_bit, "0 0 0 0 0 0 0 0\0"); 1279b458cd62SJohnny Huang } 12803cb28812SJohnny Huang printf(conf_info[i].information, valid_bit); 1281b458cd62SJohnny Huang printf("\n"); 1282b458cd62SJohnny Huang } else { 12833cb28812SJohnny Huang printf("%s\n", conf_info[i].information); 1284b458cd62SJohnny Huang } 1285b458cd62SJohnny Huang } 1286b458cd62SJohnny Huang } 1287b458cd62SJohnny Huang 1288b458cd62SJohnny Huang if (fail) 1289b458cd62SJohnny Huang return OTP_FAILURE; 1290b458cd62SJohnny Huang 129166f2f8e5SJohnny Huang return OTP_SUCCESS; 129266f2f8e5SJohnny Huang } 129366f2f8e5SJohnny Huang 12942d4b0742SJohnny Huang static int otp_print_conf_info(int input_offset) 129566f2f8e5SJohnny Huang { 129679e42a59SJoel Stanley const struct otpconf_info *conf_info = info_cb.conf_info; 1297bb34a7bfSJohnny Huang uint32_t OTPCFG[16]; 1298b458cd62SJohnny Huang uint32_t mask; 1299b458cd62SJohnny Huang uint32_t dw_offset; 1300b458cd62SJohnny Huang uint32_t bit_offset; 1301b458cd62SJohnny Huang uint32_t otp_value; 130273f11549SJohnny Huang char valid_bit[20]; 130366f2f8e5SJohnny Huang int i; 130473f11549SJohnny Huang int j; 130566f2f8e5SJohnny Huang 1306bb34a7bfSJohnny Huang for (i = 0; i < 16; i++) 130766f2f8e5SJohnny Huang otp_read_config(i, &OTPCFG[i]); 130866f2f8e5SJohnny Huang 130966f2f8e5SJohnny Huang 1310b458cd62SJohnny Huang printf("DW BIT Value Description\n"); 1311b458cd62SJohnny Huang printf("__________________________________________________________________________\n"); 13123cb28812SJohnny Huang for (i = 0; i < info_cb.conf_info_len; i++) { 13133cb28812SJohnny Huang if (input_offset != -1 && input_offset != conf_info[i].dw_offset) 13142d4b0742SJohnny Huang continue; 13153cb28812SJohnny Huang dw_offset = conf_info[i].dw_offset; 13163cb28812SJohnny Huang bit_offset = conf_info[i].bit_offset; 13173cb28812SJohnny Huang mask = BIT(conf_info[i].length) - 1; 1318b458cd62SJohnny Huang otp_value = (OTPCFG[dw_offset] >> bit_offset) & mask; 1319b458cd62SJohnny Huang 13203cb28812SJohnny Huang if ((otp_value != conf_info[i].value) && 13213cb28812SJohnny Huang conf_info[i].value != OTP_REG_RESERVED && 13223cb28812SJohnny Huang conf_info[i].value != OTP_REG_VALUE && 13233cb28812SJohnny Huang conf_info[i].value != OTP_REG_VALID_BIT) 1324b458cd62SJohnny Huang continue; 1325b458cd62SJohnny Huang printf("0x%-4X", dw_offset); 1326b458cd62SJohnny Huang 13273cb28812SJohnny Huang if (conf_info[i].length == 1) { 13283cb28812SJohnny Huang printf("0x%-9X", conf_info[i].bit_offset); 1329b458cd62SJohnny Huang } else { 1330b458cd62SJohnny Huang printf("0x%-2X:0x%-4X", 13313cb28812SJohnny Huang conf_info[i].bit_offset + conf_info[i].length - 1, 13323cb28812SJohnny Huang conf_info[i].bit_offset); 1333b458cd62SJohnny Huang } 1334b458cd62SJohnny Huang printf("0x%-10x", otp_value); 1335b458cd62SJohnny Huang 13363cb28812SJohnny Huang if (conf_info[i].value == OTP_REG_RESERVED) { 1337b458cd62SJohnny Huang printf("Reserved\n"); 13383cb28812SJohnny Huang } else if (conf_info[i].value == OTP_REG_VALUE) { 13393cb28812SJohnny Huang printf(conf_info[i].information, otp_value); 1340b458cd62SJohnny Huang printf("\n"); 13413cb28812SJohnny Huang } else if (conf_info[i].value == OTP_REG_VALID_BIT) { 1342b458cd62SJohnny Huang if (otp_value != 0) { 134373f11549SJohnny Huang for (j = 0; j < 7; j++) { 134473f11549SJohnny Huang if (otp_value == (1 << j)) { 134573f11549SJohnny Huang valid_bit[j * 2] = '1'; 1346b458cd62SJohnny Huang } else { 134773f11549SJohnny Huang valid_bit[j * 2] = '0'; 134873f11549SJohnny Huang } 134973f11549SJohnny Huang valid_bit[j * 2 + 1] = ' '; 135073f11549SJohnny Huang } 135173f11549SJohnny Huang valid_bit[15] = 0; 135273f11549SJohnny Huang } else { 135373f11549SJohnny Huang strcpy(valid_bit, "0 0 0 0 0 0 0 0\0"); 1354b458cd62SJohnny Huang } 13553cb28812SJohnny Huang printf(conf_info[i].information, valid_bit); 1356b458cd62SJohnny Huang printf("\n"); 1357b458cd62SJohnny Huang } else { 13583cb28812SJohnny Huang printf("%s\n", conf_info[i].information); 1359b458cd62SJohnny Huang } 1360b458cd62SJohnny Huang } 1361b458cd62SJohnny Huang return OTP_SUCCESS; 136266f2f8e5SJohnny Huang } 136366f2f8e5SJohnny Huang 13645010032bSJohnny Huang static int otp_print_strap_image(struct otp_image_layout *image_layout) 136576d13988SJohnny Huang { 136679e42a59SJoel Stanley const struct otpstrap_info *strap_info = info_cb.strap_info; 1367696656c6SJohnny Huang uint32_t *OTPSTRAP; 1368696656c6SJohnny Huang uint32_t *OTPSTRAP_REG_PRO; 1369696656c6SJohnny Huang uint32_t *OTPSTRAP_PRO; 1370696656c6SJohnny Huang uint32_t *OTPSTRAP_IGNORE; 137176d13988SJohnny Huang int i; 1372a8bd6d8cSJohnny Huang int fail = 0; 1373a8bd6d8cSJohnny Huang uint32_t bit_offset; 1374a8bd6d8cSJohnny Huang uint32_t dw_offset; 1375a8bd6d8cSJohnny Huang uint32_t mask; 1376a8bd6d8cSJohnny Huang uint32_t otp_value; 1377696656c6SJohnny Huang uint32_t otp_reg_protect; 1378a8bd6d8cSJohnny Huang uint32_t otp_protect; 1379696656c6SJohnny Huang uint32_t otp_ignore; 138076d13988SJohnny Huang 1381696656c6SJohnny Huang OTPSTRAP = (uint32_t *)image_layout->strap; 1382696656c6SJohnny Huang OTPSTRAP_PRO = (uint32_t *)image_layout->strap_pro; 1383696656c6SJohnny Huang OTPSTRAP_IGNORE = (uint32_t *)image_layout->strap_ignore; 13845010032bSJohnny Huang if (info_cb.version == OTP_AST2600A0) { 1385696656c6SJohnny Huang OTPSTRAP_REG_PRO = NULL; 1386a8bd6d8cSJohnny Huang printf("BIT(hex) Value Protect Description\n"); 1387696656c6SJohnny Huang } else { 1388696656c6SJohnny Huang OTPSTRAP_REG_PRO = (uint32_t *)image_layout->strap_reg_pro; 1389de6b0cc4SJohnny Huang printf("BIT(hex) Value Reg_Protect Protect Description\n"); 1390696656c6SJohnny Huang } 1391de6b0cc4SJohnny Huang printf("__________________________________________________________________________________________\n"); 1392b458cd62SJohnny Huang 13933cb28812SJohnny Huang for (i = 0; i < info_cb.strap_info_len; i++) { 1394696656c6SJohnny Huang if (strap_info[i].bit_offset > 31) { 1395a8bd6d8cSJohnny Huang dw_offset = 1; 13963cb28812SJohnny Huang bit_offset = strap_info[i].bit_offset - 32; 1397a8bd6d8cSJohnny Huang } else { 1398a8bd6d8cSJohnny Huang dw_offset = 0; 13993cb28812SJohnny Huang bit_offset = strap_info[i].bit_offset; 1400a8bd6d8cSJohnny Huang } 140176d13988SJohnny Huang 14023cb28812SJohnny Huang mask = BIT(strap_info[i].length) - 1; 1403a8bd6d8cSJohnny Huang otp_value = (OTPSTRAP[dw_offset] >> bit_offset) & mask; 1404a8bd6d8cSJohnny Huang otp_protect = (OTPSTRAP_PRO[dw_offset] >> bit_offset) & mask; 1405696656c6SJohnny Huang otp_ignore = (OTPSTRAP_IGNORE[dw_offset] >> bit_offset) & mask; 1406a8bd6d8cSJohnny Huang 14075010032bSJohnny Huang if (info_cb.version != OTP_AST2600A0) 1408696656c6SJohnny Huang otp_reg_protect = (OTPSTRAP_REG_PRO[dw_offset] >> bit_offset) & mask; 14095010032bSJohnny Huang else 14105010032bSJohnny Huang otp_reg_protect = 0; 1411696656c6SJohnny Huang 1412696656c6SJohnny Huang if (otp_ignore == mask) { 1413a8bd6d8cSJohnny Huang continue; 1414696656c6SJohnny Huang } else if (otp_ignore != 0) { 1415a8bd6d8cSJohnny Huang fail = 1; 1416a8bd6d8cSJohnny Huang } 1417a8bd6d8cSJohnny Huang 14183cb28812SJohnny Huang if ((otp_value != strap_info[i].value) && 14193cb28812SJohnny Huang strap_info[i].value != OTP_REG_RESERVED) 1420a8bd6d8cSJohnny Huang continue; 1421a8bd6d8cSJohnny Huang 14223cb28812SJohnny Huang if (strap_info[i].length == 1) { 14233cb28812SJohnny Huang printf("0x%-9X", strap_info[i].bit_offset); 1424a8bd6d8cSJohnny Huang } else { 1425b458cd62SJohnny Huang printf("0x%-2X:0x%-4X", 14263cb28812SJohnny Huang strap_info[i].bit_offset + strap_info[i].length - 1, 14273cb28812SJohnny Huang strap_info[i].bit_offset); 1428a8bd6d8cSJohnny Huang } 1429a8bd6d8cSJohnny Huang printf("0x%-10x", otp_value); 14305010032bSJohnny Huang if (info_cb.version != OTP_AST2600A0) 1431696656c6SJohnny Huang printf("0x%-10x", otp_reg_protect); 1432a8bd6d8cSJohnny Huang printf("0x%-10x", otp_protect); 1433a8bd6d8cSJohnny Huang 1434a8bd6d8cSJohnny Huang if (fail) { 1435696656c6SJohnny Huang printf("Ignore mask error\n"); 1436a8bd6d8cSJohnny Huang } else { 14373cb28812SJohnny Huang if (strap_info[i].value != OTP_REG_RESERVED) 14383cb28812SJohnny Huang printf("%s\n", strap_info[i].information); 1439a8bd6d8cSJohnny Huang else 1440a8bd6d8cSJohnny Huang printf("Reserved\n"); 1441a8bd6d8cSJohnny Huang } 1442a8bd6d8cSJohnny Huang } 1443a8bd6d8cSJohnny Huang 1444a8bd6d8cSJohnny Huang if (fail) 144576d13988SJohnny Huang return OTP_FAILURE; 144676d13988SJohnny Huang 144776d13988SJohnny Huang return OTP_SUCCESS; 144876d13988SJohnny Huang } 144976d13988SJohnny Huang 1450b458cd62SJohnny Huang static int otp_print_strap_info(int view) 145176d13988SJohnny Huang { 145279e42a59SJoel Stanley const struct otpstrap_info *strap_info = info_cb.strap_info; 145376d13988SJohnny Huang struct otpstrap_status strap_status[64]; 145407baa4e8SJohnny Huang int i, j; 1455b458cd62SJohnny Huang int fail = 0; 1456b458cd62SJohnny Huang uint32_t bit_offset; 1457b458cd62SJohnny Huang uint32_t length; 1458b458cd62SJohnny Huang uint32_t otp_value; 1459b458cd62SJohnny Huang uint32_t otp_protect; 146076d13988SJohnny Huang 1461541eb887SJohnny Huang otp_strap_status(strap_status); 146276d13988SJohnny Huang 1463b458cd62SJohnny Huang if (view) { 146483655e91SJohnny Huang if (info_cb.version == OTP_AST2600A0) 146507baa4e8SJohnny Huang printf("BIT(hex) Value Remains Protect Description\n"); 146683655e91SJohnny Huang else 146783655e91SJohnny Huang printf("BIT(hex) Value Remains Reg_Protect Protect Description\n"); 146807baa4e8SJohnny Huang printf("___________________________________________________________________________________________________\n"); 1469b458cd62SJohnny Huang } else { 1470b458cd62SJohnny Huang printf("BIT(hex) Value Description\n"); 1471b458cd62SJohnny Huang printf("________________________________________________________________________________\n"); 147276d13988SJohnny Huang } 14733cb28812SJohnny Huang for (i = 0; i < info_cb.strap_info_len; i++) { 1474b458cd62SJohnny Huang otp_value = 0; 14753cb28812SJohnny Huang bit_offset = strap_info[i].bit_offset; 14763cb28812SJohnny Huang length = strap_info[i].length; 1477b458cd62SJohnny Huang for (j = 0; j < length; j++) { 1478c947ef08SJohnny Huang otp_value |= strap_status[bit_offset + j].value << j; 1479c947ef08SJohnny Huang otp_protect |= strap_status[bit_offset + j].protected << j; 1480b458cd62SJohnny Huang } 14813cb28812SJohnny Huang if ((otp_value != strap_info[i].value) && 14823cb28812SJohnny Huang strap_info[i].value != OTP_REG_RESERVED) 1483b458cd62SJohnny Huang continue; 1484b458cd62SJohnny Huang if (view) { 1485b458cd62SJohnny Huang for (j = 0; j < length; j++) { 14863cb28812SJohnny Huang printf("0x%-7X", strap_info[i].bit_offset + j); 1487b458cd62SJohnny Huang printf("0x%-5X", strap_status[bit_offset + j].value); 148807baa4e8SJohnny Huang printf("%-9d", strap_status[bit_offset + j].remain_times); 148983655e91SJohnny Huang if (info_cb.version != OTP_AST2600A0) 1490e1a7245eSJohnny Huang printf("0x%-10X", strap_status[bit_offset + j].reg_protected); 1491e1a7245eSJohnny Huang printf("0x%-7X", strap_status[bit_offset + j].protected); 14923cb28812SJohnny Huang if (strap_info[i].value == OTP_REG_RESERVED) { 1493b458cd62SJohnny Huang printf(" Reserved\n"); 1494b458cd62SJohnny Huang continue; 1495b458cd62SJohnny Huang } 1496b458cd62SJohnny Huang if (length == 1) { 14973cb28812SJohnny Huang printf(" %s\n", strap_info[i].information); 1498b458cd62SJohnny Huang continue; 149976d13988SJohnny Huang } 150076d13988SJohnny Huang 1501b458cd62SJohnny Huang if (j == 0) 15023cb28812SJohnny Huang printf("/%s\n", strap_info[i].information); 1503b458cd62SJohnny Huang else if (j == length - 1) 1504b458cd62SJohnny Huang printf("\\ \"\n"); 1505b458cd62SJohnny Huang else 1506b458cd62SJohnny Huang printf("| \"\n"); 150776d13988SJohnny Huang } 1508b458cd62SJohnny Huang } else { 1509c947ef08SJohnny Huang if (length == 1) { 15103cb28812SJohnny Huang printf("0x%-9X", strap_info[i].bit_offset); 1511b458cd62SJohnny Huang } else { 1512b458cd62SJohnny Huang printf("0x%-2X:0x%-4X", 1513b458cd62SJohnny Huang bit_offset + length - 1, bit_offset); 1514b458cd62SJohnny Huang } 1515b458cd62SJohnny Huang 1516b458cd62SJohnny Huang printf("0x%-10X", otp_value); 1517b458cd62SJohnny Huang 15183cb28812SJohnny Huang if (strap_info[i].value != OTP_REG_RESERVED) 15193cb28812SJohnny Huang printf("%s\n", strap_info[i].information); 1520b458cd62SJohnny Huang else 1521b458cd62SJohnny Huang printf("Reserved\n"); 1522b458cd62SJohnny Huang } 1523b458cd62SJohnny Huang } 1524b458cd62SJohnny Huang 1525b458cd62SJohnny Huang if (fail) 1526b458cd62SJohnny Huang return OTP_FAILURE; 1527b458cd62SJohnny Huang 1528b458cd62SJohnny Huang return OTP_SUCCESS; 1529b458cd62SJohnny Huang } 1530b458cd62SJohnny Huang 1531696656c6SJohnny Huang static void buf_print(uint8_t *buf, int len) 153269d5fd8fSJohnny Huang { 153369d5fd8fSJohnny Huang int i; 153469d5fd8fSJohnny Huang printf(" 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F\n"); 153569d5fd8fSJohnny Huang for (i = 0; i < len; i++) { 153669d5fd8fSJohnny Huang if (i % 16 == 0) { 153769d5fd8fSJohnny Huang printf("%04X: ", i); 153869d5fd8fSJohnny Huang } 153969d5fd8fSJohnny Huang printf("%02X ", buf[i]); 154069d5fd8fSJohnny Huang if ((i + 1) % 16 == 0) { 154169d5fd8fSJohnny Huang printf("\n"); 154269d5fd8fSJohnny Huang } 154369d5fd8fSJohnny Huang } 154469d5fd8fSJohnny Huang } 154569d5fd8fSJohnny Huang 1546696656c6SJohnny Huang static int otp_print_data_info(struct otp_image_layout *image_layout) 154769d5fd8fSJohnny Huang { 154869d5fd8fSJohnny Huang int key_id, key_offset, last, key_type, key_length, exp_length; 154979e42a59SJoel Stanley const struct otpkey_type *key_info_array = info_cb.key_info; 15509a4fe690SJohnny Huang struct otpkey_type key_info; 1551696656c6SJohnny Huang uint32_t *buf; 1552696656c6SJohnny Huang uint8_t *byte_buf; 15539d998018SJohnny Huang char empty = 1; 155469d5fd8fSJohnny Huang int i = 0, len = 0; 15559a4fe690SJohnny Huang int j; 155654552c69SJohnny Huang 1557696656c6SJohnny Huang byte_buf = image_layout->data; 1558696656c6SJohnny Huang buf = (uint32_t *)byte_buf; 15599d998018SJohnny Huang 15609d998018SJohnny Huang for (i = 0; i < 16; i++) { 15619d998018SJohnny Huang if (buf[i] != 0) { 15629d998018SJohnny Huang empty = 0; 15639d998018SJohnny Huang } 15649d998018SJohnny Huang } 15659d998018SJohnny Huang if (empty) 15669d998018SJohnny Huang return 0; 15679d998018SJohnny Huang 15689d998018SJohnny Huang i = 0; 156969d5fd8fSJohnny Huang while (1) { 157069d5fd8fSJohnny Huang key_id = buf[i] & 0x7; 157169d5fd8fSJohnny Huang key_offset = buf[i] & 0x1ff8; 157269d5fd8fSJohnny Huang last = (buf[i] >> 13) & 1; 157369d5fd8fSJohnny Huang key_type = (buf[i] >> 14) & 0xf; 157469d5fd8fSJohnny Huang key_length = (buf[i] >> 18) & 0x3; 157569d5fd8fSJohnny Huang exp_length = (buf[i] >> 20) & 0xfff; 15769a4fe690SJohnny Huang 15779a4fe690SJohnny Huang for (j = 0; j < info_cb.key_info_len; j++) { 15789a4fe690SJohnny Huang if (key_type == key_info_array[j].value) { 15799a4fe690SJohnny Huang key_info = key_info_array[j]; 15809a4fe690SJohnny Huang break; 15819a4fe690SJohnny Huang } 15829a4fe690SJohnny Huang } 15839a4fe690SJohnny Huang 15847f795e57SJohnny Huang printf("\nKey[%d]:\n", i); 158569d5fd8fSJohnny Huang printf("Key Type: "); 15869a4fe690SJohnny Huang printf("%s\n", key_info.information); 15879a4fe690SJohnny Huang 15889a4fe690SJohnny Huang if (key_info.key_type == OTP_KEY_TYPE_HMAC) { 158969d5fd8fSJohnny Huang printf("HMAC SHA Type: "); 159069d5fd8fSJohnny Huang switch (key_length) { 159169d5fd8fSJohnny Huang case 0: 159269d5fd8fSJohnny Huang printf("HMAC(SHA224)\n"); 159369d5fd8fSJohnny Huang break; 159469d5fd8fSJohnny Huang case 1: 159569d5fd8fSJohnny Huang printf("HMAC(SHA256)\n"); 159669d5fd8fSJohnny Huang break; 159769d5fd8fSJohnny Huang case 2: 159869d5fd8fSJohnny Huang printf("HMAC(SHA384)\n"); 159969d5fd8fSJohnny Huang break; 160069d5fd8fSJohnny Huang case 3: 160169d5fd8fSJohnny Huang printf("HMAC(SHA512)\n"); 160269d5fd8fSJohnny Huang break; 160369d5fd8fSJohnny Huang } 16049a4fe690SJohnny Huang } else if (key_info.key_type == OTP_KEY_TYPE_RSA) { 160569d5fd8fSJohnny Huang printf("RSA SHA Type: "); 160669d5fd8fSJohnny Huang switch (key_length) { 160769d5fd8fSJohnny Huang case 0: 160869d5fd8fSJohnny Huang printf("RSA1024\n"); 160969d5fd8fSJohnny Huang len = 0x100; 161069d5fd8fSJohnny Huang break; 161169d5fd8fSJohnny Huang case 1: 161269d5fd8fSJohnny Huang printf("RSA2048\n"); 161369d5fd8fSJohnny Huang len = 0x200; 161469d5fd8fSJohnny Huang break; 161569d5fd8fSJohnny Huang case 2: 161669d5fd8fSJohnny Huang printf("RSA3072\n"); 161769d5fd8fSJohnny Huang len = 0x300; 161869d5fd8fSJohnny Huang break; 161969d5fd8fSJohnny Huang case 3: 162069d5fd8fSJohnny Huang printf("RSA4096\n"); 162169d5fd8fSJohnny Huang len = 0x400; 162269d5fd8fSJohnny Huang break; 162369d5fd8fSJohnny Huang } 162469d5fd8fSJohnny Huang printf("RSA exponent bit length: %d\n", exp_length); 162569d5fd8fSJohnny Huang } 16269a4fe690SJohnny Huang if (key_info.need_id) 162769d5fd8fSJohnny Huang printf("Key Number ID: %d\n", key_id); 162869d5fd8fSJohnny Huang printf("Key Value:\n"); 16299a4fe690SJohnny Huang if (key_info.key_type == OTP_KEY_TYPE_HMAC) { 163069d5fd8fSJohnny Huang buf_print(&byte_buf[key_offset], 0x40); 16319a4fe690SJohnny Huang } else if (key_info.key_type == OTP_KEY_TYPE_AES) { 16329a4fe690SJohnny Huang printf("AES Key:\n"); 16339a4fe690SJohnny Huang buf_print(&byte_buf[key_offset], 0x20); 1634*5fdde29fSJohnny Huang if (info_cb.version == OTP_AST2600A0) { 16359a4fe690SJohnny Huang printf("AES IV:\n"); 16369a4fe690SJohnny Huang buf_print(&byte_buf[key_offset + 0x20], 0x10); 16379a4fe690SJohnny Huang } 16389a4fe690SJohnny Huang 16399a4fe690SJohnny Huang } else if (key_info.key_type == OTP_KEY_TYPE_VAULT) { 1640*5fdde29fSJohnny Huang if (info_cb.version == OTP_AST2600A0) { 164169d5fd8fSJohnny Huang printf("AES Key:\n"); 164269d5fd8fSJohnny Huang buf_print(&byte_buf[key_offset], 0x20); 164369d5fd8fSJohnny Huang printf("AES IV:\n"); 164469d5fd8fSJohnny Huang buf_print(&byte_buf[key_offset + 0x20], 0x10); 1645*5fdde29fSJohnny Huang } else { 16469a4fe690SJohnny Huang printf("AES Key 1:\n"); 16479a4fe690SJohnny Huang buf_print(&byte_buf[key_offset], 0x20); 16489a4fe690SJohnny Huang printf("AES Key 2:\n"); 16499a4fe690SJohnny Huang buf_print(&byte_buf[key_offset + 0x20], 0x20); 16509a4fe690SJohnny Huang } 165169d5fd8fSJohnny Huang 16529a4fe690SJohnny Huang } else if (key_info.key_type == OTP_KEY_TYPE_RSA) { 165369d5fd8fSJohnny Huang printf("RSA mod:\n"); 165469d5fd8fSJohnny Huang buf_print(&byte_buf[key_offset], len / 2); 165569d5fd8fSJohnny Huang printf("RSA exp:\n"); 165669d5fd8fSJohnny Huang buf_print(&byte_buf[key_offset + (len / 2)], len / 2); 165769d5fd8fSJohnny Huang } 165869d5fd8fSJohnny Huang if (last) 165969d5fd8fSJohnny Huang break; 166069d5fd8fSJohnny Huang i++; 166169d5fd8fSJohnny Huang } 166269d5fd8fSJohnny Huang return 0; 166369d5fd8fSJohnny Huang } 166469d5fd8fSJohnny Huang 16655010032bSJohnny Huang static int otp_prog_conf(struct otp_image_layout *image_layout) 166669d5fd8fSJohnny Huang { 1667a6d0d645SJohnny Huang int i, k; 1668d90825e2SJohnny Huang int pass = 0; 1669a6d0d645SJohnny Huang uint32_t prog_address; 1670bb34a7bfSJohnny Huang uint32_t data[16]; 1671a6d0d645SJohnny Huang uint32_t compare[2]; 16725010032bSJohnny Huang uint32_t *conf = (uint32_t *)image_layout->conf; 16735010032bSJohnny Huang uint32_t *conf_ignore = (uint32_t *)image_layout->conf_ignore; 1674d90825e2SJohnny Huang uint32_t data_masked; 1675d90825e2SJohnny Huang uint32_t buf_masked; 167669d5fd8fSJohnny Huang 1677a6d0d645SJohnny Huang printf("Read OTP Config Region:\n"); 1678a6d0d645SJohnny Huang 1679bb34a7bfSJohnny Huang for (i = 0; i < 16 ; i ++) { 168069d5fd8fSJohnny Huang prog_address = 0x800; 1681a6d0d645SJohnny Huang prog_address |= (i / 8) * 0x200; 1682a6d0d645SJohnny Huang prog_address |= (i % 8) * 0x2; 1683a6d0d645SJohnny Huang otp_read_data(prog_address, &data[i]); 1684a6d0d645SJohnny Huang } 1685a6d0d645SJohnny Huang 1686a6d0d645SJohnny Huang printf("Check writable...\n"); 1687bb34a7bfSJohnny Huang for (i = 0; i < 16; i++) { 16885010032bSJohnny Huang data_masked = data[i] & ~conf_ignore[i]; 16895010032bSJohnny Huang buf_masked = conf[i] & ~conf_ignore[i]; 1690d90825e2SJohnny Huang if (data_masked == buf_masked) 169169d5fd8fSJohnny Huang continue; 1692d90825e2SJohnny Huang if ((data_masked | buf_masked) == buf_masked) { 1693a6d0d645SJohnny Huang continue; 1694a6d0d645SJohnny Huang } else { 1695a6d0d645SJohnny Huang printf("Input image can't program into OTP, please check.\n"); 1696a6af4a17SJohnny Huang printf("OTPCFG[%X] = %x\n", i, data[i]); 16975010032bSJohnny Huang printf("Input [%X] = %x\n", i, conf[i]); 16985010032bSJohnny Huang printf("Mask [%X] = %x\n", i, ~conf_ignore[i]); 16992a856b9aSJohnny Huang return OTP_FAILURE; 1700a6d0d645SJohnny Huang } 1701a6d0d645SJohnny Huang } 1702a6d0d645SJohnny Huang 1703a6d0d645SJohnny Huang printf("Start Programing...\n"); 1704d90825e2SJohnny Huang otp_soak(0); 1705bb34a7bfSJohnny Huang for (i = 0; i < 16; i++) { 17065010032bSJohnny Huang data_masked = data[i] & ~conf_ignore[i]; 17075010032bSJohnny Huang buf_masked = conf[i] & ~conf_ignore[i]; 1708a6d0d645SJohnny Huang prog_address = 0x800; 1709a6d0d645SJohnny Huang prog_address |= (i / 8) * 0x200; 1710a6d0d645SJohnny Huang prog_address |= (i % 8) * 0x2; 1711bb34a7bfSJohnny Huang if (data_masked == buf_masked) { 1712bb34a7bfSJohnny Huang pass = 1; 1713a6d0d645SJohnny Huang continue; 1714bb34a7bfSJohnny Huang } 1715de6fbf1cSJohnny Huang 1716a6d0d645SJohnny Huang 1717de6fbf1cSJohnny Huang otp_soak(1); 17185010032bSJohnny Huang otp_prog_dw(conf[i], conf_ignore[i], prog_address); 1719a6d0d645SJohnny Huang 172069d5fd8fSJohnny Huang pass = 0; 172169d5fd8fSJohnny Huang for (k = 0; k < RETRY; k++) { 17225010032bSJohnny Huang if (verify_dw(prog_address, &conf[i], &conf_ignore[i], compare, 1) != 0) { 1723de6fbf1cSJohnny Huang otp_soak(2); 1724a6d0d645SJohnny Huang otp_prog_dw(compare[0], prog_address, 1); 17255010032bSJohnny Huang if (verify_dw(prog_address, &conf[i], &conf_ignore[i], compare, 1) != 0) { 1726de6fbf1cSJohnny Huang otp_soak(1); 1727de6fbf1cSJohnny Huang } else { 1728de6fbf1cSJohnny Huang pass = 1; 1729de6fbf1cSJohnny Huang break; 1730de6fbf1cSJohnny Huang } 1731a6d0d645SJohnny Huang } else { 173269d5fd8fSJohnny Huang pass = 1; 173369d5fd8fSJohnny Huang break; 173469d5fd8fSJohnny Huang } 173569d5fd8fSJohnny Huang } 1736bb34a7bfSJohnny Huang if (pass == 0) { 1737bb34a7bfSJohnny Huang printf("address: %08x, data: %08x, buffer: %08x, mask: %08x\n", 17385010032bSJohnny Huang i, data[i], conf[i], conf_ignore[i]); 1739bb34a7bfSJohnny Huang break; 1740bb34a7bfSJohnny Huang } 1741a6d0d645SJohnny Huang } 1742a6d0d645SJohnny Huang 1743de6fbf1cSJohnny Huang otp_soak(0); 174469d5fd8fSJohnny Huang if (!pass) 17452a856b9aSJohnny Huang return OTP_FAILURE; 1746a6d0d645SJohnny Huang 17472a856b9aSJohnny Huang return OTP_SUCCESS; 1748d90825e2SJohnny Huang 174969d5fd8fSJohnny Huang } 175069d5fd8fSJohnny Huang 1751eda10d61SJohnny Huang static int otp_strap_bit_confirm(struct otpstrap_status *otpstrap, int offset, int ibit, int bit, int pbit, int rpbit) 1752eda10d61SJohnny Huang { 1753eda10d61SJohnny Huang if (ibit == 1) { 1754eda10d61SJohnny Huang return OTP_SUCCESS; 1755eda10d61SJohnny Huang } else { 1756eda10d61SJohnny Huang printf("OTPSTRAP[%X]:\n", offset); 1757eda10d61SJohnny Huang } 1758eda10d61SJohnny Huang if (bit == otpstrap->value) { 1759eda10d61SJohnny Huang printf(" The value is same as before, skip it.\n"); 1760eda10d61SJohnny Huang return OTP_PROG_SKIP; 1761eda10d61SJohnny Huang } 1762eda10d61SJohnny Huang if (otpstrap->protected == 1) { 1763eda10d61SJohnny Huang printf(" This bit is protected and is not writable\n"); 1764eda10d61SJohnny Huang return OTP_FAILURE; 1765eda10d61SJohnny Huang } 1766eda10d61SJohnny Huang if (otpstrap->remain_times == 0) { 1767eda10d61SJohnny Huang printf(" This bit is no remaining times to write.\n"); 1768eda10d61SJohnny Huang return OTP_FAILURE; 1769eda10d61SJohnny Huang } 1770eda10d61SJohnny Huang if (pbit == 1) { 1771eda10d61SJohnny Huang printf(" This bit will be protected and become non-writable.\n"); 1772eda10d61SJohnny Huang } 1773eda10d61SJohnny Huang if (rpbit == 1 && info_cb.version != OTP_AST2600A0) { 1774eda10d61SJohnny Huang printf(" The relative register will be protected.\n"); 1775eda10d61SJohnny Huang } 1776eda10d61SJohnny Huang printf(" Write 1 to OTPSTRAP[%X] OPTION[%X], that value becomes from %d to %d.\n", offset, otpstrap->writeable_option + 1, otpstrap->value, otpstrap->value ^ 1); 1777eda10d61SJohnny Huang return OTP_SUCCESS; 1778eda10d61SJohnny Huang } 1779eda10d61SJohnny Huang 17805010032bSJohnny Huang static int otp_strap_image_confirm(struct otp_image_layout *image_layout) 178169d5fd8fSJohnny Huang { 178269d5fd8fSJohnny Huang int i; 17835010032bSJohnny Huang uint32_t *strap; 17845010032bSJohnny Huang uint32_t *strap_ignore; 17855010032bSJohnny Huang uint32_t *strap_reg_protect; 17865010032bSJohnny Huang uint32_t *strap_pro; 1787eda10d61SJohnny Huang int bit, pbit, ibit, rpbit; 178869d5fd8fSJohnny Huang int fail = 0; 1789a6af4a17SJohnny Huang int skip = -1; 1790eda10d61SJohnny Huang int ret; 179166f2f8e5SJohnny Huang struct otpstrap_status otpstrap[64]; 179269d5fd8fSJohnny Huang 17935010032bSJohnny Huang strap = (uint32_t *)image_layout->strap; 17945010032bSJohnny Huang strap_pro = (uint32_t *)image_layout->strap_pro; 17955010032bSJohnny Huang strap_ignore = (uint32_t *)image_layout->strap_ignore; 17965010032bSJohnny Huang strap_reg_protect = (uint32_t *)image_layout->strap_reg_pro; 17975010032bSJohnny Huang 1798541eb887SJohnny Huang otp_strap_status(otpstrap); 179969d5fd8fSJohnny Huang for (i = 0; i < 64; i++) { 180069d5fd8fSJohnny Huang if (i < 32) { 18015010032bSJohnny Huang bit = (strap[0] >> i) & 0x1; 1802eda10d61SJohnny Huang ibit = (strap_ignore[0] >> i) & 0x1; 18035010032bSJohnny Huang pbit = (strap_pro[0] >> i) & 0x1; 180469d5fd8fSJohnny Huang } else { 18055010032bSJohnny Huang bit = (strap[1] >> (i - 32)) & 0x1; 1806eda10d61SJohnny Huang ibit = (strap_ignore[1] >> (i - 32)) & 0x1; 18075010032bSJohnny Huang pbit = (strap_pro[1] >> (i - 32)) & 0x1; 18085010032bSJohnny Huang } 18095010032bSJohnny Huang 18105010032bSJohnny Huang if (info_cb.version != OTP_AST2600A0) { 18115010032bSJohnny Huang if (i < 32) { 18125010032bSJohnny Huang rpbit = (strap_reg_protect[0] >> i) & 0x1; 18135010032bSJohnny Huang } else { 18145010032bSJohnny Huang rpbit = (strap_reg_protect[1] >> (i - 32)) & 0x1; 18155010032bSJohnny Huang } 18165010032bSJohnny Huang } else { 18175010032bSJohnny Huang rpbit = 0; 181869d5fd8fSJohnny Huang } 1819eda10d61SJohnny Huang ret = otp_strap_bit_confirm(&otpstrap[i], i, ibit, bit, pbit, rpbit); 1820eda10d61SJohnny Huang if (ret == OTP_PROG_SKIP) { 1821a6af4a17SJohnny Huang if (skip == -1) 1822a6af4a17SJohnny Huang skip = 1; 182369d5fd8fSJohnny Huang continue; 1824a6af4a17SJohnny Huang } else { 1825eda10d61SJohnny Huang skip = 1; 182669d5fd8fSJohnny Huang } 1827eda10d61SJohnny Huang 1828eda10d61SJohnny Huang if (ret == OTP_FAILURE) 182969d5fd8fSJohnny Huang fail = 1; 183069d5fd8fSJohnny Huang } 183169d5fd8fSJohnny Huang if (fail == 1) 1832a6af4a17SJohnny Huang return OTP_FAILURE; 1833a6af4a17SJohnny Huang else if (skip == 1) 1834a6af4a17SJohnny Huang return OTP_PROG_SKIP; 18357e22f42dSJohnny Huang 1836eda10d61SJohnny Huang return OTP_SUCCESS; 183769d5fd8fSJohnny Huang } 183869d5fd8fSJohnny Huang 18392a856b9aSJohnny Huang static int otp_print_strap(int start, int count) 184069d5fd8fSJohnny Huang { 184169d5fd8fSJohnny Huang int i, j; 1842de6b0cc4SJohnny Huang int remains; 184366f2f8e5SJohnny Huang struct otpstrap_status otpstrap[64]; 184469d5fd8fSJohnny Huang 18452a856b9aSJohnny Huang if (start < 0 || start > 64) 18462a856b9aSJohnny Huang return OTP_USAGE; 18472a856b9aSJohnny Huang 18482a856b9aSJohnny Huang if ((start + count) < 0 || (start + count) > 64) 18492a856b9aSJohnny Huang return OTP_USAGE; 18502a856b9aSJohnny Huang 1851541eb887SJohnny Huang otp_strap_status(otpstrap); 185269d5fd8fSJohnny Huang 1853de6b0cc4SJohnny Huang if (info_cb.version == OTP_AST2600A0) { 1854de6b0cc4SJohnny Huang remains = 7; 185507baa4e8SJohnny Huang printf("BIT(hex) Value Option Status\n"); 1856de6b0cc4SJohnny Huang } else { 1857de6b0cc4SJohnny Huang remains = 6; 1858de6b0cc4SJohnny Huang printf("BIT(hex) Value Option Reg_Protect Status\n"); 1859de6b0cc4SJohnny Huang } 1860de6b0cc4SJohnny Huang printf("______________________________________________________________________________\n"); 1861737ed20bSJohnny Huang 1862cd1610b4SJohnny Huang for (i = start; i < start + count; i++) { 186307baa4e8SJohnny Huang printf("0x%-8X", i); 1864737ed20bSJohnny Huang printf("%-7d", otpstrap[i].value); 1865de6b0cc4SJohnny Huang for (j = 0; j < remains; j++) 1866737ed20bSJohnny Huang printf("%d ", otpstrap[i].option_array[j]); 1867737ed20bSJohnny Huang printf(" "); 1868de6b0cc4SJohnny Huang if (info_cb.version != OTP_AST2600A0) { 1869de6b0cc4SJohnny Huang printf("%d ", otpstrap[i].reg_protected); 1870de6b0cc4SJohnny Huang } 187169d5fd8fSJohnny Huang if (otpstrap[i].protected == 1) { 1872737ed20bSJohnny Huang printf("protected and not writable"); 187369d5fd8fSJohnny Huang } else { 1874737ed20bSJohnny Huang printf("not protected "); 187569d5fd8fSJohnny Huang if (otpstrap[i].remain_times == 0) { 1876737ed20bSJohnny Huang printf("and no remaining times to write."); 187769d5fd8fSJohnny Huang } else { 1878737ed20bSJohnny Huang printf("and still can write %d times", otpstrap[i].remain_times); 187969d5fd8fSJohnny Huang } 188069d5fd8fSJohnny Huang } 1881737ed20bSJohnny Huang printf("\n"); 188269d5fd8fSJohnny Huang } 18832a856b9aSJohnny Huang 18842a856b9aSJohnny Huang return OTP_SUCCESS; 188569d5fd8fSJohnny Huang } 188669d5fd8fSJohnny Huang 18878848d5dcSJohnny Huang static int otp_prog_strap_bit(int bit_offset, int value) 18888848d5dcSJohnny Huang { 18898848d5dcSJohnny Huang struct otpstrap_status otpstrap[64]; 189083655e91SJohnny Huang uint32_t prog_address; 18918848d5dcSJohnny Huang int offset; 18928848d5dcSJohnny Huang int ret; 18938848d5dcSJohnny Huang 18948848d5dcSJohnny Huang 18958848d5dcSJohnny Huang otp_strap_status(otpstrap); 18968848d5dcSJohnny Huang 18978848d5dcSJohnny Huang ret = otp_strap_bit_confirm(&otpstrap[bit_offset], bit_offset, 0, value, 0, 0); 18988848d5dcSJohnny Huang 18998848d5dcSJohnny Huang if (ret != OTP_SUCCESS) { 19008848d5dcSJohnny Huang return ret; 19018848d5dcSJohnny Huang } 19028848d5dcSJohnny Huang 19038848d5dcSJohnny Huang prog_address = 0x800; 19048848d5dcSJohnny Huang if (bit_offset < 32) { 19058848d5dcSJohnny Huang offset = bit_offset; 19068848d5dcSJohnny Huang prog_address |= ((otpstrap[bit_offset].writeable_option * 2 + 16) / 8) * 0x200; 19078848d5dcSJohnny Huang prog_address |= ((otpstrap[bit_offset].writeable_option * 2 + 16) % 8) * 0x2; 19088848d5dcSJohnny Huang 19098848d5dcSJohnny Huang } else { 19108848d5dcSJohnny Huang offset = (bit_offset - 32); 19118848d5dcSJohnny Huang prog_address |= ((otpstrap[bit_offset].writeable_option * 2 + 17) / 8) * 0x200; 19128848d5dcSJohnny Huang prog_address |= ((otpstrap[bit_offset].writeable_option * 2 + 17) % 8) * 0x2; 19138848d5dcSJohnny Huang } 19148848d5dcSJohnny Huang 19158848d5dcSJohnny Huang 191683655e91SJohnny Huang return otp_prog_bit(1, prog_address, offset); 19178848d5dcSJohnny Huang } 19188848d5dcSJohnny Huang 19195010032bSJohnny Huang static int otp_prog_strap(struct otp_image_layout *image_layout) 192069d5fd8fSJohnny Huang { 19215010032bSJohnny Huang uint32_t *strap; 19225010032bSJohnny Huang uint32_t *strap_ignore; 19235010032bSJohnny Huang uint32_t *strap_pro; 19245010032bSJohnny Huang uint32_t *strap_reg_protect; 192583655e91SJohnny Huang uint32_t prog_address; 192683655e91SJohnny Huang int i; 1927eda10d61SJohnny Huang int bit, pbit, ibit, offset, rpbit; 192869d5fd8fSJohnny Huang int fail = 0; 192983655e91SJohnny Huang int ret; 193066f2f8e5SJohnny Huang struct otpstrap_status otpstrap[64]; 193169d5fd8fSJohnny Huang 19325010032bSJohnny Huang strap = (uint32_t *)image_layout->strap; 19335010032bSJohnny Huang strap_pro = (uint32_t *)image_layout->strap_pro; 19345010032bSJohnny Huang strap_ignore = (uint32_t *)image_layout->strap_ignore; 19355010032bSJohnny Huang strap_reg_protect = (uint32_t *)image_layout->strap_reg_pro; 19365010032bSJohnny Huang 19377f795e57SJohnny Huang printf("Read OTP Strap Region:\n"); 1938541eb887SJohnny Huang otp_strap_status(otpstrap); 193969d5fd8fSJohnny Huang 19407f795e57SJohnny Huang printf("Check writable...\n"); 19415010032bSJohnny Huang if (otp_strap_image_confirm(image_layout) == OTP_FAILURE) { 19427f795e57SJohnny Huang printf("Input image can't program into OTP, please check.\n"); 19437f795e57SJohnny Huang return OTP_FAILURE; 19447f795e57SJohnny Huang } 19457e22f42dSJohnny Huang 194669d5fd8fSJohnny Huang for (i = 0; i < 64; i++) { 194769d5fd8fSJohnny Huang prog_address = 0x800; 194869d5fd8fSJohnny Huang if (i < 32) { 194969d5fd8fSJohnny Huang offset = i; 19505010032bSJohnny Huang bit = (strap[0] >> offset) & 0x1; 1951eda10d61SJohnny Huang ibit = (strap_ignore[0] >> offset) & 0x1; 19525010032bSJohnny Huang pbit = (strap_pro[0] >> offset) & 0x1; 195369d5fd8fSJohnny Huang prog_address |= ((otpstrap[i].writeable_option * 2 + 16) / 8) * 0x200; 195469d5fd8fSJohnny Huang prog_address |= ((otpstrap[i].writeable_option * 2 + 16) % 8) * 0x2; 195569d5fd8fSJohnny Huang 195669d5fd8fSJohnny Huang } else { 195769d5fd8fSJohnny Huang offset = (i - 32); 19585010032bSJohnny Huang bit = (strap[1] >> offset) & 0x1; 1959eda10d61SJohnny Huang ibit = (strap_ignore[1] >> offset) & 0x1; 19605010032bSJohnny Huang pbit = (strap_pro[1] >> offset) & 0x1; 196169d5fd8fSJohnny Huang prog_address |= ((otpstrap[i].writeable_option * 2 + 17) / 8) * 0x200; 196269d5fd8fSJohnny Huang prog_address |= ((otpstrap[i].writeable_option * 2 + 17) % 8) * 0x2; 196369d5fd8fSJohnny Huang } 19645010032bSJohnny Huang if (info_cb.version != OTP_AST2600A0) { 19655010032bSJohnny Huang if (i < 32) { 19665010032bSJohnny Huang rpbit = (strap_reg_protect[0] >> i) & 0x1; 19675010032bSJohnny Huang } else { 19685010032bSJohnny Huang rpbit = (strap_reg_protect[1] >> (i - 32)) & 0x1; 19695010032bSJohnny Huang } 19705010032bSJohnny Huang } else { 19715010032bSJohnny Huang rpbit = 0; 19725010032bSJohnny Huang } 197369d5fd8fSJohnny Huang 1974eda10d61SJohnny Huang if (ibit == 1) { 197569d5fd8fSJohnny Huang continue; 197669d5fd8fSJohnny Huang } 197769d5fd8fSJohnny Huang if (bit == otpstrap[i].value) { 197869d5fd8fSJohnny Huang continue; 197969d5fd8fSJohnny Huang } 198069d5fd8fSJohnny Huang if (otpstrap[i].protected == 1) { 198169d5fd8fSJohnny Huang fail = 1; 198269d5fd8fSJohnny Huang continue; 198369d5fd8fSJohnny Huang } 198469d5fd8fSJohnny Huang if (otpstrap[i].remain_times == 0) { 198569d5fd8fSJohnny Huang fail = 1; 198669d5fd8fSJohnny Huang continue; 198769d5fd8fSJohnny Huang } 19887e22f42dSJohnny Huang 198983655e91SJohnny Huang ret = otp_prog_bit(1, prog_address, offset); 199083655e91SJohnny Huang if (!ret) 19912a856b9aSJohnny Huang return OTP_FAILURE; 199269d5fd8fSJohnny Huang 19935010032bSJohnny Huang if (rpbit == 1 && info_cb.version != OTP_AST2600A0) { 199469d5fd8fSJohnny Huang prog_address = 0x800; 199569d5fd8fSJohnny Huang if (i < 32) 19965010032bSJohnny Huang prog_address |= 0x608; 199769d5fd8fSJohnny Huang else 19985010032bSJohnny Huang prog_address |= 0x60a; 19997e22f42dSJohnny Huang 200083655e91SJohnny Huang ret = otp_prog_bit(1, prog_address, offset); 200183655e91SJohnny Huang if (!ret) 20022a856b9aSJohnny Huang return OTP_FAILURE; 20035010032bSJohnny Huang } 20045010032bSJohnny Huang 20055010032bSJohnny Huang if (pbit != 0) { 20065010032bSJohnny Huang prog_address = 0x800; 20075010032bSJohnny Huang if (i < 32) 20085010032bSJohnny Huang prog_address |= 0x60c; 20095010032bSJohnny Huang else 20105010032bSJohnny Huang prog_address |= 0x60e; 20115010032bSJohnny Huang 201283655e91SJohnny Huang ret = otp_prog_bit(1, prog_address, offset); 201383655e91SJohnny Huang if (!ret) 20145010032bSJohnny Huang return OTP_FAILURE; 20155010032bSJohnny Huang } 201669d5fd8fSJohnny Huang 201769d5fd8fSJohnny Huang } 2018de6fbf1cSJohnny Huang otp_soak(0); 201969d5fd8fSJohnny Huang if (fail == 1) 20202a856b9aSJohnny Huang return OTP_FAILURE; 202169d5fd8fSJohnny Huang else 20222a856b9aSJohnny Huang return OTP_SUCCESS; 202369d5fd8fSJohnny Huang 202469d5fd8fSJohnny Huang } 202569d5fd8fSJohnny Huang 20265010032bSJohnny Huang static int otp_prog_data(struct otp_image_layout *image_layout) 20274c1c9b35SJohnny Huang { 202854552c69SJohnny Huang int i; 202954552c69SJohnny Huang int ret; 20305010032bSJohnny Huang int data_dw; 2031d90825e2SJohnny Huang uint32_t data[2048]; 20325010032bSJohnny Huang uint32_t *buf; 20335010032bSJohnny Huang uint32_t *buf_ignore; 20344c1c9b35SJohnny Huang 203554552c69SJohnny Huang uint32_t data_masked; 203654552c69SJohnny Huang uint32_t buf_masked; 20374c1c9b35SJohnny Huang 20385010032bSJohnny Huang buf = (uint32_t *)image_layout->data; 20395010032bSJohnny Huang buf_ignore = (uint32_t *)image_layout->data_ignore; 20405010032bSJohnny Huang 20415010032bSJohnny Huang data_dw = image_layout->data_length / 4; 20425010032bSJohnny Huang 20434c1c9b35SJohnny Huang printf("Read OTP Data:\n"); 20444c1c9b35SJohnny Huang 20455010032bSJohnny Huang for (i = 0; i < data_dw - 2 ; i += 2) { 2046d90825e2SJohnny Huang otp_read_data(i, &data[i]); 20474c1c9b35SJohnny Huang } 2048d90825e2SJohnny Huang 20494c1c9b35SJohnny Huang printf("Check writable...\n"); 205054552c69SJohnny Huang // ignore last two dw, the last two dw is used for slt otp write check. 20515010032bSJohnny Huang for (i = 0; i < data_dw - 2; i++) { 2052696656c6SJohnny Huang data_masked = data[i] & ~buf_ignore[i]; 2053696656c6SJohnny Huang buf_masked = buf[i] & ~buf_ignore[i]; 205454552c69SJohnny Huang if (data_masked == buf_masked) 20554c1c9b35SJohnny Huang continue; 2056d90825e2SJohnny Huang if (i % 2 == 0) { 205754552c69SJohnny Huang if ((data_masked | buf_masked) == buf_masked) { 20584c1c9b35SJohnny Huang continue; 20594c1c9b35SJohnny Huang } else { 20604c1c9b35SJohnny Huang printf("Input image can't program into OTP, please check.\n"); 2061d90825e2SJohnny Huang printf("OTP_ADDR[%x] = %x\n", i, data[i]); 20624c1c9b35SJohnny Huang printf("Input [%x] = %x\n", i, buf[i]); 2063696656c6SJohnny Huang printf("Mask [%x] = %x\n", i, ~buf_ignore[i]); 20642a856b9aSJohnny Huang return OTP_FAILURE; 206569d5fd8fSJohnny Huang } 2066d90825e2SJohnny Huang } else { 206754552c69SJohnny Huang if ((data_masked & buf_masked) == buf_masked) { 2068d90825e2SJohnny Huang continue; 2069d90825e2SJohnny Huang } else { 2070d90825e2SJohnny Huang printf("Input image can't program into OTP, please check.\n"); 2071d90825e2SJohnny Huang printf("OTP_ADDR[%x] = %x\n", i, data[i]); 2072d90825e2SJohnny Huang printf("Input [%x] = %x\n", i, buf[i]); 2073696656c6SJohnny Huang printf("Mask [%x] = %x\n", i, ~buf_ignore[i]); 20742a856b9aSJohnny Huang return OTP_FAILURE; 2075d90825e2SJohnny Huang } 2076d90825e2SJohnny Huang } 2077d90825e2SJohnny Huang } 207869d5fd8fSJohnny Huang 2079d90825e2SJohnny Huang printf("Start Programing...\n"); 2080d90825e2SJohnny Huang 208154552c69SJohnny Huang // programing ecc region first 208254552c69SJohnny Huang for (i = 1792; i < 2046; i += 2) { 2083696656c6SJohnny Huang ret = otp_prog_verify_2dw(&data[i], &buf[i], &buf_ignore[i], i); 208454552c69SJohnny Huang if (ret != OTP_SUCCESS) { 208554552c69SJohnny Huang printf("address: %08x, data: %08x %08x, buffer: %08x %08x, mask: %08x %08x\n", 2086696656c6SJohnny Huang i, data[i], data[i + 1], buf[i], buf[i + 1], buf_ignore[i], buf_ignore[i + 1]); 208754552c69SJohnny Huang return ret; 2088d90825e2SJohnny Huang } 2089d90825e2SJohnny Huang } 2090d90825e2SJohnny Huang 209154552c69SJohnny Huang for (i = 0; i < 1792; i += 2) { 2092696656c6SJohnny Huang ret = otp_prog_verify_2dw(&data[i], &buf[i], &buf_ignore[i], i); 209354552c69SJohnny Huang if (ret != OTP_SUCCESS) { 209454552c69SJohnny Huang printf("address: %08x, data: %08x %08x, buffer: %08x %08x, mask: %08x %08x\n", 2095696656c6SJohnny Huang i, data[i], data[i + 1], buf[i], buf[i + 1], buf_ignore[i], buf_ignore[i + 1]); 209654552c69SJohnny Huang return ret; 2097d90825e2SJohnny Huang } 2098de6fbf1cSJohnny Huang } 2099de6fbf1cSJohnny Huang otp_soak(0); 21002a856b9aSJohnny Huang return OTP_SUCCESS; 2101d90825e2SJohnny Huang 2102d90825e2SJohnny Huang } 2103d90825e2SJohnny Huang 2104696656c6SJohnny Huang static int otp_image_verify(uint8_t *src_buf, uint32_t length, uint8_t *digest_buf) 2105696656c6SJohnny Huang { 2106696656c6SJohnny Huang sha256_context ctx; 2107696656c6SJohnny Huang u8 digest_ret[CHECKSUM_LEN]; 2108696656c6SJohnny Huang 2109696656c6SJohnny Huang sha256_starts(&ctx); 2110696656c6SJohnny Huang sha256_update(&ctx, src_buf, length); 2111696656c6SJohnny Huang sha256_finish(&ctx, digest_ret); 2112696656c6SJohnny Huang 2113696656c6SJohnny Huang if (!memcmp(digest_buf, digest_ret, CHECKSUM_LEN)) 2114696656c6SJohnny Huang return 0; 2115696656c6SJohnny Huang else 2116696656c6SJohnny Huang return -1; 2117696656c6SJohnny Huang 2118696656c6SJohnny Huang } 2119696656c6SJohnny Huang 2120de6b0cc4SJohnny Huang static int do_otp_prog(int addr, int nconfirm) 212169d5fd8fSJohnny Huang { 212269d5fd8fSJohnny Huang int ret; 21239a4fe690SJohnny Huang int image_version = 0; 2124696656c6SJohnny Huang struct otp_header *otp_header; 2125696656c6SJohnny Huang struct otp_image_layout image_layout; 2126696656c6SJohnny Huang int image_size; 2127696656c6SJohnny Huang uint8_t *buf; 2128696656c6SJohnny Huang uint8_t *checksum; 212969d5fd8fSJohnny Huang 2130696656c6SJohnny Huang otp_header = map_physmem(addr, sizeof(struct otp_header), MAP_WRBACK); 2131696656c6SJohnny Huang if (!otp_header) { 213269d5fd8fSJohnny Huang puts("Failed to map physical memory\n"); 21332a856b9aSJohnny Huang return OTP_FAILURE; 213469d5fd8fSJohnny Huang } 2135d90825e2SJohnny Huang 2136696656c6SJohnny Huang image_size = OTP_IMAGE_SIZE(otp_header->image_info); 2137696656c6SJohnny Huang unmap_physmem(otp_header, MAP_WRBACK); 2138696656c6SJohnny Huang 2139696656c6SJohnny Huang buf = map_physmem(addr, image_size + CHECKSUM_LEN, MAP_WRBACK); 2140696656c6SJohnny Huang 2141696656c6SJohnny Huang if (!buf) { 2142696656c6SJohnny Huang puts("Failed to map physical memory\n"); 2143696656c6SJohnny Huang return OTP_FAILURE; 2144696656c6SJohnny Huang } 2145696656c6SJohnny Huang otp_header = (struct otp_header *) buf; 2146696656c6SJohnny Huang checksum = buf + otp_header->checksum_offset; 2147696656c6SJohnny Huang 2148696656c6SJohnny Huang if (strcmp(OTP_MAGIC, (char *)otp_header->otp_magic) != 0) { 2149696656c6SJohnny Huang puts("Image is invalid\n"); 2150696656c6SJohnny Huang return OTP_FAILURE; 2151696656c6SJohnny Huang } 2152696656c6SJohnny Huang 2153696656c6SJohnny Huang 21545010032bSJohnny Huang image_layout.data_length = (int)(OTP_REGION_SIZE(otp_header->data_info) / 2); 21555010032bSJohnny Huang image_layout.data = buf + OTP_REGION_OFFSET(otp_header->data_info); 21565010032bSJohnny Huang image_layout.data_ignore = image_layout.data + image_layout.data_length; 21575010032bSJohnny Huang 21585010032bSJohnny Huang image_layout.conf_length = (int)(OTP_REGION_SIZE(otp_header->config_info) / 2); 2159696656c6SJohnny Huang image_layout.conf = buf + OTP_REGION_OFFSET(otp_header->config_info); 21605010032bSJohnny Huang image_layout.conf_ignore = image_layout.conf + image_layout.conf_length; 2161696656c6SJohnny Huang 2162696656c6SJohnny Huang image_layout.strap = buf + OTP_REGION_OFFSET(otp_header->strap_info); 2163696656c6SJohnny Huang 2164696656c6SJohnny Huang if (!strcmp("A0", (char *)otp_header->otp_version)) { 2165696656c6SJohnny Huang image_version = OTP_AST2600A0; 21665010032bSJohnny Huang image_layout.strap_length = (int)(OTP_REGION_SIZE(otp_header->strap_info) / 3); 21675010032bSJohnny Huang image_layout.strap_pro = image_layout.strap + image_layout.strap_length; 21685010032bSJohnny Huang image_layout.strap_ignore = image_layout.strap + 2 * image_layout.strap_length; 2169696656c6SJohnny Huang } else if (!strcmp("A1", (char *)otp_header->otp_version)) { 2170696656c6SJohnny Huang image_version = OTP_AST2600A1; 21715010032bSJohnny Huang image_layout.strap_length = (int)(OTP_REGION_SIZE(otp_header->strap_info) / 4); 21725010032bSJohnny Huang image_layout.strap_reg_pro = image_layout.strap + image_layout.strap_length; 21735010032bSJohnny Huang image_layout.strap_pro = image_layout.strap + 2 * image_layout.strap_length; 21745010032bSJohnny Huang image_layout.strap_ignore = image_layout.strap + 3 * image_layout.strap_length; 2175*5fdde29fSJohnny Huang } else if (!strcmp("A2", (char *)otp_header->otp_version)) { 2176*5fdde29fSJohnny Huang image_version = OTP_AST2600A2; 2177*5fdde29fSJohnny Huang image_layout.strap_length = (int)(OTP_REGION_SIZE(otp_header->strap_info) / 4); 2178*5fdde29fSJohnny Huang image_layout.strap_reg_pro = image_layout.strap + image_layout.strap_length; 2179*5fdde29fSJohnny Huang image_layout.strap_pro = image_layout.strap + 2 * image_layout.strap_length; 2180*5fdde29fSJohnny Huang image_layout.strap_ignore = image_layout.strap + 3 * image_layout.strap_length; 2181696656c6SJohnny Huang } else { 2182696656c6SJohnny Huang puts("Version is not supported\n"); 2183696656c6SJohnny Huang return OTP_FAILURE; 2184696656c6SJohnny Huang } 2185696656c6SJohnny Huang 21869a4fe690SJohnny Huang if (image_version != info_cb.version) { 21879a4fe690SJohnny Huang puts("Version is not match\n"); 21889a4fe690SJohnny Huang return OTP_FAILURE; 21899a4fe690SJohnny Huang } 21909a4fe690SJohnny Huang 2191696656c6SJohnny Huang if (otp_image_verify(buf, image_size, checksum)) { 2192696656c6SJohnny Huang puts("checksum is invalid\n"); 2193696656c6SJohnny Huang return OTP_FAILURE; 2194d90825e2SJohnny Huang } 21957332532cSJohnny Huang 219669d5fd8fSJohnny Huang if (!nconfirm) { 2197696656c6SJohnny Huang if (otp_header->image_info & OTP_INC_DATA) { 21987f795e57SJohnny Huang printf("\nOTP data region :\n"); 2199696656c6SJohnny Huang if (otp_print_data_info(&image_layout) < 0) { 220069d5fd8fSJohnny Huang printf("OTP data error, please check.\n"); 22012a856b9aSJohnny Huang return OTP_FAILURE; 220269d5fd8fSJohnny Huang } 220369d5fd8fSJohnny Huang } 2204696656c6SJohnny Huang if (otp_header->image_info & OTP_INC_STRAP) { 22057332532cSJohnny Huang printf("\nOTP strap region :\n"); 22065010032bSJohnny Huang if (otp_print_strap_image(&image_layout) < 0) { 22077332532cSJohnny Huang printf("OTP strap error, please check.\n"); 22087332532cSJohnny Huang return OTP_FAILURE; 22097332532cSJohnny Huang } 22107332532cSJohnny Huang } 2211696656c6SJohnny Huang if (otp_header->image_info & OTP_INC_CONFIG) { 22127332532cSJohnny Huang printf("\nOTP configuration region :\n"); 2213696656c6SJohnny Huang if (otp_print_conf_image(&image_layout) < 0) { 22147332532cSJohnny Huang printf("OTP config error, please check.\n"); 22157332532cSJohnny Huang return OTP_FAILURE; 22167332532cSJohnny Huang } 22177332532cSJohnny Huang } 22187332532cSJohnny Huang 221969d5fd8fSJohnny Huang printf("type \"YES\" (no quotes) to continue:\n"); 222069d5fd8fSJohnny Huang if (!confirm_yesno()) { 222169d5fd8fSJohnny Huang printf(" Aborting\n"); 22222a856b9aSJohnny Huang return OTP_FAILURE; 222369d5fd8fSJohnny Huang } 222469d5fd8fSJohnny Huang } 22257332532cSJohnny Huang 22265010032bSJohnny Huang if (otp_header->image_info & OTP_INC_DATA) { 22275010032bSJohnny Huang printf("programing data region ...\n"); 22285010032bSJohnny Huang ret = otp_prog_data(&image_layout); 22295010032bSJohnny Huang if (ret != 0) { 22305010032bSJohnny Huang printf("Error\n"); 22315010032bSJohnny Huang return ret; 22325010032bSJohnny Huang } else { 22335010032bSJohnny Huang printf("Done\n"); 22345010032bSJohnny Huang } 22355010032bSJohnny Huang } 22365010032bSJohnny Huang if (otp_header->image_info & OTP_INC_STRAP) { 22375010032bSJohnny Huang printf("programing strap region ...\n"); 22385010032bSJohnny Huang ret = otp_prog_strap(&image_layout); 22395010032bSJohnny Huang if (ret != 0) { 22405010032bSJohnny Huang printf("Error\n"); 22415010032bSJohnny Huang return ret; 22425010032bSJohnny Huang } else { 22435010032bSJohnny Huang printf("Done\n"); 22445010032bSJohnny Huang } 22455010032bSJohnny Huang } 22465010032bSJohnny Huang if (otp_header->image_info & OTP_INC_CONFIG) { 22475010032bSJohnny Huang printf("programing configuration region ...\n"); 22485010032bSJohnny Huang ret = otp_prog_conf(&image_layout); 22495010032bSJohnny Huang if (ret != 0) { 22505010032bSJohnny Huang printf("Error\n"); 22515010032bSJohnny Huang return ret; 22525010032bSJohnny Huang } 22535010032bSJohnny Huang printf("Done\n"); 22545010032bSJohnny Huang } 2255cd1610b4SJohnny Huang 22567332532cSJohnny Huang return OTP_SUCCESS; 22572a856b9aSJohnny Huang } 22582a856b9aSJohnny Huang 22592a856b9aSJohnny Huang static int do_otp_prog_bit(int mode, int otp_dw_offset, int bit_offset, int value, int nconfirm) 2260cd1610b4SJohnny Huang { 2261a6af4a17SJohnny Huang uint32_t read[2]; 2262d90825e2SJohnny Huang uint32_t prog_address = 0; 226366f2f8e5SJohnny Huang struct otpstrap_status otpstrap[64]; 2264cd1610b4SJohnny Huang int otp_bit; 226583655e91SJohnny Huang int ret = 0; 2266cd1610b4SJohnny Huang 2267cd1610b4SJohnny Huang switch (mode) { 2268a6d0d645SJohnny Huang case OTP_REGION_CONF: 2269a6af4a17SJohnny Huang otp_read_config(otp_dw_offset, read); 2270cd1610b4SJohnny Huang prog_address = 0x800; 2271cd1610b4SJohnny Huang prog_address |= (otp_dw_offset / 8) * 0x200; 2272cd1610b4SJohnny Huang prog_address |= (otp_dw_offset % 8) * 0x2; 2273a6af4a17SJohnny Huang otp_bit = (read[0] >> bit_offset) & 0x1; 2274cd1610b4SJohnny Huang if (otp_bit == value) { 2275a6af4a17SJohnny Huang printf("OTPCFG%X[%X] = %d\n", otp_dw_offset, bit_offset, value); 2276cd1610b4SJohnny Huang printf("No need to program\n"); 22772a856b9aSJohnny Huang return OTP_SUCCESS; 2278cd1610b4SJohnny Huang } 2279cd1610b4SJohnny Huang if (otp_bit == 1 && value == 0) { 2280a6af4a17SJohnny Huang printf("OTPCFG%X[%X] = 1\n", otp_dw_offset, bit_offset); 2281cd1610b4SJohnny Huang printf("OTP is programed, which can't be clean\n"); 22822a856b9aSJohnny Huang return OTP_FAILURE; 2283cd1610b4SJohnny Huang } 2284a6af4a17SJohnny Huang printf("Program OTPCFG%X[%X] to 1\n", otp_dw_offset, bit_offset); 2285cd1610b4SJohnny Huang break; 2286a6d0d645SJohnny Huang case OTP_REGION_DATA: 2287cd1610b4SJohnny Huang prog_address = otp_dw_offset; 2288cd1610b4SJohnny Huang 2289cd1610b4SJohnny Huang if (otp_dw_offset % 2 == 0) { 2290a6af4a17SJohnny Huang otp_read_data(otp_dw_offset, read); 2291a6af4a17SJohnny Huang otp_bit = (read[0] >> bit_offset) & 0x1; 2292643b9cfdSJohnny Huang 2293643b9cfdSJohnny Huang if (otp_bit == 1 && value == 0) { 2294643b9cfdSJohnny Huang printf("OTPDATA%X[%X] = 1\n", otp_dw_offset, bit_offset); 2295643b9cfdSJohnny Huang printf("OTP is programed, which can't be cleaned\n"); 2296643b9cfdSJohnny Huang return OTP_FAILURE; 2297643b9cfdSJohnny Huang } 2298cd1610b4SJohnny Huang } else { 2299a6af4a17SJohnny Huang otp_read_data(otp_dw_offset - 1, read); 2300a6af4a17SJohnny Huang otp_bit = (read[1] >> bit_offset) & 0x1; 2301643b9cfdSJohnny Huang 2302643b9cfdSJohnny Huang if (otp_bit == 0 && value == 1) { 2303643b9cfdSJohnny Huang printf("OTPDATA%X[%X] = 1\n", otp_dw_offset, bit_offset); 2304643b9cfdSJohnny Huang printf("OTP is programed, which can't be writen\n"); 2305643b9cfdSJohnny Huang return OTP_FAILURE; 2306643b9cfdSJohnny Huang } 2307cd1610b4SJohnny Huang } 2308cd1610b4SJohnny Huang if (otp_bit == value) { 2309a6af4a17SJohnny Huang printf("OTPDATA%X[%X] = %d\n", otp_dw_offset, bit_offset, value); 2310cd1610b4SJohnny Huang printf("No need to program\n"); 23112a856b9aSJohnny Huang return OTP_SUCCESS; 2312cd1610b4SJohnny Huang } 2313643b9cfdSJohnny Huang 2314a6af4a17SJohnny Huang printf("Program OTPDATA%X[%X] to 1\n", otp_dw_offset, bit_offset); 2315cd1610b4SJohnny Huang break; 2316a6d0d645SJohnny Huang case OTP_REGION_STRAP: 23178848d5dcSJohnny Huang otp_strap_status(otpstrap); 23188848d5dcSJohnny Huang otp_print_strap(bit_offset, 1); 23198848d5dcSJohnny Huang ret = otp_strap_bit_confirm(&otpstrap[bit_offset], bit_offset, 0, value, 0, 0); 23208848d5dcSJohnny Huang if (ret == OTP_FAILURE) 23218848d5dcSJohnny Huang return OTP_FAILURE; 23228848d5dcSJohnny Huang else if (ret == OTP_PROG_SKIP) 23238848d5dcSJohnny Huang return OTP_SUCCESS; 2324a6af4a17SJohnny Huang 2325cd1610b4SJohnny Huang break; 2326cd1610b4SJohnny Huang } 2327cd1610b4SJohnny Huang 2328cd1610b4SJohnny Huang if (!nconfirm) { 2329cd1610b4SJohnny Huang printf("type \"YES\" (no quotes) to continue:\n"); 2330cd1610b4SJohnny Huang if (!confirm_yesno()) { 2331cd1610b4SJohnny Huang printf(" Aborting\n"); 23322a856b9aSJohnny Huang return OTP_FAILURE; 2333cd1610b4SJohnny Huang } 2334cd1610b4SJohnny Huang } 2335cd1610b4SJohnny Huang 2336cd1610b4SJohnny Huang switch (mode) { 2337a6d0d645SJohnny Huang case OTP_REGION_STRAP: 233883655e91SJohnny Huang ret = otp_prog_strap_bit(bit_offset, value); 233983655e91SJohnny Huang break; 2340a6d0d645SJohnny Huang case OTP_REGION_CONF: 2341a6d0d645SJohnny Huang case OTP_REGION_DATA: 234283655e91SJohnny Huang ret = otp_prog_bit(value, prog_address, bit_offset); 2343de6fbf1cSJohnny Huang break; 2344de6fbf1cSJohnny Huang } 2345de6fbf1cSJohnny Huang otp_soak(0); 234683655e91SJohnny Huang if (ret) { 23479009c25dSJohnny Huang printf("SUCCESS\n"); 23482a856b9aSJohnny Huang return OTP_SUCCESS; 23499009c25dSJohnny Huang } else { 23509009c25dSJohnny Huang printf("OTP cannot be programed\n"); 23519009c25dSJohnny Huang printf("FAILED\n"); 23529009c25dSJohnny Huang return OTP_FAILURE; 23539009c25dSJohnny Huang } 2354cd1610b4SJohnny Huang 23552a856b9aSJohnny Huang return OTP_USAGE; 2356cd1610b4SJohnny Huang } 2357cd1610b4SJohnny Huang 23582a856b9aSJohnny Huang static int do_otpread(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) 235969d5fd8fSJohnny Huang { 23602a856b9aSJohnny Huang uint32_t offset, count; 23612a856b9aSJohnny Huang int ret; 236269d5fd8fSJohnny Huang 23632a856b9aSJohnny Huang if (argc == 4) { 23642a856b9aSJohnny Huang offset = simple_strtoul(argv[2], NULL, 16); 23652a856b9aSJohnny Huang count = simple_strtoul(argv[3], NULL, 16); 23662a856b9aSJohnny Huang } else if (argc == 3) { 23672a856b9aSJohnny Huang offset = simple_strtoul(argv[2], NULL, 16); 23682a856b9aSJohnny Huang count = 1; 23692a856b9aSJohnny Huang } else { 237069d5fd8fSJohnny Huang return CMD_RET_USAGE; 237169d5fd8fSJohnny Huang } 237269d5fd8fSJohnny Huang 237369d5fd8fSJohnny Huang 23742a856b9aSJohnny Huang if (!strcmp(argv[1], "conf")) { 23753d3688adSJohnny Huang writel(OTP_PASSWD, OTP_PROTECT_KEY); //password 23762a856b9aSJohnny Huang ret = otp_print_config(offset, count); 23772a856b9aSJohnny Huang } else if (!strcmp(argv[1], "data")) { 23783d3688adSJohnny Huang writel(OTP_PASSWD, OTP_PROTECT_KEY); //password 23792a856b9aSJohnny Huang ret = otp_print_data(offset, count); 23802a856b9aSJohnny Huang } else if (!strcmp(argv[1], "strap")) { 23813d3688adSJohnny Huang writel(OTP_PASSWD, OTP_PROTECT_KEY); //password 23822a856b9aSJohnny Huang ret = otp_print_strap(offset, count); 23832a856b9aSJohnny Huang } else { 23842a856b9aSJohnny Huang return CMD_RET_USAGE; 238569d5fd8fSJohnny Huang } 238669d5fd8fSJohnny Huang 23872a856b9aSJohnny Huang if (ret == OTP_SUCCESS) 23882a856b9aSJohnny Huang return CMD_RET_SUCCESS; 23892a856b9aSJohnny Huang else 23902a856b9aSJohnny Huang return CMD_RET_USAGE; 23912a856b9aSJohnny Huang 23922a856b9aSJohnny Huang } 23932a856b9aSJohnny Huang 23942a856b9aSJohnny Huang static int do_otpprog(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) 23952a856b9aSJohnny Huang { 23962a856b9aSJohnny Huang phys_addr_t addr; 23972a856b9aSJohnny Huang int ret; 23982a856b9aSJohnny Huang 2399de6b0cc4SJohnny Huang if (argc == 3) { 2400ed071a2bSJohnny Huang if (strcmp(argv[1], "o")) 24012a856b9aSJohnny Huang return CMD_RET_USAGE; 24022a856b9aSJohnny Huang addr = simple_strtoul(argv[2], NULL, 16); 24033d3688adSJohnny Huang writel(OTP_PASSWD, OTP_PROTECT_KEY); //password 2404de6b0cc4SJohnny Huang ret = do_otp_prog(addr, 1); 2405de6b0cc4SJohnny Huang } else if (argc == 2) { 24062a856b9aSJohnny Huang addr = simple_strtoul(argv[1], NULL, 16); 24073d3688adSJohnny Huang writel(OTP_PASSWD, OTP_PROTECT_KEY); //password 2408de6b0cc4SJohnny Huang ret = do_otp_prog(addr, 0); 24092a856b9aSJohnny Huang } else { 24102a856b9aSJohnny Huang return CMD_RET_USAGE; 24112a856b9aSJohnny Huang } 24122a856b9aSJohnny Huang 24132a856b9aSJohnny Huang if (ret == OTP_SUCCESS) 24142a856b9aSJohnny Huang return CMD_RET_SUCCESS; 24152a856b9aSJohnny Huang else if (ret == OTP_FAILURE) 24162a856b9aSJohnny Huang return CMD_RET_FAILURE; 24172a856b9aSJohnny Huang else 24182a856b9aSJohnny Huang return CMD_RET_USAGE; 24192a856b9aSJohnny Huang } 24202a856b9aSJohnny Huang 24212a856b9aSJohnny Huang static int do_otppb(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) 24222a856b9aSJohnny Huang { 24232a856b9aSJohnny Huang int mode = 0; 24242a856b9aSJohnny Huang int nconfirm = 0; 24252a856b9aSJohnny Huang int otp_addr = 0; 24262a856b9aSJohnny Huang int bit_offset; 24272a856b9aSJohnny Huang int value; 24282a856b9aSJohnny Huang int ret; 24292a856b9aSJohnny Huang 24302a856b9aSJohnny Huang if (argc != 4 && argc != 5 && argc != 6) 24312a856b9aSJohnny Huang return CMD_RET_USAGE; 24322a856b9aSJohnny Huang 24332a856b9aSJohnny Huang /* Drop the pb cmd */ 24342a856b9aSJohnny Huang argc--; 24352a856b9aSJohnny Huang argv++; 24362a856b9aSJohnny Huang 24372a856b9aSJohnny Huang if (!strcmp(argv[0], "conf")) 2438a6d0d645SJohnny Huang mode = OTP_REGION_CONF; 24392a856b9aSJohnny Huang else if (!strcmp(argv[0], "strap")) 2440a6d0d645SJohnny Huang mode = OTP_REGION_STRAP; 24412a856b9aSJohnny Huang else if (!strcmp(argv[0], "data")) 2442a6d0d645SJohnny Huang mode = OTP_REGION_DATA; 2443cd1610b4SJohnny Huang else 24442a856b9aSJohnny Huang return CMD_RET_USAGE; 24452a856b9aSJohnny Huang 24462a856b9aSJohnny Huang /* Drop the region cmd */ 24472a856b9aSJohnny Huang argc--; 24482a856b9aSJohnny Huang argv++; 24492a856b9aSJohnny Huang 2450ed071a2bSJohnny Huang if (!strcmp(argv[0], "o")) { 2451cd1610b4SJohnny Huang nconfirm = 1; 24522a856b9aSJohnny Huang /* Drop the force option */ 24532a856b9aSJohnny Huang argc--; 24542a856b9aSJohnny Huang argv++; 24552a856b9aSJohnny Huang } 2456cd1610b4SJohnny Huang 2457a6d0d645SJohnny Huang if (mode == OTP_REGION_STRAP) { 24582a856b9aSJohnny Huang bit_offset = simple_strtoul(argv[0], NULL, 16); 24592a856b9aSJohnny Huang value = simple_strtoul(argv[1], NULL, 16); 24600808cc55SJohnny Huang if (bit_offset >= 64 || (value != 0 && value != 1)) 24612a856b9aSJohnny Huang return CMD_RET_USAGE; 2462cd1610b4SJohnny Huang } else { 24632a856b9aSJohnny Huang otp_addr = simple_strtoul(argv[0], NULL, 16); 24642a856b9aSJohnny Huang bit_offset = simple_strtoul(argv[1], NULL, 16); 24652a856b9aSJohnny Huang value = simple_strtoul(argv[2], NULL, 16); 24660808cc55SJohnny Huang if (bit_offset >= 32 || (value != 0 && value != 1)) 24672a856b9aSJohnny Huang return CMD_RET_USAGE; 24680808cc55SJohnny Huang if (mode == OTP_REGION_DATA) { 246978855207SJohnny Huang if (otp_addr >= 0x800) 24700808cc55SJohnny Huang return CMD_RET_USAGE; 24710808cc55SJohnny Huang } else { 247278855207SJohnny Huang if (otp_addr >= 0x20) 24730808cc55SJohnny Huang return CMD_RET_USAGE; 24740808cc55SJohnny Huang } 2475cd1610b4SJohnny Huang } 2476cd1610b4SJohnny Huang if (value != 0 && value != 1) 24772a856b9aSJohnny Huang return CMD_RET_USAGE; 2478cd1610b4SJohnny Huang 24793d3688adSJohnny Huang writel(OTP_PASSWD, OTP_PROTECT_KEY); //password 24802a856b9aSJohnny Huang ret = do_otp_prog_bit(mode, otp_addr, bit_offset, value, nconfirm); 24812a856b9aSJohnny Huang 24822a856b9aSJohnny Huang if (ret == OTP_SUCCESS) 24832a856b9aSJohnny Huang return CMD_RET_SUCCESS; 24842a856b9aSJohnny Huang else if (ret == OTP_FAILURE) 24852a856b9aSJohnny Huang return CMD_RET_FAILURE; 24862a856b9aSJohnny Huang else 24872a856b9aSJohnny Huang return CMD_RET_USAGE; 24882a856b9aSJohnny Huang } 24892a856b9aSJohnny Huang 24902a856b9aSJohnny Huang static int do_otpcmp(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) 24912a856b9aSJohnny Huang { 24922a856b9aSJohnny Huang phys_addr_t addr; 24932a856b9aSJohnny Huang int otp_addr = 0; 24942a856b9aSJohnny Huang 24952a856b9aSJohnny Huang if (argc != 3) 24962a856b9aSJohnny Huang return CMD_RET_USAGE; 24972a856b9aSJohnny Huang 24983d3688adSJohnny Huang writel(OTP_PASSWD, OTP_PROTECT_KEY); //password 24992a856b9aSJohnny Huang addr = simple_strtoul(argv[1], NULL, 16); 25002a856b9aSJohnny Huang otp_addr = simple_strtoul(argv[2], NULL, 16); 25012a856b9aSJohnny Huang if (otp_compare(otp_addr, addr) == 0) { 250269d5fd8fSJohnny Huang printf("Compare pass\n"); 25032a856b9aSJohnny Huang return CMD_RET_SUCCESS; 250469d5fd8fSJohnny Huang } else { 250569d5fd8fSJohnny Huang printf("Compare fail\n"); 25062a856b9aSJohnny Huang return CMD_RET_FAILURE; 250769d5fd8fSJohnny Huang } 250869d5fd8fSJohnny Huang } 250969d5fd8fSJohnny Huang 251066f2f8e5SJohnny Huang static int do_otpinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) 251166f2f8e5SJohnny Huang { 2512a8bd6d8cSJohnny Huang int view = 0; 25132d4b0742SJohnny Huang int input; 2514a8bd6d8cSJohnny Huang 2515a8bd6d8cSJohnny Huang if (argc != 2 && argc != 3) 251666f2f8e5SJohnny Huang return CMD_RET_USAGE; 251766f2f8e5SJohnny Huang 25182d4b0742SJohnny Huang if (!strcmp(argv[1], "conf")) { 251966f2f8e5SJohnny Huang 25203d3688adSJohnny Huang writel(OTP_PASSWD, OTP_PROTECT_KEY); //password 25212d4b0742SJohnny Huang if (argc == 3) { 25222d4b0742SJohnny Huang input = simple_strtoul(argv[2], NULL, 16); 25232d4b0742SJohnny Huang otp_print_conf_info(input); 25242d4b0742SJohnny Huang } else { 25252d4b0742SJohnny Huang otp_print_conf_info(-1); 25262d4b0742SJohnny Huang } 25272d4b0742SJohnny Huang } else if (!strcmp(argv[1], "strap")) { 25282d4b0742SJohnny Huang if (!strcmp(argv[2], "v")) { 2529a8bd6d8cSJohnny Huang view = 1; 2530a8bd6d8cSJohnny Huang /* Drop the view option */ 2531a8bd6d8cSJohnny Huang argc--; 2532a8bd6d8cSJohnny Huang argv++; 2533a8bd6d8cSJohnny Huang } 25343d3688adSJohnny Huang writel(OTP_PASSWD, OTP_PROTECT_KEY); //password 2535b458cd62SJohnny Huang otp_print_strap_info(view); 253666f2f8e5SJohnny Huang } else { 253766f2f8e5SJohnny Huang return CMD_RET_USAGE; 253866f2f8e5SJohnny Huang } 25392d4b0742SJohnny Huang 254066f2f8e5SJohnny Huang return CMD_RET_SUCCESS; 254166f2f8e5SJohnny Huang } 254266f2f8e5SJohnny Huang 2543737ed20bSJohnny Huang static int do_otpprotect(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) 2544737ed20bSJohnny Huang { 2545737ed20bSJohnny Huang int input; 2546737ed20bSJohnny Huang int bit_offset; 2547737ed20bSJohnny Huang int prog_address; 254883655e91SJohnny Huang int ret; 2549737ed20bSJohnny Huang if (argc != 3 && argc != 2) 2550737ed20bSJohnny Huang return CMD_RET_USAGE; 2551737ed20bSJohnny Huang 2552ed071a2bSJohnny Huang if (!strcmp(argv[0], "o")) { 2553737ed20bSJohnny Huang input = simple_strtoul(argv[2], NULL, 16); 2554737ed20bSJohnny Huang } else { 2555737ed20bSJohnny Huang input = simple_strtoul(argv[1], NULL, 16); 2556737ed20bSJohnny Huang printf("OTPSTRAP[%d] will be protected\n", input); 2557737ed20bSJohnny Huang printf("type \"YES\" (no quotes) to continue:\n"); 2558737ed20bSJohnny Huang if (!confirm_yesno()) { 2559737ed20bSJohnny Huang printf(" Aborting\n"); 2560737ed20bSJohnny Huang return CMD_RET_FAILURE; 2561737ed20bSJohnny Huang } 2562737ed20bSJohnny Huang } 2563737ed20bSJohnny Huang 2564737ed20bSJohnny Huang prog_address = 0x800; 2565737ed20bSJohnny Huang if (input < 32) { 2566737ed20bSJohnny Huang bit_offset = input; 2567737ed20bSJohnny Huang prog_address |= 0x60c; 2568737ed20bSJohnny Huang } else if (input < 64) { 2569737ed20bSJohnny Huang bit_offset = input - 32; 2570737ed20bSJohnny Huang prog_address |= 0x60e; 2571737ed20bSJohnny Huang } else { 2572737ed20bSJohnny Huang return CMD_RET_USAGE; 2573737ed20bSJohnny Huang } 2574737ed20bSJohnny Huang 2575737ed20bSJohnny Huang if (verify_bit(prog_address, bit_offset, 1) == 0) { 2576737ed20bSJohnny Huang printf("OTPSTRAP[%d] already protected\n", input); 2577737ed20bSJohnny Huang } 2578de6fbf1cSJohnny Huang 257983655e91SJohnny Huang ret = otp_prog_bit(1, prog_address, bit_offset); 2580de6fbf1cSJohnny Huang otp_soak(0); 258183655e91SJohnny Huang 258283655e91SJohnny Huang if (ret) { 2583737ed20bSJohnny Huang printf("OTPSTRAP[%d] is protected\n", input); 2584737ed20bSJohnny Huang return CMD_RET_SUCCESS; 2585737ed20bSJohnny Huang } 2586737ed20bSJohnny Huang 2587737ed20bSJohnny Huang printf("Protect OTPSTRAP[%d] fail\n", input); 2588737ed20bSJohnny Huang return CMD_RET_FAILURE; 2589737ed20bSJohnny Huang 2590737ed20bSJohnny Huang } 25919a4fe690SJohnny Huang 25922a856b9aSJohnny Huang static cmd_tbl_t cmd_otp[] = { 25932a856b9aSJohnny Huang U_BOOT_CMD_MKENT(read, 4, 0, do_otpread, "", ""), 2594a8bd6d8cSJohnny Huang U_BOOT_CMD_MKENT(info, 3, 0, do_otpinfo, "", ""), 2595de6b0cc4SJohnny Huang U_BOOT_CMD_MKENT(prog, 3, 0, do_otpprog, "", ""), 25962a856b9aSJohnny Huang U_BOOT_CMD_MKENT(pb, 6, 0, do_otppb, "", ""), 2597737ed20bSJohnny Huang U_BOOT_CMD_MKENT(protect, 3, 0, do_otpprotect, "", ""), 25982a856b9aSJohnny Huang U_BOOT_CMD_MKENT(cmp, 3, 0, do_otpcmp, "", ""), 25992a856b9aSJohnny Huang }; 26002a856b9aSJohnny Huang 26012a856b9aSJohnny Huang static int do_ast_otp(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) 26022a856b9aSJohnny Huang { 26032a856b9aSJohnny Huang cmd_tbl_t *cp; 26042a856b9aSJohnny Huang 26052a856b9aSJohnny Huang cp = find_cmd_tbl(argv[1], cmd_otp, ARRAY_SIZE(cmd_otp)); 26062a856b9aSJohnny Huang 2607737ed20bSJohnny Huang /* Drop the otp command */ 26082a856b9aSJohnny Huang argc--; 26092a856b9aSJohnny Huang argv++; 26102a856b9aSJohnny Huang 26112a856b9aSJohnny Huang if (cp == NULL || argc > cp->maxargs) 26122a856b9aSJohnny Huang return CMD_RET_USAGE; 26132a856b9aSJohnny Huang if (flag == CMD_FLAG_REPEAT && !cmd_is_repeatable(cp)) 26142a856b9aSJohnny Huang return CMD_RET_SUCCESS; 26152a856b9aSJohnny Huang 2616696656c6SJohnny Huang if (chip_version() == OTP_AST2600A0) { 2617696656c6SJohnny Huang info_cb.version = OTP_AST2600A0; 26189a4fe690SJohnny Huang info_cb.conf_info = a0_conf_info; 26199a4fe690SJohnny Huang info_cb.conf_info_len = ARRAY_SIZE(a0_conf_info); 26209a4fe690SJohnny Huang info_cb.strap_info = a0_strap_info; 26219a4fe690SJohnny Huang info_cb.strap_info_len = ARRAY_SIZE(a0_strap_info); 26229a4fe690SJohnny Huang info_cb.key_info = a0_key_type; 26239a4fe690SJohnny Huang info_cb.key_info_len = ARRAY_SIZE(a0_key_type); 2624696656c6SJohnny Huang } else if (chip_version() == OTP_AST2600A1) { 2625696656c6SJohnny Huang info_cb.version = OTP_AST2600A1; 26263cb28812SJohnny Huang info_cb.conf_info = a1_conf_info; 26273cb28812SJohnny Huang info_cb.conf_info_len = ARRAY_SIZE(a1_conf_info); 26283cb28812SJohnny Huang info_cb.strap_info = a1_strap_info; 26293cb28812SJohnny Huang info_cb.strap_info_len = ARRAY_SIZE(a1_strap_info); 26309a4fe690SJohnny Huang info_cb.key_info = a1_key_type; 26319a4fe690SJohnny Huang info_cb.key_info_len = ARRAY_SIZE(a1_key_type); 2632*5fdde29fSJohnny Huang } else if (chip_version() == OTP_AST2600A2) { 2633*5fdde29fSJohnny Huang info_cb.version = OTP_AST2600A2; 2634*5fdde29fSJohnny Huang info_cb.conf_info = a2_conf_info; 2635*5fdde29fSJohnny Huang info_cb.conf_info_len = ARRAY_SIZE(a2_conf_info); 2636*5fdde29fSJohnny Huang info_cb.strap_info = a2_strap_info; 2637*5fdde29fSJohnny Huang info_cb.strap_info_len = ARRAY_SIZE(a2_strap_info); 2638*5fdde29fSJohnny Huang info_cb.key_info = a2_key_type; 2639*5fdde29fSJohnny Huang info_cb.key_info_len = ARRAY_SIZE(a2_key_type); 26409a4fe690SJohnny Huang } 26419a4fe690SJohnny Huang 26422a856b9aSJohnny Huang return cp->cmd(cmdtp, flag, argc, argv); 264369d5fd8fSJohnny Huang } 264469d5fd8fSJohnny Huang 264569d5fd8fSJohnny Huang U_BOOT_CMD( 264669d5fd8fSJohnny Huang otp, 7, 0, do_ast_otp, 264769d5fd8fSJohnny Huang "ASPEED One-Time-Programmable sub-system", 26482a856b9aSJohnny Huang "read conf|data <otp_dw_offset> <dw_count>\n" 26492a856b9aSJohnny Huang "otp read strap <strap_bit_offset> <bit_count>\n" 26502d4b0742SJohnny Huang "otp info strap [v]\n" 26512d4b0742SJohnny Huang "otp info conf [otp_dw_offset]\n" 2652de6b0cc4SJohnny Huang "otp prog [o] <addr>\n" 2653ed071a2bSJohnny Huang "otp pb conf|data [o] <otp_dw_offset> <bit_offset> <value>\n" 2654ed071a2bSJohnny Huang "otp pb strap [o] <bit_offset> <value>\n" 2655ed071a2bSJohnny Huang "otp protect [o] <bit_offset>\n" 26562a856b9aSJohnny Huang "otp cmp <addr> <otp_dw_offset>\n" 265769d5fd8fSJohnny Huang ); 2658