Hi,
this is version two of
lkml.kernel.org/r/[email protected]
Changes since v1:
- Addressed comments from Miquel Raynal
- Changed subject
- Coding style
- Using timeout constants
- Moving version check completely into fsl_ifc_sram_init()
Thanks,
Kurt
Kurt Kanzenbach (2):
mtd: rawnand: fsl_ifc: check result of SRAM initialization
mtd: rawnand: fsl_ifc: fixup SRAM init for newer ctrl versions
drivers/mtd/nand/raw/fsl_ifc_nand.c | 36 ++++++++++++++++++++++++++++++++----
include/linux/fsl_ifc.h | 2 ++
2 files changed, 34 insertions(+), 4 deletions(-)
--
2.11.0
Newer versions of the IFC controller use a different method of initializing the
internal SRAM: Instead of reading from flash, a bit in the NAND configuration
register has to be set in order to trigger the self-initializing process.
Signed-off-by: Kurt Kanzenbach <[email protected]>
---
Changes since v1:
- Subject
- Coding style
- Using timeout constant
- Move version check completely into fsl_ifc_sram_init()
drivers/mtd/nand/raw/fsl_ifc_nand.c | 33 ++++++++++++++++++++++++++-------
include/linux/fsl_ifc.h | 2 ++
2 files changed, 28 insertions(+), 7 deletions(-)
diff --git a/drivers/mtd/nand/raw/fsl_ifc_nand.c b/drivers/mtd/nand/raw/fsl_ifc_nand.c
index e4f5792dc589..7e7729df7827 100644
--- a/drivers/mtd/nand/raw/fsl_ifc_nand.c
+++ b/drivers/mtd/nand/raw/fsl_ifc_nand.c
@@ -30,6 +30,7 @@
#include <linux/mtd/partitions.h>
#include <linux/mtd/nand_ecc.h>
#include <linux/fsl_ifc.h>
+#include <linux/iopoll.h>
#define ERR_BYTE 0xFF /* Value returned for read
bytes when read failed */
@@ -769,6 +770,27 @@ static int fsl_ifc_sram_init(struct fsl_ifc_mtd *priv)
uint32_t csor = 0, csor_8k = 0, csor_ext = 0;
uint32_t cs = priv->bank;
+ if (ctrl->version < FSL_IFC_VERSION_1_1_0)
+ return 0;
+
+ if (ctrl->version > FSL_IFC_VERSION_1_1_0) {
+ u32 ncfgr, status;
+ int ret;
+
+ /* Trigger auto initialization */
+ ncfgr = ifc_in32(&ifc_runtime->ifc_nand.ncfgr);
+ ifc_out32(ncfgr | IFC_NAND_NCFGR_SRAM_INIT_EN, &ifc_runtime->ifc_nand.ncfgr);
+
+ /* Wait until done */
+ ret = readx_poll_timeout(ifc_in32, &ifc_runtime->ifc_nand.ncfgr,
+ status, !(status & IFC_NAND_NCFGR_SRAM_INIT_EN),
+ 10, IFC_TIMEOUT_MSECS * 1000);
+ if (ret)
+ dev_err(priv->dev, "Failed to initialize SRAM!\n");
+
+ return ret;
+ }
+
/* Save CSOR and CSOR_ext */
csor = ifc_in32(&ifc_global->csor_cs[cs].csor);
csor_ext = ifc_in32(&ifc_global->csor_cs[cs].csor_ext);
@@ -825,6 +847,7 @@ static int fsl_ifc_chip_init(struct fsl_ifc_mtd *priv)
struct nand_chip *chip = &priv->chip;
struct mtd_info *mtd = nand_to_mtd(&priv->chip);
u32 csor;
+ int ret;
/* Fill in fsl_ifc_mtd structure */
mtd->dev.parent = priv->dev;
@@ -918,13 +941,9 @@ static int fsl_ifc_chip_init(struct fsl_ifc_mtd *priv)
chip->ecc.algo = NAND_ECC_HAMMING;
}
- if (ctrl->version >= FSL_IFC_VERSION_1_1_0) {
- int ret;
-
- ret = fsl_ifc_sram_init(priv);
- if (ret)
- return ret;
- }
+ ret = fsl_ifc_sram_init(priv);
+ if (ret)
+ return ret;
/*
* As IFC version 2.0.0 has 16KB of internal SRAM as compared to older
diff --git a/include/linux/fsl_ifc.h b/include/linux/fsl_ifc.h
index 3fdfede2f0f3..5f343b796ad9 100644
--- a/include/linux/fsl_ifc.h
+++ b/include/linux/fsl_ifc.h
@@ -274,6 +274,8 @@
*/
/* Auto Boot Mode */
#define IFC_NAND_NCFGR_BOOT 0x80000000
+/* SRAM Initialization */
+#define IFC_NAND_NCFGR_SRAM_INIT_EN 0x20000000
/* Addressing Mode-ROW0+n/COL0 */
#define IFC_NAND_NCFGR_ADDR_MODE_RC0 0x00000000
/* Addressing Mode-ROW0+n/COL0+n */
--
2.11.0
The SRAM initialization might fail. If that happens further NAND operations
won't be successful. Therefore, the chip init routine should fail if the SRAM
initialization didn't work.
Signed-off-by: Kurt Kanzenbach <[email protected]>
---
Changes since v1:
- Subject
drivers/mtd/nand/raw/fsl_ifc_nand.c | 17 +++++++++++++----
1 file changed, 13 insertions(+), 4 deletions(-)
diff --git a/drivers/mtd/nand/raw/fsl_ifc_nand.c b/drivers/mtd/nand/raw/fsl_ifc_nand.c
index 24f59d0066af..e4f5792dc589 100644
--- a/drivers/mtd/nand/raw/fsl_ifc_nand.c
+++ b/drivers/mtd/nand/raw/fsl_ifc_nand.c
@@ -761,7 +761,7 @@ static const struct nand_controller_ops fsl_ifc_controller_ops = {
.attach_chip = fsl_ifc_attach_chip,
};
-static void fsl_ifc_sram_init(struct fsl_ifc_mtd *priv)
+static int fsl_ifc_sram_init(struct fsl_ifc_mtd *priv)
{
struct fsl_ifc_ctrl *ctrl = priv->ctrl;
struct fsl_ifc_runtime __iomem *ifc_runtime = ctrl->rregs;
@@ -805,12 +805,16 @@ static void fsl_ifc_sram_init(struct fsl_ifc_mtd *priv)
wait_event_timeout(ctrl->nand_wait, ctrl->nand_stat,
msecs_to_jiffies(IFC_TIMEOUT_MSECS));
- if (ctrl->nand_stat != IFC_NAND_EVTER_STAT_OPC)
+ if (ctrl->nand_stat != IFC_NAND_EVTER_STAT_OPC) {
pr_err("fsl-ifc: Failed to Initialise SRAM\n");
+ return -ETIMEDOUT;
+ }
/* Restore CSOR and CSOR_ext */
ifc_out32(csor, &ifc_global->csor_cs[cs].csor);
ifc_out32(csor_ext, &ifc_global->csor_cs[cs].csor_ext);
+
+ return 0;
}
static int fsl_ifc_chip_init(struct fsl_ifc_mtd *priv)
@@ -914,8 +918,13 @@ static int fsl_ifc_chip_init(struct fsl_ifc_mtd *priv)
chip->ecc.algo = NAND_ECC_HAMMING;
}
- if (ctrl->version >= FSL_IFC_VERSION_1_1_0)
- fsl_ifc_sram_init(priv);
+ if (ctrl->version >= FSL_IFC_VERSION_1_1_0) {
+ int ret;
+
+ ret = fsl_ifc_sram_init(priv);
+ if (ret)
+ return ret;
+ }
/*
* As IFC version 2.0.0 has 16KB of internal SRAM as compared to older
--
2.11.0
Hi Kurt,
Kurt Kanzenbach <[email protected]> wrote on Mon, 13 Aug 2018 09:18:44
+0200:
> Hi,
>
> this is version two of
>
> lkml.kernel.org/r/[email protected]
>
> Changes since v1:
>
> - Addressed comments from Miquel Raynal
> - Changed subject
> - Coding style
> - Using timeout constants
> - Moving version check completely into fsl_ifc_sram_init()
>
> Thanks,
> Kurt
>
> Kurt Kanzenbach (2):
> mtd: rawnand: fsl_ifc: check result of SRAM initialization
> mtd: rawnand: fsl_ifc: fixup SRAM init for newer ctrl versions
>
> drivers/mtd/nand/raw/fsl_ifc_nand.c | 36 ++++++++++++++++++++++++++++++++----
> include/linux/fsl_ifc.h | 2 ++
> 2 files changed, 34 insertions(+), 4 deletions(-)
>
Series applied to nand/next.
Thanks,
Miquèl