1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Copyright (c) 2014-2015, Antmicro Ltd <www.antmicro.com> 4 * Copyright (c) 2015, AW-SOM Technologies <www.aw-som.com> 5 */ 6 7#include <asm/arch/clock.h> 8#include <asm/io.h> 9#include <common.h> 10#include <config.h> 11#include <nand.h> 12#include <linux/bitops.h> 13#include <linux/ctype.h> 14#include <linux/delay.h> 15#include <linux/mtd/rawnand.h> 16 17/* registers */ 18#define NFC_CTL 0x00000000 19#define NFC_ST 0x00000004 20#define NFC_INT 0x00000008 21#define NFC_TIMING_CTL 0x0000000C 22#define NFC_TIMING_CFG 0x00000010 23#define NFC_ADDR_LOW 0x00000014 24#define NFC_ADDR_HIGH 0x00000018 25#define NFC_SECTOR_NUM 0x0000001C 26#define NFC_CNT 0x00000020 27#define NFC_CMD 0x00000024 28#define NFC_RCMD_SET 0x00000028 29#define NFC_WCMD_SET 0x0000002C 30#define NFC_IO_DATA 0x00000030 31#define NFC_ECC_CTL 0x00000034 32#define NFC_ECC_ST 0x00000038 33#define NFC_DEBUG 0x0000003C 34#define NFC_ECC_CNT0 0x00000040 35#define NFC_ECC_CNT1 0x00000044 36#define NFC_ECC_CNT2 0x00000048 37#define NFC_ECC_CNT3 0x0000004C 38#define NFC_USER_DATA_BASE 0x00000050 39#define NFC_EFNAND_STATUS 0x00000090 40#define NFC_SPARE_AREA 0x000000A0 41#define NFC_PATTERN_ID 0x000000A4 42#define NFC_RAM0_BASE 0x00000400 43#define NFC_RAM1_BASE 0x00000800 44 45#define NFC_CTL_EN (1 << 0) 46#define NFC_CTL_RESET (1 << 1) 47#define NFC_CTL_RAM_METHOD (1 << 14) 48#define NFC_CTL_PAGE_SIZE_MASK (0xf << 8) 49#define NFC_CTL_PAGE_SIZE(a) ((fls(a) - 11) << 8) 50 51 52#define NFC_ECC_EN (1 << 0) 53#define NFC_ECC_PIPELINE (1 << 3) 54#define NFC_ECC_EXCEPTION (1 << 4) 55#define NFC_ECC_BLOCK_SIZE (1 << 5) 56#define NFC_ECC_RANDOM_EN (1 << 9) 57#define NFC_ECC_RANDOM_DIRECTION (1 << 10) 58 59 60#define NFC_ADDR_NUM_OFFSET 16 61#define NFC_SEND_ADDR (1 << 19) 62#define NFC_ACCESS_DIR (1 << 20) 63#define NFC_DATA_TRANS (1 << 21) 64#define NFC_SEND_CMD1 (1 << 22) 65#define NFC_WAIT_FLAG (1 << 23) 66#define NFC_SEND_CMD2 (1 << 24) 67#define NFC_SEQ (1 << 25) 68#define NFC_DATA_SWAP_METHOD (1 << 26) 69#define NFC_ROW_AUTO_INC (1 << 27) 70#define NFC_SEND_CMD3 (1 << 28) 71#define NFC_SEND_CMD4 (1 << 29) 72#define NFC_RAW_CMD (0 << 30) 73#define NFC_ECC_CMD (1 << 30) 74#define NFC_PAGE_CMD (2 << 30) 75 76#define NFC_ST_CMD_INT_FLAG (1 << 1) 77#define NFC_ST_DMA_INT_FLAG (1 << 2) 78#define NFC_ST_CMD_FIFO_STAT (1 << 3) 79 80#define NFC_READ_CMD_OFFSET 0 81#define NFC_RANDOM_READ_CMD0_OFFSET 8 82#define NFC_RANDOM_READ_CMD1_OFFSET 16 83 84#define NFC_CMD_RNDOUTSTART 0xE0 85#define NFC_CMD_RNDOUT 0x05 86#define NFC_CMD_READSTART 0x30 87 88struct nfc_config { 89 int page_size; 90 int ecc_strength; 91 int ecc_size; 92 int addr_cycles; 93 int nseeds; 94 bool randomize; 95 bool valid; 96}; 97 98/* minimal "boot0" style NAND support for Allwinner A20 */ 99 100/* random seed used by linux */ 101const uint16_t random_seed[128] = { 102 0x2b75, 0x0bd0, 0x5ca3, 0x62d1, 0x1c93, 0x07e9, 0x2162, 0x3a72, 103 0x0d67, 0x67f9, 0x1be7, 0x077d, 0x032f, 0x0dac, 0x2716, 0x2436, 104 0x7922, 0x1510, 0x3860, 0x5287, 0x480f, 0x4252, 0x1789, 0x5a2d, 105 0x2a49, 0x5e10, 0x437f, 0x4b4e, 0x2f45, 0x216e, 0x5cb7, 0x7130, 106 0x2a3f, 0x60e4, 0x4dc9, 0x0ef0, 0x0f52, 0x1bb9, 0x6211, 0x7a56, 107 0x226d, 0x4ea7, 0x6f36, 0x3692, 0x38bf, 0x0c62, 0x05eb, 0x4c55, 108 0x60f4, 0x728c, 0x3b6f, 0x2037, 0x7f69, 0x0936, 0x651a, 0x4ceb, 109 0x6218, 0x79f3, 0x383f, 0x18d9, 0x4f05, 0x5c82, 0x2912, 0x6f17, 110 0x6856, 0x5938, 0x1007, 0x61ab, 0x3e7f, 0x57c2, 0x542f, 0x4f62, 111 0x7454, 0x2eac, 0x7739, 0x42d4, 0x2f90, 0x435a, 0x2e52, 0x2064, 112 0x637c, 0x66ad, 0x2c90, 0x0bad, 0x759c, 0x0029, 0x0986, 0x7126, 113 0x1ca7, 0x1605, 0x386a, 0x27f5, 0x1380, 0x6d75, 0x24c3, 0x0f8e, 114 0x2b7a, 0x1418, 0x1fd1, 0x7dc1, 0x2d8e, 0x43af, 0x2267, 0x7da3, 115 0x4e3d, 0x1338, 0x50db, 0x454d, 0x764d, 0x40a3, 0x42e6, 0x262b, 116 0x2d2e, 0x1aea, 0x2e17, 0x173d, 0x3a6e, 0x71bf, 0x25f9, 0x0a5d, 117 0x7c57, 0x0fbe, 0x46ce, 0x4939, 0x6b17, 0x37bb, 0x3e91, 0x76db, 118}; 119 120#define DEFAULT_TIMEOUT_US 100000 121 122static int check_value_inner(int offset, int expected_bits, 123 int timeout_us, int negation) 124{ 125 do { 126 int val = readl(offset) & expected_bits; 127 if (negation ? !val : val) 128 return 1; 129 udelay(1); 130 } while (--timeout_us); 131 132 return 0; 133} 134 135static inline int check_value(int offset, int expected_bits, 136 int timeout_us) 137{ 138 return check_value_inner(offset, expected_bits, timeout_us, 0); 139} 140 141static inline int check_value_negated(int offset, int unexpected_bits, 142 int timeout_us) 143{ 144 return check_value_inner(offset, unexpected_bits, timeout_us, 1); 145} 146 147static int nand_wait_cmd_fifo_empty(void) 148{ 149 if (!check_value_negated(SUNXI_NFC_BASE + NFC_ST, NFC_ST_CMD_FIFO_STAT, 150 DEFAULT_TIMEOUT_US)) { 151 printf("nand: timeout waiting for empty cmd FIFO\n"); 152 return -ETIMEDOUT; 153 } 154 155 return 0; 156} 157 158static int nand_wait_int(void) 159{ 160 if (!check_value(SUNXI_NFC_BASE + NFC_ST, NFC_ST_CMD_INT_FLAG, 161 DEFAULT_TIMEOUT_US)) { 162 printf("nand: timeout waiting for interruption\n"); 163 return -ETIMEDOUT; 164 } 165 166 return 0; 167} 168 169static int nand_exec_cmd(u32 cmd) 170{ 171 int ret; 172 173 ret = nand_wait_cmd_fifo_empty(); 174 if (ret) 175 return ret; 176 177 writel(NFC_ST_CMD_INT_FLAG, SUNXI_NFC_BASE + NFC_ST); 178 writel(cmd, SUNXI_NFC_BASE + NFC_CMD); 179 180 return nand_wait_int(); 181} 182 183void nand_init(void) 184{ 185 uint32_t val; 186 187 board_nand_init(); 188 189 val = readl(SUNXI_NFC_BASE + NFC_CTL); 190 /* enable and reset CTL */ 191 writel(val | NFC_CTL_EN | NFC_CTL_RESET, 192 SUNXI_NFC_BASE + NFC_CTL); 193 194 if (!check_value_negated(SUNXI_NFC_BASE + NFC_CTL, 195 NFC_CTL_RESET, DEFAULT_TIMEOUT_US)) { 196 printf("Couldn't initialize nand\n"); 197 } 198 199 /* reset NAND */ 200 nand_exec_cmd(NFC_SEND_CMD1 | NFC_WAIT_FLAG | NAND_CMD_RESET); 201} 202 203static void nand_apply_config(const struct nfc_config *conf) 204{ 205 u32 val; 206 207 nand_wait_cmd_fifo_empty(); 208 209 val = readl(SUNXI_NFC_BASE + NFC_CTL); 210 val &= ~NFC_CTL_PAGE_SIZE_MASK; 211 writel(val | NFC_CTL_PAGE_SIZE(conf->page_size), 212 SUNXI_NFC_BASE + NFC_CTL); 213 writel(conf->ecc_size, SUNXI_NFC_BASE + NFC_CNT); 214 writel(conf->page_size, SUNXI_NFC_BASE + NFC_SPARE_AREA); 215} 216 217static int nand_load_page(const struct nfc_config *conf, u32 offs) 218{ 219 int page = offs / conf->page_size; 220 221 writel((NFC_CMD_RNDOUTSTART << NFC_RANDOM_READ_CMD1_OFFSET) | 222 (NFC_CMD_RNDOUT << NFC_RANDOM_READ_CMD0_OFFSET) | 223 (NFC_CMD_READSTART << NFC_READ_CMD_OFFSET), 224 SUNXI_NFC_BASE + NFC_RCMD_SET); 225 writel(((page & 0xFFFF) << 16), SUNXI_NFC_BASE + NFC_ADDR_LOW); 226 writel((page >> 16) & 0xFF, SUNXI_NFC_BASE + NFC_ADDR_HIGH); 227 228 return nand_exec_cmd(NFC_SEND_CMD1 | NFC_SEND_CMD2 | NFC_RAW_CMD | 229 NFC_SEND_ADDR | NFC_WAIT_FLAG | 230 ((conf->addr_cycles - 1) << NFC_ADDR_NUM_OFFSET)); 231} 232 233static int nand_change_column(u16 column) 234{ 235 int ret; 236 237 writel((NFC_CMD_RNDOUTSTART << NFC_RANDOM_READ_CMD1_OFFSET) | 238 (NFC_CMD_RNDOUT << NFC_RANDOM_READ_CMD0_OFFSET) | 239 (NFC_CMD_RNDOUTSTART << NFC_READ_CMD_OFFSET), 240 SUNXI_NFC_BASE + NFC_RCMD_SET); 241 writel(column, SUNXI_NFC_BASE + NFC_ADDR_LOW); 242 243 ret = nand_exec_cmd(NFC_SEND_CMD1 | NFC_SEND_CMD2 | NFC_RAW_CMD | 244 (1 << NFC_ADDR_NUM_OFFSET) | NFC_SEND_ADDR | 245 NFC_CMD_RNDOUT); 246 if (ret) 247 return ret; 248 249 /* Ensure tCCS has passed before reading data */ 250 udelay(1); 251 252 return 0; 253} 254 255static const int ecc_bytes[] = {32, 46, 54, 60, 74, 88, 102, 110, 116}; 256 257static int nand_read_page(const struct nfc_config *conf, u32 offs, 258 void *dest, int len) 259{ 260 int nsectors = len / conf->ecc_size; 261 u16 rand_seed = 0; 262 int oob_chunk_sz = ecc_bytes[conf->ecc_strength]; 263 int page = offs / conf->page_size; 264 u32 ecc_st; 265 int i; 266 267 if (offs % conf->page_size || len % conf->ecc_size || 268 len > conf->page_size || len < 0) 269 return -EINVAL; 270 271 /* Choose correct seed if randomized */ 272 if (conf->randomize) 273 rand_seed = random_seed[page % conf->nseeds]; 274 275 /* Retrieve data from SRAM (PIO) */ 276 for (i = 0; i < nsectors; i++) { 277 int data_off = i * conf->ecc_size; 278 int oob_off = conf->page_size + (i * oob_chunk_sz); 279 u8 *data = dest + data_off; 280 281 /* Clear ECC status and restart ECC engine */ 282 writel(0, SUNXI_NFC_BASE + NFC_ECC_ST); 283 writel((rand_seed << 16) | (conf->ecc_strength << 12) | 284 (conf->randomize ? NFC_ECC_RANDOM_EN : 0) | 285 (conf->ecc_size == 512 ? NFC_ECC_BLOCK_SIZE : 0) | 286 NFC_ECC_EN | NFC_ECC_EXCEPTION, 287 SUNXI_NFC_BASE + NFC_ECC_CTL); 288 289 /* Move the data in SRAM */ 290 nand_change_column(data_off); 291 writel(conf->ecc_size, SUNXI_NFC_BASE + NFC_CNT); 292 nand_exec_cmd(NFC_DATA_TRANS); 293 294 /* 295 * Let the ECC engine consume the ECC bytes and possibly correct 296 * the data. 297 */ 298 nand_change_column(oob_off); 299 nand_exec_cmd(NFC_DATA_TRANS | NFC_ECC_CMD); 300 301 /* Get the ECC status */ 302 ecc_st = readl(SUNXI_NFC_BASE + NFC_ECC_ST); 303 304 /* ECC error detected. */ 305 if (ecc_st & 0xffff) 306 return -EIO; 307 308 /* 309 * Return 1 if the first chunk is empty (needed for 310 * configuration detection). 311 */ 312 if (!i && (ecc_st & 0x10000)) 313 return 1; 314 315 /* Retrieve the data from SRAM */ 316 memcpy_fromio(data, SUNXI_NFC_BASE + NFC_RAM0_BASE, 317 conf->ecc_size); 318 319 /* Stop the ECC engine */ 320 writel(readl(SUNXI_NFC_BASE + NFC_ECC_CTL) & ~NFC_ECC_EN, 321 SUNXI_NFC_BASE + NFC_ECC_CTL); 322 323 if (data_off + conf->ecc_size >= len) 324 break; 325 } 326 327 return 0; 328} 329 330static int nand_max_ecc_strength(struct nfc_config *conf) 331{ 332 int max_oobsize, max_ecc_bytes; 333 int nsectors = conf->page_size / conf->ecc_size; 334 int i; 335 336 /* 337 * ECC strength is limited by the size of the OOB area which is 338 * correlated with the page size. 339 */ 340 switch (conf->page_size) { 341 case 2048: 342 max_oobsize = 64; 343 break; 344 case 4096: 345 max_oobsize = 256; 346 break; 347 case 8192: 348 max_oobsize = 640; 349 break; 350 case 16384: 351 max_oobsize = 1664; 352 break; 353 default: 354 return -EINVAL; 355 } 356 357 max_ecc_bytes = max_oobsize / nsectors; 358 359 for (i = 0; i < ARRAY_SIZE(ecc_bytes); i++) { 360 if (ecc_bytes[i] > max_ecc_bytes) 361 break; 362 } 363 364 if (!i) 365 return -EINVAL; 366 367 return i - 1; 368} 369 370static int nand_detect_ecc_config(struct nfc_config *conf, u32 offs, 371 void *dest) 372{ 373 /* NAND with pages > 4k will likely require 1k sector size. */ 374 int min_ecc_size = conf->page_size > 4096 ? 1024 : 512; 375 int page = offs / conf->page_size; 376 int ret; 377 378 /* 379 * In most cases, 1k sectors are preferred over 512b ones, start 380 * testing this config first. 381 */ 382 for (conf->ecc_size = 1024; conf->ecc_size >= min_ecc_size; 383 conf->ecc_size >>= 1) { 384 int max_ecc_strength = nand_max_ecc_strength(conf); 385 386 nand_apply_config(conf); 387 388 /* 389 * We are starting from the maximum ECC strength because 390 * most of the time NAND vendors provide an OOB area that 391 * barely meets the ECC requirements. 392 */ 393 for (conf->ecc_strength = max_ecc_strength; 394 conf->ecc_strength >= 0; 395 conf->ecc_strength--) { 396 conf->randomize = false; 397 if (nand_change_column(0)) 398 return -EIO; 399 400 /* 401 * Only read the first sector to speedup detection. 402 */ 403 ret = nand_read_page(conf, offs, dest, conf->ecc_size); 404 if (!ret) { 405 return 0; 406 } else if (ret > 0) { 407 /* 408 * If page is empty we can't deduce anything 409 * about the ECC config => stop the detection. 410 */ 411 return -EINVAL; 412 } 413 414 conf->randomize = true; 415 conf->nseeds = ARRAY_SIZE(random_seed); 416 do { 417 if (nand_change_column(0)) 418 return -EIO; 419 420 if (!nand_read_page(conf, offs, dest, 421 conf->ecc_size)) 422 return 0; 423 424 /* 425 * Find the next ->nseeds value that would 426 * change the randomizer seed for the page 427 * we're trying to read. 428 */ 429 while (conf->nseeds >= 16) { 430 int seed = page % conf->nseeds; 431 432 conf->nseeds >>= 1; 433 if (seed != page % conf->nseeds) 434 break; 435 } 436 } while (conf->nseeds >= 16); 437 } 438 } 439 440 return -EINVAL; 441} 442 443static int nand_detect_config(struct nfc_config *conf, u32 offs, void *dest) 444{ 445 if (conf->valid) 446 return 0; 447 448 /* 449 * Modern NANDs are more likely than legacy ones, so we start testing 450 * with 5 address cycles. 451 */ 452 for (conf->addr_cycles = 5; 453 conf->addr_cycles >= 4; 454 conf->addr_cycles--) { 455 int max_page_size = conf->addr_cycles == 4 ? 2048 : 16384; 456 457 /* 458 * Ignoring 1k pages cause I'm not even sure this case exist 459 * in the real world. 460 */ 461 for (conf->page_size = 2048; conf->page_size <= max_page_size; 462 conf->page_size <<= 1) { 463 if (nand_load_page(conf, offs)) 464 return -1; 465 466 if (!nand_detect_ecc_config(conf, offs, dest)) { 467 conf->valid = true; 468 return 0; 469 } 470 } 471 } 472 473 return -EINVAL; 474} 475 476static int nand_read_buffer(struct nfc_config *conf, uint32_t offs, 477 unsigned int size, void *dest) 478{ 479 int first_seed = 0, page, ret; 480 481 size = ALIGN(size, conf->page_size); 482 page = offs / conf->page_size; 483 if (conf->randomize) 484 first_seed = page % conf->nseeds; 485 486 for (; size; size -= conf->page_size) { 487 if (nand_load_page(conf, offs)) 488 return -1; 489 490 ret = nand_read_page(conf, offs, dest, conf->page_size); 491 /* 492 * The ->nseeds value should be equal to the number of pages 493 * in an eraseblock. Since we don't know this information in 494 * advance we might have picked a wrong value. 495 */ 496 if (ret < 0 && conf->randomize) { 497 int cur_seed = page % conf->nseeds; 498 499 /* 500 * We already tried all the seed values => we are 501 * facing a real corruption. 502 */ 503 if (cur_seed < first_seed) 504 return -EIO; 505 506 /* Try to adjust ->nseeds and read the page again... */ 507 conf->nseeds = cur_seed; 508 509 if (nand_change_column(0)) 510 return -EIO; 511 512 /* ... it still fails => it's a real corruption. */ 513 if (nand_read_page(conf, offs, dest, conf->page_size)) 514 return -EIO; 515 } else if (ret && conf->randomize) { 516 memset(dest, 0xff, conf->page_size); 517 } 518 519 page++; 520 offs += conf->page_size; 521 dest += conf->page_size; 522 } 523 524 return 0; 525} 526 527static struct nfc_config conf; 528 529int nand_spl_load_image(uint32_t offs, unsigned int size, void *dest) 530{ 531 int ret; 532 533 ret = nand_detect_config(&conf, offs, dest); 534 if (ret) 535 return ret; 536 537 return nand_read_buffer(&conf, offs, size, dest); 538} 539 540unsigned int nand_page_size(void) 541{ 542 return conf.page_size; 543} 544 545void nand_deselect(void) 546{ 547 struct sunxi_ccm_reg *const ccm = 548 (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; 549 550 clrbits_le32(&ccm->ahb_gate0, (CLK_GATE_OPEN << AHB_GATE_OFFSET_NAND0)); 551#ifdef CONFIG_MACH_SUN9I 552 clrbits_le32(&ccm->ahb_gate1, (1 << AHB_GATE_OFFSET_DMA)); 553#else 554 clrbits_le32(&ccm->ahb_gate0, (1 << AHB_GATE_OFFSET_DMA)); 555#endif 556 clrbits_le32(&ccm->nand0_clk_cfg, CCM_NAND_CTRL_ENABLE | AHB_DIV_1); 557} 558