Nikolai Artemiev has uploaded this change for review.

View Change

ichspi.c: read chip ID and use it to identify chip

BUG=b:253715389,b:253713774
BRANCH=none
TEST=builds

Change-Id: Ia408e1e45dc6f53c0934afd6558e301abfa48ee6
Signed-off-by: Nikolai Artemiev <nartemiev@google.com>
---
M ichspi.c
1 file changed, 80 insertions(+), 0 deletions(-)

git pull ssh://review.coreboot.org:29418/flashrom refs/changes/95/69195/1
diff --git a/ichspi.c b/ichspi.c
index 6d3535c..22fe7cd 100644
--- a/ichspi.c
+++ b/ichspi.c
@@ -132,6 +132,7 @@
#define HSFC_CYCLE_READ HSFC_FCYCLE_MASK(0)
#define HSFC_CYCLE_WRITE HSFC_FCYCLE_MASK(2)
#define HSFC_CYCLE_BLOCK_ERASE HSFC_FCYCLE_MASK(3)
+#define HSFC_CYCLE_RDID HSFC_FCYCLE_MASK(6)
#define HSFC_CYCLE_WR_STATUS HSFC_FCYCLE_MASK(7)
#define HSFC_CYCLE_RD_STATUS HSFC_FCYCLE_MASK(8)
/* 3-7: reserved */
@@ -1388,6 +1389,19 @@
return ich_hwseq_wait_for_cycle_complete(len, ich_gen, addr_mask);
}

+/* Given RDID info, return pointer to entry in flashchips[] */
+static const struct flashchip *flash_id_to_entry(uint32_t mfg_id, uint32_t model_id)
+{
+ const struct flashchip *chip;
+
+ for (chip = &flashchips[0]; chip->vendor; chip++) {
+ if ((chip->manufacture_id == mfg_id) && (chip->model_id == model_id))
+ return chip;
+ }
+
+ return NULL;
+}
+
static int ich_hwseq_read_status(const struct flashctx *flash, enum flash_reg reg, uint8_t *value)
{
const int len = 1;
@@ -1431,6 +1445,53 @@
return 0;
}

+static int ich_hwseq_get_flash_id(struct flashctx *flash, enum ich_chipset ich_gen)
+{
+ uint32_t data, mfg_id, model_id;
+ const struct flashchip *entry;
+ const int len = sizeof(data);
+ const struct hwseq_data *hwseq_data = get_hwseq_data_from_context(flash);
+
+ if (ich_exec_sync_hwseq_xfer(HSFC_CYCLE_RDID, 0, len, ich_generation,
+ hwseq_data->addr_mask)) {
+ msg_perr("Timed out waiting for RDID to complete.\n");
+ return 0;
+ }
+
+ /*
+ * Data will appear in reverse order:
+ * Byte 0: Manufacturer ID
+ * Byte 1: Model ID (MSB)
+ * Byte 2: Model ID (LSB)
+ */
+ ich_read_data((uint8_t *)&data, len, ICH9_REG_FDATA0);
+ mfg_id = data & 0xff;
+ model_id = (data & 0xff00) | ((data >> 16) & 0xff);
+
+ entry = flash_id_to_entry(mfg_id, model_id);
+ if (entry == NULL) {
+ msg_perr("Unable to identify chip, mfg_id: 0x%02x, "
+ "model_id: 0x%02x\n", mfg_id, model_id);
+ return 0;
+ } else {
+ msg_pdbg("Chip identified: %s\n", entry->name);
+ /* Update informational flash chip entries only */
+ flash->chip->vendor = entry->vendor;
+ flash->chip->name = entry->name;
+ flash->chip->manufacture_id = entry->manufacture_id;
+ flash->chip->model_id = entry->model_id;
+ /* total_size read from flash descriptor */
+ flash->chip->page_size = entry->page_size;
+ flash->chip->feature_bits = entry->feature_bits;
+ flash->chip->tested = entry->tested;
+ /* support writeprotect. */
+ flash->chip->reg_bits = entry->reg_bits;
+ flash->chip->decode_range = entry->decode_range;
+ }
+
+ return 1;
+}
+
static int ich_hwseq_probe(struct flashctx *flash)
{
uint32_t total_size, boundary;
@@ -1438,6 +1499,11 @@
struct block_eraser *eraser;
const struct hwseq_data *hwseq_data = get_hwseq_data_from_context(flash);

+ if (ich_hwseq_get_flash_id(flash, ich_generation) != 1) {
+ msg_perr("Unable to read flash chip ID\n");
+ return 0;
+ }
+
total_size = hwseq_data->size_comp0 + hwseq_data->size_comp1;
msg_cdbg("Hardware sequencing reports %d attached SPI flash chip",
(hwseq_data->size_comp1 != 0) ? 2 : 1);

To view, visit change 69195. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: flashrom
Gerrit-Branch: master
Gerrit-Change-Id: Ia408e1e45dc6f53c0934afd6558e301abfa48ee6
Gerrit-Change-Number: 69195
Gerrit-PatchSet: 1
Gerrit-Owner: Nikolai Artemiev <nartemiev@google.com>
Gerrit-MessageType: newchange