blob: 235a5fcd52b2729edf61f06ea80faeb3fc64a8bb [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Chin Liang See03534df2014-09-12 00:42:17 -05002/*
3 * Copyright (C) 2014 Panasonic Corporation
4 * Copyright (C) 2013-2014, Altera Corporation <www.altera.com>
5 * Copyright (C) 2009-2010, Intel Corporation and its suppliers.
Chin Liang See03534df2014-09-12 00:42:17 -05006 */
7
Vignesh Raghavendradd62b9a2020-01-16 14:23:47 +05308#include <asm/dma-mapping.h>
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09009#include <dm.h>
Masahiro Yamada5beb1b32017-11-30 13:45:27 +090010#include <nand.h>
Simon Glassd66c5f72020-02-03 07:36:15 -070011#include <dm/devres.h>
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +090012#include <linux/bitfield.h>
13#include <linux/dma-direction.h>
Simon Glassd66c5f72020-02-03 07:36:15 -070014#include <linux/err.h>
Masahiro Yamada56a931c2016-09-21 11:28:55 +090015#include <linux/errno.h>
Masahiro Yamada54fde8e2017-09-15 21:43:19 +090016#include <linux/io.h>
Masahiro Yamada5beb1b32017-11-30 13:45:27 +090017#include <linux/mtd/mtd.h>
18#include <linux/mtd/rawnand.h>
Chin Liang See03534df2014-09-12 00:42:17 -050019
20#include "denali.h"
21
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +090022#define DENALI_NAND_NAME "denali-nand"
Chin Liang See03534df2014-09-12 00:42:17 -050023
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +090024/* for Indexed Addressing */
25#define DENALI_INDEXED_CTRL 0x00
26#define DENALI_INDEXED_DATA 0x10
Chin Liang See03534df2014-09-12 00:42:17 -050027
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +090028#define DENALI_MAP00 (0 << 26) /* direct access to buffer */
29#define DENALI_MAP01 (1 << 26) /* read/write pages in PIO */
30#define DENALI_MAP10 (2 << 26) /* high-level control plane */
31#define DENALI_MAP11 (3 << 26) /* direct controller access */
Chin Liang See03534df2014-09-12 00:42:17 -050032
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +090033/* MAP11 access cycle type */
34#define DENALI_MAP11_CMD ((DENALI_MAP11) | 0) /* command cycle */
35#define DENALI_MAP11_ADDR ((DENALI_MAP11) | 1) /* address cycle */
36#define DENALI_MAP11_DATA ((DENALI_MAP11) | 2) /* data cycle */
Chin Liang See03534df2014-09-12 00:42:17 -050037
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +090038/* MAP10 commands */
39#define DENALI_ERASE 0x01
Chin Liang See03534df2014-09-12 00:42:17 -050040
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +090041#define DENALI_BANK(denali) ((denali)->active_bank << 24)
Chin Liang See03534df2014-09-12 00:42:17 -050042
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +090043#define DENALI_INVALID_BANK -1
44#define DENALI_NR_BANKS 4
Chin Liang See03534df2014-09-12 00:42:17 -050045
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +090046static inline struct denali_nand_info *mtd_to_denali(struct mtd_info *mtd)
Chin Liang See03534df2014-09-12 00:42:17 -050047{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +090048 return container_of(mtd_to_nand(mtd), struct denali_nand_info, nand);
Chin Liang See03534df2014-09-12 00:42:17 -050049}
50
51/*
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +090052 * Direct Addressing - the slave address forms the control information (command
53 * type, bank, block, and page address). The slave data is the actual data to
54 * be transferred. This mode requires 28 bits of address region allocated.
Scott Wood3ea94ed2015-06-26 19:03:26 -050055 */
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +090056static u32 denali_direct_read(struct denali_nand_info *denali, u32 addr)
Chin Liang See03534df2014-09-12 00:42:17 -050057{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +090058 return ioread32(denali->host + addr);
Chin Liang See03534df2014-09-12 00:42:17 -050059}
60
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +090061static void denali_direct_write(struct denali_nand_info *denali, u32 addr,
62 u32 data)
Chin Liang See03534df2014-09-12 00:42:17 -050063{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +090064 iowrite32(data, denali->host + addr);
Chin Liang See03534df2014-09-12 00:42:17 -050065}
66
Scott Wood3ea94ed2015-06-26 19:03:26 -050067/*
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +090068 * Indexed Addressing - address translation module intervenes in passing the
69 * control information. This mode reduces the required address range. The
70 * control information and transferred data are latched by the registers in
71 * the translation module.
Scott Wood3ea94ed2015-06-26 19:03:26 -050072 */
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +090073static u32 denali_indexed_read(struct denali_nand_info *denali, u32 addr)
Chin Liang See03534df2014-09-12 00:42:17 -050074{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +090075 iowrite32(addr, denali->host + DENALI_INDEXED_CTRL);
76 return ioread32(denali->host + DENALI_INDEXED_DATA);
Chin Liang See03534df2014-09-12 00:42:17 -050077}
78
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +090079static void denali_indexed_write(struct denali_nand_info *denali, u32 addr,
80 u32 data)
Chin Liang See03534df2014-09-12 00:42:17 -050081{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +090082 iowrite32(addr, denali->host + DENALI_INDEXED_CTRL);
83 iowrite32(data, denali->host + DENALI_INDEXED_DATA);
Chin Liang See03534df2014-09-12 00:42:17 -050084}
85
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +090086/*
87 * Use the configuration feature register to determine the maximum number of
88 * banks that the hardware supports.
89 */
90static void denali_detect_max_banks(struct denali_nand_info *denali)
Chin Liang See03534df2014-09-12 00:42:17 -050091{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +090092 uint32_t features = ioread32(denali->reg + FEATURES);
Chin Liang See03534df2014-09-12 00:42:17 -050093
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +090094 denali->max_banks = 1 << FIELD_GET(FEATURES__N_BANKS, features);
Chin Liang See03534df2014-09-12 00:42:17 -050095
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +090096 /* the encoding changed from rev 5.0 to 5.1 */
97 if (denali->revision < 0x0501)
98 denali->max_banks <<= 1;
Chin Liang See03534df2014-09-12 00:42:17 -050099}
100
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900101static void __maybe_unused denali_enable_irq(struct denali_nand_info *denali)
Chin Liang See03534df2014-09-12 00:42:17 -0500102{
Scott Wood3ea94ed2015-06-26 19:03:26 -0500103 int i;
Chin Liang See03534df2014-09-12 00:42:17 -0500104
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900105 for (i = 0; i < DENALI_NR_BANKS; i++)
106 iowrite32(U32_MAX, denali->reg + INTR_EN(i));
107 iowrite32(GLOBAL_INT_EN_FLAG, denali->reg + GLOBAL_INT_ENABLE);
Chin Liang See03534df2014-09-12 00:42:17 -0500108}
109
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900110static void __maybe_unused denali_disable_irq(struct denali_nand_info *denali)
Chin Liang See03534df2014-09-12 00:42:17 -0500111{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900112 int i;
Chin Liang See03534df2014-09-12 00:42:17 -0500113
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900114 for (i = 0; i < DENALI_NR_BANKS; i++)
115 iowrite32(0, denali->reg + INTR_EN(i));
116 iowrite32(0, denali->reg + GLOBAL_INT_ENABLE);
117}
Chin Liang See03534df2014-09-12 00:42:17 -0500118
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900119static void denali_clear_irq(struct denali_nand_info *denali,
120 int bank, uint32_t irq_status)
121{
122 /* write one to clear bits */
123 iowrite32(irq_status, denali->reg + INTR_STATUS(bank));
124}
Chin Liang See03534df2014-09-12 00:42:17 -0500125
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900126static void denali_clear_irq_all(struct denali_nand_info *denali)
127{
128 int i;
Chin Liang See03534df2014-09-12 00:42:17 -0500129
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900130 for (i = 0; i < DENALI_NR_BANKS; i++)
131 denali_clear_irq(denali, i, U32_MAX);
132}
Chin Liang See03534df2014-09-12 00:42:17 -0500133
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900134static void __denali_check_irq(struct denali_nand_info *denali)
135{
136 uint32_t irq_status;
137 int i;
Chin Liang See03534df2014-09-12 00:42:17 -0500138
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900139 for (i = 0; i < DENALI_NR_BANKS; i++) {
140 irq_status = ioread32(denali->reg + INTR_STATUS(i));
141 denali_clear_irq(denali, i, irq_status);
Chin Liang See03534df2014-09-12 00:42:17 -0500142
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900143 if (i != denali->active_bank)
144 continue;
Chin Liang See03534df2014-09-12 00:42:17 -0500145
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900146 denali->irq_status |= irq_status;
Chin Liang See03534df2014-09-12 00:42:17 -0500147 }
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900148}
Chin Liang See03534df2014-09-12 00:42:17 -0500149
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900150static void denali_reset_irq(struct denali_nand_info *denali)
151{
152 denali->irq_status = 0;
153 denali->irq_mask = 0;
154}
Chin Liang See03534df2014-09-12 00:42:17 -0500155
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900156static uint32_t denali_wait_for_irq(struct denali_nand_info *denali,
157 uint32_t irq_mask)
158{
159 unsigned long time_left = 1000000;
Chin Liang See03534df2014-09-12 00:42:17 -0500160
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900161 while (time_left) {
162 __denali_check_irq(denali);
Chin Liang See03534df2014-09-12 00:42:17 -0500163
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900164 if (irq_mask & denali->irq_status)
165 return denali->irq_status;
166 udelay(1);
167 time_left--;
Chin Liang See03534df2014-09-12 00:42:17 -0500168 }
169
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900170 if (!time_left) {
171 dev_err(denali->dev, "timeout while waiting for irq 0x%x\n",
172 irq_mask);
173 return 0;
174 }
Chin Liang See03534df2014-09-12 00:42:17 -0500175
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900176 return denali->irq_status;
Chin Liang See03534df2014-09-12 00:42:17 -0500177}
178
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900179static uint32_t denali_check_irq(struct denali_nand_info *denali)
Chin Liang See03534df2014-09-12 00:42:17 -0500180{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900181 __denali_check_irq(denali);
Scott Wood3ea94ed2015-06-26 19:03:26 -0500182
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900183 return denali->irq_status;
Chin Liang See03534df2014-09-12 00:42:17 -0500184}
185
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900186static void denali_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
Chin Liang See03534df2014-09-12 00:42:17 -0500187{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900188 struct denali_nand_info *denali = mtd_to_denali(mtd);
189 u32 addr = DENALI_MAP11_DATA | DENALI_BANK(denali);
190 int i;
191
192 for (i = 0; i < len; i++)
193 buf[i] = denali->host_read(denali, addr);
Chin Liang See03534df2014-09-12 00:42:17 -0500194}
195
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900196static void denali_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
Chin Liang See03534df2014-09-12 00:42:17 -0500197{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900198 struct denali_nand_info *denali = mtd_to_denali(mtd);
199 u32 addr = DENALI_MAP11_DATA | DENALI_BANK(denali);
200 int i;
Chin Liang See03534df2014-09-12 00:42:17 -0500201
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900202 for (i = 0; i < len; i++)
203 denali->host_write(denali, addr, buf[i]);
Chin Liang See03534df2014-09-12 00:42:17 -0500204}
205
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900206static void denali_read_buf16(struct mtd_info *mtd, uint8_t *buf, int len)
Chin Liang See03534df2014-09-12 00:42:17 -0500207{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900208 struct denali_nand_info *denali = mtd_to_denali(mtd);
209 u32 addr = DENALI_MAP11_DATA | DENALI_BANK(denali);
210 uint16_t *buf16 = (uint16_t *)buf;
211 int i;
Chin Liang See03534df2014-09-12 00:42:17 -0500212
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900213 for (i = 0; i < len / 2; i++)
214 buf16[i] = denali->host_read(denali, addr);
Chin Liang See03534df2014-09-12 00:42:17 -0500215}
216
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900217static void denali_write_buf16(struct mtd_info *mtd, const uint8_t *buf,
218 int len)
Chin Liang See03534df2014-09-12 00:42:17 -0500219{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900220 struct denali_nand_info *denali = mtd_to_denali(mtd);
221 u32 addr = DENALI_MAP11_DATA | DENALI_BANK(denali);
222 const uint16_t *buf16 = (const uint16_t *)buf;
Chin Liang See03534df2014-09-12 00:42:17 -0500223 int i;
224
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900225 for (i = 0; i < len / 2; i++)
226 denali->host_write(denali, addr, buf16[i]);
Chin Liang See03534df2014-09-12 00:42:17 -0500227}
228
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900229static uint8_t denali_read_byte(struct mtd_info *mtd)
Chin Liang See03534df2014-09-12 00:42:17 -0500230{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900231 uint8_t byte;
Masahiro Yamada54fde8e2017-09-15 21:43:19 +0900232
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900233 denali_read_buf(mtd, &byte, 1);
Masahiro Yamada54fde8e2017-09-15 21:43:19 +0900234
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900235 return byte;
Chin Liang See03534df2014-09-12 00:42:17 -0500236}
237
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900238static void denali_write_byte(struct mtd_info *mtd, uint8_t byte)
Chin Liang See03534df2014-09-12 00:42:17 -0500239{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900240 denali_write_buf(mtd, &byte, 1);
Chin Liang See03534df2014-09-12 00:42:17 -0500241}
242
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900243static uint16_t denali_read_word(struct mtd_info *mtd)
Chin Liang See03534df2014-09-12 00:42:17 -0500244{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900245 uint16_t word;
Chin Liang See03534df2014-09-12 00:42:17 -0500246
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900247 denali_read_buf16(mtd, (uint8_t *)&word, 2);
Chin Liang See03534df2014-09-12 00:42:17 -0500248
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900249 return word;
250}
Chin Liang See03534df2014-09-12 00:42:17 -0500251
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900252static void denali_cmd_ctrl(struct mtd_info *mtd, int dat, unsigned int ctrl)
253{
254 struct denali_nand_info *denali = mtd_to_denali(mtd);
255 uint32_t type;
Chin Liang See03534df2014-09-12 00:42:17 -0500256
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900257 if (ctrl & NAND_CLE)
258 type = DENALI_MAP11_CMD;
259 else if (ctrl & NAND_ALE)
260 type = DENALI_MAP11_ADDR;
261 else
262 return;
Chin Liang See03534df2014-09-12 00:42:17 -0500263
Scott Wood3ea94ed2015-06-26 19:03:26 -0500264 /*
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900265 * Some commands are followed by chip->dev_ready or chip->waitfunc.
266 * irq_status must be cleared here to catch the R/B# interrupt later.
Chin Liang See03534df2014-09-12 00:42:17 -0500267 */
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900268 if (ctrl & NAND_CTRL_CHANGE)
269 denali_reset_irq(denali);
Chin Liang See03534df2014-09-12 00:42:17 -0500270
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900271 denali->host_write(denali, DENALI_BANK(denali) | type, dat);
Chin Liang See03534df2014-09-12 00:42:17 -0500272}
273
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900274static int denali_dev_ready(struct mtd_info *mtd)
Chin Liang See03534df2014-09-12 00:42:17 -0500275{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900276 struct denali_nand_info *denali = mtd_to_denali(mtd);
277
278 return !!(denali_check_irq(denali) & INTR__INT_ACT);
Chin Liang See03534df2014-09-12 00:42:17 -0500279}
280
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900281static int denali_check_erased_page(struct mtd_info *mtd,
282 struct nand_chip *chip, uint8_t *buf,
283 unsigned long uncor_ecc_flags,
284 unsigned int max_bitflips)
Chin Liang See03534df2014-09-12 00:42:17 -0500285{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900286 uint8_t *ecc_code = chip->buffers->ecccode;
287 int ecc_steps = chip->ecc.steps;
288 int ecc_size = chip->ecc.size;
289 int ecc_bytes = chip->ecc.bytes;
290 int i, ret, stat;
Chin Liang See03534df2014-09-12 00:42:17 -0500291
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900292 ret = mtd_ooblayout_get_eccbytes(mtd, ecc_code, chip->oob_poi, 0,
293 chip->ecc.total);
294 if (ret)
295 return ret;
Chin Liang See03534df2014-09-12 00:42:17 -0500296
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900297 for (i = 0; i < ecc_steps; i++) {
298 if (!(uncor_ecc_flags & BIT(i)))
299 continue;
Chin Liang See03534df2014-09-12 00:42:17 -0500300
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900301 stat = nand_check_erased_ecc_chunk(buf, ecc_size,
302 ecc_code, ecc_bytes,
303 NULL, 0,
304 chip->ecc.strength);
305 if (stat < 0) {
306 mtd->ecc_stats.failed++;
307 } else {
308 mtd->ecc_stats.corrected += stat;
309 max_bitflips = max_t(unsigned int, max_bitflips, stat);
310 }
Chin Liang See03534df2014-09-12 00:42:17 -0500311
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900312 buf += ecc_size;
313 ecc_code += ecc_bytes;
314 }
315
316 return max_bitflips;
Chin Liang See03534df2014-09-12 00:42:17 -0500317}
318
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900319static int denali_hw_ecc_fixup(struct mtd_info *mtd,
320 struct denali_nand_info *denali,
321 unsigned long *uncor_ecc_flags)
Chin Liang See03534df2014-09-12 00:42:17 -0500322{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900323 struct nand_chip *chip = mtd_to_nand(mtd);
324 int bank = denali->active_bank;
325 uint32_t ecc_cor;
326 unsigned int max_bitflips;
Chin Liang See03534df2014-09-12 00:42:17 -0500327
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900328 ecc_cor = ioread32(denali->reg + ECC_COR_INFO(bank));
329 ecc_cor >>= ECC_COR_INFO__SHIFT(bank);
330
331 if (ecc_cor & ECC_COR_INFO__UNCOR_ERR) {
332 /*
333 * This flag is set when uncorrectable error occurs at least in
334 * one ECC sector. We can not know "how many sectors", or
335 * "which sector(s)". We need erase-page check for all sectors.
336 */
337 *uncor_ecc_flags = GENMASK(chip->ecc.steps - 1, 0);
338 return 0;
339 }
Chin Liang See03534df2014-09-12 00:42:17 -0500340
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900341 max_bitflips = FIELD_GET(ECC_COR_INFO__MAX_ERRORS, ecc_cor);
342
343 /*
344 * The register holds the maximum of per-sector corrected bitflips.
345 * This is suitable for the return value of the ->read_page() callback.
346 * Unfortunately, we can not know the total number of corrected bits in
347 * the page. Increase the stats by max_bitflips. (compromised solution)
348 */
349 mtd->ecc_stats.corrected += max_bitflips;
350
351 return max_bitflips;
Chin Liang See03534df2014-09-12 00:42:17 -0500352}
353
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900354static int denali_sw_ecc_fixup(struct mtd_info *mtd,
355 struct denali_nand_info *denali,
356 unsigned long *uncor_ecc_flags, uint8_t *buf)
Chin Liang See03534df2014-09-12 00:42:17 -0500357{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900358 unsigned int ecc_size = denali->nand.ecc.size;
359 unsigned int bitflips = 0;
360 unsigned int max_bitflips = 0;
361 uint32_t err_addr, err_cor_info;
362 unsigned int err_byte, err_sector, err_device;
363 uint8_t err_cor_value;
364 unsigned int prev_sector = 0;
365 uint32_t irq_status;
Chin Liang See03534df2014-09-12 00:42:17 -0500366
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900367 denali_reset_irq(denali);
Chin Liang See03534df2014-09-12 00:42:17 -0500368
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900369 do {
370 err_addr = ioread32(denali->reg + ECC_ERROR_ADDRESS);
371 err_sector = FIELD_GET(ECC_ERROR_ADDRESS__SECTOR, err_addr);
372 err_byte = FIELD_GET(ECC_ERROR_ADDRESS__OFFSET, err_addr);
Chin Liang See03534df2014-09-12 00:42:17 -0500373
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900374 err_cor_info = ioread32(denali->reg + ERR_CORRECTION_INFO);
375 err_cor_value = FIELD_GET(ERR_CORRECTION_INFO__BYTE,
376 err_cor_info);
377 err_device = FIELD_GET(ERR_CORRECTION_INFO__DEVICE,
378 err_cor_info);
Chin Liang See03534df2014-09-12 00:42:17 -0500379
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900380 /* reset the bitflip counter when crossing ECC sector */
381 if (err_sector != prev_sector)
382 bitflips = 0;
Chin Liang See03534df2014-09-12 00:42:17 -0500383
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900384 if (err_cor_info & ERR_CORRECTION_INFO__UNCOR) {
385 /*
386 * Check later if this is a real ECC error, or
387 * an erased sector.
388 */
389 *uncor_ecc_flags |= BIT(err_sector);
390 } else if (err_byte < ecc_size) {
391 /*
392 * If err_byte is larger than ecc_size, means error
393 * happened in OOB, so we ignore it. It's no need for
394 * us to correct it err_device is represented the NAND
395 * error bits are happened in if there are more than
396 * one NAND connected.
397 */
398 int offset;
399 unsigned int flips_in_byte;
Chin Liang See03534df2014-09-12 00:42:17 -0500400
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900401 offset = (err_sector * ecc_size + err_byte) *
402 denali->devs_per_cs + err_device;
Chin Liang See03534df2014-09-12 00:42:17 -0500403
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900404 /* correct the ECC error */
405 flips_in_byte = hweight8(buf[offset] ^ err_cor_value);
406 buf[offset] ^= err_cor_value;
407 mtd->ecc_stats.corrected += flips_in_byte;
408 bitflips += flips_in_byte;
Chin Liang See03534df2014-09-12 00:42:17 -0500409
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900410 max_bitflips = max(max_bitflips, bitflips);
411 }
Chin Liang See03534df2014-09-12 00:42:17 -0500412
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900413 prev_sector = err_sector;
414 } while (!(err_cor_info & ERR_CORRECTION_INFO__LAST_ERR));
Chin Liang See03534df2014-09-12 00:42:17 -0500415
Scott Wood3ea94ed2015-06-26 19:03:26 -0500416 /*
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900417 * Once handle all ECC errors, controller will trigger an
418 * ECC_TRANSACTION_DONE interrupt.
Scott Wood3ea94ed2015-06-26 19:03:26 -0500419 */
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900420 irq_status = denali_wait_for_irq(denali, INTR__ECC_TRANSACTION_DONE);
421 if (!(irq_status & INTR__ECC_TRANSACTION_DONE))
422 return -EIO;
Chin Liang See03534df2014-09-12 00:42:17 -0500423
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900424 return max_bitflips;
Chin Liang See03534df2014-09-12 00:42:17 -0500425}
426
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900427static void denali_setup_dma64(struct denali_nand_info *denali,
428 dma_addr_t dma_addr, int page, int write)
Chin Liang See03534df2014-09-12 00:42:17 -0500429{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900430 uint32_t mode;
431 const int page_count = 1;
Chin Liang See03534df2014-09-12 00:42:17 -0500432
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900433 mode = DENALI_MAP10 | DENALI_BANK(denali) | page;
Chin Liang See03534df2014-09-12 00:42:17 -0500434
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900435 /* DMA is a three step process */
Chin Liang See03534df2014-09-12 00:42:17 -0500436
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900437 /*
438 * 1. setup transfer type, interrupt when complete,
439 * burst len = 64 bytes, the number of pages
440 */
441 denali->host_write(denali, mode,
442 0x01002000 | (64 << 16) | (write << 8) | page_count);
Chin Liang See03534df2014-09-12 00:42:17 -0500443
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900444 /* 2. set memory low address */
445 denali->host_write(denali, mode, lower_32_bits(dma_addr));
Chin Liang See03534df2014-09-12 00:42:17 -0500446
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900447 /* 3. set memory high address */
448 denali->host_write(denali, mode, upper_32_bits(dma_addr));
Chin Liang See03534df2014-09-12 00:42:17 -0500449}
450
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900451static void denali_setup_dma32(struct denali_nand_info *denali,
452 dma_addr_t dma_addr, int page, int write)
Chin Liang See03534df2014-09-12 00:42:17 -0500453{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900454 uint32_t mode;
455 const int page_count = 1;
Chin Liang See03534df2014-09-12 00:42:17 -0500456
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900457 mode = DENALI_MAP10 | DENALI_BANK(denali);
Chin Liang See03534df2014-09-12 00:42:17 -0500458
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900459 /* DMA is a four step process */
Chin Liang See03534df2014-09-12 00:42:17 -0500460
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900461 /* 1. setup transfer type and # of pages */
462 denali->host_write(denali, mode | page,
463 0x2000 | (write << 8) | page_count);
Chin Liang See03534df2014-09-12 00:42:17 -0500464
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900465 /* 2. set memory high address bits 23:8 */
466 denali->host_write(denali, mode | ((dma_addr >> 16) << 8), 0x2200);
Chin Liang See03534df2014-09-12 00:42:17 -0500467
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900468 /* 3. set memory low address bits 23:8 */
469 denali->host_write(denali, mode | ((dma_addr & 0xffff) << 8), 0x2300);
Chin Liang See03534df2014-09-12 00:42:17 -0500470
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900471 /* 4. interrupt when complete, burst len = 64 bytes */
472 denali->host_write(denali, mode | 0x14000, 0x2400);
Chin Liang See03534df2014-09-12 00:42:17 -0500473}
474
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900475static int denali_pio_read(struct denali_nand_info *denali, void *buf,
476 size_t size, int page, int raw)
Chin Liang See03534df2014-09-12 00:42:17 -0500477{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900478 u32 addr = DENALI_MAP01 | DENALI_BANK(denali) | page;
479 uint32_t *buf32 = (uint32_t *)buf;
480 uint32_t irq_status, ecc_err_mask;
481 int i;
Chin Liang See03534df2014-09-12 00:42:17 -0500482
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900483 if (denali->caps & DENALI_CAP_HW_ECC_FIXUP)
484 ecc_err_mask = INTR__ECC_UNCOR_ERR;
485 else
486 ecc_err_mask = INTR__ECC_ERR;
Chin Liang See03534df2014-09-12 00:42:17 -0500487
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900488 denali_reset_irq(denali);
Chin Liang See03534df2014-09-12 00:42:17 -0500489
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900490 for (i = 0; i < size / 4; i++)
491 *buf32++ = denali->host_read(denali, addr);
Chin Liang See03534df2014-09-12 00:42:17 -0500492
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900493 irq_status = denali_wait_for_irq(denali, INTR__PAGE_XFER_INC);
494 if (!(irq_status & INTR__PAGE_XFER_INC))
495 return -EIO;
Chin Liang See03534df2014-09-12 00:42:17 -0500496
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900497 if (irq_status & INTR__ERASED_PAGE)
498 memset(buf, 0xff, size);
499
500 return irq_status & ecc_err_mask ? -EBADMSG : 0;
Chin Liang See03534df2014-09-12 00:42:17 -0500501}
502
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900503static int denali_pio_write(struct denali_nand_info *denali,
504 const void *buf, size_t size, int page, int raw)
Chin Liang See03534df2014-09-12 00:42:17 -0500505{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900506 u32 addr = DENALI_MAP01 | DENALI_BANK(denali) | page;
507 const uint32_t *buf32 = (uint32_t *)buf;
508 uint32_t irq_status;
Scott Wood3ea94ed2015-06-26 19:03:26 -0500509 int i;
510
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900511 denali_reset_irq(denali);
512
513 for (i = 0; i < size / 4; i++)
514 denali->host_write(denali, addr, *buf32++);
515
516 irq_status = denali_wait_for_irq(denali,
517 INTR__PROGRAM_COMP | INTR__PROGRAM_FAIL);
518 if (!(irq_status & INTR__PROGRAM_COMP))
519 return -EIO;
520
521 return 0;
Chin Liang See03534df2014-09-12 00:42:17 -0500522}
523
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900524static int denali_pio_xfer(struct denali_nand_info *denali, void *buf,
525 size_t size, int page, int raw, int write)
Chin Liang See03534df2014-09-12 00:42:17 -0500526{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900527 if (write)
528 return denali_pio_write(denali, buf, size, page, raw);
529 else
530 return denali_pio_read(denali, buf, size, page, raw);
Chin Liang See03534df2014-09-12 00:42:17 -0500531}
532
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900533static int denali_dma_xfer(struct denali_nand_info *denali, void *buf,
534 size_t size, int page, int raw, int write)
Chin Liang See03534df2014-09-12 00:42:17 -0500535{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900536 dma_addr_t dma_addr;
537 uint32_t irq_mask, irq_status, ecc_err_mask;
538 enum dma_data_direction dir = write ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
539 int ret = 0;
Chin Liang See03534df2014-09-12 00:42:17 -0500540
Vignesh Raghavendradd62b9a2020-01-16 14:23:47 +0530541 dma_addr = dma_map_single(buf, size, dir);
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900542 if (dma_mapping_error(denali->dev, dma_addr)) {
543 dev_dbg(denali->dev, "Failed to DMA-map buffer. Trying PIO.\n");
544 return denali_pio_xfer(denali, buf, size, page, raw, write);
545 }
Chin Liang See03534df2014-09-12 00:42:17 -0500546
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900547 if (write) {
548 /*
549 * INTR__PROGRAM_COMP is never asserted for the DMA transfer.
550 * We can use INTR__DMA_CMD_COMP instead. This flag is asserted
551 * when the page program is completed.
552 */
553 irq_mask = INTR__DMA_CMD_COMP | INTR__PROGRAM_FAIL;
554 ecc_err_mask = 0;
555 } else if (denali->caps & DENALI_CAP_HW_ECC_FIXUP) {
556 irq_mask = INTR__DMA_CMD_COMP;
557 ecc_err_mask = INTR__ECC_UNCOR_ERR;
558 } else {
559 irq_mask = INTR__DMA_CMD_COMP;
560 ecc_err_mask = INTR__ECC_ERR;
561 }
Chin Liang See03534df2014-09-12 00:42:17 -0500562
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900563 iowrite32(DMA_ENABLE__FLAG, denali->reg + DMA_ENABLE);
Masahiro Yamada9ea23972018-12-19 20:03:19 +0900564 /*
565 * The ->setup_dma() hook kicks DMA by using the data/command
566 * interface, which belongs to a different AXI port from the
567 * register interface. Read back the register to avoid a race.
568 */
569 ioread32(denali->reg + DMA_ENABLE);
Chin Liang See03534df2014-09-12 00:42:17 -0500570
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900571 denali_reset_irq(denali);
572 denali->setup_dma(denali, dma_addr, page, write);
Chin Liang See03534df2014-09-12 00:42:17 -0500573
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900574 irq_status = denali_wait_for_irq(denali, irq_mask);
575 if (!(irq_status & INTR__DMA_CMD_COMP))
576 ret = -EIO;
577 else if (irq_status & ecc_err_mask)
578 ret = -EBADMSG;
Chin Liang See03534df2014-09-12 00:42:17 -0500579
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900580 iowrite32(0, denali->reg + DMA_ENABLE);
Chin Liang See03534df2014-09-12 00:42:17 -0500581
Vignesh Raghavendradd62b9a2020-01-16 14:23:47 +0530582 dma_unmap_single(buf, size, dir);
Chin Liang See03534df2014-09-12 00:42:17 -0500583
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900584 if (irq_status & INTR__ERASED_PAGE)
585 memset(buf, 0xff, size);
Chin Liang See03534df2014-09-12 00:42:17 -0500586
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900587 return ret;
Chin Liang See03534df2014-09-12 00:42:17 -0500588}
589
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900590static int denali_data_xfer(struct denali_nand_info *denali, void *buf,
591 size_t size, int page, int raw, int write)
Chin Liang See03534df2014-09-12 00:42:17 -0500592{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900593 iowrite32(raw ? 0 : ECC_ENABLE__FLAG, denali->reg + ECC_ENABLE);
594 iowrite32(raw ? TRANSFER_SPARE_REG__FLAG : 0,
595 denali->reg + TRANSFER_SPARE_REG);
Chin Liang See03534df2014-09-12 00:42:17 -0500596
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900597 if (denali->dma_avail)
598 return denali_dma_xfer(denali, buf, size, page, raw, write);
599 else
600 return denali_pio_xfer(denali, buf, size, page, raw, write);
601}
Chin Liang See03534df2014-09-12 00:42:17 -0500602
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900603static void denali_oob_xfer(struct mtd_info *mtd, struct nand_chip *chip,
604 int page, int write)
605{
606 struct denali_nand_info *denali = mtd_to_denali(mtd);
607 unsigned int start_cmd = write ? NAND_CMD_SEQIN : NAND_CMD_READ0;
608 unsigned int rnd_cmd = write ? NAND_CMD_RNDIN : NAND_CMD_RNDOUT;
609 int writesize = mtd->writesize;
610 int oobsize = mtd->oobsize;
611 uint8_t *bufpoi = chip->oob_poi;
612 int ecc_steps = chip->ecc.steps;
613 int ecc_size = chip->ecc.size;
614 int ecc_bytes = chip->ecc.bytes;
615 int oob_skip = denali->oob_skip_bytes;
616 size_t size = writesize + oobsize;
617 int i, pos, len;
Chin Liang See03534df2014-09-12 00:42:17 -0500618
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900619 /* BBM at the beginning of the OOB area */
620 chip->cmdfunc(mtd, start_cmd, writesize, page);
621 if (write)
622 chip->write_buf(mtd, bufpoi, oob_skip);
623 else
624 chip->read_buf(mtd, bufpoi, oob_skip);
625 bufpoi += oob_skip;
Chin Liang See03534df2014-09-12 00:42:17 -0500626
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900627 /* OOB ECC */
628 for (i = 0; i < ecc_steps; i++) {
629 pos = ecc_size + i * (ecc_size + ecc_bytes);
630 len = ecc_bytes;
Chin Liang See03534df2014-09-12 00:42:17 -0500631
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900632 if (pos >= writesize)
633 pos += oob_skip;
634 else if (pos + len > writesize)
635 len = writesize - pos;
Chin Liang See03534df2014-09-12 00:42:17 -0500636
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900637 chip->cmdfunc(mtd, rnd_cmd, pos, -1);
638 if (write)
639 chip->write_buf(mtd, bufpoi, len);
640 else
641 chip->read_buf(mtd, bufpoi, len);
642 bufpoi += len;
643 if (len < ecc_bytes) {
644 len = ecc_bytes - len;
645 chip->cmdfunc(mtd, rnd_cmd, writesize + oob_skip, -1);
646 if (write)
647 chip->write_buf(mtd, bufpoi, len);
648 else
649 chip->read_buf(mtd, bufpoi, len);
650 bufpoi += len;
651 }
652 }
Chin Liang See03534df2014-09-12 00:42:17 -0500653
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900654 /* OOB free */
655 len = oobsize - (bufpoi - chip->oob_poi);
656 chip->cmdfunc(mtd, rnd_cmd, size - len, -1);
657 if (write)
658 chip->write_buf(mtd, bufpoi, len);
659 else
660 chip->read_buf(mtd, bufpoi, len);
Chin Liang See03534df2014-09-12 00:42:17 -0500661}
662
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900663static int denali_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
664 uint8_t *buf, int oob_required, int page)
Chin Liang See03534df2014-09-12 00:42:17 -0500665{
666 struct denali_nand_info *denali = mtd_to_denali(mtd);
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900667 int writesize = mtd->writesize;
668 int oobsize = mtd->oobsize;
669 int ecc_steps = chip->ecc.steps;
670 int ecc_size = chip->ecc.size;
671 int ecc_bytes = chip->ecc.bytes;
672 void *tmp_buf = denali->buf;
673 int oob_skip = denali->oob_skip_bytes;
674 size_t size = writesize + oobsize;
675 int ret, i, pos, len;
Chin Liang See03534df2014-09-12 00:42:17 -0500676
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900677 ret = denali_data_xfer(denali, tmp_buf, size, page, 1, 0);
678 if (ret)
679 return ret;
Chin Liang See03534df2014-09-12 00:42:17 -0500680
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900681 /* Arrange the buffer for syndrome payload/ecc layout */
682 if (buf) {
683 for (i = 0; i < ecc_steps; i++) {
684 pos = i * (ecc_size + ecc_bytes);
685 len = ecc_size;
Chin Liang See03534df2014-09-12 00:42:17 -0500686
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900687 if (pos >= writesize)
688 pos += oob_skip;
689 else if (pos + len > writesize)
690 len = writesize - pos;
Chin Liang See03534df2014-09-12 00:42:17 -0500691
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900692 memcpy(buf, tmp_buf + pos, len);
693 buf += len;
694 if (len < ecc_size) {
695 len = ecc_size - len;
696 memcpy(buf, tmp_buf + writesize + oob_skip,
697 len);
698 buf += len;
699 }
700 }
701 }
Chin Liang See03534df2014-09-12 00:42:17 -0500702
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900703 if (oob_required) {
704 uint8_t *oob = chip->oob_poi;
Chin Liang See03534df2014-09-12 00:42:17 -0500705
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900706 /* BBM at the beginning of the OOB area */
707 memcpy(oob, tmp_buf + writesize, oob_skip);
708 oob += oob_skip;
Chin Liang See03534df2014-09-12 00:42:17 -0500709
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900710 /* OOB ECC */
711 for (i = 0; i < ecc_steps; i++) {
712 pos = ecc_size + i * (ecc_size + ecc_bytes);
713 len = ecc_bytes;
714
715 if (pos >= writesize)
716 pos += oob_skip;
717 else if (pos + len > writesize)
718 len = writesize - pos;
719
720 memcpy(oob, tmp_buf + pos, len);
721 oob += len;
722 if (len < ecc_bytes) {
723 len = ecc_bytes - len;
724 memcpy(oob, tmp_buf + writesize + oob_skip,
725 len);
726 oob += len;
727 }
728 }
729
730 /* OOB free */
731 len = oobsize - (oob - chip->oob_poi);
732 memcpy(oob, tmp_buf + size - len, len);
Chin Liang See03534df2014-09-12 00:42:17 -0500733 }
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900734
Chin Liang See03534df2014-09-12 00:42:17 -0500735 return 0;
736}
737
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900738static int denali_read_oob(struct mtd_info *mtd, struct nand_chip *chip,
739 int page)
Chin Liang See03534df2014-09-12 00:42:17 -0500740{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900741 denali_oob_xfer(mtd, chip, page, 0);
Chin Liang See03534df2014-09-12 00:42:17 -0500742
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900743 return 0;
Chin Liang See03534df2014-09-12 00:42:17 -0500744}
745
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900746static int denali_write_oob(struct mtd_info *mtd, struct nand_chip *chip,
747 int page)
Chin Liang See03534df2014-09-12 00:42:17 -0500748{
749 struct denali_nand_info *denali = mtd_to_denali(mtd);
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900750 int status;
Chin Liang See03534df2014-09-12 00:42:17 -0500751
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900752 denali_reset_irq(denali);
Chin Liang See03534df2014-09-12 00:42:17 -0500753
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900754 denali_oob_xfer(mtd, chip, page, 1);
Chin Liang See03534df2014-09-12 00:42:17 -0500755
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900756 chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
757 status = chip->waitfunc(mtd, chip);
Chin Liang See03534df2014-09-12 00:42:17 -0500758
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900759 return status & NAND_STATUS_FAIL ? -EIO : 0;
Chin Liang See03534df2014-09-12 00:42:17 -0500760}
761
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900762static int denali_read_page(struct mtd_info *mtd, struct nand_chip *chip,
763 uint8_t *buf, int oob_required, int page)
Chin Liang See03534df2014-09-12 00:42:17 -0500764{
765 struct denali_nand_info *denali = mtd_to_denali(mtd);
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900766 unsigned long uncor_ecc_flags = 0;
767 int stat = 0;
768 int ret;
Chin Liang See03534df2014-09-12 00:42:17 -0500769
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900770 ret = denali_data_xfer(denali, buf, mtd->writesize, page, 0, 0);
771 if (ret && ret != -EBADMSG)
772 return ret;
Chin Liang See03534df2014-09-12 00:42:17 -0500773
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900774 if (denali->caps & DENALI_CAP_HW_ECC_FIXUP)
775 stat = denali_hw_ecc_fixup(mtd, denali, &uncor_ecc_flags);
776 else if (ret == -EBADMSG)
777 stat = denali_sw_ecc_fixup(mtd, denali, &uncor_ecc_flags, buf);
Chin Liang See03534df2014-09-12 00:42:17 -0500778
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900779 if (stat < 0)
780 return stat;
Chin Liang See03534df2014-09-12 00:42:17 -0500781
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900782 if (uncor_ecc_flags) {
783 ret = denali_read_oob(mtd, chip, page);
784 if (ret)
785 return ret;
Chin Liang See03534df2014-09-12 00:42:17 -0500786
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900787 stat = denali_check_erased_page(mtd, chip, buf,
788 uncor_ecc_flags, stat);
Chin Liang See03534df2014-09-12 00:42:17 -0500789 }
790
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900791 return stat;
Chin Liang See03534df2014-09-12 00:42:17 -0500792}
793
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900794static int denali_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
795 const uint8_t *buf, int oob_required, int page)
Chin Liang See03534df2014-09-12 00:42:17 -0500796{
797 struct denali_nand_info *denali = mtd_to_denali(mtd);
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900798 int writesize = mtd->writesize;
799 int oobsize = mtd->oobsize;
800 int ecc_steps = chip->ecc.steps;
801 int ecc_size = chip->ecc.size;
802 int ecc_bytes = chip->ecc.bytes;
803 void *tmp_buf = denali->buf;
804 int oob_skip = denali->oob_skip_bytes;
805 size_t size = writesize + oobsize;
806 int i, pos, len;
Chin Liang See03534df2014-09-12 00:42:17 -0500807
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900808 /*
809 * Fill the buffer with 0xff first except the full page transfer.
810 * This simplifies the logic.
811 */
812 if (!buf || !oob_required)
813 memset(tmp_buf, 0xff, size);
814
815 /* Arrange the buffer for syndrome payload/ecc layout */
816 if (buf) {
817 for (i = 0; i < ecc_steps; i++) {
818 pos = i * (ecc_size + ecc_bytes);
819 len = ecc_size;
820
821 if (pos >= writesize)
822 pos += oob_skip;
823 else if (pos + len > writesize)
824 len = writesize - pos;
825
826 memcpy(tmp_buf + pos, buf, len);
827 buf += len;
828 if (len < ecc_size) {
829 len = ecc_size - len;
830 memcpy(tmp_buf + writesize + oob_skip, buf,
831 len);
832 buf += len;
833 }
834 }
Chin Liang See03534df2014-09-12 00:42:17 -0500835 }
836
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900837 if (oob_required) {
838 const uint8_t *oob = chip->oob_poi;
Chin Liang See03534df2014-09-12 00:42:17 -0500839
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900840 /* BBM at the beginning of the OOB area */
841 memcpy(tmp_buf + writesize, oob, oob_skip);
842 oob += oob_skip;
Chin Liang See03534df2014-09-12 00:42:17 -0500843
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900844 /* OOB ECC */
845 for (i = 0; i < ecc_steps; i++) {
846 pos = ecc_size + i * (ecc_size + ecc_bytes);
847 len = ecc_bytes;
Chin Liang See03534df2014-09-12 00:42:17 -0500848
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900849 if (pos >= writesize)
850 pos += oob_skip;
851 else if (pos + len > writesize)
852 len = writesize - pos;
Chin Liang See03534df2014-09-12 00:42:17 -0500853
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900854 memcpy(tmp_buf + pos, oob, len);
855 oob += len;
856 if (len < ecc_bytes) {
857 len = ecc_bytes - len;
858 memcpy(tmp_buf + writesize + oob_skip, oob,
859 len);
860 oob += len;
861 }
Chin Liang See03534df2014-09-12 00:42:17 -0500862 }
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900863
864 /* OOB free */
865 len = oobsize - (oob - chip->oob_poi);
866 memcpy(tmp_buf + size - len, oob, len);
Chin Liang See03534df2014-09-12 00:42:17 -0500867 }
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900868
869 return denali_data_xfer(denali, tmp_buf, size, page, 1, 1);
Chin Liang See03534df2014-09-12 00:42:17 -0500870}
871
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900872static int denali_write_page(struct mtd_info *mtd, struct nand_chip *chip,
873 const uint8_t *buf, int oob_required, int page)
Chin Liang See03534df2014-09-12 00:42:17 -0500874{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900875 struct denali_nand_info *denali = mtd_to_denali(mtd);
Chin Liang See03534df2014-09-12 00:42:17 -0500876
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900877 return denali_data_xfer(denali, (void *)buf, mtd->writesize,
878 page, 0, 1);
Chin Liang See03534df2014-09-12 00:42:17 -0500879}
880
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900881static void denali_select_chip(struct mtd_info *mtd, int chip)
Chin Liang See03534df2014-09-12 00:42:17 -0500882{
883 struct denali_nand_info *denali = mtd_to_denali(mtd);
Chin Liang See03534df2014-09-12 00:42:17 -0500884
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900885 denali->active_bank = chip;
Chin Liang See03534df2014-09-12 00:42:17 -0500886}
887
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900888static int denali_waitfunc(struct mtd_info *mtd, struct nand_chip *chip)
Chin Liang See03534df2014-09-12 00:42:17 -0500889{
890 struct denali_nand_info *denali = mtd_to_denali(mtd);
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900891 uint32_t irq_status;
Chin Liang See03534df2014-09-12 00:42:17 -0500892
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900893 /* R/B# pin transitioned from low to high? */
894 irq_status = denali_wait_for_irq(denali, INTR__INT_ACT);
Chin Liang See03534df2014-09-12 00:42:17 -0500895
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900896 return irq_status & INTR__INT_ACT ? 0 : NAND_STATUS_FAIL;
Chin Liang See03534df2014-09-12 00:42:17 -0500897}
898
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900899static int denali_erase(struct mtd_info *mtd, int page)
Chin Liang See03534df2014-09-12 00:42:17 -0500900{
901 struct denali_nand_info *denali = mtd_to_denali(mtd);
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900902 uint32_t irq_status;
Chin Liang See03534df2014-09-12 00:42:17 -0500903
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900904 denali_reset_irq(denali);
Chin Liang See03534df2014-09-12 00:42:17 -0500905
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900906 denali->host_write(denali, DENALI_MAP10 | DENALI_BANK(denali) | page,
907 DENALI_ERASE);
Scott Wood3ea94ed2015-06-26 19:03:26 -0500908
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900909 /* wait for erase to complete or failure to occur */
910 irq_status = denali_wait_for_irq(denali,
911 INTR__ERASE_COMP | INTR__ERASE_FAIL);
Chin Liang See03534df2014-09-12 00:42:17 -0500912
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900913 return irq_status & INTR__ERASE_COMP ? 0 : NAND_STATUS_FAIL;
Chin Liang See03534df2014-09-12 00:42:17 -0500914}
915
Masahiro Yamada59a1f3e2017-11-29 19:18:18 +0900916static int denali_setup_data_interface(struct mtd_info *mtd, int chipnr,
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900917 const struct nand_data_interface *conf)
Chin Liang See03534df2014-09-12 00:42:17 -0500918{
919 struct denali_nand_info *denali = mtd_to_denali(mtd);
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900920 const struct nand_sdr_timings *timings;
Masahiro Yamada2d1fbc82018-12-19 20:03:18 +0900921 unsigned long t_x, mult_x;
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900922 int acc_clks, re_2_we, re_2_re, we_2_re, addr_2_data;
923 int rdwr_en_lo, rdwr_en_hi, rdwr_en_lo_hi, cs_setup;
924 int addr_2_data_mask;
925 uint32_t tmp;
Scott Wood3ea94ed2015-06-26 19:03:26 -0500926
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900927 timings = nand_get_sdr_timings(conf);
928 if (IS_ERR(timings))
929 return PTR_ERR(timings);
Chin Liang See03534df2014-09-12 00:42:17 -0500930
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900931 /* clk_x period in picoseconds */
Masahiro Yamada2d1fbc82018-12-19 20:03:18 +0900932 t_x = DIV_ROUND_DOWN_ULL(1000000000000ULL, denali->clk_x_rate);
933 if (!t_x)
934 return -EINVAL;
935
936 /*
937 * The bus interface clock, clk_x, is phase aligned with the core clock.
938 * The clk_x is an integral multiple N of the core clk. The value N is
939 * configured at IP delivery time, and its available value is 4, 5, 6.
940 */
941 mult_x = DIV_ROUND_CLOSEST_ULL(denali->clk_x_rate, denali->clk_rate);
942 if (mult_x < 4 || mult_x > 6)
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900943 return -EINVAL;
Chin Liang See03534df2014-09-12 00:42:17 -0500944
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900945 if (chipnr == NAND_DATA_IFACE_CHECK_ONLY)
946 return 0;
Chin Liang See03534df2014-09-12 00:42:17 -0500947
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900948 /* tREA -> ACC_CLKS */
Masahiro Yamada2d1fbc82018-12-19 20:03:18 +0900949 acc_clks = DIV_ROUND_UP(timings->tREA_max, t_x);
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900950 acc_clks = min_t(int, acc_clks, ACC_CLKS__VALUE);
951
952 tmp = ioread32(denali->reg + ACC_CLKS);
953 tmp &= ~ACC_CLKS__VALUE;
954 tmp |= FIELD_PREP(ACC_CLKS__VALUE, acc_clks);
955 iowrite32(tmp, denali->reg + ACC_CLKS);
956
957 /* tRWH -> RE_2_WE */
Masahiro Yamada2d1fbc82018-12-19 20:03:18 +0900958 re_2_we = DIV_ROUND_UP(timings->tRHW_min, t_x);
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900959 re_2_we = min_t(int, re_2_we, RE_2_WE__VALUE);
Chin Liang See03534df2014-09-12 00:42:17 -0500960
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900961 tmp = ioread32(denali->reg + RE_2_WE);
962 tmp &= ~RE_2_WE__VALUE;
963 tmp |= FIELD_PREP(RE_2_WE__VALUE, re_2_we);
964 iowrite32(tmp, denali->reg + RE_2_WE);
965
966 /* tRHZ -> RE_2_RE */
Masahiro Yamada2d1fbc82018-12-19 20:03:18 +0900967 re_2_re = DIV_ROUND_UP(timings->tRHZ_max, t_x);
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900968 re_2_re = min_t(int, re_2_re, RE_2_RE__VALUE);
969
970 tmp = ioread32(denali->reg + RE_2_RE);
971 tmp &= ~RE_2_RE__VALUE;
972 tmp |= FIELD_PREP(RE_2_RE__VALUE, re_2_re);
973 iowrite32(tmp, denali->reg + RE_2_RE);
974
975 /*
976 * tCCS, tWHR -> WE_2_RE
977 *
978 * With WE_2_RE properly set, the Denali controller automatically takes
979 * care of the delay; the driver need not set NAND_WAIT_TCCS.
980 */
Masahiro Yamada2d1fbc82018-12-19 20:03:18 +0900981 we_2_re = DIV_ROUND_UP(max(timings->tCCS_min, timings->tWHR_min), t_x);
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900982 we_2_re = min_t(int, we_2_re, TWHR2_AND_WE_2_RE__WE_2_RE);
983
984 tmp = ioread32(denali->reg + TWHR2_AND_WE_2_RE);
985 tmp &= ~TWHR2_AND_WE_2_RE__WE_2_RE;
986 tmp |= FIELD_PREP(TWHR2_AND_WE_2_RE__WE_2_RE, we_2_re);
987 iowrite32(tmp, denali->reg + TWHR2_AND_WE_2_RE);
988
989 /* tADL -> ADDR_2_DATA */
990
991 /* for older versions, ADDR_2_DATA is only 6 bit wide */
992 addr_2_data_mask = TCWAW_AND_ADDR_2_DATA__ADDR_2_DATA;
993 if (denali->revision < 0x0501)
994 addr_2_data_mask >>= 1;
995
Masahiro Yamada2d1fbc82018-12-19 20:03:18 +0900996 addr_2_data = DIV_ROUND_UP(timings->tADL_min, t_x);
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900997 addr_2_data = min_t(int, addr_2_data, addr_2_data_mask);
998
999 tmp = ioread32(denali->reg + TCWAW_AND_ADDR_2_DATA);
1000 tmp &= ~TCWAW_AND_ADDR_2_DATA__ADDR_2_DATA;
1001 tmp |= FIELD_PREP(TCWAW_AND_ADDR_2_DATA__ADDR_2_DATA, addr_2_data);
1002 iowrite32(tmp, denali->reg + TCWAW_AND_ADDR_2_DATA);
1003
1004 /* tREH, tWH -> RDWR_EN_HI_CNT */
1005 rdwr_en_hi = DIV_ROUND_UP(max(timings->tREH_min, timings->tWH_min),
Masahiro Yamada2d1fbc82018-12-19 20:03:18 +09001006 t_x);
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001007 rdwr_en_hi = min_t(int, rdwr_en_hi, RDWR_EN_HI_CNT__VALUE);
1008
1009 tmp = ioread32(denali->reg + RDWR_EN_HI_CNT);
1010 tmp &= ~RDWR_EN_HI_CNT__VALUE;
1011 tmp |= FIELD_PREP(RDWR_EN_HI_CNT__VALUE, rdwr_en_hi);
1012 iowrite32(tmp, denali->reg + RDWR_EN_HI_CNT);
1013
1014 /* tRP, tWP -> RDWR_EN_LO_CNT */
Masahiro Yamada2d1fbc82018-12-19 20:03:18 +09001015 rdwr_en_lo = DIV_ROUND_UP(max(timings->tRP_min, timings->tWP_min), t_x);
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001016 rdwr_en_lo_hi = DIV_ROUND_UP(max(timings->tRC_min, timings->tWC_min),
Masahiro Yamada2d1fbc82018-12-19 20:03:18 +09001017 t_x);
1018 rdwr_en_lo_hi = max_t(int, rdwr_en_lo_hi, mult_x);
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001019 rdwr_en_lo = max(rdwr_en_lo, rdwr_en_lo_hi - rdwr_en_hi);
1020 rdwr_en_lo = min_t(int, rdwr_en_lo, RDWR_EN_LO_CNT__VALUE);
1021
1022 tmp = ioread32(denali->reg + RDWR_EN_LO_CNT);
1023 tmp &= ~RDWR_EN_LO_CNT__VALUE;
1024 tmp |= FIELD_PREP(RDWR_EN_LO_CNT__VALUE, rdwr_en_lo);
1025 iowrite32(tmp, denali->reg + RDWR_EN_LO_CNT);
1026
1027 /* tCS, tCEA -> CS_SETUP_CNT */
Masahiro Yamada2d1fbc82018-12-19 20:03:18 +09001028 cs_setup = max3((int)DIV_ROUND_UP(timings->tCS_min, t_x) - rdwr_en_lo,
1029 (int)DIV_ROUND_UP(timings->tCEA_max, t_x) - acc_clks,
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001030 0);
1031 cs_setup = min_t(int, cs_setup, CS_SETUP_CNT__VALUE);
1032
1033 tmp = ioread32(denali->reg + CS_SETUP_CNT);
1034 tmp &= ~CS_SETUP_CNT__VALUE;
1035 tmp |= FIELD_PREP(CS_SETUP_CNT__VALUE, cs_setup);
1036 iowrite32(tmp, denali->reg + CS_SETUP_CNT);
Scott Wood3ea94ed2015-06-26 19:03:26 -05001037
1038 return 0;
Chin Liang See03534df2014-09-12 00:42:17 -05001039}
1040
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001041static void denali_reset_banks(struct denali_nand_info *denali)
Chin Liang See03534df2014-09-12 00:42:17 -05001042{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001043 u32 irq_status;
1044 int i;
Chin Liang See03534df2014-09-12 00:42:17 -05001045
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001046 for (i = 0; i < denali->max_banks; i++) {
1047 denali->active_bank = i;
1048
1049 denali_reset_irq(denali);
1050
1051 iowrite32(DEVICE_RESET__BANK(i),
1052 denali->reg + DEVICE_RESET);
1053
1054 irq_status = denali_wait_for_irq(denali,
1055 INTR__RST_COMP | INTR__INT_ACT | INTR__TIME_OUT);
1056 if (!(irq_status & INTR__INT_ACT))
1057 break;
Chin Liang See03534df2014-09-12 00:42:17 -05001058 }
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001059
1060 dev_dbg(denali->dev, "%d chips connected\n", i);
1061 denali->max_banks = i;
Chin Liang See03534df2014-09-12 00:42:17 -05001062}
Chin Liang See03534df2014-09-12 00:42:17 -05001063
Chin Liang See03534df2014-09-12 00:42:17 -05001064static void denali_hw_init(struct denali_nand_info *denali)
1065{
1066 /*
Masahiro Yamada54fde8e2017-09-15 21:43:19 +09001067 * The REVISION register may not be reliable. Platforms are allowed to
1068 * override it.
1069 */
1070 if (!denali->revision)
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001071 denali->revision = swab16(ioread32(denali->reg + REVISION));
Masahiro Yamada54fde8e2017-09-15 21:43:19 +09001072
1073 /*
Masahiro Yamada6be38732020-01-30 00:55:55 +09001074 * Set how many bytes should be skipped before writing data in OOB.
1075 * If a platform requests a non-zero value, set it to the register.
1076 * Otherwise, read the value out, expecting it has already been set up
1077 * by firmware.
Chin Liang See03534df2014-09-12 00:42:17 -05001078 */
Masahiro Yamada6be38732020-01-30 00:55:55 +09001079 if (denali->oob_skip_bytes)
1080 iowrite32(denali->oob_skip_bytes,
1081 denali->reg + SPARE_AREA_SKIP_BYTES);
1082 else
1083 denali->oob_skip_bytes = ioread32(denali->reg +
1084 SPARE_AREA_SKIP_BYTES);
1085
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001086 denali_detect_max_banks(denali);
1087 iowrite32(0x0F, denali->reg + RB_PIN_ENABLED);
1088 iowrite32(CHIP_EN_DONT_CARE__FLAG, denali->reg + CHIP_ENABLE_DONT_CARE);
Chin Liang See03534df2014-09-12 00:42:17 -05001089
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001090 iowrite32(0xffff, denali->reg + SPARE_AREA_MARKER);
Chin Liang See03534df2014-09-12 00:42:17 -05001091}
1092
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001093int denali_calc_ecc_bytes(int step_size, int strength)
1094{
1095 /* BCH code. Denali requires ecc.bytes to be multiple of 2 */
1096 return DIV_ROUND_UP(strength * fls(step_size * 8), 16) * 2;
1097}
1098EXPORT_SYMBOL(denali_calc_ecc_bytes);
Chin Liang See03534df2014-09-12 00:42:17 -05001099
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001100static int denali_ecc_setup(struct mtd_info *mtd, struct nand_chip *chip,
1101 struct denali_nand_info *denali)
Chin Liang See03534df2014-09-12 00:42:17 -05001102{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001103 int oobavail = mtd->oobsize - denali->oob_skip_bytes;
Masahiro Yamadada0763d2014-11-13 20:31:50 +09001104 int ret;
Chin Liang See03534df2014-09-12 00:42:17 -05001105
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001106 /*
1107 * If .size and .strength are already set (usually by DT),
1108 * check if they are supported by this controller.
1109 */
1110 if (chip->ecc.size && chip->ecc.strength)
1111 return nand_check_ecc_caps(chip, denali->ecc_caps, oobavail);
1112
1113 /*
1114 * We want .size and .strength closest to the chip's requirement
1115 * unless NAND_ECC_MAXIMIZE is requested.
1116 */
1117 if (!(chip->ecc.options & NAND_ECC_MAXIMIZE)) {
1118 ret = nand_match_ecc_req(chip, denali->ecc_caps, oobavail);
1119 if (!ret)
1120 return 0;
1121 }
1122
1123 /* Max ECC strength is the last thing we can do */
1124 return nand_maximize_ecc(chip, denali->ecc_caps, oobavail);
1125}
1126
1127static struct nand_ecclayout nand_oob;
1128
1129static int denali_ooblayout_ecc(struct mtd_info *mtd, int section,
1130 struct mtd_oob_region *oobregion)
1131{
1132 struct denali_nand_info *denali = mtd_to_denali(mtd);
1133 struct nand_chip *chip = mtd_to_nand(mtd);
1134
1135 if (section)
1136 return -ERANGE;
1137
1138 oobregion->offset = denali->oob_skip_bytes;
1139 oobregion->length = chip->ecc.total;
1140
1141 return 0;
1142}
1143
1144static int denali_ooblayout_free(struct mtd_info *mtd, int section,
1145 struct mtd_oob_region *oobregion)
1146{
1147 struct denali_nand_info *denali = mtd_to_denali(mtd);
1148 struct nand_chip *chip = mtd_to_nand(mtd);
1149
1150 if (section)
1151 return -ERANGE;
1152
1153 oobregion->offset = chip->ecc.total + denali->oob_skip_bytes;
1154 oobregion->length = mtd->oobsize - oobregion->offset;
1155
1156 return 0;
1157}
Chin Liang See03534df2014-09-12 00:42:17 -05001158
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001159static const struct mtd_ooblayout_ops denali_ooblayout_ops = {
1160 .ecc = denali_ooblayout_ecc,
Simon Glass62fd1a42020-02-03 07:35:56 -07001161 .rfree = denali_ooblayout_free,
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001162};
Chin Liang See03534df2014-09-12 00:42:17 -05001163
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001164static int denali_multidev_fixup(struct denali_nand_info *denali)
1165{
1166 struct nand_chip *chip = &denali->nand;
1167 struct mtd_info *mtd = nand_to_mtd(chip);
Masahiro Yamadada0763d2014-11-13 20:31:50 +09001168
1169 /*
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001170 * Support for multi device:
1171 * When the IP configuration is x16 capable and two x8 chips are
1172 * connected in parallel, DEVICES_CONNECTED should be set to 2.
1173 * In this case, the core framework knows nothing about this fact,
1174 * so we should tell it the _logical_ pagesize and anything necessary.
Masahiro Yamadada0763d2014-11-13 20:31:50 +09001175 */
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001176 denali->devs_per_cs = ioread32(denali->reg + DEVICES_CONNECTED);
Chin Liang See03534df2014-09-12 00:42:17 -05001177
Chin Liang See03534df2014-09-12 00:42:17 -05001178 /*
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001179 * On some SoCs, DEVICES_CONNECTED is not auto-detected.
1180 * For those, DEVICES_CONNECTED is left to 0. Set 1 if it is the case.
Chin Liang See03534df2014-09-12 00:42:17 -05001181 */
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001182 if (denali->devs_per_cs == 0) {
1183 denali->devs_per_cs = 1;
1184 iowrite32(1, denali->reg + DEVICES_CONNECTED);
1185 }
1186
1187 if (denali->devs_per_cs == 1)
1188 return 0;
1189
1190 if (denali->devs_per_cs != 2) {
1191 dev_err(denali->dev, "unsupported number of devices %d\n",
1192 denali->devs_per_cs);
1193 return -EINVAL;
1194 }
1195
1196 /* 2 chips in parallel */
1197 mtd->size <<= 1;
1198 mtd->erasesize <<= 1;
1199 mtd->writesize <<= 1;
1200 mtd->oobsize <<= 1;
1201 chip->chipsize <<= 1;
1202 chip->page_shift += 1;
1203 chip->phys_erase_shift += 1;
1204 chip->bbt_erase_shift += 1;
1205 chip->chip_shift += 1;
1206 chip->pagemask <<= 1;
1207 chip->ecc.size <<= 1;
1208 chip->ecc.bytes <<= 1;
1209 chip->ecc.strength <<= 1;
1210 denali->oob_skip_bytes <<= 1;
1211
1212 return 0;
1213}
1214
1215int denali_init(struct denali_nand_info *denali)
1216{
1217 struct nand_chip *chip = &denali->nand;
1218 struct mtd_info *mtd = nand_to_mtd(chip);
1219 u32 features = ioread32(denali->reg + FEATURES);
1220 int ret;
1221
1222 denali_hw_init(denali);
1223
1224 denali_clear_irq_all(denali);
1225
1226 denali_reset_banks(denali);
1227
1228 denali->active_bank = DENALI_INVALID_BANK;
1229
1230 chip->flash_node = dev_of_offset(denali->dev);
1231 /* Fallback to the default name if DT did not give "label" property */
1232 if (!mtd->name)
1233 mtd->name = "denali-nand";
Chin Liang See03534df2014-09-12 00:42:17 -05001234
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001235 chip->select_chip = denali_select_chip;
1236 chip->read_byte = denali_read_byte;
1237 chip->write_byte = denali_write_byte;
1238 chip->read_word = denali_read_word;
1239 chip->cmd_ctrl = denali_cmd_ctrl;
1240 chip->dev_ready = denali_dev_ready;
1241 chip->waitfunc = denali_waitfunc;
1242
1243 if (features & FEATURES__INDEX_ADDR) {
1244 denali->host_read = denali_indexed_read;
1245 denali->host_write = denali_indexed_write;
1246 } else {
1247 denali->host_read = denali_direct_read;
1248 denali->host_write = denali_direct_write;
1249 }
1250
1251 /* clk rate info is needed for setup_data_interface */
1252 if (denali->clk_x_rate)
1253 chip->setup_data_interface = denali_setup_data_interface;
1254
1255 ret = nand_scan_ident(mtd, denali->max_banks, NULL);
1256 if (ret)
1257 return ret;
1258
1259 if (ioread32(denali->reg + FEATURES) & FEATURES__DMA)
1260 denali->dma_avail = 1;
1261
1262 if (denali->dma_avail) {
Masahiro Yamadae83725e2018-07-19 10:13:23 +09001263 chip->buf_align = ARCH_DMA_MINALIGN;
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001264 if (denali->caps & DENALI_CAP_DMA_64BIT)
1265 denali->setup_dma = denali_setup_dma64;
1266 else
1267 denali->setup_dma = denali_setup_dma32;
1268 } else {
1269 chip->buf_align = 4;
1270 }
1271
1272 chip->options |= NAND_USE_BOUNCE_BUFFER;
1273 chip->bbt_options |= NAND_BBT_USE_FLASH;
1274 chip->bbt_options |= NAND_BBT_NO_OOB;
1275 denali->nand.ecc.mode = NAND_ECC_HW_SYNDROME;
Masahiro Yamadada0763d2014-11-13 20:31:50 +09001276
Scott Wood3ea94ed2015-06-26 19:03:26 -05001277 /* no subpage writes on denali */
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001278 chip->options |= NAND_NO_SUBPAGE_WRITE;
Scott Wood3ea94ed2015-06-26 19:03:26 -05001279
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001280 ret = denali_ecc_setup(mtd, chip, denali);
1281 if (ret) {
1282 dev_err(denali->dev, "Failed to setup ECC settings.\n");
1283 return ret;
Chin Liang See03534df2014-09-12 00:42:17 -05001284 }
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001285
1286 dev_dbg(denali->dev,
1287 "chosen ECC settings: step=%d, strength=%d, bytes=%d\n",
1288 chip->ecc.size, chip->ecc.strength, chip->ecc.bytes);
1289
1290 iowrite32(FIELD_PREP(ECC_CORRECTION__ERASE_THRESHOLD, 1) |
1291 FIELD_PREP(ECC_CORRECTION__VALUE, chip->ecc.strength),
1292 denali->reg + ECC_CORRECTION);
1293 iowrite32(mtd->erasesize / mtd->writesize,
1294 denali->reg + PAGES_PER_BLOCK);
1295 iowrite32(chip->options & NAND_BUSWIDTH_16 ? 1 : 0,
1296 denali->reg + DEVICE_WIDTH);
1297 iowrite32(chip->options & NAND_ROW_ADDR_3 ? 0 : TWO_ROW_ADDR_CYCLES__FLAG,
1298 denali->reg + TWO_ROW_ADDR_CYCLES);
1299 iowrite32(mtd->writesize, denali->reg + DEVICE_MAIN_AREA_SIZE);
1300 iowrite32(mtd->oobsize, denali->reg + DEVICE_SPARE_AREA_SIZE);
1301
1302 iowrite32(chip->ecc.size, denali->reg + CFG_DATA_BLOCK_SIZE);
1303 iowrite32(chip->ecc.size, denali->reg + CFG_LAST_DATA_BLOCK_SIZE);
1304 /* chip->ecc.steps is set by nand_scan_tail(); not available here */
1305 iowrite32(mtd->writesize / chip->ecc.size,
1306 denali->reg + CFG_NUM_DATA_BLOCKS);
1307
1308 mtd_set_ooblayout(mtd, &denali_ooblayout_ops);
1309
Masahiro Yamadada0763d2014-11-13 20:31:50 +09001310 nand_oob.eccbytes = denali->nand.ecc.bytes;
1311 denali->nand.ecc.layout = &nand_oob;
Chin Liang See03534df2014-09-12 00:42:17 -05001312
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001313 if (chip->options & NAND_BUSWIDTH_16) {
1314 chip->read_buf = denali_read_buf16;
1315 chip->write_buf = denali_write_buf16;
1316 } else {
1317 chip->read_buf = denali_read_buf;
1318 chip->write_buf = denali_write_buf;
1319 }
1320 chip->ecc.options |= NAND_ECC_CUSTOM_PAGE_ACCESS;
1321 chip->ecc.read_page = denali_read_page;
1322 chip->ecc.read_page_raw = denali_read_page_raw;
1323 chip->ecc.write_page = denali_write_page;
1324 chip->ecc.write_page_raw = denali_write_page_raw;
1325 chip->ecc.read_oob = denali_read_oob;
1326 chip->ecc.write_oob = denali_write_oob;
1327 chip->erase = denali_erase;
Masahiro Yamada628ee1e2014-11-13 20:31:51 +09001328
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001329 ret = denali_multidev_fixup(denali);
1330 if (ret)
1331 return ret;
Masahiro Yamadada0763d2014-11-13 20:31:50 +09001332
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001333 /*
1334 * This buffer is DMA-mapped by denali_{read,write}_page_raw. Do not
1335 * use devm_kmalloc() because the memory allocated by devm_ does not
1336 * guarantee DMA-safe alignment.
1337 */
1338 denali->buf = kmalloc(mtd->writesize + mtd->oobsize, GFP_KERNEL);
1339 if (!denali->buf)
1340 return -ENOMEM;
1341
1342 ret = nand_scan_tail(mtd);
1343 if (ret)
1344 goto free_buf;
Masahiro Yamadada0763d2014-11-13 20:31:50 +09001345
Scott Wood52ab7ce2016-05-30 13:57:58 -05001346 ret = nand_register(0, mtd);
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001347 if (ret) {
1348 dev_err(denali->dev, "Failed to register MTD: %d\n", ret);
1349 goto free_buf;
1350 }
1351 return 0;
1352
1353free_buf:
1354 kfree(denali->buf);
Masahiro Yamadada0763d2014-11-13 20:31:50 +09001355
Masahiro Yamadada0763d2014-11-13 20:31:50 +09001356 return ret;
Chin Liang See03534df2014-09-12 00:42:17 -05001357}