Raw NAND core

* Useless extra checks dropped.
 * Updated the detection of the bad block markers position
 
 Raw NAND controller drivers:
 * Cadence : New driver
 * Brcmnand: Support for flash-dma v0 + fixes
 * Denali : Support for the legacy controller/chip DT representation
            dropped
 * Superfluous dev_err() calls removed
 -----BEGIN PGP SIGNATURE-----
 
 iQEzBAABCgAdFiEE9HuaYnbmDhq/XIDIJWrqGEe9VoQFAl3KwQYACgkQJWrqGEe9
 VoTj1wf/Zvnk1u2vNVUaWDaHnUTAcMvjYNr1N1ppXquRXQTknZHxcgqavcwOA3yV
 inHRdjQpvTPft3Pb0tddC2VBOMQTYWDGJs6JOLiPF5c4QdW/w4yHRrdnEIumbVP/
 itXySbPj2QsXcRuIoEm165NTI8mdSzZFixZvCNS58r2mvMXvQbcUHsP9vjlUs9/S
 XPqBlSBPKa6hC2ToIiXhgkGDQzVJ/OkCOSgG+37ATUrEqWUi9oN2KUPkbk4HSZe9
 dntUIFSjeAqGjKGRGwAlt4axhnFWABfWa9xBwX9k5s4mt/FJ9QF24geemz/F1Ljp
 7xd6MJu3JYoW8qBcXRRDgHuv5RNnHA==
 =rpUJ
 -----END PGP SIGNATURE-----

Merge tag 'nand/for-5.5' into mtd/next

Raw NAND core
* Useless extra checks dropped.
* Updated the detection of the bad block markers position

Raw NAND controller drivers:
* Cadence : New driver
* Brcmnand: Support for flash-dma v0 + fixes
* Denali : Support for the legacy controller/chip DT representation
           dropped
* Superfluous dev_err() calls removed
This commit is contained in:
Miquel Raynal 2019-11-17 18:34:25 +01:00
commit 589e1b6c47
10 changed files with 3132 additions and 60 deletions

View File

@ -0,0 +1,53 @@
* Cadence NAND controller
Required properties:
- compatible : "cdns,hp-nfc"
- reg : Contains two entries, each of which is a tuple consisting of a
physical address and length. The first entry is the address and
length of the controller register set. The second entry is the
address and length of the Slave DMA data port.
- reg-names: should contain "reg" and "sdma"
- #address-cells: should be 1. The cell encodes the chip select connection.
- #size-cells : should be 0.
- interrupts : The interrupt number.
- clocks: phandle of the controller core clock (nf_clk).
Optional properties:
- dmas: shall reference DMA channel associated to the NAND controller
- cdns,board-delay-ps : Estimated Board delay. The value includes the total
round trip delay for the signals and is used for deciding on values
associated with data read capture. The example formula for SDR mode is
the following:
board delay = RE#PAD delay + PCB trace to device + PCB trace from device
+ DQ PAD delay
Child nodes represent the available NAND chips.
Required properties of NAND chips:
- reg: shall contain the native Chip Select ids from 0 to max supported by
the cadence nand flash controller
See Documentation/devicetree/bindings/mtd/nand.txt for more details on
generic bindings.
Example:
nand_controller: nand-controller@60000000 {
compatible = "cdns,hp-nfc";
#address-cells = <1>;
#size-cells = <0>;
reg = <0x60000000 0x10000>, <0x80000000 0x10000>;
reg-names = "reg", "sdma";
clocks = <&nf_clk>;
cdns,board-delay-ps = <4830>;
interrupts = <2 0>;
nand@0 {
reg = <0>;
label = "nand-1";
};
nand@1 {
reg = <1>;
label = "nand-2";
};
};

View File

