Hi Christophe

On 7/31/20 9:53 AM, Christophe Kerello wrote:
> FMC2 EBI support has been added. Common resources (registers base
> address and clock) can now be shared between the 2 drivers using
> "st,stm32mp1-fmc2-nfc" compatible string. It means that the
> common resources should now be found in the parent device when EBI
> node is available.
>
> Signed-off-by: Christophe Kerello <christophe.kere...@st.com>
> ---
>
>  drivers/mtd/nand/raw/stm32_fmc2_nand.c | 87 
> +++++++++++++++++++++++-----------
>  1 file changed, 59 insertions(+), 28 deletions(-)
>
> diff --git a/drivers/mtd/nand/raw/stm32_fmc2_nand.c 
> b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
> index 1e4d757..47fe610 100644
> --- a/drivers/mtd/nand/raw/stm32_fmc2_nand.c
> +++ b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
> @@ -158,10 +158,10 @@ struct stm32_fmc2_nfc {
>       struct nand_hw_control base;
>       struct stm32_fmc2_nand nand;
>       struct nand_ecclayout ecclayout;
> -     void __iomem *io_base;
> -     void __iomem *data_base[FMC2_MAX_CE];
> -     void __iomem *cmd_base[FMC2_MAX_CE];
> -     void __iomem *addr_base[FMC2_MAX_CE];
> +     fdt_addr_t io_base;
> +     fdt_addr_t data_base[FMC2_MAX_CE];
> +     fdt_addr_t cmd_base[FMC2_MAX_CE];
> +     fdt_addr_t addr_base[FMC2_MAX_CE];
>       struct clk clk;
>  
>       u8 cs_assigned;
> @@ -241,8 +241,8 @@ static void stm32_fmc2_nfc_select_chip(struct mtd_info 
> *mtd, int chipnr)
>               return;
>  
>       nfc->cs_sel = nand->cs_used[chipnr];
> -     chip->IO_ADDR_R = nfc->data_base[nfc->cs_sel];
> -     chip->IO_ADDR_W = nfc->data_base[nfc->cs_sel];
> +     chip->IO_ADDR_R = (void __iomem *)nfc->data_base[nfc->cs_sel];
> +     chip->IO_ADDR_W = (void __iomem *)nfc->data_base[nfc->cs_sel];
>  
>       stm32_fmc2_nfc_setup(chip);
>       stm32_fmc2_nfc_timings_init(chip);
> @@ -548,7 +548,7 @@ static int stm32_fmc2_nfc_read_page(struct mtd_info *mtd,
>       return max_bitflips;
>  }
>  
> -static void stm32_fmc2_nfc_init(struct stm32_fmc2_nfc *nfc)
> +static void stm32_fmc2_nfc_init(struct stm32_fmc2_nfc *nfc, bool has_parent)
>  {
>       u32 pcr = readl(nfc->io_base + FMC2_PCR);
>  
> @@ -581,7 +581,8 @@ static void stm32_fmc2_nfc_init(struct stm32_fmc2_nfc 
> *nfc)
>       pcr |= FIELD_PREP(FMC2_PCR_TAR, FMC2_PCR_TAR_DEFAULT);
>  
>       /* Enable FMC2 controller */
> -     setbits_le32(nfc->io_base + FMC2_BCR1, FMC2_BCR1_FMC2EN);
> +     if (!has_parent)
> +             setbits_le32(nfc->io_base + FMC2_BCR1, FMC2_BCR1_FMC2EN);
>  
>       writel(pcr, nfc->io_base + FMC2_PCR);
>       writel(FMC2_PMEM_DEFAULT, nfc->io_base + FMC2_PMEM);
> @@ -854,6 +855,30 @@ static int stm32_fmc2_nfc_parse_dt(struct udevice *dev,
>       return 0;
>  }
>  
> +static struct udevice *stm32_fmc2_nfc_get_cdev(struct udevice *dev)
> +{
> +     struct udevice *pdev = dev_get_parent(dev);
> +     struct udevice *cdev = NULL;
> +     bool ebi_found = false;
> +
> +     if (pdev && ofnode_device_is_compatible(dev_ofnode(pdev),
> +                                             "st,stm32mp1-fmc2-ebi"))
> +             ebi_found = true;
> +
> +     if (ofnode_device_is_compatible(dev_ofnode(dev),
> +                                     "st,stm32mp1-fmc2-nfc")) {
> +             if (ebi_found)
> +                     cdev = pdev;
> +
> +             return cdev;
> +     }
> +
> +     if (!ebi_found)
> +             cdev = dev;
> +
> +     return cdev;
> +}
> +
>  static int stm32_fmc2_nfc_probe(struct udevice *dev)
>  {
>       struct stm32_fmc2_nfc *nfc = dev_get_priv(dev);
> @@ -861,58 +886,63 @@ static int stm32_fmc2_nfc_probe(struct udevice *dev)
>       struct nand_chip *chip = &nand->chip;
>       struct mtd_info *mtd = &chip->mtd;
>       struct nand_ecclayout *ecclayout;
> -     struct resource resource;
> +     struct udevice *cdev;
>       struct reset_ctl reset;
>       int oob_index, chip_cs, mem_region, ret;
>       unsigned int i;
> +     int start_region = 0;
> +     fdt_addr_t addr;
>  
>       spin_lock_init(&nfc->controller.lock);
>       init_waitqueue_head(&nfc->controller.wq);
>  
> +     cdev = stm32_fmc2_nfc_get_cdev(dev);
> +     if (!cdev)
> +             return -EINVAL;
> +
>       ret = stm32_fmc2_nfc_parse_dt(dev, nfc);
>       if (ret)
>               return ret;
>  
> -     /* Get resources */
> -     ret = dev_read_resource(dev, 0, &resource);
> -     if (ret) {
> -             pr_err("Resource io_base not found");
> -             return ret;
> -     }
> -     nfc->io_base = (void __iomem *)resource.start;
> +     nfc->io_base = dev_read_addr(cdev);
> +     if (nfc->io_base == FDT_ADDR_T_NONE)
> +             return -EINVAL;
> +
> +     if (dev == cdev)
> +             start_region = 1;
>  
> -     for (chip_cs = 0, mem_region = 1; chip_cs < FMC2_MAX_CE;
> +     for (chip_cs = 0, mem_region = start_region; chip_cs < FMC2_MAX_CE;
>            chip_cs++, mem_region += 3) {
>               if (!(nfc->cs_assigned & BIT(chip_cs)))
>                       continue;
>  
> -             ret = dev_read_resource(dev, mem_region, &resource);
> -             if (ret) {
> +             addr = dev_read_addr_index(dev, mem_region);
> +             if (addr == FDT_ADDR_T_NONE) {
>                       pr_err("Resource data_base not found for cs%d",
>                              chip_cs);
>                       return ret;
>               }
> -             nfc->data_base[chip_cs] = (void __iomem *)resource.start;
> +             nfc->data_base[chip_cs] = addr;
>  
> -             ret = dev_read_resource(dev, mem_region + 1, &resource);
> -             if (ret) {
> +             addr = dev_read_addr_index(dev, mem_region + 1);
> +             if (addr == FDT_ADDR_T_NONE) {
>                       pr_err("Resource cmd_base not found for cs%d",
>                              chip_cs);
>                       return ret;
>               }
> -             nfc->cmd_base[chip_cs] = (void __iomem *)resource.start;
> +             nfc->cmd_base[chip_cs] = addr;
>  
> -             ret = dev_read_resource(dev, mem_region + 2, &resource);
> -             if (ret) {
> +             addr = dev_read_addr_index(dev, mem_region + 2);
> +             if (addr == FDT_ADDR_T_NONE) {
>                       pr_err("Resource addr_base not found for cs%d",
>                              chip_cs);
>                       return ret;
>               }
> -             nfc->addr_base[chip_cs] = (void __iomem *)resource.start;
> +             nfc->addr_base[chip_cs] = addr;
>       }
>  
>       /* Enable the clock */
> -     ret = clk_get_by_index(dev, 0, &nfc->clk);
> +     ret = clk_get_by_index(cdev, 0, &nfc->clk);
>       if (ret)
>               return ret;
>  
> @@ -928,7 +958,7 @@ static int stm32_fmc2_nfc_probe(struct udevice *dev)
>               reset_deassert(&reset);
>       }
>  
> -     stm32_fmc2_nfc_init(nfc);
> +     stm32_fmc2_nfc_init(nfc, dev != cdev);
>  
>       chip->controller = &nfc->base;
>       chip->select_chip = stm32_fmc2_nfc_select_chip;
> @@ -994,6 +1024,7 @@ static int stm32_fmc2_nfc_probe(struct udevice *dev)
>  
>  static const struct udevice_id stm32_fmc2_nfc_match[] = {
>       { .compatible = "st,stm32mp15-fmc2" },
> +     { .compatible = "st,stm32mp1-fmc2-nfc" },
>       { /* Sentinel */ }
>  };
>  

Reviewed-by: Patrice Chotard <patrice.chot...@st.com>

Thanks

Patrice

Reply via email to