blob: 3e0ac39777d8c9c3114e36d5efca4e401120c6ad [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>
Simon Glass9bc15642020-02-03 07:36:16 -070010#include <malloc.h>
Masahiro Yamada5beb1b32017-11-30 13:45:27 +090011#include <nand.h>
Simon Glass9bc15642020-02-03 07:36:16 -070012#include <dm/device_compat.h>
Simon Glassd66c5f72020-02-03 07:36:15 -070013#include <dm/devres.h>
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +090014#include <linux/bitfield.h>
15#include <linux/dma-direction.h>
Simon Glassd66c5f72020-02-03 07:36:15 -070016#include <linux/err.h>
Masahiro Yamada56a931c2016-09-21 11:28:55 +090017#include <linux/errno.h>
Masahiro Yamada54fde8e2017-09-15 21:43:19 +090018#include <linux/io.h>
Masahiro Yamada5beb1b32017-11-30 13:45:27 +090019#include <linux/mtd/mtd.h>
20#include <linux/mtd/rawnand.h>
Chin Liang See03534df2014-09-12 00:42:17 -050021
22#include "denali.h"
23
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +090024#define DENALI_NAND_NAME "denali-nand"
Chin Liang See03534df2014-09-12 00:42:17 -050025
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +090026/* for Indexed Addressing */
27#define DENALI_INDEXED_CTRL 0x00
28#define DENALI_INDEXED_DATA 0x10
Chin Liang See03534df2014-09-12 00:42:17 -050029
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +090030#define DENALI_MAP00 (0 << 26) /* direct access to buffer */
31#define DENALI_MAP01 (1 << 26) /* read/write pages in PIO */
32#define DENALI_MAP10 (2 << 26) /* high-level control plane */
33#define DENALI_MAP11 (3 << 26) /* direct controller access */
Chin Liang See03534df2014-09-12 00:42:17 -050034
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +090035/* MAP11 access cycle type */
36#define DENALI_MAP11_CMD ((DENALI_MAP11) | 0) /* command cycle */
37#define DENALI_MAP11_ADDR ((DENALI_MAP11) | 1) /* address cycle */
38#define DENALI_MAP11_DATA ((DENALI_MAP11) | 2) /* data cycle */
Chin Liang See03534df2014-09-12 00:42:17 -050039
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +090040/* MAP10 commands */
41#define DENALI_ERASE 0x01
Chin Liang See03534df2014-09-12 00:42:17 -050042
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +090043#define DENALI_BANK(denali) ((denali)->active_bank << 24)
Chin Liang See03534df2014-09-12 00:42:17 -050044
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +090045#define DENALI_INVALID_BANK -1
46#define DENALI_NR_BANKS 4
Chin Liang See03534df2014-09-12 00:42:17 -050047
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +090048static inline struct denali_nand_info *mtd_to_denali(struct mtd_info *mtd)
Chin Liang See03534df2014-09-12 00:42:17 -050049{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +090050 return container_of(mtd_to_nand(mtd), struct denali_nand_info, nand);
Chin Liang See03534df2014-09-12 00:42:17 -050051}
52
53/*
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +090054 * Direct Addressing - the slave address forms the control information (command
55 * type, bank, block, and page address). The slave data is the actual data to
56 * be transferred. This mode requires 28 bits of address region allocated.
Scott Wood3ea94ed2015-06-26 19:03:26 -050057 */
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +090058static u32 denali_direct_read(struct denali_nand_info *denali, u32 addr)
Chin Liang See03534df2014-09-12 00:42:17 -050059{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +090060 return ioread32(denali->host + addr);
Chin Liang See03534df2014-09-12 00:42:17 -050061}
62
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +090063static void denali_direct_write(struct denali_nand_info *denali, u32 addr,
64 u32 data)
Chin Liang See03534df2014-09-12 00:42:17 -050065{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +090066 iowrite32(data, denali->host + addr);
Chin Liang See03534df2014-09-12 00:42:17 -050067}
68
Scott Wood3ea94ed2015-06-26 19:03:26 -050069/*
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +090070 * Indexed Addressing - address translation module intervenes in passing the
71 * control information. This mode reduces the required address range. The
72 * control information and transferred data are latched by the registers in
73 * the translation module.
Scott Wood3ea94ed2015-06-26 19:03:26 -050074 */
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +090075static u32 denali_indexed_read(struct denali_nand_info *denali, u32 addr)
Chin Liang See03534df2014-09-12 00:42:17 -050076{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +090077 iowrite32(addr, denali->host + DENALI_INDEXED_CTRL);
78 return ioread32(denali->host + DENALI_INDEXED_DATA);
Chin Liang See03534df2014-09-12 00:42:17 -050079}
80
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +090081static void denali_indexed_write(struct denali_nand_info *denali, u32 addr,
82 u32 data)
Chin Liang See03534df2014-09-12 00:42:17 -050083{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +090084 iowrite32(addr, denali->host + DENALI_INDEXED_CTRL);
85 iowrite32(data, denali->host + DENALI_INDEXED_DATA);
Chin Liang See03534df2014-09-12 00:42:17 -050086}
87
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +090088/*
89 * Use the configuration feature register to determine the maximum number of
90 * banks that the hardware supports.
91 */
92static void denali_detect_max_banks(struct denali_nand_info *denali)
Chin Liang See03534df2014-09-12 00:42:17 -050093{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +090094 uint32_t features = ioread32(denali->reg + FEATURES);
Chin Liang See03534df2014-09-12 00:42:17 -050095
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +090096 denali->max_banks = 1 << FIELD_GET(FEATURES__N_BANKS, features);
Chin Liang See03534df2014-09-12 00:42:17 -050097
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +090098 /* the encoding changed from rev 5.0 to 5.1 */
99 if (denali->revision < 0x0501)
100 denali->max_banks <<= 1;
Chin Liang See03534df2014-09-12 00:42:17 -0500101}
102
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900103static void __maybe_unused denali_enable_irq(struct denali_nand_info *denali)
Chin Liang See03534df2014-09-12 00:42:17 -0500104{
Scott Wood3ea94ed2015-06-26 19:03:26 -0500105 int i;
Chin Liang See03534df2014-09-12 00:42:17 -0500106
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900107 for (i = 0; i < DENALI_NR_BANKS; i++)
108 iowrite32(U32_MAX, denali->reg + INTR_EN(i));
109 iowrite32(GLOBAL_INT_EN_FLAG, denali->reg + GLOBAL_INT_ENABLE);
Chin Liang See03534df2014-09-12 00:42:17 -0500110}
111
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900112static void __maybe_unused denali_disable_irq(struct denali_nand_info *denali)
Chin Liang See03534df2014-09-12 00:42:17 -0500113{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900114 int i;
Chin Liang See03534df2014-09-12 00:42:17 -0500115
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900116 for (i = 0; i < DENALI_NR_BANKS; i++)
117 iowrite32(0, denali->reg + INTR_EN(i));
118 iowrite32(0, denali->reg + GLOBAL_INT_ENABLE);
119}
Chin Liang See03534df2014-09-12 00:42:17 -0500120
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900121static void denali_clear_irq(struct denali_nand_info *denali,
122 int bank, uint32_t irq_status)
123{
124 /* write one to clear bits */
125 iowrite32(irq_status, denali->reg + INTR_STATUS(bank));
126}
Chin Liang See03534df2014-09-12 00:42:17 -0500127
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900128static void denali_clear_irq_all(struct denali_nand_info *denali)
129{
130 int i;
Chin Liang See03534df2014-09-12 00:42:17 -0500131
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900132 for (i = 0; i < DENALI_NR_BANKS; i++)
133 denali_clear_irq(denali, i, U32_MAX);
134}
Chin Liang See03534df2014-09-12 00:42:17 -0500135
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900136static void __denali_check_irq(struct denali_nand_info *denali)
137{
138 uint32_t irq_status;
139 int i;
Chin Liang See03534df2014-09-12 00:42:17 -0500140
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900141 for (i = 0; i < DENALI_NR_BANKS; i++) {
142 irq_status = ioread32(denali->reg + INTR_STATUS(i));
143 denali_clear_irq(denali, i, irq_status);
Chin Liang See03534df2014-09-12 00:42:17 -0500144
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900145 if (i != denali->active_bank)
146 continue;
Chin Liang See03534df2014-09-12 00:42:17 -0500147
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900148 denali->irq_status |= irq_status;
Chin Liang See03534df2014-09-12 00:42:17 -0500149 }
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900150}
Chin Liang See03534df2014-09-12 00:42:17 -0500151
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900152static void denali_reset_irq(struct denali_nand_info *denali)
153{
154 denali->irq_status = 0;
155 denali->irq_mask = 0;
156}
Chin Liang See03534df2014-09-12 00:42:17 -0500157
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900158static uint32_t denali_wait_for_irq(struct denali_nand_info *denali,
159 uint32_t irq_mask)
160{
161 unsigned long time_left = 1000000;
Chin Liang See03534df2014-09-12 00:42:17 -0500162
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900163 while (time_left) {
164 __denali_check_irq(denali);
Chin Liang See03534df2014-09-12 00:42:17 -0500165
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900166 if (irq_mask & denali->irq_status)
167 return denali->irq_status;
168 udelay(1);
169 time_left--;
Chin Liang See03534df2014-09-12 00:42:17 -0500170 }
171
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900172 if (!time_left) {
173 dev_err(denali->dev, "timeout while waiting for irq 0x%x\n",
174 irq_mask);
175 return 0;
176 }
Chin Liang See03534df2014-09-12 00:42:17 -0500177
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900178 return denali->irq_status;
Chin Liang See03534df2014-09-12 00:42:17 -0500179}
180
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900181static uint32_t denali_check_irq(struct denali_nand_info *denali)
Chin Liang See03534df2014-09-12 00:42:17 -0500182{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900183 __denali_check_irq(denali);
Scott Wood3ea94ed2015-06-26 19:03:26 -0500184
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900185 return denali->irq_status;
Chin Liang See03534df2014-09-12 00:42:17 -0500186}
187
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900188static void denali_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
Chin Liang See03534df2014-09-12 00:42:17 -0500189{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900190 struct denali_nand_info *denali = mtd_to_denali(mtd);
191 u32 addr = DENALI_MAP11_DATA | DENALI_BANK(denali);
192 int i;
193
194 for (i = 0; i < len; i++)
195 buf[i] = denali->host_read(denali, addr);
Chin Liang See03534df2014-09-12 00:42:17 -0500196}
197
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900198static void denali_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
Chin Liang See03534df2014-09-12 00:42:17 -0500199{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900200 struct denali_nand_info *denali = mtd_to_denali(mtd);
201 u32 addr = DENALI_MAP11_DATA | DENALI_BANK(denali);
202 int i;
Chin Liang See03534df2014-09-12 00:42:17 -0500203
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900204 for (i = 0; i < len; i++)
205 denali->host_write(denali, addr, buf[i]);
Chin Liang See03534df2014-09-12 00:42:17 -0500206}
207
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900208static void denali_read_buf16(struct mtd_info *mtd, uint8_t *buf, int len)
Chin Liang See03534df2014-09-12 00:42:17 -0500209{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900210 struct denali_nand_info *denali = mtd_to_denali(mtd);
211 u32 addr = DENALI_MAP11_DATA | DENALI_BANK(denali);
212 uint16_t *buf16 = (uint16_t *)buf;
213 int i;
Chin Liang See03534df2014-09-12 00:42:17 -0500214
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900215 for (i = 0; i < len / 2; i++)
216 buf16[i] = denali->host_read(denali, addr);
Chin Liang See03534df2014-09-12 00:42:17 -0500217}
218
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900219static void denali_write_buf16(struct mtd_info *mtd, const uint8_t *buf,
220 int len)
Chin Liang See03534df2014-09-12 00:42:17 -0500221{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900222 struct denali_nand_info *denali = mtd_to_denali(mtd);
223 u32 addr = DENALI_MAP11_DATA | DENALI_BANK(denali);
224 const uint16_t *buf16 = (const uint16_t *)buf;
Chin Liang See03534df2014-09-12 00:42:17 -0500225 int i;
226
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900227 for (i = 0; i < len / 2; i++)
228 denali->host_write(denali, addr, buf16[i]);
Chin Liang See03534df2014-09-12 00:42:17 -0500229}
230
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900231static uint8_t denali_read_byte(struct mtd_info *mtd)
Chin Liang See03534df2014-09-12 00:42:17 -0500232{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900233 uint8_t byte;
Masahiro Yamada54fde8e2017-09-15 21:43:19 +0900234
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900235 denali_read_buf(mtd, &byte, 1);
Masahiro Yamada54fde8e2017-09-15 21:43:19 +0900236
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900237 return byte;
Chin Liang See03534df2014-09-12 00:42:17 -0500238}
239
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900240static void denali_write_byte(struct mtd_info *mtd, uint8_t byte)
Chin Liang See03534df2014-09-12 00:42:17 -0500241{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900242 denali_write_buf(mtd, &byte, 1);
Chin Liang See03534df2014-09-12 00:42:17 -0500243}
244
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900245static uint16_t denali_read_word(struct mtd_info *mtd)
Chin Liang See03534df2014-09-12 00:42:17 -0500246{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900247 uint16_t word;
Chin Liang See03534df2014-09-12 00:42:17 -0500248
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900249 denali_read_buf16(mtd, (uint8_t *)&word, 2);
Chin Liang See03534df2014-09-12 00:42:17 -0500250
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900251 return word;
252}
Chin Liang See03534df2014-09-12 00:42:17 -0500253
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900254static void denali_cmd_ctrl(struct mtd_info *mtd, int dat, unsigned int ctrl)
255{
256 struct denali_nand_info *denali = mtd_to_denali(mtd);
257 uint32_t type;
Chin Liang See03534df2014-09-12 00:42:17 -0500258
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900259 if (ctrl & NAND_CLE)
260 type = DENALI_MAP11_CMD;
261 else if (ctrl & NAND_ALE)
262 type = DENALI_MAP11_ADDR;
263 else
264 return;
Chin Liang See03534df2014-09-12 00:42:17 -0500265
Scott Wood3ea94ed2015-06-26 19:03:26 -0500266 /*
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900267 * Some commands are followed by chip->dev_ready or chip->waitfunc.
268 * irq_status must be cleared here to catch the R/B# interrupt later.
Chin Liang See03534df2014-09-12 00:42:17 -0500269 */
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900270 if (ctrl & NAND_CTRL_CHANGE)
271 denali_reset_irq(denali);
Chin Liang See03534df2014-09-12 00:42:17 -0500272
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900273 denali->host_write(denali, DENALI_BANK(denali) | type, dat);
Chin Liang See03534df2014-09-12 00:42:17 -0500274}
275
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900276static int denali_dev_ready(struct mtd_info *mtd)
Chin Liang See03534df2014-09-12 00:42:17 -0500277{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900278 struct denali_nand_info *denali = mtd_to_denali(mtd);
279
280 return !!(denali_check_irq(denali) & INTR__INT_ACT);
Chin Liang See03534df2014-09-12 00:42:17 -0500281}
282
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900283static int denali_check_erased_page(struct mtd_info *mtd,
284 struct nand_chip *chip, uint8_t *buf,
285 unsigned long uncor_ecc_flags,
286 unsigned int max_bitflips)
Chin Liang See03534df2014-09-12 00:42:17 -0500287{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900288 uint8_t *ecc_code = chip->buffers->ecccode;
289 int ecc_steps = chip->ecc.steps;
290 int ecc_size = chip->ecc.size;
291 int ecc_bytes = chip->ecc.bytes;
292 int i, ret, stat;
Chin Liang See03534df2014-09-12 00:42:17 -0500293
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900294 ret = mtd_ooblayout_get_eccbytes(mtd, ecc_code, chip->oob_poi, 0,
295 chip->ecc.total);
296 if (ret)
297 return ret;
Chin Liang See03534df2014-09-12 00:42:17 -0500298
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900299 for (i = 0; i < ecc_steps; i++) {
300 if (!(uncor_ecc_flags & BIT(i)))
301 continue;
Chin Liang See03534df2014-09-12 00:42:17 -0500302
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900303 stat = nand_check_erased_ecc_chunk(buf, ecc_size,
304 ecc_code, ecc_bytes,
305 NULL, 0,
306 chip->ecc.strength);
307 if (stat < 0) {
308 mtd->ecc_stats.failed++;
309 } else {
310 mtd->ecc_stats.corrected += stat;
311 max_bitflips = max_t(unsigned int, max_bitflips, stat);
312 }
Chin Liang See03534df2014-09-12 00:42:17 -0500313
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900314 buf += ecc_size;
315 ecc_code += ecc_bytes;
316 }
317
318 return max_bitflips;
Chin Liang See03534df2014-09-12 00:42:17 -0500319}
320
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900321static int denali_hw_ecc_fixup(struct mtd_info *mtd,
322 struct denali_nand_info *denali,
323 unsigned long *uncor_ecc_flags)
Chin Liang See03534df2014-09-12 00:42:17 -0500324{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900325 struct nand_chip *chip = mtd_to_nand(mtd);
326 int bank = denali->active_bank;
327 uint32_t ecc_cor;
328 unsigned int max_bitflips;
Chin Liang See03534df2014-09-12 00:42:17 -0500329
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900330 ecc_cor = ioread32(denali->reg + ECC_COR_INFO(bank));
331 ecc_cor >>= ECC_COR_INFO__SHIFT(bank);
332
333 if (ecc_cor & ECC_COR_INFO__UNCOR_ERR) {
334 /*
335 * This flag is set when uncorrectable error occurs at least in
336 * one ECC sector. We can not know "how many sectors", or
337 * "which sector(s)". We need erase-page check for all sectors.
338 */
339 *uncor_ecc_flags = GENMASK(chip->ecc.steps - 1, 0);
340 return 0;
341 }
Chin Liang See03534df2014-09-12 00:42:17 -0500342
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900343 max_bitflips = FIELD_GET(ECC_COR_INFO__MAX_ERRORS, ecc_cor);
344
345 /*
346 * The register holds the maximum of per-sector corrected bitflips.
347 * This is suitable for the return value of the ->read_page() callback.
348 * Unfortunately, we can not know the total number of corrected bits in
349 * the page. Increase the stats by max_bitflips. (compromised solution)
350 */
351 mtd->ecc_stats.corrected += max_bitflips;
352
353 return max_bitflips;
Chin Liang See03534df2014-09-12 00:42:17 -0500354}
355
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900356static int denali_sw_ecc_fixup(struct mtd_info *mtd,
357 struct denali_nand_info *denali,
358 unsigned long *uncor_ecc_flags, uint8_t *buf)
Chin Liang See03534df2014-09-12 00:42:17 -0500359{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900360 unsigned int ecc_size = denali->nand.ecc.size;
361 unsigned int bitflips = 0;
362 unsigned int max_bitflips = 0;
363 uint32_t err_addr, err_cor_info;
364 unsigned int err_byte, err_sector, err_device;
365 uint8_t err_cor_value;
366 unsigned int prev_sector = 0;
367 uint32_t irq_status;
Chin Liang See03534df2014-09-12 00:42:17 -0500368
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900369 denali_reset_irq(denali);
Chin Liang See03534df2014-09-12 00:42:17 -0500370
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900371 do {
372 err_addr = ioread32(denali->reg + ECC_ERROR_ADDRESS);
373 err_sector = FIELD_GET(ECC_ERROR_ADDRESS__SECTOR, err_addr);
374 err_byte = FIELD_GET(ECC_ERROR_ADDRESS__OFFSET, err_addr);
Chin Liang See03534df2014-09-12 00:42:17 -0500375
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900376 err_cor_info = ioread32(denali->reg + ERR_CORRECTION_INFO);
377 err_cor_value = FIELD_GET(ERR_CORRECTION_INFO__BYTE,
378 err_cor_info);
379 err_device = FIELD_GET(ERR_CORRECTION_INFO__DEVICE,
380 err_cor_info);
Chin Liang See03534df2014-09-12 00:42:17 -0500381
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900382 /* reset the bitflip counter when crossing ECC sector */
383 if (err_sector != prev_sector)
384 bitflips = 0;
Chin Liang See03534df2014-09-12 00:42:17 -0500385
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900386 if (err_cor_info & ERR_CORRECTION_INFO__UNCOR) {
387 /*
388 * Check later if this is a real ECC error, or
389 * an erased sector.
390 */
391 *uncor_ecc_flags |= BIT(err_sector);
392 } else if (err_byte < ecc_size) {
393 /*
394 * If err_byte is larger than ecc_size, means error
395 * happened in OOB, so we ignore it. It's no need for
396 * us to correct it err_device is represented the NAND
397 * error bits are happened in if there are more than
398 * one NAND connected.
399 */
400 int offset;
401 unsigned int flips_in_byte;
Chin Liang See03534df2014-09-12 00:42:17 -0500402
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900403 offset = (err_sector * ecc_size + err_byte) *
404 denali->devs_per_cs + err_device;
Chin Liang See03534df2014-09-12 00:42:17 -0500405
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900406 /* correct the ECC error */
407 flips_in_byte = hweight8(buf[offset] ^ err_cor_value);
408 buf[offset] ^= err_cor_value;
409 mtd->ecc_stats.corrected += flips_in_byte;
410 bitflips += flips_in_byte;
Chin Liang See03534df2014-09-12 00:42:17 -0500411
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900412 max_bitflips = max(max_bitflips, bitflips);
413 }
Chin Liang See03534df2014-09-12 00:42:17 -0500414
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900415 prev_sector = err_sector;
416 } while (!(err_cor_info & ERR_CORRECTION_INFO__LAST_ERR));
Chin Liang See03534df2014-09-12 00:42:17 -0500417
Scott Wood3ea94ed2015-06-26 19:03:26 -0500418 /*
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900419 * Once handle all ECC errors, controller will trigger an
420 * ECC_TRANSACTION_DONE interrupt.
Scott Wood3ea94ed2015-06-26 19:03:26 -0500421 */
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900422 irq_status = denali_wait_for_irq(denali, INTR__ECC_TRANSACTION_DONE);
423 if (!(irq_status & INTR__ECC_TRANSACTION_DONE))
424 return -EIO;
Chin Liang See03534df2014-09-12 00:42:17 -0500425
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900426 return max_bitflips;
Chin Liang See03534df2014-09-12 00:42:17 -0500427}
428
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900429static void denali_setup_dma64(struct denali_nand_info *denali,
430 dma_addr_t dma_addr, int page, int write)
Chin Liang See03534df2014-09-12 00:42:17 -0500431{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900432 uint32_t mode;
433 const int page_count = 1;
Chin Liang See03534df2014-09-12 00:42:17 -0500434
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900435 mode = DENALI_MAP10 | DENALI_BANK(denali) | page;
Chin Liang See03534df2014-09-12 00:42:17 -0500436
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900437 /* DMA is a three step process */
Chin Liang See03534df2014-09-12 00:42:17 -0500438
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900439 /*
440 * 1. setup transfer type, interrupt when complete,
441 * burst len = 64 bytes, the number of pages
442 */
443 denali->host_write(denali, mode,
444 0x01002000 | (64 << 16) | (write << 8) | page_count);
Chin Liang See03534df2014-09-12 00:42:17 -0500445
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900446 /* 2. set memory low address */
447 denali->host_write(denali, mode, lower_32_bits(dma_addr));
Chin Liang See03534df2014-09-12 00:42:17 -0500448
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900449 /* 3. set memory high address */
450 denali->host_write(denali, mode, upper_32_bits(dma_addr));
Chin Liang See03534df2014-09-12 00:42:17 -0500451}
452
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900453static void denali_setup_dma32(struct denali_nand_info *denali,
454 dma_addr_t dma_addr, int page, int write)
Chin Liang See03534df2014-09-12 00:42:17 -0500455{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900456 uint32_t mode;
457 const int page_count = 1;
Chin Liang See03534df2014-09-12 00:42:17 -0500458
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900459 mode = DENALI_MAP10 | DENALI_BANK(denali);
Chin Liang See03534df2014-09-12 00:42:17 -0500460
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900461 /* DMA is a four step process */
Chin Liang See03534df2014-09-12 00:42:17 -0500462
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900463 /* 1. setup transfer type and # of pages */
464 denali->host_write(denali, mode | page,
465 0x2000 | (write << 8) | page_count);
Chin Liang See03534df2014-09-12 00:42:17 -0500466
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900467 /* 2. set memory high address bits 23:8 */
468 denali->host_write(denali, mode | ((dma_addr >> 16) << 8), 0x2200);
Chin Liang See03534df2014-09-12 00:42:17 -0500469
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900470 /* 3. set memory low address bits 23:8 */
471 denali->host_write(denali, mode | ((dma_addr & 0xffff) << 8), 0x2300);
Chin Liang See03534df2014-09-12 00:42:17 -0500472
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900473 /* 4. interrupt when complete, burst len = 64 bytes */
474 denali->host_write(denali, mode | 0x14000, 0x2400);
Chin Liang See03534df2014-09-12 00:42:17 -0500475}
476
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900477static int denali_pio_read(struct denali_nand_info *denali, void *buf,
478 size_t size, int page, int raw)
Chin Liang See03534df2014-09-12 00:42:17 -0500479{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900480 u32 addr = DENALI_MAP01 | DENALI_BANK(denali) | page;
481 uint32_t *buf32 = (uint32_t *)buf;
482 uint32_t irq_status, ecc_err_mask;
483 int i;
Chin Liang See03534df2014-09-12 00:42:17 -0500484
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900485 if (denali->caps & DENALI_CAP_HW_ECC_FIXUP)
486 ecc_err_mask = INTR__ECC_UNCOR_ERR;
487 else
488 ecc_err_mask = INTR__ECC_ERR;
Chin Liang See03534df2014-09-12 00:42:17 -0500489
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900490 denali_reset_irq(denali);
Chin Liang See03534df2014-09-12 00:42:17 -0500491
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900492 for (i = 0; i < size / 4; i++)
493 *buf32++ = denali->host_read(denali, addr);
Chin Liang See03534df2014-09-12 00:42:17 -0500494
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900495 irq_status = denali_wait_for_irq(denali, INTR__PAGE_XFER_INC);
496 if (!(irq_status & INTR__PAGE_XFER_INC))
497 return -EIO;
Chin Liang See03534df2014-09-12 00:42:17 -0500498
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900499 if (irq_status & INTR__ERASED_PAGE)
500 memset(buf, 0xff, size);
501
502 return irq_status & ecc_err_mask ? -EBADMSG : 0;
Chin Liang See03534df2014-09-12 00:42:17 -0500503}
504
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900505static int denali_pio_write(struct denali_nand_info *denali,
506 const void *buf, size_t size, int page, int raw)
Chin Liang See03534df2014-09-12 00:42:17 -0500507{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900508 u32 addr = DENALI_MAP01 | DENALI_BANK(denali) | page;
509 const uint32_t *buf32 = (uint32_t *)buf;
510 uint32_t irq_status;
Scott Wood3ea94ed2015-06-26 19:03:26 -0500511 int i;
512
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900513 denali_reset_irq(denali);
514
515 for (i = 0; i < size / 4; i++)
516 denali->host_write(denali, addr, *buf32++);
517
518 irq_status = denali_wait_for_irq(denali,
519 INTR__PROGRAM_COMP | INTR__PROGRAM_FAIL);
520 if (!(irq_status & INTR__PROGRAM_COMP))
521 return -EIO;
522
523 return 0;
Chin Liang See03534df2014-09-12 00:42:17 -0500524}
525
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900526static int denali_pio_xfer(struct denali_nand_info *denali, void *buf,
527 size_t size, int page, int raw, int write)
Chin Liang See03534df2014-09-12 00:42:17 -0500528{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900529 if (write)
530 return denali_pio_write(denali, buf, size, page, raw);
531 else
532 return denali_pio_read(denali, buf, size, page, raw);
Chin Liang See03534df2014-09-12 00:42:17 -0500533}
534
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900535static int denali_dma_xfer(struct denali_nand_info *denali, void *buf,
536 size_t size, int page, int raw, int write)
Chin Liang See03534df2014-09-12 00:42:17 -0500537{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900538 dma_addr_t dma_addr;
539 uint32_t irq_mask, irq_status, ecc_err_mask;
540 enum dma_data_direction dir = write ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
541 int ret = 0;
Chin Liang See03534df2014-09-12 00:42:17 -0500542
Vignesh Raghavendradd62b9a2020-01-16 14:23:47 +0530543 dma_addr = dma_map_single(buf, size, dir);
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900544 if (dma_mapping_error(denali->dev, dma_addr)) {
545 dev_dbg(denali->dev, "Failed to DMA-map buffer. Trying PIO.\n");
546 return denali_pio_xfer(denali, buf, size, page, raw, write);
547 }
Chin Liang See03534df2014-09-12 00:42:17 -0500548
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900549 if (write) {
550 /*
551 * INTR__PROGRAM_COMP is never asserted for the DMA transfer.
552 * We can use INTR__DMA_CMD_COMP instead. This flag is asserted
553 * when the page program is completed.
554 */
555 irq_mask = INTR__DMA_CMD_COMP | INTR__PROGRAM_FAIL;
556 ecc_err_mask = 0;
557 } else if (denali->caps & DENALI_CAP_HW_ECC_FIXUP) {
558 irq_mask = INTR__DMA_CMD_COMP;
559 ecc_err_mask = INTR__ECC_UNCOR_ERR;
560 } else {
561 irq_mask = INTR__DMA_CMD_COMP;
562 ecc_err_mask = INTR__ECC_ERR;
563 }
Chin Liang See03534df2014-09-12 00:42:17 -0500564
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900565 iowrite32(DMA_ENABLE__FLAG, denali->reg + DMA_ENABLE);
Masahiro Yamada9ea23972018-12-19 20:03:19 +0900566 /*
567 * The ->setup_dma() hook kicks DMA by using the data/command
568 * interface, which belongs to a different AXI port from the
569 * register interface. Read back the register to avoid a race.
570 */
571 ioread32(denali->reg + DMA_ENABLE);
Chin Liang See03534df2014-09-12 00:42:17 -0500572
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900573 denali_reset_irq(denali);
574 denali->setup_dma(denali, dma_addr, page, write);
Chin Liang See03534df2014-09-12 00:42:17 -0500575
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900576 irq_status = denali_wait_for_irq(denali, irq_mask);
577 if (!(irq_status & INTR__DMA_CMD_COMP))
578 ret = -EIO;
579 else if (irq_status & ecc_err_mask)
580 ret = -EBADMSG;
Chin Liang See03534df2014-09-12 00:42:17 -0500581
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900582 iowrite32(0, denali->reg + DMA_ENABLE);
Chin Liang See03534df2014-09-12 00:42:17 -0500583
Masahiro Yamada05a5dba2020-02-14 16:40:18 +0900584 dma_unmap_single(dma_addr, size, dir);
Chin Liang See03534df2014-09-12 00:42:17 -0500585
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900586 if (irq_status & INTR__ERASED_PAGE)
587 memset(buf, 0xff, size);
Chin Liang See03534df2014-09-12 00:42:17 -0500588
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900589 return ret;
Chin Liang See03534df2014-09-12 00:42:17 -0500590}
591
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900592static int denali_data_xfer(struct denali_nand_info *denali, void *buf,
593 size_t size, int page, int raw, int write)
Chin Liang See03534df2014-09-12 00:42:17 -0500594{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900595 iowrite32(raw ? 0 : ECC_ENABLE__FLAG, denali->reg + ECC_ENABLE);
596 iowrite32(raw ? TRANSFER_SPARE_REG__FLAG : 0,
597 denali->reg + TRANSFER_SPARE_REG);
Chin Liang See03534df2014-09-12 00:42:17 -0500598
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900599 if (denali->dma_avail)
600 return denali_dma_xfer(denali, buf, size, page, raw, write);
601 else
602 return denali_pio_xfer(denali, buf, size, page, raw, write);
603}
Chin Liang See03534df2014-09-12 00:42:17 -0500604
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900605static void denali_oob_xfer(struct mtd_info *mtd, struct nand_chip *chip,
606 int page, int write)
607{
608 struct denali_nand_info *denali = mtd_to_denali(mtd);
609 unsigned int start_cmd = write ? NAND_CMD_SEQIN : NAND_CMD_READ0;
610 unsigned int rnd_cmd = write ? NAND_CMD_RNDIN : NAND_CMD_RNDOUT;
611 int writesize = mtd->writesize;
612 int oobsize = mtd->oobsize;
613 uint8_t *bufpoi = chip->oob_poi;
614 int ecc_steps = chip->ecc.steps;
615 int ecc_size = chip->ecc.size;
616 int ecc_bytes = chip->ecc.bytes;
617 int oob_skip = denali->oob_skip_bytes;
618 size_t size = writesize + oobsize;
619 int i, pos, len;
Chin Liang See03534df2014-09-12 00:42:17 -0500620
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900621 /* BBM at the beginning of the OOB area */
622 chip->cmdfunc(mtd, start_cmd, writesize, page);
623 if (write)
624 chip->write_buf(mtd, bufpoi, oob_skip);
625 else
626 chip->read_buf(mtd, bufpoi, oob_skip);
627 bufpoi += oob_skip;
Chin Liang See03534df2014-09-12 00:42:17 -0500628
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900629 /* OOB ECC */
630 for (i = 0; i < ecc_steps; i++) {
631 pos = ecc_size + i * (ecc_size + ecc_bytes);
632 len = ecc_bytes;
Chin Liang See03534df2014-09-12 00:42:17 -0500633
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900634 if (pos >= writesize)
635 pos += oob_skip;
636 else if (pos + len > writesize)
637 len = writesize - pos;
Chin Liang See03534df2014-09-12 00:42:17 -0500638
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900639 chip->cmdfunc(mtd, rnd_cmd, pos, -1);
640 if (write)
641 chip->write_buf(mtd, bufpoi, len);
642 else
643 chip->read_buf(mtd, bufpoi, len);
644 bufpoi += len;
645 if (len < ecc_bytes) {
646 len = ecc_bytes - len;
647 chip->cmdfunc(mtd, rnd_cmd, writesize + oob_skip, -1);
648 if (write)
649 chip->write_buf(mtd, bufpoi, len);
650 else
651 chip->read_buf(mtd, bufpoi, len);
652 bufpoi += len;
653 }
654 }
Chin Liang See03534df2014-09-12 00:42:17 -0500655
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900656 /* OOB free */
657 len = oobsize - (bufpoi - chip->oob_poi);
658 chip->cmdfunc(mtd, rnd_cmd, size - len, -1);
659 if (write)
660 chip->write_buf(mtd, bufpoi, len);
661 else
662 chip->read_buf(mtd, bufpoi, len);
Chin Liang See03534df2014-09-12 00:42:17 -0500663}
664
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900665static int denali_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
666 uint8_t *buf, int oob_required, int page)
Chin Liang See03534df2014-09-12 00:42:17 -0500667{
668 struct denali_nand_info *denali = mtd_to_denali(mtd);
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900669 int writesize = mtd->writesize;
670 int oobsize = mtd->oobsize;
671 int ecc_steps = chip->ecc.steps;
672 int ecc_size = chip->ecc.size;
673 int ecc_bytes = chip->ecc.bytes;
674 void *tmp_buf = denali->buf;
675 int oob_skip = denali->oob_skip_bytes;
676 size_t size = writesize + oobsize;
677 int ret, i, pos, len;
Chin Liang See03534df2014-09-12 00:42:17 -0500678
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900679 ret = denali_data_xfer(denali, tmp_buf, size, page, 1, 0);
680 if (ret)
681 return ret;
Chin Liang See03534df2014-09-12 00:42:17 -0500682
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900683 /* Arrange the buffer for syndrome payload/ecc layout */
684 if (buf) {
685 for (i = 0; i < ecc_steps; i++) {
686 pos = i * (ecc_size + ecc_bytes);
687 len = ecc_size;
Chin Liang See03534df2014-09-12 00:42:17 -0500688
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900689 if (pos >= writesize)
690 pos += oob_skip;
691 else if (pos + len > writesize)
692 len = writesize - pos;
Chin Liang See03534df2014-09-12 00:42:17 -0500693
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900694 memcpy(buf, tmp_buf + pos, len);
695 buf += len;
696 if (len < ecc_size) {
697 len = ecc_size - len;
698 memcpy(buf, tmp_buf + writesize + oob_skip,
699 len);
700 buf += len;
701 }
702 }
703 }
Chin Liang See03534df2014-09-12 00:42:17 -0500704
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900705 if (oob_required) {
706 uint8_t *oob = chip->oob_poi;
Chin Liang See03534df2014-09-12 00:42:17 -0500707
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900708 /* BBM at the beginning of the OOB area */
709 memcpy(oob, tmp_buf + writesize, oob_skip);
710 oob += oob_skip;
Chin Liang See03534df2014-09-12 00:42:17 -0500711
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900712 /* OOB ECC */
713 for (i = 0; i < ecc_steps; i++) {
714 pos = ecc_size + i * (ecc_size + ecc_bytes);
715 len = ecc_bytes;
716
717 if (pos >= writesize)
718 pos += oob_skip;
719 else if (pos + len > writesize)
720 len = writesize - pos;
721
722 memcpy(oob, tmp_buf + pos, len);
723 oob += len;
724 if (len < ecc_bytes) {
725 len = ecc_bytes - len;
726 memcpy(oob, tmp_buf + writesize + oob_skip,
727 len);
728 oob += len;
729 }
730 }
731
732 /* OOB free */
733 len = oobsize - (oob - chip->oob_poi);
734 memcpy(oob, tmp_buf + size - len, len);
Chin Liang See03534df2014-09-12 00:42:17 -0500735 }
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900736
Chin Liang See03534df2014-09-12 00:42:17 -0500737 return 0;
738}
739
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900740static int denali_read_oob(struct mtd_info *mtd, struct nand_chip *chip,
741 int page)
Chin Liang See03534df2014-09-12 00:42:17 -0500742{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900743 denali_oob_xfer(mtd, chip, page, 0);
Chin Liang See03534df2014-09-12 00:42:17 -0500744
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900745 return 0;
Chin Liang See03534df2014-09-12 00:42:17 -0500746}
747
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900748static int denali_write_oob(struct mtd_info *mtd, struct nand_chip *chip,
749 int page)
Chin Liang See03534df2014-09-12 00:42:17 -0500750{
751 struct denali_nand_info *denali = mtd_to_denali(mtd);
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900752 int status;
Chin Liang See03534df2014-09-12 00:42:17 -0500753
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900754 denali_reset_irq(denali);
Chin Liang See03534df2014-09-12 00:42:17 -0500755
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900756 denali_oob_xfer(mtd, chip, page, 1);
Chin Liang See03534df2014-09-12 00:42:17 -0500757
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900758 chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
759 status = chip->waitfunc(mtd, chip);
Chin Liang See03534df2014-09-12 00:42:17 -0500760
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900761 return status & NAND_STATUS_FAIL ? -EIO : 0;
Chin Liang See03534df2014-09-12 00:42:17 -0500762}
763
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900764static int denali_read_page(struct mtd_info *mtd, struct nand_chip *chip,
765 uint8_t *buf, int oob_required, int page)
Chin Liang See03534df2014-09-12 00:42:17 -0500766{
767 struct denali_nand_info *denali = mtd_to_denali(mtd);
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900768 unsigned long uncor_ecc_flags = 0;
769 int stat = 0;
770 int ret;
Chin Liang See03534df2014-09-12 00:42:17 -0500771
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900772 ret = denali_data_xfer(denali, buf, mtd->writesize, page, 0, 0);
773 if (ret && ret != -EBADMSG)
774 return ret;
Chin Liang See03534df2014-09-12 00:42:17 -0500775
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900776 if (denali->caps & DENALI_CAP_HW_ECC_FIXUP)
777 stat = denali_hw_ecc_fixup(mtd, denali, &uncor_ecc_flags);
778 else if (ret == -EBADMSG)
779 stat = denali_sw_ecc_fixup(mtd, denali, &uncor_ecc_flags, buf);
Chin Liang See03534df2014-09-12 00:42:17 -0500780
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900781 if (stat < 0)
782 return stat;
Chin Liang See03534df2014-09-12 00:42:17 -0500783
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900784 if (uncor_ecc_flags) {
785 ret = denali_read_oob(mtd, chip, page);
786 if (ret)
787 return ret;
Chin Liang See03534df2014-09-12 00:42:17 -0500788
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900789 stat = denali_check_erased_page(mtd, chip, buf,
790 uncor_ecc_flags, stat);
Chin Liang See03534df2014-09-12 00:42:17 -0500791 }
792
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900793 return stat;
Chin Liang See03534df2014-09-12 00:42:17 -0500794}
795
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900796static int denali_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
797 const uint8_t *buf, int oob_required, int page)
Chin Liang See03534df2014-09-12 00:42:17 -0500798{
799 struct denali_nand_info *denali = mtd_to_denali(mtd);
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900800 int writesize = mtd->writesize;
801 int oobsize = mtd->oobsize;
802 int ecc_steps = chip->ecc.steps;
803 int ecc_size = chip->ecc.size;
804 int ecc_bytes = chip->ecc.bytes;
805 void *tmp_buf = denali->buf;
806 int oob_skip = denali->oob_skip_bytes;
807 size_t size = writesize + oobsize;
808 int i, pos, len;
Chin Liang See03534df2014-09-12 00:42:17 -0500809
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900810 /*
811 * Fill the buffer with 0xff first except the full page transfer.
812 * This simplifies the logic.
813 */
814 if (!buf || !oob_required)
815 memset(tmp_buf, 0xff, size);
816
817 /* Arrange the buffer for syndrome payload/ecc layout */
818 if (buf) {
819 for (i = 0; i < ecc_steps; i++) {
820 pos = i * (ecc_size + ecc_bytes);
821 len = ecc_size;
822
823 if (pos >= writesize)
824 pos += oob_skip;
825 else if (pos + len > writesize)
826 len = writesize - pos;
827
828 memcpy(tmp_buf + pos, buf, len);
829 buf += len;
830 if (len < ecc_size) {
831 len = ecc_size - len;
832 memcpy(tmp_buf + writesize + oob_skip, buf,
833 len);
834 buf += len;
835 }
836 }
Chin Liang See03534df2014-09-12 00:42:17 -0500837 }
838
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900839 if (oob_required) {
840 const uint8_t *oob = chip->oob_poi;
Chin Liang See03534df2014-09-12 00:42:17 -0500841
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900842 /* BBM at the beginning of the OOB area */
843 memcpy(tmp_buf + writesize, oob, oob_skip);
844 oob += oob_skip;
Chin Liang See03534df2014-09-12 00:42:17 -0500845
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900846 /* OOB ECC */
847 for (i = 0; i < ecc_steps; i++) {
848 pos = ecc_size + i * (ecc_size + ecc_bytes);
849 len = ecc_bytes;
Chin Liang See03534df2014-09-12 00:42:17 -0500850
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900851 if (pos >= writesize)
852 pos += oob_skip;
853 else if (pos + len > writesize)
854 len = writesize - pos;
Chin Liang See03534df2014-09-12 00:42:17 -0500855
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900856 memcpy(tmp_buf + pos, oob, len);
857 oob += len;
858 if (len < ecc_bytes) {
859 len = ecc_bytes - len;
860 memcpy(tmp_buf + writesize + oob_skip, oob,
861 len);
862 oob += len;
863 }
Chin Liang See03534df2014-09-12 00:42:17 -0500864 }
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900865
866 /* OOB free */
867 len = oobsize - (oob - chip->oob_poi);
868 memcpy(tmp_buf + size - len, oob, len);
Chin Liang See03534df2014-09-12 00:42:17 -0500869 }
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900870
871 return denali_data_xfer(denali, tmp_buf, size, page, 1, 1);
Chin Liang See03534df2014-09-12 00:42:17 -0500872}
873
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900874static int denali_write_page(struct mtd_info *mtd, struct nand_chip *chip,
875 const uint8_t *buf, int oob_required, int page)
Chin Liang See03534df2014-09-12 00:42:17 -0500876{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900877 struct denali_nand_info *denali = mtd_to_denali(mtd);
Chin Liang See03534df2014-09-12 00:42:17 -0500878
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900879 return denali_data_xfer(denali, (void *)buf, mtd->writesize,
880 page, 0, 1);
Chin Liang See03534df2014-09-12 00:42:17 -0500881}
882
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900883static void denali_select_chip(struct mtd_info *mtd, int chip)
Chin Liang See03534df2014-09-12 00:42:17 -0500884{
885 struct denali_nand_info *denali = mtd_to_denali(mtd);
Chin Liang See03534df2014-09-12 00:42:17 -0500886
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900887 denali->active_bank = chip;
Chin Liang See03534df2014-09-12 00:42:17 -0500888}
889
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900890static int denali_waitfunc(struct mtd_info *mtd, struct nand_chip *chip)
Chin Liang See03534df2014-09-12 00:42:17 -0500891{
892 struct denali_nand_info *denali = mtd_to_denali(mtd);
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900893 uint32_t irq_status;
Chin Liang See03534df2014-09-12 00:42:17 -0500894
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900895 /* R/B# pin transitioned from low to high? */
896 irq_status = denali_wait_for_irq(denali, INTR__INT_ACT);
Chin Liang See03534df2014-09-12 00:42:17 -0500897
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900898 return irq_status & INTR__INT_ACT ? 0 : NAND_STATUS_FAIL;
Chin Liang See03534df2014-09-12 00:42:17 -0500899}
900
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900901static int denali_erase(struct mtd_info *mtd, int page)
Chin Liang See03534df2014-09-12 00:42:17 -0500902{
903 struct denali_nand_info *denali = mtd_to_denali(mtd);
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900904 uint32_t irq_status;
Chin Liang See03534df2014-09-12 00:42:17 -0500905
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900906 denali_reset_irq(denali);
Chin Liang See03534df2014-09-12 00:42:17 -0500907
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900908 denali->host_write(denali, DENALI_MAP10 | DENALI_BANK(denali) | page,
909 DENALI_ERASE);
Scott Wood3ea94ed2015-06-26 19:03:26 -0500910
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900911 /* wait for erase to complete or failure to occur */
912 irq_status = denali_wait_for_irq(denali,
913 INTR__ERASE_COMP | INTR__ERASE_FAIL);
Chin Liang See03534df2014-09-12 00:42:17 -0500914
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900915 return irq_status & INTR__ERASE_COMP ? 0 : NAND_STATUS_FAIL;
Chin Liang See03534df2014-09-12 00:42:17 -0500916}
917
Masahiro Yamada59a1f3e2017-11-29 19:18:18 +0900918static int denali_setup_data_interface(struct mtd_info *mtd, int chipnr,
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900919 const struct nand_data_interface *conf)
Chin Liang See03534df2014-09-12 00:42:17 -0500920{
921 struct denali_nand_info *denali = mtd_to_denali(mtd);
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900922 const struct nand_sdr_timings *timings;
Masahiro Yamada2d1fbc82018-12-19 20:03:18 +0900923 unsigned long t_x, mult_x;
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900924 int acc_clks, re_2_we, re_2_re, we_2_re, addr_2_data;
925 int rdwr_en_lo, rdwr_en_hi, rdwr_en_lo_hi, cs_setup;
926 int addr_2_data_mask;
927 uint32_t tmp;
Scott Wood3ea94ed2015-06-26 19:03:26 -0500928
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900929 timings = nand_get_sdr_timings(conf);
930 if (IS_ERR(timings))
931 return PTR_ERR(timings);
Chin Liang See03534df2014-09-12 00:42:17 -0500932
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900933 /* clk_x period in picoseconds */
Masahiro Yamada2d1fbc82018-12-19 20:03:18 +0900934 t_x = DIV_ROUND_DOWN_ULL(1000000000000ULL, denali->clk_x_rate);
935 if (!t_x)
936 return -EINVAL;
937
938 /*
939 * The bus interface clock, clk_x, is phase aligned with the core clock.
940 * The clk_x is an integral multiple N of the core clk. The value N is
941 * configured at IP delivery time, and its available value is 4, 5, 6.
942 */
943 mult_x = DIV_ROUND_CLOSEST_ULL(denali->clk_x_rate, denali->clk_rate);
944 if (mult_x < 4 || mult_x > 6)
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900945 return -EINVAL;
Chin Liang See03534df2014-09-12 00:42:17 -0500946
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900947 if (chipnr == NAND_DATA_IFACE_CHECK_ONLY)
948 return 0;
Chin Liang See03534df2014-09-12 00:42:17 -0500949
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900950 /* tREA -> ACC_CLKS */
Masahiro Yamada2d1fbc82018-12-19 20:03:18 +0900951 acc_clks = DIV_ROUND_UP(timings->tREA_max, t_x);
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900952 acc_clks = min_t(int, acc_clks, ACC_CLKS__VALUE);
953
954 tmp = ioread32(denali->reg + ACC_CLKS);
955 tmp &= ~ACC_CLKS__VALUE;
956 tmp |= FIELD_PREP(ACC_CLKS__VALUE, acc_clks);
957 iowrite32(tmp, denali->reg + ACC_CLKS);
958
959 /* tRWH -> RE_2_WE */
Masahiro Yamada2d1fbc82018-12-19 20:03:18 +0900960 re_2_we = DIV_ROUND_UP(timings->tRHW_min, t_x);
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900961 re_2_we = min_t(int, re_2_we, RE_2_WE__VALUE);
Chin Liang See03534df2014-09-12 00:42:17 -0500962
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900963 tmp = ioread32(denali->reg + RE_2_WE);
964 tmp &= ~RE_2_WE__VALUE;
965 tmp |= FIELD_PREP(RE_2_WE__VALUE, re_2_we);
966 iowrite32(tmp, denali->reg + RE_2_WE);
967
968 /* tRHZ -> RE_2_RE */
Masahiro Yamada2d1fbc82018-12-19 20:03:18 +0900969 re_2_re = DIV_ROUND_UP(timings->tRHZ_max, t_x);
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900970 re_2_re = min_t(int, re_2_re, RE_2_RE__VALUE);
971
972 tmp = ioread32(denali->reg + RE_2_RE);
973 tmp &= ~RE_2_RE__VALUE;
974 tmp |= FIELD_PREP(RE_2_RE__VALUE, re_2_re);
975 iowrite32(tmp, denali->reg + RE_2_RE);
976
977 /*
978 * tCCS, tWHR -> WE_2_RE
979 *
980 * With WE_2_RE properly set, the Denali controller automatically takes
981 * care of the delay; the driver need not set NAND_WAIT_TCCS.
982 */
Masahiro Yamada2d1fbc82018-12-19 20:03:18 +0900983 we_2_re = DIV_ROUND_UP(max(timings->tCCS_min, timings->tWHR_min), t_x);
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900984 we_2_re = min_t(int, we_2_re, TWHR2_AND_WE_2_RE__WE_2_RE);
985
986 tmp = ioread32(denali->reg + TWHR2_AND_WE_2_RE);
987 tmp &= ~TWHR2_AND_WE_2_RE__WE_2_RE;
988 tmp |= FIELD_PREP(TWHR2_AND_WE_2_RE__WE_2_RE, we_2_re);
989 iowrite32(tmp, denali->reg + TWHR2_AND_WE_2_RE);
990
991 /* tADL -> ADDR_2_DATA */
992
993 /* for older versions, ADDR_2_DATA is only 6 bit wide */
994 addr_2_data_mask = TCWAW_AND_ADDR_2_DATA__ADDR_2_DATA;
995 if (denali->revision < 0x0501)
996 addr_2_data_mask >>= 1;
997
Masahiro Yamada2d1fbc82018-12-19 20:03:18 +0900998 addr_2_data = DIV_ROUND_UP(timings->tADL_min, t_x);
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +0900999 addr_2_data = min_t(int, addr_2_data, addr_2_data_mask);
1000
1001 tmp = ioread32(denali->reg + TCWAW_AND_ADDR_2_DATA);
1002 tmp &= ~TCWAW_AND_ADDR_2_DATA__ADDR_2_DATA;
1003 tmp |= FIELD_PREP(TCWAW_AND_ADDR_2_DATA__ADDR_2_DATA, addr_2_data);
1004 iowrite32(tmp, denali->reg + TCWAW_AND_ADDR_2_DATA);
1005
1006 /* tREH, tWH -> RDWR_EN_HI_CNT */
1007 rdwr_en_hi = DIV_ROUND_UP(max(timings->tREH_min, timings->tWH_min),
Masahiro Yamada2d1fbc82018-12-19 20:03:18 +09001008 t_x);
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001009 rdwr_en_hi = min_t(int, rdwr_en_hi, RDWR_EN_HI_CNT__VALUE);
1010
1011 tmp = ioread32(denali->reg + RDWR_EN_HI_CNT);
1012 tmp &= ~RDWR_EN_HI_CNT__VALUE;
1013 tmp |= FIELD_PREP(RDWR_EN_HI_CNT__VALUE, rdwr_en_hi);
1014 iowrite32(tmp, denali->reg + RDWR_EN_HI_CNT);
1015
1016 /* tRP, tWP -> RDWR_EN_LO_CNT */
Masahiro Yamada2d1fbc82018-12-19 20:03:18 +09001017 rdwr_en_lo = DIV_ROUND_UP(max(timings->tRP_min, timings->tWP_min), t_x);
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001018 rdwr_en_lo_hi = DIV_ROUND_UP(max(timings->tRC_min, timings->tWC_min),
Masahiro Yamada2d1fbc82018-12-19 20:03:18 +09001019 t_x);
1020 rdwr_en_lo_hi = max_t(int, rdwr_en_lo_hi, mult_x);
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001021 rdwr_en_lo = max(rdwr_en_lo, rdwr_en_lo_hi - rdwr_en_hi);
1022 rdwr_en_lo = min_t(int, rdwr_en_lo, RDWR_EN_LO_CNT__VALUE);
1023
1024 tmp = ioread32(denali->reg + RDWR_EN_LO_CNT);
1025 tmp &= ~RDWR_EN_LO_CNT__VALUE;
1026 tmp |= FIELD_PREP(RDWR_EN_LO_CNT__VALUE, rdwr_en_lo);
1027 iowrite32(tmp, denali->reg + RDWR_EN_LO_CNT);
1028
1029 /* tCS, tCEA -> CS_SETUP_CNT */
Masahiro Yamada2d1fbc82018-12-19 20:03:18 +09001030 cs_setup = max3((int)DIV_ROUND_UP(timings->tCS_min, t_x) - rdwr_en_lo,
1031 (int)DIV_ROUND_UP(timings->tCEA_max, t_x) - acc_clks,
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001032 0);
1033 cs_setup = min_t(int, cs_setup, CS_SETUP_CNT__VALUE);
1034
1035 tmp = ioread32(denali->reg + CS_SETUP_CNT);
1036 tmp &= ~CS_SETUP_CNT__VALUE;
1037 tmp |= FIELD_PREP(CS_SETUP_CNT__VALUE, cs_setup);
1038 iowrite32(tmp, denali->reg + CS_SETUP_CNT);
Scott Wood3ea94ed2015-06-26 19:03:26 -05001039
1040 return 0;
Chin Liang See03534df2014-09-12 00:42:17 -05001041}
1042
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001043static void denali_reset_banks(struct denali_nand_info *denali)
Chin Liang See03534df2014-09-12 00:42:17 -05001044{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001045 u32 irq_status;
1046 int i;
Chin Liang See03534df2014-09-12 00:42:17 -05001047
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001048 for (i = 0; i < denali->max_banks; i++) {
1049 denali->active_bank = i;
1050
1051 denali_reset_irq(denali);
1052
1053 iowrite32(DEVICE_RESET__BANK(i),
1054 denali->reg + DEVICE_RESET);
1055
1056 irq_status = denali_wait_for_irq(denali,
1057 INTR__RST_COMP | INTR__INT_ACT | INTR__TIME_OUT);
1058 if (!(irq_status & INTR__INT_ACT))
1059 break;
Chin Liang See03534df2014-09-12 00:42:17 -05001060 }
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001061
1062 dev_dbg(denali->dev, "%d chips connected\n", i);
1063 denali->max_banks = i;
Chin Liang See03534df2014-09-12 00:42:17 -05001064}
Chin Liang See03534df2014-09-12 00:42:17 -05001065
Chin Liang See03534df2014-09-12 00:42:17 -05001066static void denali_hw_init(struct denali_nand_info *denali)
1067{
1068 /*
Masahiro Yamada54fde8e2017-09-15 21:43:19 +09001069 * The REVISION register may not be reliable. Platforms are allowed to
1070 * override it.
1071 */
1072 if (!denali->revision)
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001073 denali->revision = swab16(ioread32(denali->reg + REVISION));
Masahiro Yamada54fde8e2017-09-15 21:43:19 +09001074
1075 /*
Masahiro Yamada6be38732020-01-30 00:55:55 +09001076 * Set how many bytes should be skipped before writing data in OOB.
1077 * If a platform requests a non-zero value, set it to the register.
1078 * Otherwise, read the value out, expecting it has already been set up
1079 * by firmware.
Chin Liang See03534df2014-09-12 00:42:17 -05001080 */
Masahiro Yamada6be38732020-01-30 00:55:55 +09001081 if (denali->oob_skip_bytes)
1082 iowrite32(denali->oob_skip_bytes,
1083 denali->reg + SPARE_AREA_SKIP_BYTES);
1084 else
1085 denali->oob_skip_bytes = ioread32(denali->reg +
1086 SPARE_AREA_SKIP_BYTES);
1087
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001088 denali_detect_max_banks(denali);
1089 iowrite32(0x0F, denali->reg + RB_PIN_ENABLED);
1090 iowrite32(CHIP_EN_DONT_CARE__FLAG, denali->reg + CHIP_ENABLE_DONT_CARE);
Chin Liang See03534df2014-09-12 00:42:17 -05001091
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001092 iowrite32(0xffff, denali->reg + SPARE_AREA_MARKER);
Chin Liang See03534df2014-09-12 00:42:17 -05001093}
1094
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001095int denali_calc_ecc_bytes(int step_size, int strength)
1096{
1097 /* BCH code. Denali requires ecc.bytes to be multiple of 2 */
1098 return DIV_ROUND_UP(strength * fls(step_size * 8), 16) * 2;
1099}
1100EXPORT_SYMBOL(denali_calc_ecc_bytes);
Chin Liang See03534df2014-09-12 00:42:17 -05001101
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001102static int denali_ecc_setup(struct mtd_info *mtd, struct nand_chip *chip,
1103 struct denali_nand_info *denali)
Chin Liang See03534df2014-09-12 00:42:17 -05001104{
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001105 int oobavail = mtd->oobsize - denali->oob_skip_bytes;
Masahiro Yamadada0763d2014-11-13 20:31:50 +09001106 int ret;
Chin Liang See03534df2014-09-12 00:42:17 -05001107
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001108 /*
1109 * If .size and .strength are already set (usually by DT),
1110 * check if they are supported by this controller.
1111 */
1112 if (chip->ecc.size && chip->ecc.strength)
1113 return nand_check_ecc_caps(chip, denali->ecc_caps, oobavail);
1114
1115 /*
1116 * We want .size and .strength closest to the chip's requirement
1117 * unless NAND_ECC_MAXIMIZE is requested.
1118 */
1119 if (!(chip->ecc.options & NAND_ECC_MAXIMIZE)) {
1120 ret = nand_match_ecc_req(chip, denali->ecc_caps, oobavail);
1121 if (!ret)
1122 return 0;
1123 }
1124
1125 /* Max ECC strength is the last thing we can do */
1126 return nand_maximize_ecc(chip, denali->ecc_caps, oobavail);
1127}
1128
1129static struct nand_ecclayout nand_oob;
1130
1131static int denali_ooblayout_ecc(struct mtd_info *mtd, int section,
1132 struct mtd_oob_region *oobregion)
1133{
1134 struct denali_nand_info *denali = mtd_to_denali(mtd);
1135 struct nand_chip *chip = mtd_to_nand(mtd);
1136
1137 if (section)
1138 return -ERANGE;
1139
1140 oobregion->offset = denali->oob_skip_bytes;
1141 oobregion->length = chip->ecc.total;
1142
1143 return 0;
1144}
1145
1146static int denali_ooblayout_free(struct mtd_info *mtd, int section,
1147 struct mtd_oob_region *oobregion)
1148{
1149 struct denali_nand_info *denali = mtd_to_denali(mtd);
1150 struct nand_chip *chip = mtd_to_nand(mtd);
1151
1152 if (section)
1153 return -ERANGE;
1154
1155 oobregion->offset = chip->ecc.total + denali->oob_skip_bytes;
1156 oobregion->length = mtd->oobsize - oobregion->offset;
1157
1158 return 0;
1159}
Chin Liang See03534df2014-09-12 00:42:17 -05001160
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001161static const struct mtd_ooblayout_ops denali_ooblayout_ops = {
1162 .ecc = denali_ooblayout_ecc,
Simon Glass62fd1a42020-02-03 07:35:56 -07001163 .rfree = denali_ooblayout_free,
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001164};
Chin Liang See03534df2014-09-12 00:42:17 -05001165
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001166static int denali_multidev_fixup(struct denali_nand_info *denali)
1167{
1168 struct nand_chip *chip = &denali->nand;
1169 struct mtd_info *mtd = nand_to_mtd(chip);
Masahiro Yamadada0763d2014-11-13 20:31:50 +09001170
1171 /*
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001172 * Support for multi device:
1173 * When the IP configuration is x16 capable and two x8 chips are
1174 * connected in parallel, DEVICES_CONNECTED should be set to 2.
1175 * In this case, the core framework knows nothing about this fact,
1176 * so we should tell it the _logical_ pagesize and anything necessary.
Masahiro Yamadada0763d2014-11-13 20:31:50 +09001177 */
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001178 denali->devs_per_cs = ioread32(denali->reg + DEVICES_CONNECTED);
Chin Liang See03534df2014-09-12 00:42:17 -05001179
Chin Liang See03534df2014-09-12 00:42:17 -05001180 /*
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001181 * On some SoCs, DEVICES_CONNECTED is not auto-detected.
1182 * For those, DEVICES_CONNECTED is left to 0. Set 1 if it is the case.
Chin Liang See03534df2014-09-12 00:42:17 -05001183 */
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001184 if (denali->devs_per_cs == 0) {
1185 denali->devs_per_cs = 1;
1186 iowrite32(1, denali->reg + DEVICES_CONNECTED);
1187 }
1188
1189 if (denali->devs_per_cs == 1)
1190 return 0;
1191
1192 if (denali->devs_per_cs != 2) {
1193 dev_err(denali->dev, "unsupported number of devices %d\n",
1194 denali->devs_per_cs);
1195 return -EINVAL;
1196 }
1197
1198 /* 2 chips in parallel */
1199 mtd->size <<= 1;
1200 mtd->erasesize <<= 1;
1201 mtd->writesize <<= 1;
1202 mtd->oobsize <<= 1;
1203 chip->chipsize <<= 1;
1204 chip->page_shift += 1;
1205 chip->phys_erase_shift += 1;
1206 chip->bbt_erase_shift += 1;
1207 chip->chip_shift += 1;
1208 chip->pagemask <<= 1;
1209 chip->ecc.size <<= 1;
1210 chip->ecc.bytes <<= 1;
1211 chip->ecc.strength <<= 1;
1212 denali->oob_skip_bytes <<= 1;
1213
1214 return 0;
1215}
1216
1217int denali_init(struct denali_nand_info *denali)
1218{
1219 struct nand_chip *chip = &denali->nand;
1220 struct mtd_info *mtd = nand_to_mtd(chip);
1221 u32 features = ioread32(denali->reg + FEATURES);
1222 int ret;
1223
1224 denali_hw_init(denali);
1225
1226 denali_clear_irq_all(denali);
1227
1228 denali_reset_banks(denali);
1229
1230 denali->active_bank = DENALI_INVALID_BANK;
1231
1232 chip->flash_node = dev_of_offset(denali->dev);
1233 /* Fallback to the default name if DT did not give "label" property */
1234 if (!mtd->name)
1235 mtd->name = "denali-nand";
Chin Liang See03534df2014-09-12 00:42:17 -05001236
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001237 chip->select_chip = denali_select_chip;
1238 chip->read_byte = denali_read_byte;
1239 chip->write_byte = denali_write_byte;
1240 chip->read_word = denali_read_word;
1241 chip->cmd_ctrl = denali_cmd_ctrl;
1242 chip->dev_ready = denali_dev_ready;
1243 chip->waitfunc = denali_waitfunc;
1244
1245 if (features & FEATURES__INDEX_ADDR) {
1246 denali->host_read = denali_indexed_read;
1247 denali->host_write = denali_indexed_write;
1248 } else {
1249 denali->host_read = denali_direct_read;
1250 denali->host_write = denali_direct_write;
1251 }
1252
1253 /* clk rate info is needed for setup_data_interface */
1254 if (denali->clk_x_rate)
1255 chip->setup_data_interface = denali_setup_data_interface;
1256
1257 ret = nand_scan_ident(mtd, denali->max_banks, NULL);
1258 if (ret)
1259 return ret;
1260
1261 if (ioread32(denali->reg + FEATURES) & FEATURES__DMA)
1262 denali->dma_avail = 1;
1263
1264 if (denali->dma_avail) {
Masahiro Yamadae83725e2018-07-19 10:13:23 +09001265 chip->buf_align = ARCH_DMA_MINALIGN;
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001266 if (denali->caps & DENALI_CAP_DMA_64BIT)
1267 denali->setup_dma = denali_setup_dma64;
1268 else
1269 denali->setup_dma = denali_setup_dma32;
1270 } else {
1271 chip->buf_align = 4;
1272 }
1273
1274 chip->options |= NAND_USE_BOUNCE_BUFFER;
1275 chip->bbt_options |= NAND_BBT_USE_FLASH;
1276 chip->bbt_options |= NAND_BBT_NO_OOB;
1277 denali->nand.ecc.mode = NAND_ECC_HW_SYNDROME;
Masahiro Yamadada0763d2014-11-13 20:31:50 +09001278
Scott Wood3ea94ed2015-06-26 19:03:26 -05001279 /* no subpage writes on denali */
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001280 chip->options |= NAND_NO_SUBPAGE_WRITE;
Scott Wood3ea94ed2015-06-26 19:03:26 -05001281
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001282 ret = denali_ecc_setup(mtd, chip, denali);
1283 if (ret) {
1284 dev_err(denali->dev, "Failed to setup ECC settings.\n");
1285 return ret;
Chin Liang See03534df2014-09-12 00:42:17 -05001286 }
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001287
1288 dev_dbg(denali->dev,
1289 "chosen ECC settings: step=%d, strength=%d, bytes=%d\n",
1290 chip->ecc.size, chip->ecc.strength, chip->ecc.bytes);
1291
1292 iowrite32(FIELD_PREP(ECC_CORRECTION__ERASE_THRESHOLD, 1) |
1293 FIELD_PREP(ECC_CORRECTION__VALUE, chip->ecc.strength),
1294 denali->reg + ECC_CORRECTION);
1295 iowrite32(mtd->erasesize / mtd->writesize,
1296 denali->reg + PAGES_PER_BLOCK);
1297 iowrite32(chip->options & NAND_BUSWIDTH_16 ? 1 : 0,
1298 denali->reg + DEVICE_WIDTH);
1299 iowrite32(chip->options & NAND_ROW_ADDR_3 ? 0 : TWO_ROW_ADDR_CYCLES__FLAG,
1300 denali->reg + TWO_ROW_ADDR_CYCLES);
1301 iowrite32(mtd->writesize, denali->reg + DEVICE_MAIN_AREA_SIZE);
1302 iowrite32(mtd->oobsize, denali->reg + DEVICE_SPARE_AREA_SIZE);
1303
1304 iowrite32(chip->ecc.size, denali->reg + CFG_DATA_BLOCK_SIZE);
1305 iowrite32(chip->ecc.size, denali->reg + CFG_LAST_DATA_BLOCK_SIZE);
1306 /* chip->ecc.steps is set by nand_scan_tail(); not available here */
1307 iowrite32(mtd->writesize / chip->ecc.size,
1308 denali->reg + CFG_NUM_DATA_BLOCKS);
1309
1310 mtd_set_ooblayout(mtd, &denali_ooblayout_ops);
1311
Masahiro Yamadada0763d2014-11-13 20:31:50 +09001312 nand_oob.eccbytes = denali->nand.ecc.bytes;
1313 denali->nand.ecc.layout = &nand_oob;
Chin Liang See03534df2014-09-12 00:42:17 -05001314
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001315 if (chip->options & NAND_BUSWIDTH_16) {
1316 chip->read_buf = denali_read_buf16;
1317 chip->write_buf = denali_write_buf16;
1318 } else {
1319 chip->read_buf = denali_read_buf;
1320 chip->write_buf = denali_write_buf;
1321 }
1322 chip->ecc.options |= NAND_ECC_CUSTOM_PAGE_ACCESS;
1323 chip->ecc.read_page = denali_read_page;
1324 chip->ecc.read_page_raw = denali_read_page_raw;
1325 chip->ecc.write_page = denali_write_page;
1326 chip->ecc.write_page_raw = denali_write_page_raw;
1327 chip->ecc.read_oob = denali_read_oob;
1328 chip->ecc.write_oob = denali_write_oob;
1329 chip->erase = denali_erase;
Masahiro Yamada628ee1e2014-11-13 20:31:51 +09001330
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001331 ret = denali_multidev_fixup(denali);
1332 if (ret)
1333 return ret;
Masahiro Yamadada0763d2014-11-13 20:31:50 +09001334
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001335 /*
1336 * This buffer is DMA-mapped by denali_{read,write}_page_raw. Do not
1337 * use devm_kmalloc() because the memory allocated by devm_ does not
1338 * guarantee DMA-safe alignment.
1339 */
1340 denali->buf = kmalloc(mtd->writesize + mtd->oobsize, GFP_KERNEL);
1341 if (!denali->buf)
1342 return -ENOMEM;
1343
1344 ret = nand_scan_tail(mtd);
1345 if (ret)
1346 goto free_buf;
Masahiro Yamadada0763d2014-11-13 20:31:50 +09001347
Scott Wood52ab7ce2016-05-30 13:57:58 -05001348 ret = nand_register(0, mtd);
Masahiro Yamada8b0c16f2017-11-22 02:38:32 +09001349 if (ret) {
1350 dev_err(denali->dev, "Failed to register MTD: %d\n", ret);
1351 goto free_buf;
1352 }
1353 return 0;
1354
1355free_buf:
1356 kfree(denali->buf);
Masahiro Yamadada0763d2014-11-13 20:31:50 +09001357
Masahiro Yamadada0763d2014-11-13 20:31:50 +09001358 return ret;
Chin Liang See03534df2014-09-12 00:42:17 -05001359}