Message ID | CAP9ODKpAarHeQ3w7dwChkNd7+AY7u3xdBXr4df3Fx2TBTakVtg@mail.gmail.com |
---|---|
State | Not Applicable |
Delegated to: | Stefano Babic |
Headers | show |
Hi Otavio, Le Tue, 26 Nov 2013 12:32:45 -0200, Otavio Salvador <otavio@ossystems.com.br> a écrit : > Hello, > > last days I've been trying to isolate the hung cause of a customer > board, and also SabreSD board, when using the Freescale's Linux fork > of 3.10.9 with 2013.10 U-Boot. > > The below patch makes it work fine but it does not seem to be possible > to upstream this fix, that way. How you guys thing this could be > properly integrated into U-Boot to not break other boards? > > diff --git a/arch/arm/cpu/armv7/mx6/soc.c b/arch/arm/cpu/armv7/mx6/soc.c > index a390296..08f3eda 100644 > --- a/arch/arm/cpu/armv7/mx6/soc.c > +++ b/arch/arm/cpu/armv7/mx6/soc.c > @@ -131,6 +131,34 @@ static void imx_set_wdog_powerdown(bool enable) > writew(enable, &wdog2->wmcr); > } > > +static void imx_set_vddpu_power_down(void) > +{ > + struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR; > + u32 val; > + > + /* need to power down xPU in GPC before turn off PU LDO */ > + val = readl(GPC_BASE_ADDR + 0x260); > + writel(val | 0x1, GPC_BASE_ADDR + 0x260); > + > + val = readl(GPC_BASE_ADDR + 0x0); > + writel(val | 0x1, GPC_BASE_ADDR + 0x0); > + while (readl(GPC_BASE_ADDR + 0x0) & 0x1) > + ; > + > + /* disable VDDPU */ > + val = 0x3e00; > + writel(val, &anatop->reg_core_clr); > +} > + > +static void imx_set_pcie_phy_power_down(void) > +{ > + u32 val; > + > + val = readl(IOMUXC_BASE_ADDR + 0x4); > + val |= 0x1 << 18; > + writel(val, IOMUXC_BASE_ADDR + 0x4); > +} > + > int arch_cpu_init(void) > { > init_aips(); > @@ -139,6 +167,9 @@ int arch_cpu_init(void) > > imx_set_wdog_powerdown(false); /* Disable PDE bit of WMCR register */ > > + imx_set_pcie_phy_power_down(); > + imx_set_vddpu_power_down(); > + > #ifdef CONFIG_APBH_DMA > /* Start APBH DMA */ > mxs_dma_init(); > diff --git a/arch/arm/imx-common/cpu.c b/arch/arm/imx-common/cpu.c > index 0cd2538..5cac1a9 100644 > --- a/arch/arm/imx-common/cpu.c > +++ b/arch/arm/imx-common/cpu.c > @@ -171,9 +171,21 @@ u32 get_ahb_clk(void) > return get_periph_clk() / (ahb_podf + 1); > } > > +static void set_anatop_bypass(void) > +{ > + struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR; > + u32 reg = readl(&anatop->reg_core); > + > + /* bypass VDDARM/VDDSOC */ > + reg = reg | (0x1F << 18) | 0x1F; > + writel(reg, &anatop->reg_core); > +} > + > #if defined(CONFIG_VIDEO_IPUV3) > void arch_preboot_os(void) > { > + set_anatop_bypass(); > + > /* disable video before launching O/S */ > ipuv3_fb_shutdown(); > } > isn't the last change (enabling bypass) sufficient to fix the problem or do you also need the 2 power_down before ? Do you also get the kernel freeze without changing anything in u-boot when you disable cpufreq in the kernel ? Eric
Dear Otavio, In message <CAP9ODKpAarHeQ3w7dwChkNd7+AY7u3xdBXr4df3Fx2TBTakVtg@mail.gmail.com> you wrote: > > last days I've been trying to isolate the hung cause of a customer > board, and also SabreSD board, when using the Freescale's Linux fork > of 3.10.9 with 2013.10 U-Boot. Do I understand correctly that this happens only with the FSL kernel, i. e. not with mainline Linux? What exactly is the effect of calling your set_anatop_bypass() function? Why would that be needed on the FSL kernel, and not on mainline? Best regards, Wolfgang Denk
On Tue, Nov 26, 2013 at 1:39 PM, Wolfgang Denk <wd@denx.de> wrote: > Dear Otavio, > > In message <CAP9ODKpAarHeQ3w7dwChkNd7+AY7u3xdBXr4df3Fx2TBTakVtg@mail.gmail.com> you wrote: >> >> last days I've been trying to isolate the hung cause of a customer >> board, and also SabreSD board, when using the Freescale's Linux fork >> of 3.10.9 with 2013.10 U-Boot. > > Do I understand correctly that this happens only with the FSL kernel, > i. e. not with mainline Linux? Exactly. > What exactly is the effect of calling your set_anatop_bypass() > function? Why would that be needed on the FSL kernel, and not on > mainline? Mainline seems to not drive the pmic while the FSL kernel does. So it seems we ought to bypass the internal LDO.
Dear Otavio Salvador, In message <CAP9ODKqBwH+LfhTcPMBn1ppUtfpfUnUyyN8CTi=akwja1ka6Qg@mail.gmail.com> you wrote: > > > Do I understand correctly that this happens only with the FSL kernel, > > i. e. not with mainline Linux? > > Exactly. > > > What exactly is the effect of calling your set_anatop_bypass() > > function? Why would that be needed on the FSL kernel, and not on > > mainline? > > Mainline seems to not drive the pmic while the FSL kernel does. So it > seems we ought to bypass the internal LDO. Or rather fix the FSL kernel? Best regards, Wolfgang Denk
On Wed, Nov 27, 2013 at 4:40 AM, Wolfgang Denk <wd@denx.de> wrote: > Dear Otavio Salvador, > > In message <CAP9ODKqBwH+LfhTcPMBn1ppUtfpfUnUyyN8CTi=akwja1ka6Qg@mail.gmail.com> you wrote: >> >> > Do I understand correctly that this happens only with the FSL kernel, >> > i. e. not with mainline Linux? >> >> Exactly. >> >> > What exactly is the effect of calling your set_anatop_bypass() >> > function? Why would that be needed on the FSL kernel, and not on >> > mainline? >> >> Mainline seems to not drive the pmic while the FSL kernel does. So it >> seems we ought to bypass the internal LDO. > > Or rather fix the FSL kernel? I am not sure the kernel is wrong here. As I said in previous message, the mainline kernel does not drive the PMIC and the power sources are the internal LDO. The FSL kernel changes the power sources to the ones from the PMIC (which makes sense) but in the end it depends on U-Boot have done it too.
diff --git a/arch/arm/cpu/armv7/mx6/soc.c b/arch/arm/cpu/armv7/mx6/soc.c index a390296..08f3eda 100644 --- a/arch/arm/cpu/armv7/mx6/soc.c +++ b/arch/arm/cpu/armv7/mx6/soc.c @@ -131,6 +131,34 @@ static void imx_set_wdog_powerdown(bool enable) writew(enable, &wdog2->wmcr); } +static void imx_set_vddpu_power_down(void) +{ + struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR; + u32 val; + + /* need to power down xPU in GPC before turn off PU LDO */ + val = readl(GPC_BASE_ADDR + 0x260); + writel(val | 0x1, GPC_BASE_ADDR + 0x260); + + val = readl(GPC_BASE_ADDR + 0x0); + writel(val | 0x1, GPC_BASE_ADDR + 0x0); + while (readl(GPC_BASE_ADDR + 0x0) & 0x1) + ; + + /* disable VDDPU */ + val = 0x3e00; + writel(val, &anatop->reg_core_clr); +} + +static void imx_set_pcie_phy_power_down(void) +{ + u32 val; + + val = readl(IOMUXC_BASE_ADDR + 0x4); + val |= 0x1 << 18; + writel(val, IOMUXC_BASE_ADDR + 0x4); +} + int arch_cpu_init(void) { init_aips(); @@ -139,6 +167,9 @@ int arch_cpu_init(void) imx_set_wdog_powerdown(false); /* Disable PDE bit of WMCR register */ + imx_set_pcie_phy_power_down(); + imx_set_vddpu_power_down(); + #ifdef CONFIG_APBH_DMA /* Start APBH DMA */ mxs_dma_init(); diff --git a/arch/arm/imx-common/cpu.c b/arch/arm/imx-common/cpu.c index 0cd2538..5cac1a9 100644 --- a/arch/arm/imx-common/cpu.c +++ b/arch/arm/imx-common/cpu.c @@ -171,9 +171,21 @@ u32 get_ahb_clk(void) return get_periph_clk() / (ahb_podf + 1); } +static void set_anatop_bypass(void) +{ + struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR; + u32 reg = readl(&anatop->reg_core); + + /* bypass VDDARM/VDDSOC */ + reg = reg | (0x1F << 18) | 0x1F; + writel(reg, &anatop->reg_core); +} + #if defined(CONFIG_VIDEO_IPUV3) void arch_preboot_os(void) { + set_anatop_bypass(); + /* disable video before launching O/S */ ipuv3_fb_shutdown(); }