summaryrefslogtreecommitdiff
path: root/util/flashrom/ichspi.c
diff options
context:
space:
mode:
Diffstat (limited to 'util/flashrom/ichspi.c')
-rw-r--r--util/flashrom/ichspi.c800
1 files changed, 0 insertions, 800 deletions
diff --git a/util/flashrom/ichspi.c b/util/flashrom/ichspi.c
deleted file mode 100644
index 19f4b8066a..0000000000
--- a/util/flashrom/ichspi.c
+++ /dev/null
@@ -1,800 +0,0 @@
-/*
- * This file is part of the flashrom project.
- *
- * Copyright (C) 2008 Stefan Wildemann <stefan.wildemann@kontron.com>
- * Copyright (C) 2008 Claus Gindhart <claus.gindhart@kontron.com>
- * Copyright (C) 2008 Dominik Geyer <dominik.geyer@kontron.com>
- * Copyright (C) 2008 coresystems GmbH <info@coresystems.de>
- *
- * 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; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/*
- * This module is designed for supporting the devices
- * ST M25P40
- * ST M25P80
- * ST M25P16
- * ST M25P32 already tested
- * ST M25P64
- * AT 25DF321 already tested
- *
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <stdint.h>
-#include <sys/mman.h>
-#include <pci/pci.h>
-#include "flash.h"
-#include "spi.h"
-
-/* ICH9 controller register definition */
-#define ICH9_REG_FADDR 0x08 /* 32 Bits */
-#define ICH9_REG_FDATA0 0x10 /* 64 Bytes */
-
-#define ICH9_REG_SSFS 0x90 /* 08 Bits */
-#define SSFS_SCIP 0x00000001
-#define SSFS_CDS 0x00000004
-#define SSFS_FCERR 0x00000008
-#define SSFS_AEL 0x00000010
-
-#define ICH9_REG_SSFC 0x91 /* 24 Bits */
-#define SSFC_SCGO 0x00000200
-#define SSFC_ACS 0x00000400
-#define SSFC_SPOP 0x00000800
-#define SSFC_COP 0x00001000
-#define SSFC_DBC 0x00010000
-#define SSFC_DS 0x00400000
-#define SSFC_SME 0x00800000
-#define SSFC_SCF 0x01000000
-#define SSFC_SCF_20MHZ 0x00000000
-#define SSFC_SCF_33MHZ 0x01000000
-
-#define ICH9_REG_PREOP 0x94 /* 16 Bits */
-#define ICH9_REG_OPTYPE 0x96 /* 16 Bits */
-#define ICH9_REG_OPMENU 0x98 /* 64 Bits */
-
-// ICH9R SPI commands
-#define SPI_OPCODE_TYPE_READ_NO_ADDRESS 0
-#define SPI_OPCODE_TYPE_WRITE_NO_ADDRESS 1
-#define SPI_OPCODE_TYPE_READ_WITH_ADDRESS 2
-#define SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS 3
-
-// ICH7 registers
-#define ICH7_REG_SPIS 0x00 /* 16 Bits */
-#define SPIS_SCIP 0x00000001
-#define SPIS_CDS 0x00000004
-#define SPIS_FCERR 0x00000008
-
-/* VIA SPI is compatible with ICH7, but maxdata
- to transfer is 16 bytes.
-
- DATA byte count on ICH7 is 8:13, on VIA 8:11
-
- bit 12 is port select CS0 CS1
- bit 13 is FAST READ enable
- bit 7 is used with fast read and one shot controls CS de-assert?
-*/
-
-#define ICH7_REG_SPIC 0x02 /* 16 Bits */
-#define SPIC_SCGO 0x0002
-#define SPIC_ACS 0x0004
-#define SPIC_SPOP 0x0008
-#define SPIC_DS 0x4000
-
-#define ICH7_REG_SPIA 0x04 /* 32 Bits */
-#define ICH7_REG_SPID0 0x08 /* 64 Bytes */
-#define ICH7_REG_PREOP 0x54 /* 16 Bits */
-#define ICH7_REG_OPTYPE 0x56 /* 16 Bits */
-#define ICH7_REG_OPMENU 0x58 /* 64 Bits */
-
-/* ICH SPI configuration lock-down. May be set during chipset enabling. */
-int ichspi_lock = 0;
-
-typedef struct _OPCODE {
- uint8_t opcode; //This commands spi opcode
- uint8_t spi_type; //This commands spi type
- uint8_t atomic; //Use preop: (0: none, 1: preop0, 2: preop1
-} OPCODE;
-
-/* Opcode definition:
- * Preop 1: Write Enable
- * Preop 2: Write Status register enable
- *
- * OP 0: Write address
- * OP 1: Read Address
- * OP 2: ERASE block
- * OP 3: Read Status register
- * OP 4: Read ID
- * OP 5: Write Status register
- * OP 6: chip private (read JDEC id)
- * OP 7: Chip erase
- */
-typedef struct _OPCODES {
- uint8_t preop[2];
- OPCODE opcode[8];
-} OPCODES;
-
-static OPCODES *curopcodes = NULL;
-
-/* HW access functions */
-static inline uint32_t REGREAD32(int X)
-{
- volatile uint32_t regval;
- regval = *(volatile uint32_t *)((uint8_t *) spibar + X);
- return regval;
-}
-
-static inline uint16_t REGREAD16(int X)
-{
- volatile uint16_t regval;
- regval = *(volatile uint16_t *)((uint8_t *) spibar + X);
- return regval;
-}
-
-#define REGWRITE32(X,Y) (*(uint32_t *)((uint8_t *)spibar+X)=Y)
-#define REGWRITE16(X,Y) (*(uint16_t *)((uint8_t *)spibar+X)=Y)
-#define REGWRITE8(X,Y) (*(uint8_t *)((uint8_t *)spibar+X)=Y)
-
-/* Common SPI functions */
-static inline int find_opcode(OPCODES *op, uint8_t opcode);
-static inline int find_preop(OPCODES *op, uint8_t preop);
-static int generate_opcodes(OPCODES * op);
-static int program_opcodes(OPCODES * op);
-static int run_opcode(OPCODE op, uint32_t offset,
- uint8_t datalength, uint8_t * data);
-static int ich_spi_read_page(struct flashchip *flash, uint8_t * buf,
- int offset, int maxdata);
-static int ich_spi_write_page(struct flashchip *flash, uint8_t * bytes,
- int offset, int maxdata);
-
-/* for pairing opcodes with their required preop */
-struct preop_opcode_pair {
- uint8_t preop;
- uint8_t opcode;
-};
-
-struct preop_opcode_pair pops[] = {
- {JEDEC_WREN, JEDEC_BYTE_PROGRAM},
- {JEDEC_WREN, JEDEC_SE}, /* sector erase */
- {JEDEC_WREN, JEDEC_BE_52}, /* block erase */
- {JEDEC_WREN, JEDEC_BE_D8}, /* block erase */
- {JEDEC_WREN, JEDEC_CE_60}, /* chip erase */
- {JEDEC_WREN, JEDEC_CE_C7}, /* chip erase */
- {JEDEC_EWSR, JEDEC_WRSR},
- {0,}
-};
-
-OPCODES O_ST_M25P = {
- {
- JEDEC_WREN,
- 0},
- {
- {JEDEC_BYTE_PROGRAM, SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS, 1}, // Write Byte
- {JEDEC_READ, SPI_OPCODE_TYPE_READ_WITH_ADDRESS, 0}, // Read Data
- {JEDEC_BE_D8, SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS, 1}, // Erase Sector
- {JEDEC_RDSR, SPI_OPCODE_TYPE_READ_NO_ADDRESS, 0}, // Read Device Status Reg
- {JEDEC_RES, SPI_OPCODE_TYPE_READ_WITH_ADDRESS, 0}, // Resume Deep Power-Down
- {JEDEC_WRSR, SPI_OPCODE_TYPE_WRITE_NO_ADDRESS, 1}, // Write Status Register
- {JEDEC_RDID, SPI_OPCODE_TYPE_READ_NO_ADDRESS, 0}, // Read JDEC ID
- {JEDEC_CE_C7, SPI_OPCODE_TYPE_WRITE_NO_ADDRESS, 1}, // Bulk erase
- }
-};
-
-OPCODES O_EXISTING = {};
-
-static inline int find_opcode(OPCODES *op, uint8_t opcode)
-{
- int a;
-
- for (a = 0; a < 8; a++) {
- if (op->opcode[a].opcode == opcode)
- return a;
- }
-
- return -1;
-}
-
-static inline int find_preop(OPCODES *op, uint8_t preop)
-{
- int a;
-
- for (a = 0; a < 2; a++) {
- if (op->preop[a] == preop)
- return a;
- }
-
- return -1;
-}
-
-static int generate_opcodes(OPCODES * op)
-{
- int a, b, i;
- uint16_t preop, optype;
- uint32_t opmenu[2];
-
- if (op == NULL) {
- printf_debug("\n%s: null OPCODES pointer!\n", __FUNCTION__);
- return -1;
- }
-
- switch (flashbus) {
- case BUS_TYPE_ICH7_SPI:
- case BUS_TYPE_VIA_SPI:
- preop = REGREAD16(ICH7_REG_PREOP);
- optype = REGREAD16(ICH7_REG_OPTYPE);
- opmenu[0] = REGREAD32(ICH7_REG_OPMENU);
- opmenu[1] = REGREAD32(ICH7_REG_OPMENU + 4);
- break;
- case BUS_TYPE_ICH9_SPI:
- preop = REGREAD16(ICH9_REG_PREOP);
- optype = REGREAD16(ICH9_REG_OPTYPE);
- opmenu[0] = REGREAD32(ICH9_REG_OPMENU);
- opmenu[1] = REGREAD32(ICH9_REG_OPMENU + 4);
- break;
- default:
- printf_debug("%s: unsupported chipset\n", __FUNCTION__);
- return -1;
- }
-
- op->preop[0] = (uint8_t) preop;
- op->preop[1] = (uint8_t) (preop >> 8);
-
- for (a = 0; a < 8; a++) {
- op->opcode[a].spi_type = (uint8_t) (optype & 0x3);
- optype >>= 2;
- }
-
- for (a = 0; a < 4; a++) {
- op->opcode[a].opcode = (uint8_t) (opmenu[0] & 0xff);
- opmenu[0] >>= 8;
- }
-
- for (a = 4; a < 8; a++) {
- op->opcode[a].opcode = (uint8_t) (opmenu[1] & 0xff);
- opmenu[1] >>= 8;
- }
-
- /* atomic (link opcode with required pre-op) */
- for (a = 4; a < 8; a++)
- op->opcode[a].atomic = 0;
-
- for (i = 0; pops[i].opcode; i++) {
- a = find_opcode(op, pops[i].opcode);
- b = find_preop(op, pops[i].preop);
- if ((a != -1) && (b != -1))
- op->opcode[a].atomic = (uint8_t) ++b;
- }
-
- return 0;
-}
-
-int program_opcodes(OPCODES * op)
-{
- uint8_t a;
- uint16_t preop, optype;
- uint32_t opmenu[2];
-
- /* Program Prefix Opcodes */
- /* 0:7 Prefix Opcode 1 */
- preop = (op->preop[0]);
- /* 8:16 Prefix Opcode 2 */
- preop |= ((uint16_t) op->preop[1]) << 8;
-
- /* Program Opcode Types 0 - 7 */
- optype = 0;
- for (a = 0; a < 8; a++) {
- optype |= ((uint16_t) op->opcode[a].spi_type) << (a * 2);
- }
-
- /* Program Allowable Opcodes 0 - 3 */
- opmenu[0] = 0;
- for (a = 0; a < 4; a++) {
- opmenu[0] |= ((uint32_t) op->opcode[a].opcode) << (a * 8);
- }
-
- /*Program Allowable Opcodes 4 - 7 */
- opmenu[1] = 0;
- for (a = 4; a < 8; a++) {
- opmenu[1] |= ((uint32_t) op->opcode[a].opcode) << ((a - 4) * 8);
- }
-
- printf_debug("\n%s: preop=%04x optype=%04x opmenu=%08x%08x\n", __func__, preop, optype, opmenu[0], opmenu[1]);
- switch (flashbus) {
- case BUS_TYPE_ICH7_SPI:
- case BUS_TYPE_VIA_SPI:
- REGWRITE16(ICH7_REG_PREOP, preop);
- REGWRITE16(ICH7_REG_OPTYPE, optype);
- REGWRITE32(ICH7_REG_OPMENU, opmenu[0]);
- REGWRITE32(ICH7_REG_OPMENU + 4, opmenu[1]);
- break;
- case BUS_TYPE_ICH9_SPI:
- REGWRITE16(ICH9_REG_PREOP, preop);
- REGWRITE16(ICH9_REG_OPTYPE, optype);
- REGWRITE32(ICH9_REG_OPMENU, opmenu[0]);
- REGWRITE32(ICH9_REG_OPMENU + 4, opmenu[1]);
- break;
- default:
- printf_debug("%s: unsupported chipset\n", __FUNCTION__);
- return -1;
- }
-
- return 0;
-}
-
-/* This function generates OPCODES from or programs OPCODES to ICH according to
- * the chipset's SPI configuration lock.
- *
- * It should be called before ICH sends any spi command.
- */
-int ich_init_opcodes(void)
-{
- int rc = 0;
- OPCODES *curopcodes_done;
-
- if (curopcodes)
- return 0;
-
- if (ichspi_lock) {
- printf_debug("Generating OPCODES... ");
- curopcodes_done = &O_EXISTING;
- rc = generate_opcodes(curopcodes_done);
- } else {
- printf_debug("Programming OPCODES... ");
- curopcodes_done = &O_ST_M25P;
- rc = program_opcodes(curopcodes_done);
- }
-
- if (rc) {
- curopcodes = NULL;
- printf_debug("failed\n");
- return 1;
- } else {
- curopcodes = curopcodes_done;
- printf_debug("done\n");
- return 0;
- }
-}
-
-static int ich7_run_opcode(OPCODE op, uint32_t offset,
- uint8_t datalength, uint8_t * data, int maxdata)
-{
- int write_cmd = 0;
- int timeout;
- uint32_t temp32 = 0;
- uint16_t temp16;
- uint32_t a;
- uint64_t opmenu;
- int opcode_index;
-
- /* Is it a write command? */
- if ((op.spi_type == SPI_OPCODE_TYPE_WRITE_NO_ADDRESS)
- || (op.spi_type == SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS)) {
- write_cmd = 1;
- }
-
- /* Programm Offset in Flash into FADDR */
- REGWRITE32(ICH7_REG_SPIA, (offset & 0x00FFFFFF)); /* SPI addresses are 24 BIT only */
-
- /* Program data into FDATA0 to N */
- if (write_cmd && (datalength != 0)) {
- temp32 = 0;
- for (a = 0; a < datalength; a++) {
- if ((a % 4) == 0) {
- temp32 = 0;
- }
-
- temp32 |= ((uint32_t) data[a]) << ((a % 4) * 8);
-
- if ((a % 4) == 3) {
- REGWRITE32(ICH7_REG_SPID0 + (a - (a % 4)),
- temp32);
- }
- }
- if (((a - 1) % 4) != 3) {
- REGWRITE32(ICH7_REG_SPID0 +
- ((a - 1) - ((a - 1) % 4)), temp32);
- }
-
- }
-
- /* Assemble SPIS */
- temp16 = 0;
- /* clear error status registers */
- temp16 |= (SPIS_CDS + SPIS_FCERR);
- REGWRITE16(ICH7_REG_SPIS, temp16);
-
- /* Assemble SPIC */
- temp16 = 0;
-
- if (datalength != 0) {
- temp16 |= SPIC_DS;
- temp16 |= ((uint32_t) ((datalength - 1) & (maxdata - 1))) << 8;
- }
-
- /* Select opcode */
- 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 */
- if (op.atomic != 0) {
- /* Select atomic command */
- temp16 |= SPIC_ACS;
- /* Select prefix opcode */
- if ((op.atomic - 1) == 1) {
- /*Select prefix opcode 2 */
- temp16 |= SPIC_SPOP;
- }
- }
-
- /* Start */
- temp16 |= SPIC_SCGO;
-
- /* write it */
- REGWRITE16(ICH7_REG_SPIC, temp16);
-
- /* wait for cycle complete */
- timeout = 1000 * 60; // 60s is a looong timeout.
- while (((REGREAD16(ICH7_REG_SPIS) & SPIS_CDS) == 0) && --timeout) {
- myusec_delay(1000);
- }
- if (!timeout) {
- printf_debug("timeout\n");
- }
-
- if ((REGREAD16(ICH7_REG_SPIS) & SPIS_FCERR) != 0) {
- printf_debug("Transaction error!\n");
- return 1;
- }
-
- if ((!write_cmd) && (datalength != 0)) {
- for (a = 0; a < datalength; a++) {
- if ((a % 4) == 0) {
- temp32 = REGREAD32(ICH7_REG_SPID0 + (a));
- }
-
- data[a] =
- (temp32 & (((uint32_t) 0xff) << ((a % 4) * 8)))
- >> ((a % 4) * 8);
- }
- }
-
- return 0;
-}
-
-static int ich9_run_opcode(OPCODE op, uint32_t offset,
- uint8_t datalength, uint8_t * data)
-{
- int write_cmd = 0;
- int timeout;
- uint32_t temp32;
- uint32_t a;
- uint64_t opmenu;
- int opcode_index;
-
- /* Is it a write command? */
- if ((op.spi_type == SPI_OPCODE_TYPE_WRITE_NO_ADDRESS)
- || (op.spi_type == SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS)) {
- write_cmd = 1;
- }
-
- /* Programm Offset in Flash into FADDR */
- REGWRITE32(ICH9_REG_FADDR, (offset & 0x00FFFFFF)); /* SPI addresses are 24 BIT only */
-
- /* Program data into FDATA0 to N */
- if (write_cmd && (datalength != 0)) {
- temp32 = 0;
- for (a = 0; a < datalength; a++) {
- if ((a % 4) == 0) {
- temp32 = 0;
- }
-
- temp32 |= ((uint32_t) data[a]) << ((a % 4) * 8);
-
- if ((a % 4) == 3) {
- REGWRITE32(ICH9_REG_FDATA0 + (a - (a % 4)),
- temp32);
- }
- }
- if (((a - 1) % 4) != 3) {
- REGWRITE32(ICH9_REG_FDATA0 +
- ((a - 1) - ((a - 1) % 4)), temp32);
- }
- }
-
- /* Assemble SSFS + SSFC */
- temp32 = 0;
-
- /* clear error status registers */
- temp32 |= (SSFS_CDS + SSFS_FCERR);
- /* USE 20 MhZ */
- temp32 |= SSFC_SCF_20MHZ;
-
- if (datalength != 0) {
- uint32_t datatemp;
- temp32 |= SSFC_DS;
- datatemp = ((uint32_t) ((datalength - 1) & 0x3f)) << (8 + 8);
- temp32 |= datatemp;
- }
-
- /* Select opcode */
- 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 */
- if (op.atomic != 0) {
- /* Select atomic command */
- temp32 |= SSFC_ACS;
- /* Selct prefix opcode */
- if ((op.atomic - 1) == 1) {
- /*Select prefix opcode 2 */
- temp32 |= SSFC_SPOP;
- }
- }
-
- /* Start */
- temp32 |= SSFC_SCGO;
-
- /* write it */
- REGWRITE32(ICH9_REG_SSFS, temp32);
-
- /*wait for cycle complete */
- timeout = 1000 * 60; // 60s is a looong timeout.
- while (((REGREAD32(ICH9_REG_SSFS) & SSFS_CDS) == 0) && --timeout) {
- myusec_delay(1000);
- }
- if (!timeout) {
- printf_debug("timeout\n");
- }
-
- if ((REGREAD32(ICH9_REG_SSFS) & SSFS_FCERR) != 0) {
- printf_debug("Transaction error!\n");
- return 1;
- }
-
- if ((!write_cmd) && (datalength != 0)) {
- for (a = 0; a < datalength; a++) {
- if ((a % 4) == 0) {
- temp32 = REGREAD32(ICH9_REG_FDATA0 + (a));
- }
-
- data[a] =
- (temp32 & (((uint32_t) 0xff) << ((a % 4) * 8)))
- >> ((a % 4) * 8);
- }
- }
-
- return 0;
-}
-
-static int run_opcode(OPCODE op, uint32_t offset,
- uint8_t datalength, uint8_t * data)
-{
- switch (flashbus) {
- case BUS_TYPE_VIA_SPI:
- return ich7_run_opcode(op, offset, datalength, data, 16);
- case BUS_TYPE_ICH7_SPI:
- return ich7_run_opcode(op, offset, datalength, data, 64);
- case BUS_TYPE_ICH9_SPI:
- return ich9_run_opcode(op, offset, datalength, data);
- default:
- printf_debug("%s: unsupported chipset\n", __FUNCTION__);
- }
-
- /* If we ever get here, something really weird happened */
- return -1;
-}
-
-static int ich_spi_read_page(struct flashchip *flash, uint8_t * buf, int offset,
- int maxdata)
-{
- int page_size = flash->page_size;
- uint32_t remaining = flash->page_size;
- int a;
-
- printf_debug("ich_spi_read_page: offset=%d, number=%d, buf=%p\n",
- offset, page_size, buf);
-
- for (a = 0; a < page_size; a += maxdata) {
- if (remaining < maxdata) {
-
- if (spi_nbyte_read(offset + (page_size - remaining),
- &buf[page_size - remaining], remaining)) {
- printf_debug("Error reading");
- return 1;
- }
- remaining = 0;
- } else {
- if (spi_nbyte_read(offset + (page_size - remaining),
- &buf[page_size - remaining], maxdata)) {
- printf_debug("Error reading");
- return 1;
- }
- remaining -= maxdata;
- }
- }
-
- return 0;
-}
-
-static int ich_spi_write_page(struct flashchip *flash, uint8_t * bytes,
- int offset, int maxdata)
-{
- int page_size = flash->page_size;
- uint32_t remaining = page_size;
- int a;
-
- printf_debug("ich_spi_write_page: offset=%d, number=%d, buf=%p\n",
- offset, page_size, bytes);
-
- for (a = 0; a < page_size; a += maxdata) {
- if (remaining < maxdata) {
- if (run_opcode
- (curopcodes->opcode[0],
- offset + (page_size - remaining), remaining,
- &bytes[page_size - remaining]) != 0) {
- printf_debug("Error writing");
- return 1;
- }
- remaining = 0;
- } else {
- if (run_opcode
- (curopcodes->opcode[0],
- offset + (page_size - remaining), maxdata,
- &bytes[page_size - remaining]) != 0) {
- printf_debug("Error writing");
- return 1;
- }
- remaining -= maxdata;
- }
- }
-
- return 0;
-}
-
-int ich_spi_read(struct flashchip *flash, uint8_t * buf)
-{
- int i, rc = 0;
- int total_size = flash->total_size * 1024;
- int page_size = flash->page_size;
- int maxdata = 64;
-
- if (flashbus == BUS_TYPE_VIA_SPI) {
- maxdata = 16;
- }
-
- for (i = 0; (i < total_size / page_size) && (rc == 0); i++) {
- rc = ich_spi_read_page(flash, (void *)(buf + i * page_size),
- i * page_size, maxdata);
- }
-
- return rc;
-}
-
-int ich_spi_write(struct flashchip *flash, uint8_t * buf)
-{
- int i, j, rc = 0;
- int total_size = flash->total_size * 1024;
- int page_size = flash->page_size;
- int erase_size = 64 * 1024;
- int maxdata = 64;
-
- spi_disable_blockprotect();
-
- printf("Programming page: \n");
-
- for (i = 0; i < total_size / erase_size; i++) {
- /* FIMXE: call the chip-specific spi_block_erase_XX instead.
- * For this, we need to add a block erase function to
- * struct flashchip.
- */
- rc = spi_block_erase_d8(flash, i * erase_size);
- if (rc) {
- printf("Error erasing block at 0x%x\n", i);
- break;
- }
-
- if (flashbus == BUS_TYPE_VIA_SPI)
- maxdata = 16;
-
- for (j = 0; j < erase_size / page_size; j++) {
- ich_spi_write_page(flash,
- (void *)(buf + (i * erase_size) + (j * page_size)),
- (i * erase_size) + (j * page_size), maxdata);
- }
- }
-
- printf("\n");
-
- return rc;
-}
-
-int ich_spi_command(unsigned int writecnt, unsigned int readcnt,
- const unsigned char *writearr, unsigned char *readarr)
-{
- int a;
- int opcode_index = -1;
- const unsigned char cmd = *writearr;
- OPCODE *opcode;
- uint32_t addr = 0;
- uint8_t *data;
- int count;
-
- /* find cmd in opcodes-table */
- for (a = 0; a < 8; a++) {
- if ((curopcodes->opcode[a]).opcode == cmd) {
- opcode_index = a;
- break;
- }
- }
-
- /* unknown / not programmed command */
- if (opcode_index == -1) {
- printf_debug("Invalid OPCODE 0x%02x\n", cmd);
- return 1;
- }
-
- opcode = &(curopcodes->opcode[opcode_index]);
-
- /* if opcode-type requires an address */
- if (opcode->spi_type == SPI_OPCODE_TYPE_READ_WITH_ADDRESS ||
- opcode->spi_type == SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS) {
- addr = (writearr[1] << 16) |
- (writearr[2] << 8) | (writearr[3] << 0);
- }
-
- /* translate read/write array/count */
- if (opcode->spi_type == SPI_OPCODE_TYPE_WRITE_NO_ADDRESS) {
- data = (uint8_t *) (writearr + 1);
- count = writecnt - 1;
- } else if (opcode->spi_type == SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS) {
- data = (uint8_t *) (writearr + 4);
- count = writecnt - 4;
- } else {
- data = (uint8_t *) readarr;
- count = readcnt;
- }
-
- if (run_opcode(*opcode, addr, count, data) != 0) {
- printf_debug("run OPCODE 0x%02x failed\n", opcode->opcode);
- return 1;
- }
-
- return 0;
-}