Home | History | Annotate | Download | only in mtd
      1 // SPDX-License-Identifier: GPL-2.0+
      2 /*
      3  * (C) Copyright 2009
      4  * Vipin Kumar, ST Microelectronics, vipin.kumar (at) st.com.
      5  */
      6 
      7 #include <common.h>
      8 #include <flash.h>
      9 #include <linux/err.h>
     10 #include <linux/mtd/st_smi.h>
     11 
     12 #include <asm/io.h>
     13 #include <asm/arch/hardware.h>
     14 
     15 #if defined(CONFIG_MTD_NOR_FLASH)
     16 
     17 static struct smi_regs *const smicntl =
     18     (struct smi_regs * const)CONFIG_SYS_SMI_BASE;
     19 static ulong bank_base[CONFIG_SYS_MAX_FLASH_BANKS] =
     20     CONFIG_SYS_FLASH_ADDR_BASE;
     21 flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS];
     22 
     23 /* data structure to maintain flash ids from different vendors */
     24 struct flash_device {
     25 	char *name;
     26 	u8 erase_cmd;
     27 	u32 device_id;
     28 	u32 pagesize;
     29 	unsigned long sectorsize;
     30 	unsigned long size_in_bytes;
     31 };
     32 
     33 #define FLASH_ID(n, es, id, psize, ssize, size)	\
     34 {				\
     35 	.name = n,		\
     36 	.erase_cmd = es,	\
     37 	.device_id = id,	\
     38 	.pagesize = psize,	\
     39 	.sectorsize = ssize,	\
     40 	.size_in_bytes = size	\
     41 }
     42 
     43 /*
     44  * List of supported flash devices.
     45  * Currently the erase_cmd field is not used in this driver.
     46  */
     47 static struct flash_device flash_devices[] = {
     48 	FLASH_ID("st m25p16"     , 0xd8, 0x00152020, 0x100, 0x10000, 0x200000),
     49 	FLASH_ID("st m25p32"     , 0xd8, 0x00162020, 0x100, 0x10000, 0x400000),
     50 	FLASH_ID("st m25p64"     , 0xd8, 0x00172020, 0x100, 0x10000, 0x800000),
     51 	FLASH_ID("st m25p128"    , 0xd8, 0x00182020, 0x100, 0x40000, 0x1000000),
     52 	FLASH_ID("st m25p05"     , 0xd8, 0x00102020, 0x80 , 0x8000 , 0x10000),
     53 	FLASH_ID("st m25p10"     , 0xd8, 0x00112020, 0x80 , 0x8000 , 0x20000),
     54 	FLASH_ID("st m25p20"     , 0xd8, 0x00122020, 0x100, 0x10000, 0x40000),
     55 	FLASH_ID("st m25p40"     , 0xd8, 0x00132020, 0x100, 0x10000, 0x80000),
     56 	FLASH_ID("st m25p80"     , 0xd8, 0x00142020, 0x100, 0x10000, 0x100000),
     57 	FLASH_ID("st m45pe10"    , 0xd8, 0x00114020, 0x100, 0x10000, 0x20000),
     58 	FLASH_ID("st m45pe20"    , 0xd8, 0x00124020, 0x100, 0x10000, 0x40000),
     59 	FLASH_ID("st m45pe40"    , 0xd8, 0x00134020, 0x100, 0x10000, 0x80000),
     60 	FLASH_ID("st m45pe80"    , 0xd8, 0x00144020, 0x100, 0x10000, 0x100000),
     61 	FLASH_ID("sp s25fl004"   , 0xd8, 0x00120201, 0x100, 0x10000, 0x80000),
     62 	FLASH_ID("sp s25fl008"   , 0xd8, 0x00130201, 0x100, 0x10000, 0x100000),
     63 	FLASH_ID("sp s25fl016"   , 0xd8, 0x00140201, 0x100, 0x10000, 0x200000),
     64 	FLASH_ID("sp s25fl032"   , 0xd8, 0x00150201, 0x100, 0x10000, 0x400000),
     65 	FLASH_ID("sp s25fl064"   , 0xd8, 0x00160201, 0x100, 0x10000, 0x800000),
     66 	FLASH_ID("mac 25l512"    , 0xd8, 0x001020C2, 0x010, 0x10000, 0x10000),
     67 	FLASH_ID("mac 25l1005"   , 0xd8, 0x001120C2, 0x010, 0x10000, 0x20000),
     68 	FLASH_ID("mac 25l2005"   , 0xd8, 0x001220C2, 0x010, 0x10000, 0x40000),
     69 	FLASH_ID("mac 25l4005"   , 0xd8, 0x001320C2, 0x010, 0x10000, 0x80000),
     70 	FLASH_ID("mac 25l4005a"  , 0xd8, 0x001320C2, 0x010, 0x10000, 0x80000),
     71 	FLASH_ID("mac 25l8005"   , 0xd8, 0x001420C2, 0x010, 0x10000, 0x100000),
     72 	FLASH_ID("mac 25l1605"   , 0xd8, 0x001520C2, 0x100, 0x10000, 0x200000),
     73 	FLASH_ID("mac 25l1605a"  , 0xd8, 0x001520C2, 0x010, 0x10000, 0x200000),
     74 	FLASH_ID("mac 25l3205"   , 0xd8, 0x001620C2, 0x100, 0x10000, 0x400000),
     75 	FLASH_ID("mac 25l3205a"  , 0xd8, 0x001620C2, 0x100, 0x10000, 0x400000),
     76 	FLASH_ID("mac 25l6405"   , 0xd8, 0x001720C2, 0x100, 0x10000, 0x800000),
     77 	FLASH_ID("wbd w25q128" , 0xd8, 0x001840EF, 0x100, 0x10000, 0x1000000),
     78 };
     79 
     80 /*
     81  * smi_wait_xfer_finish - Wait until TFF is set in status register
     82  * @timeout:	 timeout in milliseconds
     83  *
     84  * Wait until TFF is set in status register
     85  */
     86 static int smi_wait_xfer_finish(int timeout)
     87 {
     88 	ulong start = get_timer(0);
     89 
     90 	while (get_timer(start) < timeout) {
     91 		if (readl(&smicntl->smi_sr) & TFF)
     92 			return 0;
     93 
     94 		/* Try after 10 ms */
     95 		udelay(10);
     96 	};
     97 
     98 	return -1;
     99 }
    100 
    101 /*
    102  * smi_read_id - Read flash id
    103  * @info:	 flash_info structure pointer
    104  * @banknum:	 bank number
    105  *
    106  * Read the flash id present at bank #banknum
    107  */
    108 static unsigned int smi_read_id(flash_info_t *info, int banknum)
    109 {
    110 	unsigned int value;
    111 
    112 	writel(readl(&smicntl->smi_cr1) | SW_MODE, &smicntl->smi_cr1);
    113 	writel(READ_ID, &smicntl->smi_tr);
    114 	writel((banknum << BANKSEL_SHIFT) | SEND | TX_LEN_1 | RX_LEN_3,
    115 	       &smicntl->smi_cr2);
    116 
    117 	if (smi_wait_xfer_finish(XFER_FINISH_TOUT))
    118 		return -EIO;
    119 
    120 	value = (readl(&smicntl->smi_rr) & 0x00FFFFFF);
    121 
    122 	writel(readl(&smicntl->smi_sr) & ~TFF, &smicntl->smi_sr);
    123 	writel(readl(&smicntl->smi_cr1) & ~SW_MODE, &smicntl->smi_cr1);
    124 
    125 	return value;
    126 }
    127 
    128 /*
    129  * flash_get_size - Detect the SMI flash by reading the ID.
    130  * @base:	 Base address of the flash area bank #banknum
    131  * @banknum:	 Bank number
    132  *
    133  * Detect the SMI flash by reading the ID. Initializes the flash_info structure
    134  * with size, sector count etc.
    135  */
    136 static ulong flash_get_size(ulong base, int banknum)
    137 {
    138 	flash_info_t *info = &flash_info[banknum];
    139 	int value;
    140 	int i;
    141 
    142 	value = smi_read_id(info, banknum);
    143 
    144 	if (value < 0) {
    145 		printf("Flash id could not be read\n");
    146 		return 0;
    147 	}
    148 
    149 	/* Matches chip-id to entire list of 'serial-nor flash' ids */
    150 	for (i = 0; i < ARRAY_SIZE(flash_devices); i++) {
    151 		if (flash_devices[i].device_id == value) {
    152 			info->size = flash_devices[i].size_in_bytes;
    153 			info->flash_id = value;
    154 			info->start[0] = base;
    155 			info->sector_count =
    156 					info->size/flash_devices[i].sectorsize;
    157 
    158 			return info->size;
    159 		}
    160 	}
    161 
    162 	return 0;
    163 }
    164 
    165 /*
    166  * smi_read_sr - Read status register of SMI
    167  * @bank:	 bank number
    168  *
    169  * This routine will get the status register of the flash chip present at the
    170  * given bank
    171  */
    172 static int smi_read_sr(int bank)
    173 {
    174 	u32 ctrlreg1, val;
    175 
    176 	/* store the CTRL REG1 state */
    177 	ctrlreg1 = readl(&smicntl->smi_cr1);
    178 
    179 	/* Program SMI in HW Mode */
    180 	writel(readl(&smicntl->smi_cr1) & ~(SW_MODE | WB_MODE),
    181 	       &smicntl->smi_cr1);
    182 
    183 	/* Performing a RSR instruction in HW mode */
    184 	writel((bank << BANKSEL_SHIFT) | RD_STATUS_REG, &smicntl->smi_cr2);
    185 
    186 	if (smi_wait_xfer_finish(XFER_FINISH_TOUT))
    187 		return -1;
    188 
    189 	val = readl(&smicntl->smi_sr);
    190 
    191 	/* Restore the CTRL REG1 state */
    192 	writel(ctrlreg1, &smicntl->smi_cr1);
    193 
    194 	return val;
    195 }
    196 
    197 /*
    198  * smi_wait_till_ready - Wait till last operation is over.
    199  * @bank:	 bank number shifted.
    200  * @timeout:	 timeout in milliseconds.
    201  *
    202  * This routine checks for WIP(write in progress)bit in Status register(SMSR-b0)
    203  * The routine checks for #timeout loops, each at interval of 1 milli-second.
    204  * If successful the routine returns 0.
    205  */
    206 static int smi_wait_till_ready(int bank, int timeout)
    207 {
    208 	int sr;
    209 	ulong start = get_timer(0);
    210 
    211 	/* One chip guarantees max 5 msec wait here after page writes,
    212 	   but potentially three seconds (!) after page erase. */
    213 	while (get_timer(start) < timeout) {
    214 		sr = smi_read_sr(bank);
    215 		if ((sr >= 0) && (!(sr & WIP_BIT)))
    216 			return 0;
    217 
    218 		/* Try again after 10 usec */
    219 		udelay(10);
    220 	} while (timeout--);
    221 
    222 	printf("SMI controller is still in wait, timeout=%d\n", timeout);
    223 	return -EIO;
    224 }
    225 
    226 /*
    227  * smi_write_enable - Enable the flash to do write operation
    228  * @bank:	 bank number
    229  *
    230  * Set write enable latch with Write Enable command.
    231  * Returns negative if error occurred.
    232  */
    233 static int smi_write_enable(int bank)
    234 {
    235 	u32 ctrlreg1;
    236 	u32 start;
    237 	int timeout = WMODE_TOUT;
    238 	int sr;
    239 
    240 	/* Store the CTRL REG1 state */
    241 	ctrlreg1 = readl(&smicntl->smi_cr1);
    242 
    243 	/* Program SMI in H/W Mode */
    244 	writel(readl(&smicntl->smi_cr1) & ~SW_MODE, &smicntl->smi_cr1);
    245 
    246 	/* Give the Flash, Write Enable command */
    247 	writel((bank << BANKSEL_SHIFT) | WE, &smicntl->smi_cr2);
    248 
    249 	if (smi_wait_xfer_finish(XFER_FINISH_TOUT))
    250 		return -1;
    251 
    252 	/* Restore the CTRL REG1 state */
    253 	writel(ctrlreg1, &smicntl->smi_cr1);
    254 
    255 	start = get_timer(0);
    256 	while (get_timer(start) < timeout) {
    257 		sr = smi_read_sr(bank);
    258 		if ((sr >= 0) && (sr & (1 << (bank + WM_SHIFT))))
    259 			return 0;
    260 
    261 		/* Try again after 10 usec */
    262 		udelay(10);
    263 	};
    264 
    265 	return -1;
    266 }
    267 
    268 /*
    269  * smi_init - SMI initialization routine
    270  *
    271  * SMI initialization routine. Sets SMI control register1.
    272  */
    273 void smi_init(void)
    274 {
    275 	/* Setting the fast mode values. SMI working at 166/4 = 41.5 MHz */
    276 	writel(HOLD1 | FAST_MODE | BANK_EN | DSEL_TIME | PRESCAL4,
    277 	       &smicntl->smi_cr1);
    278 }
    279 
    280 /*
    281  * smi_sector_erase - Erase flash sector
    282  * @info:	 flash_info structure pointer
    283  * @sector:	 sector number
    284  *
    285  * Set write enable latch with Write Enable command.
    286  * Returns negative if error occurred.
    287  */
    288 static int smi_sector_erase(flash_info_t *info, unsigned int sector)
    289 {
    290 	int bank;
    291 	unsigned int sect_add;
    292 	unsigned int instruction;
    293 
    294 	switch (info->start[0]) {
    295 	case SMIBANK0_BASE:
    296 		bank = BANK0;
    297 		break;
    298 	case SMIBANK1_BASE:
    299 		bank = BANK1;
    300 		break;
    301 	case SMIBANK2_BASE:
    302 		bank = BANK2;
    303 		break;
    304 	case SMIBANK3_BASE:
    305 		bank = BANK3;
    306 		break;
    307 	default:
    308 		return -1;
    309 	}
    310 
    311 	sect_add = sector * (info->size / info->sector_count);
    312 	instruction = ((sect_add >> 8) & 0x0000FF00) | SECTOR_ERASE;
    313 
    314 	writel(readl(&smicntl->smi_sr) & ~(ERF1 | ERF2), &smicntl->smi_sr);
    315 
    316 	/* Wait until finished previous write command. */
    317 	if (smi_wait_till_ready(bank, CONFIG_SYS_FLASH_ERASE_TOUT))
    318 		return -EBUSY;
    319 
    320 	/* Send write enable, before erase commands. */
    321 	if (smi_write_enable(bank))
    322 		return -EIO;
    323 
    324 	/* Put SMI in SW mode */
    325 	writel(readl(&smicntl->smi_cr1) | SW_MODE, &smicntl->smi_cr1);
    326 
    327 	/* Send Sector Erase command in SW Mode */
    328 	writel(instruction, &smicntl->smi_tr);
    329 	writel((bank << BANKSEL_SHIFT) | SEND | TX_LEN_4,
    330 		       &smicntl->smi_cr2);
    331 	if (smi_wait_xfer_finish(XFER_FINISH_TOUT))
    332 		return -EIO;
    333 
    334 	if (smi_wait_till_ready(bank, CONFIG_SYS_FLASH_ERASE_TOUT))
    335 		return -EBUSY;
    336 
    337 	/* Put SMI in HW mode */
    338 	writel(readl(&smicntl->smi_cr1) & ~SW_MODE,
    339 		       &smicntl->smi_cr1);
    340 
    341 	return 0;
    342 }
    343 
    344 /*
    345  * smi_write - Write to SMI flash
    346  * @src_addr:	 source buffer
    347  * @dst_addr:	 destination buffer
    348  * @length:	 length to write in bytes
    349  * @bank:	 bank base address
    350  *
    351  * Write to SMI flash
    352  */
    353 static int smi_write(unsigned int *src_addr, unsigned int *dst_addr,
    354 		     unsigned int length, ulong bank_addr)
    355 {
    356 	u8 *src_addr8 = (u8 *)src_addr;
    357 	u8 *dst_addr8 = (u8 *)dst_addr;
    358 	int banknum;
    359 	int i;
    360 
    361 	switch (bank_addr) {
    362 	case SMIBANK0_BASE:
    363 		banknum = BANK0;
    364 		break;
    365 	case SMIBANK1_BASE:
    366 		banknum = BANK1;
    367 		break;
    368 	case SMIBANK2_BASE:
    369 		banknum = BANK2;
    370 		break;
    371 	case SMIBANK3_BASE:
    372 		banknum = BANK3;
    373 		break;
    374 	default:
    375 		return -1;
    376 	}
    377 
    378 	if (smi_wait_till_ready(banknum, CONFIG_SYS_FLASH_WRITE_TOUT))
    379 		return -EBUSY;
    380 
    381 	/* Set SMI in Hardware Mode */
    382 	writel(readl(&smicntl->smi_cr1) & ~SW_MODE, &smicntl->smi_cr1);
    383 
    384 	if (smi_write_enable(banknum))
    385 		return -EIO;
    386 
    387 	/* Perform the write command */
    388 	for (i = 0; i < length; i += 4) {
    389 		if (((ulong) (dst_addr) % SFLASH_PAGE_SIZE) == 0) {
    390 			if (smi_wait_till_ready(banknum,
    391 						CONFIG_SYS_FLASH_WRITE_TOUT))
    392 				return -EBUSY;
    393 
    394 			if (smi_write_enable(banknum))
    395 				return -EIO;
    396 		}
    397 
    398 		if (length < 4) {
    399 			int k;
    400 
    401 			/*
    402 			 * Handle special case, where length < 4 (redundant env)
    403 			 */
    404 			for (k = 0; k < length; k++)
    405 				*dst_addr8++ = *src_addr8++;
    406 		} else {
    407 			/* Normal 32bit write */
    408 			*dst_addr++ = *src_addr++;
    409 		}
    410 
    411 		if ((readl(&smicntl->smi_sr) & (ERF1 | ERF2)))
    412 			return -EIO;
    413 	}
    414 
    415 	if (smi_wait_till_ready(banknum, CONFIG_SYS_FLASH_WRITE_TOUT))
    416 		return -EBUSY;
    417 
    418 	writel(readl(&smicntl->smi_sr) & ~(WCF), &smicntl->smi_sr);
    419 
    420 	return 0;
    421 }
    422 
    423 /*
    424  * write_buff - Write to SMI flash
    425  * @info:	 flash info structure
    426  * @src:	 source buffer
    427  * @dest_addr:	 destination buffer
    428  * @length:	 length to write in words
    429  *
    430  * Write to SMI flash
    431  */
    432 int write_buff(flash_info_t *info, uchar *src, ulong dest_addr, ulong length)
    433 {
    434 	return smi_write((unsigned int *)src, (unsigned int *)dest_addr,
    435 			 length, info->start[0]);
    436 }
    437 
    438 /*
    439  * flash_init - SMI flash initialization
    440  *
    441  * SMI flash initialization
    442  */
    443 unsigned long flash_init(void)
    444 {
    445 	unsigned long size = 0;
    446 	int i, j;
    447 
    448 	smi_init();
    449 
    450 	for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i++) {
    451 		flash_info[i].flash_id = FLASH_UNKNOWN;
    452 		size += flash_info[i].size = flash_get_size(bank_base[i], i);
    453 	}
    454 
    455 	for (j = 0; j < CONFIG_SYS_MAX_FLASH_BANKS; j++) {
    456 		for (i = 1; i < flash_info[j].sector_count; i++)
    457 			flash_info[j].start[i] =
    458 			    flash_info[j].start[i - 1] +
    459 			    flash_info->size / flash_info->sector_count;
    460 
    461 	}
    462 
    463 	return size;
    464 }
    465 
    466 /*
    467  * flash_print_info - Print SMI flash information
    468  *
    469  * Print SMI flash information
    470  */
    471 void flash_print_info(flash_info_t *info)
    472 {
    473 	int i;
    474 	if (info->flash_id == FLASH_UNKNOWN) {
    475 		puts("missing or unknown FLASH type\n");
    476 		return;
    477 	}
    478 
    479 	if (info->size >= 0x100000)
    480 		printf("  Size: %ld MB in %d Sectors\n",
    481 		       info->size >> 20, info->sector_count);
    482 	else
    483 		printf("  Size: %ld KB in %d Sectors\n",
    484 		       info->size >> 10, info->sector_count);
    485 
    486 	puts("  Sector Start Addresses:");
    487 	for (i = 0; i < info->sector_count; ++i) {
    488 #ifdef CONFIG_SYS_FLASH_EMPTY_INFO
    489 		int size;
    490 		int erased;
    491 		u32 *flash;
    492 
    493 		/*
    494 		 * Check if whole sector is erased
    495 		 */
    496 		size = (info->size) / (info->sector_count);
    497 		flash = (u32 *) info->start[i];
    498 		size = size / sizeof(int);
    499 
    500 		while ((size--) && (*flash++ == ~0))
    501 			;
    502 
    503 		size++;
    504 		if (size)
    505 			erased = 0;
    506 		else
    507 			erased = 1;
    508 
    509 		if ((i % 5) == 0)
    510 			printf("\n");
    511 
    512 		printf(" %08lX%s%s",
    513 		       info->start[i],
    514 		       erased ? " E" : "  ", info->protect[i] ? "RO " : "   ");
    515 #else
    516 		if ((i % 5) == 0)
    517 			printf("\n   ");
    518 		printf(" %08lX%s",
    519 		       info->start[i], info->protect[i] ? " (RO)  " : "     ");
    520 #endif
    521 	}
    522 	putc('\n');
    523 	return;
    524 }
    525 
    526 /*
    527  * flash_erase - Erase SMI flash
    528  *
    529  * Erase SMI flash
    530  */
    531 int flash_erase(flash_info_t *info, int s_first, int s_last)
    532 {
    533 	int rcode = 0;
    534 	int prot = 0;
    535 	flash_sect_t sect;
    536 
    537 	if ((s_first < 0) || (s_first > s_last)) {
    538 		puts("- no sectors to erase\n");
    539 		return 1;
    540 	}
    541 
    542 	for (sect = s_first; sect <= s_last; ++sect) {
    543 		if (info->protect[sect])
    544 			prot++;
    545 	}
    546 	if (prot) {
    547 		printf("- Warning: %d protected sectors will not be erased!\n",
    548 		       prot);
    549 	} else {
    550 		putc('\n');
    551 	}
    552 
    553 	for (sect = s_first; sect <= s_last; sect++) {
    554 		if (info->protect[sect] == 0) {
    555 			if (smi_sector_erase(info, sect))
    556 				rcode = 1;
    557 			else
    558 				putc('.');
    559 		}
    560 	}
    561 	puts(" done\n");
    562 	return rcode;
    563 }
    564 #endif
    565