Merge https://gitlab.denx.de/u-boot/custodians/u-boot-spi
[platform/kernel/u-boot.git] / drivers / mtd / nand / raw / zynq_nand.c
index f322d1a..3941297 100644 (file)
@@ -11,6 +11,7 @@
 #include <asm/io.h>
 #include <linux/errno.h>
 #include <nand.h>
+#include <linux/ioport.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/rawnand.h>
 #include <linux/mtd/partitions.h>
@@ -121,8 +122,6 @@ struct zynq_nand_smc_regs {
        u32 reserved2[2];
        u32 eval0r;             /* 0x418 */
 };
-#define zynq_nand_smc_base     ((struct zynq_nand_smc_regs __iomem *)\
-                               ZYNQ_SMC_BASEADDR)
 
 /*
  * struct nand_config - Defines the NAND flash driver instance
@@ -137,8 +136,14 @@ struct nand_config {
        u8              end_cmd;
 };
 
+struct nand_drv {
+       struct zynq_nand_smc_regs *reg;
+       struct nand_config config;
+};
+
 struct zynq_nand_info {
        struct udevice *dev;
+       struct nand_drv nand_ctrl;
        struct nand_chip nand_chip;
 };
 
@@ -245,16 +250,18 @@ static struct nand_bbt_descr bbt_mirror_descr = {
  *
  * returns: status for command completion, -1 for Timeout
  */
-static int zynq_nand_waitfor_ecc_completion(void)
+static int zynq_nand_waitfor_ecc_completion(struct mtd_info *mtd)
 {
+       struct nand_chip *nand_chip = mtd_to_nand(mtd);
+       struct nand_drv *smc = nand_get_controller_data(nand_chip);
        unsigned long timeout;
        u32 status;
 
        /* Wait max 10us */
        timeout = 10;
-       status = readl(&zynq_nand_smc_base->esr);
+       status = readl(&smc->reg->esr);
        while (status & ZYNQ_NAND_ECC_BUSY) {
-               status = readl(&zynq_nand_smc_base->esr);
+               status = readl(&smc->reg->esr);
                if (timeout == 0)
                        return -1;
                timeout--;
@@ -272,33 +279,35 @@ static int zynq_nand_waitfor_ecc_completion(void)
  *
  * returns:    0 on success or error value on failure
  */
-static int zynq_nand_init_nand_flash(int option)
+static int zynq_nand_init_nand_flash(struct mtd_info *mtd, int option)
 {
+       struct nand_chip *nand_chip = mtd_to_nand(mtd);
+       struct nand_drv *smc = nand_get_controller_data(nand_chip);
        u32 status;
 
        /* disable interrupts */
-       writel(ZYNQ_NAND_CLR_CONFIG, &zynq_nand_smc_base->cfr);
+       writel(ZYNQ_NAND_CLR_CONFIG, &smc->reg->cfr);
 #ifndef CONFIG_NAND_ZYNQ_USE_BOOTLOADER1_TIMINGS
        /* Initialize the NAND interface by setting cycles and operation mode */
-       writel(ZYNQ_NAND_SET_CYCLES, &zynq_nand_smc_base->scr);
+       writel(ZYNQ_NAND_SET_CYCLES, &smc->reg->scr);
 #endif
        if (option & NAND_BUSWIDTH_16)
-               writel(ZYNQ_NAND_SET_OPMODE_16BIT, &zynq_nand_smc_base->sor);
+               writel(ZYNQ_NAND_SET_OPMODE_16BIT, &smc->reg->sor);
        else
-               writel(ZYNQ_NAND_SET_OPMODE_8BIT, &zynq_nand_smc_base->sor);
+               writel(ZYNQ_NAND_SET_OPMODE_8BIT, &smc->reg->sor);
 
-       writel(ZYNQ_NAND_DIRECT_CMD, &zynq_nand_smc_base->dcr);
+       writel(ZYNQ_NAND_DIRECT_CMD, &smc->reg->dcr);
 
        /* Wait till the ECC operation is complete */
-       status = zynq_nand_waitfor_ecc_completion();
+       status = zynq_nand_waitfor_ecc_completion(mtd);
        if (status < 0) {
                printf("%s: Timeout\n", __func__);
                return status;
        }
 
        /* Set the command1 and command2 register */
-       writel(ZYNQ_NAND_ECC_CMD1, &zynq_nand_smc_base->emcmd1r);
-       writel(ZYNQ_NAND_ECC_CMD2, &zynq_nand_smc_base->emcmd2r);
+       writel(ZYNQ_NAND_ECC_CMD1, &smc->reg->emcmd1r);
+       writel(ZYNQ_NAND_ECC_CMD2, &smc->reg->emcmd2r);
 
        return 0;
 }
@@ -317,12 +326,14 @@ static int zynq_nand_init_nand_flash(int option)
 static int zynq_nand_calculate_hwecc(struct mtd_info *mtd, const u8 *data,
                u8 *ecc_code)
 {
+       struct nand_chip *nand_chip = mtd_to_nand(mtd);
+       struct nand_drv *smc = nand_get_controller_data(nand_chip);
        u32 ecc_value = 0;
        u8 ecc_reg, ecc_byte;
        u32 ecc_status;
 
        /* Wait till the ECC operation is complete */
-       ecc_status = zynq_nand_waitfor_ecc_completion();
+       ecc_status = zynq_nand_waitfor_ecc_completion(mtd);
        if (ecc_status < 0) {
                printf("%s: Timeout\n", __func__);
                return ecc_status;
@@ -330,7 +341,7 @@ static int zynq_nand_calculate_hwecc(struct mtd_info *mtd, const u8 *data,
 
        for (ecc_reg = 0; ecc_reg < 4; ecc_reg++) {
                /* Read ECC value for each block */
-               ecc_value = readl(&zynq_nand_smc_base->eval0r + ecc_reg);
+               ecc_value = readl(&smc->reg->eval0r + ecc_reg);
 
                /* Get the ecc status from ecc read value */
                ecc_status = (ecc_value >> 24) & 0xFF;
@@ -785,10 +796,11 @@ static void zynq_nand_select_chip(struct mtd_info *mtd, int chip)
 static void zynq_nand_cmd_function(struct mtd_info *mtd, unsigned int command,
                                 int column, int page_addr)
 {
-       struct nand_chip *chip = mtd->priv;
+       struct nand_chip *chip = mtd_to_nand(mtd);
+       struct nand_drv *smc = nand_get_controller_data(chip);
        const struct zynq_nand_command_format *curr_cmd = NULL;
        u8 addr_cycles = 0;
-       struct nand_config *xnand = (struct nand_config *)chip->priv;
+       struct nand_config *xnand = &smc->config;
        void *cmd_addr;
        unsigned long cmd_data = 0;
        unsigned long cmd_phase_addr = 0;
@@ -827,13 +839,13 @@ static void zynq_nand_cmd_function(struct mtd_info *mtd, unsigned int command,
        curr_cmd = &zynq_nand_commands[index];
 
        /* Clear interrupt */
-       writel(ZYNQ_MEMC_CLRCR_INT_CLR1, &zynq_nand_smc_base->cfr);
+       writel(ZYNQ_MEMC_CLRCR_INT_CLR1, &smc->reg->cfr);
 
        /* Get the command phase address */
        if (curr_cmd->end_cmd_valid == ZYNQ_NAND_CMD_PHASE)
                end_cmd_valid = 1;
 
-       if (curr_cmd->end_cmd == NAND_CMD_NONE)
+       if (curr_cmd->end_cmd == (u8)NAND_CMD_NONE)
                end_cmd = 0x0;
        else
                end_cmd = curr_cmd->end_cmd;
@@ -924,7 +936,7 @@ static void zynq_nand_cmd_function(struct mtd_info *mtd, unsigned int command,
  */
 static void zynq_nand_read_buf(struct mtd_info *mtd, u8 *buf, int len)
 {
-       struct nand_chip *chip = mtd->priv;
+       struct nand_chip *chip = mtd_to_nand(mtd);
 
        /* Make sure that buf is 32 bit aligned */
        if (((unsigned long)buf & 0x3) != 0) {
@@ -972,7 +984,7 @@ static void zynq_nand_read_buf(struct mtd_info *mtd, u8 *buf, int len)
  */
 static void zynq_nand_write_buf(struct mtd_info *mtd, const u8 *buf, int len)
 {
-       struct nand_chip *chip = mtd->priv;
+       struct nand_chip *chip = mtd_to_nand(mtd);
        const u32 *nand = chip->IO_ADDR_W;
 
        /* Make sure that buf is 32 bit aligned */
@@ -1022,13 +1034,15 @@ static void zynq_nand_write_buf(struct mtd_info *mtd, const u8 *buf, int len)
  */
 static int zynq_nand_device_ready(struct mtd_info *mtd)
 {
+       struct nand_chip *nand_chip = mtd_to_nand(mtd);
+       struct nand_drv *smc = nand_get_controller_data(nand_chip);
        u32 csr_val;
 
-       csr_val = readl(&zynq_nand_smc_base->csr);
+       csr_val = readl(&smc->reg->csr);
        /* Check the raw_int_status1 bit */
        if (csr_val & ZYNQ_MEMC_SR_RAW_INT_ST1) {
                /* Clear the interrupt condition */
-               writel(ZYNQ_MEMC_SR_INT_ST1, &zynq_nand_smc_base->cfr);
+               writel(ZYNQ_MEMC_SR_INT_ST1, &smc->reg->cfr);
                return 1;
        }
 
@@ -1056,28 +1070,39 @@ static int zynq_nand_probe(struct udevice *dev)
 {
        struct zynq_nand_info *zynq = dev_get_priv(dev);
        struct nand_chip *nand_chip = &zynq->nand_chip;
-       struct nand_config *xnand;
+       struct nand_drv *smc = &zynq->nand_ctrl;
+       struct nand_config *xnand = &smc->config;
        struct mtd_info *mtd;
+       struct resource res;
+       ofnode of_nand;
        unsigned long ecc_page_size;
        u8 maf_id, dev_id, i;
        u8 get_feature[4];
        u8 set_feature[4] = {ONDIE_ECC_FEATURE_ENABLE, 0x00, 0x00, 0x00};
        unsigned long ecc_cfg;
        int ondie_ecc_enabled = 0;
-       int err = -1;
        int is_16bit_bw;
 
-       xnand = calloc(1, sizeof(struct nand_config));
-       if (!xnand) {
-               printf("%s: failed to allocate\n", __func__);
-               goto fail;
+       smc->reg = (struct zynq_nand_smc_regs *)dev_read_addr(dev);
+       of_nand = dev_read_subnode(dev, "flash@e1000000");
+       if (!ofnode_valid(of_nand)) {
+               printf("Failed to find nand node in dt\n");
+               return -ENODEV;
        }
 
-       xnand->nand_base = (void __iomem *)ZYNQ_NAND_BASEADDR;
-       mtd = nand_to_mtd(nand_chip);
+       if (!ofnode_is_available(of_nand)) {
+               debug("Nand node in dt disabled\n");
+               return dm_scan_fdt_dev(dev);
+       }
 
-       nand_chip->priv = xnand;
-       mtd->priv = nand_chip;
+       if (ofnode_read_resource(of_nand, 0, &res)) {
+               printf("Failed to get nand resource\n");
+               return -ENODEV;
+       }
+
+       xnand->nand_base = (void __iomem *)res.start;
+       mtd = nand_to_mtd(nand_chip);
+       nand_set_controller_data(nand_chip, &zynq->nand_ctrl);
 
        /* Set address of NAND IO lines */
        nand_chip->IO_ADDR_R = xnand->nand_base;
@@ -1099,7 +1124,7 @@ static int zynq_nand_probe(struct udevice *dev)
        if (is_16bit_bw == NAND_BW_UNKNOWN) {
                printf("%s: Unable detect NAND based on MIO settings\n",
                       __func__);
-               goto fail;
+               return -EINVAL;
        }
 
        if (is_16bit_bw == NAND_BW_16BIT)
@@ -1108,15 +1133,15 @@ static int zynq_nand_probe(struct udevice *dev)
        nand_chip->bbt_options = NAND_BBT_USE_FLASH;
 
        /* Initialize the NAND flash interface on NAND controller */
-       if (zynq_nand_init_nand_flash(nand_chip->options) < 0) {
+       if (zynq_nand_init_nand_flash(mtd, nand_chip->options) < 0) {
                printf("%s: nand flash init failed\n", __func__);
-               goto fail;
+               return -EINVAL;
        }
 
        /* first scan to find the device and get the page size */
        if (nand_scan_ident(mtd, 1, NULL)) {
                printf("%s: nand_scan_ident failed\n", __func__);
-               goto fail;
+               return -EINVAL;
        }
        /* Send the command for reading device ID */
        nand_chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
@@ -1156,9 +1181,9 @@ static int zynq_nand_probe(struct udevice *dev)
 
        if (ondie_ecc_enabled) {
                /* Bypass the controller ECC block */
-               ecc_cfg = readl(&zynq_nand_smc_base->emcr);
+               ecc_cfg = readl(&smc->reg->emcr);
                ecc_cfg &= ~ZYNQ_MEMC_NAND_ECC_MODE_MASK;
-               writel(ecc_cfg, &zynq_nand_smc_base->emcr);
+               writel(ecc_cfg, &smc->reg->emcr);
 
                /* The software ECC routines won't work
                 * with the SMC controller
@@ -1206,19 +1231,19 @@ static int zynq_nand_probe(struct udevice *dev)
                        ecc_page_size = 0x1;
                        /* Set the ECC memory config register */
                        writel((ZYNQ_NAND_ECC_CONFIG | ecc_page_size),
-                              &zynq_nand_smc_base->emcr);
+                              &smc->reg->emcr);
                        break;
                case 1024:
                        ecc_page_size = 0x2;
                        /* Set the ECC memory config register */
                        writel((ZYNQ_NAND_ECC_CONFIG | ecc_page_size),
-                              &zynq_nand_smc_base->emcr);
+                              &smc->reg->emcr);
                        break;
                case 2048:
                        ecc_page_size = 0x3;
                        /* Set the ECC memory config register */
                        writel((ZYNQ_NAND_ECC_CONFIG | ecc_page_size),
-                              &zynq_nand_smc_base->emcr);
+                              &smc->reg->emcr);
                        break;
                default:
                        nand_chip->ecc.mode = NAND_ECC_SOFT;
@@ -1241,14 +1266,12 @@ static int zynq_nand_probe(struct udevice *dev)
        /* Second phase scan */
        if (nand_scan_tail(mtd)) {
                printf("%s: nand_scan_tail failed\n", __func__);
-               goto fail;
+               return -EINVAL;
        }
        if (nand_register(0, mtd))
-               goto fail;
+               return -EINVAL;
+
        return 0;
-fail:
-       free(xnand);
-       return err;
 }
 
 static const struct udevice_id zynq_nand_dt_ids[] = {