From 92185e373ea70b4a9af6fb7f38b0855d7d898bf3 Mon Sep 17 00:00:00 2001 From: Arthur Heymans Date: Tue, 28 May 2019 13:06:34 +0200 Subject: [PATCH] sb/intel/common: Add a common interface to set final OPs settings This adds a common place to set the final opprefix, optype and opmenu, with a hook to override the opmenu. Change-Id: I162ae6bad7da3ea02b96854ee28e70594e210947 Signed-off-by: Arthur Heymans Reviewed-on: https://review.coreboot.org/c/coreboot/+/33036 Tested-by: build bot (Jenkins) Reviewed-by: Nico Huber --- src/southbridge/intel/common/spi.c | 41 ++++++++++++++++++++++++++++++ src/southbridge/intel/common/spi.h | 38 +++++++++++++++++++++++++++ 2 files changed, 79 insertions(+) create mode 100644 src/southbridge/intel/common/spi.h 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 +#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), diff --git a/src/southbridge/intel/common/spi.h b/src/southbridge/intel/common/spi.h new file mode 100644 index 0000000000..3b8410cd9f --- /dev/null +++ b/src/southbridge/intel/common/spi.h @@ -0,0 +1,38 @@ +/* + * This file is part of the coreboot project. + + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; version 2 of + * the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef SOUTHBRIDGE_INTEL_SPI_H +#define SOUTHBRIDGE_INTEL_SPI_H + +enum optype { + READ_NO_ADDR = 0, + WRITE_NO_ADDR = 1, + READ_WITH_ADDR = 2, + WRITE_WITH_ADDR = 3 +}; + +struct intel_spi_op { + u8 op; + enum optype type; +}; + +struct intel_swseq_spi_config { + u8 opprefixes[2]; + struct intel_spi_op ops[8]; +}; + +void spi_finalize_ops(void); +void intel_southbridge_override_spi(struct intel_swseq_spi_config *spi_config); + +#endif