Drop nr/opcode_index parameter from run_opcode and search the opmenu for the opcode instead.
This is slightly slower (ha, ha), but works on boards with a locked opmenu. Tested on ICH7 and works. Signed-off-by: Stefan Reinauer <stepan@coresystems.de> Acked-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net> git-svn-id: svn://svn.coreboot.org/coreboot/trunk@3721 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
This commit is contained in:
parent
54c5276c3a
commit
d22ef49783
|
@ -148,7 +148,7 @@ static inline uint16_t REGREAD16(int X)
|
||||||
|
|
||||||
/* Common SPI functions */
|
/* Common SPI functions */
|
||||||
static int program_opcodes(OPCODES * op);
|
static int program_opcodes(OPCODES * op);
|
||||||
static int run_opcode(uint8_t nr, OPCODE op, uint32_t offset,
|
static int run_opcode(OPCODE op, uint32_t offset,
|
||||||
uint8_t datalength, uint8_t * data);
|
uint8_t datalength, uint8_t * data);
|
||||||
static int ich_spi_read_page(struct flashchip *flash, uint8_t * buf,
|
static int ich_spi_read_page(struct flashchip *flash, uint8_t * buf,
|
||||||
int offset, int maxdata);
|
int offset, int maxdata);
|
||||||
|
@ -225,7 +225,7 @@ int program_opcodes(OPCODES * op)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ich7_run_opcode(uint8_t nr, OPCODE op, uint32_t offset,
|
static int ich7_run_opcode(OPCODE op, uint32_t offset,
|
||||||
uint8_t datalength, uint8_t * data, int maxdata)
|
uint8_t datalength, uint8_t * data, int maxdata)
|
||||||
{
|
{
|
||||||
int write_cmd = 0;
|
int write_cmd = 0;
|
||||||
|
@ -233,6 +233,8 @@ static int ich7_run_opcode(uint8_t nr, OPCODE op, uint32_t offset,
|
||||||
uint32_t temp32 = 0;
|
uint32_t temp32 = 0;
|
||||||
uint16_t temp16;
|
uint16_t temp16;
|
||||||
uint32_t a;
|
uint32_t a;
|
||||||
|
uint64_t opmenu;
|
||||||
|
int opcode_index;
|
||||||
|
|
||||||
/* Is it a write command? */
|
/* Is it a write command? */
|
||||||
if ((op.spi_type == SPI_OPCODE_TYPE_WRITE_NO_ADDRESS)
|
if ((op.spi_type == SPI_OPCODE_TYPE_WRITE_NO_ADDRESS)
|
||||||
|
@ -280,7 +282,20 @@ static int ich7_run_opcode(uint8_t nr, OPCODE op, uint32_t offset,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Select opcode */
|
/* Select opcode */
|
||||||
temp16 |= ((uint16_t) (nr & 0x07)) << 4;
|
opmenu = REGREAD32(ICH7_REG_OPMENU);
|
||||||
|
opmenu |= ((uint64_t)REGREAD32(ICH7_REG_OPMENU + 4)) << 32;
|
||||||
|
|
||||||
|
for (opcode_index=0; opcode_index<8; opcode_index++) {
|
||||||
|
if((opmenu & 0xff) == op.opcode) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
opmenu >>= 8;
|
||||||
|
}
|
||||||
|
if (opcode_index == 8) {
|
||||||
|
printf_debug("Opcode %x not found.\n", op.opcode);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
temp16 |= ((uint16_t) (opcode_index & 0x07)) << 4;
|
||||||
|
|
||||||
/* Handle Atomic */
|
/* Handle Atomic */
|
||||||
if (op.atomic != 0) {
|
if (op.atomic != 0) {
|
||||||
|
@ -328,13 +343,15 @@ static int ich7_run_opcode(uint8_t nr, OPCODE op, uint32_t offset,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ich9_run_opcode(uint8_t nr, OPCODE op, uint32_t offset,
|
static int ich9_run_opcode(OPCODE op, uint32_t offset,
|
||||||
uint8_t datalength, uint8_t * data)
|
uint8_t datalength, uint8_t * data)
|
||||||
{
|
{
|
||||||
int write_cmd = 0;
|
int write_cmd = 0;
|
||||||
int timeout;
|
int timeout;
|
||||||
uint32_t temp32;
|
uint32_t temp32;
|
||||||
uint32_t a;
|
uint32_t a;
|
||||||
|
uint64_t opmenu;
|
||||||
|
int opcode_index;
|
||||||
|
|
||||||
/* Is it a write command? */
|
/* Is it a write command? */
|
||||||
if ((op.spi_type == SPI_OPCODE_TYPE_WRITE_NO_ADDRESS)
|
if ((op.spi_type == SPI_OPCODE_TYPE_WRITE_NO_ADDRESS)
|
||||||
|
@ -383,7 +400,20 @@ static int ich9_run_opcode(uint8_t nr, OPCODE op, uint32_t offset,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Select opcode */
|
/* Select opcode */
|
||||||
temp32 |= ((uint32_t) (nr & 0x07)) << (8 + 4);
|
opmenu = REGREAD32(ICH9_REG_OPMENU);
|
||||||
|
opmenu |= ((uint64_t)REGREAD32(ICH9_REG_OPMENU + 4)) << 32;
|
||||||
|
|
||||||
|
for (opcode_index=0; opcode_index<8; opcode_index++) {
|
||||||
|
if((opmenu & 0xff) == op.opcode) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
opmenu >>= 8;
|
||||||
|
}
|
||||||
|
if (opcode_index == 8) {
|
||||||
|
printf_debug("Opcode %x not found.\n", op.opcode);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
temp32 |= ((uint32_t) (opcode_index & 0x07)) << (8 + 4);
|
||||||
|
|
||||||
/* Handle Atomic */
|
/* Handle Atomic */
|
||||||
if (op.atomic != 0) {
|
if (op.atomic != 0) {
|
||||||
|
@ -431,16 +461,16 @@ static int ich9_run_opcode(uint8_t nr, OPCODE op, uint32_t offset,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int run_opcode(uint8_t nr, OPCODE op, uint32_t offset,
|
static int run_opcode(OPCODE op, uint32_t offset,
|
||||||
uint8_t datalength, uint8_t * data)
|
uint8_t datalength, uint8_t * data)
|
||||||
{
|
{
|
||||||
switch (flashbus) {
|
switch (flashbus) {
|
||||||
case BUS_TYPE_VIA_SPI:
|
case BUS_TYPE_VIA_SPI:
|
||||||
return ich7_run_opcode(nr, op, offset, datalength, data, 16);
|
return ich7_run_opcode(op, offset, datalength, data, 16);
|
||||||
case BUS_TYPE_ICH7_SPI:
|
case BUS_TYPE_ICH7_SPI:
|
||||||
return ich7_run_opcode(nr, op, offset, datalength, data, 64);
|
return ich7_run_opcode(op, offset, datalength, data, 64);
|
||||||
case BUS_TYPE_ICH9_SPI:
|
case BUS_TYPE_ICH9_SPI:
|
||||||
return ich9_run_opcode(nr, op, offset, datalength, data);
|
return ich9_run_opcode(op, offset, datalength, data);
|
||||||
default:
|
default:
|
||||||
printf_debug("%s: unsupported chipset\n", __FUNCTION__);
|
printf_debug("%s: unsupported chipset\n", __FUNCTION__);
|
||||||
}
|
}
|
||||||
|
@ -453,7 +483,7 @@ static int ich_spi_erase_block(struct flashchip *flash, int offset)
|
||||||
{
|
{
|
||||||
printf_debug("ich_spi_erase_block: offset=%d, sectors=%d\n", offset, 1);
|
printf_debug("ich_spi_erase_block: offset=%d, sectors=%d\n", offset, 1);
|
||||||
|
|
||||||
if (run_opcode(2, curopcodes->opcode[2], offset, 0, NULL) != 0) {
|
if (run_opcode(curopcodes->opcode[2], offset, 0, NULL) != 0) {
|
||||||
printf_debug("Error erasing sector at 0x%x", offset);
|
printf_debug("Error erasing sector at 0x%x", offset);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -477,7 +507,7 @@ static int ich_spi_read_page(struct flashchip *flash, uint8_t * buf, int offset,
|
||||||
if (remaining < maxdata) {
|
if (remaining < maxdata) {
|
||||||
|
|
||||||
if (run_opcode
|
if (run_opcode
|
||||||
(1, curopcodes->opcode[1],
|
(curopcodes->opcode[1],
|
||||||
offset + (page_size - remaining), remaining,
|
offset + (page_size - remaining), remaining,
|
||||||
&buf[page_size - remaining]) != 0) {
|
&buf[page_size - remaining]) != 0) {
|
||||||
printf_debug("Error reading");
|
printf_debug("Error reading");
|
||||||
|
@ -486,7 +516,7 @@ static int ich_spi_read_page(struct flashchip *flash, uint8_t * buf, int offset,
|
||||||
remaining = 0;
|
remaining = 0;
|
||||||
} else {
|
} else {
|
||||||
if (run_opcode
|
if (run_opcode
|
||||||
(1, curopcodes->opcode[1],
|
(curopcodes->opcode[1],
|
||||||
offset + (page_size - remaining), maxdata,
|
offset + (page_size - remaining), maxdata,
|
||||||
&buf[page_size - remaining]) != 0) {
|
&buf[page_size - remaining]) != 0) {
|
||||||
printf_debug("Error reading");
|
printf_debug("Error reading");
|
||||||
|
@ -512,7 +542,7 @@ static int ich_spi_write_page(struct flashchip *flash, uint8_t * bytes,
|
||||||
for (a = 0; a < page_size; a += maxdata) {
|
for (a = 0; a < page_size; a += maxdata) {
|
||||||
if (remaining < maxdata) {
|
if (remaining < maxdata) {
|
||||||
if (run_opcode
|
if (run_opcode
|
||||||
(0, curopcodes->opcode[0],
|
(curopcodes->opcode[0],
|
||||||
offset + (page_size - remaining), remaining,
|
offset + (page_size - remaining), remaining,
|
||||||
&bytes[page_size - remaining]) != 0) {
|
&bytes[page_size - remaining]) != 0) {
|
||||||
printf_debug("Error writing");
|
printf_debug("Error writing");
|
||||||
|
@ -521,7 +551,7 @@ static int ich_spi_write_page(struct flashchip *flash, uint8_t * bytes,
|
||||||
remaining = 0;
|
remaining = 0;
|
||||||
} else {
|
} else {
|
||||||
if (run_opcode
|
if (run_opcode
|
||||||
(0, curopcodes->opcode[0],
|
(curopcodes->opcode[0],
|
||||||
offset + (page_size - remaining), maxdata,
|
offset + (page_size - remaining), maxdata,
|
||||||
&bytes[page_size - remaining]) != 0) {
|
&bytes[page_size - remaining]) != 0) {
|
||||||
printf_debug("Error writing");
|
printf_debug("Error writing");
|
||||||
|
@ -641,7 +671,7 @@ int ich_spi_command(unsigned int writecnt, unsigned int readcnt,
|
||||||
count = readcnt;
|
count = readcnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (run_opcode(opcode_index, *opcode, addr, count, data) != 0) {
|
if (run_opcode(*opcode, addr, count, data) != 0) {
|
||||||
printf_debug("run OPCODE 0x%02x failed\n", opcode->opcode);
|
printf_debug("run OPCODE 0x%02x failed\n", opcode->opcode);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue