2018-08-20 12:26:36 +09:00
|
|
|
// SPDX-License-Identifier: GPL-2.0
|
2010-05-13 15:57:33 +01:00
|
|
|
/*
|
|
|
|
* NAND Flash Controller Device Driver
|
|
|
|
* Copyright © 2009-2010, Intel Corporation and its suppliers.
|
|
|
|
*
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
* Copyright (c) 2017-2019 Socionext Inc.
|
2018-08-20 12:26:36 +09:00
|
|
|
* Reworked by Masahiro Yamada <yamada.masahiro@socionext.com>
|
2010-05-13 15:57:33 +01:00
|
|
|
*/
|
2017-09-22 12:46:40 +09:00
|
|
|
|
2017-09-22 12:46:43 +09:00
|
|
|
#include <linux/bitfield.h>
|
2017-09-22 12:46:40 +09:00
|
|
|
#include <linux/completion.h>
|
2011-05-06 15:28:55 +01:00
|
|
|
#include <linux/dma-mapping.h>
|
2017-09-22 12:46:40 +09:00
|
|
|
#include <linux/interrupt.h>
|
|
|
|
#include <linux/io.h>
|
2010-05-13 15:57:33 +01:00
|
|
|
#include <linux/module.h>
|
2017-09-22 12:46:40 +09:00
|
|
|
#include <linux/mtd/mtd.h>
|
|
|
|
#include <linux/mtd/rawnand.h>
|
2017-06-13 22:45:48 +09:00
|
|
|
#include <linux/slab.h>
|
2017-09-22 12:46:40 +09:00
|
|
|
#include <linux/spinlock.h>
|
2010-05-13 15:57:33 +01:00
|
|
|
|
|
|
|
#include "denali.h"
|
|
|
|
|
|
|
|
#define DENALI_NAND_NAME "denali-nand"
|
|
|
|
|
2017-09-22 12:46:48 +09:00
|
|
|
/* for Indexed Addressing */
|
|
|
|
#define DENALI_INDEXED_CTRL 0x00
|
|
|
|
#define DENALI_INDEXED_DATA 0x10
|
mtd: nand: denali: avoid magic numbers and rename for clarification
Introduce some macros and helpers to avoid magic numbers and
rename macros/functions for clarification.
- We see '| 2' in several places. This means Data Cycle in MAP11 mode.
The Denali User's Guide says bit[1:0] of MAP11 is like follows:
b'00 = Command Cycle
b'01 = Address Cycle
b'10 = Data Cycle
So, this commit added DENALI_MAP11_{CMD,ADDR,DATA} macros.
- We see 'denali->flash_mem + 0x10' in several places, but 0x10 is a
magic number. Actually, this accesses the data port of the Host
Data/Command Interface. So, this commit added DENALI_HOST_DATA.
On the other hand, 'denali->flash_mem' gets access to the address
port, so DENALI_HOST_ADDR was also added.
- We see 'index_addr(denali, cmd, 0x1)' in denali_erase(), but 0x1
is a magic number. 0x1 means the erase operation. Replace 0x1
with DENALI_ERASE.
- Rename index_addr() to denali_host_write() for clarification
- Denali User's Guide says MAP{00,01,10,11} for access mode. Match
the macros with terminology in the IP document.
- Rename struct members as follows:
flash_bank -> active_bank (currently selected bank)
flash_reg -> reg (base address of registers)
flash_mem -> host (base address of host interface)
devnum -> devs_per_cs (devices connected in parallel)
bbtskipbytes -> oob_skip_bytes (number of bytes to skip in OOB)
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-06-16 14:36:39 +09:00
|
|
|
|
|
|
|
#define DENALI_MAP00 (0 << 26) /* direct access to buffer */
|
|
|
|
#define DENALI_MAP01 (1 << 26) /* read/write pages in PIO */
|
|
|
|
#define DENALI_MAP10 (2 << 26) /* high-level control plane */
|
|
|
|
#define DENALI_MAP11 (3 << 26) /* direct controller access */
|
|
|
|
|
|
|
|
/* MAP11 access cycle type */
|
|
|
|
#define DENALI_MAP11_CMD ((DENALI_MAP11) | 0) /* command cycle */
|
|
|
|
#define DENALI_MAP11_ADDR ((DENALI_MAP11) | 1) /* address cycle */
|
|
|
|
#define DENALI_MAP11_DATA ((DENALI_MAP11) | 2) /* data cycle */
|
|
|
|
|
|
|
|
#define DENALI_BANK(denali) ((denali)->active_bank << 24)
|
2010-05-13 15:57:33 +01:00
|
|
|
|
mtd: nand: denali: avoid magic numbers and rename for clarification
Introduce some macros and helpers to avoid magic numbers and
rename macros/functions for clarification.
- We see '| 2' in several places. This means Data Cycle in MAP11 mode.
The Denali User's Guide says bit[1:0] of MAP11 is like follows:
b'00 = Command Cycle
b'01 = Address Cycle
b'10 = Data Cycle
So, this commit added DENALI_MAP11_{CMD,ADDR,DATA} macros.
- We see 'denali->flash_mem + 0x10' in several places, but 0x10 is a
magic number. Actually, this accesses the data port of the Host
Data/Command Interface. So, this commit added DENALI_HOST_DATA.
On the other hand, 'denali->flash_mem' gets access to the address
port, so DENALI_HOST_ADDR was also added.
- We see 'index_addr(denali, cmd, 0x1)' in denali_erase(), but 0x1
is a magic number. 0x1 means the erase operation. Replace 0x1
with DENALI_ERASE.
- Rename index_addr() to denali_host_write() for clarification
- Denali User's Guide says MAP{00,01,10,11} for access mode. Match
the macros with terminology in the IP document.
- Rename struct members as follows:
flash_bank -> active_bank (currently selected bank)
flash_reg -> reg (base address of registers)
flash_mem -> host (base address of host interface)
devnum -> devs_per_cs (devices connected in parallel)
bbtskipbytes -> oob_skip_bytes (number of bytes to skip in OOB)
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-06-16 14:36:39 +09:00
|
|
|
#define DENALI_INVALID_BANK -1
|
2017-06-13 22:45:38 +09:00
|
|
|
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
static struct denali_chip *to_denali_chip(struct nand_chip *chip)
|
2015-12-11 15:06:00 +01:00
|
|
|
{
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
return container_of(chip, struct denali_chip, chip);
|
2015-12-11 15:06:00 +01:00
|
|
|
}
|
2010-05-13 15:57:33 +01:00
|
|
|
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
static struct denali_controller *to_denali_controller(struct nand_chip *chip)
|
2019-04-02 13:03:01 +09:00
|
|
|
{
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
return container_of(chip->controller, struct denali_controller,
|
|
|
|
controller);
|
2019-04-02 13:03:01 +09:00
|
|
|
}
|
|
|
|
|
2017-09-22 12:46:48 +09:00
|
|
|
/*
|
|
|
|
* Direct Addressing - the slave address forms the control information (command
|
|
|
|
* type, bank, block, and page address). The slave data is the actual data to
|
|
|
|
* be transferred. This mode requires 28 bits of address region allocated.
|
|
|
|
*/
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
static u32 denali_direct_read(struct denali_controller *denali, u32 addr)
|
2017-09-22 12:46:48 +09:00
|
|
|
{
|
|
|
|
return ioread32(denali->host + addr);
|
|
|
|
}
|
|
|
|
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
static void denali_direct_write(struct denali_controller *denali, u32 addr,
|
2017-09-22 12:46:48 +09:00
|
|
|
u32 data)
|
|
|
|
{
|
|
|
|
iowrite32(data, denali->host + addr);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Indexed Addressing - address translation module intervenes in passing the
|
|
|
|
* control information. This mode reduces the required address range. The
|
|
|
|
* control information and transferred data are latched by the registers in
|
|
|
|
* the translation module.
|
|
|
|
*/
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
static u32 denali_indexed_read(struct denali_controller *denali, u32 addr)
|
2010-05-13 15:57:33 +01:00
|
|
|
{
|
2017-09-22 12:46:48 +09:00
|
|
|
iowrite32(addr, denali->host + DENALI_INDEXED_CTRL);
|
|
|
|
return ioread32(denali->host + DENALI_INDEXED_DATA);
|
|
|
|
}
|
|
|
|
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
static void denali_indexed_write(struct denali_controller *denali, u32 addr,
|
2017-09-22 12:46:48 +09:00
|
|
|
u32 data)
|
|
|
|
{
|
|
|
|
iowrite32(addr, denali->host + DENALI_INDEXED_CTRL);
|
|
|
|
iowrite32(data, denali->host + DENALI_INDEXED_DATA);
|
2010-05-13 15:57:33 +01:00
|
|
|
}
|
|
|
|
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
static void denali_enable_irq(struct denali_controller *denali)
|
2010-05-13 15:57:33 +01:00
|
|
|
{
|
2017-06-13 22:45:38 +09:00
|
|
|
int i;
|
2010-05-13 15:57:33 +01:00
|
|
|
|
2019-04-02 13:03:08 +09:00
|
|
|
for (i = 0; i < denali->nbanks; i++)
|
mtd: nand: denali: avoid magic numbers and rename for clarification
Introduce some macros and helpers to avoid magic numbers and
rename macros/functions for clarification.
- We see '| 2' in several places. This means Data Cycle in MAP11 mode.
The Denali User's Guide says bit[1:0] of MAP11 is like follows:
b'00 = Command Cycle
b'01 = Address Cycle
b'10 = Data Cycle
So, this commit added DENALI_MAP11_{CMD,ADDR,DATA} macros.
- We see 'denali->flash_mem + 0x10' in several places, but 0x10 is a
magic number. Actually, this accesses the data port of the Host
Data/Command Interface. So, this commit added DENALI_HOST_DATA.
On the other hand, 'denali->flash_mem' gets access to the address
port, so DENALI_HOST_ADDR was also added.
- We see 'index_addr(denali, cmd, 0x1)' in denali_erase(), but 0x1
is a magic number. 0x1 means the erase operation. Replace 0x1
with DENALI_ERASE.
- Rename index_addr() to denali_host_write() for clarification
- Denali User's Guide says MAP{00,01,10,11} for access mode. Match
the macros with terminology in the IP document.
- Rename struct members as follows:
flash_bank -> active_bank (currently selected bank)
flash_reg -> reg (base address of registers)
flash_mem -> host (base address of host interface)
devnum -> devs_per_cs (devices connected in parallel)
bbtskipbytes -> oob_skip_bytes (number of bytes to skip in OOB)
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-06-16 14:36:39 +09:00
|
|
|
iowrite32(U32_MAX, denali->reg + INTR_EN(i));
|
|
|
|
iowrite32(GLOBAL_INT_EN_FLAG, denali->reg + GLOBAL_INT_ENABLE);
|
2010-05-13 15:57:33 +01:00
|
|
|
}
|
|
|
|
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
static void denali_disable_irq(struct denali_controller *denali)
|
2010-05-13 15:57:33 +01:00
|
|
|
{
|
2011-05-06 15:28:56 +01:00
|
|
|
int i;
|
2010-05-13 15:57:33 +01:00
|
|
|
|
2019-04-02 13:03:08 +09:00
|
|
|
for (i = 0; i < denali->nbanks; i++)
|
mtd: nand: denali: avoid magic numbers and rename for clarification
Introduce some macros and helpers to avoid magic numbers and
rename macros/functions for clarification.
- We see '| 2' in several places. This means Data Cycle in MAP11 mode.
The Denali User's Guide says bit[1:0] of MAP11 is like follows:
b'00 = Command Cycle
b'01 = Address Cycle
b'10 = Data Cycle
So, this commit added DENALI_MAP11_{CMD,ADDR,DATA} macros.
- We see 'denali->flash_mem + 0x10' in several places, but 0x10 is a
magic number. Actually, this accesses the data port of the Host
Data/Command Interface. So, this commit added DENALI_HOST_DATA.
On the other hand, 'denali->flash_mem' gets access to the address
port, so DENALI_HOST_ADDR was also added.
- We see 'index_addr(denali, cmd, 0x1)' in denali_erase(), but 0x1
is a magic number. 0x1 means the erase operation. Replace 0x1
with DENALI_ERASE.
- Rename index_addr() to denali_host_write() for clarification
- Denali User's Guide says MAP{00,01,10,11} for access mode. Match
the macros with terminology in the IP document.
- Rename struct members as follows:
flash_bank -> active_bank (currently selected bank)
flash_reg -> reg (base address of registers)
flash_mem -> host (base address of host interface)
devnum -> devs_per_cs (devices connected in parallel)
bbtskipbytes -> oob_skip_bytes (number of bytes to skip in OOB)
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-06-16 14:36:39 +09:00
|
|
|
iowrite32(0, denali->reg + INTR_EN(i));
|
|
|
|
iowrite32(0, denali->reg + GLOBAL_INT_ENABLE);
|
2010-05-13 15:57:33 +01:00
|
|
|
}
|
|
|
|
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
static void denali_clear_irq(struct denali_controller *denali,
|
2019-04-02 13:03:09 +09:00
|
|
|
int bank, u32 irq_status)
|
2010-05-13 15:57:33 +01:00
|
|
|
{
|
2017-06-13 22:45:38 +09:00
|
|
|
/* write one to clear bits */
|
mtd: nand: denali: avoid magic numbers and rename for clarification
Introduce some macros and helpers to avoid magic numbers and
rename macros/functions for clarification.
- We see '| 2' in several places. This means Data Cycle in MAP11 mode.
The Denali User's Guide says bit[1:0] of MAP11 is like follows:
b'00 = Command Cycle
b'01 = Address Cycle
b'10 = Data Cycle
So, this commit added DENALI_MAP11_{CMD,ADDR,DATA} macros.
- We see 'denali->flash_mem + 0x10' in several places, but 0x10 is a
magic number. Actually, this accesses the data port of the Host
Data/Command Interface. So, this commit added DENALI_HOST_DATA.
On the other hand, 'denali->flash_mem' gets access to the address
port, so DENALI_HOST_ADDR was also added.
- We see 'index_addr(denali, cmd, 0x1)' in denali_erase(), but 0x1
is a magic number. 0x1 means the erase operation. Replace 0x1
with DENALI_ERASE.
- Rename index_addr() to denali_host_write() for clarification
- Denali User's Guide says MAP{00,01,10,11} for access mode. Match
the macros with terminology in the IP document.
- Rename struct members as follows:
flash_bank -> active_bank (currently selected bank)
flash_reg -> reg (base address of registers)
flash_mem -> host (base address of host interface)
devnum -> devs_per_cs (devices connected in parallel)
bbtskipbytes -> oob_skip_bytes (number of bytes to skip in OOB)
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-06-16 14:36:39 +09:00
|
|
|
iowrite32(irq_status, denali->reg + INTR_STATUS(bank));
|
2010-05-13 15:57:33 +01:00
|
|
|
}
|
|
|
|
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
static void denali_clear_irq_all(struct denali_controller *denali)
|
2010-05-13 15:57:33 +01:00
|
|
|
{
|
2011-05-06 15:28:56 +01:00
|
|
|
int i;
|
|
|
|
|
2019-04-02 13:03:08 +09:00
|
|
|
for (i = 0; i < denali->nbanks; i++)
|
2017-06-13 22:45:38 +09:00
|
|
|
denali_clear_irq(denali, i, U32_MAX);
|
2010-05-13 15:57:33 +01:00
|
|
|
}
|
|
|
|
|
2017-06-13 22:45:38 +09:00
|
|
|
static irqreturn_t denali_isr(int irq, void *dev_id)
|
2010-05-13 15:57:33 +01:00
|
|
|
{
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
struct denali_controller *denali = dev_id;
|
2017-06-13 22:45:38 +09:00
|
|
|
irqreturn_t ret = IRQ_NONE;
|
2019-04-02 13:03:09 +09:00
|
|
|
u32 irq_status;
|
2017-06-13 22:45:38 +09:00
|
|
|
int i;
|
2010-05-13 15:57:33 +01:00
|
|
|
|
2017-06-13 22:45:38 +09:00
|
|
|
spin_lock(&denali->irq_lock);
|
2010-05-13 15:57:33 +01:00
|
|
|
|
2019-04-02 13:03:08 +09:00
|
|
|
for (i = 0; i < denali->nbanks; i++) {
|
mtd: nand: denali: avoid magic numbers and rename for clarification
Introduce some macros and helpers to avoid magic numbers and
rename macros/functions for clarification.
- We see '| 2' in several places. This means Data Cycle in MAP11 mode.
The Denali User's Guide says bit[1:0] of MAP11 is like follows:
b'00 = Command Cycle
b'01 = Address Cycle
b'10 = Data Cycle
So, this commit added DENALI_MAP11_{CMD,ADDR,DATA} macros.
- We see 'denali->flash_mem + 0x10' in several places, but 0x10 is a
magic number. Actually, this accesses the data port of the Host
Data/Command Interface. So, this commit added DENALI_HOST_DATA.
On the other hand, 'denali->flash_mem' gets access to the address
port, so DENALI_HOST_ADDR was also added.
- We see 'index_addr(denali, cmd, 0x1)' in denali_erase(), but 0x1
is a magic number. 0x1 means the erase operation. Replace 0x1
with DENALI_ERASE.
- Rename index_addr() to denali_host_write() for clarification
- Denali User's Guide says MAP{00,01,10,11} for access mode. Match
the macros with terminology in the IP document.
- Rename struct members as follows:
flash_bank -> active_bank (currently selected bank)
flash_reg -> reg (base address of registers)
flash_mem -> host (base address of host interface)
devnum -> devs_per_cs (devices connected in parallel)
bbtskipbytes -> oob_skip_bytes (number of bytes to skip in OOB)
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-06-16 14:36:39 +09:00
|
|
|
irq_status = ioread32(denali->reg + INTR_STATUS(i));
|
2017-06-13 22:45:38 +09:00
|
|
|
if (irq_status)
|
|
|
|
ret = IRQ_HANDLED;
|
2010-05-13 15:57:33 +01:00
|
|
|
|
2017-06-13 22:45:38 +09:00
|
|
|
denali_clear_irq(denali, i, irq_status);
|
2010-05-13 15:57:33 +01:00
|
|
|
|
mtd: nand: denali: avoid magic numbers and rename for clarification
Introduce some macros and helpers to avoid magic numbers and
rename macros/functions for clarification.
- We see '| 2' in several places. This means Data Cycle in MAP11 mode.
The Denali User's Guide says bit[1:0] of MAP11 is like follows:
b'00 = Command Cycle
b'01 = Address Cycle
b'10 = Data Cycle
So, this commit added DENALI_MAP11_{CMD,ADDR,DATA} macros.
- We see 'denali->flash_mem + 0x10' in several places, but 0x10 is a
magic number. Actually, this accesses the data port of the Host
Data/Command Interface. So, this commit added DENALI_HOST_DATA.
On the other hand, 'denali->flash_mem' gets access to the address
port, so DENALI_HOST_ADDR was also added.
- We see 'index_addr(denali, cmd, 0x1)' in denali_erase(), but 0x1
is a magic number. 0x1 means the erase operation. Replace 0x1
with DENALI_ERASE.
- Rename index_addr() to denali_host_write() for clarification
- Denali User's Guide says MAP{00,01,10,11} for access mode. Match
the macros with terminology in the IP document.
- Rename struct members as follows:
flash_bank -> active_bank (currently selected bank)
flash_reg -> reg (base address of registers)
flash_mem -> host (base address of host interface)
devnum -> devs_per_cs (devices connected in parallel)
bbtskipbytes -> oob_skip_bytes (number of bytes to skip in OOB)
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-06-16 14:36:39 +09:00
|
|
|
if (i != denali->active_bank)
|
2017-06-13 22:45:38 +09:00
|
|
|
continue;
|
|
|
|
|
|
|
|
denali->irq_status |= irq_status;
|
2014-09-09 11:01:52 +09:00
|
|
|
|
2017-06-13 22:45:38 +09:00
|
|
|
if (denali->irq_status & denali->irq_mask)
|
|
|
|
complete(&denali->complete);
|
|
|
|
}
|
2010-05-13 15:57:33 +01:00
|
|
|
|
2017-06-13 22:45:38 +09:00
|
|
|
spin_unlock(&denali->irq_lock);
|
2010-05-13 15:57:33 +01:00
|
|
|
|
2017-06-13 22:45:38 +09:00
|
|
|
return ret;
|
2010-05-13 15:57:33 +01:00
|
|
|
}
|
|
|
|
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
static void denali_reset_irq(struct denali_controller *denali)
|
2010-05-13 15:57:33 +01:00
|
|
|
{
|
2017-06-13 22:45:38 +09:00
|
|
|
unsigned long flags;
|
2010-05-13 15:57:33 +01:00
|
|
|
|
2017-06-13 22:45:38 +09:00
|
|
|
spin_lock_irqsave(&denali->irq_lock, flags);
|
|
|
|
denali->irq_status = 0;
|
|
|
|
denali->irq_mask = 0;
|
|
|
|
spin_unlock_irqrestore(&denali->irq_lock, flags);
|
2010-05-13 15:57:33 +01:00
|
|
|
}
|
|
|
|
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
static u32 denali_wait_for_irq(struct denali_controller *denali, u32 irq_mask)
|
2010-05-13 15:57:33 +01:00
|
|
|
{
|
2017-06-13 22:45:38 +09:00
|
|
|
unsigned long time_left, flags;
|
2019-04-02 13:03:09 +09:00
|
|
|
u32 irq_status;
|
2010-05-13 15:57:33 +01:00
|
|
|
|
2017-06-13 22:45:38 +09:00
|
|
|
spin_lock_irqsave(&denali->irq_lock, flags);
|
2010-05-13 15:57:33 +01:00
|
|
|
|
2017-06-13 22:45:38 +09:00
|
|
|
irq_status = denali->irq_status;
|
|
|
|
|
|
|
|
if (irq_mask & irq_status) {
|
|
|
|
/* return immediately if the IRQ has already happened. */
|
|
|
|
spin_unlock_irqrestore(&denali->irq_lock, flags);
|
|
|
|
return irq_status;
|
2010-05-13 15:57:33 +01:00
|
|
|
}
|
2017-06-13 22:45:38 +09:00
|
|
|
|
|
|
|
denali->irq_mask = irq_mask;
|
|
|
|
reinit_completion(&denali->complete);
|
|
|
|
spin_unlock_irqrestore(&denali->irq_lock, flags);
|
|
|
|
|
|
|
|
time_left = wait_for_completion_timeout(&denali->complete,
|
|
|
|
msecs_to_jiffies(1000));
|
|
|
|
if (!time_left) {
|
|
|
|
dev_err(denali->dev, "timeout while waiting for irq 0x%x\n",
|
2017-09-22 12:46:42 +09:00
|
|
|
irq_mask);
|
2017-06-13 22:45:38 +09:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return denali->irq_status;
|
2010-05-13 15:57:33 +01:00
|
|
|
}
|
|
|
|
|
2019-04-02 13:03:04 +09:00
|
|
|
static void denali_select_target(struct nand_chip *chip, int cs)
|
2017-06-13 22:45:39 +09:00
|
|
|
{
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
struct denali_controller *denali = to_denali_controller(chip);
|
|
|
|
struct denali_chip_sel *sel = &to_denali_chip(chip)->sels[cs];
|
|
|
|
struct mtd_info *mtd = nand_to_mtd(chip);
|
|
|
|
|
|
|
|
denali->active_bank = sel->bank;
|
2017-06-13 22:45:39 +09:00
|
|
|
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
iowrite32(1 << (chip->phys_erase_shift - chip->page_shift),
|
|
|
|
denali->reg + PAGES_PER_BLOCK);
|
|
|
|
iowrite32(chip->options & NAND_BUSWIDTH_16 ? 1 : 0,
|
|
|
|
denali->reg + DEVICE_WIDTH);
|
|
|
|
iowrite32(mtd->writesize, denali->reg + DEVICE_MAIN_AREA_SIZE);
|
|
|
|
iowrite32(mtd->oobsize, denali->reg + DEVICE_SPARE_AREA_SIZE);
|
|
|
|
iowrite32(chip->options & NAND_ROW_ADDR_3 ?
|
|
|
|
0 : TWO_ROW_ADDR_CYCLES__FLAG,
|
|
|
|
denali->reg + TWO_ROW_ADDR_CYCLES);
|
|
|
|
iowrite32(FIELD_PREP(ECC_CORRECTION__ERASE_THRESHOLD, 1) |
|
|
|
|
FIELD_PREP(ECC_CORRECTION__VALUE, chip->ecc.strength),
|
|
|
|
denali->reg + ECC_CORRECTION);
|
|
|
|
iowrite32(chip->ecc.size, denali->reg + CFG_DATA_BLOCK_SIZE);
|
|
|
|
iowrite32(chip->ecc.size, denali->reg + CFG_LAST_DATA_BLOCK_SIZE);
|
|
|
|
iowrite32(chip->ecc.steps, denali->reg + CFG_NUM_DATA_BLOCKS);
|
|
|
|
|
|
|
|
if (chip->options & NAND_KEEP_TIMINGS)
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* update timing registers unless NAND_KEEP_TIMINGS is set */
|
|
|
|
iowrite32(sel->hwhr2_and_we_2_re, denali->reg + TWHR2_AND_WE_2_RE);
|
|
|
|
iowrite32(sel->tcwaw_and_addr_2_data,
|
|
|
|
denali->reg + TCWAW_AND_ADDR_2_DATA);
|
|
|
|
iowrite32(sel->re_2_we, denali->reg + RE_2_WE);
|
|
|
|
iowrite32(sel->acc_clks, denali->reg + ACC_CLKS);
|
|
|
|
iowrite32(sel->rdwr_en_lo_cnt, denali->reg + RDWR_EN_LO_CNT);
|
|
|
|
iowrite32(sel->rdwr_en_hi_cnt, denali->reg + RDWR_EN_HI_CNT);
|
|
|
|
iowrite32(sel->cs_setup_cnt, denali->reg + CS_SETUP_CNT);
|
|
|
|
iowrite32(sel->re_2_re, denali->reg + RE_2_RE);
|
2017-06-13 22:45:39 +09:00
|
|
|
}
|
|
|
|
|
2019-04-02 13:03:02 +09:00
|
|
|
static int denali_change_column(struct nand_chip *chip, unsigned int offset,
|
|
|
|
void *buf, unsigned int len, bool write)
|
|
|
|
{
|
|
|
|
if (write)
|
|
|
|
return nand_change_write_column_op(chip, offset, buf, len,
|
|
|
|
false);
|
|
|
|
else
|
|
|
|
return nand_change_read_column_op(chip, offset, buf, len,
|
|
|
|
false);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int denali_payload_xfer(struct nand_chip *chip, void *buf, bool write)
|
|
|
|
{
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
struct denali_controller *denali = to_denali_controller(chip);
|
2019-04-02 13:03:02 +09:00
|
|
|
struct mtd_info *mtd = nand_to_mtd(chip);
|
|
|
|
struct nand_ecc_ctrl *ecc = &chip->ecc;
|
|
|
|
int writesize = mtd->writesize;
|
|
|
|
int oob_skip = denali->oob_skip_bytes;
|
|
|
|
int ret, i, pos, len;
|
|
|
|
|
|
|
|
for (i = 0; i < ecc->steps; i++) {
|
|
|
|
pos = i * (ecc->size + ecc->bytes);
|
|
|
|
len = ecc->size;
|
|
|
|
|
|
|
|
if (pos >= writesize) {
|
|
|
|
pos += oob_skip;
|
|
|
|
} else if (pos + len > writesize) {
|
|
|
|
/* This chunk overwraps the BBM area. Must be split */
|
|
|
|
ret = denali_change_column(chip, pos, buf,
|
|
|
|
writesize - pos, write);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
buf += writesize - pos;
|
|
|
|
len -= writesize - pos;
|
|
|
|
pos = writesize + oob_skip;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = denali_change_column(chip, pos, buf, len, write);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
buf += len;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int denali_oob_xfer(struct nand_chip *chip, void *buf, bool write)
|
|
|
|
{
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
struct denali_controller *denali = to_denali_controller(chip);
|
2019-04-02 13:03:02 +09:00
|
|
|
struct mtd_info *mtd = nand_to_mtd(chip);
|
|
|
|
struct nand_ecc_ctrl *ecc = &chip->ecc;
|
|
|
|
int writesize = mtd->writesize;
|
|
|
|
int oobsize = mtd->oobsize;
|
|
|
|
int oob_skip = denali->oob_skip_bytes;
|
|
|
|
int ret, i, pos, len;
|
|
|
|
|
|
|
|
/* BBM at the beginning of the OOB area */
|
|
|
|
ret = denali_change_column(chip, writesize, buf, oob_skip, write);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
buf += oob_skip;
|
|
|
|
|
|
|
|
for (i = 0; i < ecc->steps; i++) {
|
|
|
|
pos = ecc->size + i * (ecc->size + ecc->bytes);
|
|
|
|
|
|
|
|
if (i == ecc->steps - 1)
|
|
|
|
/* The last chunk includes OOB free */
|
|
|
|
len = writesize + oobsize - pos - oob_skip;
|
|
|
|
else
|
|
|
|
len = ecc->bytes;
|
|
|
|
|
|
|
|
if (pos >= writesize) {
|
|
|
|
pos += oob_skip;
|
|
|
|
} else if (pos + len > writesize) {
|
|
|
|
/* This chunk overwraps the BBM area. Must be split */
|
|
|
|
ret = denali_change_column(chip, pos, buf,
|
|
|
|
writesize - pos, write);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
buf += writesize - pos;
|
|
|
|
len -= writesize - pos;
|
|
|
|
pos = writesize + oob_skip;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = denali_change_column(chip, pos, buf, len, write);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
buf += len;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int denali_read_raw(struct nand_chip *chip, void *buf, void *oob_buf,
|
|
|
|
int page)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
if (!buf && !oob_buf)
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
ret = nand_read_page_op(chip, page, 0, NULL, 0);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
if (buf) {
|
|
|
|
ret = denali_payload_xfer(chip, buf, false);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (oob_buf) {
|
|
|
|
ret = denali_oob_xfer(chip, oob_buf, false);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int denali_write_raw(struct nand_chip *chip, const void *buf,
|
|
|
|
const void *oob_buf, int page)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
if (!buf && !oob_buf)
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
ret = nand_prog_page_begin_op(chip, page, 0, NULL, 0);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
if (buf) {
|
|
|
|
ret = denali_payload_xfer(chip, (void *)buf, true);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (oob_buf) {
|
|
|
|
ret = denali_oob_xfer(chip, (void *)oob_buf, true);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
return nand_prog_page_end_op(chip);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int denali_read_page_raw(struct nand_chip *chip, u8 *buf,
|
|
|
|
int oob_required, int page)
|
|
|
|
{
|
|
|
|
return denali_read_raw(chip, buf, oob_required ? chip->oob_poi : NULL,
|
|
|
|
page);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int denali_write_page_raw(struct nand_chip *chip, const u8 *buf,
|
|
|
|
int oob_required, int page)
|
|
|
|
{
|
|
|
|
return denali_write_raw(chip, buf, oob_required ? chip->oob_poi : NULL,
|
|
|
|
page);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int denali_read_oob(struct nand_chip *chip, int page)
|
|
|
|
{
|
|
|
|
return denali_read_raw(chip, NULL, chip->oob_poi, page);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int denali_write_oob(struct nand_chip *chip, int page)
|
|
|
|
{
|
|
|
|
return denali_write_raw(chip, NULL, chip->oob_poi, page);
|
|
|
|
}
|
|
|
|
|
2019-04-02 13:03:01 +09:00
|
|
|
static int denali_check_erased_page(struct nand_chip *chip, u8 *buf,
|
2017-03-30 15:45:51 +09:00
|
|
|
unsigned long uncor_ecc_flags,
|
|
|
|
unsigned int max_bitflips)
|
2010-05-13 15:57:33 +01:00
|
|
|
{
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
struct denali_controller *denali = to_denali_controller(chip);
|
2019-04-02 13:03:01 +09:00
|
|
|
struct mtd_ecc_stats *ecc_stats = &nand_to_mtd(chip)->ecc_stats;
|
2019-04-02 13:03:09 +09:00
|
|
|
struct nand_ecc_ctrl *ecc = &chip->ecc;
|
|
|
|
u8 *ecc_code = chip->oob_poi + denali->oob_skip_bytes;
|
2017-12-05 12:09:28 +01:00
|
|
|
int i, stat;
|
2017-03-30 15:45:51 +09:00
|
|
|
|
2019-04-02 13:03:09 +09:00
|
|
|
for (i = 0; i < ecc->steps; i++) {
|
2017-03-30 15:45:51 +09:00
|
|
|
if (!(uncor_ecc_flags & BIT(i)))
|
|
|
|
continue;
|
|
|
|
|
2019-04-02 13:03:09 +09:00
|
|
|
stat = nand_check_erased_ecc_chunk(buf, ecc->size, ecc_code,
|
|
|
|
ecc->bytes, NULL, 0,
|
|
|
|
ecc->strength);
|
2017-03-30 15:45:51 +09:00
|
|
|
if (stat < 0) {
|
2019-04-02 13:03:01 +09:00
|
|
|
ecc_stats->failed++;
|
2017-03-30 15:45:51 +09:00
|
|
|
} else {
|
2019-04-02 13:03:01 +09:00
|
|
|
ecc_stats->corrected += stat;
|
2017-03-30 15:45:51 +09:00
|
|
|
max_bitflips = max_t(unsigned int, max_bitflips, stat);
|
|
|
|
}
|
|
|
|
|
2019-04-02 13:03:09 +09:00
|
|
|
buf += ecc->size;
|
|
|
|
ecc_code += ecc->bytes;
|
2017-03-30 15:45:51 +09:00
|
|
|
}
|
2014-09-16 20:04:25 +09:00
|
|
|
|
2017-03-30 15:45:51 +09:00
|
|
|
return max_bitflips;
|
2010-05-13 15:57:33 +01:00
|
|
|
}
|
2017-03-30 15:45:51 +09:00
|
|
|
|
2019-04-02 13:03:01 +09:00
|
|
|
static int denali_hw_ecc_fixup(struct nand_chip *chip,
|
2017-03-30 15:45:52 +09:00
|
|
|
unsigned long *uncor_ecc_flags)
|
|
|
|
{
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
struct denali_controller *denali = to_denali_controller(chip);
|
2019-04-02 13:03:01 +09:00
|
|
|
struct mtd_ecc_stats *ecc_stats = &nand_to_mtd(chip)->ecc_stats;
|
mtd: nand: denali: avoid magic numbers and rename for clarification
Introduce some macros and helpers to avoid magic numbers and
rename macros/functions for clarification.
- We see '| 2' in several places. This means Data Cycle in MAP11 mode.
The Denali User's Guide says bit[1:0] of MAP11 is like follows:
b'00 = Command Cycle
b'01 = Address Cycle
b'10 = Data Cycle
So, this commit added DENALI_MAP11_{CMD,ADDR,DATA} macros.
- We see 'denali->flash_mem + 0x10' in several places, but 0x10 is a
magic number. Actually, this accesses the data port of the Host
Data/Command Interface. So, this commit added DENALI_HOST_DATA.
On the other hand, 'denali->flash_mem' gets access to the address
port, so DENALI_HOST_ADDR was also added.
- We see 'index_addr(denali, cmd, 0x1)' in denali_erase(), but 0x1
is a magic number. 0x1 means the erase operation. Replace 0x1
with DENALI_ERASE.
- Rename index_addr() to denali_host_write() for clarification
- Denali User's Guide says MAP{00,01,10,11} for access mode. Match
the macros with terminology in the IP document.
- Rename struct members as follows:
flash_bank -> active_bank (currently selected bank)
flash_reg -> reg (base address of registers)
flash_mem -> host (base address of host interface)
devnum -> devs_per_cs (devices connected in parallel)
bbtskipbytes -> oob_skip_bytes (number of bytes to skip in OOB)
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-06-16 14:36:39 +09:00
|
|
|
int bank = denali->active_bank;
|
2019-04-02 13:03:09 +09:00
|
|
|
u32 ecc_cor;
|
2017-03-30 15:45:52 +09:00
|
|
|
unsigned int max_bitflips;
|
|
|
|
|
mtd: nand: denali: avoid magic numbers and rename for clarification
Introduce some macros and helpers to avoid magic numbers and
rename macros/functions for clarification.
- We see '| 2' in several places. This means Data Cycle in MAP11 mode.
The Denali User's Guide says bit[1:0] of MAP11 is like follows:
b'00 = Command Cycle
b'01 = Address Cycle
b'10 = Data Cycle
So, this commit added DENALI_MAP11_{CMD,ADDR,DATA} macros.
- We see 'denali->flash_mem + 0x10' in several places, but 0x10 is a
magic number. Actually, this accesses the data port of the Host
Data/Command Interface. So, this commit added DENALI_HOST_DATA.
On the other hand, 'denali->flash_mem' gets access to the address
port, so DENALI_HOST_ADDR was also added.
- We see 'index_addr(denali, cmd, 0x1)' in denali_erase(), but 0x1
is a magic number. 0x1 means the erase operation. Replace 0x1
with DENALI_ERASE.
- Rename index_addr() to denali_host_write() for clarification
- Denali User's Guide says MAP{00,01,10,11} for access mode. Match
the macros with terminology in the IP document.
- Rename struct members as follows:
flash_bank -> active_bank (currently selected bank)
flash_reg -> reg (base address of registers)
flash_mem -> host (base address of host interface)
devnum -> devs_per_cs (devices connected in parallel)
bbtskipbytes -> oob_skip_bytes (number of bytes to skip in OOB)
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-06-16 14:36:39 +09:00
|
|
|
ecc_cor = ioread32(denali->reg + ECC_COR_INFO(bank));
|
2017-03-30 15:45:52 +09:00
|
|
|
ecc_cor >>= ECC_COR_INFO__SHIFT(bank);
|
|
|
|
|
|
|
|
if (ecc_cor & ECC_COR_INFO__UNCOR_ERR) {
|
|
|
|
/*
|
|
|
|
* This flag is set when uncorrectable error occurs at least in
|
|
|
|
* one ECC sector. We can not know "how many sectors", or
|
|
|
|
* "which sector(s)". We need erase-page check for all sectors.
|
|
|
|
*/
|
|
|
|
*uncor_ecc_flags = GENMASK(chip->ecc.steps - 1, 0);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2017-09-22 12:46:44 +09:00
|
|
|
max_bitflips = FIELD_GET(ECC_COR_INFO__MAX_ERRORS, ecc_cor);
|
2017-03-30 15:45:52 +09:00
|
|
|
|
|
|
|
/*
|
|
|
|
* The register holds the maximum of per-sector corrected bitflips.
|
|
|
|
* This is suitable for the return value of the ->read_page() callback.
|
|
|
|
* Unfortunately, we can not know the total number of corrected bits in
|
|
|
|
* the page. Increase the stats by max_bitflips. (compromised solution)
|
|
|
|
*/
|
2019-04-02 13:03:01 +09:00
|
|
|
ecc_stats->corrected += max_bitflips;
|
2017-03-30 15:45:52 +09:00
|
|
|
|
|
|
|
return max_bitflips;
|
|
|
|
}
|
|
|
|
|
2019-04-02 13:03:01 +09:00
|
|
|
static int denali_sw_ecc_fixup(struct nand_chip *chip,
|
2019-04-02 13:03:09 +09:00
|
|
|
unsigned long *uncor_ecc_flags, u8 *buf)
|
2010-05-13 15:57:33 +01:00
|
|
|
{
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
struct denali_controller *denali = to_denali_controller(chip);
|
2019-04-02 13:03:01 +09:00
|
|
|
struct mtd_ecc_stats *ecc_stats = &nand_to_mtd(chip)->ecc_stats;
|
|
|
|
unsigned int ecc_size = chip->ecc.size;
|
2012-04-25 12:06:09 -07:00
|
|
|
unsigned int bitflips = 0;
|
2017-03-30 15:45:50 +09:00
|
|
|
unsigned int max_bitflips = 0;
|
2019-04-02 13:03:09 +09:00
|
|
|
u32 err_addr, err_cor_info;
|
2017-03-30 15:45:50 +09:00
|
|
|
unsigned int err_byte, err_sector, err_device;
|
2019-04-02 13:03:09 +09:00
|
|
|
u8 err_cor_value;
|
2017-03-30 15:45:50 +09:00
|
|
|
unsigned int prev_sector = 0;
|
2019-04-02 13:03:09 +09:00
|
|
|
u32 irq_status;
|
2010-05-13 15:57:33 +01:00
|
|
|
|
2017-06-13 22:45:38 +09:00
|
|
|
denali_reset_irq(denali);
|
2017-03-30 15:45:50 +09:00
|
|
|
|
|
|
|
do {
|
mtd: nand: denali: avoid magic numbers and rename for clarification
Introduce some macros and helpers to avoid magic numbers and
rename macros/functions for clarification.
- We see '| 2' in several places. This means Data Cycle in MAP11 mode.
The Denali User's Guide says bit[1:0] of MAP11 is like follows:
b'00 = Command Cycle
b'01 = Address Cycle
b'10 = Data Cycle
So, this commit added DENALI_MAP11_{CMD,ADDR,DATA} macros.
- We see 'denali->flash_mem + 0x10' in several places, but 0x10 is a
magic number. Actually, this accesses the data port of the Host
Data/Command Interface. So, this commit added DENALI_HOST_DATA.
On the other hand, 'denali->flash_mem' gets access to the address
port, so DENALI_HOST_ADDR was also added.
- We see 'index_addr(denali, cmd, 0x1)' in denali_erase(), but 0x1
is a magic number. 0x1 means the erase operation. Replace 0x1
with DENALI_ERASE.
- Rename index_addr() to denali_host_write() for clarification
- Denali User's Guide says MAP{00,01,10,11} for access mode. Match
the macros with terminology in the IP document.
- Rename struct members as follows:
flash_bank -> active_bank (currently selected bank)
flash_reg -> reg (base address of registers)
flash_mem -> host (base address of host interface)
devnum -> devs_per_cs (devices connected in parallel)
bbtskipbytes -> oob_skip_bytes (number of bytes to skip in OOB)
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-06-16 14:36:39 +09:00
|
|
|
err_addr = ioread32(denali->reg + ECC_ERROR_ADDRESS);
|
2017-09-22 12:46:43 +09:00
|
|
|
err_sector = FIELD_GET(ECC_ERROR_ADDRESS__SECTOR, err_addr);
|
|
|
|
err_byte = FIELD_GET(ECC_ERROR_ADDRESS__OFFSET, err_addr);
|
2017-03-30 15:45:50 +09:00
|
|
|
|
mtd: nand: denali: avoid magic numbers and rename for clarification
Introduce some macros and helpers to avoid magic numbers and
rename macros/functions for clarification.
- We see '| 2' in several places. This means Data Cycle in MAP11 mode.
The Denali User's Guide says bit[1:0] of MAP11 is like follows:
b'00 = Command Cycle
b'01 = Address Cycle
b'10 = Data Cycle
So, this commit added DENALI_MAP11_{CMD,ADDR,DATA} macros.
- We see 'denali->flash_mem + 0x10' in several places, but 0x10 is a
magic number. Actually, this accesses the data port of the Host
Data/Command Interface. So, this commit added DENALI_HOST_DATA.
On the other hand, 'denali->flash_mem' gets access to the address
port, so DENALI_HOST_ADDR was also added.
- We see 'index_addr(denali, cmd, 0x1)' in denali_erase(), but 0x1
is a magic number. 0x1 means the erase operation. Replace 0x1
with DENALI_ERASE.
- Rename index_addr() to denali_host_write() for clarification
- Denali User's Guide says MAP{00,01,10,11} for access mode. Match
the macros with terminology in the IP document.
- Rename struct members as follows:
flash_bank -> active_bank (currently selected bank)
flash_reg -> reg (base address of registers)
flash_mem -> host (base address of host interface)
devnum -> devs_per_cs (devices connected in parallel)
bbtskipbytes -> oob_skip_bytes (number of bytes to skip in OOB)
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-06-16 14:36:39 +09:00
|
|
|
err_cor_info = ioread32(denali->reg + ERR_CORRECTION_INFO);
|
2017-09-22 12:46:43 +09:00
|
|
|
err_cor_value = FIELD_GET(ERR_CORRECTION_INFO__BYTE,
|
|
|
|
err_cor_info);
|
|
|
|
err_device = FIELD_GET(ERR_CORRECTION_INFO__DEVICE,
|
|
|
|
err_cor_info);
|
2017-03-30 15:45:50 +09:00
|
|
|
|
|
|
|
/* reset the bitflip counter when crossing ECC sector */
|
|
|
|
if (err_sector != prev_sector)
|
|
|
|
bitflips = 0;
|
|
|
|
|
2017-09-22 12:46:43 +09:00
|
|
|
if (err_cor_info & ERR_CORRECTION_INFO__UNCOR) {
|
2017-03-30 15:45:50 +09:00
|
|
|
/*
|
2017-03-30 15:45:51 +09:00
|
|
|
* Check later if this is a real ECC error, or
|
|
|
|
* an erased sector.
|
2017-03-30 15:45:50 +09:00
|
|
|
*/
|
2017-03-30 15:45:51 +09:00
|
|
|
*uncor_ecc_flags |= BIT(err_sector);
|
mtd: nand: denali: avoid hard-coding ECC step, strength, bytes
This driver was originally written for the Intel MRST platform with
several platform-specific parameters hard-coded.
Currently, the ECC settings are hard-coded as follows:
#define ECC_SECTOR_SIZE 512
#define ECC_8BITS 14
#define ECC_15BITS 26
Therefore, the driver can only support two cases.
- ecc.size = 512, ecc.strength = 8 --> ecc.bytes = 14
- ecc.size = 512, ecc.strength = 15 --> ecc.bytes = 26
However, these are actually customizable parameters, for example,
UniPhier platform supports the following:
- ecc.size = 1024, ecc.strength = 8 --> ecc.bytes = 14
- ecc.size = 1024, ecc.strength = 16 --> ecc.bytes = 28
- ecc.size = 1024, ecc.strength = 24 --> ecc.bytes = 42
So, we need to handle the ECC parameters in a more generic manner.
Fortunately, the Denali User's Guide explains how to calculate the
ecc.bytes. The formula is:
ecc.bytes = 2 * CEIL(13 * ecc.strength / 16) (for ecc.size = 512)
ecc.bytes = 2 * CEIL(14 * ecc.strength / 16) (for ecc.size = 1024)
For DT platforms, it would be reasonable to allow DT to specify ECC
strength by either "nand-ecc-strength" or "nand-ecc-maximize". If
none of them is specified, the driver will try to meet the chip's ECC
requirement.
For PCI platforms, the max ECC strength is used to keep the original
behavior.
Newer versions of this IP need ecc.size and ecc.steps explicitly
set up via the following registers:
CFG_DATA_BLOCK_SIZE (0x6b0)
CFG_LAST_DATA_BLOCK_SIZE (0x6c0)
CFG_NUM_DATA_BLOCKS (0x6d0)
For older IP versions, write accesses to these registers are just
ignored.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-06-07 20:52:12 +09:00
|
|
|
} else if (err_byte < ecc_size) {
|
2017-03-30 15:45:50 +09:00
|
|
|
/*
|
mtd: nand: denali: avoid hard-coding ECC step, strength, bytes
This driver was originally written for the Intel MRST platform with
several platform-specific parameters hard-coded.
Currently, the ECC settings are hard-coded as follows:
#define ECC_SECTOR_SIZE 512
#define ECC_8BITS 14
#define ECC_15BITS 26
Therefore, the driver can only support two cases.
- ecc.size = 512, ecc.strength = 8 --> ecc.bytes = 14
- ecc.size = 512, ecc.strength = 15 --> ecc.bytes = 26
However, these are actually customizable parameters, for example,
UniPhier platform supports the following:
- ecc.size = 1024, ecc.strength = 8 --> ecc.bytes = 14
- ecc.size = 1024, ecc.strength = 16 --> ecc.bytes = 28
- ecc.size = 1024, ecc.strength = 24 --> ecc.bytes = 42
So, we need to handle the ECC parameters in a more generic manner.
Fortunately, the Denali User's Guide explains how to calculate the
ecc.bytes. The formula is:
ecc.bytes = 2 * CEIL(13 * ecc.strength / 16) (for ecc.size = 512)
ecc.bytes = 2 * CEIL(14 * ecc.strength / 16) (for ecc.size = 1024)
For DT platforms, it would be reasonable to allow DT to specify ECC
strength by either "nand-ecc-strength" or "nand-ecc-maximize". If
none of them is specified, the driver will try to meet the chip's ECC
requirement.
For PCI platforms, the max ECC strength is used to keep the original
behavior.
Newer versions of this IP need ecc.size and ecc.steps explicitly
set up via the following registers:
CFG_DATA_BLOCK_SIZE (0x6b0)
CFG_LAST_DATA_BLOCK_SIZE (0x6c0)
CFG_NUM_DATA_BLOCKS (0x6d0)
For older IP versions, write accesses to these registers are just
ignored.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-06-07 20:52:12 +09:00
|
|
|
* If err_byte is larger than ecc_size, means error
|
2017-03-30 15:45:50 +09:00
|
|
|
* happened in OOB, so we ignore it. It's no need for
|
|
|
|
* us to correct it err_device is represented the NAND
|
|
|
|
* error bits are happened in if there are more than
|
|
|
|
* one NAND connected.
|
|
|
|
*/
|
|
|
|
int offset;
|
|
|
|
unsigned int flips_in_byte;
|
|
|
|
|
mtd: nand: denali: avoid hard-coding ECC step, strength, bytes
This driver was originally written for the Intel MRST platform with
several platform-specific parameters hard-coded.
Currently, the ECC settings are hard-coded as follows:
#define ECC_SECTOR_SIZE 512
#define ECC_8BITS 14
#define ECC_15BITS 26
Therefore, the driver can only support two cases.
- ecc.size = 512, ecc.strength = 8 --> ecc.bytes = 14
- ecc.size = 512, ecc.strength = 15 --> ecc.bytes = 26
However, these are actually customizable parameters, for example,
UniPhier platform supports the following:
- ecc.size = 1024, ecc.strength = 8 --> ecc.bytes = 14
- ecc.size = 1024, ecc.strength = 16 --> ecc.bytes = 28
- ecc.size = 1024, ecc.strength = 24 --> ecc.bytes = 42
So, we need to handle the ECC parameters in a more generic manner.
Fortunately, the Denali User's Guide explains how to calculate the
ecc.bytes. The formula is:
ecc.bytes = 2 * CEIL(13 * ecc.strength / 16) (for ecc.size = 512)
ecc.bytes = 2 * CEIL(14 * ecc.strength / 16) (for ecc.size = 1024)
For DT platforms, it would be reasonable to allow DT to specify ECC
strength by either "nand-ecc-strength" or "nand-ecc-maximize". If
none of them is specified, the driver will try to meet the chip's ECC
requirement.
For PCI platforms, the max ECC strength is used to keep the original
behavior.
Newer versions of this IP need ecc.size and ecc.steps explicitly
set up via the following registers:
CFG_DATA_BLOCK_SIZE (0x6b0)
CFG_LAST_DATA_BLOCK_SIZE (0x6c0)
CFG_NUM_DATA_BLOCKS (0x6d0)
For older IP versions, write accesses to these registers are just
ignored.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-06-07 20:52:12 +09:00
|
|
|
offset = (err_sector * ecc_size + err_byte) *
|
mtd: nand: denali: avoid magic numbers and rename for clarification
Introduce some macros and helpers to avoid magic numbers and
rename macros/functions for clarification.
- We see '| 2' in several places. This means Data Cycle in MAP11 mode.
The Denali User's Guide says bit[1:0] of MAP11 is like follows:
b'00 = Command Cycle
b'01 = Address Cycle
b'10 = Data Cycle
So, this commit added DENALI_MAP11_{CMD,ADDR,DATA} macros.
- We see 'denali->flash_mem + 0x10' in several places, but 0x10 is a
magic number. Actually, this accesses the data port of the Host
Data/Command Interface. So, this commit added DENALI_HOST_DATA.
On the other hand, 'denali->flash_mem' gets access to the address
port, so DENALI_HOST_ADDR was also added.
- We see 'index_addr(denali, cmd, 0x1)' in denali_erase(), but 0x1
is a magic number. 0x1 means the erase operation. Replace 0x1
with DENALI_ERASE.
- Rename index_addr() to denali_host_write() for clarification
- Denali User's Guide says MAP{00,01,10,11} for access mode. Match
the macros with terminology in the IP document.
- Rename struct members as follows:
flash_bank -> active_bank (currently selected bank)
flash_reg -> reg (base address of registers)
flash_mem -> host (base address of host interface)
devnum -> devs_per_cs (devices connected in parallel)
bbtskipbytes -> oob_skip_bytes (number of bytes to skip in OOB)
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-06-16 14:36:39 +09:00
|
|
|
denali->devs_per_cs + err_device;
|
2017-03-30 15:45:50 +09:00
|
|
|
|
|
|
|
/* correct the ECC error */
|
|
|
|
flips_in_byte = hweight8(buf[offset] ^ err_cor_value);
|
|
|
|
buf[offset] ^= err_cor_value;
|
2019-04-02 13:03:01 +09:00
|
|
|
ecc_stats->corrected += flips_in_byte;
|
2017-03-30 15:45:50 +09:00
|
|
|
bitflips += flips_in_byte;
|
|
|
|
|
|
|
|
max_bitflips = max(max_bitflips, bitflips);
|
|
|
|
}
|
|
|
|
|
|
|
|
prev_sector = err_sector;
|
2017-09-22 12:46:43 +09:00
|
|
|
} while (!(err_cor_info & ERR_CORRECTION_INFO__LAST_ERR));
|
2017-03-30 15:45:50 +09:00
|
|
|
|
|
|
|
/*
|
2017-09-22 12:46:45 +09:00
|
|
|
* Once handle all ECC errors, controller will trigger an
|
|
|
|
* ECC_TRANSACTION_DONE interrupt.
|
2017-03-30 15:45:50 +09:00
|
|
|
*/
|
2017-06-13 22:45:38 +09:00
|
|
|
irq_status = denali_wait_for_irq(denali, INTR__ECC_TRANSACTION_DONE);
|
|
|
|
if (!(irq_status & INTR__ECC_TRANSACTION_DONE))
|
|
|
|
return -EIO;
|
2017-03-30 15:45:50 +09:00
|
|
|
|
|
|
|
return max_bitflips;
|
2010-05-13 15:57:33 +01:00
|
|
|
}
|
|
|
|
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
static void denali_setup_dma64(struct denali_controller *denali,
|
2019-04-02 13:03:05 +09:00
|
|
|
dma_addr_t dma_addr, int page, bool write)
|
2017-03-30 15:45:54 +09:00
|
|
|
{
|
2019-04-02 13:03:09 +09:00
|
|
|
u32 mode;
|
2017-03-30 15:45:54 +09:00
|
|
|
const int page_count = 1;
|
|
|
|
|
mtd: nand: denali: avoid magic numbers and rename for clarification
Introduce some macros and helpers to avoid magic numbers and
rename macros/functions for clarification.
- We see '| 2' in several places. This means Data Cycle in MAP11 mode.
The Denali User's Guide says bit[1:0] of MAP11 is like follows:
b'00 = Command Cycle
b'01 = Address Cycle
b'10 = Data Cycle
So, this commit added DENALI_MAP11_{CMD,ADDR,DATA} macros.
- We see 'denali->flash_mem + 0x10' in several places, but 0x10 is a
magic number. Actually, this accesses the data port of the Host
Data/Command Interface. So, this commit added DENALI_HOST_DATA.
On the other hand, 'denali->flash_mem' gets access to the address
port, so DENALI_HOST_ADDR was also added.
- We see 'index_addr(denali, cmd, 0x1)' in denali_erase(), but 0x1
is a magic number. 0x1 means the erase operation. Replace 0x1
with DENALI_ERASE.
- Rename index_addr() to denali_host_write() for clarification
- Denali User's Guide says MAP{00,01,10,11} for access mode. Match
the macros with terminology in the IP document.
- Rename struct members as follows:
flash_bank -> active_bank (currently selected bank)
flash_reg -> reg (base address of registers)
flash_mem -> host (base address of host interface)
devnum -> devs_per_cs (devices connected in parallel)
bbtskipbytes -> oob_skip_bytes (number of bytes to skip in OOB)
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-06-16 14:36:39 +09:00
|
|
|
mode = DENALI_MAP10 | DENALI_BANK(denali) | page;
|
2017-03-30 15:45:54 +09:00
|
|
|
|
|
|
|
/* DMA is a three step process */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* 1. setup transfer type, interrupt when complete,
|
|
|
|
* burst len = 64 bytes, the number of pages
|
|
|
|
*/
|
2017-09-22 12:46:48 +09:00
|
|
|
denali->host_write(denali, mode,
|
2019-04-02 13:03:05 +09:00
|
|
|
0x01002000 | (64 << 16) |
|
|
|
|
(write ? BIT(8) : 0) | page_count);
|
2017-03-30 15:45:54 +09:00
|
|
|
|
|
|
|
/* 2. set memory low address */
|
2017-09-22 12:46:48 +09:00
|
|
|
denali->host_write(denali, mode, lower_32_bits(dma_addr));
|
2017-03-30 15:45:54 +09:00
|
|
|
|
|
|
|
/* 3. set memory high address */
|
2017-09-22 12:46:48 +09:00
|
|
|
denali->host_write(denali, mode, upper_32_bits(dma_addr));
|
2017-03-30 15:45:54 +09:00
|
|
|
}
|
|
|
|
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
static void denali_setup_dma32(struct denali_controller *denali,
|
2019-04-02 13:03:05 +09:00
|
|
|
dma_addr_t dma_addr, int page, bool write)
|
2010-05-13 15:57:33 +01:00
|
|
|
{
|
2019-04-02 13:03:09 +09:00
|
|
|
u32 mode;
|
2010-05-13 15:57:33 +01:00
|
|
|
const int page_count = 1;
|
|
|
|
|
mtd: nand: denali: avoid magic numbers and rename for clarification
Introduce some macros and helpers to avoid magic numbers and
rename macros/functions for clarification.
- We see '| 2' in several places. This means Data Cycle in MAP11 mode.
The Denali User's Guide says bit[1:0] of MAP11 is like follows:
b'00 = Command Cycle
b'01 = Address Cycle
b'10 = Data Cycle
So, this commit added DENALI_MAP11_{CMD,ADDR,DATA} macros.
- We see 'denali->flash_mem + 0x10' in several places, but 0x10 is a
magic number. Actually, this accesses the data port of the Host
Data/Command Interface. So, this commit added DENALI_HOST_DATA.
On the other hand, 'denali->flash_mem' gets access to the address
port, so DENALI_HOST_ADDR was also added.
- We see 'index_addr(denali, cmd, 0x1)' in denali_erase(), but 0x1
is a magic number. 0x1 means the erase operation. Replace 0x1
with DENALI_ERASE.
- Rename index_addr() to denali_host_write() for clarification
- Denali User's Guide says MAP{00,01,10,11} for access mode. Match
the macros with terminology in the IP document.
- Rename struct members as follows:
flash_bank -> active_bank (currently selected bank)
flash_reg -> reg (base address of registers)
flash_mem -> host (base address of host interface)
devnum -> devs_per_cs (devices connected in parallel)
bbtskipbytes -> oob_skip_bytes (number of bytes to skip in OOB)
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-06-16 14:36:39 +09:00
|
|
|
mode = DENALI_MAP10 | DENALI_BANK(denali);
|
2010-05-13 15:57:33 +01:00
|
|
|
|
|
|
|
/* DMA is a four step process */
|
|
|
|
|
|
|
|
/* 1. setup transfer type and # of pages */
|
2017-09-22 12:46:48 +09:00
|
|
|
denali->host_write(denali, mode | page,
|
2019-04-02 13:03:05 +09:00
|
|
|
0x2000 | (write ? BIT(8) : 0) | page_count);
|
2010-05-13 15:57:33 +01:00
|
|
|
|
|
|
|
/* 2. set memory high address bits 23:8 */
|
2017-09-22 12:46:48 +09:00
|
|
|
denali->host_write(denali, mode | ((dma_addr >> 16) << 8), 0x2200);
|
2010-05-13 15:57:33 +01:00
|
|
|
|
|
|
|
/* 3. set memory low address bits 23:8 */
|
2017-09-22 12:46:48 +09:00
|
|
|
denali->host_write(denali, mode | ((dma_addr & 0xffff) << 8), 0x2300);
|
2010-05-13 15:57:33 +01:00
|
|
|
|
2014-09-09 11:01:51 +09:00
|
|
|
/* 4. interrupt when complete, burst len = 64 bytes */
|
2017-09-22 12:46:48 +09:00
|
|
|
denali->host_write(denali, mode | 0x14000, 0x2400);
|
2010-05-13 15:57:33 +01:00
|
|
|
}
|
|
|
|
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
static int denali_pio_read(struct denali_controller *denali, u32 *buf,
|
2019-01-24 13:19:07 +09:00
|
|
|
size_t size, int page)
|
2010-05-13 15:57:33 +01:00
|
|
|
{
|
2017-09-22 12:46:48 +09:00
|
|
|
u32 addr = DENALI_MAP01 | DENALI_BANK(denali) | page;
|
2019-04-02 13:03:09 +09:00
|
|
|
u32 irq_status, ecc_err_mask;
|
2017-06-13 22:45:45 +09:00
|
|
|
int i;
|
2017-06-13 22:45:35 +09:00
|
|
|
|
2017-06-13 22:45:45 +09:00
|
|
|
if (denali->caps & DENALI_CAP_HW_ECC_FIXUP)
|
|
|
|
ecc_err_mask = INTR__ECC_UNCOR_ERR;
|
|
|
|
else
|
|
|
|
ecc_err_mask = INTR__ECC_ERR;
|
2010-05-13 15:57:33 +01:00
|
|
|
|
2017-06-13 22:45:45 +09:00
|
|
|
denali_reset_irq(denali);
|
2010-05-13 15:57:33 +01:00
|
|
|
|
2017-06-13 22:45:45 +09:00
|
|
|
for (i = 0; i < size / 4; i++)
|
2019-04-02 13:03:03 +09:00
|
|
|
buf[i] = denali->host_read(denali, addr);
|
2017-06-13 22:45:45 +09:00
|
|
|
|
|
|
|
irq_status = denali_wait_for_irq(denali, INTR__PAGE_XFER_INC);
|
|
|
|
if (!(irq_status & INTR__PAGE_XFER_INC))
|
|
|
|
return -EIO;
|
2010-05-13 15:57:33 +01:00
|
|
|
|
mtd: nand: denali: support hardware-assisted erased page detection
Recent versions of this IP support automatic erased page detection.
If an erased page is detected on reads, the controller does not set
INTR__ECC_UNCOR_ERR, but INTR__ERASED_PAGE.
The detection of erased pages is based on the number of zeros in a
page; if the number of zeros is less than the value in the field
ERASED_THRESHOLD, the page is assumed as erased.
Please note ERASED_THRESHOLD specifies the number of zeros in a _page_
instead of an ECC chunk. Moreover, the controller does not provide a
way to know the actual number of bitflips.
Actually, an erased page (all 0xff) is not an ECC correctable pattern
on the Denali ECC engine. In other words, there may be overlap between
the following two:
[1] a bit pattern reachable from a valid payload + ECC pattern within
ecc.strength bitflips
[2] a bit pattern reachable from an erased state (all 0xff) within
ecc.strength bitflips
So, this feature may intercept ECC correctable patterns, then replace
[1] with [2].
After all, this feature can work safely only when ECC_THRESHOLD == 1,
i.e. detect erased pages without any bitflips. This should be the
case most of the time. If there is a bitflip or more, the driver will
fallback to the software method by using nand_check_erased_ecc_chunk().
Strangely enough, the driver still has to fill the buffer with 0xff
in case of INTR__ERASED_PAGE because the ECC correction engine has
already manipulated the data in the buffer before it judges erased
pages.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-06-13 22:45:46 +09:00
|
|
|
if (irq_status & INTR__ERASED_PAGE)
|
|
|
|
memset(buf, 0xff, size);
|
|
|
|
|
2017-06-13 22:45:45 +09:00
|
|
|
return irq_status & ecc_err_mask ? -EBADMSG : 0;
|
|
|
|
}
|
|
|
|
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
static int denali_pio_write(struct denali_controller *denali, const u32 *buf,
|
2019-04-02 13:03:03 +09:00
|
|
|
size_t size, int page)
|
2017-06-13 22:45:45 +09:00
|
|
|
{
|
2017-09-22 12:46:48 +09:00
|
|
|
u32 addr = DENALI_MAP01 | DENALI_BANK(denali) | page;
|
2019-04-02 13:03:09 +09:00
|
|
|
u32 irq_status;
|
2017-06-13 22:45:45 +09:00
|
|
|
int i;
|
2010-05-13 15:57:33 +01:00
|
|
|
|
2017-06-13 22:45:38 +09:00
|
|
|
denali_reset_irq(denali);
|
2017-06-13 22:45:45 +09:00
|
|
|
|
|
|
|
for (i = 0; i < size / 4; i++)
|
2019-04-02 13:03:03 +09:00
|
|
|
denali->host_write(denali, addr, buf[i]);
|
2017-06-13 22:45:45 +09:00
|
|
|
|
|
|
|
irq_status = denali_wait_for_irq(denali,
|
2019-04-02 13:03:09 +09:00
|
|
|
INTR__PROGRAM_COMP |
|
|
|
|
INTR__PROGRAM_FAIL);
|
2017-06-13 22:45:45 +09:00
|
|
|
if (!(irq_status & INTR__PROGRAM_COMP))
|
|
|
|
return -EIO;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
static int denali_pio_xfer(struct denali_controller *denali, void *buf,
|
2019-04-02 13:03:05 +09:00
|
|
|
size_t size, int page, bool write)
|
2017-06-13 22:45:45 +09:00
|
|
|
{
|
|
|
|
if (write)
|
2019-01-24 13:19:07 +09:00
|
|
|
return denali_pio_write(denali, buf, size, page);
|
2017-06-13 22:45:45 +09:00
|
|
|
else
|
2019-01-24 13:19:07 +09:00
|
|
|
return denali_pio_read(denali, buf, size, page);
|
2017-06-13 22:45:45 +09:00
|
|
|
}
|
|
|
|
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
static int denali_dma_xfer(struct denali_controller *denali, void *buf,
|
2019-04-02 13:03:05 +09:00
|
|
|
size_t size, int page, bool write)
|
2017-06-13 22:45:45 +09:00
|
|
|
{
|
2017-06-13 22:45:47 +09:00
|
|
|
dma_addr_t dma_addr;
|
2019-04-02 13:03:09 +09:00
|
|
|
u32 irq_mask, irq_status, ecc_err_mask;
|
2017-06-13 22:45:45 +09:00
|
|
|
enum dma_data_direction dir = write ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
|
|
|
|
int ret = 0;
|
|
|
|
|
2017-06-13 22:45:47 +09:00
|
|
|
dma_addr = dma_map_single(denali->dev, buf, size, dir);
|
|
|
|
if (dma_mapping_error(denali->dev, dma_addr)) {
|
|
|
|
dev_dbg(denali->dev, "Failed to DMA-map buffer. Trying PIO.\n");
|
2019-01-24 13:19:07 +09:00
|
|
|
return denali_pio_xfer(denali, buf, size, page, write);
|
2017-06-13 22:45:47 +09:00
|
|
|
}
|
2017-06-13 22:45:45 +09:00
|
|
|
|
|
|
|
if (write) {
|
|
|
|
/*
|
|
|
|
* INTR__PROGRAM_COMP is never asserted for the DMA transfer.
|
|
|
|
* We can use INTR__DMA_CMD_COMP instead. This flag is asserted
|
|
|
|
* when the page program is completed.
|
|
|
|
*/
|
|
|
|
irq_mask = INTR__DMA_CMD_COMP | INTR__PROGRAM_FAIL;
|
|
|
|
ecc_err_mask = 0;
|
|
|
|
} else if (denali->caps & DENALI_CAP_HW_ECC_FIXUP) {
|
|
|
|
irq_mask = INTR__DMA_CMD_COMP;
|
|
|
|
ecc_err_mask = INTR__ECC_UNCOR_ERR;
|
|
|
|
} else {
|
|
|
|
irq_mask = INTR__DMA_CMD_COMP;
|
|
|
|
ecc_err_mask = INTR__ECC_ERR;
|
|
|
|
}
|
|
|
|
|
2017-09-22 12:46:41 +09:00
|
|
|
iowrite32(DMA_ENABLE__FLAG, denali->reg + DMA_ENABLE);
|
2018-09-13 14:58:49 +09:00
|
|
|
/*
|
|
|
|
* The ->setup_dma() hook kicks DMA by using the data/command
|
|
|
|
* interface, which belongs to a different AXI port from the
|
|
|
|
* register interface. Read back the register to avoid a race.
|
|
|
|
*/
|
|
|
|
ioread32(denali->reg + DMA_ENABLE);
|
2010-05-13 15:57:33 +01:00
|
|
|
|
2017-06-13 22:45:45 +09:00
|
|
|
denali_reset_irq(denali);
|
2017-09-22 12:46:49 +09:00
|
|
|
denali->setup_dma(denali, dma_addr, page, write);
|
2010-05-13 15:57:33 +01:00
|
|
|
|
2017-06-13 22:45:38 +09:00
|
|
|
irq_status = denali_wait_for_irq(denali, irq_mask);
|
2017-06-13 22:45:45 +09:00
|
|
|
if (!(irq_status & INTR__DMA_CMD_COMP))
|
2017-06-13 22:45:35 +09:00
|
|
|
ret = -EIO;
|
2017-06-13 22:45:45 +09:00
|
|
|
else if (irq_status & ecc_err_mask)
|
|
|
|
ret = -EBADMSG;
|
2010-05-13 15:57:33 +01:00
|
|
|
|
2017-09-22 12:46:41 +09:00
|
|
|
iowrite32(0, denali->reg + DMA_ENABLE);
|
|
|
|
|
2017-06-13 22:45:47 +09:00
|
|
|
dma_unmap_single(denali->dev, dma_addr, size, dir);
|
2012-06-25 18:07:45 +08:00
|
|
|
|
mtd: nand: denali: support hardware-assisted erased page detection
Recent versions of this IP support automatic erased page detection.
If an erased page is detected on reads, the controller does not set
INTR__ECC_UNCOR_ERR, but INTR__ERASED_PAGE.
The detection of erased pages is based on the number of zeros in a
page; if the number of zeros is less than the value in the field
ERASED_THRESHOLD, the page is assumed as erased.
Please note ERASED_THRESHOLD specifies the number of zeros in a _page_
instead of an ECC chunk. Moreover, the controller does not provide a
way to know the actual number of bitflips.
Actually, an erased page (all 0xff) is not an ECC correctable pattern
on the Denali ECC engine. In other words, there may be overlap between
the following two:
[1] a bit pattern reachable from a valid payload + ECC pattern within
ecc.strength bitflips
[2] a bit pattern reachable from an erased state (all 0xff) within
ecc.strength bitflips
So, this feature may intercept ECC correctable patterns, then replace
[1] with [2].
After all, this feature can work safely only when ECC_THRESHOLD == 1,
i.e. detect erased pages without any bitflips. This should be the
case most of the time. If there is a bitflip or more, the driver will
fallback to the software method by using nand_check_erased_ecc_chunk().
Strangely enough, the driver still has to fill the buffer with 0xff
in case of INTR__ERASED_PAGE because the ECC correction engine has
already manipulated the data in the buffer before it judges erased
pages.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-06-13 22:45:46 +09:00
|
|
|
if (irq_status & INTR__ERASED_PAGE)
|
|
|
|
memset(buf, 0xff, size);
|
|
|
|
|
2017-06-13 22:45:35 +09:00
|
|
|
return ret;
|
2010-05-13 15:57:33 +01:00
|
|
|
}
|
|
|
|
|
2019-04-02 13:03:02 +09:00
|
|
|
static int denali_page_xfer(struct nand_chip *chip, void *buf, size_t size,
|
2019-04-02 13:03:05 +09:00
|
|
|
int page, bool write)
|
2010-05-13 15:57:33 +01:00
|
|
|
{
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
struct denali_controller *denali = to_denali_controller(chip);
|
2019-04-02 13:03:01 +09:00
|
|
|
|
2019-04-02 13:03:04 +09:00
|
|
|
denali_select_target(chip, chip->cur_cs);
|
|
|
|
|
2017-06-13 22:45:45 +09:00
|
|
|
if (denali->dma_avail)
|
2019-01-24 13:19:07 +09:00
|
|
|
return denali_dma_xfer(denali, buf, size, page, write);
|
2017-06-13 22:45:45 +09:00
|
|
|
else
|
2019-01-24 13:19:07 +09:00
|
|
|
return denali_pio_xfer(denali, buf, size, page, write);
|
2010-05-13 15:57:33 +01:00
|
|
|
}
|
|
|
|
|
2019-04-02 13:03:09 +09:00
|
|
|
static int denali_read_page(struct nand_chip *chip, u8 *buf,
|
2018-09-06 14:05:20 +02:00
|
|
|
int oob_required, int page)
|
2017-06-13 22:45:45 +09:00
|
|
|
{
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
struct denali_controller *denali = to_denali_controller(chip);
|
2018-09-06 14:05:20 +02:00
|
|
|
struct mtd_info *mtd = nand_to_mtd(chip);
|
2017-06-13 22:45:45 +09:00
|
|
|
unsigned long uncor_ecc_flags = 0;
|
|
|
|
int stat = 0;
|
|
|
|
int ret;
|
2010-05-13 15:57:33 +01:00
|
|
|
|
2019-04-02 13:03:05 +09:00
|
|
|
ret = denali_page_xfer(chip, buf, mtd->writesize, page, false);
|
2017-06-13 22:45:45 +09:00
|
|
|
if (ret && ret != -EBADMSG)
|
|
|
|
return ret;
|
2010-05-13 15:57:33 +01:00
|
|
|
|
2017-03-30 15:45:52 +09:00
|
|
|
if (denali->caps & DENALI_CAP_HW_ECC_FIXUP)
|
2019-04-02 13:03:01 +09:00
|
|
|
stat = denali_hw_ecc_fixup(chip, &uncor_ecc_flags);
|
2017-06-13 22:45:45 +09:00
|
|
|
else if (ret == -EBADMSG)
|
2019-04-02 13:03:01 +09:00
|
|
|
stat = denali_sw_ecc_fixup(chip, &uncor_ecc_flags, buf);
|
2010-05-13 15:57:33 +01:00
|
|
|
|
2017-03-30 15:45:51 +09:00
|
|
|
if (stat < 0)
|
|
|
|
return stat;
|
|
|
|
|
|
|
|
if (uncor_ecc_flags) {
|
2018-09-06 14:05:20 +02:00
|
|
|
ret = denali_read_oob(chip, page);
|
2017-06-13 22:45:45 +09:00
|
|
|
if (ret)
|
|
|
|
return ret;
|
2010-05-13 15:57:33 +01:00
|
|
|
|
2019-04-02 13:03:01 +09:00
|
|
|
stat = denali_check_erased_page(chip, buf,
|
2017-03-30 15:45:51 +09:00
|
|
|
uncor_ecc_flags, stat);
|
2010-05-13 15:57:33 +01:00
|
|
|
}
|
2017-03-30 15:45:51 +09:00
|
|
|
|
|
|
|
return stat;
|
2010-05-13 15:57:33 +01:00
|
|
|
}
|
|
|
|
|
2019-04-02 13:03:09 +09:00
|
|
|
static int denali_write_page(struct nand_chip *chip, const u8 *buf,
|
2018-09-06 14:05:21 +02:00
|
|
|
int oob_required, int page)
|
2017-06-13 22:45:45 +09:00
|
|
|
{
|
2018-09-06 14:05:21 +02:00
|
|
|
struct mtd_info *mtd = nand_to_mtd(chip);
|
2010-05-13 15:57:33 +01:00
|
|
|
|
2019-04-02 13:03:05 +09:00
|
|
|
return denali_page_xfer(chip, (void *)buf, mtd->writesize, page, true);
|
2010-05-13 15:57:33 +01:00
|
|
|
}
|
|
|
|
|
2020-05-29 13:13:13 +02:00
|
|
|
static int denali_setup_interface(struct nand_chip *chip, int chipnr,
|
|
|
|
const struct nand_interface_config *conf)
|
mtd: nand: denali: handle timing parameters by setup_data_interface()
Handling timing parameters in a driver's own way should be avoided
because it duplicates efforts of drivers/mtd/nand/nand_timings.c
Besides, this driver hard-codes Intel specific parameters such as
CLK_X=5, CLK_MULTI=4. Taking a certain device (Samsung K9WAG08U1A)
into account by get_samsung_nand_para() is weird as well.
Now, the core framework provides .setup_data_interface() hook, which
handles timing parameters in a generic manner.
While I am working on this, I found even more issues in the current
code, so fixed the following as well:
- In recent IP versions, WE_2_RE and TWHR2 share the same register.
Likewise for ADDR_2_DATA and TCWAW, CS_SETUP_CNT and TWB. When
updating one, the other must be masked. Otherwise, the other will
be set to 0, then timing settings will be broken.
- The recent IP release expanded the ADDR_2_DATA to 7-bit wide.
This register is related to tADL. As commit 74a332e78e8f ("mtd:
nand: timings: Fix tADL_min for ONFI 4.0 chips") addressed, the
ONFi 4.0 increased the minimum of tADL to 400 nsec. This may not
fit in the 6-bit ADDR_2_DATA in older versions. Check the IP
revision and handle this correctly, otherwise the register value
would wrap around.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-06-13 22:45:37 +09:00
|
|
|
{
|
mtd: rawnand: denali: add more delays before latching incoming data
The Denali IP have several registers to specify how many clock cycles
should be waited between falling/rising signals. You can improve the
NAND access performance by programming these registers with optimized
values.
Because struct nand_sdr_timings represents the device requirement
in pico seconds, denali_setup_data_interface() computes the register
values by dividing the device timings with the clock period.
Marek Vasut reported this driver in the latest kernel does not work
on his SOCFPGA board. (The on-board NAND chip is mode 5)
The suspicious parameter is acc_clks, so this commit relaxes it.
The Denali NAND Flash Memory Controller User's Guide describes this
register as follows:
acc_clks
signifies the number of bus interface clk_x clock cycles,
controller should wait from read enable going low to sending
out a strobe of clk_x for capturing of incoming data.
Currently, acc_clks is calculated only based on tREA, the delay on the
chip side. This does not include additional delays that come from the
data path on the PCB and in the SoC, load capacity of the pins, etc.
This relatively becomes a big factor on faster timing modes like mode 5.
Before supporting the ->setup_data_interface() hook (e.g. Linux 4.12),
the Denali driver hacks acc_clks in a couple of ways [1] [2] to support
the timing mode 5.
We would not go back to the hard-coded acc_clks, but we need to include
this factor into the delay somehow. Let's say the amount of the additional
delay is 10000 pico sec.
In the new calculation, acc_clks is determined by timings->tREA_max +
data_setup_on_host.
Also, prolong the RE# low period to make sure the data hold is met.
Finally, re-center the data latch timing for extra safety.
[1] https://github.com/torvalds/linux/blob/v4.12/drivers/mtd/nand/denali.c#L276
[2] https://github.com/torvalds/linux/blob/v4.12/drivers/mtd/nand/denali.c#L282
Reported-by: Marek Vasut <marex@denx.de>
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Tested-by: Marek Vasut <marex@denx.de>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/linux-mtd/20200317071821.9916-1-yamada.masahiro@socionext.com
2020-03-17 16:18:21 +09:00
|
|
|
static const unsigned int data_setup_on_host = 10000;
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
struct denali_controller *denali = to_denali_controller(chip);
|
|
|
|
struct denali_chip_sel *sel;
|
mtd: nand: denali: handle timing parameters by setup_data_interface()
Handling timing parameters in a driver's own way should be avoided
because it duplicates efforts of drivers/mtd/nand/nand_timings.c
Besides, this driver hard-codes Intel specific parameters such as
CLK_X=5, CLK_MULTI=4. Taking a certain device (Samsung K9WAG08U1A)
into account by get_samsung_nand_para() is weird as well.
Now, the core framework provides .setup_data_interface() hook, which
handles timing parameters in a generic manner.
While I am working on this, I found even more issues in the current
code, so fixed the following as well:
- In recent IP versions, WE_2_RE and TWHR2 share the same register.
Likewise for ADDR_2_DATA and TCWAW, CS_SETUP_CNT and TWB. When
updating one, the other must be masked. Otherwise, the other will
be set to 0, then timing settings will be broken.
- The recent IP release expanded the ADDR_2_DATA to 7-bit wide.
This register is related to tADL. As commit 74a332e78e8f ("mtd:
nand: timings: Fix tADL_min for ONFI 4.0 chips") addressed, the
ONFi 4.0 increased the minimum of tADL to 400 nsec. This may not
fit in the 6-bit ADDR_2_DATA in older versions. Check the IP
revision and handle this correctly, otherwise the register value
would wrap around.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-06-13 22:45:37 +09:00
|
|
|
const struct nand_sdr_timings *timings;
|
2018-06-23 01:06:38 +09:00
|
|
|
unsigned long t_x, mult_x;
|
mtd: nand: denali: handle timing parameters by setup_data_interface()
Handling timing parameters in a driver's own way should be avoided
because it duplicates efforts of drivers/mtd/nand/nand_timings.c
Besides, this driver hard-codes Intel specific parameters such as
CLK_X=5, CLK_MULTI=4. Taking a certain device (Samsung K9WAG08U1A)
into account by get_samsung_nand_para() is weird as well.
Now, the core framework provides .setup_data_interface() hook, which
handles timing parameters in a generic manner.
While I am working on this, I found even more issues in the current
code, so fixed the following as well:
- In recent IP versions, WE_2_RE and TWHR2 share the same register.
Likewise for ADDR_2_DATA and TCWAW, CS_SETUP_CNT and TWB. When
updating one, the other must be masked. Otherwise, the other will
be set to 0, then timing settings will be broken.
- The recent IP release expanded the ADDR_2_DATA to 7-bit wide.
This register is related to tADL. As commit 74a332e78e8f ("mtd:
nand: timings: Fix tADL_min for ONFI 4.0 chips") addressed, the
ONFi 4.0 increased the minimum of tADL to 400 nsec. This may not
fit in the 6-bit ADDR_2_DATA in older versions. Check the IP
revision and handle this correctly, otherwise the register value
would wrap around.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-06-13 22:45:37 +09:00
|
|
|
int acc_clks, re_2_we, re_2_re, we_2_re, addr_2_data;
|
|
|
|
int rdwr_en_lo, rdwr_en_hi, rdwr_en_lo_hi, cs_setup;
|
|
|
|
int addr_2_data_mask;
|
2019-04-02 13:03:09 +09:00
|
|
|
u32 tmp;
|
mtd: nand: denali: handle timing parameters by setup_data_interface()
Handling timing parameters in a driver's own way should be avoided
because it duplicates efforts of drivers/mtd/nand/nand_timings.c
Besides, this driver hard-codes Intel specific parameters such as
CLK_X=5, CLK_MULTI=4. Taking a certain device (Samsung K9WAG08U1A)
into account by get_samsung_nand_para() is weird as well.
Now, the core framework provides .setup_data_interface() hook, which
handles timing parameters in a generic manner.
While I am working on this, I found even more issues in the current
code, so fixed the following as well:
- In recent IP versions, WE_2_RE and TWHR2 share the same register.
Likewise for ADDR_2_DATA and TCWAW, CS_SETUP_CNT and TWB. When
updating one, the other must be masked. Otherwise, the other will
be set to 0, then timing settings will be broken.
- The recent IP release expanded the ADDR_2_DATA to 7-bit wide.
This register is related to tADL. As commit 74a332e78e8f ("mtd:
nand: timings: Fix tADL_min for ONFI 4.0 chips") addressed, the
ONFi 4.0 increased the minimum of tADL to 400 nsec. This may not
fit in the 6-bit ADDR_2_DATA in older versions. Check the IP
revision and handle this correctly, otherwise the register value
would wrap around.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-06-13 22:45:37 +09:00
|
|
|
|
|
|
|
timings = nand_get_sdr_timings(conf);
|
|
|
|
if (IS_ERR(timings))
|
|
|
|
return PTR_ERR(timings);
|
|
|
|
|
|
|
|
/* clk_x period in picoseconds */
|
2018-06-23 01:06:38 +09:00
|
|
|
t_x = DIV_ROUND_DOWN_ULL(1000000000000ULL, denali->clk_x_rate);
|
|
|
|
if (!t_x)
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The bus interface clock, clk_x, is phase aligned with the core clock.
|
|
|
|
* The clk_x is an integral multiple N of the core clk. The value N is
|
|
|
|
* configured at IP delivery time, and its available value is 4, 5, 6.
|
|
|
|
*/
|
|
|
|
mult_x = DIV_ROUND_CLOSEST_ULL(denali->clk_x_rate, denali->clk_rate);
|
|
|
|
if (mult_x < 4 || mult_x > 6)
|
mtd: nand: denali: handle timing parameters by setup_data_interface()
Handling timing parameters in a driver's own way should be avoided
because it duplicates efforts of drivers/mtd/nand/nand_timings.c
Besides, this driver hard-codes Intel specific parameters such as
CLK_X=5, CLK_MULTI=4. Taking a certain device (Samsung K9WAG08U1A)
into account by get_samsung_nand_para() is weird as well.
Now, the core framework provides .setup_data_interface() hook, which
handles timing parameters in a generic manner.
While I am working on this, I found even more issues in the current
code, so fixed the following as well:
- In recent IP versions, WE_2_RE and TWHR2 share the same register.
Likewise for ADDR_2_DATA and TCWAW, CS_SETUP_CNT and TWB. When
updating one, the other must be masked. Otherwise, the other will
be set to 0, then timing settings will be broken.
- The recent IP release expanded the ADDR_2_DATA to 7-bit wide.
This register is related to tADL. As commit 74a332e78e8f ("mtd:
nand: timings: Fix tADL_min for ONFI 4.0 chips") addressed, the
ONFi 4.0 increased the minimum of tADL to 400 nsec. This may not
fit in the 6-bit ADDR_2_DATA in older versions. Check the IP
revision and handle this correctly, otherwise the register value
would wrap around.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-06-13 22:45:37 +09:00
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
if (chipnr == NAND_DATA_IFACE_CHECK_ONLY)
|
|
|
|
return 0;
|
|
|
|
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
sel = &to_denali_chip(chip)->sels[chipnr];
|
|
|
|
|
mtd: nand: denali: handle timing parameters by setup_data_interface()
Handling timing parameters in a driver's own way should be avoided
because it duplicates efforts of drivers/mtd/nand/nand_timings.c
Besides, this driver hard-codes Intel specific parameters such as
CLK_X=5, CLK_MULTI=4. Taking a certain device (Samsung K9WAG08U1A)
into account by get_samsung_nand_para() is weird as well.
Now, the core framework provides .setup_data_interface() hook, which
handles timing parameters in a generic manner.
While I am working on this, I found even more issues in the current
code, so fixed the following as well:
- In recent IP versions, WE_2_RE and TWHR2 share the same register.
Likewise for ADDR_2_DATA and TCWAW, CS_SETUP_CNT and TWB. When
updating one, the other must be masked. Otherwise, the other will
be set to 0, then timing settings will be broken.
- The recent IP release expanded the ADDR_2_DATA to 7-bit wide.
This register is related to tADL. As commit 74a332e78e8f ("mtd:
nand: timings: Fix tADL_min for ONFI 4.0 chips") addressed, the
ONFi 4.0 increased the minimum of tADL to 400 nsec. This may not
fit in the 6-bit ADDR_2_DATA in older versions. Check the IP
revision and handle this correctly, otherwise the register value
would wrap around.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-06-13 22:45:37 +09:00
|
|
|
/* tRWH -> RE_2_WE */
|
2018-06-23 01:06:38 +09:00
|
|
|
re_2_we = DIV_ROUND_UP(timings->tRHW_min, t_x);
|
mtd: nand: denali: handle timing parameters by setup_data_interface()
Handling timing parameters in a driver's own way should be avoided
because it duplicates efforts of drivers/mtd/nand/nand_timings.c
Besides, this driver hard-codes Intel specific parameters such as
CLK_X=5, CLK_MULTI=4. Taking a certain device (Samsung K9WAG08U1A)
into account by get_samsung_nand_para() is weird as well.
Now, the core framework provides .setup_data_interface() hook, which
handles timing parameters in a generic manner.
While I am working on this, I found even more issues in the current
code, so fixed the following as well:
- In recent IP versions, WE_2_RE and TWHR2 share the same register.
Likewise for ADDR_2_DATA and TCWAW, CS_SETUP_CNT and TWB. When
updating one, the other must be masked. Otherwise, the other will
be set to 0, then timing settings will be broken.
- The recent IP release expanded the ADDR_2_DATA to 7-bit wide.
This register is related to tADL. As commit 74a332e78e8f ("mtd:
nand: timings: Fix tADL_min for ONFI 4.0 chips") addressed, the
ONFi 4.0 increased the minimum of tADL to 400 nsec. This may not
fit in the 6-bit ADDR_2_DATA in older versions. Check the IP
revision and handle this correctly, otherwise the register value
would wrap around.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-06-13 22:45:37 +09:00
|
|
|
re_2_we = min_t(int, re_2_we, RE_2_WE__VALUE);
|
|
|
|
|
mtd: nand: denali: avoid magic numbers and rename for clarification
Introduce some macros and helpers to avoid magic numbers and
rename macros/functions for clarification.
- We see '| 2' in several places. This means Data Cycle in MAP11 mode.
The Denali User's Guide says bit[1:0] of MAP11 is like follows:
b'00 = Command Cycle
b'01 = Address Cycle
b'10 = Data Cycle
So, this commit added DENALI_MAP11_{CMD,ADDR,DATA} macros.
- We see 'denali->flash_mem + 0x10' in several places, but 0x10 is a
magic number. Actually, this accesses the data port of the Host
Data/Command Interface. So, this commit added DENALI_HOST_DATA.
On the other hand, 'denali->flash_mem' gets access to the address
port, so DENALI_HOST_ADDR was also added.
- We see 'index_addr(denali, cmd, 0x1)' in denali_erase(), but 0x1
is a magic number. 0x1 means the erase operation. Replace 0x1
with DENALI_ERASE.
- Rename index_addr() to denali_host_write() for clarification
- Denali User's Guide says MAP{00,01,10,11} for access mode. Match
the macros with terminology in the IP document.
- Rename struct members as follows:
flash_bank -> active_bank (currently selected bank)
flash_reg -> reg (base address of registers)
flash_mem -> host (base address of host interface)
devnum -> devs_per_cs (devices connected in parallel)
bbtskipbytes -> oob_skip_bytes (number of bytes to skip in OOB)
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-06-16 14:36:39 +09:00
|
|
|
tmp = ioread32(denali->reg + RE_2_WE);
|
mtd: nand: denali: handle timing parameters by setup_data_interface()
Handling timing parameters in a driver's own way should be avoided
because it duplicates efforts of drivers/mtd/nand/nand_timings.c
Besides, this driver hard-codes Intel specific parameters such as
CLK_X=5, CLK_MULTI=4. Taking a certain device (Samsung K9WAG08U1A)
into account by get_samsung_nand_para() is weird as well.
Now, the core framework provides .setup_data_interface() hook, which
handles timing parameters in a generic manner.
While I am working on this, I found even more issues in the current
code, so fixed the following as well:
- In recent IP versions, WE_2_RE and TWHR2 share the same register.
Likewise for ADDR_2_DATA and TCWAW, CS_SETUP_CNT and TWB. When
updating one, the other must be masked. Otherwise, the other will
be set to 0, then timing settings will be broken.
- The recent IP release expanded the ADDR_2_DATA to 7-bit wide.
This register is related to tADL. As commit 74a332e78e8f ("mtd:
nand: timings: Fix tADL_min for ONFI 4.0 chips") addressed, the
ONFi 4.0 increased the minimum of tADL to 400 nsec. This may not
fit in the 6-bit ADDR_2_DATA in older versions. Check the IP
revision and handle this correctly, otherwise the register value
would wrap around.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-06-13 22:45:37 +09:00
|
|
|
tmp &= ~RE_2_WE__VALUE;
|
2017-09-22 12:46:44 +09:00
|
|
|
tmp |= FIELD_PREP(RE_2_WE__VALUE, re_2_we);
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
sel->re_2_we = tmp;
|
mtd: nand: denali: handle timing parameters by setup_data_interface()
Handling timing parameters in a driver's own way should be avoided
because it duplicates efforts of drivers/mtd/nand/nand_timings.c
Besides, this driver hard-codes Intel specific parameters such as
CLK_X=5, CLK_MULTI=4. Taking a certain device (Samsung K9WAG08U1A)
into account by get_samsung_nand_para() is weird as well.
Now, the core framework provides .setup_data_interface() hook, which
handles timing parameters in a generic manner.
While I am working on this, I found even more issues in the current
code, so fixed the following as well:
- In recent IP versions, WE_2_RE and TWHR2 share the same register.
Likewise for ADDR_2_DATA and TCWAW, CS_SETUP_CNT and TWB. When
updating one, the other must be masked. Otherwise, the other will
be set to 0, then timing settings will be broken.
- The recent IP release expanded the ADDR_2_DATA to 7-bit wide.
This register is related to tADL. As commit 74a332e78e8f ("mtd:
nand: timings: Fix tADL_min for ONFI 4.0 chips") addressed, the
ONFi 4.0 increased the minimum of tADL to 400 nsec. This may not
fit in the 6-bit ADDR_2_DATA in older versions. Check the IP
revision and handle this correctly, otherwise the register value
would wrap around.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-06-13 22:45:37 +09:00
|
|
|
|
|
|
|
/* tRHZ -> RE_2_RE */
|
2018-06-23 01:06:38 +09:00
|
|
|
re_2_re = DIV_ROUND_UP(timings->tRHZ_max, t_x);
|
mtd: nand: denali: handle timing parameters by setup_data_interface()
Handling timing parameters in a driver's own way should be avoided
because it duplicates efforts of drivers/mtd/nand/nand_timings.c
Besides, this driver hard-codes Intel specific parameters such as
CLK_X=5, CLK_MULTI=4. Taking a certain device (Samsung K9WAG08U1A)
into account by get_samsung_nand_para() is weird as well.
Now, the core framework provides .setup_data_interface() hook, which
handles timing parameters in a generic manner.
While I am working on this, I found even more issues in the current
code, so fixed the following as well:
- In recent IP versions, WE_2_RE and TWHR2 share the same register.
Likewise for ADDR_2_DATA and TCWAW, CS_SETUP_CNT and TWB. When
updating one, the other must be masked. Otherwise, the other will
be set to 0, then timing settings will be broken.
- The recent IP release expanded the ADDR_2_DATA to 7-bit wide.
This register is related to tADL. As commit 74a332e78e8f ("mtd:
nand: timings: Fix tADL_min for ONFI 4.0 chips") addressed, the
ONFi 4.0 increased the minimum of tADL to 400 nsec. This may not
fit in the 6-bit ADDR_2_DATA in older versions. Check the IP
revision and handle this correctly, otherwise the register value
would wrap around.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-06-13 22:45:37 +09:00
|
|
|
re_2_re = min_t(int, re_2_re, RE_2_RE__VALUE);
|
|
|
|
|
mtd: nand: denali: avoid magic numbers and rename for clarification
Introduce some macros and helpers to avoid magic numbers and
rename macros/functions for clarification.
- We see '| 2' in several places. This means Data Cycle in MAP11 mode.
The Denali User's Guide says bit[1:0] of MAP11 is like follows:
b'00 = Command Cycle
b'01 = Address Cycle
b'10 = Data Cycle
So, this commit added DENALI_MAP11_{CMD,ADDR,DATA} macros.
- We see 'denali->flash_mem + 0x10' in several places, but 0x10 is a
magic number. Actually, this accesses the data port of the Host
Data/Command Interface. So, this commit added DENALI_HOST_DATA.
On the other hand, 'denali->flash_mem' gets access to the address
port, so DENALI_HOST_ADDR was also added.
- We see 'index_addr(denali, cmd, 0x1)' in denali_erase(), but 0x1
is a magic number. 0x1 means the erase operation. Replace 0x1
with DENALI_ERASE.
- Rename index_addr() to denali_host_write() for clarification
- Denali User's Guide says MAP{00,01,10,11} for access mode. Match
the macros with terminology in the IP document.
- Rename struct members as follows:
flash_bank -> active_bank (currently selected bank)
flash_reg -> reg (base address of registers)
flash_mem -> host (base address of host interface)
devnum -> devs_per_cs (devices connected in parallel)
bbtskipbytes -> oob_skip_bytes (number of bytes to skip in OOB)
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-06-16 14:36:39 +09:00
|
|
|
tmp = ioread32(denali->reg + RE_2_RE);
|
mtd: nand: denali: handle timing parameters by setup_data_interface()
Handling timing parameters in a driver's own way should be avoided
because it duplicates efforts of drivers/mtd/nand/nand_timings.c
Besides, this driver hard-codes Intel specific parameters such as
CLK_X=5, CLK_MULTI=4. Taking a certain device (Samsung K9WAG08U1A)
into account by get_samsung_nand_para() is weird as well.
Now, the core framework provides .setup_data_interface() hook, which
handles timing parameters in a generic manner.
While I am working on this, I found even more issues in the current
code, so fixed the following as well:
- In recent IP versions, WE_2_RE and TWHR2 share the same register.
Likewise for ADDR_2_DATA and TCWAW, CS_SETUP_CNT and TWB. When
updating one, the other must be masked. Otherwise, the other will
be set to 0, then timing settings will be broken.
- The recent IP release expanded the ADDR_2_DATA to 7-bit wide.
This register is related to tADL. As commit 74a332e78e8f ("mtd:
nand: timings: Fix tADL_min for ONFI 4.0 chips") addressed, the
ONFi 4.0 increased the minimum of tADL to 400 nsec. This may not
fit in the 6-bit ADDR_2_DATA in older versions. Check the IP
revision and handle this correctly, otherwise the register value
would wrap around.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-06-13 22:45:37 +09:00
|
|
|
tmp &= ~RE_2_RE__VALUE;
|
2017-09-22 12:46:44 +09:00
|
|
|
tmp |= FIELD_PREP(RE_2_RE__VALUE, re_2_re);
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
sel->re_2_re = tmp;
|
mtd: nand: denali: handle timing parameters by setup_data_interface()
Handling timing parameters in a driver's own way should be avoided
because it duplicates efforts of drivers/mtd/nand/nand_timings.c
Besides, this driver hard-codes Intel specific parameters such as
CLK_X=5, CLK_MULTI=4. Taking a certain device (Samsung K9WAG08U1A)
into account by get_samsung_nand_para() is weird as well.
Now, the core framework provides .setup_data_interface() hook, which
handles timing parameters in a generic manner.
While I am working on this, I found even more issues in the current
code, so fixed the following as well:
- In recent IP versions, WE_2_RE and TWHR2 share the same register.
Likewise for ADDR_2_DATA and TCWAW, CS_SETUP_CNT and TWB. When
updating one, the other must be masked. Otherwise, the other will
be set to 0, then timing settings will be broken.
- The recent IP release expanded the ADDR_2_DATA to 7-bit wide.
This register is related to tADL. As commit 74a332e78e8f ("mtd:
nand: timings: Fix tADL_min for ONFI 4.0 chips") addressed, the
ONFi 4.0 increased the minimum of tADL to 400 nsec. This may not
fit in the 6-bit ADDR_2_DATA in older versions. Check the IP
revision and handle this correctly, otherwise the register value
would wrap around.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-06-13 22:45:37 +09:00
|
|
|
|
2017-09-29 23:12:57 +09:00
|
|
|
/*
|
|
|
|
* tCCS, tWHR -> WE_2_RE
|
|
|
|
*
|
|
|
|
* With WE_2_RE properly set, the Denali controller automatically takes
|
|
|
|
* care of the delay; the driver need not set NAND_WAIT_TCCS.
|
|
|
|
*/
|
2018-06-23 01:06:38 +09:00
|
|
|
we_2_re = DIV_ROUND_UP(max(timings->tCCS_min, timings->tWHR_min), t_x);
|
mtd: nand: denali: handle timing parameters by setup_data_interface()
Handling timing parameters in a driver's own way should be avoided
because it duplicates efforts of drivers/mtd/nand/nand_timings.c
Besides, this driver hard-codes Intel specific parameters such as
CLK_X=5, CLK_MULTI=4. Taking a certain device (Samsung K9WAG08U1A)
into account by get_samsung_nand_para() is weird as well.
Now, the core framework provides .setup_data_interface() hook, which
handles timing parameters in a generic manner.
While I am working on this, I found even more issues in the current
code, so fixed the following as well:
- In recent IP versions, WE_2_RE and TWHR2 share the same register.
Likewise for ADDR_2_DATA and TCWAW, CS_SETUP_CNT and TWB. When
updating one, the other must be masked. Otherwise, the other will
be set to 0, then timing settings will be broken.
- The recent IP release expanded the ADDR_2_DATA to 7-bit wide.
This register is related to tADL. As commit 74a332e78e8f ("mtd:
nand: timings: Fix tADL_min for ONFI 4.0 chips") addressed, the
ONFi 4.0 increased the minimum of tADL to 400 nsec. This may not
fit in the 6-bit ADDR_2_DATA in older versions. Check the IP
revision and handle this correctly, otherwise the register value
would wrap around.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-06-13 22:45:37 +09:00
|
|
|
we_2_re = min_t(int, we_2_re, TWHR2_AND_WE_2_RE__WE_2_RE);
|
|
|
|
|
mtd: nand: denali: avoid magic numbers and rename for clarification
Introduce some macros and helpers to avoid magic numbers and
rename macros/functions for clarification.
- We see '| 2' in several places. This means Data Cycle in MAP11 mode.
The Denali User's Guide says bit[1:0] of MAP11 is like follows:
b'00 = Command Cycle
b'01 = Address Cycle
b'10 = Data Cycle
So, this commit added DENALI_MAP11_{CMD,ADDR,DATA} macros.
- We see 'denali->flash_mem + 0x10' in several places, but 0x10 is a
magic number. Actually, this accesses the data port of the Host
Data/Command Interface. So, this commit added DENALI_HOST_DATA.
On the other hand, 'denali->flash_mem' gets access to the address
port, so DENALI_HOST_ADDR was also added.
- We see 'index_addr(denali, cmd, 0x1)' in denali_erase(), but 0x1
is a magic number. 0x1 means the erase operation. Replace 0x1
with DENALI_ERASE.
- Rename index_addr() to denali_host_write() for clarification
- Denali User's Guide says MAP{00,01,10,11} for access mode. Match
the macros with terminology in the IP document.
- Rename struct members as follows:
flash_bank -> active_bank (currently selected bank)
flash_reg -> reg (base address of registers)
flash_mem -> host (base address of host interface)
devnum -> devs_per_cs (devices connected in parallel)
bbtskipbytes -> oob_skip_bytes (number of bytes to skip in OOB)
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-06-16 14:36:39 +09:00
|
|
|
tmp = ioread32(denali->reg + TWHR2_AND_WE_2_RE);
|
mtd: nand: denali: handle timing parameters by setup_data_interface()
Handling timing parameters in a driver's own way should be avoided
because it duplicates efforts of drivers/mtd/nand/nand_timings.c
Besides, this driver hard-codes Intel specific parameters such as
CLK_X=5, CLK_MULTI=4. Taking a certain device (Samsung K9WAG08U1A)
into account by get_samsung_nand_para() is weird as well.
Now, the core framework provides .setup_data_interface() hook, which
handles timing parameters in a generic manner.
While I am working on this, I found even more issues in the current
code, so fixed the following as well:
- In recent IP versions, WE_2_RE and TWHR2 share the same register.
Likewise for ADDR_2_DATA and TCWAW, CS_SETUP_CNT and TWB. When
updating one, the other must be masked. Otherwise, the other will
be set to 0, then timing settings will be broken.
- The recent IP release expanded the ADDR_2_DATA to 7-bit wide.
This register is related to tADL. As commit 74a332e78e8f ("mtd:
nand: timings: Fix tADL_min for ONFI 4.0 chips") addressed, the
ONFi 4.0 increased the minimum of tADL to 400 nsec. This may not
fit in the 6-bit ADDR_2_DATA in older versions. Check the IP
revision and handle this correctly, otherwise the register value
would wrap around.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-06-13 22:45:37 +09:00
|
|
|
tmp &= ~TWHR2_AND_WE_2_RE__WE_2_RE;
|
2017-09-22 12:46:44 +09:00
|
|
|
tmp |= FIELD_PREP(TWHR2_AND_WE_2_RE__WE_2_RE, we_2_re);
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
sel->hwhr2_and_we_2_re = tmp;
|
mtd: nand: denali: handle timing parameters by setup_data_interface()
Handling timing parameters in a driver's own way should be avoided
because it duplicates efforts of drivers/mtd/nand/nand_timings.c
Besides, this driver hard-codes Intel specific parameters such as
CLK_X=5, CLK_MULTI=4. Taking a certain device (Samsung K9WAG08U1A)
into account by get_samsung_nand_para() is weird as well.
Now, the core framework provides .setup_data_interface() hook, which
handles timing parameters in a generic manner.
While I am working on this, I found even more issues in the current
code, so fixed the following as well:
- In recent IP versions, WE_2_RE and TWHR2 share the same register.
Likewise for ADDR_2_DATA and TCWAW, CS_SETUP_CNT and TWB. When
updating one, the other must be masked. Otherwise, the other will
be set to 0, then timing settings will be broken.
- The recent IP release expanded the ADDR_2_DATA to 7-bit wide.
This register is related to tADL. As commit 74a332e78e8f ("mtd:
nand: timings: Fix tADL_min for ONFI 4.0 chips") addressed, the
ONFi 4.0 increased the minimum of tADL to 400 nsec. This may not
fit in the 6-bit ADDR_2_DATA in older versions. Check the IP
revision and handle this correctly, otherwise the register value
would wrap around.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-06-13 22:45:37 +09:00
|
|
|
|
|
|
|
/* tADL -> ADDR_2_DATA */
|
|
|
|
|
|
|
|
/* for older versions, ADDR_2_DATA is only 6 bit wide */
|
|
|
|
addr_2_data_mask = TCWAW_AND_ADDR_2_DATA__ADDR_2_DATA;
|
|
|
|
if (denali->revision < 0x0501)
|
|
|
|
addr_2_data_mask >>= 1;
|
|
|
|
|
2018-06-23 01:06:38 +09:00
|
|
|
addr_2_data = DIV_ROUND_UP(timings->tADL_min, t_x);
|
mtd: nand: denali: handle timing parameters by setup_data_interface()
Handling timing parameters in a driver's own way should be avoided
because it duplicates efforts of drivers/mtd/nand/nand_timings.c
Besides, this driver hard-codes Intel specific parameters such as
CLK_X=5, CLK_MULTI=4. Taking a certain device (Samsung K9WAG08U1A)
into account by get_samsung_nand_para() is weird as well.
Now, the core framework provides .setup_data_interface() hook, which
handles timing parameters in a generic manner.
While I am working on this, I found even more issues in the current
code, so fixed the following as well:
- In recent IP versions, WE_2_RE and TWHR2 share the same register.
Likewise for ADDR_2_DATA and TCWAW, CS_SETUP_CNT and TWB. When
updating one, the other must be masked. Otherwise, the other will
be set to 0, then timing settings will be broken.
- The recent IP release expanded the ADDR_2_DATA to 7-bit wide.
This register is related to tADL. As commit 74a332e78e8f ("mtd:
nand: timings: Fix tADL_min for ONFI 4.0 chips") addressed, the
ONFi 4.0 increased the minimum of tADL to 400 nsec. This may not
fit in the 6-bit ADDR_2_DATA in older versions. Check the IP
revision and handle this correctly, otherwise the register value
would wrap around.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-06-13 22:45:37 +09:00
|
|
|
addr_2_data = min_t(int, addr_2_data, addr_2_data_mask);
|
|
|
|
|
mtd: nand: denali: avoid magic numbers and rename for clarification
Introduce some macros and helpers to avoid magic numbers and
rename macros/functions for clarification.
- We see '| 2' in several places. This means Data Cycle in MAP11 mode.
The Denali User's Guide says bit[1:0] of MAP11 is like follows:
b'00 = Command Cycle
b'01 = Address Cycle
b'10 = Data Cycle
So, this commit added DENALI_MAP11_{CMD,ADDR,DATA} macros.
- We see 'denali->flash_mem + 0x10' in several places, but 0x10 is a
magic number. Actually, this accesses the data port of the Host
Data/Command Interface. So, this commit added DENALI_HOST_DATA.
On the other hand, 'denali->flash_mem' gets access to the address
port, so DENALI_HOST_ADDR was also added.
- We see 'index_addr(denali, cmd, 0x1)' in denali_erase(), but 0x1
is a magic number. 0x1 means the erase operation. Replace 0x1
with DENALI_ERASE.
- Rename index_addr() to denali_host_write() for clarification
- Denali User's Guide says MAP{00,01,10,11} for access mode. Match
the macros with terminology in the IP document.
- Rename struct members as follows:
flash_bank -> active_bank (currently selected bank)
flash_reg -> reg (base address of registers)
flash_mem -> host (base address of host interface)
devnum -> devs_per_cs (devices connected in parallel)
bbtskipbytes -> oob_skip_bytes (number of bytes to skip in OOB)
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-06-16 14:36:39 +09:00
|
|
|
tmp = ioread32(denali->reg + TCWAW_AND_ADDR_2_DATA);
|
2017-09-22 12:46:44 +09:00
|
|
|
tmp &= ~TCWAW_AND_ADDR_2_DATA__ADDR_2_DATA;
|
|
|
|
tmp |= FIELD_PREP(TCWAW_AND_ADDR_2_DATA__ADDR_2_DATA, addr_2_data);
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
sel->tcwaw_and_addr_2_data = tmp;
|
mtd: nand: denali: handle timing parameters by setup_data_interface()
Handling timing parameters in a driver's own way should be avoided
because it duplicates efforts of drivers/mtd/nand/nand_timings.c
Besides, this driver hard-codes Intel specific parameters such as
CLK_X=5, CLK_MULTI=4. Taking a certain device (Samsung K9WAG08U1A)
into account by get_samsung_nand_para() is weird as well.
Now, the core framework provides .setup_data_interface() hook, which
handles timing parameters in a generic manner.
While I am working on this, I found even more issues in the current
code, so fixed the following as well:
- In recent IP versions, WE_2_RE and TWHR2 share the same register.
Likewise for ADDR_2_DATA and TCWAW, CS_SETUP_CNT and TWB. When
updating one, the other must be masked. Otherwise, the other will
be set to 0, then timing settings will be broken.
- The recent IP release expanded the ADDR_2_DATA to 7-bit wide.
This register is related to tADL. As commit 74a332e78e8f ("mtd:
nand: timings: Fix tADL_min for ONFI 4.0 chips") addressed, the
ONFi 4.0 increased the minimum of tADL to 400 nsec. This may not
fit in the 6-bit ADDR_2_DATA in older versions. Check the IP
revision and handle this correctly, otherwise the register value
would wrap around.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-06-13 22:45:37 +09:00
|
|
|
|
|
|
|
/* tREH, tWH -> RDWR_EN_HI_CNT */
|
|
|
|
rdwr_en_hi = DIV_ROUND_UP(max(timings->tREH_min, timings->tWH_min),
|
2018-06-23 01:06:38 +09:00
|
|
|
t_x);
|
mtd: nand: denali: handle timing parameters by setup_data_interface()
Handling timing parameters in a driver's own way should be avoided
because it duplicates efforts of drivers/mtd/nand/nand_timings.c
Besides, this driver hard-codes Intel specific parameters such as
CLK_X=5, CLK_MULTI=4. Taking a certain device (Samsung K9WAG08U1A)
into account by get_samsung_nand_para() is weird as well.
Now, the core framework provides .setup_data_interface() hook, which
handles timing parameters in a generic manner.
While I am working on this, I found even more issues in the current
code, so fixed the following as well:
- In recent IP versions, WE_2_RE and TWHR2 share the same register.
Likewise for ADDR_2_DATA and TCWAW, CS_SETUP_CNT and TWB. When
updating one, the other must be masked. Otherwise, the other will
be set to 0, then timing settings will be broken.
- The recent IP release expanded the ADDR_2_DATA to 7-bit wide.
This register is related to tADL. As commit 74a332e78e8f ("mtd:
nand: timings: Fix tADL_min for ONFI 4.0 chips") addressed, the
ONFi 4.0 increased the minimum of tADL to 400 nsec. This may not
fit in the 6-bit ADDR_2_DATA in older versions. Check the IP
revision and handle this correctly, otherwise the register value
would wrap around.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-06-13 22:45:37 +09:00
|
|
|
rdwr_en_hi = min_t(int, rdwr_en_hi, RDWR_EN_HI_CNT__VALUE);
|
|
|
|
|
mtd: nand: denali: avoid magic numbers and rename for clarification
Introduce some macros and helpers to avoid magic numbers and
rename macros/functions for clarification.
- We see '| 2' in several places. This means Data Cycle in MAP11 mode.
The Denali User's Guide says bit[1:0] of MAP11 is like follows:
b'00 = Command Cycle
b'01 = Address Cycle
b'10 = Data Cycle
So, this commit added DENALI_MAP11_{CMD,ADDR,DATA} macros.
- We see 'denali->flash_mem + 0x10' in several places, but 0x10 is a
magic number. Actually, this accesses the data port of the Host
Data/Command Interface. So, this commit added DENALI_HOST_DATA.
On the other hand, 'denali->flash_mem' gets access to the address
port, so DENALI_HOST_ADDR was also added.
- We see 'index_addr(denali, cmd, 0x1)' in denali_erase(), but 0x1
is a magic number. 0x1 means the erase operation. Replace 0x1
with DENALI_ERASE.
- Rename index_addr() to denali_host_write() for clarification
- Denali User's Guide says MAP{00,01,10,11} for access mode. Match
the macros with terminology in the IP document.
- Rename struct members as follows:
flash_bank -> active_bank (currently selected bank)
flash_reg -> reg (base address of registers)
flash_mem -> host (base address of host interface)
devnum -> devs_per_cs (devices connected in parallel)
bbtskipbytes -> oob_skip_bytes (number of bytes to skip in OOB)
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-06-16 14:36:39 +09:00
|
|
|
tmp = ioread32(denali->reg + RDWR_EN_HI_CNT);
|
mtd: nand: denali: handle timing parameters by setup_data_interface()
Handling timing parameters in a driver's own way should be avoided
because it duplicates efforts of drivers/mtd/nand/nand_timings.c
Besides, this driver hard-codes Intel specific parameters such as
CLK_X=5, CLK_MULTI=4. Taking a certain device (Samsung K9WAG08U1A)
into account by get_samsung_nand_para() is weird as well.
Now, the core framework provides .setup_data_interface() hook, which
handles timing parameters in a generic manner.
While I am working on this, I found even more issues in the current
code, so fixed the following as well:
- In recent IP versions, WE_2_RE and TWHR2 share the same register.
Likewise for ADDR_2_DATA and TCWAW, CS_SETUP_CNT and TWB. When
updating one, the other must be masked. Otherwise, the other will
be set to 0, then timing settings will be broken.
- The recent IP release expanded the ADDR_2_DATA to 7-bit wide.
This register is related to tADL. As commit 74a332e78e8f ("mtd:
nand: timings: Fix tADL_min for ONFI 4.0 chips") addressed, the
ONFi 4.0 increased the minimum of tADL to 400 nsec. This may not
fit in the 6-bit ADDR_2_DATA in older versions. Check the IP
revision and handle this correctly, otherwise the register value
would wrap around.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-06-13 22:45:37 +09:00
|
|
|
tmp &= ~RDWR_EN_HI_CNT__VALUE;
|
2017-09-22 12:46:44 +09:00
|
|
|
tmp |= FIELD_PREP(RDWR_EN_HI_CNT__VALUE, rdwr_en_hi);
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
sel->rdwr_en_hi_cnt = tmp;
|
mtd: nand: denali: handle timing parameters by setup_data_interface()
Handling timing parameters in a driver's own way should be avoided
because it duplicates efforts of drivers/mtd/nand/nand_timings.c
Besides, this driver hard-codes Intel specific parameters such as
CLK_X=5, CLK_MULTI=4. Taking a certain device (Samsung K9WAG08U1A)
into account by get_samsung_nand_para() is weird as well.
Now, the core framework provides .setup_data_interface() hook, which
handles timing parameters in a generic manner.
While I am working on this, I found even more issues in the current
code, so fixed the following as well:
- In recent IP versions, WE_2_RE and TWHR2 share the same register.
Likewise for ADDR_2_DATA and TCWAW, CS_SETUP_CNT and TWB. When
updating one, the other must be masked. Otherwise, the other will
be set to 0, then timing settings will be broken.
- The recent IP release expanded the ADDR_2_DATA to 7-bit wide.
This register is related to tADL. As commit 74a332e78e8f ("mtd:
nand: timings: Fix tADL_min for ONFI 4.0 chips") addressed, the
ONFi 4.0 increased the minimum of tADL to 400 nsec. This may not
fit in the 6-bit ADDR_2_DATA in older versions. Check the IP
revision and handle this correctly, otherwise the register value
would wrap around.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-06-13 22:45:37 +09:00
|
|
|
|
mtd: rawnand: denali: add more delays before latching incoming data
The Denali IP have several registers to specify how many clock cycles
should be waited between falling/rising signals. You can improve the
NAND access performance by programming these registers with optimized
values.
Because struct nand_sdr_timings represents the device requirement
in pico seconds, denali_setup_data_interface() computes the register
values by dividing the device timings with the clock period.
Marek Vasut reported this driver in the latest kernel does not work
on his SOCFPGA board. (The on-board NAND chip is mode 5)
The suspicious parameter is acc_clks, so this commit relaxes it.
The Denali NAND Flash Memory Controller User's Guide describes this
register as follows:
acc_clks
signifies the number of bus interface clk_x clock cycles,
controller should wait from read enable going low to sending
out a strobe of clk_x for capturing of incoming data.
Currently, acc_clks is calculated only based on tREA, the delay on the
chip side. This does not include additional delays that come from the
data path on the PCB and in the SoC, load capacity of the pins, etc.
This relatively becomes a big factor on faster timing modes like mode 5.
Before supporting the ->setup_data_interface() hook (e.g. Linux 4.12),
the Denali driver hacks acc_clks in a couple of ways [1] [2] to support
the timing mode 5.
We would not go back to the hard-coded acc_clks, but we need to include
this factor into the delay somehow. Let's say the amount of the additional
delay is 10000 pico sec.
In the new calculation, acc_clks is determined by timings->tREA_max +
data_setup_on_host.
Also, prolong the RE# low period to make sure the data hold is met.
Finally, re-center the data latch timing for extra safety.
[1] https://github.com/torvalds/linux/blob/v4.12/drivers/mtd/nand/denali.c#L276
[2] https://github.com/torvalds/linux/blob/v4.12/drivers/mtd/nand/denali.c#L282
Reported-by: Marek Vasut <marex@denx.de>
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Tested-by: Marek Vasut <marex@denx.de>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/linux-mtd/20200317071821.9916-1-yamada.masahiro@socionext.com
2020-03-17 16:18:21 +09:00
|
|
|
/*
|
|
|
|
* tREA -> ACC_CLKS
|
|
|
|
* tRP, tWP, tRHOH, tRC, tWC -> RDWR_EN_LO_CNT
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Determine the minimum of acc_clks to meet the setup timing when
|
|
|
|
* capturing the incoming data.
|
|
|
|
*
|
|
|
|
* The delay on the chip side is well-defined as tREA, but we need to
|
|
|
|
* take additional delay into account. This includes a certain degree
|
|
|
|
* of unknowledge, such as signal propagation delays on the PCB and
|
|
|
|
* in the SoC, load capacity of the I/O pins, etc.
|
|
|
|
*/
|
|
|
|
acc_clks = DIV_ROUND_UP(timings->tREA_max + data_setup_on_host, t_x);
|
|
|
|
|
|
|
|
/* Determine the minimum of rdwr_en_lo_cnt from RE#/WE# pulse width */
|
2018-06-23 01:06:38 +09:00
|
|
|
rdwr_en_lo = DIV_ROUND_UP(max(timings->tRP_min, timings->tWP_min), t_x);
|
mtd: rawnand: denali: add more delays before latching incoming data
The Denali IP have several registers to specify how many clock cycles
should be waited between falling/rising signals. You can improve the
NAND access performance by programming these registers with optimized
values.
Because struct nand_sdr_timings represents the device requirement
in pico seconds, denali_setup_data_interface() computes the register
values by dividing the device timings with the clock period.
Marek Vasut reported this driver in the latest kernel does not work
on his SOCFPGA board. (The on-board NAND chip is mode 5)
The suspicious parameter is acc_clks, so this commit relaxes it.
The Denali NAND Flash Memory Controller User's Guide describes this
register as follows:
acc_clks
signifies the number of bus interface clk_x clock cycles,
controller should wait from read enable going low to sending
out a strobe of clk_x for capturing of incoming data.
Currently, acc_clks is calculated only based on tREA, the delay on the
chip side. This does not include additional delays that come from the
data path on the PCB and in the SoC, load capacity of the pins, etc.
This relatively becomes a big factor on faster timing modes like mode 5.
Before supporting the ->setup_data_interface() hook (e.g. Linux 4.12),
the Denali driver hacks acc_clks in a couple of ways [1] [2] to support
the timing mode 5.
We would not go back to the hard-coded acc_clks, but we need to include
this factor into the delay somehow. Let's say the amount of the additional
delay is 10000 pico sec.
In the new calculation, acc_clks is determined by timings->tREA_max +
data_setup_on_host.
Also, prolong the RE# low period to make sure the data hold is met.
Finally, re-center the data latch timing for extra safety.
[1] https://github.com/torvalds/linux/blob/v4.12/drivers/mtd/nand/denali.c#L276
[2] https://github.com/torvalds/linux/blob/v4.12/drivers/mtd/nand/denali.c#L282
Reported-by: Marek Vasut <marex@denx.de>
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Tested-by: Marek Vasut <marex@denx.de>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/linux-mtd/20200317071821.9916-1-yamada.masahiro@socionext.com
2020-03-17 16:18:21 +09:00
|
|
|
|
|
|
|
/* Extend rdwr_en_lo to meet the data hold timing */
|
|
|
|
rdwr_en_lo = max_t(int, rdwr_en_lo,
|
|
|
|
acc_clks - timings->tRHOH_min / t_x);
|
|
|
|
|
|
|
|
/* Extend rdwr_en_lo to meet the requirement for RE#/WE# cycle time */
|
mtd: nand: denali: handle timing parameters by setup_data_interface()
Handling timing parameters in a driver's own way should be avoided
because it duplicates efforts of drivers/mtd/nand/nand_timings.c
Besides, this driver hard-codes Intel specific parameters such as
CLK_X=5, CLK_MULTI=4. Taking a certain device (Samsung K9WAG08U1A)
into account by get_samsung_nand_para() is weird as well.
Now, the core framework provides .setup_data_interface() hook, which
handles timing parameters in a generic manner.
While I am working on this, I found even more issues in the current
code, so fixed the following as well:
- In recent IP versions, WE_2_RE and TWHR2 share the same register.
Likewise for ADDR_2_DATA and TCWAW, CS_SETUP_CNT and TWB. When
updating one, the other must be masked. Otherwise, the other will
be set to 0, then timing settings will be broken.
- The recent IP release expanded the ADDR_2_DATA to 7-bit wide.
This register is related to tADL. As commit 74a332e78e8f ("mtd:
nand: timings: Fix tADL_min for ONFI 4.0 chips") addressed, the
ONFi 4.0 increased the minimum of tADL to 400 nsec. This may not
fit in the 6-bit ADDR_2_DATA in older versions. Check the IP
revision and handle this correctly, otherwise the register value
would wrap around.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-06-13 22:45:37 +09:00
|
|
|
rdwr_en_lo_hi = DIV_ROUND_UP(max(timings->tRC_min, timings->tWC_min),
|
2018-06-23 01:06:38 +09:00
|
|
|
t_x);
|
mtd: nand: denali: handle timing parameters by setup_data_interface()
Handling timing parameters in a driver's own way should be avoided
because it duplicates efforts of drivers/mtd/nand/nand_timings.c
Besides, this driver hard-codes Intel specific parameters such as
CLK_X=5, CLK_MULTI=4. Taking a certain device (Samsung K9WAG08U1A)
into account by get_samsung_nand_para() is weird as well.
Now, the core framework provides .setup_data_interface() hook, which
handles timing parameters in a generic manner.
While I am working on this, I found even more issues in the current
code, so fixed the following as well:
- In recent IP versions, WE_2_RE and TWHR2 share the same register.
Likewise for ADDR_2_DATA and TCWAW, CS_SETUP_CNT and TWB. When
updating one, the other must be masked. Otherwise, the other will
be set to 0, then timing settings will be broken.
- The recent IP release expanded the ADDR_2_DATA to 7-bit wide.
This register is related to tADL. As commit 74a332e78e8f ("mtd:
nand: timings: Fix tADL_min for ONFI 4.0 chips") addressed, the
ONFi 4.0 increased the minimum of tADL to 400 nsec. This may not
fit in the 6-bit ADDR_2_DATA in older versions. Check the IP
revision and handle this correctly, otherwise the register value
would wrap around.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-06-13 22:45:37 +09:00
|
|
|
rdwr_en_lo = max(rdwr_en_lo, rdwr_en_lo_hi - rdwr_en_hi);
|
|
|
|
rdwr_en_lo = min_t(int, rdwr_en_lo, RDWR_EN_LO_CNT__VALUE);
|
|
|
|
|
mtd: rawnand: denali: add more delays before latching incoming data
The Denali IP have several registers to specify how many clock cycles
should be waited between falling/rising signals. You can improve the
NAND access performance by programming these registers with optimized
values.
Because struct nand_sdr_timings represents the device requirement
in pico seconds, denali_setup_data_interface() computes the register
values by dividing the device timings with the clock period.
Marek Vasut reported this driver in the latest kernel does not work
on his SOCFPGA board. (The on-board NAND chip is mode 5)
The suspicious parameter is acc_clks, so this commit relaxes it.
The Denali NAND Flash Memory Controller User's Guide describes this
register as follows:
acc_clks
signifies the number of bus interface clk_x clock cycles,
controller should wait from read enable going low to sending
out a strobe of clk_x for capturing of incoming data.
Currently, acc_clks is calculated only based on tREA, the delay on the
chip side. This does not include additional delays that come from the
data path on the PCB and in the SoC, load capacity of the pins, etc.
This relatively becomes a big factor on faster timing modes like mode 5.
Before supporting the ->setup_data_interface() hook (e.g. Linux 4.12),
the Denali driver hacks acc_clks in a couple of ways [1] [2] to support
the timing mode 5.
We would not go back to the hard-coded acc_clks, but we need to include
this factor into the delay somehow. Let's say the amount of the additional
delay is 10000 pico sec.
In the new calculation, acc_clks is determined by timings->tREA_max +
data_setup_on_host.
Also, prolong the RE# low period to make sure the data hold is met.
Finally, re-center the data latch timing for extra safety.
[1] https://github.com/torvalds/linux/blob/v4.12/drivers/mtd/nand/denali.c#L276
[2] https://github.com/torvalds/linux/blob/v4.12/drivers/mtd/nand/denali.c#L282
Reported-by: Marek Vasut <marex@denx.de>
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Tested-by: Marek Vasut <marex@denx.de>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/linux-mtd/20200317071821.9916-1-yamada.masahiro@socionext.com
2020-03-17 16:18:21 +09:00
|
|
|
/* Center the data latch timing for extra safety */
|
|
|
|
acc_clks = (acc_clks + rdwr_en_lo +
|
|
|
|
DIV_ROUND_UP(timings->tRHOH_min, t_x)) / 2;
|
|
|
|
acc_clks = min_t(int, acc_clks, ACC_CLKS__VALUE);
|
|
|
|
|
|
|
|
tmp = ioread32(denali->reg + ACC_CLKS);
|
|
|
|
tmp &= ~ACC_CLKS__VALUE;
|
|
|
|
tmp |= FIELD_PREP(ACC_CLKS__VALUE, acc_clks);
|
|
|
|
sel->acc_clks = tmp;
|
|
|
|
|
mtd: nand: denali: avoid magic numbers and rename for clarification
Introduce some macros and helpers to avoid magic numbers and
rename macros/functions for clarification.
- We see '| 2' in several places. This means Data Cycle in MAP11 mode.
The Denali User's Guide says bit[1:0] of MAP11 is like follows:
b'00 = Command Cycle
b'01 = Address Cycle
b'10 = Data Cycle
So, this commit added DENALI_MAP11_{CMD,ADDR,DATA} macros.
- We see 'denali->flash_mem + 0x10' in several places, but 0x10 is a
magic number. Actually, this accesses the data port of the Host
Data/Command Interface. So, this commit added DENALI_HOST_DATA.
On the other hand, 'denali->flash_mem' gets access to the address
port, so DENALI_HOST_ADDR was also added.
- We see 'index_addr(denali, cmd, 0x1)' in denali_erase(), but 0x1
is a magic number. 0x1 means the erase operation. Replace 0x1
with DENALI_ERASE.
- Rename index_addr() to denali_host_write() for clarification
- Denali User's Guide says MAP{00,01,10,11} for access mode. Match
the macros with terminology in the IP document.
- Rename struct members as follows:
flash_bank -> active_bank (currently selected bank)
flash_reg -> reg (base address of registers)
flash_mem -> host (base address of host interface)
devnum -> devs_per_cs (devices connected in parallel)
bbtskipbytes -> oob_skip_bytes (number of bytes to skip in OOB)
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-06-16 14:36:39 +09:00
|
|
|
tmp = ioread32(denali->reg + RDWR_EN_LO_CNT);
|
mtd: nand: denali: handle timing parameters by setup_data_interface()
Handling timing parameters in a driver's own way should be avoided
because it duplicates efforts of drivers/mtd/nand/nand_timings.c
Besides, this driver hard-codes Intel specific parameters such as
CLK_X=5, CLK_MULTI=4. Taking a certain device (Samsung K9WAG08U1A)
into account by get_samsung_nand_para() is weird as well.
Now, the core framework provides .setup_data_interface() hook, which
handles timing parameters in a generic manner.
While I am working on this, I found even more issues in the current
code, so fixed the following as well:
- In recent IP versions, WE_2_RE and TWHR2 share the same register.
Likewise for ADDR_2_DATA and TCWAW, CS_SETUP_CNT and TWB. When
updating one, the other must be masked. Otherwise, the other will
be set to 0, then timing settings will be broken.
- The recent IP release expanded the ADDR_2_DATA to 7-bit wide.
This register is related to tADL. As commit 74a332e78e8f ("mtd:
nand: timings: Fix tADL_min for ONFI 4.0 chips") addressed, the
ONFi 4.0 increased the minimum of tADL to 400 nsec. This may not
fit in the 6-bit ADDR_2_DATA in older versions. Check the IP
revision and handle this correctly, otherwise the register value
would wrap around.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-06-13 22:45:37 +09:00
|
|
|
tmp &= ~RDWR_EN_LO_CNT__VALUE;
|
2017-09-22 12:46:44 +09:00
|
|
|
tmp |= FIELD_PREP(RDWR_EN_LO_CNT__VALUE, rdwr_en_lo);
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
sel->rdwr_en_lo_cnt = tmp;
|
mtd: nand: denali: handle timing parameters by setup_data_interface()
Handling timing parameters in a driver's own way should be avoided
because it duplicates efforts of drivers/mtd/nand/nand_timings.c
Besides, this driver hard-codes Intel specific parameters such as
CLK_X=5, CLK_MULTI=4. Taking a certain device (Samsung K9WAG08U1A)
into account by get_samsung_nand_para() is weird as well.
Now, the core framework provides .setup_data_interface() hook, which
handles timing parameters in a generic manner.
While I am working on this, I found even more issues in the current
code, so fixed the following as well:
- In recent IP versions, WE_2_RE and TWHR2 share the same register.
Likewise for ADDR_2_DATA and TCWAW, CS_SETUP_CNT and TWB. When
updating one, the other must be masked. Otherwise, the other will
be set to 0, then timing settings will be broken.
- The recent IP release expanded the ADDR_2_DATA to 7-bit wide.
This register is related to tADL. As commit 74a332e78e8f ("mtd:
nand: timings: Fix tADL_min for ONFI 4.0 chips") addressed, the
ONFi 4.0 increased the minimum of tADL to 400 nsec. This may not
fit in the 6-bit ADDR_2_DATA in older versions. Check the IP
revision and handle this correctly, otherwise the register value
would wrap around.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-06-13 22:45:37 +09:00
|
|
|
|
|
|
|
/* tCS, tCEA -> CS_SETUP_CNT */
|
2018-06-23 01:06:38 +09:00
|
|
|
cs_setup = max3((int)DIV_ROUND_UP(timings->tCS_min, t_x) - rdwr_en_lo,
|
|
|
|
(int)DIV_ROUND_UP(timings->tCEA_max, t_x) - acc_clks,
|
mtd: nand: denali: handle timing parameters by setup_data_interface()
Handling timing parameters in a driver's own way should be avoided
because it duplicates efforts of drivers/mtd/nand/nand_timings.c
Besides, this driver hard-codes Intel specific parameters such as
CLK_X=5, CLK_MULTI=4. Taking a certain device (Samsung K9WAG08U1A)
into account by get_samsung_nand_para() is weird as well.
Now, the core framework provides .setup_data_interface() hook, which
handles timing parameters in a generic manner.
While I am working on this, I found even more issues in the current
code, so fixed the following as well:
- In recent IP versions, WE_2_RE and TWHR2 share the same register.
Likewise for ADDR_2_DATA and TCWAW, CS_SETUP_CNT and TWB. When
updating one, the other must be masked. Otherwise, the other will
be set to 0, then timing settings will be broken.
- The recent IP release expanded the ADDR_2_DATA to 7-bit wide.
This register is related to tADL. As commit 74a332e78e8f ("mtd:
nand: timings: Fix tADL_min for ONFI 4.0 chips") addressed, the
ONFi 4.0 increased the minimum of tADL to 400 nsec. This may not
fit in the 6-bit ADDR_2_DATA in older versions. Check the IP
revision and handle this correctly, otherwise the register value
would wrap around.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-06-13 22:45:37 +09:00
|
|
|
0);
|
|
|
|
cs_setup = min_t(int, cs_setup, CS_SETUP_CNT__VALUE);
|
|
|
|
|
mtd: nand: denali: avoid magic numbers and rename for clarification
Introduce some macros and helpers to avoid magic numbers and
rename macros/functions for clarification.
- We see '| 2' in several places. This means Data Cycle in MAP11 mode.
The Denali User's Guide says bit[1:0] of MAP11 is like follows:
b'00 = Command Cycle
b'01 = Address Cycle
b'10 = Data Cycle
So, this commit added DENALI_MAP11_{CMD,ADDR,DATA} macros.
- We see 'denali->flash_mem + 0x10' in several places, but 0x10 is a
magic number. Actually, this accesses the data port of the Host
Data/Command Interface. So, this commit added DENALI_HOST_DATA.
On the other hand, 'denali->flash_mem' gets access to the address
port, so DENALI_HOST_ADDR was also added.
- We see 'index_addr(denali, cmd, 0x1)' in denali_erase(), but 0x1
is a magic number. 0x1 means the erase operation. Replace 0x1
with DENALI_ERASE.
- Rename index_addr() to denali_host_write() for clarification
- Denali User's Guide says MAP{00,01,10,11} for access mode. Match
the macros with terminology in the IP document.
- Rename struct members as follows:
flash_bank -> active_bank (currently selected bank)
flash_reg -> reg (base address of registers)
flash_mem -> host (base address of host interface)
devnum -> devs_per_cs (devices connected in parallel)
bbtskipbytes -> oob_skip_bytes (number of bytes to skip in OOB)
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-06-16 14:36:39 +09:00
|
|
|
tmp = ioread32(denali->reg + CS_SETUP_CNT);
|
mtd: nand: denali: handle timing parameters by setup_data_interface()
Handling timing parameters in a driver's own way should be avoided
because it duplicates efforts of drivers/mtd/nand/nand_timings.c
Besides, this driver hard-codes Intel specific parameters such as
CLK_X=5, CLK_MULTI=4. Taking a certain device (Samsung K9WAG08U1A)
into account by get_samsung_nand_para() is weird as well.
Now, the core framework provides .setup_data_interface() hook, which
handles timing parameters in a generic manner.
While I am working on this, I found even more issues in the current
code, so fixed the following as well:
- In recent IP versions, WE_2_RE and TWHR2 share the same register.
Likewise for ADDR_2_DATA and TCWAW, CS_SETUP_CNT and TWB. When
updating one, the other must be masked. Otherwise, the other will
be set to 0, then timing settings will be broken.
- The recent IP release expanded the ADDR_2_DATA to 7-bit wide.
This register is related to tADL. As commit 74a332e78e8f ("mtd:
nand: timings: Fix tADL_min for ONFI 4.0 chips") addressed, the
ONFi 4.0 increased the minimum of tADL to 400 nsec. This may not
fit in the 6-bit ADDR_2_DATA in older versions. Check the IP
revision and handle this correctly, otherwise the register value
would wrap around.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-06-13 22:45:37 +09:00
|
|
|
tmp &= ~CS_SETUP_CNT__VALUE;
|
2017-09-22 12:46:44 +09:00
|
|
|
tmp |= FIELD_PREP(CS_SETUP_CNT__VALUE, cs_setup);
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
sel->cs_setup_cnt = tmp;
|
mtd: nand: denali: handle timing parameters by setup_data_interface()
Handling timing parameters in a driver's own way should be avoided
because it duplicates efforts of drivers/mtd/nand/nand_timings.c
Besides, this driver hard-codes Intel specific parameters such as
CLK_X=5, CLK_MULTI=4. Taking a certain device (Samsung K9WAG08U1A)
into account by get_samsung_nand_para() is weird as well.
Now, the core framework provides .setup_data_interface() hook, which
handles timing parameters in a generic manner.
While I am working on this, I found even more issues in the current
code, so fixed the following as well:
- In recent IP versions, WE_2_RE and TWHR2 share the same register.
Likewise for ADDR_2_DATA and TCWAW, CS_SETUP_CNT and TWB. When
updating one, the other must be masked. Otherwise, the other will
be set to 0, then timing settings will be broken.
- The recent IP release expanded the ADDR_2_DATA to 7-bit wide.
This register is related to tADL. As commit 74a332e78e8f ("mtd:
nand: timings: Fix tADL_min for ONFI 4.0 chips") addressed, the
ONFi 4.0 increased the minimum of tADL to 400 nsec. This may not
fit in the 6-bit ADDR_2_DATA in older versions. Check the IP
revision and handle this correctly, otherwise the register value
would wrap around.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-06-13 22:45:37 +09:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2010-05-13 15:57:33 +01:00
|
|
|
|
mtd: nand: denali: avoid hard-coding ECC step, strength, bytes
This driver was originally written for the Intel MRST platform with
several platform-specific parameters hard-coded.
Currently, the ECC settings are hard-coded as follows:
#define ECC_SECTOR_SIZE 512
#define ECC_8BITS 14
#define ECC_15BITS 26
Therefore, the driver can only support two cases.
- ecc.size = 512, ecc.strength = 8 --> ecc.bytes = 14
- ecc.size = 512, ecc.strength = 15 --> ecc.bytes = 26
However, these are actually customizable parameters, for example,
UniPhier platform supports the following:
- ecc.size = 1024, ecc.strength = 8 --> ecc.bytes = 14
- ecc.size = 1024, ecc.strength = 16 --> ecc.bytes = 28
- ecc.size = 1024, ecc.strength = 24 --> ecc.bytes = 42
So, we need to handle the ECC parameters in a more generic manner.
Fortunately, the Denali User's Guide explains how to calculate the
ecc.bytes. The formula is:
ecc.bytes = 2 * CEIL(13 * ecc.strength / 16) (for ecc.size = 512)
ecc.bytes = 2 * CEIL(14 * ecc.strength / 16) (for ecc.size = 1024)
For DT platforms, it would be reasonable to allow DT to specify ECC
strength by either "nand-ecc-strength" or "nand-ecc-maximize". If
none of them is specified, the driver will try to meet the chip's ECC
requirement.
For PCI platforms, the max ECC strength is used to keep the original
behavior.
Newer versions of this IP need ecc.size and ecc.steps explicitly
set up via the following registers:
CFG_DATA_BLOCK_SIZE (0x6b0)
CFG_LAST_DATA_BLOCK_SIZE (0x6c0)
CFG_NUM_DATA_BLOCKS (0x6d0)
For older IP versions, write accesses to these registers are just
ignored.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-06-07 20:52:12 +09:00
|
|
|
int denali_calc_ecc_bytes(int step_size, int strength)
|
|
|
|
{
|
|
|
|
/* BCH code. Denali requires ecc.bytes to be multiple of 2 */
|
|
|
|
return DIV_ROUND_UP(strength * fls(step_size * 8), 16) * 2;
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL(denali_calc_ecc_bytes);
|
|
|
|
|
2016-02-03 20:00:11 +01:00
|
|
|
static int denali_ooblayout_ecc(struct mtd_info *mtd, int section,
|
|
|
|
struct mtd_oob_region *oobregion)
|
|
|
|
{
|
|
|
|
struct nand_chip *chip = mtd_to_nand(mtd);
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
struct denali_controller *denali = to_denali_controller(chip);
|
2016-02-03 20:00:11 +01:00
|
|
|
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
if (section > 0)
|
2016-02-03 20:00:11 +01:00
|
|
|
return -ERANGE;
|
|
|
|
|
mtd: nand: denali: avoid magic numbers and rename for clarification
Introduce some macros and helpers to avoid magic numbers and
rename macros/functions for clarification.
- We see '| 2' in several places. This means Data Cycle in MAP11 mode.
The Denali User's Guide says bit[1:0] of MAP11 is like follows:
b'00 = Command Cycle
b'01 = Address Cycle
b'10 = Data Cycle
So, this commit added DENALI_MAP11_{CMD,ADDR,DATA} macros.
- We see 'denali->flash_mem + 0x10' in several places, but 0x10 is a
magic number. Actually, this accesses the data port of the Host
Data/Command Interface. So, this commit added DENALI_HOST_DATA.
On the other hand, 'denali->flash_mem' gets access to the address
port, so DENALI_HOST_ADDR was also added.
- We see 'index_addr(denali, cmd, 0x1)' in denali_erase(), but 0x1
is a magic number. 0x1 means the erase operation. Replace 0x1
with DENALI_ERASE.
- Rename index_addr() to denali_host_write() for clarification
- Denali User's Guide says MAP{00,01,10,11} for access mode. Match
the macros with terminology in the IP document.
- Rename struct members as follows:
flash_bank -> active_bank (currently selected bank)
flash_reg -> reg (base address of registers)
flash_mem -> host (base address of host interface)
devnum -> devs_per_cs (devices connected in parallel)
bbtskipbytes -> oob_skip_bytes (number of bytes to skip in OOB)
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-06-16 14:36:39 +09:00
|
|
|
oobregion->offset = denali->oob_skip_bytes;
|
2016-02-03 20:00:11 +01:00
|
|
|
oobregion->length = chip->ecc.total;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int denali_ooblayout_free(struct mtd_info *mtd, int section,
|
|
|
|
struct mtd_oob_region *oobregion)
|
|
|
|
{
|
|
|
|
struct nand_chip *chip = mtd_to_nand(mtd);
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
struct denali_controller *denali = to_denali_controller(chip);
|
2016-02-03 20:00:11 +01:00
|
|
|
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
if (section > 0)
|
2016-02-03 20:00:11 +01:00
|
|
|
return -ERANGE;
|
|
|
|
|
mtd: nand: denali: avoid magic numbers and rename for clarification
Introduce some macros and helpers to avoid magic numbers and
rename macros/functions for clarification.
- We see '| 2' in several places. This means Data Cycle in MAP11 mode.
The Denali User's Guide says bit[1:0] of MAP11 is like follows:
b'00 = Command Cycle
b'01 = Address Cycle
b'10 = Data Cycle
So, this commit added DENALI_MAP11_{CMD,ADDR,DATA} macros.
- We see 'denali->flash_mem + 0x10' in several places, but 0x10 is a
magic number. Actually, this accesses the data port of the Host
Data/Command Interface. So, this commit added DENALI_HOST_DATA.
On the other hand, 'denali->flash_mem' gets access to the address
port, so DENALI_HOST_ADDR was also added.
- We see 'index_addr(denali, cmd, 0x1)' in denali_erase(), but 0x1
is a magic number. 0x1 means the erase operation. Replace 0x1
with DENALI_ERASE.
- Rename index_addr() to denali_host_write() for clarification
- Denali User's Guide says MAP{00,01,10,11} for access mode. Match
the macros with terminology in the IP document.
- Rename struct members as follows:
flash_bank -> active_bank (currently selected bank)
flash_reg -> reg (base address of registers)
flash_mem -> host (base address of host interface)
devnum -> devs_per_cs (devices connected in parallel)
bbtskipbytes -> oob_skip_bytes (number of bytes to skip in OOB)
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-06-16 14:36:39 +09:00
|
|
|
oobregion->offset = chip->ecc.total + denali->oob_skip_bytes;
|
2016-02-03 20:00:11 +01:00
|
|
|
oobregion->length = mtd->oobsize - oobregion->offset;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const struct mtd_ooblayout_ops denali_ooblayout_ops = {
|
|
|
|
.ecc = denali_ooblayout_ecc,
|
|
|
|
.free = denali_ooblayout_free,
|
2010-05-13 15:57:33 +01:00
|
|
|
};
|
|
|
|
|
2019-04-02 13:03:01 +09:00
|
|
|
static int denali_multidev_fixup(struct nand_chip *chip)
|
2017-03-23 05:07:20 +09:00
|
|
|
{
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
struct denali_controller *denali = to_denali_controller(chip);
|
2017-03-23 05:07:20 +09:00
|
|
|
struct mtd_info *mtd = nand_to_mtd(chip);
|
2018-10-25 17:10:37 +02:00
|
|
|
struct nand_memory_organization *memorg;
|
|
|
|
|
|
|
|
memorg = nanddev_get_memorg(&chip->base);
|
2017-03-23 05:07:20 +09:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Support for multi device:
|
|
|
|
* When the IP configuration is x16 capable and two x8 chips are
|
|
|
|
* connected in parallel, DEVICES_CONNECTED should be set to 2.
|
|
|
|
* In this case, the core framework knows nothing about this fact,
|
|
|
|
* so we should tell it the _logical_ pagesize and anything necessary.
|
|
|
|
*/
|
mtd: nand: denali: avoid magic numbers and rename for clarification
Introduce some macros and helpers to avoid magic numbers and
rename macros/functions for clarification.
- We see '| 2' in several places. This means Data Cycle in MAP11 mode.
The Denali User's Guide says bit[1:0] of MAP11 is like follows:
b'00 = Command Cycle
b'01 = Address Cycle
b'10 = Data Cycle
So, this commit added DENALI_MAP11_{CMD,ADDR,DATA} macros.
- We see 'denali->flash_mem + 0x10' in several places, but 0x10 is a
magic number. Actually, this accesses the data port of the Host
Data/Command Interface. So, this commit added DENALI_HOST_DATA.
On the other hand, 'denali->flash_mem' gets access to the address
port, so DENALI_HOST_ADDR was also added.
- We see 'index_addr(denali, cmd, 0x1)' in denali_erase(), but 0x1
is a magic number. 0x1 means the erase operation. Replace 0x1
with DENALI_ERASE.
- Rename index_addr() to denali_host_write() for clarification
- Denali User's Guide says MAP{00,01,10,11} for access mode. Match
the macros with terminology in the IP document.
- Rename struct members as follows:
flash_bank -> active_bank (currently selected bank)
flash_reg -> reg (base address of registers)
flash_mem -> host (base address of host interface)
devnum -> devs_per_cs (devices connected in parallel)
bbtskipbytes -> oob_skip_bytes (number of bytes to skip in OOB)
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-06-16 14:36:39 +09:00
|
|
|
denali->devs_per_cs = ioread32(denali->reg + DEVICES_CONNECTED);
|
2017-03-23 05:07:20 +09:00
|
|
|
|
2017-03-23 05:07:22 +09:00
|
|
|
/*
|
|
|
|
* On some SoCs, DEVICES_CONNECTED is not auto-detected.
|
|
|
|
* For those, DEVICES_CONNECTED is left to 0. Set 1 if it is the case.
|
|
|
|
*/
|
mtd: nand: denali: avoid magic numbers and rename for clarification
Introduce some macros and helpers to avoid magic numbers and
rename macros/functions for clarification.
- We see '| 2' in several places. This means Data Cycle in MAP11 mode.
The Denali User's Guide says bit[1:0] of MAP11 is like follows:
b'00 = Command Cycle
b'01 = Address Cycle
b'10 = Data Cycle
So, this commit added DENALI_MAP11_{CMD,ADDR,DATA} macros.
- We see 'denali->flash_mem + 0x10' in several places, but 0x10 is a
magic number. Actually, this accesses the data port of the Host
Data/Command Interface. So, this commit added DENALI_HOST_DATA.
On the other hand, 'denali->flash_mem' gets access to the address
port, so DENALI_HOST_ADDR was also added.
- We see 'index_addr(denali, cmd, 0x1)' in denali_erase(), but 0x1
is a magic number. 0x1 means the erase operation. Replace 0x1
with DENALI_ERASE.
- Rename index_addr() to denali_host_write() for clarification
- Denali User's Guide says MAP{00,01,10,11} for access mode. Match
the macros with terminology in the IP document.
- Rename struct members as follows:
flash_bank -> active_bank (currently selected bank)
flash_reg -> reg (base address of registers)
flash_mem -> host (base address of host interface)
devnum -> devs_per_cs (devices connected in parallel)
bbtskipbytes -> oob_skip_bytes (number of bytes to skip in OOB)
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-06-16 14:36:39 +09:00
|
|
|
if (denali->devs_per_cs == 0) {
|
|
|
|
denali->devs_per_cs = 1;
|
|
|
|
iowrite32(1, denali->reg + DEVICES_CONNECTED);
|
2017-03-23 05:07:22 +09:00
|
|
|
}
|
|
|
|
|
mtd: nand: denali: avoid magic numbers and rename for clarification
Introduce some macros and helpers to avoid magic numbers and
rename macros/functions for clarification.
- We see '| 2' in several places. This means Data Cycle in MAP11 mode.
The Denali User's Guide says bit[1:0] of MAP11 is like follows:
b'00 = Command Cycle
b'01 = Address Cycle
b'10 = Data Cycle
So, this commit added DENALI_MAP11_{CMD,ADDR,DATA} macros.
- We see 'denali->flash_mem + 0x10' in several places, but 0x10 is a
magic number. Actually, this accesses the data port of the Host
Data/Command Interface. So, this commit added DENALI_HOST_DATA.
On the other hand, 'denali->flash_mem' gets access to the address
port, so DENALI_HOST_ADDR was also added.
- We see 'index_addr(denali, cmd, 0x1)' in denali_erase(), but 0x1
is a magic number. 0x1 means the erase operation. Replace 0x1
with DENALI_ERASE.
- Rename index_addr() to denali_host_write() for clarification
- Denali User's Guide says MAP{00,01,10,11} for access mode. Match
the macros with terminology in the IP document.
- Rename struct members as follows:
flash_bank -> active_bank (currently selected bank)
flash_reg -> reg (base address of registers)
flash_mem -> host (base address of host interface)
devnum -> devs_per_cs (devices connected in parallel)
bbtskipbytes -> oob_skip_bytes (number of bytes to skip in OOB)
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-06-16 14:36:39 +09:00
|
|
|
if (denali->devs_per_cs == 1)
|
2017-03-23 05:07:21 +09:00
|
|
|
return 0;
|
|
|
|
|
mtd: nand: denali: avoid magic numbers and rename for clarification
Introduce some macros and helpers to avoid magic numbers and
rename macros/functions for clarification.
- We see '| 2' in several places. This means Data Cycle in MAP11 mode.
The Denali User's Guide says bit[1:0] of MAP11 is like follows:
b'00 = Command Cycle
b'01 = Address Cycle
b'10 = Data Cycle
So, this commit added DENALI_MAP11_{CMD,ADDR,DATA} macros.
- We see 'denali->flash_mem + 0x10' in several places, but 0x10 is a
magic number. Actually, this accesses the data port of the Host
Data/Command Interface. So, this commit added DENALI_HOST_DATA.
On the other hand, 'denali->flash_mem' gets access to the address
port, so DENALI_HOST_ADDR was also added.
- We see 'index_addr(denali, cmd, 0x1)' in denali_erase(), but 0x1
is a magic number. 0x1 means the erase operation. Replace 0x1
with DENALI_ERASE.
- Rename index_addr() to denali_host_write() for clarification
- Denali User's Guide says MAP{00,01,10,11} for access mode. Match
the macros with terminology in the IP document.
- Rename struct members as follows:
flash_bank -> active_bank (currently selected bank)
flash_reg -> reg (base address of registers)
flash_mem -> host (base address of host interface)
devnum -> devs_per_cs (devices connected in parallel)
bbtskipbytes -> oob_skip_bytes (number of bytes to skip in OOB)
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-06-16 14:36:39 +09:00
|
|
|
if (denali->devs_per_cs != 2) {
|
2017-03-23 05:07:21 +09:00
|
|
|
dev_err(denali->dev, "unsupported number of devices %d\n",
|
mtd: nand: denali: avoid magic numbers and rename for clarification
Introduce some macros and helpers to avoid magic numbers and
rename macros/functions for clarification.
- We see '| 2' in several places. This means Data Cycle in MAP11 mode.
The Denali User's Guide says bit[1:0] of MAP11 is like follows:
b'00 = Command Cycle
b'01 = Address Cycle
b'10 = Data Cycle
So, this commit added DENALI_MAP11_{CMD,ADDR,DATA} macros.
- We see 'denali->flash_mem + 0x10' in several places, but 0x10 is a
magic number. Actually, this accesses the data port of the Host
Data/Command Interface. So, this commit added DENALI_HOST_DATA.
On the other hand, 'denali->flash_mem' gets access to the address
port, so DENALI_HOST_ADDR was also added.
- We see 'index_addr(denali, cmd, 0x1)' in denali_erase(), but 0x1
is a magic number. 0x1 means the erase operation. Replace 0x1
with DENALI_ERASE.
- Rename index_addr() to denali_host_write() for clarification
- Denali User's Guide says MAP{00,01,10,11} for access mode. Match
the macros with terminology in the IP document.
- Rename struct members as follows:
flash_bank -> active_bank (currently selected bank)
flash_reg -> reg (base address of registers)
flash_mem -> host (base address of host interface)
devnum -> devs_per_cs (devices connected in parallel)
bbtskipbytes -> oob_skip_bytes (number of bytes to skip in OOB)
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-06-16 14:36:39 +09:00
|
|
|
denali->devs_per_cs);
|
2017-03-23 05:07:21 +09:00
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* 2 chips in parallel */
|
2018-10-25 17:10:37 +02:00
|
|
|
memorg->pagesize <<= 1;
|
|
|
|
memorg->oobsize <<= 1;
|
2017-03-23 05:07:21 +09:00
|
|
|
mtd->size <<= 1;
|
|
|
|
mtd->erasesize <<= 1;
|
|
|
|
mtd->writesize <<= 1;
|
|
|
|
mtd->oobsize <<= 1;
|
|
|
|
chip->page_shift += 1;
|
|
|
|
chip->phys_erase_shift += 1;
|
|
|
|
chip->bbt_erase_shift += 1;
|
|
|
|
chip->chip_shift += 1;
|
|
|
|
chip->pagemask <<= 1;
|
|
|
|
chip->ecc.size <<= 1;
|
|
|
|
chip->ecc.bytes <<= 1;
|
|
|
|
chip->ecc.strength <<= 1;
|
mtd: nand: denali: avoid magic numbers and rename for clarification
Introduce some macros and helpers to avoid magic numbers and
rename macros/functions for clarification.
- We see '| 2' in several places. This means Data Cycle in MAP11 mode.
The Denali User's Guide says bit[1:0] of MAP11 is like follows:
b'00 = Command Cycle
b'01 = Address Cycle
b'10 = Data Cycle
So, this commit added DENALI_MAP11_{CMD,ADDR,DATA} macros.
- We see 'denali->flash_mem + 0x10' in several places, but 0x10 is a
magic number. Actually, this accesses the data port of the Host
Data/Command Interface. So, this commit added DENALI_HOST_DATA.
On the other hand, 'denali->flash_mem' gets access to the address
port, so DENALI_HOST_ADDR was also added.
- We see 'index_addr(denali, cmd, 0x1)' in denali_erase(), but 0x1
is a magic number. 0x1 means the erase operation. Replace 0x1
with DENALI_ERASE.
- Rename index_addr() to denali_host_write() for clarification
- Denali User's Guide says MAP{00,01,10,11} for access mode. Match
the macros with terminology in the IP document.
- Rename struct members as follows:
flash_bank -> active_bank (currently selected bank)
flash_reg -> reg (base address of registers)
flash_mem -> host (base address of host interface)
devnum -> devs_per_cs (devices connected in parallel)
bbtskipbytes -> oob_skip_bytes (number of bytes to skip in OOB)
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-06-16 14:36:39 +09:00
|
|
|
denali->oob_skip_bytes <<= 1;
|
2017-03-23 05:07:21 +09:00
|
|
|
|
|
|
|
return 0;
|
2017-03-23 05:07:20 +09:00
|
|
|
}
|
|
|
|
|
2018-07-20 17:14:56 +02:00
|
|
|
static int denali_attach_chip(struct nand_chip *chip)
|
2010-05-13 15:57:33 +01:00
|
|
|
{
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
struct denali_controller *denali = to_denali_controller(chip);
|
2017-03-23 05:07:17 +09:00
|
|
|
struct mtd_info *mtd = nand_to_mtd(chip);
|
2012-09-27 10:58:05 -06:00
|
|
|
int ret;
|
2010-05-13 15:57:33 +01:00
|
|
|
|
2018-06-20 12:57:29 +05:30
|
|
|
ret = nand_ecc_choose_conf(chip, denali->ecc_caps,
|
|
|
|
mtd->oobsize - denali->oob_skip_bytes);
|
mtd: nand: denali: avoid hard-coding ECC step, strength, bytes
This driver was originally written for the Intel MRST platform with
several platform-specific parameters hard-coded.
Currently, the ECC settings are hard-coded as follows:
#define ECC_SECTOR_SIZE 512
#define ECC_8BITS 14
#define ECC_15BITS 26
Therefore, the driver can only support two cases.
- ecc.size = 512, ecc.strength = 8 --> ecc.bytes = 14
- ecc.size = 512, ecc.strength = 15 --> ecc.bytes = 26
However, these are actually customizable parameters, for example,
UniPhier platform supports the following:
- ecc.size = 1024, ecc.strength = 8 --> ecc.bytes = 14
- ecc.size = 1024, ecc.strength = 16 --> ecc.bytes = 28
- ecc.size = 1024, ecc.strength = 24 --> ecc.bytes = 42
So, we need to handle the ECC parameters in a more generic manner.
Fortunately, the Denali User's Guide explains how to calculate the
ecc.bytes. The formula is:
ecc.bytes = 2 * CEIL(13 * ecc.strength / 16) (for ecc.size = 512)
ecc.bytes = 2 * CEIL(14 * ecc.strength / 16) (for ecc.size = 1024)
For DT platforms, it would be reasonable to allow DT to specify ECC
strength by either "nand-ecc-strength" or "nand-ecc-maximize". If
none of them is specified, the driver will try to meet the chip's ECC
requirement.
For PCI platforms, the max ECC strength is used to keep the original
behavior.
Newer versions of this IP need ecc.size and ecc.steps explicitly
set up via the following registers:
CFG_DATA_BLOCK_SIZE (0x6b0)
CFG_LAST_DATA_BLOCK_SIZE (0x6c0)
CFG_NUM_DATA_BLOCKS (0x6d0)
For older IP versions, write accesses to these registers are just
ignored.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-06-07 20:52:12 +09:00
|
|
|
if (ret) {
|
|
|
|
dev_err(denali->dev, "Failed to setup ECC settings.\n");
|
2018-07-20 17:14:56 +02:00
|
|
|
return ret;
|
2010-05-13 15:57:33 +01:00
|
|
|
}
|
|
|
|
|
mtd: nand: denali: avoid hard-coding ECC step, strength, bytes
This driver was originally written for the Intel MRST platform with
several platform-specific parameters hard-coded.
Currently, the ECC settings are hard-coded as follows:
#define ECC_SECTOR_SIZE 512
#define ECC_8BITS 14
#define ECC_15BITS 26
Therefore, the driver can only support two cases.
- ecc.size = 512, ecc.strength = 8 --> ecc.bytes = 14
- ecc.size = 512, ecc.strength = 15 --> ecc.bytes = 26
However, these are actually customizable parameters, for example,
UniPhier platform supports the following:
- ecc.size = 1024, ecc.strength = 8 --> ecc.bytes = 14
- ecc.size = 1024, ecc.strength = 16 --> ecc.bytes = 28
- ecc.size = 1024, ecc.strength = 24 --> ecc.bytes = 42
So, we need to handle the ECC parameters in a more generic manner.
Fortunately, the Denali User's Guide explains how to calculate the
ecc.bytes. The formula is:
ecc.bytes = 2 * CEIL(13 * ecc.strength / 16) (for ecc.size = 512)
ecc.bytes = 2 * CEIL(14 * ecc.strength / 16) (for ecc.size = 1024)
For DT platforms, it would be reasonable to allow DT to specify ECC
strength by either "nand-ecc-strength" or "nand-ecc-maximize". If
none of them is specified, the driver will try to meet the chip's ECC
requirement.
For PCI platforms, the max ECC strength is used to keep the original
behavior.
Newer versions of this IP need ecc.size and ecc.steps explicitly
set up via the following registers:
CFG_DATA_BLOCK_SIZE (0x6b0)
CFG_LAST_DATA_BLOCK_SIZE (0x6c0)
CFG_NUM_DATA_BLOCKS (0x6d0)
For older IP versions, write accesses to these registers are just
ignored.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-06-07 20:52:12 +09:00
|
|
|
dev_dbg(denali->dev,
|
|
|
|
"chosen ECC settings: step=%d, strength=%d, bytes=%d\n",
|
|
|
|
chip->ecc.size, chip->ecc.strength, chip->ecc.bytes);
|
|
|
|
|
2019-04-02 13:03:01 +09:00
|
|
|
ret = denali_multidev_fixup(chip);
|
2017-03-23 05:07:21 +09:00
|
|
|
if (ret)
|
2018-07-20 17:14:56 +02:00
|
|
|
return ret;
|
2017-03-23 05:07:20 +09:00
|
|
|
|
2018-07-20 17:14:56 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
static void denali_exec_in8(struct denali_controller *denali, u32 type,
|
2019-04-02 13:03:04 +09:00
|
|
|
u8 *buf, unsigned int len)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < len; i++)
|
|
|
|
buf[i] = denali->host_read(denali, type | DENALI_BANK(denali));
|
|
|
|
}
|
|
|
|
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
static void denali_exec_in16(struct denali_controller *denali, u32 type,
|
2019-04-02 13:03:04 +09:00
|
|
|
u8 *buf, unsigned int len)
|
|
|
|
{
|
|
|
|
u32 data;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < len; i += 2) {
|
|
|
|
data = denali->host_read(denali, type | DENALI_BANK(denali));
|
|
|
|
/* bit 31:24 and 15:8 are used for DDR */
|
|
|
|
buf[i] = data;
|
|
|
|
buf[i + 1] = data >> 16;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
static void denali_exec_in(struct denali_controller *denali, u32 type,
|
2019-04-02 13:03:04 +09:00
|
|
|
u8 *buf, unsigned int len, bool width16)
|
|
|
|
{
|
|
|
|
if (width16)
|
|
|
|
denali_exec_in16(denali, type, buf, len);
|
|
|
|
else
|
|
|
|
denali_exec_in8(denali, type, buf, len);
|
|
|
|
}
|
|
|
|
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
static void denali_exec_out8(struct denali_controller *denali, u32 type,
|
2019-04-02 13:03:04 +09:00
|
|
|
const u8 *buf, unsigned int len)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < len; i++)
|
|
|
|
denali->host_write(denali, type | DENALI_BANK(denali), buf[i]);
|
|
|
|
}
|
|
|
|
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
static void denali_exec_out16(struct denali_controller *denali, u32 type,
|
2019-04-02 13:03:04 +09:00
|
|
|
const u8 *buf, unsigned int len)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < len; i += 2)
|
|
|
|
denali->host_write(denali, type | DENALI_BANK(denali),
|
|
|
|
buf[i + 1] << 16 | buf[i]);
|
|
|
|
}
|
|
|
|
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
static void denali_exec_out(struct denali_controller *denali, u32 type,
|
2019-04-02 13:03:04 +09:00
|
|
|
const u8 *buf, unsigned int len, bool width16)
|
|
|
|
{
|
|
|
|
if (width16)
|
|
|
|
denali_exec_out16(denali, type, buf, len);
|
|
|
|
else
|
|
|
|
denali_exec_out8(denali, type, buf, len);
|
|
|
|
}
|
|
|
|
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
static int denali_exec_waitrdy(struct denali_controller *denali)
|
2019-04-02 13:03:04 +09:00
|
|
|
{
|
|
|
|
u32 irq_stat;
|
|
|
|
|
|
|
|
/* R/B# pin transitioned from low to high? */
|
|
|
|
irq_stat = denali_wait_for_irq(denali, INTR__INT_ACT);
|
|
|
|
|
|
|
|
/* Just in case nand_operation has multiple NAND_OP_WAITRDY_INSTR. */
|
|
|
|
denali_reset_irq(denali);
|
|
|
|
|
|
|
|
return irq_stat & INTR__INT_ACT ? 0 : -EIO;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int denali_exec_instr(struct nand_chip *chip,
|
|
|
|
const struct nand_op_instr *instr)
|
|
|
|
{
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
struct denali_controller *denali = to_denali_controller(chip);
|
2019-04-02 13:03:04 +09:00
|
|
|
|
|
|
|
switch (instr->type) {
|
|
|
|
case NAND_OP_CMD_INSTR:
|
|
|
|
denali_exec_out8(denali, DENALI_MAP11_CMD,
|
|
|
|
&instr->ctx.cmd.opcode, 1);
|
|
|
|
return 0;
|
|
|
|
case NAND_OP_ADDR_INSTR:
|
|
|
|
denali_exec_out8(denali, DENALI_MAP11_ADDR,
|
|
|
|
instr->ctx.addr.addrs,
|
|
|
|
instr->ctx.addr.naddrs);
|
|
|
|
return 0;
|
|
|
|
case NAND_OP_DATA_IN_INSTR:
|
|
|
|
denali_exec_in(denali, DENALI_MAP11_DATA,
|
|
|
|
instr->ctx.data.buf.in,
|
|
|
|
instr->ctx.data.len,
|
|
|
|
!instr->ctx.data.force_8bit &&
|
|
|
|
chip->options & NAND_BUSWIDTH_16);
|
|
|
|
return 0;
|
|
|
|
case NAND_OP_DATA_OUT_INSTR:
|
|
|
|
denali_exec_out(denali, DENALI_MAP11_DATA,
|
|
|
|
instr->ctx.data.buf.out,
|
|
|
|
instr->ctx.data.len,
|
|
|
|
!instr->ctx.data.force_8bit &&
|
|
|
|
chip->options & NAND_BUSWIDTH_16);
|
|
|
|
return 0;
|
|
|
|
case NAND_OP_WAITRDY_INSTR:
|
|
|
|
return denali_exec_waitrdy(denali);
|
|
|
|
default:
|
|
|
|
WARN_ONCE(1, "unsupported NAND instruction type: %d\n",
|
|
|
|
instr->type);
|
|
|
|
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static int denali_exec_op(struct nand_chip *chip,
|
|
|
|
const struct nand_operation *op, bool check_only)
|
|
|
|
{
|
|
|
|
int i, ret;
|
|
|
|
|
|
|
|
if (check_only)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
denali_select_target(chip, op->cs);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Some commands contain NAND_OP_WAITRDY_INSTR.
|
|
|
|
* irq must be cleared here to catch the R/B# interrupt there.
|
|
|
|
*/
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
denali_reset_irq(to_denali_controller(chip));
|
2019-04-02 13:03:04 +09:00
|
|
|
|
|
|
|
for (i = 0; i < op->ninstrs; i++) {
|
|
|
|
ret = denali_exec_instr(chip, &op->instrs[i]);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-07-20 17:14:56 +02:00
|
|
|
static const struct nand_controller_ops denali_controller_ops = {
|
|
|
|
.attach_chip = denali_attach_chip,
|
2019-04-02 13:03:04 +09:00
|
|
|
.exec_op = denali_exec_op,
|
2020-05-29 13:13:13 +02:00
|
|
|
.setup_interface = denali_setup_interface,
|
2018-07-20 17:14:56 +02:00
|
|
|
};
|
|
|
|
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
int denali_chip_init(struct denali_controller *denali,
|
|
|
|
struct denali_chip *dchip)
|
2018-07-20 17:14:56 +02:00
|
|
|
{
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
struct nand_chip *chip = &dchip->chip;
|
2018-07-20 17:14:56 +02:00
|
|
|
struct mtd_info *mtd = nand_to_mtd(chip);
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
struct denali_chip *dchip2;
|
|
|
|
int i, j, ret;
|
2018-07-20 17:14:56 +02:00
|
|
|
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
chip->controller = &denali->controller;
|
2018-07-20 17:14:56 +02:00
|
|
|
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
/* sanity checks for bank numbers */
|
|
|
|
for (i = 0; i < dchip->nsels; i++) {
|
|
|
|
unsigned int bank = dchip->sels[i].bank;
|
2018-07-20 17:14:56 +02:00
|
|
|
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
if (bank >= denali->nbanks) {
|
|
|
|
dev_err(denali->dev, "unsupported bank %d\n", bank);
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
2018-07-20 17:14:56 +02:00
|
|
|
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
for (j = 0; j < i; j++) {
|
|
|
|
if (bank == dchip->sels[j].bank) {
|
|
|
|
dev_err(denali->dev,
|
|
|
|
"bank %d is assigned twice in the same chip\n",
|
|
|
|
bank);
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
}
|
2018-07-20 17:14:56 +02:00
|
|
|
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
list_for_each_entry(dchip2, &denali->chips, node) {
|
|
|
|
for (j = 0; j < dchip2->nsels; j++) {
|
|
|
|
if (bank == dchip2->sels[j].bank) {
|
|
|
|
dev_err(denali->dev,
|
|
|
|
"bank %d is already used\n",
|
|
|
|
bank);
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2018-07-20 17:14:56 +02:00
|
|
|
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
mtd->dev.parent = denali->dev;
|
2018-07-20 17:14:56 +02:00
|
|
|
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
/*
|
|
|
|
* Fallback to the default name if DT did not give "label" property.
|
|
|
|
* Use "label" property if multiple chips are connected.
|
|
|
|
*/
|
|
|
|
if (!mtd->name && list_empty(&denali->chips))
|
2018-07-20 17:14:56 +02:00
|
|
|
mtd->name = "denali-nand";
|
|
|
|
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
if (denali->dma_avail) {
|
2020-05-07 12:52:31 +02:00
|
|
|
chip->options |= NAND_USES_DMA;
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
chip->buf_align = 16;
|
2017-06-13 22:45:48 +09:00
|
|
|
}
|
|
|
|
|
2020-05-29 13:13:13 +02:00
|
|
|
/* clk rate info is needed for setup_interface */
|
2019-01-18 14:30:38 +09:00
|
|
|
if (!denali->clk_rate || !denali->clk_x_rate)
|
2018-11-11 08:55:24 +01:00
|
|
|
chip->options |= NAND_KEEP_TIMINGS;
|
2018-07-20 17:14:56 +02:00
|
|
|
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
chip->bbt_options |= NAND_BBT_USE_FLASH;
|
|
|
|
chip->bbt_options |= NAND_BBT_NO_OOB;
|
|
|
|
chip->options |= NAND_NO_SUBPAGE_WRITE;
|
2020-08-27 10:51:58 +02:00
|
|
|
chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST;
|
2020-08-27 10:51:57 +02:00
|
|
|
chip->ecc.placement = NAND_ECC_PLACEMENT_INTERLEAVED;
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
chip->ecc.read_page = denali_read_page;
|
|
|
|
chip->ecc.write_page = denali_write_page;
|
|
|
|
chip->ecc.read_page_raw = denali_read_page_raw;
|
|
|
|
chip->ecc.write_page_raw = denali_write_page_raw;
|
|
|
|
chip->ecc.read_oob = denali_read_oob;
|
|
|
|
chip->ecc.write_oob = denali_write_oob;
|
|
|
|
|
|
|
|
mtd_set_ooblayout(mtd, &denali_ooblayout_ops);
|
|
|
|
|
|
|
|
ret = nand_scan(chip, dchip->nsels);
|
2016-11-09 13:35:28 +09:00
|
|
|
if (ret)
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
return ret;
|
2010-05-13 15:57:33 +01:00
|
|
|
|
2015-12-11 15:06:00 +01:00
|
|
|
ret = mtd_device_register(mtd, NULL, 0);
|
2010-05-13 15:57:33 +01:00
|
|
|
if (ret) {
|
2016-11-09 13:35:24 +09:00
|
|
|
dev_err(denali->dev, "Failed to register MTD: %d\n", ret);
|
2018-03-21 14:01:45 +01:00
|
|
|
goto cleanup_nand;
|
2010-05-13 15:57:33 +01:00
|
|
|
}
|
2018-07-20 17:14:56 +02:00
|
|
|
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
list_add_tail(&dchip->node, &denali->chips);
|
|
|
|
|
2010-05-13 15:57:33 +01:00
|
|
|
return 0;
|
|
|
|
|
2018-03-21 14:01:45 +01:00
|
|
|
cleanup_nand:
|
|
|
|
nand_cleanup(chip);
|
2012-09-27 10:58:05 -06:00
|
|
|
|
2010-05-13 15:57:33 +01:00
|
|
|
return ret;
|
|
|
|
}
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
EXPORT_SYMBOL_GPL(denali_chip_init);
|
|
|
|
|
|
|
|
int denali_init(struct denali_controller *denali)
|
|
|
|
{
|
|
|
|
u32 features = ioread32(denali->reg + FEATURES);
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
nand_controller_init(&denali->controller);
|
|
|
|
denali->controller.ops = &denali_controller_ops;
|
|
|
|
init_completion(&denali->complete);
|
|
|
|
spin_lock_init(&denali->irq_lock);
|
|
|
|
INIT_LIST_HEAD(&denali->chips);
|
|
|
|
denali->active_bank = DENALI_INVALID_BANK;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The REVISION register may not be reliable. Platforms are allowed to
|
|
|
|
* override it.
|
|
|
|
*/
|
|
|
|
if (!denali->revision)
|
|
|
|
denali->revision = swab16(ioread32(denali->reg + REVISION));
|
|
|
|
|
|
|
|
denali->nbanks = 1 << FIELD_GET(FEATURES__N_BANKS, features);
|
|
|
|
|
|
|
|
/* the encoding changed from rev 5.0 to 5.1 */
|
|
|
|
if (denali->revision < 0x0501)
|
|
|
|
denali->nbanks <<= 1;
|
|
|
|
|
|
|
|
if (features & FEATURES__DMA)
|
|
|
|
denali->dma_avail = true;
|
|
|
|
|
|
|
|
if (denali->dma_avail) {
|
|
|
|
int dma_bit = denali->caps & DENALI_CAP_DMA_64BIT ? 64 : 32;
|
|
|
|
|
|
|
|
ret = dma_set_mask(denali->dev, DMA_BIT_MASK(dma_bit));
|
|
|
|
if (ret) {
|
|
|
|
dev_info(denali->dev,
|
|
|
|
"Failed to set DMA mask. Disabling DMA.\n");
|
|
|
|
denali->dma_avail = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (denali->dma_avail) {
|
|
|
|
if (denali->caps & DENALI_CAP_DMA_64BIT)
|
|
|
|
denali->setup_dma = denali_setup_dma64;
|
|
|
|
else
|
|
|
|
denali->setup_dma = denali_setup_dma32;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (features & FEATURES__INDEX_ADDR) {
|
|
|
|
denali->host_read = denali_indexed_read;
|
|
|
|
denali->host_write = denali_indexed_write;
|
|
|
|
} else {
|
|
|
|
denali->host_read = denali_direct_read;
|
|
|
|
denali->host_write = denali_direct_write;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Set how many bytes should be skipped before writing data in OOB.
|
2019-12-20 20:31:55 +09:00
|
|
|
* If a platform requests a non-zero value, set it to the register.
|
|
|
|
* Otherwise, read the value out, expecting it has already been set up
|
|
|
|
* by firmware.
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
*/
|
2019-12-20 20:31:55 +09:00
|
|
|
if (denali->oob_skip_bytes)
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
iowrite32(denali->oob_skip_bytes,
|
|
|
|
denali->reg + SPARE_AREA_SKIP_BYTES);
|
2019-12-20 20:31:55 +09:00
|
|
|
else
|
|
|
|
denali->oob_skip_bytes = ioread32(denali->reg +
|
|
|
|
SPARE_AREA_SKIP_BYTES);
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
|
|
|
|
iowrite32(0, denali->reg + TRANSFER_SPARE_REG);
|
|
|
|
iowrite32(GENMASK(denali->nbanks - 1, 0), denali->reg + RB_PIN_ENABLED);
|
|
|
|
iowrite32(CHIP_EN_DONT_CARE__FLAG, denali->reg + CHIP_ENABLE_DONT_CARE);
|
|
|
|
iowrite32(ECC_ENABLE__FLAG, denali->reg + ECC_ENABLE);
|
|
|
|
iowrite32(0xffff, denali->reg + SPARE_AREA_MARKER);
|
2020-01-27 21:39:34 +09:00
|
|
|
iowrite32(WRITE_PROTECT__FLAG, denali->reg + WRITE_PROTECT);
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
|
|
|
|
denali_clear_irq_all(denali);
|
|
|
|
|
|
|
|
ret = devm_request_irq(denali->dev, denali->irq, denali_isr,
|
|
|
|
IRQF_SHARED, DENALI_NAND_NAME, denali);
|
|
|
|
if (ret) {
|
|
|
|
dev_err(denali->dev, "Unable to request IRQ\n");
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
denali_enable_irq(denali);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2012-09-27 10:58:05 -06:00
|
|
|
EXPORT_SYMBOL(denali_init);
|
2010-05-13 15:57:33 +01:00
|
|
|
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
void denali_remove(struct denali_controller *denali)
|
2010-05-13 15:57:33 +01:00
|
|
|
{
|
2020-05-19 14:59:43 +02:00
|
|
|
struct denali_chip *dchip, *tmp;
|
2020-05-19 14:59:44 +02:00
|
|
|
struct nand_chip *chip;
|
|
|
|
int ret;
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
|
2020-05-19 14:59:43 +02:00
|
|
|
list_for_each_entry_safe(dchip, tmp, &denali->chips, node) {
|
2020-05-19 14:59:44 +02:00
|
|
|
chip = &dchip->chip;
|
|
|
|
ret = mtd_device_unregister(nand_to_mtd(chip));
|
|
|
|
WARN_ON(ret);
|
|
|
|
nand_cleanup(chip);
|
2020-05-19 14:59:43 +02:00
|
|
|
list_del(&dchip->node);
|
|
|
|
}
|
mtd: rawnand: denali: decouple controller and NAND chips
Currently, this driver sticks to the legacy NAND model because it was
upstreamed before commit 2d472aba15ff ("mtd: nand: document the NAND
controller/NAND chip DT representation"). However, relying on the
dummy_controller is already deprecated.
Switch over to the new controller/chip representation.
The struct denali_nand_info has been split into denali_controller
and denali_chip, to contain the controller data, per-chip data,
respectively.
One problem is, this commit changes the DT binding. So, as always,
the backward compatibility must be taken into consideration.
In the new binding, the controller node expects
#address-cells = <1>;
#size-cells = <0>;
... since the child nodes represent NAND chips.
In the old binding, the controller node may have subnodes, but they
are MTD partitions.
The denali_dt_is_legacy_binding() exploits it to distinguish old/new
platforms.
Going forward, the old binding is only allowed for existing DT files.
I updated the binding document.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
2019-04-02 13:03:07 +09:00
|
|
|
|
2017-06-13 22:45:38 +09:00
|
|
|
denali_disable_irq(denali);
|
2010-05-13 15:57:33 +01:00
|
|
|
}
|
2012-09-27 10:58:05 -06:00
|
|
|
EXPORT_SYMBOL(denali_remove);
|
2018-08-20 12:26:36 +09:00
|
|
|
|
|
|
|
MODULE_DESCRIPTION("Driver core for Denali NAND controller");
|
|
|
|
MODULE_AUTHOR("Intel Corporation and its suppliers");
|
|
|
|
MODULE_LICENSE("GPL v2");
|