summaryrefslogtreecommitdiff
path: root/src/southbridge
diff options
context:
space:
mode:
Diffstat (limited to 'src/southbridge')
-rw-r--r--src/southbridge/intel/common/spi.c41
-rw-r--r--src/southbridge/intel/common/spi.h38
2 files changed, 79 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),
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