Home | History | Annotate | Download | only in arm926ejs
      1 // SPDX-License-Identifier: GPL-2.0+
      2 /*
      3  * (C) Copyright 2010
      4  * Reinhard Meyer, EMK Elektronik, reinhard.meyer (at) emk-elektronik.de
      5  */
      6 
      7 /*
      8  * this driver supports the enhanced embedded flash in the Atmel
      9  * AT91SAM9XE devices with the following geometry:
     10  *
     11  * AT91SAM9XE128: 1 plane of  8 regions of 32 pages (total  256 pages)
     12  * AT91SAM9XE256: 1 plane of 16 regions of 32 pages (total  512 pages)
     13  * AT91SAM9XE512: 1 plane of 32 regions of 32 pages (total 1024 pages)
     14  * (the exact geometry is read from the flash at runtime, so any
     15  *  future devices should already be covered)
     16  *
     17  * Regions can be write/erase protected.
     18  * Whole (!) pages can be individually written with erase on the fly.
     19  * Writing partial pages will corrupt the rest of the page.
     20  *
     21  * The flash is presented to u-boot with each region being a sector,
     22  * having the following effects:
     23  * Each sector can be hardware protected (protect on/off).
     24  * Each page in a sector can be rewritten anytime.
     25  * Since pages are erased when written, the "erase" does nothing.
     26  * The first "CONFIG_EFLASH_PROTSECTORS" cannot be unprotected
     27  * by u-Boot commands.
     28  *
     29  * Note: Redundant environment will not work in this flash since
     30  * it does use partial page writes. Make sure the environment spans
     31  * whole pages!
     32  */
     33 
     34 /*
     35  * optional TODOs (nice to have features):
     36  *
     37  * make the driver coexist with other NOR flash drivers
     38  *	(use an index into flash_info[], requires work
     39  *	in those other drivers, too)
     40  * Make the erase command fill the sectors with 0xff
     41  *	(if the flashes grow larger in the future and
     42  *	someone puts a jffs2 into them)
     43  * do a read-modify-write for partially programmed pages
     44  */
     45 #include <common.h>
     46 #include <asm/io.h>
     47 #include <asm/arch/hardware.h>
     48 #include <asm/arch/at91_common.h>
     49 #include <asm/arch/at91_eefc.h>
     50 #include <asm/arch/at91_dbu.h>
     51 
     52 /* checks to detect configuration errors */
     53 #if CONFIG_SYS_MAX_FLASH_BANKS!=1
     54 #error eflash: this driver can only handle 1 bank
     55 #endif
     56 
     57 /* global structure */
     58 flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS];
     59 static u32 pagesize;
     60 
     61 unsigned long flash_init (void)
     62 {
     63 	at91_eefc_t *eefc = (at91_eefc_t *) ATMEL_BASE_EEFC;
     64 	at91_dbu_t *dbu = (at91_dbu_t *) ATMEL_BASE_DBGU;
     65 	u32 id, size, nplanes, planesize, nlocks;
     66 	u32 addr, i, tmp=0;
     67 
     68 	debug("eflash: init\n");
     69 
     70 	flash_info[0].flash_id = FLASH_UNKNOWN;
     71 
     72 	/* check if its an AT91ARM9XE SoC */
     73 	if ((readl(&dbu->cidr) & AT91_DBU_CID_ARCH_MASK) != AT91_DBU_CID_ARCH_9XExx) {
     74 		puts("eflash: not an AT91SAM9XE\n");
     75 		return 0;
     76 	}
     77 
     78 	/* now query the eflash for its structure */
     79 	writel(AT91_EEFC_FCR_KEY | AT91_EEFC_FCR_FCMD_GETD, &eefc->fcr);
     80 	while ((readl(&eefc->fsr) & AT91_EEFC_FSR_FRDY) == 0)
     81 		;
     82 	id = readl(&eefc->frr);		/* word 0 */
     83 	size = readl(&eefc->frr);	/* word 1 */
     84 	pagesize = readl(&eefc->frr);	/* word 2 */
     85 	nplanes = readl(&eefc->frr);	/* word 3 */
     86 	planesize = readl(&eefc->frr);	/* word 4 */
     87 	debug("id=%08x size=%u pagesize=%u planes=%u planesize=%u\n",
     88 		id, size, pagesize, nplanes, planesize);
     89 	for (i=1; i<nplanes; i++) {
     90 		tmp = readl(&eefc->frr);	/* words 5..4+nplanes-1 */
     91 	};
     92 	nlocks = readl(&eefc->frr);	/* word 4+nplanes */
     93 	debug("nlocks=%u\n", nlocks);
     94 	/* since we are going to use the lock regions as sectors, check count */
     95 	if (nlocks > CONFIG_SYS_MAX_FLASH_SECT) {
     96 		printf("eflash: number of lock regions(%u) "\
     97 			"> CONFIG_SYS_MAX_FLASH_SECT. reducing...\n",
     98 			nlocks);
     99 		nlocks = CONFIG_SYS_MAX_FLASH_SECT;
    100 	}
    101 	flash_info[0].size = size;
    102 	flash_info[0].sector_count = nlocks;
    103 	flash_info[0].flash_id = id;
    104 
    105 	addr = ATMEL_BASE_FLASH;
    106 	for (i=0; i<nlocks; i++) {
    107 		tmp = readl(&eefc->frr);	/* words 4+nplanes+1.. */
    108 		flash_info[0].start[i] = addr;
    109 		flash_info[0].protect[i] = 0;
    110 		addr += tmp;
    111 	};
    112 
    113 	/* now read the protection information for all regions */
    114 	writel(AT91_EEFC_FCR_KEY | AT91_EEFC_FCR_FCMD_GLB, &eefc->fcr);
    115 	while ((readl(&eefc->fsr) & AT91_EEFC_FSR_FRDY) == 0)
    116 		;
    117 	for (i=0; i<flash_info[0].sector_count; i++) {
    118 		if (i%32 == 0)
    119 			tmp = readl(&eefc->frr);
    120 		flash_info[0].protect[i] = (tmp >> (i%32)) & 1;
    121 #if defined(CONFIG_EFLASH_PROTSECTORS)
    122 		if (i < CONFIG_EFLASH_PROTSECTORS)
    123 			flash_info[0].protect[i] = 1;
    124 #endif
    125 	}
    126 
    127 	return size;
    128 }
    129 
    130 void flash_print_info (flash_info_t *info)
    131 {
    132 	int i;
    133 
    134 	puts("AT91SAM9XE embedded flash\n  Size: ");
    135 	print_size(info->size, " in ");
    136 	printf("%d Sectors\n", info->sector_count);
    137 
    138 	printf("  Sector Start Addresses:");
    139 	for (i=0; i<info->sector_count; ++i) {
    140 		if ((i % 5) == 0)
    141 			printf("\n   ");
    142 		printf(" %08lX%s",
    143 			info->start[i],
    144 			info->protect[i] ? " (RO)" : "     "
    145 		);
    146 	}
    147 	printf ("\n");
    148 	return;
    149 }
    150 
    151 int flash_real_protect (flash_info_t *info, long sector, int prot)
    152 {
    153 	at91_eefc_t *eefc = (at91_eefc_t *) ATMEL_BASE_EEFC;
    154 	u32 pagenum = (info->start[sector]-ATMEL_BASE_FLASH)/pagesize;
    155 	u32 i, tmp=0;
    156 
    157 	debug("protect sector=%ld prot=%d\n", sector, prot);
    158 
    159 #if defined(CONFIG_EFLASH_PROTSECTORS)
    160 	if (sector < CONFIG_EFLASH_PROTSECTORS) {
    161 		if (!prot) {
    162 			printf("eflash: sector %lu cannot be unprotected\n",
    163 				sector);
    164 		}
    165 		return 1; /* return anyway, caller does not care for result */
    166 	}
    167 #endif
    168 	if (prot) {
    169 		writel(AT91_EEFC_FCR_KEY | AT91_EEFC_FCR_FCMD_SLB |
    170 			(pagenum << AT91_EEFC_FCR_FARG_SHIFT), &eefc->fcr);
    171 	} else {
    172 		writel(AT91_EEFC_FCR_KEY | AT91_EEFC_FCR_FCMD_CLB |
    173 			(pagenum << AT91_EEFC_FCR_FARG_SHIFT), &eefc->fcr);
    174 	}
    175 	while ((readl(&eefc->fsr) & AT91_EEFC_FSR_FRDY) == 0)
    176 		;
    177 	/* now re-read the protection information for all regions */
    178 	writel(AT91_EEFC_FCR_KEY | AT91_EEFC_FCR_FCMD_GLB, &eefc->fcr);
    179 	while ((readl(&eefc->fsr) & AT91_EEFC_FSR_FRDY) == 0)
    180 		;
    181 	for (i=0; i<info->sector_count; i++) {
    182 		if (i%32 == 0)
    183 			tmp = readl(&eefc->frr);
    184 		info->protect[i] = (tmp >> (i%32)) & 1;
    185 	}
    186 	return 0;
    187 }
    188 
    189 static u32 erase_write_page (u32 pagenum)
    190 {
    191 	at91_eefc_t *eefc = (at91_eefc_t *) ATMEL_BASE_EEFC;
    192 
    193 	debug("erase+write page=%u\n", pagenum);
    194 
    195 	/* give erase and write page command */
    196 	writel(AT91_EEFC_FCR_KEY | AT91_EEFC_FCR_FCMD_EWP |
    197 		(pagenum << AT91_EEFC_FCR_FARG_SHIFT), &eefc->fcr);
    198 	while ((readl(&eefc->fsr) & AT91_EEFC_FSR_FRDY) == 0)
    199 		;
    200 	/* return status */
    201 	return readl(&eefc->fsr)
    202 		& (AT91_EEFC_FSR_FCMDE | AT91_EEFC_FSR_FLOCKE);
    203 }
    204 
    205 int flash_erase (flash_info_t *info, int s_first, int s_last)
    206 {
    207 	debug("erase first=%d last=%d\n", s_first, s_last);
    208 	puts("this flash does not need and support erasing!\n");
    209 	return 0;
    210 }
    211 
    212 /*
    213  * Copy memory to flash, returns:
    214  * 0 - OK
    215  * 1 - write timeout
    216  */
    217 
    218 int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
    219 {
    220 	u32 pagenum;
    221 	u32 *src32, *dst32;
    222 	u32 i;
    223 
    224 	debug("write src=%08lx addr=%08lx cnt=%lx\n",
    225 		(ulong)src, addr, cnt);
    226 
    227 	/* REQUIRE addr to be on a page start, abort if not */
    228 	if (addr % pagesize) {
    229 		printf ("eflash: start %08lx is not on page start\n"\
    230 			"        write aborted\n", addr);
    231 		return 1;
    232 	}
    233 
    234 	/* now start copying data */
    235 	pagenum = (addr-ATMEL_BASE_FLASH)/pagesize;
    236 	src32 = (u32 *) src;
    237 	dst32 = (u32 *) addr;
    238 	while (cnt > 0) {
    239 		i = pagesize / 4;
    240 		/* fill page buffer */
    241 		while (i--)
    242 			*dst32++ = *src32++;
    243 		/* write page */
    244 		if (erase_write_page(pagenum))
    245 			return 1;
    246 		pagenum++;
    247 		if (cnt > pagesize)
    248 			cnt -= pagesize;
    249 		else
    250 			cnt = 0;
    251 	}
    252 	return 0;
    253 }
    254