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 19*39cd206cSRafał 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 30*39cd206cSRafał 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 48*39cd206cSRafał 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*39cd206cSRafał Miłecki const struct ssb_sflash_tbl_e *e; 7759015278SRafał Miłecki u32 id, id2; 7859015278SRafał Miłecki 7959015278SRafał Miłecki switch (cc->capabilities & SSB_CHIPCO_CAP_FLASHT) { 8059015278SRafał Miłecki case SSB_CHIPCO_FLASHT_STSER: 8159015278SRafał Miłecki ssb_sflash_cmd(cc, SSB_CHIPCO_FLASHCTL_ST_DP); 8259015278SRafał Miłecki 8359015278SRafał Miłecki chipco_write32(cc, SSB_CHIPCO_FLASHADDR, 0); 8459015278SRafał Miłecki ssb_sflash_cmd(cc, SSB_CHIPCO_FLASHCTL_ST_RES); 8559015278SRafał Miłecki id = chipco_read32(cc, SSB_CHIPCO_FLASHDATA); 8659015278SRafał Miłecki 8759015278SRafał Miłecki chipco_write32(cc, SSB_CHIPCO_FLASHADDR, 1); 8859015278SRafał Miłecki ssb_sflash_cmd(cc, SSB_CHIPCO_FLASHCTL_ST_RES); 8959015278SRafał Miłecki id2 = chipco_read32(cc, SSB_CHIPCO_FLASHDATA); 9059015278SRafał Miłecki 9159015278SRafał Miłecki switch (id) { 9259015278SRafał Miłecki case 0xbf: 9359015278SRafał Miłecki for (e = ssb_sflash_sst_tbl; e->name; e++) { 9459015278SRafał Miłecki if (e->id == id2) 9559015278SRafał Miłecki break; 9659015278SRafał Miłecki } 9759015278SRafał Miłecki break; 9859015278SRafał Miłecki case 0x13: 9959015278SRafał Miłecki return -ENOTSUPP; 10059015278SRafał Miłecki default: 10159015278SRafał Miłecki for (e = ssb_sflash_st_tbl; e->name; e++) { 10259015278SRafał Miłecki if (e->id == id) 10359015278SRafał Miłecki break; 10459015278SRafał Miłecki } 10559015278SRafał Miłecki break; 10659015278SRafał Miłecki } 10759015278SRafał Miłecki if (!e->name) { 10859015278SRafał Miłecki pr_err("Unsupported ST serial flash (id: 0x%X, id2: 0x%X)\n", 10959015278SRafał Miłecki id, id2); 11059015278SRafał Miłecki return -ENOTSUPP; 11159015278SRafał Miłecki } 11259015278SRafał Miłecki 11359015278SRafał Miłecki break; 11459015278SRafał Miłecki case SSB_CHIPCO_FLASHT_ATSER: 11559015278SRafał Miłecki ssb_sflash_cmd(cc, SSB_CHIPCO_FLASHCTL_AT_STATUS); 11659015278SRafał Miłecki id = chipco_read32(cc, SSB_CHIPCO_FLASHDATA) & 0x3c; 11759015278SRafał Miłecki 11859015278SRafał Miłecki for (e = ssb_sflash_at_tbl; e->name; e++) { 11959015278SRafał Miłecki if (e->id == id) 12059015278SRafał Miłecki break; 12159015278SRafał Miłecki } 12259015278SRafał Miłecki if (!e->name) { 12359015278SRafał Miłecki pr_err("Unsupported Atmel serial flash (id: 0x%X)\n", 12459015278SRafał Miłecki id); 12559015278SRafał Miłecki return -ENOTSUPP; 12659015278SRafał Miłecki } 12759015278SRafał Miłecki 12859015278SRafał Miłecki break; 12959015278SRafał Miłecki default: 13059015278SRafał Miłecki pr_err("Unsupported flash type\n"); 13159015278SRafał Miłecki return -ENOTSUPP; 13259015278SRafał Miłecki } 13359015278SRafał Miłecki 13459015278SRafał Miłecki pr_info("Found %s serial flash (blocksize: 0x%X, blocks: %d)\n", 13559015278SRafał Miłecki e->name, e->blocksize, e->numblocks); 13659015278SRafał Miłecki 13772a525cbSRafał Miłecki pr_err("Serial flash support is not implemented yet!\n"); 13872a525cbSRafał Miłecki 13972a525cbSRafał Miłecki return -ENOTSUPP; 14072a525cbSRafał Miłecki } 141