summaryrefslogtreecommitdiffstats
path: root/ichspi.c
diff options
context:
space:
mode:
authorCarl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net>2011-05-03 21:49:41 +0000
committerCarl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net>2011-05-03 21:49:41 +0000
commit54ce73a1f5c7ddecc7579c136dbac9c2c201b621 (patch)
treef24b7ce88dfdedbb3388cb3f6e4e44ee4e9f15f0 /ichspi.c
parent8ed293416dc3d47539dd95709f2b1dc0ccfe0736 (diff)
downloadast2050-flashrom-54ce73a1f5c7ddecc7579c136dbac9c2c201b621.zip
ast2050-flashrom-54ce73a1f5c7ddecc7579c136dbac9c2c201b621.tar.gz
Revert MMIO space writes on shutdown as needed
Reversible MMIO space writes now use rmmio_write*(). Reversible PCI MMIO space writes now use pci_rmmio_write*(). If a MMIO value needs to be queued for restore without writing it, use rmmio_val*(). MMIO space writes which are one-shot (e.g. communication with some chip) should continue to use the permanent mmio_write* variants. Corresponding to flashrom svn r1292. Signed-off-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net> David tested it successfully on some NM10/ICH7 platforms which switch between SPI and LPC targets (x86 BIOS ROM vs. EC firmware ROM). Acked-by: David Hendricks <dhendrix@google.com>
Diffstat (limited to 'ichspi.c')
-rw-r--r--ichspi.c50
1 files changed, 34 insertions, 16 deletions
diff --git a/ichspi.c b/ichspi.c
index 78c5422..f2814d1 100644
--- a/ichspi.c
+++ b/ichspi.c
@@ -163,7 +163,7 @@ static uint16_t REGREAD8(int X)
static int find_opcode(OPCODES *op, uint8_t opcode);
static int find_preop(OPCODES *op, uint8_t preop);
static int generate_opcodes(OPCODES * op);
-static int program_opcodes(OPCODES * op);
+static int program_opcodes(OPCODES *op, int enable_undo);
static int run_opcode(OPCODE op, uint32_t offset,
uint8_t datalength, uint8_t * data);
@@ -269,7 +269,7 @@ static int reprogram_opcode_on_the_fly(uint8_t opcode, unsigned int writecnt, un
int oppos=2; // use original JEDEC_BE_D8 offset
curopcodes->opcode[oppos].opcode = opcode;
curopcodes->opcode[oppos].spi_type = spi_type;
- program_opcodes(curopcodes);
+ program_opcodes(curopcodes, 0);
oppos = find_opcode(curopcodes, opcode);
msg_pdbg ("on-the-fly OPCODE (0x%02X) re-programmed, op-pos=%d\n", opcode, oppos);
return oppos;
@@ -357,7 +357,7 @@ static int generate_opcodes(OPCODES * op)
return 0;
}
-int program_opcodes(OPCODES * op)
+static int program_opcodes(OPCODES *op, int enable_undo)
{
uint8_t a;
uint16_t preop, optype;
@@ -391,16 +391,30 @@ int program_opcodes(OPCODES * op)
switch (spi_controller) {
case SPI_CONTROLLER_ICH7:
case SPI_CONTROLLER_VIA:
- REGWRITE16(ICH7_REG_PREOP, preop);
- REGWRITE16(ICH7_REG_OPTYPE, optype);
- REGWRITE32(ICH7_REG_OPMENU, opmenu[0]);
- REGWRITE32(ICH7_REG_OPMENU + 4, opmenu[1]);
+ /* Register undo only for enable_undo=1, i.e. first call. */
+ if (enable_undo) {
+ rmmio_valw(ich_spibar + ICH7_REG_PREOP);
+ rmmio_valw(ich_spibar + ICH7_REG_OPTYPE);
+ rmmio_vall(ich_spibar + ICH7_REG_OPMENU);
+ rmmio_vall(ich_spibar + ICH7_REG_OPMENU + 4);
+ }
+ mmio_writew(preop, ich_spibar + ICH7_REG_PREOP);
+ mmio_writew(optype, ich_spibar + ICH7_REG_OPTYPE);
+ mmio_writel(opmenu[0], ich_spibar + ICH7_REG_OPMENU);
+ mmio_writel(opmenu[1], ich_spibar + ICH7_REG_OPMENU + 4);
break;
case SPI_CONTROLLER_ICH9:
- REGWRITE16(ICH9_REG_PREOP, preop);
- REGWRITE16(ICH9_REG_OPTYPE, optype);
- REGWRITE32(ICH9_REG_OPMENU, opmenu[0]);
- REGWRITE32(ICH9_REG_OPMENU + 4, opmenu[1]);
+ /* Register undo only for enable_undo=1, i.e. first call. */
+ if (enable_undo) {
+ rmmio_valw(ich_spibar + ICH9_REG_PREOP);
+ rmmio_valw(ich_spibar + ICH9_REG_OPTYPE);
+ rmmio_vall(ich_spibar + ICH9_REG_OPMENU);
+ rmmio_vall(ich_spibar + ICH9_REG_OPMENU + 4);
+ }
+ mmio_writew(preop, ich_spibar + ICH9_REG_PREOP);
+ mmio_writew(optype, ich_spibar + ICH9_REG_OPTYPE);
+ mmio_writel(opmenu[0], ich_spibar + ICH9_REG_OPMENU);
+ mmio_writel(opmenu[1], ich_spibar + ICH9_REG_OPMENU + 4);
break;
default:
msg_perr("%s: unsupported chipset\n", __func__);
@@ -426,9 +440,11 @@ void ich_set_bbar(uint32_t minaddr)
msg_pdbg("Reserved bits in BBAR not zero: 0x%04x",
ichspi_bbar);
ichspi_bbar |= minaddr;
- mmio_writel(ichspi_bbar, ich_spibar + 0x50);
+ rmmio_writel(ichspi_bbar, ich_spibar + 0x50);
ichspi_bbar = mmio_readl(ich_spibar + 0x50);
- /* We don't have any option except complaining. */
+ /* We don't have any option except complaining. And if the write
+ * failed, the restore will fail as well, so no problem there.
+ */
if (ichspi_bbar != minaddr)
msg_perr("Setting BBAR failed!\n");
break;
@@ -438,9 +454,11 @@ void ich_set_bbar(uint32_t minaddr)
msg_pdbg("Reserved bits in BBAR not zero: 0x%04x",
ichspi_bbar);
ichspi_bbar |= minaddr;
- mmio_writel(ichspi_bbar, ich_spibar + 0xA0);
+ rmmio_writel(ichspi_bbar, ich_spibar + 0xA0);
ichspi_bbar = mmio_readl(ich_spibar + 0xA0);
- /* We don't have any option except complaining. */
+ /* We don't have any option except complaining. And if the write
+ * failed, the restore will fail as well, so no problem there.
+ */
if (ichspi_bbar != minaddr)
msg_perr("Setting BBAR failed!\n");
break;
@@ -470,7 +488,7 @@ static int ich_init_opcodes(void)
} else {
msg_pdbg("Programming OPCODES... ");
curopcodes_done = &O_ST_M25P;
- rc = program_opcodes(curopcodes_done);
+ rc = program_opcodes(curopcodes_done, 1);
/* Technically not part of opcode init, but it allows opcodes
* to run without transaction errors by setting the lowest
* allowed address to zero.
OpenPOWER on IntegriCloud