11 #include "sw/device/lib/base/multibits.h"
14 #include "flash_ctrl_regs.h"
27 static ptrdiff_t get_data_region_mp_reg_offset(uint32_t region) {
28 return FLASH_CTRL_MP_REGION_CFG_0_REG_OFFSET +
29 (ptrdiff_t)region * (ptrdiff_t)
sizeof(uint32_t);
33 static ptrdiff_t get_data_region_reg_offset(uint32_t region) {
34 return FLASH_CTRL_MP_REGION_0_REG_OFFSET +
35 (ptrdiff_t)region * (ptrdiff_t)
sizeof(uint32_t);
39 static ptrdiff_t get_data_region_lock_reg_offset(uint32_t region) {
40 return FLASH_CTRL_REGION_CFG_REGWEN_0_REG_OFFSET +
41 (ptrdiff_t)region * (ptrdiff_t)
sizeof(uint32_t);
47 static_assert(FLASH_CTRL_PARAM_REG_NUM_BANKS == 2,
48 "Please update the info region register tables.");
52 #ifndef FLASH_CTRL_NUM_INFO_TYPES
53 #define FLASH_CTRL_NUM_INFO_TYPES 3
58 static const ptrdiff_t
59 kInfoConfigOffsets[FLASH_CTRL_NUM_INFO_TYPES]
60 [FLASH_CTRL_PARAM_REG_NUM_BANKS] = {
62 FLASH_CTRL_BANK0_INFO0_PAGE_CFG_0_REG_OFFSET,
63 FLASH_CTRL_BANK1_INFO0_PAGE_CFG_0_REG_OFFSET,
66 FLASH_CTRL_BANK0_INFO1_PAGE_CFG_REG_OFFSET,
67 FLASH_CTRL_BANK1_INFO1_PAGE_CFG_REG_OFFSET,
70 FLASH_CTRL_BANK0_INFO2_PAGE_CFG_0_REG_OFFSET,
71 FLASH_CTRL_BANK1_INFO2_PAGE_CFG_0_REG_OFFSET,
75 static const ptrdiff_t
76 kInfoLockOffsets[FLASH_CTRL_NUM_INFO_TYPES]
77 [FLASH_CTRL_PARAM_REG_NUM_BANKS] = {
79 FLASH_CTRL_BANK0_INFO0_REGWEN_0_REG_OFFSET,
80 FLASH_CTRL_BANK1_INFO0_REGWEN_0_REG_OFFSET,
83 FLASH_CTRL_BANK0_INFO1_REGWEN_REG_OFFSET,
84 FLASH_CTRL_BANK1_INFO1_REGWEN_REG_OFFSET,
87 FLASH_CTRL_BANK0_INFO2_REGWEN_0_REG_OFFSET,
88 FLASH_CTRL_BANK1_INFO2_REGWEN_0_REG_OFFSET,
92 static const uint32_t kNumInfoPagesPerBank[FLASH_CTRL_NUM_INFO_TYPES] = {
93 FLASH_CTRL_PARAM_NUM_INFOS0,
94 FLASH_CTRL_PARAM_NUM_INFOS1,
95 FLASH_CTRL_PARAM_NUM_INFOS2,
107 static ptrdiff_t get_info_region_mp_reg_offset(
110 (ptrdiff_t)region.
page * (ptrdiff_t)
sizeof(uint32_t);
114 static ptrdiff_t get_info_region_lock_reg_offset(
117 (ptrdiff_t)region.
page * (ptrdiff_t)
sizeof(uint32_t);
123 if (handle == NULL) {
138 .
num_banks = FLASH_CTRL_PARAM_REG_NUM_BANKS,
139 .bytes_per_word = FLASH_CTRL_PARAM_BYTES_PER_WORD,
140 .bytes_per_page = FLASH_CTRL_PARAM_BYTES_PER_PAGE,
141 .data_pages = FLASH_CTRL_PARAM_REG_PAGES_PER_BANK,
142 .info0_pages = FLASH_CTRL_PARAM_NUM_INFOS0,
143 .info1_pages = FLASH_CTRL_PARAM_NUM_INFOS1,
144 .info2_pages = FLASH_CTRL_PARAM_NUM_INFOS2,
152 enum multi_bit_bool disable_flash;
153 if (handle == NULL) {
161 disable_flash = kMultiBitBool4False;
164 disable_flash = kMultiBitBool4True;
169 mmio_region_write32(handle->
dev.
base_addr, FLASH_CTRL_DIS_REG_OFFSET,
177 if (handle == NULL || enabled_out == NULL) {
181 mmio_region_read32(handle->
dev.
base_addr, FLASH_CTRL_DIS_REG_OFFSET);
182 enum multi_bit_bool flash_disabled =
187 if (flash_disabled == kMultiBitBool4False) {
199 if (handle == NULL) {
204 value = FLASH_CTRL_PARAM_EXEC_EN;
212 mmio_region_write32(handle->
dev.
base_addr, FLASH_CTRL_EXEC_REG_OFFSET, value);
219 if (handle == NULL || enabled_out == NULL) {
223 mmio_region_read32(handle->
dev.
base_addr, FLASH_CTRL_EXEC_REG_OFFSET);
224 if (reg == FLASH_CTRL_PARAM_EXEC_EN) {
235 if (handle == NULL) {
239 mmio_region_read32(handle->
dev.
base_addr, FLASH_CTRL_INIT_REG_OFFSET);
245 mmio_region_write32(handle->
dev.
base_addr, FLASH_CTRL_INIT_REG_OFFSET, value);
252 if (handle == NULL || status_out == NULL) {
256 mmio_region_read32(handle->
dev.
base_addr, FLASH_CTRL_STATUS_REG_OFFSET);
265 .controller_init_wip =
267 .controller_initialized =
278 if (handle == NULL || allowed_types_out == NULL) {
282 uint32_t reg = mmio_region_read32(handle->
dev.
base_addr,
283 FLASH_CTRL_PROG_TYPE_EN_REG_OFFSET);
290 *allowed_types_out = allowed_types;
298 if (handle == NULL) {
302 uint32_t ctrl_regwen = mmio_region_read32(handle->
dev.
base_addr,
303 FLASH_CTRL_CTRL_REGWEN_REG_OFFSET);
313 mmio_region_write32(handle->
dev.
base_addr, FLASH_CTRL_PROG_TYPE_EN_REG_OFFSET,
321 if (handle == NULL) {
324 uint32_t ctrl_regwen = mmio_region_read32(handle->
dev.
base_addr,
325 FLASH_CTRL_CTRL_REGWEN_REG_OFFSET);
331 transaction.word_count - 1);
332 switch (transaction.op) {
336 FLASH_CTRL_CONTROL_OP_VALUE_READ);
341 FLASH_CTRL_CONTROL_OP_VALUE_PROG);
343 control_reg, FLASH_CTRL_CONTROL_PROG_SEL_BIT,
false);
348 FLASH_CTRL_CONTROL_OP_VALUE_PROG);
350 FLASH_CTRL_CONTROL_PROG_SEL_BIT,
true);
355 FLASH_CTRL_CONTROL_OP_VALUE_ERASE);
357 control_reg, FLASH_CTRL_CONTROL_ERASE_SEL_BIT,
false);
362 FLASH_CTRL_CONTROL_OP_VALUE_ERASE);
364 control_reg, FLASH_CTRL_CONTROL_ERASE_SEL_BIT,
true);
370 switch (transaction.partition_type) {
371 case kDifFlashCtrlPartitionTypeData:
373 control_reg, FLASH_CTRL_CONTROL_PARTITION_SEL_BIT,
false);
375 case kDifFlashCtrlPartitionTypeInfo:
378 transaction.partition_id);
380 control_reg, FLASH_CTRL_CONTROL_PARTITION_SEL_BIT,
true);
386 mmio_region_write32(handle->
dev.
base_addr, FLASH_CTRL_CONTROL_REG_OFFSET,
388 mmio_region_write32(handle->
dev.
base_addr, FLASH_CTRL_ADDR_REG_OFFSET,
389 transaction.byte_address);
390 mmio_region_write32(handle->
dev.
base_addr, FLASH_CTRL_CONTROL_REG_OFFSET,
391 control_reg | (1u << FLASH_CTRL_CONTROL_START_BIT));
406 if (handle == NULL) {
410 if (transaction.partition_type == kDifFlashCtrlPartitionTypeInfo &&
411 transaction.partition_id >= FLASH_CTRL_NUM_INFO_TYPES) {
415 const uint32_t max_word_count = FLASH_CTRL_CONTROL_NUM_MASK;
418 if (transaction.word_count - 1 > max_word_count ||
419 transaction.word_count == 0) {
434 if (!
status.read_fifo_empty || !
status.prog_fifo_empty) {
443 if (handle == NULL) {
449 FLASH_CTRL_ERASE_SUSPEND_REG_OFFSET, reg);
456 if (handle == NULL || request_pending_out == NULL) {
459 uint32_t reg = mmio_region_read32(handle->
dev.
base_addr,
460 FLASH_CTRL_ERASE_SUSPEND_REG_OFFSET);
461 *request_pending_out =
471 if (handle == NULL || data == NULL) {
474 uint32_t written = 0;
475 while (written < word_count) {
476 mmio_region_write32(handle->
dev.
base_addr, FLASH_CTRL_PROG_FIFO_REG_OFFSET,
487 const uint32_t *data) {
488 if (handle == NULL || data == NULL) {
497 const uint32_t control_reg =
498 mmio_region_read32(handle->
dev.
base_addr, FLASH_CTRL_CONTROL_REG_OFFSET);
501 if (op != FLASH_CTRL_CONTROL_OP_VALUE_PROG) {
511 if (handle == NULL || data == NULL) {
515 while (read < word_count) {
517 FLASH_CTRL_RD_FIFO_REG_OFFSET);
526 uint32_t word_count, uint32_t *data) {
527 if (handle == NULL || data == NULL) {
536 const uint32_t control_reg =
537 mmio_region_read32(handle->
dev.
base_addr, FLASH_CTRL_CONTROL_REG_OFFSET);
540 if (op != FLASH_CTRL_CONTROL_OP_VALUE_READ) {
550 if (handle == NULL || error_code_out == NULL) {
553 const uint32_t code_reg =
554 mmio_region_read32(handle->
dev.
base_addr, FLASH_CTRL_ERR_CODE_REG_OFFSET);
564 .shadow_register_error =
568 const uint32_t address_reg =
569 mmio_region_read32(handle->
dev.
base_addr, FLASH_CTRL_ERR_ADDR_REG_OFFSET);
574 *error_code_out = error_code;
581 if (handle == NULL) {
584 uint32_t code_reg = 0;
592 code_reg, FLASH_CTRL_ERR_CODE_PROG_TYPE_ERR_BIT, codes.
prog_type_error);
595 mmio_region_write32(handle->
dev.
base_addr, FLASH_CTRL_ERR_CODE_REG_OFFSET,
603 if (handle == NULL || out == NULL) {
609 uint32_t status_reg = mmio_region_read32(handle->
dev.
base_addr,
610 FLASH_CTRL_OP_STATUS_REG_OFFSET);
624 .error_code = error_code_tmp};
626 mmio_region_write32(handle->
dev.
base_addr, FLASH_CTRL_OP_STATUS_REG_OFFSET,
636 if (handle == NULL || region >= FLASH_CTRL_PARAM_NUM_REGIONS) {
647 ptrdiff_t mp_reg_offset = get_data_region_mp_reg_offset(region);
648 uint32_t mp_reg = mmio_region_read32(handle->
dev.
base_addr, mp_reg_offset);
652 mp_reg, FLASH_CTRL_MP_REGION_CFG_0_EN_0_FIELD, kMultiBitBool4True);
656 mp_reg, FLASH_CTRL_MP_REGION_CFG_0_EN_0_FIELD, kMultiBitBool4False);
661 mmio_region_write32(handle->
dev.
base_addr, mp_reg_offset, mp_reg);
669 if (handle == NULL || enabled_out == NULL ||
670 region >= FLASH_CTRL_PARAM_NUM_REGIONS) {
673 ptrdiff_t mp_reg_offset = get_data_region_mp_reg_offset(region);
674 uint32_t mp_reg = mmio_region_read32(handle->
dev.
base_addr, mp_reg_offset);
676 kMultiBitBool4True) {
688 if (handle == NULL || region.
bank >= FLASH_CTRL_PARAM_REG_NUM_BANKS ||
700 ptrdiff_t mp_reg_offset = get_info_region_mp_reg_offset(region);
701 uint32_t mp_reg = mmio_region_read32(handle->
dev.
base_addr, mp_reg_offset);
705 mp_reg, FLASH_CTRL_BANK0_INFO0_PAGE_CFG_0_EN_0_FIELD,
710 mp_reg, FLASH_CTRL_BANK0_INFO0_PAGE_CFG_0_EN_0_FIELD,
711 kMultiBitBool4False);
716 mmio_region_write32(handle->
dev.
base_addr, mp_reg_offset, mp_reg);
724 if (handle == NULL || enabled_out == NULL ||
725 region.
bank >= FLASH_CTRL_PARAM_REG_NUM_BANKS ||
730 ptrdiff_t mp_reg_offset = get_info_region_mp_reg_offset(region);
731 uint32_t mp_reg = mmio_region_read32(handle->
dev.
base_addr, mp_reg_offset);
733 kMultiBitBool4True) {
745 if (handle == NULL) {
762 FLASH_CTRL_DEFAULT_REGION_REG_OFFSET, reg);
770 if (handle == NULL || properties_out == NULL) {
773 const uint32_t reg = mmio_region_read32(handle->
dev.
base_addr,
774 FLASH_CTRL_DEFAULT_REGION_REG_OFFSET);
783 reg, FLASH_CTRL_DEFAULT_REGION_SCRAMBLE_EN_FIELD),
789 *properties_out = properties;
797 const uint32_t page_limit =
798 FLASH_CTRL_PARAM_REG_NUM_BANKS * FLASH_CTRL_PARAM_REG_PAGES_PER_BANK;
799 if (handle == NULL || region >= FLASH_CTRL_PARAM_NUM_REGIONS ||
800 config.
base + config.
size > page_limit) {
811 ptrdiff_t mp_reg_offset = get_data_region_mp_reg_offset(region);
812 uint32_t reg = mmio_region_read32(handle->
dev.
base_addr, mp_reg_offset);
820 FLASH_CTRL_MP_REGION_CFG_0_SCRAMBLE_EN_0_FIELD,
827 mmio_region_write32(handle->
dev.
base_addr, mp_reg_offset, reg);
830 mp_reg_offset = get_data_region_reg_offset(region);
836 mmio_region_write32(handle->
dev.
base_addr, mp_reg_offset, reg);
844 if (handle == NULL || config_out == NULL ||
845 region >= FLASH_CTRL_PARAM_NUM_REGIONS) {
849 ptrdiff_t mp_reg_offset = get_data_region_mp_reg_offset(region);
850 uint32_t reg = mmio_region_read32(handle->
dev.
base_addr, mp_reg_offset);
859 reg, FLASH_CTRL_MP_REGION_CFG_0_SCRAMBLE_EN_0_FIELD);
865 mp_reg_offset = get_data_region_reg_offset(region);
866 reg = mmio_region_read32(handle->
dev.
base_addr, mp_reg_offset);
869 *config_out = config;
877 if (handle == NULL || region.
bank >= FLASH_CTRL_PARAM_REG_NUM_BANKS ||
890 ptrdiff_t mp_reg_offset = get_info_region_mp_reg_offset(region);
891 uint32_t reg = mmio_region_read32(handle->
dev.
base_addr, mp_reg_offset);
899 FLASH_CTRL_MP_REGION_CFG_0_SCRAMBLE_EN_0_FIELD,
905 mmio_region_write32(handle->
dev.
base_addr, mp_reg_offset, reg);
913 if (handle == NULL || properties_out == NULL ||
914 region.
bank >= FLASH_CTRL_PARAM_REG_NUM_BANKS ||
920 ptrdiff_t mp_reg_offset = get_info_region_mp_reg_offset(region);
921 const uint32_t reg = mmio_region_read32(handle->
dev.
base_addr, mp_reg_offset);
924 reg, FLASH_CTRL_BANK0_INFO0_PAGE_CFG_0_RD_EN_0_FIELD);
926 reg, FLASH_CTRL_BANK0_INFO0_PAGE_CFG_0_PROG_EN_0_FIELD);
928 reg, FLASH_CTRL_BANK0_INFO0_PAGE_CFG_0_ERASE_EN_0_FIELD);
930 reg, FLASH_CTRL_BANK0_INFO0_PAGE_CFG_0_SCRAMBLE_EN_0_FIELD);
932 reg, FLASH_CTRL_BANK0_INFO0_PAGE_CFG_0_ECC_EN_0_FIELD);
934 reg, FLASH_CTRL_BANK0_INFO0_PAGE_CFG_0_HE_EN_0_FIELD);
935 *properties_out = properties;
942 if (handle == NULL || region >= FLASH_CTRL_PARAM_NUM_REGIONS) {
953 ptrdiff_t lock_reg_offset = get_data_region_lock_reg_offset(region);
955 0, FLASH_CTRL_REGION_CFG_REGWEN_0_REGION_0_BIT,
false);
956 mmio_region_write32(handle->
dev.
base_addr, lock_reg_offset, reg);
963 if (handle == NULL || region.
bank >= FLASH_CTRL_PARAM_REG_NUM_BANKS ||
976 ptrdiff_t lock_reg_offset = get_info_region_lock_reg_offset(region);
978 0, FLASH_CTRL_BANK0_INFO0_REGWEN_0_REGION_0_BIT,
false);
979 mmio_region_write32(handle->
dev.
base_addr, lock_reg_offset, reg);
986 if (handle == NULL || locked_out == NULL ||
987 region >= FLASH_CTRL_PARAM_NUM_REGIONS) {
990 ptrdiff_t lock_reg_offset = get_data_region_lock_reg_offset(region);
991 uint32_t reg = mmio_region_read32(handle->
dev.
base_addr, lock_reg_offset);
1001 if (handle == NULL || locked_out == NULL ||
1002 region.
bank >= FLASH_CTRL_PARAM_REG_NUM_BANKS ||
1008 ptrdiff_t lock_reg_offset = get_info_region_lock_reg_offset(region);
1009 uint32_t reg = mmio_region_read32(handle->
dev.
base_addr, lock_reg_offset);
1018 if (handle == NULL || bank >= FLASH_CTRL_PARAM_REG_NUM_BANKS) {
1030 uint32_t value = mmio_region_read32(
1031 handle->
dev.
base_addr, FLASH_CTRL_MP_BANK_CFG_SHADOWED_REG_OFFSET);
1042 mmio_region_write32_shadowed(
1043 handle->
dev.
base_addr, FLASH_CTRL_MP_BANK_CFG_SHADOWED_REG_OFFSET, value);
1051 if (handle == NULL || enabled_out == NULL ||
1052 bank >= FLASH_CTRL_PARAM_REG_NUM_BANKS) {
1055 uint32_t reg = mmio_region_read32(handle->
dev.
base_addr,
1056 FLASH_CTRL_MP_BANK_CFG_SHADOWED_REG_OFFSET);
1070 if (handle == NULL) {
1084 FLASH_CTRL_BANK_CFG_REGWEN_REG_OFFSET, reg);
1091 if (handle == NULL || locked_out == NULL) {
1094 const uint32_t reg = mmio_region_read32(
1095 handle->
dev.
base_addr, FLASH_CTRL_BANK_CFG_REGWEN_REG_OFFSET);
1103 if (handle == NULL || level > FLASH_CTRL_FIFO_LVL_PROG_MASK) {
1107 mmio_region_read32(handle->
dev.
base_addr, FLASH_CTRL_FIFO_LVL_REG_OFFSET);
1109 mmio_region_write32(handle->
dev.
base_addr, FLASH_CTRL_FIFO_LVL_REG_OFFSET,
1117 if (handle == NULL || level > FLASH_CTRL_FIFO_LVL_RD_MASK) {
1121 mmio_region_read32(handle->
dev.
base_addr, FLASH_CTRL_FIFO_LVL_REG_OFFSET);
1123 mmio_region_write32(handle->
dev.
base_addr, FLASH_CTRL_FIFO_LVL_REG_OFFSET,
1131 uint32_t *read_out) {
1132 if (handle == NULL) {
1135 const uint32_t reg =
1136 mmio_region_read32(handle->
dev.
base_addr, FLASH_CTRL_FIFO_LVL_REG_OFFSET);
1137 if (prog_out != NULL) {
1140 if (read_out != NULL) {
1149 if (handle == NULL) {
1153 mmio_region_write32(handle->
dev.
base_addr, FLASH_CTRL_FIFO_RST_REG_OFFSET,
1156 mmio_region_write32(handle->
dev.
base_addr, FLASH_CTRL_FIFO_RST_REG_OFFSET,
1164 if (handle == NULL || faults_out == NULL) {
1167 uint32_t reg = mmio_region_read32(handle->
dev.
base_addr,
1168 FLASH_CTRL_FAULT_STATUS_REG_OFFSET);
1181 FLASH_CTRL_STD_FAULT_STATUS_REG_OFFSET);
1190 *faults_out = faults;
1198 if (handle == NULL || errors_out == NULL ||
1199 bank > FLASH_CTRL_PARAM_REG_NUM_BANKS) {
1203 ptrdiff_t last_addr_reg_offset;
1204 #if FLASH_CTRL_PARAM_REG_NUM_BANKS > 2
1205 #error "Revise this function to handle more banks."
1209 FLASH_CTRL_ECC_SINGLE_ERR_CNT_ECC_SINGLE_ERR_CNT_0_FIELD;
1210 last_addr_reg_offset = FLASH_CTRL_ECC_SINGLE_ERR_ADDR_0_REG_OFFSET;
1213 FLASH_CTRL_ECC_SINGLE_ERR_CNT_ECC_SINGLE_ERR_CNT_1_FIELD;
1214 last_addr_reg_offset = FLASH_CTRL_ECC_SINGLE_ERR_ADDR_1_REG_OFFSET;
1217 uint32_t reg = mmio_region_read32(handle->
dev.
base_addr,
1218 FLASH_CTRL_ECC_SINGLE_ERR_CNT_REG_OFFSET);
1222 mmio_region_read32(handle->
dev.
base_addr, last_addr_reg_offset);
1230 if (handle == NULL || status_out == NULL) {
1233 const uint32_t reg = mmio_region_read32(handle->
dev.
base_addr,
1234 FLASH_CTRL_PHY_STATUS_REG_OFFSET);
1238 .prog_normal_available =
1240 .prog_repair_available =
1250 if (handle == NULL) {
1253 mmio_region_write32(handle->
dev.
base_addr, FLASH_CTRL_SCRATCH_REG_OFFSET,
1260 uint32_t *value_out) {
1261 if (handle == NULL || value_out == NULL) {
1265 mmio_region_read32(handle->
dev.
base_addr, FLASH_CTRL_SCRATCH_REG_OFFSET);