cxgb4: Add support for new flash parts

Add support for new flash parts identification, and
also cleanup the flash Part identifying and decoding
code.

Based on the original work of Casey Leedom <leedom@chelsio.com>

Signed-off-by: Ganesh Goudar <ganeshgr@chelsio.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Ganesh Goudar 2017-10-10 12:44:13 +05:30 committed by David S. Miller
parent 9f77fad3c2
commit 96ac18f14a
1 changed files with 118 additions and 22 deletions

View File

@ -8205,7 +8205,7 @@ struct flash_desc {
u32 size_mb; u32 size_mb;
}; };
static int get_flash_params(struct adapter *adap) static int t4_get_flash_params(struct adapter *adap)
{ {
/* Table for non-Numonix supported flash parts. Numonix parts are left /* Table for non-Numonix supported flash parts. Numonix parts are left
* to the preexisting code. All flash parts have 64KB sectors. * to the preexisting code. All flash parts have 64KB sectors.
@ -8214,40 +8214,136 @@ static int get_flash_params(struct adapter *adap)
{ 0x150201, 4 << 20 }, /* Spansion 4MB S25FL032P */ { 0x150201, 4 << 20 }, /* Spansion 4MB S25FL032P */
}; };
unsigned int part, manufacturer;
unsigned int density, size;
u32 flashid = 0;
int ret; int ret;
u32 info;
/* Issue a Read ID Command to the Flash part. We decode supported
* Flash parts and their sizes from this. There's a newer Query
* Command which can retrieve detailed geometry information but many
* Flash parts don't support it.
*/
ret = sf1_write(adap, 1, 1, 0, SF_RD_ID); ret = sf1_write(adap, 1, 1, 0, SF_RD_ID);
if (!ret) if (!ret)
ret = sf1_read(adap, 3, 0, 1, &info); ret = sf1_read(adap, 3, 0, 1, &flashid);
t4_write_reg(adap, SF_OP_A, 0); /* unlock SF */ t4_write_reg(adap, SF_OP_A, 0); /* unlock SF */
if (ret) if (ret)
return ret; return ret;
for (ret = 0; ret < ARRAY_SIZE(supported_flash); ++ret) /* Check to see if it's one of our non-standard supported Flash parts.
if (supported_flash[ret].vendor_and_model_id == info) { */
adap->params.sf_size = supported_flash[ret].size_mb; for (part = 0; part < ARRAY_SIZE(supported_flash); part++)
if (supported_flash[part].vendor_and_model_id == flashid) {
adap->params.sf_size = supported_flash[part].size_mb;
adap->params.sf_nsec = adap->params.sf_nsec =
adap->params.sf_size / SF_SEC_SIZE; adap->params.sf_size / SF_SEC_SIZE;
return 0; goto found;
} }
if ((info & 0xff) != 0x20) /* not a Numonix flash */ /* Decode Flash part size. The code below looks repetative with
return -EINVAL; * common encodings, but that's not guaranteed in the JEDEC
info >>= 16; /* log2 of size */ * specification for the Read JADEC ID command. The only thing that
if (info >= 0x14 && info < 0x18) * we're guaranteed by the JADEC specification is where the
adap->params.sf_nsec = 1 << (info - 16); * Manufacturer ID is in the returned result. After that each
else if (info == 0x18) * Manufacturer ~could~ encode things completely differently.
adap->params.sf_nsec = 64; * Note, all Flash parts must have 64KB sectors.
else */
return -EINVAL; manufacturer = flashid & 0xff;
adap->params.sf_size = 1 << info; switch (manufacturer) {
adap->params.sf_fw_start = case 0x20: { /* Micron/Numonix */
t4_read_reg(adap, CIM_BOOT_CFG_A) & BOOTADDR_M; /* This Density -> Size decoding table is taken from Micron
* Data Sheets.
*/
density = (flashid >> 16) & 0xff;
switch (density) {
case 0x14: /* 1MB */
size = 1 << 20;
break;
case 0x15: /* 2MB */
size = 1 << 21;
break;
case 0x16: /* 4MB */
size = 1 << 22;
break;
case 0x17: /* 8MB */
size = 1 << 23;
break;
case 0x18: /* 16MB */
size = 1 << 24;
break;
case 0x19: /* 32MB */
size = 1 << 25;
break;
case 0x20: /* 64MB */
size = 1 << 26;
break;
case 0x21: /* 128MB */
size = 1 << 27;
break;
case 0x22: /* 256MB */
size = 1 << 28;
break;
default:
dev_err(adap->pdev_dev, "Micron Flash Part has bad size, ID = %#x, Density code = %#x\n",
flashid, density);
return -EINVAL;
}
break;
}
case 0xc2: { /* Macronix */
/* This Density -> Size decoding table is taken from Macronix
* Data Sheets.
*/
density = (flashid >> 16) & 0xff;
switch (density) {
case 0x17: /* 8MB */
size = 1 << 23;
break;
case 0x18: /* 16MB */
size = 1 << 24;
break;
default:
dev_err(adap->pdev_dev, "Macronix Flash Part has bad size, ID = %#x, Density code = %#x\n",
flashid, density);
return -EINVAL;
}
}
case 0xef: { /* Winbond */
/* This Density -> Size decoding table is taken from Winbond
* Data Sheets.
*/
density = (flashid >> 16) & 0xff;
switch (density) {
case 0x17: /* 8MB */
size = 1 << 23;
break;
case 0x18: /* 16MB */
size = 1 << 24;
break;
default:
dev_err(adap->pdev_dev, "Winbond Flash Part has bad size, ID = %#x, Density code = %#x\n",
flashid, density);
return -EINVAL;
}
break;
}
default:
dev_err(adap->pdev_dev, "Unsupported Flash Part, ID = %#x\n",
flashid);
return -EINVAL;
}
/* Store decoded Flash size and fall through into vetting code. */
adap->params.sf_size = size;
adap->params.sf_nsec = size / SF_SEC_SIZE;
found:
if (adap->params.sf_size < FLASH_MIN_SIZE) if (adap->params.sf_size < FLASH_MIN_SIZE)
dev_warn(adap->pdev_dev, "WARNING!!! FLASH size %#x < %#x!!!\n", dev_warn(adap->pdev_dev, "WARNING: Flash Part ID %#x, size %#x < %#x\n",
adap->params.sf_size, FLASH_MIN_SIZE); flashid, adap->params.sf_size, FLASH_MIN_SIZE);
return 0; return 0;
} }
@ -8285,7 +8381,7 @@ int t4_prep_adapter(struct adapter *adapter)
get_pci_mode(adapter, &adapter->params.pci); get_pci_mode(adapter, &adapter->params.pci);
pl_rev = REV_G(t4_read_reg(adapter, PL_REV_A)); pl_rev = REV_G(t4_read_reg(adapter, PL_REV_A));
ret = get_flash_params(adapter); ret = t4_get_flash_params(adapter);
if (ret < 0) { if (ret < 0) {
dev_err(adapter->pdev_dev, "error %d identifying flash\n", ret); dev_err(adapter->pdev_dev, "error %d identifying flash\n", ret);
return ret; return ret;