1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Copyright (C) 2014 Panasonic Corporation 4 * Copyright (C) 2014-2015 Masahiro Yamada <yamada.masahiro@socionext.com> 5 */ 6 7#include <common.h> 8#include <log.h> 9#include <asm/io.h> 10#include <asm/unaligned.h> 11#include <linux/delay.h> 12#include <linux/mtd/rawnand.h> 13#include "denali.h" 14 15#define DENALI_MAP01 (1 << 26) /* read/write pages in PIO */ 16#define DENALI_MAP10 (2 << 26) /* high-level control plane */ 17 18#define INDEX_CTRL_REG 0x0 19#define INDEX_DATA_REG 0x10 20 21#define SPARE_ACCESS 0x41 22#define MAIN_ACCESS 0x42 23#define PIPELINE_ACCESS 0x2000 24 25#define BANK(x) ((x) << 24) 26 27static void __iomem *denali_flash_mem = 28 (void __iomem *)CFG_SYS_NAND_DATA_BASE; 29static void __iomem *denali_flash_reg = 30 (void __iomem *)CFG_SYS_NAND_REGS_BASE; 31 32static const int flash_bank; 33static int page_size, oob_size, pages_per_block; 34 35static void index_addr(uint32_t address, uint32_t data) 36{ 37 writel(address, denali_flash_mem + INDEX_CTRL_REG); 38 writel(data, denali_flash_mem + INDEX_DATA_REG); 39} 40 41static int wait_for_irq(uint32_t irq_mask) 42{ 43 unsigned long timeout = 1000000; 44 uint32_t intr_status; 45 46 do { 47 intr_status = readl(denali_flash_reg + INTR_STATUS(flash_bank)); 48 49 if (intr_status & INTR__ECC_UNCOR_ERR) { 50 debug("Uncorrected ECC detected\n"); 51 return -EBADMSG; 52 } 53 54 if (intr_status & irq_mask) 55 break; 56 57 udelay(1); 58 timeout--; 59 } while (timeout); 60 61 if (!timeout) { 62 debug("Timeout with interrupt status %08x\n", intr_status); 63 return -EIO; 64 } 65 66 return 0; 67} 68 69static void read_data_from_flash_mem(uint8_t *buf, int len) 70{ 71 int i; 72 uint32_t *buf32; 73 74 /* transfer the data from the flash */ 75 buf32 = (uint32_t *)buf; 76 77 /* 78 * Let's take care of unaligned access although it rarely happens. 79 * Avoid put_unaligned() for the normal use cases since it leads to 80 * a bit performance regression. 81 */ 82 if ((unsigned long)buf32 % 4) { 83 for (i = 0; i < len / 4; i++) 84 put_unaligned(readl(denali_flash_mem + INDEX_DATA_REG), 85 buf32++); 86 } else { 87 for (i = 0; i < len / 4; i++) 88 *buf32++ = readl(denali_flash_mem + INDEX_DATA_REG); 89 } 90 91 if (len % 4) { 92 u32 tmp; 93 94 tmp = cpu_to_le32(readl(denali_flash_mem + INDEX_DATA_REG)); 95 buf = (uint8_t *)buf32; 96 for (i = 0; i < len % 4; i++) { 97 *buf++ = tmp; 98 tmp >>= 8; 99 } 100 } 101} 102 103int denali_send_pipeline_cmd(int page, int ecc_en, int access_type) 104{ 105 uint32_t addr, cmd; 106 static uint32_t page_count = 1; 107 108 writel(ecc_en, denali_flash_reg + ECC_ENABLE); 109 110 /* clear all bits of intr_status. */ 111 writel(0xffff, denali_flash_reg + INTR_STATUS(flash_bank)); 112 113 addr = BANK(flash_bank) | page; 114 115 /* setup the acccess type */ 116 cmd = DENALI_MAP10 | addr; 117 index_addr(cmd, access_type); 118 119 /* setup the pipeline command */ 120 index_addr(cmd, PIPELINE_ACCESS | page_count); 121 122 cmd = DENALI_MAP01 | addr; 123 writel(cmd, denali_flash_mem + INDEX_CTRL_REG); 124 125 return wait_for_irq(INTR__LOAD_COMP); 126} 127 128static int nand_read_oob(void *buf, int page) 129{ 130 int ret; 131 132 ret = denali_send_pipeline_cmd(page, 0, SPARE_ACCESS); 133 if (ret < 0) 134 return ret; 135 136 read_data_from_flash_mem(buf, oob_size); 137 138 return 0; 139} 140 141static int nand_read_page(void *buf, int page) 142{ 143 int ret; 144 145 ret = denali_send_pipeline_cmd(page, 1, MAIN_ACCESS); 146 if (ret < 0) 147 return ret; 148 149 read_data_from_flash_mem(buf, page_size); 150 151 return 0; 152} 153 154static int nand_block_isbad(void *buf, int block) 155{ 156 int ret; 157 158 ret = nand_read_oob(buf, block * pages_per_block); 159 if (ret < 0) 160 return ret; 161 162 return *((uint8_t *)buf + CONFIG_SYS_NAND_BAD_BLOCK_POS) != 0xff; 163} 164 165/* nand_init() - initialize data to make nand usable by SPL */ 166void nand_init(void) 167{ 168 /* access to main area */ 169 writel(0, denali_flash_reg + TRANSFER_SPARE_REG); 170 171 /* 172 * These registers are expected to be already set by the hardware 173 * or earlier boot code. So we read these values out. 174 */ 175 page_size = readl(denali_flash_reg + DEVICE_MAIN_AREA_SIZE); 176 oob_size = readl(denali_flash_reg + DEVICE_SPARE_AREA_SIZE); 177 pages_per_block = readl(denali_flash_reg + PAGES_PER_BLOCK); 178 179 /* Do as denali_hw_init() does. */ 180 writel(CONFIG_NAND_DENALI_SPARE_AREA_SKIP_BYTES, 181 denali_flash_reg + SPARE_AREA_SKIP_BYTES); 182 writel(0x0F, denali_flash_reg + RB_PIN_ENABLED); 183 writel(CHIP_EN_DONT_CARE__FLAG, denali_flash_reg + CHIP_ENABLE_DONT_CARE); 184 writel(0xffff, denali_flash_reg + SPARE_AREA_MARKER); 185} 186 187int nand_spl_load_image(uint32_t offs, unsigned int size, void *dst) 188{ 189 int block, page, column, readlen; 190 int ret; 191 int force_bad_block_check = 1; 192 193 page = offs / page_size; 194 column = offs % page_size; 195 196 block = page / pages_per_block; 197 page = page % pages_per_block; 198 199 while (size) { 200 if (force_bad_block_check || page == 0) { 201 ret = nand_block_isbad(dst, block); 202 if (ret < 0) 203 return ret; 204 205 if (ret) { 206 block++; 207 continue; 208 } 209 } 210 211 force_bad_block_check = 0; 212 213 ret = nand_read_page(dst, block * pages_per_block + page); 214 if (ret < 0) 215 return ret; 216 217 readlen = min(page_size - column, (int)size); 218 219 if (unlikely(column)) { 220 /* Partial page read */ 221 memmove(dst, dst + column, readlen); 222 column = 0; 223 } 224 225 size -= readlen; 226 dst += readlen; 227 page++; 228 if (page == pages_per_block) { 229 block++; 230 page = 0; 231 } 232 } 233 234 return 0; 235} 236 237unsigned int nand_page_size(void) 238{ 239 return page_size; 240} 241 242void nand_deselect(void) {} 243