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:
commit
589e1b6c47
|
@ -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";
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
|
@ -3594,6 +3594,13 @@ S: Maintained
|
||||||
F: Documentation/devicetree/bindings/media/cdns,*.txt
|
F: Documentation/devicetree/bindings/media/cdns,*.txt
|
||||||
F: drivers/media/platform/cadence/cdns-csi2*
|
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
|
CADET FM/AM RADIO RECEIVER DRIVER
|
||||||
M: Hans Verkuil <hverkuil@xs4all.nl>
|
M: Hans Verkuil <hverkuil@xs4all.nl>
|
||||||
L: linux-media@vger.kernel.org
|
L: linux-media@vger.kernel.org
|
||||||
|
|
|
@ -450,6 +450,13 @@ config MTD_NAND_PLATFORM
|
||||||
devices. You will need to provide platform-specific functions
|
devices. You will need to provide platform-specific functions
|
||||||
via platform_data.
|
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"
|
comment "Misc"
|
||||||
|
|
||||||
config MTD_SM_COMMON
|
config MTD_SM_COMMON
|
||||||
|
|
|
@ -57,6 +57,7 @@ obj-$(CONFIG_MTD_NAND_MXIC) += mxic_nand.o
|
||||||
obj-$(CONFIG_MTD_NAND_TEGRA) += tegra_nand.o
|
obj-$(CONFIG_MTD_NAND_TEGRA) += tegra_nand.o
|
||||||
obj-$(CONFIG_MTD_NAND_STM32_FMC2) += stm32_fmc2_nand.o
|
obj-$(CONFIG_MTD_NAND_STM32_FMC2) += stm32_fmc2_nand.o
|
||||||
obj-$(CONFIG_MTD_NAND_MESON) += meson_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_base.o nand_legacy.o nand_bbt.o nand_timings.o nand_ids.o
|
||||||
nand-objs += nand_onfi.o
|
nand-objs += nand_onfi.o
|
||||||
|
|
|
@ -117,6 +117,18 @@ enum flash_dma_reg {
|
||||||
FLASH_DMA_CURRENT_DESC_EXT,
|
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*/
|
/* flash_dma registers v1*/
|
||||||
static const u16 flash_dma_regs_v1[] = {
|
static const u16 flash_dma_regs_v1[] = {
|
||||||
[FLASH_DMA_REVISION] = 0x00,
|
[FLASH_DMA_REVISION] = 0x00,
|
||||||
|
@ -597,6 +609,8 @@ static void brcmnand_flash_dma_revision_init(struct brcmnand_controller *ctrl)
|
||||||
/* flash_dma register offsets */
|
/* flash_dma register offsets */
|
||||||
if (ctrl->nand_version >= 0x0703)
|
if (ctrl->nand_version >= 0x0703)
|
||||||
ctrl->flash_dma_offsets = flash_dma_regs_v4;
|
ctrl->flash_dma_offsets = flash_dma_regs_v4;
|
||||||
|
else if (ctrl->nand_version == 0x0602)
|
||||||
|
ctrl->flash_dma_offsets = flash_dma_regs_v0;
|
||||||
else
|
else
|
||||||
ctrl->flash_dma_offsets = flash_dma_regs_v1;
|
ctrl->flash_dma_offsets = flash_dma_regs_v1;
|
||||||
}
|
}
|
||||||
|
@ -918,7 +932,7 @@ static inline void disable_ctrl_irqs(struct brcmnand_controller *ctrl)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (has_flash_dma(ctrl)) {
|
if (has_flash_dma(ctrl)) {
|
||||||
ctrl->flash_dma_base = 0;
|
ctrl->flash_dma_base = NULL;
|
||||||
disable_irq(ctrl->dma_irq);
|
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));
|
flash_dma_writel(ctrl, FLASH_DMA_FIRST_DESC, lower_32_bits(desc));
|
||||||
(void)flash_dma_readl(ctrl, FLASH_DMA_FIRST_DESC);
|
(void)flash_dma_readl(ctrl, FLASH_DMA_FIRST_DESC);
|
||||||
flash_dma_writel(ctrl, FLASH_DMA_FIRST_DESC_EXT, upper_32_bits(desc));
|
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);
|
(void)flash_dma_readl(ctrl, FLASH_DMA_FIRST_DESC_EXT);
|
||||||
|
}
|
||||||
|
|
||||||
/* Start FLASH_DMA engine */
|
/* Start FLASH_DMA engine */
|
||||||
ctrl->dma_pending = true;
|
ctrl->dma_pending = true;
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -102,47 +102,6 @@ static int denali_dt_chip_init(struct denali_controller *denali,
|
||||||
return denali_chip_init(denali, dchip);
|
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)
|
static int denali_dt_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct device *dev = &pdev->dev;
|
struct device *dev = &pdev->dev;
|
||||||
|
@ -211,11 +170,6 @@ static int denali_dt_probe(struct platform_device *pdev)
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out_disable_clk_ecc;
|
goto out_disable_clk_ecc;
|
||||||
|
|
||||||
if (denali_dt_is_legacy_binding(dev->of_node)) {
|
|
||||||
ret = denali_dt_legacy_chip_init(denali);
|
|
||||||
if (ret)
|
|
||||||
goto out_remove_denali;
|
|
||||||
} else {
|
|
||||||
for_each_child_of_node(dev->of_node, np) {
|
for_each_child_of_node(dev->of_node, np) {
|
||||||
ret = denali_dt_chip_init(denali, np);
|
ret = denali_dt_chip_init(denali, np);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
@ -223,7 +177,6 @@ static int denali_dt_probe(struct platform_device *pdev)
|
||||||
goto out_remove_denali;
|
goto out_remove_denali;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
platform_set_drvdata(pdev, dt);
|
platform_set_drvdata(pdev, dt);
|
||||||
|
|
||||||
|
|
|
@ -524,10 +524,8 @@ static int mxic_nfc_probe(struct platform_device *pdev)
|
||||||
nand_chip->controller = &nfc->controller;
|
nand_chip->controller = &nfc->controller;
|
||||||
|
|
||||||
irq = platform_get_irq(pdev, 0);
|
irq = platform_get_irq(pdev, 0);
|
||||||
if (irq < 0) {
|
if (irq < 0)
|
||||||
dev_err(&pdev->dev, "failed to retrieve irq\n");
|
|
||||||
return irq;
|
return irq;
|
||||||
}
|
|
||||||
|
|
||||||
mxic_nfc_hw_init(nfc);
|
mxic_nfc_hw_init(nfc);
|
||||||
|
|
||||||
|
|
|
@ -292,12 +292,16 @@ int nand_bbm_get_next_page(struct nand_chip *chip, int page)
|
||||||
struct mtd_info *mtd = nand_to_mtd(chip);
|
struct mtd_info *mtd = nand_to_mtd(chip);
|
||||||
int last_page = ((mtd->erasesize - mtd->writesize) >>
|
int last_page = ((mtd->erasesize - mtd->writesize) >>
|
||||||
chip->page_shift) & chip->pagemask;
|
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)
|
if (page == 0 && chip->options & NAND_BBM_FIRSTPAGE)
|
||||||
return 0;
|
return 0;
|
||||||
else if (page <= 1 && chip->options & NAND_BBM_SECONDPAGE)
|
if (page <= 1 && chip->options & NAND_BBM_SECONDPAGE)
|
||||||
return 1;
|
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 last_page;
|
||||||
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
|
@ -446,8 +446,10 @@ static int micron_nand_init(struct nand_chip *chip)
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err_free_manuf_data;
|
goto err_free_manuf_data;
|
||||||
|
|
||||||
|
chip->options |= NAND_BBM_FIRSTPAGE;
|
||||||
|
|
||||||
if (mtd->writesize == 2048)
|
if (mtd->writesize == 2048)
|
||||||
chip->options |= NAND_BBM_FIRSTPAGE | NAND_BBM_SECONDPAGE;
|
chip->options |= NAND_BBM_SECONDPAGE;
|
||||||
|
|
||||||
ondie = micron_supports_on_die_ecc(chip);
|
ondie = micron_supports_on_die_ecc(chip);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue