blob: 8537c609fb620dfadd4c38da15307800e1da2670 [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>
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +090011#include <linux/bitfield.h>
12#include <linux/dma-direction.h>
Masahiro Yamada56a931c2016-09-21 11:28:55 +090013#include <linux/errno.h>
Masahiro Yamada54fde8e2017-09-15 21:43:19 +090014#include <linux/io.h>
Masahiro Yamada5beb1b32017-11-30 13:45:27 +090015#include <linux/mtd/mtd.h>
16#include <linux/mtd/rawnand.h>
Chin Liang See03534df2014-09-12 00:42:17 -050017
18#include "denali.h"
19
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +090020#define DENALI_NAND_NAME "denali-nand"
Chin Liang See03534df2014-09-12 00:42:17 -050021
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +090022/* for Indexed Addressing */
23#define DENALI_INDEXED_CTRL 0x00
24#define DENALI_INDEXED_DATA 0x10
Chin Liang See03534df2014-09-12 00:42:17 -050025
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +090026#define DENALI_MAP00 (0 << 26) /* direct access to buffer */
27#define DENALI_MAP01 (1 << 26) /* read/write pages in PIO */
28#define DENALI_MAP10 (2 << 26) /* high-level control plane */
29#define DENALI_MAP11 (3 << 26) /* direct controller access */
Chin Liang See03534df2014-09-12 00:42:17 -050030
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +090031/* MAP11 access cycle type */
32#define DENALI_MAP11_CMD ((DENALI_MAP11) | 0) /* command cycle */
33#define DENALI_MAP11_ADDR ((DENALI_MAP11) | 1) /* address cycle */
34#define DENALI_MAP11_DATA ((DENALI_MAP11) | 2) /* data cycle */
Chin Liang See03534df2014-09-12 00:42:17 -050035
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +090036/* MAP10 commands */
37#define DENALI_ERASE 0x01
Chin Liang See03534df2014-09-12 00:42:17 -050038
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +090039#define DENALI_BANK(denali) ((denali)->active_bank << 24)
Chin Liang See03534df2014-09-12 00:42:17 -050040
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +090041#define DENALI_INVALID_BANK -1
42#define DENALI_NR_BANKS 4
Chin Liang See03534df2014-09-12 00:42:17 -050043
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +090044static inline struct denali_nand_info *mtd_to_denali(struct mtd_info *mtd)
Chin Liang See03534df2014-09-12 00:42:17 -050045{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +090046 return container_of(mtd_to_nand(mtd), struct denali_nand_info, nand);
Chin Liang See03534df2014-09-12 00:42:17 -050047}
48
49/*
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +090050 * Direct Addressing - the slave address forms the control information (command
51 * type, bank, block, and page address). The slave data is the actual data to
52 * be transferred. This mode requires 28 bits of address region allocated.
Scott Wood3ea94ed2015-06-26 19:03:26 -050053 */
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +090054static u32 denali_direct_read(struct denali_nand_info *denali, u32 addr)
Chin Liang See03534df2014-09-12 00:42:17 -050055{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +090056 return ioread32(denali->host + addr);
Chin Liang See03534df2014-09-12 00:42:17 -050057}
58
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +090059static void denali_direct_write(struct denali_nand_info *denali, u32 addr,
60 u32 data)
Chin Liang See03534df2014-09-12 00:42:17 -050061{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +090062 iowrite32(data, denali->host + addr);
Chin Liang See03534df2014-09-12 00:42:17 -050063}
64
Scott Wood3ea94ed2015-06-26 19:03:26 -050065/*
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +090066 * Indexed Addressing - address translation module intervenes in passing the
67 * control information. This mode reduces the required address range. The
68 * control information and transferred data are latched by the registers in
69 * the translation module.
Scott Wood3ea94ed2015-06-26 19:03:26 -050070 */
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +090071static u32 denali_indexed_read(struct denali_nand_info *denali, u32 addr)
Chin Liang See03534df2014-09-12 00:42:17 -050072{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +090073 iowrite32(addr, denali->host + DENALI_INDEXED_CTRL);
74 return ioread32(denali->host + DENALI_INDEXED_DATA);
Chin Liang See03534df2014-09-12 00:42:17 -050075}
76
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +090077static void denali_indexed_write(struct denali_nand_info *denali, u32 addr,
78 u32 data)
Chin Liang See03534df2014-09-12 00:42:17 -050079{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +090080 iowrite32(addr, denali->host + DENALI_INDEXED_CTRL);
81 iowrite32(data, denali->host + DENALI_INDEXED_DATA);
Chin Liang See03534df2014-09-12 00:42:17 -050082}
83
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +090084/*
85 * Use the configuration feature register to determine the maximum number of
86 * banks that the hardware supports.
87 */
88static void denali_detect_max_banks(struct denali_nand_info *denali)
Chin Liang See03534df2014-09-12 00:42:17 -050089{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +090090 uint32_t features = ioread32(denali->reg + FEATURES);
Chin Liang See03534df2014-09-12 00:42:17 -050091
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +090092 denali->max_banks = 1 << FIELD_GET(FEATURES__N_BANKS, features);
Chin Liang See03534df2014-09-12 00:42:17 -050093
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +090094 /* the encoding changed from rev 5.0 to 5.1 */
95 if (denali->revision < 0x0501)
96 denali->max_banks <<= 1;
Chin Liang See03534df2014-09-12 00:42:17 -050097}
98
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +090099static void __maybe_unused denali_enable_irq(struct denali_nand_info *denali)
Chin Liang See03534df2014-09-12 00:42:17 -0500100{
Scott Wood3ea94ed2015-06-26 19:03:26 -0500101 int i;
Chin Liang See03534df2014-09-12 00:42:17 -0500102
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900103 for (i = 0; i < DENALI_NR_BANKS; i++)
104 iowrite32(U32_MAX, denali->reg + INTR_EN(i));
105 iowrite32(GLOBAL_INT_EN_FLAG, denali->reg + GLOBAL_INT_ENABLE);
Chin Liang See03534df2014-09-12 00:42:17 -0500106}
107
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900108static void __maybe_unused denali_disable_irq(struct denali_nand_info *denali)
Chin Liang See03534df2014-09-12 00:42:17 -0500109{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900110 int i;
Chin Liang See03534df2014-09-12 00:42:17 -0500111
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900112 for (i = 0; i < DENALI_NR_BANKS; i++)
113 iowrite32(0, denali->reg + INTR_EN(i));
114 iowrite32(0, denali->reg + GLOBAL_INT_ENABLE);
115}
Chin Liang See03534df2014-09-12 00:42:17 -0500116
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900117static void denali_clear_irq(struct denali_nand_info *denali,
118 int bank, uint32_t irq_status)
119{
120 /* write one to clear bits */
121 iowrite32(irq_status, denali->reg + INTR_STATUS(bank));
122}
Chin Liang See03534df2014-09-12 00:42:17 -0500123
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900124static void denali_clear_irq_all(struct denali_nand_info *denali)
125{
126 int i;
Chin Liang See03534df2014-09-12 00:42:17 -0500127
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900128 for (i = 0; i < DENALI_NR_BANKS; i++)
129 denali_clear_irq(denali, i, U32_MAX);
130}
Chin Liang See03534df2014-09-12 00:42:17 -0500131
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900132static void __denali_check_irq(struct denali_nand_info *denali)
133{
134 uint32_t irq_status;
135 int i;
Chin Liang See03534df2014-09-12 00:42:17 -0500136
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900137 for (i = 0; i < DENALI_NR_BANKS; i++) {
138 irq_status = ioread32(denali->reg + INTR_STATUS(i));
139 denali_clear_irq(denali, i, irq_status);
Chin Liang See03534df2014-09-12 00:42:17 -0500140
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900141 if (i != denali->active_bank)
142 continue;
Chin Liang See03534df2014-09-12 00:42:17 -0500143
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900144 denali->irq_status |= irq_status;
Chin Liang See03534df2014-09-12 00:42:17 -0500145 }
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900146}
Chin Liang See03534df2014-09-12 00:42:17 -0500147
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900148static void denali_reset_irq(struct denali_nand_info *denali)
149{
150 denali->irq_status = 0;
151 denali->irq_mask = 0;
152}
Chin Liang See03534df2014-09-12 00:42:17 -0500153
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900154static uint32_t denali_wait_for_irq(struct denali_nand_info *denali,
155 uint32_t irq_mask)
156{
157 unsigned long time_left = 1000000;
Chin Liang See03534df2014-09-12 00:42:17 -0500158
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900159 while (time_left) {
160 __denali_check_irq(denali);
Chin Liang See03534df2014-09-12 00:42:17 -0500161
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900162 if (irq_mask & denali->irq_status)
163 return denali->irq_status;
164 udelay(1);
165 time_left--;
Chin Liang See03534df2014-09-12 00:42:17 -0500166 }
167
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900168 if (!time_left) {
169 dev_err(denali->dev, "timeout while waiting for irq 0x%x\n",
170 irq_mask);
171 return 0;
172 }
Chin Liang See03534df2014-09-12 00:42:17 -0500173
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900174 return denali->irq_status;
Chin Liang See03534df2014-09-12 00:42:17 -0500175}
176
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900177static uint32_t denali_check_irq(struct denali_nand_info *denali)
Chin Liang See03534df2014-09-12 00:42:17 -0500178{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900179 __denali_check_irq(denali);
Scott Wood3ea94ed2015-06-26 19:03:26 -0500180
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900181 return denali->irq_status;
Chin Liang See03534df2014-09-12 00:42:17 -0500182}
183
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900184static void denali_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
Chin Liang See03534df2014-09-12 00:42:17 -0500185{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900186 struct denali_nand_info *denali = mtd_to_denali(mtd);
187 u32 addr = DENALI_MAP11_DATA | DENALI_BANK(denali);
188 int i;
189
190 for (i = 0; i < len; i++)
191 buf[i] = denali->host_read(denali, addr);
Chin Liang See03534df2014-09-12 00:42:17 -0500192}
193
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900194static void denali_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
Chin Liang See03534df2014-09-12 00:42:17 -0500195{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900196 struct denali_nand_info *denali = mtd_to_denali(mtd);
197 u32 addr = DENALI_MAP11_DATA | DENALI_BANK(denali);
198 int i;
Chin Liang See03534df2014-09-12 00:42:17 -0500199
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900200 for (i = 0; i < len; i++)
201 denali->host_write(denali, addr, buf[i]);
Chin Liang See03534df2014-09-12 00:42:17 -0500202}
203
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900204static void denali_read_buf16(struct mtd_info *mtd, uint8_t *buf, int len)
Chin Liang See03534df2014-09-12 00:42:17 -0500205{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900206 struct denali_nand_info *denali = mtd_to_denali(mtd);
207 u32 addr = DENALI_MAP11_DATA | DENALI_BANK(denali);
208 uint16_t *buf16 = (uint16_t *)buf;
209 int i;
Chin Liang See03534df2014-09-12 00:42:17 -0500210
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900211 for (i = 0; i < len / 2; i++)
212 buf16[i] = denali->host_read(denali, addr);
Chin Liang See03534df2014-09-12 00:42:17 -0500213}
214
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900215static void denali_write_buf16(struct mtd_info *mtd, const uint8_t *buf,
216 int len)
Chin Liang See03534df2014-09-12 00:42:17 -0500217{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900218 struct denali_nand_info *denali = mtd_to_denali(mtd);
219 u32 addr = DENALI_MAP11_DATA | DENALI_BANK(denali);
220 const uint16_t *buf16 = (const uint16_t *)buf;
Chin Liang See03534df2014-09-12 00:42:17 -0500221 int i;
222
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900223 for (i = 0; i < len / 2; i++)
224 denali->host_write(denali, addr, buf16[i]);
Chin Liang See03534df2014-09-12 00:42:17 -0500225}
226
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900227static uint8_t denali_read_byte(struct mtd_info *mtd)
Chin Liang See03534df2014-09-12 00:42:17 -0500228{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900229 uint8_t byte;
Masahiro Yamada54fde8e2017-09-15 21:43:19 +0900230
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900231 denali_read_buf(mtd, &byte, 1);
Masahiro Yamada54fde8e2017-09-15 21:43:19 +0900232
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900233 return byte;
Chin Liang See03534df2014-09-12 00:42:17 -0500234}
235
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900236static void denali_write_byte(struct mtd_info *mtd, uint8_t byte)
Chin Liang See03534df2014-09-12 00:42:17 -0500237{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900238 denali_write_buf(mtd, &byte, 1);
Chin Liang See03534df2014-09-12 00:42:17 -0500239}
240
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900241static uint16_t denali_read_word(struct mtd_info *mtd)
Chin Liang See03534df2014-09-12 00:42:17 -0500242{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900243 uint16_t word;
Chin Liang See03534df2014-09-12 00:42:17 -0500244
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900245 denali_read_buf16(mtd, (uint8_t *)&word, 2);
Chin Liang See03534df2014-09-12 00:42:17 -0500246
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900247 return word;
248}
Chin Liang See03534df2014-09-12 00:42:17 -0500249
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900250static void denali_cmd_ctrl(struct mtd_info *mtd, int dat, unsigned int ctrl)
251{
252 struct denali_nand_info *denali = mtd_to_denali(mtd);
253 uint32_t type;
Chin Liang See03534df2014-09-12 00:42:17 -0500254
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900255 if (ctrl & NAND_CLE)
256 type = DENALI_MAP11_CMD;
257 else if (ctrl & NAND_ALE)
258 type = DENALI_MAP11_ADDR;
259 else
260 return;
Chin Liang See03534df2014-09-12 00:42:17 -0500261
Scott Wood3ea94ed2015-06-26 19:03:26 -0500262 /*
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900263 * Some commands are followed by chip->dev_ready or chip->waitfunc.
264 * irq_status must be cleared here to catch the R/B# interrupt later.
Chin Liang See03534df2014-09-12 00:42:17 -0500265 */
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900266 if (ctrl & NAND_CTRL_CHANGE)
267 denali_reset_irq(denali);
Chin Liang See03534df2014-09-12 00:42:17 -0500268
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900269 denali->host_write(denali, DENALI_BANK(denali) | type, dat);
Chin Liang See03534df2014-09-12 00:42:17 -0500270}
271
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900272static int denali_dev_ready(struct mtd_info *mtd)
Chin Liang See03534df2014-09-12 00:42:17 -0500273{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900274 struct denali_nand_info *denali = mtd_to_denali(mtd);
275
276 return !!(denali_check_irq(denali) & INTR__INT_ACT);
Chin Liang See03534df2014-09-12 00:42:17 -0500277}
278
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900279static int denali_check_erased_page(struct mtd_info *mtd,
280 struct nand_chip *chip, uint8_t *buf,
281 unsigned long uncor_ecc_flags,
282 unsigned int max_bitflips)
Chin Liang See03534df2014-09-12 00:42:17 -0500283{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900284 uint8_t *ecc_code = chip->buffers->ecccode;
285 int ecc_steps = chip->ecc.steps;
286 int ecc_size = chip->ecc.size;
287 int ecc_bytes = chip->ecc.bytes;
288 int i, ret, stat;
Chin Liang See03534df2014-09-12 00:42:17 -0500289
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900290 ret = mtd_ooblayout_get_eccbytes(mtd, ecc_code, chip->oob_poi, 0,
291 chip->ecc.total);
292 if (ret)
293 return ret;
Chin Liang See03534df2014-09-12 00:42:17 -0500294
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900295 for (i = 0; i < ecc_steps; i++) {
296 if (!(uncor_ecc_flags & BIT(i)))
297 continue;
Chin Liang See03534df2014-09-12 00:42:17 -0500298
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900299 stat = nand_check_erased_ecc_chunk(buf, ecc_size,
300 ecc_code, ecc_bytes,
301 NULL, 0,
302 chip->ecc.strength);
303 if (stat < 0) {
304 mtd->ecc_stats.failed++;
305 } else {
306 mtd->ecc_stats.corrected += stat;
307 max_bitflips = max_t(unsigned int, max_bitflips, stat);
308 }
Chin Liang See03534df2014-09-12 00:42:17 -0500309
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900310 buf += ecc_size;
311 ecc_code += ecc_bytes;
312 }
313
314 return max_bitflips;
Chin Liang See03534df2014-09-12 00:42:17 -0500315}
316
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900317static int denali_hw_ecc_fixup(struct mtd_info *mtd,
318 struct denali_nand_info *denali,
319 unsigned long *uncor_ecc_flags)
Chin Liang See03534df2014-09-12 00:42:17 -0500320{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900321 struct nand_chip *chip = mtd_to_nand(mtd);
322 int bank = denali->active_bank;
323 uint32_t ecc_cor;
324 unsigned int max_bitflips;
Chin Liang See03534df2014-09-12 00:42:17 -0500325
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900326 ecc_cor = ioread32(denali->reg + ECC_COR_INFO(bank));
327 ecc_cor >>= ECC_COR_INFO__SHIFT(bank);
328
329 if (ecc_cor & ECC_COR_INFO__UNCOR_ERR) {
330 /*
331 * This flag is set when uncorrectable error occurs at least in
332 * one ECC sector. We can not know "how many sectors", or
333 * "which sector(s)". We need erase-page check for all sectors.
334 */
335 *uncor_ecc_flags = GENMASK(chip->ecc.steps - 1, 0);
336 return 0;
337 }
Chin Liang See03534df2014-09-12 00:42:17 -0500338
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900339 max_bitflips = FIELD_GET(ECC_COR_INFO__MAX_ERRORS, ecc_cor);
340
341 /*
342 * The register holds the maximum of per-sector corrected bitflips.
343 * This is suitable for the return value of the ->read_page() callback.
344 * Unfortunately, we can not know the total number of corrected bits in
345 * the page. Increase the stats by max_bitflips. (compromised solution)
346 */
347 mtd->ecc_stats.corrected += max_bitflips;
348
349 return max_bitflips;
Chin Liang See03534df2014-09-12 00:42:17 -0500350}
351
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900352static int denali_sw_ecc_fixup(struct mtd_info *mtd,
353 struct denali_nand_info *denali,
354 unsigned long *uncor_ecc_flags, uint8_t *buf)
Chin Liang See03534df2014-09-12 00:42:17 -0500355{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900356 unsigned int ecc_size = denali->nand.ecc.size;
357 unsigned int bitflips = 0;
358 unsigned int max_bitflips = 0;
359 uint32_t err_addr, err_cor_info;
360 unsigned int err_byte, err_sector, err_device;
361 uint8_t err_cor_value;
362 unsigned int prev_sector = 0;
363 uint32_t irq_status;
Chin Liang See03534df2014-09-12 00:42:17 -0500364
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900365 denali_reset_irq(denali);
Chin Liang See03534df2014-09-12 00:42:17 -0500366
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900367 do {
368 err_addr = ioread32(denali->reg + ECC_ERROR_ADDRESS);
369 err_sector = FIELD_GET(ECC_ERROR_ADDRESS__SECTOR, err_addr);
370 err_byte = FIELD_GET(ECC_ERROR_ADDRESS__OFFSET, err_addr);
Chin Liang See03534df2014-09-12 00:42:17 -0500371
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900372 err_cor_info = ioread32(denali->reg + ERR_CORRECTION_INFO);
373 err_cor_value = FIELD_GET(ERR_CORRECTION_INFO__BYTE,
374 err_cor_info);
375 err_device = FIELD_GET(ERR_CORRECTION_INFO__DEVICE,
376 err_cor_info);
Chin Liang See03534df2014-09-12 00:42:17 -0500377
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900378 /* reset the bitflip counter when crossing ECC sector */
379 if (err_sector != prev_sector)
380 bitflips = 0;
Chin Liang See03534df2014-09-12 00:42:17 -0500381
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900382 if (err_cor_info & ERR_CORRECTION_INFO__UNCOR) {
383 /*
384 * Check later if this is a real ECC error, or
385 * an erased sector.
386 */
387 *uncor_ecc_flags |= BIT(err_sector);
388 } else if (err_byte < ecc_size) {
389 /*
390 * If err_byte is larger than ecc_size, means error
391 * happened in OOB, so we ignore it. It's no need for
392 * us to correct it err_device is represented the NAND
393 * error bits are happened in if there are more than
394 * one NAND connected.
395 */
396 int offset;
397 unsigned int flips_in_byte;
Chin Liang See03534df2014-09-12 00:42:17 -0500398
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900399 offset = (err_sector * ecc_size + err_byte) *
400 denali->devs_per_cs + err_device;
Chin Liang See03534df2014-09-12 00:42:17 -0500401
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900402 /* correct the ECC error */
403 flips_in_byte = hweight8(buf[offset] ^ err_cor_value);
404 buf[offset] ^= err_cor_value;
405 mtd->ecc_stats.corrected += flips_in_byte;
406 bitflips += flips_in_byte;
Chin Liang See03534df2014-09-12 00:42:17 -0500407
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900408 max_bitflips = max(max_bitflips, bitflips);
409 }
Chin Liang See03534df2014-09-12 00:42:17 -0500410
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900411 prev_sector = err_sector;
412 } while (!(err_cor_info & ERR_CORRECTION_INFO__LAST_ERR));
Chin Liang See03534df2014-09-12 00:42:17 -0500413
Scott Wood3ea94ed2015-06-26 19:03:26 -0500414 /*
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900415 * Once handle all ECC errors, controller will trigger an
416 * ECC_TRANSACTION_DONE interrupt.
Scott Wood3ea94ed2015-06-26 19:03:26 -0500417 */
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900418 irq_status = denali_wait_for_irq(denali, INTR__ECC_TRANSACTION_DONE);
419 if (!(irq_status & INTR__ECC_TRANSACTION_DONE))
420 return -EIO;
Chin Liang See03534df2014-09-12 00:42:17 -0500421
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900422 return max_bitflips;
Chin Liang See03534df2014-09-12 00:42:17 -0500423}
424
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900425static void denali_setup_dma64(struct denali_nand_info *denali,
426 dma_addr_t dma_addr, int page, int write)
Chin Liang See03534df2014-09-12 00:42:17 -0500427{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900428 uint32_t mode;
429 const int page_count = 1;
Chin Liang See03534df2014-09-12 00:42:17 -0500430
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900431 mode = DENALI_MAP10 | DENALI_BANK(denali) | page;
Chin Liang See03534df2014-09-12 00:42:17 -0500432
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900433 /* DMA is a three step process */
Chin Liang See03534df2014-09-12 00:42:17 -0500434
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900435 /*
436 * 1. setup transfer type, interrupt when complete,
437 * burst len = 64 bytes, the number of pages
438 */
439 denali->host_write(denali, mode,
440 0x01002000 | (64 << 16) | (write << 8) | page_count);
Chin Liang See03534df2014-09-12 00:42:17 -0500441
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900442 /* 2. set memory low address */
443 denali->host_write(denali, mode, lower_32_bits(dma_addr));
Chin Liang See03534df2014-09-12 00:42:17 -0500444
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900445 /* 3. set memory high address */
446 denali->host_write(denali, mode, upper_32_bits(dma_addr));
Chin Liang See03534df2014-09-12 00:42:17 -0500447}
448
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900449static void denali_setup_dma32(struct denali_nand_info *denali,
450 dma_addr_t dma_addr, int page, int write)
Chin Liang See03534df2014-09-12 00:42:17 -0500451{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900452 uint32_t mode;
453 const int page_count = 1;
Chin Liang See03534df2014-09-12 00:42:17 -0500454
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900455 mode = DENALI_MAP10 | DENALI_BANK(denali);
Chin Liang See03534df2014-09-12 00:42:17 -0500456
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900457 /* DMA is a four step process */
Chin Liang See03534df2014-09-12 00:42:17 -0500458
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900459 /* 1. setup transfer type and # of pages */
460 denali->host_write(denali, mode | page,
461 0x2000 | (write << 8) | page_count);
Chin Liang See03534df2014-09-12 00:42:17 -0500462
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900463 /* 2. set memory high address bits 23:8 */
464 denali->host_write(denali, mode | ((dma_addr >> 16) << 8), 0x2200);
Chin Liang See03534df2014-09-12 00:42:17 -0500465
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900466 /* 3. set memory low address bits 23:8 */
467 denali->host_write(denali, mode | ((dma_addr & 0xffff) << 8), 0x2300);
Chin Liang See03534df2014-09-12 00:42:17 -0500468
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900469 /* 4. interrupt when complete, burst len = 64 bytes */
470 denali->host_write(denali, mode | 0x14000, 0x2400);
Chin Liang See03534df2014-09-12 00:42:17 -0500471}
472
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900473static int denali_pio_read(struct denali_nand_info *denali, void *buf,
474 size_t size, int page, int raw)
Chin Liang See03534df2014-09-12 00:42:17 -0500475{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900476 u32 addr = DENALI_MAP01 | DENALI_BANK(denali) | page;
477 uint32_t *buf32 = (uint32_t *)buf;
478 uint32_t irq_status, ecc_err_mask;
479 int i;
Chin Liang See03534df2014-09-12 00:42:17 -0500480
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900481 if (denali->caps & DENALI_CAP_HW_ECC_FIXUP)
482 ecc_err_mask = INTR__ECC_UNCOR_ERR;
483 else
484 ecc_err_mask = INTR__ECC_ERR;
Chin Liang See03534df2014-09-12 00:42:17 -0500485
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900486 denali_reset_irq(denali);
Chin Liang See03534df2014-09-12 00:42:17 -0500487
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900488 for (i = 0; i < size / 4; i++)
489 *buf32++ = denali->host_read(denali, addr);
Chin Liang See03534df2014-09-12 00:42:17 -0500490
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900491 irq_status = denali_wait_for_irq(denali, INTR__PAGE_XFER_INC);
492 if (!(irq_status & INTR__PAGE_XFER_INC))
493 return -EIO;
Chin Liang See03534df2014-09-12 00:42:17 -0500494
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900495 if (irq_status & INTR__ERASED_PAGE)
496 memset(buf, 0xff, size);
497
498 return irq_status & ecc_err_mask ? -EBADMSG : 0;
Chin Liang See03534df2014-09-12 00:42:17 -0500499}
500
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900501static int denali_pio_write(struct denali_nand_info *denali,
502 const void *buf, size_t size, int page, int raw)
Chin Liang See03534df2014-09-12 00:42:17 -0500503{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900504 u32 addr = DENALI_MAP01 | DENALI_BANK(denali) | page;
505 const uint32_t *buf32 = (uint32_t *)buf;
506 uint32_t irq_status;
Scott Wood3ea94ed2015-06-26 19:03:26 -0500507 int i;
508
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900509 denali_reset_irq(denali);
510
511 for (i = 0; i < size / 4; i++)
512 denali->host_write(denali, addr, *buf32++);
513
514 irq_status = denali_wait_for_irq(denali,
515 INTR__PROGRAM_COMP | INTR__PROGRAM_FAIL);
516 if (!(irq_status & INTR__PROGRAM_COMP))
517 return -EIO;
518
519 return 0;
Chin Liang See03534df2014-09-12 00:42:17 -0500520}
521
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900522static int denali_pio_xfer(struct denali_nand_info *denali, void *buf,
523 size_t size, int page, int raw, int write)
Chin Liang See03534df2014-09-12 00:42:17 -0500524{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900525 if (write)
526 return denali_pio_write(denali, buf, size, page, raw);
527 else
528 return denali_pio_read(denali, buf, size, page, raw);
Chin Liang See03534df2014-09-12 00:42:17 -0500529}
530
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900531static int denali_dma_xfer(struct denali_nand_info *denali, void *buf,
532 size_t size, int page, int raw, int write)
Chin Liang See03534df2014-09-12 00:42:17 -0500533{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900534 dma_addr_t dma_addr;
535 uint32_t irq_mask, irq_status, ecc_err_mask;
536 enum dma_data_direction dir = write ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
537 int ret = 0;
Chin Liang See03534df2014-09-12 00:42:17 -0500538
Vignesh Raghavendradd62b9a2020-01-16 14:23:47 +0530539 dma_addr = dma_map_single(buf, size, dir);
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900540 if (dma_mapping_error(denali->dev, dma_addr)) {
541 dev_dbg(denali->dev, "Failed to DMA-map buffer. Trying PIO.\n");
542 return denali_pio_xfer(denali, buf, size, page, raw, write);
543 }
Chin Liang See03534df2014-09-12 00:42:17 -0500544
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900545 if (write) {
546 /*
547 * INTR__PROGRAM_COMP is never asserted for the DMA transfer.
548 * We can use INTR__DMA_CMD_COMP instead. This flag is asserted
549 * when the page program is completed.
550 */
551 irq_mask = INTR__DMA_CMD_COMP | INTR__PROGRAM_FAIL;
552 ecc_err_mask = 0;
553 } else if (denali->caps & DENALI_CAP_HW_ECC_FIXUP) {
554 irq_mask = INTR__DMA_CMD_COMP;
555 ecc_err_mask = INTR__ECC_UNCOR_ERR;
556 } else {
557 irq_mask = INTR__DMA_CMD_COMP;
558 ecc_err_mask = INTR__ECC_ERR;
559 }
Chin Liang See03534df2014-09-12 00:42:17 -0500560
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900561 iowrite32(DMA_ENABLE__FLAG, denali->reg + DMA_ENABLE);
Masahiro Yamada9ea23972018-12-19 20:03:19 +0900562 /*
563 * The ->setup_dma() hook kicks DMA by using the data/command
564 * interface, which belongs to a different AXI port from the
565 * register interface. Read back the register to avoid a race.
566 */
567 ioread32(denali->reg + DMA_ENABLE);
Chin Liang See03534df2014-09-12 00:42:17 -0500568
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900569 denali_reset_irq(denali);
570 denali->setup_dma(denali, dma_addr, page, write);
Chin Liang See03534df2014-09-12 00:42:17 -0500571
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900572 irq_status = denali_wait_for_irq(denali, irq_mask);
573 if (!(irq_status & INTR__DMA_CMD_COMP))
574 ret = -EIO;
575 else if (irq_status & ecc_err_mask)
576 ret = -EBADMSG;
Chin Liang See03534df2014-09-12 00:42:17 -0500577
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900578 iowrite32(0, denali->reg + DMA_ENABLE);
Chin Liang See03534df2014-09-12 00:42:17 -0500579
Vignesh Raghavendradd62b9a2020-01-16 14:23:47 +0530580 dma_unmap_single(buf, size, dir);
Chin Liang See03534df2014-09-12 00:42:17 -0500581
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900582 if (irq_status & INTR__ERASED_PAGE)
583 memset(buf, 0xff, size);
Chin Liang See03534df2014-09-12 00:42:17 -0500584
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900585 return ret;
Chin Liang See03534df2014-09-12 00:42:17 -0500586}
587
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900588static int denali_data_xfer(struct denali_nand_info *denali, void *buf,
589 size_t size, int page, int raw, int write)
Chin Liang See03534df2014-09-12 00:42:17 -0500590{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900591 iowrite32(raw ? 0 : ECC_ENABLE__FLAG, denali->reg + ECC_ENABLE);
592 iowrite32(raw ? TRANSFER_SPARE_REG__FLAG : 0,
593 denali->reg + TRANSFER_SPARE_REG);
Chin Liang See03534df2014-09-12 00:42:17 -0500594
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900595 if (denali->dma_avail)
596 return denali_dma_xfer(denali, buf, size, page, raw, write);
597 else
598 return denali_pio_xfer(denali, buf, size, page, raw, write);
599}
Chin Liang See03534df2014-09-12 00:42:17 -0500600
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900601static void denali_oob_xfer(struct mtd_info *mtd, struct nand_chip *chip,
602 int page, int write)
603{
604 struct denali_nand_info *denali = mtd_to_denali(mtd);
605 unsigned int start_cmd = write ? NAND_CMD_SEQIN : NAND_CMD_READ0;
606 unsigned int rnd_cmd = write ? NAND_CMD_RNDIN : NAND_CMD_RNDOUT;
607 int writesize = mtd->writesize;
608 int oobsize = mtd->oobsize;
609 uint8_t *bufpoi = chip->oob_poi;
610 int ecc_steps = chip->ecc.steps;
611 int ecc_size = chip->ecc.size;
612 int ecc_bytes = chip->ecc.bytes;
613 int oob_skip = denali->oob_skip_bytes;
614 size_t size = writesize + oobsize;
615 int i, pos, len;
Chin Liang See03534df2014-09-12 00:42:17 -0500616
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900617 /* BBM at the beginning of the OOB area */
618 chip->cmdfunc(mtd, start_cmd, writesize, page);
619 if (write)
620 chip->write_buf(mtd, bufpoi, oob_skip);
621 else
622 chip->read_buf(mtd, bufpoi, oob_skip);
623 bufpoi += oob_skip;
Chin Liang See03534df2014-09-12 00:42:17 -0500624
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900625 /* OOB ECC */
626 for (i = 0; i < ecc_steps; i++) {
627 pos = ecc_size + i * (ecc_size + ecc_bytes);
628 len = ecc_bytes;
Chin Liang See03534df2014-09-12 00:42:17 -0500629
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900630 if (pos >= writesize)
631 pos += oob_skip;
632 else if (pos + len > writesize)
633 len = writesize - pos;
Chin Liang See03534df2014-09-12 00:42:17 -0500634
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900635 chip->cmdfunc(mtd, rnd_cmd, pos, -1);
636 if (write)
637 chip->write_buf(mtd, bufpoi, len);
638 else
639 chip->read_buf(mtd, bufpoi, len);
640 bufpoi += len;
641 if (len < ecc_bytes) {
642 len = ecc_bytes - len;
643 chip->cmdfunc(mtd, rnd_cmd, writesize + oob_skip, -1);
644 if (write)
645 chip->write_buf(mtd, bufpoi, len);
646 else
647 chip->read_buf(mtd, bufpoi, len);
648 bufpoi += len;
649 }
650 }
Chin Liang See03534df2014-09-12 00:42:17 -0500651
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900652 /* OOB free */
653 len = oobsize - (bufpoi - chip->oob_poi);
654 chip->cmdfunc(mtd, rnd_cmd, size - len, -1);
655 if (write)
656 chip->write_buf(mtd, bufpoi, len);
657 else
658 chip->read_buf(mtd, bufpoi, len);
Chin Liang See03534df2014-09-12 00:42:17 -0500659}
660
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900661static int denali_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
662 uint8_t *buf, int oob_required, int page)
Chin Liang See03534df2014-09-12 00:42:17 -0500663{
664 struct denali_nand_info *denali = mtd_to_denali(mtd);
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900665 int writesize = mtd->writesize;
666 int oobsize = mtd->oobsize;
667 int ecc_steps = chip->ecc.steps;
668 int ecc_size = chip->ecc.size;
669 int ecc_bytes = chip->ecc.bytes;
670 void *tmp_buf = denali->buf;
671 int oob_skip = denali->oob_skip_bytes;
672 size_t size = writesize + oobsize;
673 int ret, i, pos, len;
Chin Liang See03534df2014-09-12 00:42:17 -0500674
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900675 ret = denali_data_xfer(denali, tmp_buf, size, page, 1, 0);
676 if (ret)
677 return ret;
Chin Liang See03534df2014-09-12 00:42:17 -0500678
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900679 /* Arrange the buffer for syndrome payload/ecc layout */
680 if (buf) {
681 for (i = 0; i < ecc_steps; i++) {
682 pos = i * (ecc_size + ecc_bytes);
683 len = ecc_size;
Chin Liang See03534df2014-09-12 00:42:17 -0500684
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900685 if (pos >= writesize)
686 pos += oob_skip;
687 else if (pos + len > writesize)
688 len = writesize - pos;
Chin Liang See03534df2014-09-12 00:42:17 -0500689
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900690 memcpy(buf, tmp_buf + pos, len);
691 buf += len;
692 if (len < ecc_size) {
693 len = ecc_size - len;
694 memcpy(buf, tmp_buf + writesize + oob_skip,
695 len);
696 buf += len;
697 }
698 }
699 }
Chin Liang See03534df2014-09-12 00:42:17 -0500700
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900701 if (oob_required) {
702 uint8_t *oob = chip->oob_poi;
Chin Liang See03534df2014-09-12 00:42:17 -0500703
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900704 /* BBM at the beginning of the OOB area */
705 memcpy(oob, tmp_buf + writesize, oob_skip);
706 oob += oob_skip;
Chin Liang See03534df2014-09-12 00:42:17 -0500707
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900708 /* OOB ECC */
709 for (i = 0; i < ecc_steps; i++) {
710 pos = ecc_size + i * (ecc_size + ecc_bytes);
711 len = ecc_bytes;
712
713 if (pos >= writesize)
714 pos += oob_skip;
715 else if (pos + len > writesize)
716 len = writesize - pos;
717
718 memcpy(oob, tmp_buf + pos, len);
719 oob += len;
720 if (len < ecc_bytes) {
721 len = ecc_bytes - len;
722 memcpy(oob, tmp_buf + writesize + oob_skip,
723 len);
724 oob += len;
725 }
726 }
727
728 /* OOB free */
729 len = oobsize - (oob - chip->oob_poi);
730 memcpy(oob, tmp_buf + size - len, len);
Chin Liang See03534df2014-09-12 00:42:17 -0500731 }
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900732
Chin Liang See03534df2014-09-12 00:42:17 -0500733 return 0;
734}
735
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900736static int denali_read_oob(struct mtd_info *mtd, struct nand_chip *chip,
737 int page)
Chin Liang See03534df2014-09-12 00:42:17 -0500738{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900739 denali_oob_xfer(mtd, chip, page, 0);
Chin Liang See03534df2014-09-12 00:42:17 -0500740
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900741 return 0;
Chin Liang See03534df2014-09-12 00:42:17 -0500742}
743
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900744static int denali_write_oob(struct mtd_info *mtd, struct nand_chip *chip,
745 int page)
Chin Liang See03534df2014-09-12 00:42:17 -0500746{
747 struct denali_nand_info *denali = mtd_to_denali(mtd);
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900748 int status;
Chin Liang See03534df2014-09-12 00:42:17 -0500749
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900750 denali_reset_irq(denali);
Chin Liang See03534df2014-09-12 00:42:17 -0500751
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900752 denali_oob_xfer(mtd, chip, page, 1);
Chin Liang See03534df2014-09-12 00:42:17 -0500753
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900754 chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
755 status = chip->waitfunc(mtd, chip);
Chin Liang See03534df2014-09-12 00:42:17 -0500756
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900757 return status & NAND_STATUS_FAIL ? -EIO : 0;
Chin Liang See03534df2014-09-12 00:42:17 -0500758}
759
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900760static int denali_read_page(struct mtd_info *mtd, struct nand_chip *chip,
761 uint8_t *buf, int oob_required, int page)
Chin Liang See03534df2014-09-12 00:42:17 -0500762{
763 struct denali_nand_info *denali = mtd_to_denali(mtd);
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900764 unsigned long uncor_ecc_flags = 0;
765 int stat = 0;
766 int ret;
Chin Liang See03534df2014-09-12 00:42:17 -0500767
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900768 ret = denali_data_xfer(denali, buf, mtd->writesize, page, 0, 0);
769 if (ret && ret != -EBADMSG)
770 return ret;
Chin Liang See03534df2014-09-12 00:42:17 -0500771
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900772 if (denali->caps & DENALI_CAP_HW_ECC_FIXUP)
773 stat = denali_hw_ecc_fixup(mtd, denali, &uncor_ecc_flags);
774 else if (ret == -EBADMSG)
775 stat = denali_sw_ecc_fixup(mtd, denali, &uncor_ecc_flags, buf);
Chin Liang See03534df2014-09-12 00:42:17 -0500776
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900777 if (stat < 0)
778 return stat;
Chin Liang See03534df2014-09-12 00:42:17 -0500779
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900780 if (uncor_ecc_flags) {
781 ret = denali_read_oob(mtd, chip, page);
782 if (ret)
783 return ret;
Chin Liang See03534df2014-09-12 00:42:17 -0500784
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900785 stat = denali_check_erased_page(mtd, chip, buf,
786 uncor_ecc_flags, stat);
Chin Liang See03534df2014-09-12 00:42:17 -0500787 }
788
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900789 return stat;
Chin Liang See03534df2014-09-12 00:42:17 -0500790}
791
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900792static int denali_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
793 const uint8_t *buf, int oob_required, int page)
Chin Liang See03534df2014-09-12 00:42:17 -0500794{
795 struct denali_nand_info *denali = mtd_to_denali(mtd);
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900796 int writesize = mtd->writesize;
797 int oobsize = mtd->oobsize;
798 int ecc_steps = chip->ecc.steps;
799 int ecc_size = chip->ecc.size;
800 int ecc_bytes = chip->ecc.bytes;
801 void *tmp_buf = denali->buf;
802 int oob_skip = denali->oob_skip_bytes;
803 size_t size = writesize + oobsize;
804 int i, pos, len;
Chin Liang See03534df2014-09-12 00:42:17 -0500805
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900806 /*
807 * Fill the buffer with 0xff first except the full page transfer.
808 * This simplifies the logic.
809 */
810 if (!buf || !oob_required)
811 memset(tmp_buf, 0xff, size);
812
813 /* Arrange the buffer for syndrome payload/ecc layout */
814 if (buf) {
815 for (i = 0; i < ecc_steps; i++) {
816 pos = i * (ecc_size + ecc_bytes);
817 len = ecc_size;
818
819 if (pos >= writesize)
820 pos += oob_skip;
821 else if (pos + len > writesize)
822 len = writesize - pos;
823
824 memcpy(tmp_buf + pos, buf, len);
825 buf += len;
826 if (len < ecc_size) {
827 len = ecc_size - len;
828 memcpy(tmp_buf + writesize + oob_skip, buf,
829 len);
830 buf += len;
831 }
832 }
Chin Liang See03534df2014-09-12 00:42:17 -0500833 }
834
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900835 if (oob_required) {
836 const uint8_t *oob = chip->oob_poi;
Chin Liang See03534df2014-09-12 00:42:17 -0500837
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900838 /* BBM at the beginning of the OOB area */
839 memcpy(tmp_buf + writesize, oob, oob_skip);
840 oob += oob_skip;
Chin Liang See03534df2014-09-12 00:42:17 -0500841
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900842 /* OOB ECC */
843 for (i = 0; i < ecc_steps; i++) {
844 pos = ecc_size + i * (ecc_size + ecc_bytes);
845 len = ecc_bytes;
Chin Liang See03534df2014-09-12 00:42:17 -0500846
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900847 if (pos >= writesize)
848 pos += oob_skip;
849 else if (pos + len > writesize)
850 len = writesize - pos;
Chin Liang See03534df2014-09-12 00:42:17 -0500851
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900852 memcpy(tmp_buf + pos, oob, len);
853 oob += len;
854 if (len < ecc_bytes) {
855 len = ecc_bytes - len;
856 memcpy(tmp_buf + writesize + oob_skip, oob,
857 len);
858 oob += len;
859 }
Chin Liang See03534df2014-09-12 00:42:17 -0500860 }
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900861
862 /* OOB free */
863 len = oobsize - (oob - chip->oob_poi);
864 memcpy(tmp_buf + size - len, oob, len);
Chin Liang See03534df2014-09-12 00:42:17 -0500865 }
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900866
867 return denali_data_xfer(denali, tmp_buf, size, page, 1, 1);
Chin Liang See03534df2014-09-12 00:42:17 -0500868}
869
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900870static int denali_write_page(struct mtd_info *mtd, struct nand_chip *chip,
871 const uint8_t *buf, int oob_required, int page)
Chin Liang See03534df2014-09-12 00:42:17 -0500872{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900873 struct denali_nand_info *denali = mtd_to_denali(mtd);
Chin Liang See03534df2014-09-12 00:42:17 -0500874
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900875 return denali_data_xfer(denali, (void *)buf, mtd->writesize,
876 page, 0, 1);
Chin Liang See03534df2014-09-12 00:42:17 -0500877}
878
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900879static void denali_select_chip(struct mtd_info *mtd, int chip)
Chin Liang See03534df2014-09-12 00:42:17 -0500880{
881 struct denali_nand_info *denali = mtd_to_denali(mtd);
Chin Liang See03534df2014-09-12 00:42:17 -0500882
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900883 denali->active_bank = chip;
Chin Liang See03534df2014-09-12 00:42:17 -0500884}
885
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900886static int denali_waitfunc(struct mtd_info *mtd, struct nand_chip *chip)
Chin Liang See03534df2014-09-12 00:42:17 -0500887{
888 struct denali_nand_info *denali = mtd_to_denali(mtd);
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900889 uint32_t irq_status;
Chin Liang See03534df2014-09-12 00:42:17 -0500890
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900891 /* R/B# pin transitioned from low to high? */
892 irq_status = denali_wait_for_irq(denali, INTR__INT_ACT);
Chin Liang See03534df2014-09-12 00:42:17 -0500893
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900894 return irq_status & INTR__INT_ACT ? 0 : NAND_STATUS_FAIL;
Chin Liang See03534df2014-09-12 00:42:17 -0500895}
896
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900897static int denali_erase(struct mtd_info *mtd, int page)
Chin Liang See03534df2014-09-12 00:42:17 -0500898{
899 struct denali_nand_info *denali = mtd_to_denali(mtd);
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900900 uint32_t irq_status;
Chin Liang See03534df2014-09-12 00:42:17 -0500901
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900902 denali_reset_irq(denali);
Chin Liang See03534df2014-09-12 00:42:17 -0500903
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900904 denali->host_write(denali, DENALI_MAP10 | DENALI_BANK(denali) | page,
905 DENALI_ERASE);
Scott Wood3ea94ed2015-06-26 19:03:26 -0500906
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900907 /* wait for erase to complete or failure to occur */
908 irq_status = denali_wait_for_irq(denali,
909 INTR__ERASE_COMP | INTR__ERASE_FAIL);
Chin Liang See03534df2014-09-12 00:42:17 -0500910
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900911 return irq_status & INTR__ERASE_COMP ? 0 : NAND_STATUS_FAIL;
Chin Liang See03534df2014-09-12 00:42:17 -0500912}
913
Masahiro Yamada59a1f3e2017-11-29 19:18:18 +0900914static int denali_setup_data_interface(struct mtd_info *mtd, int chipnr,
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900915 const struct nand_data_interface *conf)
Chin Liang See03534df2014-09-12 00:42:17 -0500916{
917 struct denali_nand_info *denali = mtd_to_denali(mtd);
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900918 const struct nand_sdr_timings *timings;
Masahiro Yamada2d1fbc82018-12-19 20:03:18 +0900919 unsigned long t_x, mult_x;
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900920 int acc_clks, re_2_we, re_2_re, we_2_re, addr_2_data;
921 int rdwr_en_lo, rdwr_en_hi, rdwr_en_lo_hi, cs_setup;
922 int addr_2_data_mask;
923 uint32_t tmp;
Scott Wood3ea94ed2015-06-26 19:03:26 -0500924
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900925 timings = nand_get_sdr_timings(conf);
926 if (IS_ERR(timings))
927 return PTR_ERR(timings);
Chin Liang See03534df2014-09-12 00:42:17 -0500928
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900929 /* clk_x period in picoseconds */
Masahiro Yamada2d1fbc82018-12-19 20:03:18 +0900930 t_x = DIV_ROUND_DOWN_ULL(1000000000000ULL, denali->clk_x_rate);
931 if (!t_x)
932 return -EINVAL;
933
934 /*
935 * The bus interface clock, clk_x, is phase aligned with the core clock.
936 * The clk_x is an integral multiple N of the core clk. The value N is
937 * configured at IP delivery time, and its available value is 4, 5, 6.
938 */
939 mult_x = DIV_ROUND_CLOSEST_ULL(denali->clk_x_rate, denali->clk_rate);
940 if (mult_x < 4 || mult_x > 6)
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900941 return -EINVAL;
Chin Liang See03534df2014-09-12 00:42:17 -0500942
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900943 if (chipnr == NAND_DATA_IFACE_CHECK_ONLY)
944 return 0;
Chin Liang See03534df2014-09-12 00:42:17 -0500945
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900946 /* tREA -> ACC_CLKS */
Masahiro Yamada2d1fbc82018-12-19 20:03:18 +0900947 acc_clks = DIV_ROUND_UP(timings->tREA_max, t_x);
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900948 acc_clks = min_t(int, acc_clks, ACC_CLKS__VALUE);
949
950 tmp = ioread32(denali->reg + ACC_CLKS);
951 tmp &= ~ACC_CLKS__VALUE;
952 tmp |= FIELD_PREP(ACC_CLKS__VALUE, acc_clks);
953 iowrite32(tmp, denali->reg + ACC_CLKS);
954
955 /* tRWH -> RE_2_WE */
Masahiro Yamada2d1fbc82018-12-19 20:03:18 +0900956 re_2_we = DIV_ROUND_UP(timings->tRHW_min, t_x);
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900957 re_2_we = min_t(int, re_2_we, RE_2_WE__VALUE);
Chin Liang See03534df2014-09-12 00:42:17 -0500958
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900959 tmp = ioread32(denali->reg + RE_2_WE);
960 tmp &= ~RE_2_WE__VALUE;
961 tmp |= FIELD_PREP(RE_2_WE__VALUE, re_2_we);
962 iowrite32(tmp, denali->reg + RE_2_WE);
963
964 /* tRHZ -> RE_2_RE */
Masahiro Yamada2d1fbc82018-12-19 20:03:18 +0900965 re_2_re = DIV_ROUND_UP(timings->tRHZ_max, t_x);
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900966 re_2_re = min_t(int, re_2_re, RE_2_RE__VALUE);
967
968 tmp = ioread32(denali->reg + RE_2_RE);
969 tmp &= ~RE_2_RE__VALUE;
970 tmp |= FIELD_PREP(RE_2_RE__VALUE, re_2_re);
971 iowrite32(tmp, denali->reg + RE_2_RE);
972
973 /*
974 * tCCS, tWHR -> WE_2_RE
975 *
976 * With WE_2_RE properly set, the Denali controller automatically takes
977 * care of the delay; the driver need not set NAND_WAIT_TCCS.
978 */
Masahiro Yamada2d1fbc82018-12-19 20:03:18 +0900979 we_2_re = DIV_ROUND_UP(max(timings->tCCS_min, timings->tWHR_min), t_x);
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900980 we_2_re = min_t(int, we_2_re, TWHR2_AND_WE_2_RE__WE_2_RE);
981
982 tmp = ioread32(denali->reg + TWHR2_AND_WE_2_RE);
983 tmp &= ~TWHR2_AND_WE_2_RE__WE_2_RE;
984 tmp |= FIELD_PREP(TWHR2_AND_WE_2_RE__WE_2_RE, we_2_re);
985 iowrite32(tmp, denali->reg + TWHR2_AND_WE_2_RE);
986
987 /* tADL -> ADDR_2_DATA */
988
989 /* for older versions, ADDR_2_DATA is only 6 bit wide */
990 addr_2_data_mask = TCWAW_AND_ADDR_2_DATA__ADDR_2_DATA;
991 if (denali->revision < 0x0501)
992 addr_2_data_mask >>= 1;
993
Masahiro Yamada2d1fbc82018-12-19 20:03:18 +0900994 addr_2_data = DIV_ROUND_UP(timings->tADL_min, t_x);
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900995 addr_2_data = min_t(int, addr_2_data, addr_2_data_mask);
996
997 tmp = ioread32(denali->reg + TCWAW_AND_ADDR_2_DATA);
998 tmp &= ~TCWAW_AND_ADDR_2_DATA__ADDR_2_DATA;
999 tmp |= FIELD_PREP(TCWAW_AND_ADDR_2_DATA__ADDR_2_DATA, addr_2_data);
1000 iowrite32(tmp, denali->reg + TCWAW_AND_ADDR_2_DATA);
1001
1002 /* tREH, tWH -> RDWR_EN_HI_CNT */
1003 rdwr_en_hi = DIV_ROUND_UP(max(timings->tREH_min, timings->tWH_min),
Masahiro Yamada2d1fbc82018-12-19 20:03:18 +09001004 t_x);
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001005 rdwr_en_hi = min_t(int, rdwr_en_hi, RDWR_EN_HI_CNT__VALUE);
1006
1007 tmp = ioread32(denali->reg + RDWR_EN_HI_CNT);
1008 tmp &= ~RDWR_EN_HI_CNT__VALUE;
1009 tmp |= FIELD_PREP(RDWR_EN_HI_CNT__VALUE, rdwr_en_hi);
1010 iowrite32(tmp, denali->reg + RDWR_EN_HI_CNT);
1011
1012 /* tRP, tWP -> RDWR_EN_LO_CNT */
Masahiro Yamada2d1fbc82018-12-19 20:03:18 +09001013 rdwr_en_lo = DIV_ROUND_UP(max(timings->tRP_min, timings->tWP_min), t_x);
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001014 rdwr_en_lo_hi = DIV_ROUND_UP(max(timings->tRC_min, timings->tWC_min),
Masahiro Yamada2d1fbc82018-12-19 20:03:18 +09001015 t_x);
1016 rdwr_en_lo_hi = max_t(int, rdwr_en_lo_hi, mult_x);
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001017 rdwr_en_lo = max(rdwr_en_lo, rdwr_en_lo_hi - rdwr_en_hi);
1018 rdwr_en_lo = min_t(int, rdwr_en_lo, RDWR_EN_LO_CNT__VALUE);
1019
1020 tmp = ioread32(denali->reg + RDWR_EN_LO_CNT);
1021 tmp &= ~RDWR_EN_LO_CNT__VALUE;
1022 tmp |= FIELD_PREP(RDWR_EN_LO_CNT__VALUE, rdwr_en_lo);
1023 iowrite32(tmp, denali->reg + RDWR_EN_LO_CNT);
1024
1025 /* tCS, tCEA -> CS_SETUP_CNT */
Masahiro Yamada2d1fbc82018-12-19 20:03:18 +09001026 cs_setup = max3((int)DIV_ROUND_UP(timings->tCS_min, t_x) - rdwr_en_lo,
1027 (int)DIV_ROUND_UP(timings->tCEA_max, t_x) - acc_clks,
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001028 0);
1029 cs_setup = min_t(int, cs_setup, CS_SETUP_CNT__VALUE);
1030
1031 tmp = ioread32(denali->reg + CS_SETUP_CNT);
1032 tmp &= ~CS_SETUP_CNT__VALUE;
1033 tmp |= FIELD_PREP(CS_SETUP_CNT__VALUE, cs_setup);
1034 iowrite32(tmp, denali->reg + CS_SETUP_CNT);
Scott Wood3ea94ed2015-06-26 19:03:26 -05001035
1036 return 0;
Chin Liang See03534df2014-09-12 00:42:17 -05001037}
1038
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001039static void denali_reset_banks(struct denali_nand_info *denali)
Chin Liang See03534df2014-09-12 00:42:17 -05001040{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001041 u32 irq_status;
1042 int i;
Chin Liang See03534df2014-09-12 00:42:17 -05001043
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001044 for (i = 0; i < denali->max_banks; i++) {
1045 denali->active_bank = i;
1046
1047 denali_reset_irq(denali);
1048
1049 iowrite32(DEVICE_RESET__BANK(i),
1050 denali->reg + DEVICE_RESET);
1051
1052 irq_status = denali_wait_for_irq(denali,
1053 INTR__RST_COMP | INTR__INT_ACT | INTR__TIME_OUT);
1054 if (!(irq_status & INTR__INT_ACT))
1055 break;
Chin Liang See03534df2014-09-12 00:42:17 -05001056 }
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001057
1058 dev_dbg(denali->dev, "%d chips connected\n", i);
1059 denali->max_banks = i;
Chin Liang See03534df2014-09-12 00:42:17 -05001060}
Chin Liang See03534df2014-09-12 00:42:17 -05001061
Chin Liang See03534df2014-09-12 00:42:17 -05001062static void denali_hw_init(struct denali_nand_info *denali)
1063{
1064 /*
Masahiro Yamada54fde8e2017-09-15 21:43:19 +09001065 * The REVISION register may not be reliable. Platforms are allowed to
1066 * override it.
1067 */
1068 if (!denali->revision)
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001069 denali->revision = swab16(ioread32(denali->reg + REVISION));
Masahiro Yamada54fde8e2017-09-15 21:43:19 +09001070
1071 /*
Chin Liang See03534df2014-09-12 00:42:17 -05001072 * tell driver how many bit controller will skip before writing
1073 * ECC code in OOB. This is normally used for bad block marker
1074 */
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001075 denali->oob_skip_bytes = CONFIG_NAND_DENALI_SPARE_AREA_SKIP_BYTES;
1076 iowrite32(denali->oob_skip_bytes, denali->reg + SPARE_AREA_SKIP_BYTES);
1077 denali_detect_max_banks(denali);
1078 iowrite32(0x0F, denali->reg + RB_PIN_ENABLED);
1079 iowrite32(CHIP_EN_DONT_CARE__FLAG, denali->reg + CHIP_ENABLE_DONT_CARE);
Chin Liang See03534df2014-09-12 00:42:17 -05001080
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001081 iowrite32(0xffff, denali->reg + SPARE_AREA_MARKER);
Chin Liang See03534df2014-09-12 00:42:17 -05001082}
1083
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001084int denali_calc_ecc_bytes(int step_size, int strength)
1085{
1086 /* BCH code. Denali requires ecc.bytes to be multiple of 2 */
1087 return DIV_ROUND_UP(strength * fls(step_size * 8), 16) * 2;
1088}
1089EXPORT_SYMBOL(denali_calc_ecc_bytes);
Chin Liang See03534df2014-09-12 00:42:17 -05001090
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001091static int denali_ecc_setup(struct mtd_info *mtd, struct nand_chip *chip,
1092 struct denali_nand_info *denali)
Chin Liang See03534df2014-09-12 00:42:17 -05001093{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001094 int oobavail = mtd->oobsize - denali->oob_skip_bytes;
Masahiro Yamadada0763d2014-11-13 20:31:50 +09001095 int ret;
Chin Liang See03534df2014-09-12 00:42:17 -05001096
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001097 /*
1098 * If .size and .strength are already set (usually by DT),
1099 * check if they are supported by this controller.
1100 */
1101 if (chip->ecc.size && chip->ecc.strength)
1102 return nand_check_ecc_caps(chip, denali->ecc_caps, oobavail);
1103
1104 /*
1105 * We want .size and .strength closest to the chip's requirement
1106 * unless NAND_ECC_MAXIMIZE is requested.
1107 */
1108 if (!(chip->ecc.options & NAND_ECC_MAXIMIZE)) {
1109 ret = nand_match_ecc_req(chip, denali->ecc_caps, oobavail);
1110 if (!ret)
1111 return 0;
1112 }
1113
1114 /* Max ECC strength is the last thing we can do */
1115 return nand_maximize_ecc(chip, denali->ecc_caps, oobavail);
1116}
1117
1118static struct nand_ecclayout nand_oob;
1119
1120static int denali_ooblayout_ecc(struct mtd_info *mtd, int section,
1121 struct mtd_oob_region *oobregion)
1122{
1123 struct denali_nand_info *denali = mtd_to_denali(mtd);
1124 struct nand_chip *chip = mtd_to_nand(mtd);
1125
1126 if (section)
1127 return -ERANGE;
1128
1129 oobregion->offset = denali->oob_skip_bytes;
1130 oobregion->length = chip->ecc.total;
1131
1132 return 0;
1133}
1134
1135static int denali_ooblayout_free(struct mtd_info *mtd, int section,
1136 struct mtd_oob_region *oobregion)
1137{
1138 struct denali_nand_info *denali = mtd_to_denali(mtd);
1139 struct nand_chip *chip = mtd_to_nand(mtd);
1140
1141 if (section)
1142 return -ERANGE;
1143
1144 oobregion->offset = chip->ecc.total + denali->oob_skip_bytes;
1145 oobregion->length = mtd->oobsize - oobregion->offset;
1146
1147 return 0;
1148}
Chin Liang See03534df2014-09-12 00:42:17 -05001149
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001150static const struct mtd_ooblayout_ops denali_ooblayout_ops = {
1151 .ecc = denali_ooblayout_ecc,
1152 .free = denali_ooblayout_free,
1153};
Chin Liang See03534df2014-09-12 00:42:17 -05001154
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001155static int denali_multidev_fixup(struct denali_nand_info *denali)
1156{
1157 struct nand_chip *chip = &denali->nand;
1158 struct mtd_info *mtd = nand_to_mtd(chip);
Masahiro Yamadada0763d2014-11-13 20:31:50 +09001159
1160 /*
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001161 * Support for multi device:
1162 * When the IP configuration is x16 capable and two x8 chips are
1163 * connected in parallel, DEVICES_CONNECTED should be set to 2.
1164 * In this case, the core framework knows nothing about this fact,
1165 * so we should tell it the _logical_ pagesize and anything necessary.
Masahiro Yamadada0763d2014-11-13 20:31:50 +09001166 */
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001167 denali->devs_per_cs = ioread32(denali->reg + DEVICES_CONNECTED);
Chin Liang See03534df2014-09-12 00:42:17 -05001168
Chin Liang See03534df2014-09-12 00:42:17 -05001169 /*
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001170 * On some SoCs, DEVICES_CONNECTED is not auto-detected.
1171 * For those, DEVICES_CONNECTED is left to 0. Set 1 if it is the case.
Chin Liang See03534df2014-09-12 00:42:17 -05001172 */
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001173 if (denali->devs_per_cs == 0) {
1174 denali->devs_per_cs = 1;
1175 iowrite32(1, denali->reg + DEVICES_CONNECTED);
1176 }
1177
1178 if (denali->devs_per_cs == 1)
1179 return 0;
1180
1181 if (denali->devs_per_cs != 2) {
1182 dev_err(denali->dev, "unsupported number of devices %d\n",
1183 denali->devs_per_cs);
1184 return -EINVAL;
1185 }
1186
1187 /* 2 chips in parallel */
1188 mtd->size <<= 1;
1189 mtd->erasesize <<= 1;
1190 mtd->writesize <<= 1;
1191 mtd->oobsize <<= 1;
1192 chip->chipsize <<= 1;
1193 chip->page_shift += 1;
1194 chip->phys_erase_shift += 1;
1195 chip->bbt_erase_shift += 1;
1196 chip->chip_shift += 1;
1197 chip->pagemask <<= 1;
1198 chip->ecc.size <<= 1;
1199 chip->ecc.bytes <<= 1;
1200 chip->ecc.strength <<= 1;
1201 denali->oob_skip_bytes <<= 1;
1202
1203 return 0;
1204}
1205
1206int denali_init(struct denali_nand_info *denali)
1207{
1208 struct nand_chip *chip = &denali->nand;
1209 struct mtd_info *mtd = nand_to_mtd(chip);
1210 u32 features = ioread32(denali->reg + FEATURES);
1211 int ret;
1212
1213 denali_hw_init(denali);
1214
1215 denali_clear_irq_all(denali);
1216
1217 denali_reset_banks(denali);
1218
1219 denali->active_bank = DENALI_INVALID_BANK;
1220
1221 chip->flash_node = dev_of_offset(denali->dev);
1222 /* Fallback to the default name if DT did not give "label" property */
1223 if (!mtd->name)
1224 mtd->name = "denali-nand";
Chin Liang See03534df2014-09-12 00:42:17 -05001225
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001226 chip->select_chip = denali_select_chip;
1227 chip->read_byte = denali_read_byte;
1228 chip->write_byte = denali_write_byte;
1229 chip->read_word = denali_read_word;
1230 chip->cmd_ctrl = denali_cmd_ctrl;
1231 chip->dev_ready = denali_dev_ready;
1232 chip->waitfunc = denali_waitfunc;
1233
1234 if (features & FEATURES__INDEX_ADDR) {
1235 denali->host_read = denali_indexed_read;
1236 denali->host_write = denali_indexed_write;
1237 } else {
1238 denali->host_read = denali_direct_read;
1239 denali->host_write = denali_direct_write;
1240 }
1241
1242 /* clk rate info is needed for setup_data_interface */
1243 if (denali->clk_x_rate)
1244 chip->setup_data_interface = denali_setup_data_interface;
1245
1246 ret = nand_scan_ident(mtd, denali->max_banks, NULL);
1247 if (ret)
1248 return ret;
1249
1250 if (ioread32(denali->reg + FEATURES) & FEATURES__DMA)
1251 denali->dma_avail = 1;
1252
1253 if (denali->dma_avail) {
Masahiro Yamadae83725e2018-07-19 10:13:23 +09001254 chip->buf_align = ARCH_DMA_MINALIGN;
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001255 if (denali->caps & DENALI_CAP_DMA_64BIT)
1256 denali->setup_dma = denali_setup_dma64;
1257 else
1258 denali->setup_dma = denali_setup_dma32;
1259 } else {
1260 chip->buf_align = 4;
1261 }
1262
1263 chip->options |= NAND_USE_BOUNCE_BUFFER;
1264 chip->bbt_options |= NAND_BBT_USE_FLASH;
1265 chip->bbt_options |= NAND_BBT_NO_OOB;
1266 denali->nand.ecc.mode = NAND_ECC_HW_SYNDROME;
Masahiro Yamadada0763d2014-11-13 20:31:50 +09001267
Scott Wood3ea94ed2015-06-26 19:03:26 -05001268 /* no subpage writes on denali */
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001269 chip->options |= NAND_NO_SUBPAGE_WRITE;
Scott Wood3ea94ed2015-06-26 19:03:26 -05001270
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001271 ret = denali_ecc_setup(mtd, chip, denali);
1272 if (ret) {
1273 dev_err(denali->dev, "Failed to setup ECC settings.\n");
1274 return ret;
Chin Liang See03534df2014-09-12 00:42:17 -05001275 }
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001276
1277 dev_dbg(denali->dev,
1278 "chosen ECC settings: step=%d, strength=%d, bytes=%d\n",
1279 chip->ecc.size, chip->ecc.strength, chip->ecc.bytes);
1280
1281 iowrite32(FIELD_PREP(ECC_CORRECTION__ERASE_THRESHOLD, 1) |
1282 FIELD_PREP(ECC_CORRECTION__VALUE, chip->ecc.strength),
1283 denali->reg + ECC_CORRECTION);
1284 iowrite32(mtd->erasesize / mtd->writesize,
1285 denali->reg + PAGES_PER_BLOCK);
1286 iowrite32(chip->options & NAND_BUSWIDTH_16 ? 1 : 0,
1287 denali->reg + DEVICE_WIDTH);
1288 iowrite32(chip->options & NAND_ROW_ADDR_3 ? 0 : TWO_ROW_ADDR_CYCLES__FLAG,
1289 denali->reg + TWO_ROW_ADDR_CYCLES);
1290 iowrite32(mtd->writesize, denali->reg + DEVICE_MAIN_AREA_SIZE);
1291 iowrite32(mtd->oobsize, denali->reg + DEVICE_SPARE_AREA_SIZE);
1292
1293 iowrite32(chip->ecc.size, denali->reg + CFG_DATA_BLOCK_SIZE);
1294 iowrite32(chip->ecc.size, denali->reg + CFG_LAST_DATA_BLOCK_SIZE);
1295 /* chip->ecc.steps is set by nand_scan_tail(); not available here */
1296 iowrite32(mtd->writesize / chip->ecc.size,
1297 denali->reg + CFG_NUM_DATA_BLOCKS);
1298
1299 mtd_set_ooblayout(mtd, &denali_ooblayout_ops);
1300
Masahiro Yamadada0763d2014-11-13 20:31:50 +09001301 nand_oob.eccbytes = denali->nand.ecc.bytes;
1302 denali->nand.ecc.layout = &nand_oob;
Chin Liang See03534df2014-09-12 00:42:17 -05001303
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001304 if (chip->options & NAND_BUSWIDTH_16) {
1305 chip->read_buf = denali_read_buf16;
1306 chip->write_buf = denali_write_buf16;
1307 } else {
1308 chip->read_buf = denali_read_buf;
1309 chip->write_buf = denali_write_buf;
1310 }
1311 chip->ecc.options |= NAND_ECC_CUSTOM_PAGE_ACCESS;
1312 chip->ecc.read_page = denali_read_page;
1313 chip->ecc.read_page_raw = denali_read_page_raw;
1314 chip->ecc.write_page = denali_write_page;
1315 chip->ecc.write_page_raw = denali_write_page_raw;
1316 chip->ecc.read_oob = denali_read_oob;
1317 chip->ecc.write_oob = denali_write_oob;
1318 chip->erase = denali_erase;
Masahiro Yamada628ee1e2014-11-13 20:31:51 +09001319
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001320 ret = denali_multidev_fixup(denali);
1321 if (ret)
1322 return ret;
Masahiro Yamadada0763d2014-11-13 20:31:50 +09001323
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001324 /*
1325 * This buffer is DMA-mapped by denali_{read,write}_page_raw. Do not
1326 * use devm_kmalloc() because the memory allocated by devm_ does not
1327 * guarantee DMA-safe alignment.
1328 */
1329 denali->buf = kmalloc(mtd->writesize + mtd->oobsize, GFP_KERNEL);
1330 if (!denali->buf)
1331 return -ENOMEM;
1332
1333 ret = nand_scan_tail(mtd);
1334 if (ret)
1335 goto free_buf;
Masahiro Yamadada0763d2014-11-13 20:31:50 +09001336
Scott Wood52ab7ce2016-05-30 13:57:58 -05001337 ret = nand_register(0, mtd);
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001338 if (ret) {
1339 dev_err(denali->dev, "Failed to register MTD: %d\n", ret);
1340 goto free_buf;
1341 }
1342 return 0;
1343
1344free_buf:
1345 kfree(denali->buf);
Masahiro Yamadada0763d2014-11-13 20:31:50 +09001346
Masahiro Yamadada0763d2014-11-13 20:31:50 +09001347 return ret;
Chin Liang See03534df2014-09-12 00:42:17 -05001348}