Message ID | 20180821135743.31421-1-marex@denx.de |
---|---|
State | Deferred |
Delegated to: | Tom Rini |
Headers | show |
Series | [U-Boot] mtd: nand: denali_dt: Add reset support | expand |
Hi Marek, 2018-08-21 22:57 GMT+09:00 Marek Vasut <marex@denx.de>: > Add optional reset support into the Denali NAND driver. In case there is > a valid reset entry in the DT, the reset gets deasserted before the NAND > controller gets used. > > Signed-off-by: Marek Vasut <marex@denx.de> > Cc: Masahiro Yamada <yamada.masahiro@socionext.com> > --- > drivers/mtd/nand/denali_dt.c | 9 +++++++++ > 1 file changed, 9 insertions(+) > > diff --git a/drivers/mtd/nand/denali_dt.c b/drivers/mtd/nand/denali_dt.c > index 65a7797f0f..6fcd7d3843 100644 > --- a/drivers/mtd/nand/denali_dt.c > +++ b/drivers/mtd/nand/denali_dt.c > @@ -9,6 +9,7 @@ > #include <linux/io.h> > #include <linux/ioport.h> > #include <linux/printk.h> > +#include <reset.h> > > #include "denali.h" > > @@ -64,6 +65,7 @@ static int denali_dt_probe(struct udevice *dev) > const struct denali_dt_data *data; > struct clk clk; > struct resource res; > + struct reset_ctl reset_ctl; > int ret; > > data = (void *)dev_get_driver_data(dev); > @@ -97,6 +99,13 @@ static int denali_dt_probe(struct udevice *dev) > > denali->clk_x_rate = clk_get_rate(&clk); > > + ret = reset_get_by_index(dev, 0, &reset_ctl); > + if (!ret) { > + reset_assert(&reset_ctl); > + udelay(2); > + reset_deassert(&reset_ctl); > + } > + > return denali_init(denali); > } > I was testing this patch today because my SoC also has a reset line for NAND. This patch looks trivial enough, but if the NAND is reset here, my board fails to boot with "nand_base: timeout while waiting for chip to become ready" I do not know why. Please give me more time to figure out what is going on in my SoC. U-Boot SPL 2018.09-rc2-00106-g5f0d7e5-dirty (Aug 24 2018 - 22:00:33 +0900) Trying to boot from NOR U-Boot 2018.09-rc2-00106-g5f0d7e5-dirty (Aug 24 2018 - 22:00:33 +0900) SoC: LD4 (model 1, revision 3) Model: UniPhier LD4 Reference Board DRAM: 512 MiB SC: Micro Support Card (CPLD version 3.6) NAND: nand_base: timeout while waiting for chip to become ready
On 08/24/2018 03:05 PM, Masahiro Yamada wrote: > Hi Marek, Hi, > 2018-08-21 22:57 GMT+09:00 Marek Vasut <marex@denx.de>: >> Add optional reset support into the Denali NAND driver. In case there is >> a valid reset entry in the DT, the reset gets deasserted before the NAND >> controller gets used. >> >> Signed-off-by: Marek Vasut <marex@denx.de> >> Cc: Masahiro Yamada <yamada.masahiro@socionext.com> >> --- >> drivers/mtd/nand/denali_dt.c | 9 +++++++++ >> 1 file changed, 9 insertions(+) >> >> diff --git a/drivers/mtd/nand/denali_dt.c b/drivers/mtd/nand/denali_dt.c >> index 65a7797f0f..6fcd7d3843 100644 >> --- a/drivers/mtd/nand/denali_dt.c >> +++ b/drivers/mtd/nand/denali_dt.c >> @@ -9,6 +9,7 @@ >> #include <linux/io.h> >> #include <linux/ioport.h> >> #include <linux/printk.h> >> +#include <reset.h> >> >> #include "denali.h" >> >> @@ -64,6 +65,7 @@ static int denali_dt_probe(struct udevice *dev) >> const struct denali_dt_data *data; >> struct clk clk; >> struct resource res; >> + struct reset_ctl reset_ctl; >> int ret; >> >> data = (void *)dev_get_driver_data(dev); >> @@ -97,6 +99,13 @@ static int denali_dt_probe(struct udevice *dev) >> >> denali->clk_x_rate = clk_get_rate(&clk); >> >> + ret = reset_get_by_index(dev, 0, &reset_ctl); >> + if (!ret) { >> + reset_assert(&reset_ctl); >> + udelay(2); >> + reset_deassert(&reset_ctl); >> + } >> + >> return denali_init(denali); >> } >> > > > I was testing this patch today > because my SoC also has a reset line for NAND. > > > This patch looks trivial enough, > but if the NAND is reset here, > my board fails to boot with > "nand_base: timeout while waiting for chip to become ready" > > > I do not know why. > Please give me more time to figure out what is going on in my SoC. Sure. Maybe you need to un-reset more stuff or the reset polarity is wrong ?
On 08/24/2018 03:10 PM, Marek Vasut wrote: > On 08/24/2018 03:05 PM, Masahiro Yamada wrote: >> Hi Marek, > > Hi, > >> 2018-08-21 22:57 GMT+09:00 Marek Vasut <marex@denx.de>: >>> Add optional reset support into the Denali NAND driver. In case there is >>> a valid reset entry in the DT, the reset gets deasserted before the NAND >>> controller gets used. >>> >>> Signed-off-by: Marek Vasut <marex@denx.de> >>> Cc: Masahiro Yamada <yamada.masahiro@socionext.com> >>> --- >>> drivers/mtd/nand/denali_dt.c | 9 +++++++++ >>> 1 file changed, 9 insertions(+) >>> >>> diff --git a/drivers/mtd/nand/denali_dt.c b/drivers/mtd/nand/denali_dt.c >>> index 65a7797f0f..6fcd7d3843 100644 >>> --- a/drivers/mtd/nand/denali_dt.c >>> +++ b/drivers/mtd/nand/denali_dt.c >>> @@ -9,6 +9,7 @@ >>> #include <linux/io.h> >>> #include <linux/ioport.h> >>> #include <linux/printk.h> >>> +#include <reset.h> >>> >>> #include "denali.h" >>> >>> @@ -64,6 +65,7 @@ static int denali_dt_probe(struct udevice *dev) >>> const struct denali_dt_data *data; >>> struct clk clk; >>> struct resource res; >>> + struct reset_ctl reset_ctl; >>> int ret; >>> >>> data = (void *)dev_get_driver_data(dev); >>> @@ -97,6 +99,13 @@ static int denali_dt_probe(struct udevice *dev) >>> >>> denali->clk_x_rate = clk_get_rate(&clk); >>> >>> + ret = reset_get_by_index(dev, 0, &reset_ctl); >>> + if (!ret) { >>> + reset_assert(&reset_ctl); >>> + udelay(2); >>> + reset_deassert(&reset_ctl); >>> + } >>> + >>> return denali_init(denali); >>> } >>> >> >> >> I was testing this patch today >> because my SoC also has a reset line for NAND. >> >> >> This patch looks trivial enough, >> but if the NAND is reset here, >> my board fails to boot with >> "nand_base: timeout while waiting for chip to become ready" >> >> >> I do not know why. >> Please give me more time to figure out what is going on in my SoC. > > Sure. Maybe you need to un-reset more stuff or the reset polarity is wrong ? Did you figure something out ?
2018-09-05 17:31 GMT+09:00 Marek Vasut <marek.vasut@gmail.com>: > On 08/24/2018 03:10 PM, Marek Vasut wrote: >> On 08/24/2018 03:05 PM, Masahiro Yamada wrote: >>> Hi Marek, >> >> Hi, >> >>> 2018-08-21 22:57 GMT+09:00 Marek Vasut <marex@denx.de>: >>>> Add optional reset support into the Denali NAND driver. In case there is >>>> a valid reset entry in the DT, the reset gets deasserted before the NAND >>>> controller gets used. >>>> >>>> Signed-off-by: Marek Vasut <marex@denx.de> >>>> Cc: Masahiro Yamada <yamada.masahiro@socionext.com> >>>> --- >>>> drivers/mtd/nand/denali_dt.c | 9 +++++++++ >>>> 1 file changed, 9 insertions(+) >>>> >>>> diff --git a/drivers/mtd/nand/denali_dt.c b/drivers/mtd/nand/denali_dt.c >>>> index 65a7797f0f..6fcd7d3843 100644 >>>> --- a/drivers/mtd/nand/denali_dt.c >>>> +++ b/drivers/mtd/nand/denali_dt.c >>>> @@ -9,6 +9,7 @@ >>>> #include <linux/io.h> >>>> #include <linux/ioport.h> >>>> #include <linux/printk.h> >>>> +#include <reset.h> >>>> >>>> #include "denali.h" >>>> >>>> @@ -64,6 +65,7 @@ static int denali_dt_probe(struct udevice *dev) >>>> const struct denali_dt_data *data; >>>> struct clk clk; >>>> struct resource res; >>>> + struct reset_ctl reset_ctl; >>>> int ret; >>>> >>>> data = (void *)dev_get_driver_data(dev); >>>> @@ -97,6 +99,13 @@ static int denali_dt_probe(struct udevice *dev) >>>> >>>> denali->clk_x_rate = clk_get_rate(&clk); >>>> >>>> + ret = reset_get_by_index(dev, 0, &reset_ctl); >>>> + if (!ret) { >>>> + reset_assert(&reset_ctl); >>>> + udelay(2); >>>> + reset_deassert(&reset_ctl); >>>> + } >>>> + >>>> return denali_init(denali); >>>> } >>>> >>> >>> >>> I was testing this patch today >>> because my SoC also has a reset line for NAND. >>> >>> >>> This patch looks trivial enough, >>> but if the NAND is reset here, >>> my board fails to boot with >>> "nand_base: timeout while waiting for chip to become ready" >>> >>> >>> I do not know why. >>> Please give me more time to figure out what is going on in my SoC. >> >> Sure. Maybe you need to un-reset more stuff or the reset polarity is wrong ? I do not think so. The reset sequence of Denali is not so simple as you may think because the HW sequencer runs after the reset de-assertion. It includes some SoC-dependent parts. > > Did you figure something out ? > Just testing one of my boards. It booted by adding mdelay() after reset_deassert(). reset_assert(&reset_ctl); udelay(2); reset_deassert(&reset_ctl); mdelay(1); /* Why is this long delay required? */ I will read HW docs more, and talk to HW engineers to figure out the right solution.
On 09/06/2018 03:46 AM, Masahiro Yamada wrote: > 2018-09-05 17:31 GMT+09:00 Marek Vasut <marek.vasut@gmail.com>: >> On 08/24/2018 03:10 PM, Marek Vasut wrote: >>> On 08/24/2018 03:05 PM, Masahiro Yamada wrote: >>>> Hi Marek, >>> >>> Hi, >>> >>>> 2018-08-21 22:57 GMT+09:00 Marek Vasut <marex@denx.de>: >>>>> Add optional reset support into the Denali NAND driver. In case there is >>>>> a valid reset entry in the DT, the reset gets deasserted before the NAND >>>>> controller gets used. >>>>> >>>>> Signed-off-by: Marek Vasut <marex@denx.de> >>>>> Cc: Masahiro Yamada <yamada.masahiro@socionext.com> >>>>> --- >>>>> drivers/mtd/nand/denali_dt.c | 9 +++++++++ >>>>> 1 file changed, 9 insertions(+) >>>>> >>>>> diff --git a/drivers/mtd/nand/denali_dt.c b/drivers/mtd/nand/denali_dt.c >>>>> index 65a7797f0f..6fcd7d3843 100644 >>>>> --- a/drivers/mtd/nand/denali_dt.c >>>>> +++ b/drivers/mtd/nand/denali_dt.c >>>>> @@ -9,6 +9,7 @@ >>>>> #include <linux/io.h> >>>>> #include <linux/ioport.h> >>>>> #include <linux/printk.h> >>>>> +#include <reset.h> >>>>> >>>>> #include "denali.h" >>>>> >>>>> @@ -64,6 +65,7 @@ static int denali_dt_probe(struct udevice *dev) >>>>> const struct denali_dt_data *data; >>>>> struct clk clk; >>>>> struct resource res; >>>>> + struct reset_ctl reset_ctl; >>>>> int ret; >>>>> >>>>> data = (void *)dev_get_driver_data(dev); >>>>> @@ -97,6 +99,13 @@ static int denali_dt_probe(struct udevice *dev) >>>>> >>>>> denali->clk_x_rate = clk_get_rate(&clk); >>>>> >>>>> + ret = reset_get_by_index(dev, 0, &reset_ctl); >>>>> + if (!ret) { >>>>> + reset_assert(&reset_ctl); >>>>> + udelay(2); >>>>> + reset_deassert(&reset_ctl); >>>>> + } >>>>> + >>>>> return denali_init(denali); >>>>> } >>>>> >>>> >>>> >>>> I was testing this patch today >>>> because my SoC also has a reset line for NAND. >>>> >>>> >>>> This patch looks trivial enough, >>>> but if the NAND is reset here, >>>> my board fails to boot with >>>> "nand_base: timeout while waiting for chip to become ready" >>>> >>>> >>>> I do not know why. >>>> Please give me more time to figure out what is going on in my SoC. >>> >>> Sure. Maybe you need to un-reset more stuff or the reset polarity is wrong ? > > > I do not think so. > > The reset sequence of Denali is not so simple as you may think > because the HW sequencer runs after the reset de-assertion. > It includes some SoC-dependent parts. > > > >> >> Did you figure something out ? >> > > > Just testing one of my boards. > > It booted by adding mdelay() after reset_deassert(). > > > > reset_assert(&reset_ctl); > udelay(2); > reset_deassert(&reset_ctl); > mdelay(1); /* Why is this long delay required? */ It works right away after ungating the reset on my board. > I will read HW docs more, > and talk to HW engineers > to figure out the right solution. OK
Hi Marek, 2018-09-06 17:02 GMT+09:00 Marek Vasut <marek.vasut@gmail.com>: > On 09/06/2018 03:46 AM, Masahiro Yamada wrote: >> 2018-09-05 17:31 GMT+09:00 Marek Vasut <marek.vasut@gmail.com>: >>> On 08/24/2018 03:10 PM, Marek Vasut wrote: >>>> On 08/24/2018 03:05 PM, Masahiro Yamada wrote: >>>>> Hi Marek, >>>> >>>> Hi, >>>> >>>>> 2018-08-21 22:57 GMT+09:00 Marek Vasut <marex@denx.de>: >>>>>> Add optional reset support into the Denali NAND driver. In case there is >>>>>> a valid reset entry in the DT, the reset gets deasserted before the NAND >>>>>> controller gets used. >>>>>> >>>>>> Signed-off-by: Marek Vasut <marex@denx.de> >>>>>> Cc: Masahiro Yamada <yamada.masahiro@socionext.com> >>>>>> --- >>>>>> drivers/mtd/nand/denali_dt.c | 9 +++++++++ >>>>>> 1 file changed, 9 insertions(+) >>>>>> >>>>>> diff --git a/drivers/mtd/nand/denali_dt.c b/drivers/mtd/nand/denali_dt.c >>>>>> index 65a7797f0f..6fcd7d3843 100644 >>>>>> --- a/drivers/mtd/nand/denali_dt.c >>>>>> +++ b/drivers/mtd/nand/denali_dt.c >>>>>> @@ -9,6 +9,7 @@ >>>>>> #include <linux/io.h> >>>>>> #include <linux/ioport.h> >>>>>> #include <linux/printk.h> >>>>>> +#include <reset.h> >>>>>> >>>>>> #include "denali.h" >>>>>> >>>>>> @@ -64,6 +65,7 @@ static int denali_dt_probe(struct udevice *dev) >>>>>> const struct denali_dt_data *data; >>>>>> struct clk clk; >>>>>> struct resource res; >>>>>> + struct reset_ctl reset_ctl; >>>>>> int ret; >>>>>> >>>>>> data = (void *)dev_get_driver_data(dev); >>>>>> @@ -97,6 +99,13 @@ static int denali_dt_probe(struct udevice *dev) >>>>>> >>>>>> denali->clk_x_rate = clk_get_rate(&clk); >>>>>> >>>>>> + ret = reset_get_by_index(dev, 0, &reset_ctl); >>>>>> + if (!ret) { >>>>>> + reset_assert(&reset_ctl); >>>>>> + udelay(2); >>>>>> + reset_deassert(&reset_ctl); >>>>>> + } >>>>>> + >>>>>> return denali_init(denali); >>>>>> } >>>>>> >>>>> >>>>> >>>>> I was testing this patch today >>>>> because my SoC also has a reset line for NAND. >>>>> >>>>> >>>>> This patch looks trivial enough, >>>>> but if the NAND is reset here, >>>>> my board fails to boot with >>>>> "nand_base: timeout while waiting for chip to become ready" >>>>> >>>>> >>>>> I do not know why. >>>>> Please give me more time to figure out what is going on in my SoC. >>>> >>>> Sure. Maybe you need to un-reset more stuff or the reset polarity is wrong ? >> >> >> I do not think so. >> >> The reset sequence of Denali is not so simple as you may think >> because the HW sequencer runs after the reset de-assertion. >> It includes some SoC-dependent parts. >> >> >> >>> >>> Did you figure something out ? >>> >> >> >> Just testing one of my boards. >> >> It booted by adding mdelay() after reset_deassert(). >> >> >> >> reset_assert(&reset_ctl); >> udelay(2); >> reset_deassert(&reset_ctl); >> mdelay(1); /* Why is this long delay required? */ > > It works right away after ungating the reset on my board. With my further tests, it typically takes 200 usec for the chip identification sequence after the reset de-assertion. The number is for my UniPhier SoC family. This part is SoC-dependent, so the situation is probably different for SOCFPGA. I'd like to suggest the following sequence. reset_assert(&reset_ctl); udelay(1); reset_deassert(&reset_ctl); udelay(200); Is this OK with you? The IP datasheet says that the reset lines should be kept 10 clock cycles. I think udelay(1) is good enough for reset assertion. BTW, are you applying this patch to your tree? Or, do you want me to pick this up? >> I will read HW docs more, >> and talk to HW engineers >> to figure out the right solution. > > OK
diff --git a/drivers/mtd/nand/denali_dt.c b/drivers/mtd/nand/denali_dt.c index 65a7797f0f..6fcd7d3843 100644 --- a/drivers/mtd/nand/denali_dt.c +++ b/drivers/mtd/nand/denali_dt.c @@ -9,6 +9,7 @@ #include <linux/io.h> #include <linux/ioport.h> #include <linux/printk.h> +#include <reset.h> #include "denali.h" @@ -64,6 +65,7 @@ static int denali_dt_probe(struct udevice *dev) const struct denali_dt_data *data; struct clk clk; struct resource res; + struct reset_ctl reset_ctl; int ret; data = (void *)dev_get_driver_data(dev); @@ -97,6 +99,13 @@ static int denali_dt_probe(struct udevice *dev) denali->clk_x_rate = clk_get_rate(&clk); + ret = reset_get_by_index(dev, 0, &reset_ctl); + if (!ret) { + reset_assert(&reset_ctl); + udelay(2); + reset_deassert(&reset_ctl); + } + return denali_init(denali); }
Add optional reset support into the Denali NAND driver. In case there is a valid reset entry in the DT, the reset gets deasserted before the NAND controller gets used. Signed-off-by: Marek Vasut <marex@denx.de> Cc: Masahiro Yamada <yamada.masahiro@socionext.com> --- drivers/mtd/nand/denali_dt.c | 9 +++++++++ 1 file changed, 9 insertions(+)