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 коммит произвёл David S. Miller
Родитель 9f77fad3c2
Коммит 96ac18f14a
1 изменённых файлов: 118 добавлений и 22 удалений

Просмотреть файл

@ -8205,7 +8205,7 @@ struct flash_desc {
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
* 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 */
};
unsigned int part, manufacturer;
unsigned int density, size;
u32 flashid = 0;
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);
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 */
if (ret)
return ret;
for (ret = 0; ret < ARRAY_SIZE(supported_flash); ++ret)
if (supported_flash[ret].vendor_and_model_id == info) {
adap->params.sf_size = supported_flash[ret].size_mb;
/* Check to see if it's one of our non-standard supported Flash parts.
*/
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_size / SF_SEC_SIZE;
return 0;
goto found;
}
if ((info & 0xff) != 0x20) /* not a Numonix flash */
return -EINVAL;
info >>= 16; /* log2 of size */
if (info >= 0x14 && info < 0x18)
adap->params.sf_nsec = 1 << (info - 16);
else if (info == 0x18)
adap->params.sf_nsec = 64;
else
return -EINVAL;
adap->params.sf_size = 1 << info;
adap->params.sf_fw_start =
t4_read_reg(adap, CIM_BOOT_CFG_A) & BOOTADDR_M;
/* 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: /* 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)
dev_warn(adap->pdev_dev, "WARNING!!! FLASH size %#x < %#x!!!\n",
adap->params.sf_size, FLASH_MIN_SIZE);
dev_warn(adap->pdev_dev, "WARNING: Flash Part ID %#x, size %#x < %#x\n",
flashid, adap->params.sf_size, FLASH_MIN_SIZE);
return 0;
}
@ -8285,7 +8381,7 @@ int t4_prep_adapter(struct adapter *adapter)
get_pci_mode(adapter, &adapter->params.pci);
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) {
dev_err(adapter->pdev_dev, "error %d identifying flash\n", ret);
return ret;