@ -3594,6 +3594,13 @@ S: Maintained
F: Documentation/devicetree/bindings/media/cdns,*.txt
F: drivers/media/platform/cadence/cdns-csi2*
CADENCE NAND DRIVER
M: Piotr Sroka <piotrs@cadence.com>
L: linux-mtd@lists.infradead.org
S: Maintained
F: drivers/mtd/nand/raw/cadence-nand-controller.c
F: Documentation/devicetree/bindings/mtd/cadence-nand-controller.txt
CADET FM/AM RADIO RECEIVER DRIVER
M: Hans Verkuil <hverkuil@xs4all.nl>
L: linux-media@vger.kernel.org

View File

@ -450,6 +450,13 @@ config MTD_NAND_PLATFORM
devices. You will need to provide platform-specific functions
via platform_data.
config MTD_NAND_CADENCE
tristate "Support Cadence NAND (HPNFC) controller"
depends on OF || COMPILE_TEST
help
Enable the driver for NAND flash on platforms using a Cadence NAND
controller.
comment "Misc"
config MTD_SM_COMMON

View File

@ -57,6 +57,7 @@ obj-$(CONFIG_MTD_NAND_MXIC) += mxic_nand.o
obj-$(CONFIG_MTD_NAND_TEGRA) += tegra_nand.o
obj-$(CONFIG_MTD_NAND_STM32_FMC2) += stm32_fmc2_nand.o
obj-$(CONFIG_MTD_NAND_MESON) += meson_nand.o
obj-$(CONFIG_MTD_NAND_CADENCE) += cadence-nand-controller.o
nand-objs := nand_base.o nand_legacy.o nand_bbt.o nand_timings.o nand_ids.o
nand-objs += nand_onfi.o

View File

@ -117,6 +117,18 @@ enum flash_dma_reg {
FLASH_DMA_CURRENT_DESC_EXT,
};
/* flash_dma registers v0*/
static const u16 flash_dma_regs_v0[] = {
[FLASH_DMA_REVISION] = 0x00,
[FLASH_DMA_FIRST_DESC] = 0x04,
[FLASH_DMA_CTRL] = 0x08,
[FLASH_DMA_MODE] = 0x0c,
[FLASH_DMA_STATUS] = 0x10,
[FLASH_DMA_INTERRUPT_DESC] = 0x14,
[FLASH_DMA_ERROR_STATUS] = 0x18,
[FLASH_DMA_CURRENT_DESC] = 0x1c,
};
/* flash_dma registers v1*/
static const u16 flash_dma_regs_v1[] = {
[FLASH_DMA_REVISION] = 0x00,
@ -597,6 +609,8 @@ static void brcmnand_flash_dma_revision_init(struct brcmnand_controller *ctrl)
/* flash_dma register offsets */
if (ctrl->nand_version >= 0x0703)
ctrl->flash_dma_offsets = flash_dma_regs_v4;
else if (ctrl->nand_version == 0x0602)
ctrl->flash_dma_offsets = flash_dma_regs_v0;
else
ctrl->flash_dma_offsets = flash_dma_regs_v1;
}
@ -918,7 +932,7 @@ static inline void disable_ctrl_irqs(struct brcmnand_controller *ctrl)
return;
if (has_flash_dma(ctrl)) {
ctrl->flash_dma_base = 0;
ctrl->flash_dma_base = NULL;
disable_irq(ctrl->dma_irq);
}
@ -1673,8 +1687,11 @@ static void brcmnand_dma_run(struct brcmnand_host *host, dma_addr_t desc)
flash_dma_writel(ctrl, FLASH_DMA_FIRST_DESC, lower_32_bits(desc));
(void)flash_dma_readl(ctrl, FLASH_DMA_FIRST_DESC);
flash_dma_writel(ctrl, FLASH_DMA_FIRST_DESC_EXT, upper_32_bits(desc));
(void)flash_dma_readl(ctrl, FLASH_DMA_FIRST_DESC_EXT);
if (ctrl->nand_version > 0x0602) {
flash_dma_writel(ctrl, FLASH_DMA_FIRST_DESC_EXT,
upper_32_bits(desc));
(void)flash_dma_readl(ctrl, FLASH_DMA_FIRST_DESC_EXT);
}
/* Start FLASH_DMA engine */
ctrl->dma_pending = true;

