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