diff options
Diffstat (limited to 'src/southbridge/intel/common/spi.c')
-rw-r--r-- | src/southbridge/intel/common/spi.c | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/src/southbridge/intel/common/spi.c b/src/southbridge/intel/common/spi.c index e9e66dcda3..8430dc8611 100644 --- a/src/southbridge/intel/common/spi.c +++ b/src/southbridge/intel/common/spi.c @@ -31,6 +31,8 @@ #include <spi-generic.h> +#include "spi.h" + #define HSFC_FCYCLE_OFF 1 /* 1-2: FLASH Cycle */ #define HSFC_FCYCLE (0x3 << HSFC_FCYCLE_OFF) #define HSFC_FDBC_OFF 8 /* 8-13: Flash Data Byte Count */ @@ -1048,6 +1050,45 @@ static int spi_flash_protect(const struct spi_flash *flash, return 0; } +void spi_finalize_ops(void) +{ + struct ich_spi_controller *cntlr = &g_cntlr; + u16 spi_opprefix; + u16 optype = 0; + struct intel_swseq_spi_config spi_config = { + {0x06, 0x50}, /* OPPREFIXES: EWSR and WREN */ + { /* OPTYPE and OPCODE */ + {0x01, WRITE_NO_ADDR}, /* WRSR: Write Status Register */ + {0x02, WRITE_WITH_ADDR}, /* BYPR: Byte Program */ + {0x03, READ_WITH_ADDR}, /* READ: Read Data */ + {0x05, READ_NO_ADDR}, /* RDSR: Read Status Register */ + {0x20, WRITE_WITH_ADDR}, /* SE20: Sector Erase 0x20 */ + {0x9f, READ_NO_ADDR}, /* RDID: Read ID */ + {0xd8, WRITE_WITH_ADDR}, /* BED8: Block Erase 0xd8 */ + {0x0b, READ_WITH_ADDR}, /* FAST: Fast Read */ + } + }; + int i; + + if (spi_locked()) + return; + + intel_southbridge_override_spi(&spi_config); + + spi_opprefix = spi_config.opprefixes[0] + | (spi_config.opprefixes[1] << 8); + writew_(spi_opprefix, cntlr->preop); + for (i = 0; i < ARRAY_SIZE(spi_config.ops); i++) { + optype |= (spi_config.ops[i].type & 3) << (i * 2); + writeb_(spi_config.ops[i].op, &cntlr->opmenu[i]); + } + writew_(optype, &cntlr->optype); +} + +__weak void intel_southbridge_override_spi(struct intel_swseq_spi_config *spi_config) +{ +} + static const struct spi_ctrlr spi_ctrlr = { .xfer_vector = xfer_vectors, .max_xfer_size = member_size(struct ich9_spi_regs, fdata), |