Edward O'Callaghan has uploaded this change for review.
ichspi.c: Implement read_write_status for wp
The ichspi hwseq path has a opaque master specialisation that
allows for reading and writing STATUS1 registers. Hook the callbacks
with a implementation to allow for this so that writeprotect maybe
supported though this path.
Change-Id: I7ecbe8491ecea3697922c91af26ca62276e86317
Signed-off-by: Edward O'Callaghan <quasisec@google.com>
---
M ichspi.c
1 file changed, 73 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/flashrom refs/changes/40/64540/1
diff --git a/ichspi.c b/ichspi.c
index ce7004b..6b4e582 100644
--- a/ichspi.c
+++ b/ichspi.c
@@ -118,6 +118,16 @@
#define ICH9_REG_HSFC 0x06 /* 16 Bits Hardware Sequencing Flash Control */
#define HSFC_FGO_OFF 0 /* 0: Flash Cycle Go */
#define HSFC_FGO (0x1 << HSFC_FGO_OFF)
+
+/* FIXME(quasisec): Port to new macros? - Control bits */
+#define HSFSC_FGO_OFF 16 /* 0: Flash Cycle Go */
+#define HSFSC_FGO (0x1 << HSFSC_FGO_OFF)
+#define HSFSC_FCYCLE_OFF 17 /* 17-20: FLASH Cycle */
+#define HSFSC_FCYCLE (0xf << HSFSC_FCYCLE_OFF)
+#define HSFSC_FDBC_OFF 24 /* 24-29 : Flash Data Byte Count */
+#define HSFSC_FDBC (0x3f << HSFSC_FDBC_OFF)
+/*******/
+
/*
* 2 bits to represents the FCYCLE operation for ICH9 as:
* 0: SPI Read
@@ -1336,6 +1346,67 @@
return 0;
}
+static int ich_hwseq_read_status(const struct flashctx *flash, enum flash_reg reg_, uint8_t *value)
+{
+ uint32_t hsfc;
+ int len = 1;
+
+ msg_pdbg("Reading Status register\n");
+
+ /* clear FDONE, FCERR, AEL by writing 1 to them (if they are set) */
+ REGWRITE32(ICH9_REG_HSFS, REGREAD32(ICH9_REG_HSFS));
+
+ hsfc = REGREAD32(ICH9_REG_HSFS);
+ hsfc &= ~HSFSC_FCYCLE; /* set read operation */
+
+ /* read status register */
+ hsfc |= (0x8 << HSFSC_FCYCLE_OFF);
+
+ hsfc &= ~HSFSC_FDBC; /* clear byte count */
+ /* set byte count */
+ hsfc |= (((len - 1) << HSFSC_FDBC_OFF) & HSFSC_FDBC);
+ hsfc |= HSFSC_FGO; /* start */
+ REGWRITE32(ICH9_REG_HSFS, hsfc);
+ if (ich_hwseq_wait_for_cycle_complete(len, ich_generation)) {
+ msg_perr("Reading Status register failed\n!!");
+ return -1;
+ }
+ ich_read_data(value, len, ICH9_REG_FDATA0);
+
+ return 0;
+}
+
+static int ich_hwseq_write_status(const struct flashctx *flash, enum flash_reg reg_, uint8_t value)
+{
+ uint32_t hsfc;
+ int len = 1;
+
+ msg_pdbg("Writing status register\n");
+
+ /* clear FDONE, FCERR, AEL by writing 1 to them (if they are set) */
+ REGWRITE32(ICH9_REG_HSFS, REGREAD32(ICH9_REG_HSFS));
+
+ ich_fill_data(&value, len, ICH9_REG_FDATA0);
+ hsfc = REGREAD32(ICH9_REG_HSFS);
+ hsfc &= ~HSFSC_FCYCLE; /* clear operation */
+
+ /* write status register */
+ hsfc |= (0x7 << HSFSC_FCYCLE_OFF);
+ hsfc &= ~HSFSC_FDBC; /* clear byte count */
+
+ /* set byte count */
+ hsfc |= (((len - 1) << HSFSC_FDBC_OFF) & HSFSC_FDBC);
+ hsfc |= HSFSC_FGO; /* start */
+ REGWRITE32(ICH9_REG_HSFS, hsfc);
+
+ if (ich_hwseq_wait_for_cycle_complete(len, ich_generation)) {
+ msg_perr("Writing Status register failed\n!!");
+ return -1;
+ }
+
+ return 0;
+}
+
static int ich_hwseq_probe(struct flashctx *flash)
{
uint32_t total_size, boundary;
@@ -1744,6 +1815,8 @@
.read = ich_hwseq_read,
.write = ich_hwseq_write,
.erase = ich_hwseq_block_erase,
+ .read_status = ich_hwseq_read_status,
+ .write_status = ich_hwseq_write_status,
};
static int init_ich7_spi(void *spibar, enum ich_chipset ich_gen)
To view, visit change 64540. To unsubscribe, or for help writing mail filters, visit settings.