172a525cbSRafał Miłecki /* 272a525cbSRafał Miłecki * Sonics Silicon Backplane 372a525cbSRafał Miłecki * ChipCommon serial flash interface 472a525cbSRafał Miłecki * 572a525cbSRafał Miłecki * Licensed under the GNU/GPL. See COPYING for details. 672a525cbSRafał Miłecki */ 772a525cbSRafał Miłecki 872a525cbSRafał Miłecki #include <linux/ssb/ssb.h> 972a525cbSRafał Miłecki 1072a525cbSRafał Miłecki #include "ssb_private.h" 1172a525cbSRafał Miłecki 1259015278SRafał Miłecki struct ssb_sflash_tbl_e { 1359015278SRafał Miłecki char *name; 1459015278SRafał Miłecki u32 id; 1559015278SRafał Miłecki u32 blocksize; 1659015278SRafał Miłecki u16 numblocks; 1759015278SRafał Miłecki }; 1859015278SRafał Miłecki 1939cd206cSRafał Miłecki static const struct ssb_sflash_tbl_e ssb_sflash_st_tbl[] = { 2059015278SRafał Miłecki { "M25P20", 0x11, 0x10000, 4, }, 2159015278SRafał Miłecki { "M25P40", 0x12, 0x10000, 8, }, 2259015278SRafał Miłecki 2359015278SRafał Miłecki { "M25P16", 0x14, 0x10000, 32, }, 2459015278SRafał Miłecki { "M25P32", 0x15, 0x10000, 64, }, 2559015278SRafał Miłecki { "M25P64", 0x16, 0x10000, 128, }, 2659015278SRafał Miłecki { "M25FL128", 0x17, 0x10000, 256, }, 2759015278SRafał Miłecki { 0 }, 2859015278SRafał Miłecki }; 2959015278SRafał Miłecki 3039cd206cSRafał Miłecki static const struct ssb_sflash_tbl_e ssb_sflash_sst_tbl[] = { 3159015278SRafał Miłecki { "SST25WF512", 1, 0x1000, 16, }, 3259015278SRafał Miłecki { "SST25VF512", 0x48, 0x1000, 16, }, 3359015278SRafał Miłecki { "SST25WF010", 2, 0x1000, 32, }, 3459015278SRafał Miłecki { "SST25VF010", 0x49, 0x1000, 32, }, 3559015278SRafał Miłecki { "SST25WF020", 3, 0x1000, 64, }, 3659015278SRafał Miłecki { "SST25VF020", 0x43, 0x1000, 64, }, 3759015278SRafał Miłecki { "SST25WF040", 4, 0x1000, 128, }, 3859015278SRafał Miłecki { "SST25VF040", 0x44, 0x1000, 128, }, 3959015278SRafał Miłecki { "SST25VF040B", 0x8d, 0x1000, 128, }, 4059015278SRafał Miłecki { "SST25WF080", 5, 0x1000, 256, }, 4159015278SRafał Miłecki { "SST25VF080B", 0x8e, 0x1000, 256, }, 4259015278SRafał Miłecki { "SST25VF016", 0x41, 0x1000, 512, }, 4359015278SRafał Miłecki { "SST25VF032", 0x4a, 0x1000, 1024, }, 4459015278SRafał Miłecki { "SST25VF064", 0x4b, 0x1000, 2048, }, 4559015278SRafał Miłecki { 0 }, 4659015278SRafał Miłecki }; 4759015278SRafał Miłecki 4839cd206cSRafał Miłecki static const struct ssb_sflash_tbl_e ssb_sflash_at_tbl[] = { 4959015278SRafał Miłecki { "AT45DB011", 0xc, 256, 512, }, 5059015278SRafał Miłecki { "AT45DB021", 0x14, 256, 1024, }, 5159015278SRafał Miłecki { "AT45DB041", 0x1c, 256, 2048, }, 5259015278SRafał Miłecki { "AT45DB081", 0x24, 256, 4096, }, 5359015278SRafał Miłecki { "AT45DB161", 0x2c, 512, 4096, }, 5459015278SRafał Miłecki { "AT45DB321", 0x34, 512, 8192, }, 5559015278SRafał Miłecki { "AT45DB642", 0x3c, 1024, 8192, }, 5659015278SRafał Miłecki { 0 }, 5759015278SRafał Miłecki }; 5859015278SRafał Miłecki 5959015278SRafał Miłecki static void ssb_sflash_cmd(struct ssb_chipcommon *cc, u32 opcode) 6059015278SRafał Miłecki { 6159015278SRafał Miłecki int i; 6259015278SRafał Miłecki chipco_write32(cc, SSB_CHIPCO_FLASHCTL, 6359015278SRafał Miłecki SSB_CHIPCO_FLASHCTL_START | opcode); 6459015278SRafał Miłecki for (i = 0; i < 1000; i++) { 6559015278SRafał Miłecki if (!(chipco_read32(cc, SSB_CHIPCO_FLASHCTL) & 6659015278SRafał Miłecki SSB_CHIPCO_FLASHCTL_BUSY)) 6759015278SRafał Miłecki return; 6859015278SRafał Miłecki cpu_relax(); 6959015278SRafał Miłecki } 7059015278SRafał Miłecki pr_err("SFLASH control command failed (timeout)!\n"); 7159015278SRafał Miłecki } 7259015278SRafał Miłecki 7372a525cbSRafał Miłecki /* Initialize serial flash access */ 7472a525cbSRafał Miłecki int ssb_sflash_init(struct ssb_chipcommon *cc) 7572a525cbSRafał Miłecki { 76*e570bd04SRafał Miłecki struct ssb_sflash *sflash = &cc->dev->bus->mipscore.sflash; 7739cd206cSRafał Miłecki const struct ssb_sflash_tbl_e *e; 7859015278SRafał Miłecki u32 id, id2; 7959015278SRafał Miłecki 8059015278SRafał Miłecki switch (cc->capabilities & SSB_CHIPCO_CAP_FLASHT) { 8159015278SRafał Miłecki case SSB_CHIPCO_FLASHT_STSER: 8259015278SRafał Miłecki ssb_sflash_cmd(cc, SSB_CHIPCO_FLASHCTL_ST_DP); 8359015278SRafał Miłecki 8459015278SRafał Miłecki chipco_write32(cc, SSB_CHIPCO_FLASHADDR, 0); 8559015278SRafał Miłecki ssb_sflash_cmd(cc, SSB_CHIPCO_FLASHCTL_ST_RES); 8659015278SRafał Miłecki id = chipco_read32(cc, SSB_CHIPCO_FLASHDATA); 8759015278SRafał Miłecki 8859015278SRafał Miłecki chipco_write32(cc, SSB_CHIPCO_FLASHADDR, 1); 8959015278SRafał Miłecki ssb_sflash_cmd(cc, SSB_CHIPCO_FLASHCTL_ST_RES); 9059015278SRafał Miłecki id2 = chipco_read32(cc, SSB_CHIPCO_FLASHDATA); 9159015278SRafał Miłecki 9259015278SRafał Miłecki switch (id) { 9359015278SRafał Miłecki case 0xbf: 9459015278SRafał Miłecki for (e = ssb_sflash_sst_tbl; e->name; e++) { 9559015278SRafał Miłecki if (e->id == id2) 9659015278SRafał Miłecki break; 9759015278SRafał Miłecki } 9859015278SRafał Miłecki break; 9959015278SRafał Miłecki case 0x13: 10059015278SRafał Miłecki return -ENOTSUPP; 10159015278SRafał Miłecki default: 10259015278SRafał Miłecki for (e = ssb_sflash_st_tbl; e->name; e++) { 10359015278SRafał Miłecki if (e->id == id) 10459015278SRafał Miłecki break; 10559015278SRafał Miłecki } 10659015278SRafał Miłecki break; 10759015278SRafał Miłecki } 10859015278SRafał Miłecki if (!e->name) { 10959015278SRafał Miłecki pr_err("Unsupported ST serial flash (id: 0x%X, id2: 0x%X)\n", 11059015278SRafał Miłecki id, id2); 11159015278SRafał Miłecki return -ENOTSUPP; 11259015278SRafał Miłecki } 11359015278SRafał Miłecki 11459015278SRafał Miłecki break; 11559015278SRafał Miłecki case SSB_CHIPCO_FLASHT_ATSER: 11659015278SRafał Miłecki ssb_sflash_cmd(cc, SSB_CHIPCO_FLASHCTL_AT_STATUS); 11759015278SRafał Miłecki id = chipco_read32(cc, SSB_CHIPCO_FLASHDATA) & 0x3c; 11859015278SRafał Miłecki 11959015278SRafał Miłecki for (e = ssb_sflash_at_tbl; e->name; e++) { 12059015278SRafał Miłecki if (e->id == id) 12159015278SRafał Miłecki break; 12259015278SRafał Miłecki } 12359015278SRafał Miłecki if (!e->name) { 12459015278SRafał Miłecki pr_err("Unsupported Atmel serial flash (id: 0x%X)\n", 12559015278SRafał Miłecki id); 12659015278SRafał Miłecki return -ENOTSUPP; 12759015278SRafał Miłecki } 12859015278SRafał Miłecki 12959015278SRafał Miłecki break; 13059015278SRafał Miłecki default: 13159015278SRafał Miłecki pr_err("Unsupported flash type\n"); 13259015278SRafał Miłecki return -ENOTSUPP; 13359015278SRafał Miłecki } 13459015278SRafał Miłecki 135*e570bd04SRafał Miłecki sflash->window = SSB_FLASH2; 136*e570bd04SRafał Miłecki sflash->blocksize = e->blocksize; 137*e570bd04SRafał Miłecki sflash->numblocks = e->numblocks; 138*e570bd04SRafał Miłecki sflash->size = sflash->blocksize * sflash->numblocks; 139*e570bd04SRafał Miłecki sflash->present = true; 140*e570bd04SRafał Miłecki 14159015278SRafał Miłecki pr_info("Found %s serial flash (blocksize: 0x%X, blocks: %d)\n", 14259015278SRafał Miłecki e->name, e->blocksize, e->numblocks); 14359015278SRafał Miłecki 14472a525cbSRafał Miłecki pr_err("Serial flash support is not implemented yet!\n"); 14572a525cbSRafał Miłecki 14672a525cbSRafał Miłecki return -ENOTSUPP; 14772a525cbSRafał Miłecki } 148