Software APIs
ast_program.c
1 // Copyright lowRISC contributors (OpenTitan project).
2 // Licensed under the Apache License, Version 2.0, see LICENSE for details.
3 // SPDX-License-Identifier: Apache-2.0
4 
6 #include "sw/device/lib/base/status.h"
12 #include "sw/device/lib/testing/flash_ctrl_testutils.h"
13 #include "sw/device/silicon_creator/manuf/lib/flash_info_fields.h"
14 
16 
17 #ifndef AST_PROGRAM_UNITTEST
18 // In normal operation, AST writes should go directly to the AST
19 // peripheral. The DIF variables should be only visible to this
20 // source unit.
21 #define ast_write(addr, data) abs_mmio_write32(addr, data)
22 static dif_flash_ctrl_state_t flash_state;
23 static dif_pinmux_t pinmux;
24 static dif_uart_t uart0;
25 #else
26 // If we're running a unit test, we want to supply an AST writing function
27 // and make the DIFs externally visible so the test program can verify
28 // the written values and examine/modify the flash.
29 extern void ast_write(uint32_t addr, uint32_t data);
30 dif_flash_ctrl_state_t flash_state;
31 dif_pinmux_t pinmux;
32 dif_uart_t uart0;
33 #endif
34 
35 static status_t setup_uart(bool enable) {
36  if (enable) {
37  TRY(dif_pinmux_init(
46  &uart0));
47  TRY(dif_uart_configure(&uart0,
49  .baudrate = (uint32_t)kUartBaudrate,
50  .clk_freq_hz = (uint32_t)kClockFreqPeripheralHz,
51  .parity_enable = kDifToggleDisabled,
52  .parity = kDifUartParityEven,
53  .tx_enable = kDifToggleEnabled,
54  .rx_enable = kDifToggleEnabled,
55  }));
56  base_uart_stdout(&uart0);
57  } else {
58  base_uart_stdout(NULL);
59  }
60  return OK_STATUS();
61 }
62 
63 status_t ast_program_init(bool verbose) {
64  setup_uart(verbose);
65  LOG_INFO("Starting AST config");
66  // Initialize the flash_ctrl DIF.
68  &flash_state,
70  TRY(flash_ctrl_testutils_wait_for_init(&flash_state));
71 
72  // Set up parameters for accessing the AST calibration data in flash info page
73  // 0.
74  TRY(flash_ctrl_testutils_info_region_setup_properties(
75  &flash_state, kFlashInfoFieldAstCalibrationData.page,
76  kFlashInfoFieldAstCalibrationData.bank,
77  kFlashInfoFieldAstCalibrationData.partition,
79  .ecc_en = kMultiBitBool4True,
80  .high_endurance_en = kMultiBitBool4False,
81  .erase_en = kMultiBitBool4True,
82  .prog_en = kMultiBitBool4True,
83  .rd_en = kMultiBitBool4True,
84  .scramble_en = kMultiBitBool4False},
85  /*offset=*/NULL));
86 
87  return OK_STATUS();
88 }
89 
90 status_t ast_program_config(bool verbose) {
91  TRY(ast_program_init(verbose));
92 
93  // Read AST calibration values from flash.
94  LOG_INFO("Reading AST data");
96  uint32_t byte_address =
97  (kFlashInfoFieldAstCalibrationData.page * device_info.bytes_per_page) +
98  kFlashInfoFieldAstCalibrationData.byte_offset;
99  uint32_t ast_data[kFlashInfoAstCalibrationDataSizeIn32BitWords];
100  TRY(flash_ctrl_testutils_wait_for_init(&flash_state));
101  TRY(flash_ctrl_testutils_read(&flash_state, byte_address,
102  kFlashInfoFieldAstCalibrationData.partition,
103  ast_data, kDifFlashCtrlPartitionTypeInfo,
104  kFlashInfoAstCalibrationDataSizeIn32BitWords,
105  /*delay=*/0));
106 
107  // Program AST CSRs.
108  LOG_INFO("Programming %u AST words",
109  kFlashInfoAstCalibrationDataSizeIn32BitWords);
110  for (size_t i = 0; i < kFlashInfoAstCalibrationDataSizeIn32BitWords; ++i) {
111  uint32_t addr = TOP_EARLGREY_AST_BASE_ADDR + i * sizeof(uint32_t);
112  uint32_t data = ast_data[i];
113  LOG_INFO("\tAddress = 0x%08x, Data = 0x%08x", addr, data);
114  ast_write(addr, data);
115  }
116 
117  return OK_STATUS();
118 }