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