1 /* 2 * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 #include "sdkconfig.h" 8 #include <sys/param.h> 9 #include "soc/soc_caps.h" 10 #include "hal/efuse_ll.h" 11 #include "hal/assert.h" 12 #include "hal/efuse_hal.h" 13 #include "soc/syscon_reg.h" 14 #include "esp_attr.h" 15 efuse_hal_get_major_chip_version(void)16IRAM_ATTR uint32_t efuse_hal_get_major_chip_version(void) 17 { 18 uint8_t eco_bit0 = efuse_ll_get_chip_ver_rev1(); 19 uint8_t eco_bit1 = efuse_ll_get_chip_ver_rev2(); 20 uint8_t eco_bit2 = (REG_READ(SYSCON_DATE_REG) & 0x80000000) >> 31; 21 uint32_t combine_value = (eco_bit2 << 2) | (eco_bit1 << 1) | eco_bit0; 22 uint32_t chip_ver = 0; 23 switch (combine_value) { 24 case 0: 25 chip_ver = 0; 26 break; 27 case 1: 28 chip_ver = 1; 29 break; 30 case 3: 31 chip_ver = 2; 32 break; 33 #if CONFIG_IDF_ENV_FPGA 34 case 4: /* Empty efuses, but SYSCON_DATE_REG bit is set */ 35 chip_ver = 3; 36 break; 37 #endif // CONFIG_IDF_ENV_FPGA 38 case 7: 39 chip_ver = 3; 40 break; 41 default: 42 chip_ver = 0; 43 break; 44 } 45 return chip_ver; 46 } 47 efuse_hal_get_minor_chip_version(void)48IRAM_ATTR uint32_t efuse_hal_get_minor_chip_version(void) 49 { 50 return efuse_ll_get_chip_wafer_version_minor(); 51 } 52 efuse_hal_get_rated_freq_mhz(void)53uint32_t efuse_hal_get_rated_freq_mhz(void) 54 { 55 //Check if ESP32 is rated for a CPU frequency of 160MHz only 56 if (efuse_ll_get_chip_cpu_freq_rated() && efuse_ll_get_chip_cpu_freq_low()) { 57 return 160; 58 } 59 return 240; 60 } 61 62 /******************* eFuse control functions *************************/ 63 efuse_hal_set_timing(uint32_t apb_freq_mhz)64void efuse_hal_set_timing(uint32_t apb_freq_mhz) 65 { 66 uint32_t clk_sel0; 67 uint32_t clk_sel1; 68 uint32_t dac_clk_div; 69 if (apb_freq_mhz <= 26) { 70 clk_sel0 = 250; 71 clk_sel1 = 255; 72 dac_clk_div = 52; 73 } else if (apb_freq_mhz <= 40) { 74 clk_sel0 = 160; 75 clk_sel1 = 255; 76 dac_clk_div = 80; 77 } else { 78 clk_sel0 = 80; 79 clk_sel1 = 128; 80 dac_clk_div = 100; 81 } 82 efuse_ll_set_dac_clk_div(dac_clk_div); 83 efuse_ll_set_dac_clk_sel0(clk_sel0); 84 efuse_ll_set_dac_clk_sel1(clk_sel1); 85 } 86 efuse_hal_read(void)87void efuse_hal_read(void) 88 { 89 efuse_ll_set_conf_read_op_code(); 90 efuse_ll_set_read_cmd(); 91 while (efuse_ll_get_cmd() != 0) { }; 92 } 93 efuse_hal_clear_program_registers(void)94void efuse_hal_clear_program_registers(void) 95 { 96 for (uint32_t r = EFUSE_BLK0_WDATA0_REG; r <= EFUSE_BLK0_WDATA6_REG; r += 4) { 97 REG_WRITE(r, 0); 98 } 99 for (uint32_t r = EFUSE_BLK1_WDATA0_REG; r <= EFUSE_BLK1_WDATA7_REG; r += 4) { 100 REG_WRITE(r, 0); 101 } 102 for (uint32_t r = EFUSE_BLK2_WDATA0_REG; r <= EFUSE_BLK2_WDATA7_REG; r += 4) { 103 REG_WRITE(r, 0); 104 } 105 for (uint32_t r = EFUSE_BLK3_WDATA0_REG; r <= EFUSE_BLK3_WDATA7_REG; r += 4) { 106 REG_WRITE(r, 0); 107 } 108 } 109 efuse_hal_program(uint32_t block)110void efuse_hal_program(uint32_t block) 111 { 112 (void) block; 113 // Permanently update values written to the efuse write registers 114 efuse_ll_set_conf_write_op_code(); 115 efuse_ll_set_pgm_cmd(); 116 while (efuse_ll_get_cmd() != 0) { }; 117 118 efuse_hal_read(); 119 } 120 121 /******************* eFuse control functions *************************/ 122 efuse_hal_is_coding_error_in_block(unsigned block)123bool efuse_hal_is_coding_error_in_block(unsigned block) 124 { 125 return block > 0 && 126 efuse_ll_get_coding_scheme() == 1 && // 3/4 coding scheme 127 efuse_ll_get_dec_warnings(block); 128 } 129