scsi: csiostor: update csio_get_flash_params()

- Updates csio_get_flash_params() to take care of ISSI, Macronix and
  Winbond FLASH parts.

- Assume flash part size to be 4MB if it cannot be identified

Signed-off-by: Arjun Vynipadath <arjun@chelsio.com>
Signed-off-by: Varun Prakash <varun@chelsio.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
Arjun Vynipadath 2018-08-01 17:17:12 +05:30 committed by Martin K. Petersen
parent 0ee223b2e1
commit 46a75118d6

View file

@ -761,27 +761,116 @@ csio_hw_fw_dload(struct csio_hw *hw, uint8_t *fw_data, uint32_t size)
static int static int
csio_hw_get_flash_params(struct csio_hw *hw) csio_hw_get_flash_params(struct csio_hw *hw)
{ {
/* Table for non-Numonix supported flash parts. Numonix parts are left
* to the preexisting code. All flash parts have 64KB sectors.
*/
static struct flash_desc {
u32 vendor_and_model_id;
u32 size_mb;
} supported_flash[] = {
{ 0x150201, 4 << 20 }, /* Spansion 4MB S25FL032P */
};
u32 part, manufacturer;
u32 density, size = 0;
u32 flashid = 0;
int ret; int ret;
uint32_t info = 0;
ret = csio_hw_sf1_write(hw, 1, 1, 0, SF_RD_ID); ret = csio_hw_sf1_write(hw, 1, 1, 0, SF_RD_ID);
if (!ret) if (!ret)
ret = csio_hw_sf1_read(hw, 3, 0, 1, &info); ret = csio_hw_sf1_read(hw, 3, 0, 1, &flashid);
csio_wr_reg32(hw, 0, SF_OP_A); /* unlock SF */ csio_wr_reg32(hw, 0, SF_OP_A); /* unlock SF */
if (ret != 0) if (ret)
return ret; return ret;
if ((info & 0xff) != 0x20) /* not a Numonix flash */ /* Check to see if it's one of our non-standard supported Flash parts.
return -EINVAL; */
info >>= 16; /* log2 of size */ for (part = 0; part < ARRAY_SIZE(supported_flash); part++)
if (info >= 0x14 && info < 0x18) if (supported_flash[part].vendor_and_model_id == flashid) {
hw->params.sf_nsec = 1 << (info - 16); hw->params.sf_size = supported_flash[part].size_mb;
else if (info == 0x18) hw->params.sf_nsec =
hw->params.sf_nsec = 64; hw->params.sf_size / SF_SEC_SIZE;
else goto found;
return -EINVAL; }
hw->params.sf_size = 1 << info;
/* Decode Flash part size. The code below looks repetative with
* common encodings, but that's not guaranteed in the JEDEC
* specification for the Read JADEC ID command. The only thing that
* we're guaranteed by the JADEC specification is where the
* Manufacturer ID is in the returned result. After that each
* Manufacturer ~could~ encode things completely differently.
* Note, all Flash parts must have 64KB sectors.
*/
manufacturer = flashid & 0xff;
switch (manufacturer) {
case 0x20: { /* Micron/Numonix */
/* This Density -> Size decoding table is taken from Micron
* Data Sheets.
*/
density = (flashid >> 16) & 0xff;
switch (density) {
case 0x14 ... 0x19: /* 1MB - 32MB */
size = 1 << density;
break;
case 0x20: /* 64MB */
size = 1 << 26;
break;
case 0x21: /* 128MB */
size = 1 << 27;
break;
case 0x22: /* 256MB */
size = 1 << 28;
}
break;
}
case 0x9d: { /* ISSI -- Integrated Silicon Solution, Inc. */
/* This Density -> Size decoding table is taken from ISSI
* Data Sheets.
*/
density = (flashid >> 16) & 0xff;
switch (density) {
case 0x16: /* 32 MB */
size = 1 << 25;
break;
case 0x17: /* 64MB */
size = 1 << 26;
}
break;
}
case 0xc2: /* Macronix */
case 0xef: /* Winbond */ {
/* This Density -> Size decoding table is taken from
* Macronix and Winbond Data Sheets.
*/
density = (flashid >> 16) & 0xff;
switch (density) {
case 0x17: /* 8MB */
case 0x18: /* 16MB */
size = 1 << density;
}
}
}
/* If we didn't recognize the FLASH part, that's no real issue: the
* Hardware/Software contract says that Hardware will _*ALWAYS*_
* use a FLASH part which is at least 4MB in size and has 64KB
* sectors. The unrecognized FLASH part is likely to be much larger
* than 4MB, but that's all we really need.
*/
if (size == 0) {
csio_warn(hw, "Unknown Flash Part, ID = %#x, assuming 4MB\n",
flashid);
size = 1 << 22;
}
/* Store decoded Flash size */
hw->params.sf_size = size;
hw->params.sf_nsec = size / SF_SEC_SIZE;
found:
if (hw->params.sf_size < FLASH_MIN_SIZE)
csio_warn(hw, "WARNING: Flash Part ID %#x, size %#x < %#x\n",
flashid, hw->params.sf_size, FLASH_MIN_SIZE);
return 0; return 0;
} }