5 #include "sw/device/silicon_creator/lib/drivers/spi_device.h" 
    7 #include "dt/dt_spi_device.h" 
   11 #include "sw/device/silicon_creator/lib/drivers/lifecycle.h" 
   12 #include "sw/device/silicon_creator/lib/error.h" 
   14 #include "flash_ctrl_regs.h" 
   15 #include "spi_device_regs.h" 
   17 static const dt_spi_device_t kSpiDeviceDt = kDtSpiDevice;
 
   22 static inline uint32_t spi_device_reg_base(
void) {
 
   23   return dt_spi_device_primary_reg_block(kSpiDeviceDt);
 
   31       SPI_DEVICE_EGRESS_BUFFER_REG_OFFSET + kSpiDeviceSfdpAreaOffset,
 
   35   kSfdpAreaEndOff = SPI_DEVICE_EGRESS_BUFFER_REG_OFFSET +
 
   36                     kSpiDeviceSfdpAreaOffset + kSpiDeviceSfdpAreaNumBytes,
 
   41       FLASH_CTRL_PARAM_REG_NUM_BANKS * FLASH_CTRL_PARAM_BYTES_PER_BANK * 8,
 
   46   kSfdpSignature = 0x50444653,
 
   57   kSfdpMajorRevision = 0x01,
 
   61   kSfdpMinorRevision = 0x0a,
 
   65   kSfdpAccessProtocol = 0xff,
 
   69   kBfptMajorRevision = 0x01,
 
   73   kBfptMinorRevision = 0x07,
 
   77   kBfptParamIdLsb = 0x00,
 
   81   kBfptParamIdMsb = 0xff,
 
   93   kBfptNotSupported = 0,
 
   96 static_assert(kBfptTablePointer % 
sizeof(uint32_t) == 0,
 
   97               "BFPT must be word-aligned");
 
  105 #define BFPT_FIELD_WIDTH(upper, lower) ((upper) - (lower) + 1) 
  113 #define BFPT_FIELD_MASK(upper, lower) \ 
  114   (((UINT64_C(1) << BFPT_FIELD_WIDTH(upper, lower)) - 1) << (lower)) 
  127 #define BFPT_FIELD_VALUE(upper, lower, value) \ 
  128   ((uint32_t)~BFPT_FIELD_MASK(upper, lower) | \ 
  129    (BFPT_FIELD_MASK(upper, lower) & ((uint32_t)(value) << (uint32_t)(lower)))) 
  151 #define BFPT_WORD_1(X) \ 
  152   X(22, 19, kBfptNotSupported) & \ 
  154   X(16, 16, kBfptNotSupported) & \ 
  155   X(15,  8, kSpiDeviceOpcodeSectorErase) & \ 
  167 #define BFPT_WORD_2(X) \ 
  169   X(30,  0, kFlashBitCount - 1) 
  176 #define BFPT_WORD_3(X) \ 
  177   X(31,  0, kBfptNotSupported) 
  184 #define BFPT_WORD_4(X) \ 
  185   X(31,  0, kBfptNotSupported) 
  195 #define BFPT_WORD_5(X) \ 
  196   X( 4,  4, kBfptNotSupported) & \ 
  197   X( 0,  0, kBfptNotSupported) 
  205 #define BFPT_WORD_6(X) \ 
  206   X(31, 16, kBfptNotSupported) 
  214 #define BFPT_WORD_7(X) \ 
  215   X(31, 16, kBfptNotSupported) 
  224 #define BFPT_WORD_8(X) \ 
  225   X(31, 16, kBfptNotSupported) & \ 
  226   X(15,  8, kSpiDeviceOpcodeSectorErase) & \ 
  234 #define BFPT_WORD_9(X) \ 
  235   X(31,  0, kBfptNotSupported) 
  248 #define BFPT_WORD_10(X) \ 
  249   X(31, 11, kBfptNotSupported) & \ 
  278 #define BFPT_WORD_11(X) \ 
  298 #define BFPT_WORD_12(X) \ 
  300  X(30,  9, kBfptNotSupported) & \ 
  301  X( 7,  0, kBfptNotSupported) 
  308 #define BFPT_WORD_13(X) \ 
  309  X(31, 0, kBfptNotSupported) 
  319 #define BFPT_WORD_14(X) \ 
  321  X(30,  8, kBfptNotSupported) & \ 
  330 #define BFPT_WORD_15(X) \ 
  331  X(23,  0, kBfptNotSupported) 
  341 #define BFPT_WORD_16(X) \ 
  342   X(31, 14, kBfptNotSupported) & \ 
  351 #define BFPT_WORD_17(X) \ 
  352   X(31,  0, kBfptNotSupported) 
  361 #define BFPT_WORD_18(X) \ 
  362   X(31,  0, kBfptNotSupported) 
  371 #define BFPT_WORD_19(X) \ 
  372   X(31,  0, kBfptNotSupported) 
  380 #define BFPT_WORD_20(X) \ 
  390 #define BFPT_WORD_21(X) \ 
  391   X(31,  0, kBfptNotSupported) 
  398 #define BFPT_WORD_22(X) \ 
  399   X(31,  0, kBfptNotSupported) 
  406 #define BFPT_WORD_23(X) \ 
  407   X(31,  0, kBfptNotSupported) 
  414             .minor_revision = kSfdpMinorRevision,
 
  415             .major_revision = kSfdpMajorRevision,
 
  416             .param_count = kSfdpParamCount,
 
  417             .access_protocol = kSfdpAccessProtocol,
 
  421             .param_id_lsb = kBfptParamIdLsb,
 
  422             .minor_revision = kBfptMinorRevision,
 
  423             .major_revision = kBfptMajorRevision,
 
  424             .table_word_count = kSpiDeviceBfptNumWords,
 
  425             .table_pointer = {kBfptTablePointer},
 
  426             .param_id_msb = kBfptParamIdMsb,
 
  429         BFPT_WORD_1(BFPT_FIELD_VALUE),  BFPT_WORD_2(BFPT_FIELD_VALUE),
 
  430         BFPT_WORD_3(BFPT_FIELD_VALUE),  BFPT_WORD_4(BFPT_FIELD_VALUE),
 
  431         BFPT_WORD_5(BFPT_FIELD_VALUE),  BFPT_WORD_6(BFPT_FIELD_VALUE),
 
  432         BFPT_WORD_7(BFPT_FIELD_VALUE),  BFPT_WORD_8(BFPT_FIELD_VALUE),
 
  433         BFPT_WORD_9(BFPT_FIELD_VALUE),  BFPT_WORD_10(BFPT_FIELD_VALUE),
 
  434         BFPT_WORD_11(BFPT_FIELD_VALUE), BFPT_WORD_12(BFPT_FIELD_VALUE),
 
  435         BFPT_WORD_13(BFPT_FIELD_VALUE), BFPT_WORD_14(BFPT_FIELD_VALUE),
 
  436         BFPT_WORD_15(BFPT_FIELD_VALUE), BFPT_WORD_16(BFPT_FIELD_VALUE),
 
  437         BFPT_WORD_17(BFPT_FIELD_VALUE), BFPT_WORD_18(BFPT_FIELD_VALUE),
 
  438         BFPT_WORD_19(BFPT_FIELD_VALUE), BFPT_WORD_20(BFPT_FIELD_VALUE),
 
  439         BFPT_WORD_21(BFPT_FIELD_VALUE), BFPT_WORD_22(BFPT_FIELD_VALUE),
 
  440         BFPT_WORD_23(BFPT_FIELD_VALUE),
 
  487       reg, SPI_DEVICE_CMD_INFO_0_ADDR_MODE_0_FIELD,
 
  489                        : SPI_DEVICE_CMD_INFO_0_ADDR_MODE_0_VALUE_ADDRDISABLED);
 
  504 void spi_device_init(
void) {
 
  509   abs_mmio_write32(spi_device_reg_base() + SPI_DEVICE_CFG_REG_OFFSET, reg);
 
  512   abs_mmio_write32(spi_device_reg_base() + SPI_DEVICE_ADDR_MODE_REG_OFFSET,
 
  519                                kSpiDeviceJedecContCode);
 
  521                                kSpiDeviceJedecContCodeCount);
 
  522   abs_mmio_write32(spi_device_reg_base() + SPI_DEVICE_JEDEC_CC_REG_OFFSET, reg);
 
  527   lifecycle_hw_rev_get(&hw_rev);
 
  535                                kSpiDeviceJedecDensity);
 
  537                                kSpiDeviceJedecManufId);
 
  538   abs_mmio_write32(spi_device_reg_base() + SPI_DEVICE_JEDEC_ID_REG_OFFSET, reg);
 
  541   uint32_t dest = spi_device_reg_base() + kSfdpAreaStartOff;
 
  542   const char *table = (
const char *)&kSpiDeviceSfdpTable;
 
  543   for (
size_t i = 0; i < kSpiDeviceSfdpTableNumWords; ++i) {
 
  544     abs_mmio_write32(dest, 
read_32(table));
 
  545     dest += 
sizeof(uint32_t);
 
  546     table += 
sizeof(uint32_t);
 
  549   for (; dest < spi_device_reg_base() + kSfdpAreaEndOff;
 
  550        dest += 
sizeof(uint32_t)) {
 
  551     abs_mmio_write32(dest, UINT32_MAX);
 
  555   abs_mmio_write32(spi_device_reg_base() + SPI_DEVICE_FLASH_STATUS_REG_OFFSET,
 
  560       .reg_offset = SPI_DEVICE_CMD_INFO_0_REG_OFFSET,
 
  561       .op_code = kSpiDeviceOpcodeReadStatus,
 
  564       .handled_in_sw = 
false,
 
  568       .reg_offset = SPI_DEVICE_CMD_INFO_3_REG_OFFSET,
 
  569       .op_code = kSpiDeviceOpcodeReadJedecId,
 
  572       .handled_in_sw = 
false,
 
  576       .reg_offset = SPI_DEVICE_CMD_INFO_4_REG_OFFSET,
 
  577       .op_code = kSpiDeviceOpcodeReadSfdp,
 
  580       .handled_in_sw = 
false,
 
  584       .reg_offset = SPI_DEVICE_CMD_INFO_11_REG_OFFSET,
 
  585       .op_code = kSpiDeviceOpcodeChipErase,
 
  588       .handled_in_sw = 
true,
 
  592       .reg_offset = SPI_DEVICE_CMD_INFO_12_REG_OFFSET,
 
  593       .op_code = kSpiDeviceOpcodeSectorErase,
 
  596       .handled_in_sw = 
true,
 
  600       .reg_offset = SPI_DEVICE_CMD_INFO_13_REG_OFFSET,
 
  601       .op_code = kSpiDeviceOpcodePageProgram,
 
  604       .handled_in_sw = 
true,
 
  608       .reg_offset = SPI_DEVICE_CMD_INFO_14_REG_OFFSET,
 
  609       .op_code = kSpiDeviceOpcodeReset,
 
  612       .handled_in_sw = 
true,
 
  616                                kSpiDeviceOpcodeWriteEnable);
 
  618   abs_mmio_write32(spi_device_reg_base() + SPI_DEVICE_CMD_INFO_WREN_REG_OFFSET,
 
  621                                kSpiDeviceOpcodeWriteDisable);
 
  622   abs_mmio_write32(spi_device_reg_base() + SPI_DEVICE_CMD_INFO_WRDI_REG_OFFSET,
 
  628   bool cmd_pending = 
false;
 
  629   while (!cmd_pending) {
 
  632     reg = abs_mmio_read32(spi_device_reg_base() +
 
  633                           SPI_DEVICE_INTR_STATE_REG_OFFSET);
 
  635         reg, SPI_DEVICE_INTR_COMMON_UPLOAD_CMDFIFO_NOT_EMPTY_BIT);
 
  637   abs_mmio_write32(spi_device_reg_base() + SPI_DEVICE_INTR_STATE_REG_OFFSET,
 
  640                           SPI_DEVICE_INTR_COMMON_UPLOAD_PAYLOAD_OVERFLOW_BIT)) {
 
  641     return kErrorSpiDevicePayloadOverflow;
 
  644   reg = abs_mmio_read32(spi_device_reg_base() +
 
  645                         SPI_DEVICE_UPLOAD_CMDFIFO_REG_OFFSET);
 
  648   cmd->
address = kSpiDeviceNoAddress;
 
  649   reg = abs_mmio_read32(spi_device_reg_base() +
 
  650                         SPI_DEVICE_UPLOAD_STATUS_REG_OFFSET);
 
  652                           SPI_DEVICE_UPLOAD_STATUS_ADDRFIFO_NOTEMPTY_BIT)) {
 
  653     cmd->
address = abs_mmio_read32(spi_device_reg_base() +
 
  654                                    SPI_DEVICE_UPLOAD_ADDRFIFO_REG_OFFSET);
 
  657   reg = abs_mmio_read32(spi_device_reg_base() +
 
  658                         SPI_DEVICE_UPLOAD_STATUS2_REG_OFFSET);
 
  663   uint32_t src = spi_device_reg_base() + SPI_DEVICE_INGRESS_BUFFER_REG_OFFSET +
 
  664                  kSpiDevicePayloadAreaOffset;
 
  665   char *dest = (
char *)&cmd->
payload;
 
  667     write_32(abs_mmio_read32(src + i), dest + i);
 
  673 void spi_device_flash_status_clear(
void) {
 
  674   abs_mmio_write32(spi_device_reg_base() + SPI_DEVICE_FLASH_STATUS_REG_OFFSET,
 
  678 uint32_t spi_device_flash_status_get(
void) {
 
  679   return abs_mmio_read32(spi_device_reg_base() +
 
  680                          SPI_DEVICE_FLASH_STATUS_REG_OFFSET);