On 8/13/20 9:33 AM, Patrice CHOTARD wrote:
> 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(-)

Applied on u-boot-stm/master

Thanks

>>
>> 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