File diff suppressed because it is too large Load Diff

View File

@ -102,47 +102,6 @@ static int denali_dt_chip_init(struct denali_controller *denali,
return denali_chip_init(denali, dchip);
}
/* Backward compatibility for old platforms */
static int denali_dt_legacy_chip_init(struct denali_controller *denali)
{
struct denali_chip *dchip;
int nsels, i;
nsels = denali->nbanks;
dchip = devm_kzalloc(denali->dev, struct_size(dchip, sels, nsels),
GFP_KERNEL);
if (!dchip)
return -ENOMEM;
dchip->nsels = nsels;
for (i = 0; i < nsels; i++)
dchip->sels[i].bank = i;
nand_set_flash_node(&dchip->chip, denali->dev->of_node);
return denali_chip_init(denali, dchip);
}
/*
* Check the DT binding.
* The new binding expects chip subnodes in the controller node.
* So, #address-cells = <1>; #size-cells = <0>; are required.
* Check the #size-cells to distinguish the binding.
*/
static bool denali_dt_is_legacy_binding(struct device_node *np)
{
u32 cells;
int ret;
ret = of_property_read_u32(np, "#size-cells", &cells);
if (ret)
return true;
return cells != 0;
}
static int denali_dt_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
@ -211,17 +170,11 @@ static int denali_dt_probe(struct platform_device *pdev)
if (ret)
goto out_disable_clk_ecc;
if (denali_dt_is_legacy_binding(dev->of_node)) {
ret = denali_dt_legacy_chip_init(denali);
if (ret)
for_each_child_of_node(dev->of_node, np) {
ret = denali_dt_chip_init(denali, np);
if (ret) {
of_node_put(np);
goto out_remove_denali;
} else {
for_each_child_of_node(dev->of_node, np) {
ret = denali_dt_chip_init(denali, np);
if (ret) {
of_node_put(np);
goto out_remove_denali;
}
}
}

View File

@ -524,10 +524,8 @@ static int mxic_nfc_probe(struct platform_device *pdev)
nand_chip->controller = &nfc->controller;
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
dev_err(&pdev->dev, "failed to retrieve irq\n");
if (irq < 0)
return irq;
}
mxic_nfc_hw_init(nfc);

View File

@ -292,12 +292,16 @@ int nand_bbm_get_next_page(struct nand_chip *chip, int page)
struct mtd_info *mtd = nand_to_mtd(chip);
int last_page = ((mtd->erasesize - mtd->writesize) >>
chip->page_shift) & chip->pagemask;
unsigned int bbm_flags = NAND_BBM_FIRSTPAGE | NAND_BBM_SECONDPAGE
| NAND_BBM_LASTPAGE;
if (page == 0 && !(chip->options & bbm_flags))
return 0;
if (page == 0 && chip->options & NAND_BBM_FIRSTPAGE)
return 0;
else if (page <= 1 && chip->options & NAND_BBM_SECONDPAGE)
if (page <= 1 && chip->options & NAND_BBM_SECONDPAGE)
return 1;
else if (page <= last_page && chip->options & NAND_BBM_LASTPAGE)
if (page <= last_page && chip->options & NAND_BBM_LASTPAGE)
return last_page;
return -EINVAL;

View File

@ -446,8 +446,10 @@ static int micron_nand_init(struct nand_chip *chip)
if (ret)
goto err_free_manuf_data;
chip->options |= NAND_BBM_FIRSTPAGE;
if (mtd->writesize == 2048)
chip->options |= NAND_BBM_FIRSTPAGE | NAND_BBM_SECONDPAGE;
chip->options |= NAND_BBM_SECONDPAGE;
ondie = micron_supports_on_die_ecc(chip);