mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-03 23:58:05 +00:00
The imx fixes for 3.13:
- A couple of imx5 and imx6 clock fixes - Two follow-up patches for improving/fixing the commit "ARM: imx: replace imx6q_restart()with mxc_restart()" - One compile fix for imx6sl with randconfig - Commits to fix pllv3 relock/power issues found in IPU/HDMI testing -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) iQEcBAABAgAGBQJSgPeFAAoJEFBXWFqHsHzON9cH/0HBoqVK11d0F5BbZgRGoBwt U4jOoww1I04nAi4PcWfcnfFjyfyFl8dm5NovFsMUsTmSQHG/8Wo0dViDGlk0R/WS Tw3L6shoXJaHEfCXrK+K1iZrxXNzfzXhaZwDrGSIkddmodZUrgeWOJ6zQP+GVGqM rNr6nDIIIRd7LO60m1LiWg2wqHzVMBQrLIX4Vd+wDtzoLVG0BhCfxBZ+ekFhyfgV WYDu1phulrhhywpNkHsake2nI0QcTmfBWMRzuDTGXp9vdC0fjf6aGRHklUr0N2GK yetnlugfeSBVUuKjm2TO8Kr65d2dk7YyopthpkB+Bel1Y92yYTonN490apyYgRc= =OTBh -----END PGP SIGNATURE----- Merge tag 'imx-fixes-3.13' of git://git.linaro.org/people/shawnguo/linux-2.6 into fixes From Shawn Guo, imx fixes for 3.13: - A couple of imx5 and imx6 clock fixes - Two follow-up patches for improving/fixing the commit "ARM: imx: replace imx6q_restart()with mxc_restart()" - One compile fix for imx6sl with randconfig - Commits to fix pllv3 relock/power issues found in IPU/HDMI testing * tag 'imx-fixes-3.13' of git://git.linaro.org/people/shawnguo/linux-2.6: ARM: dts: i.MX51: Fix OTG PHY clock ARM: imx: set up pllv3 POWER and BYPASS sequentially ARM: imx: pllv3 needs relock in .set_rate() call ARM: imx: add sleep for pllv3 relock ARM: imx6q: add missing sentinel to divider table ARM: imx: v7_cpu_resume() is needed by imx6sl build ARM: imx: improve mxc_restart() on the SRC bit writes ARM: imx: remove imx_src_prepare_restart() call ARM: i.MX6q: fix the wrong parent of can_root clock
This commit is contained in:
commit
004f47bcad
7 changed files with 50 additions and 48 deletions
|
@ -190,7 +190,7 @@ esdhc4: esdhc@70024000 {
|
|||
|
||||
usbphy0: usbphy@0 {
|
||||
compatible = "usb-nop-xceiv";
|
||||
clocks = <&clks 124>;
|
||||
clocks = <&clks 75>;
|
||||
clock-names = "main_clk";
|
||||
status = "okay";
|
||||
};
|
||||
|
|
|
@ -102,8 +102,8 @@ obj-$(CONFIG_SOC_IMX6SL) += clk-imx6sl.o mach-imx6sl.o
|
|||
|
||||
ifeq ($(CONFIG_PM),y)
|
||||
obj-$(CONFIG_SOC_IMX6Q) += pm-imx6q.o headsmp.o
|
||||
# i.MX6SL reuses pm-imx6q.c
|
||||
obj-$(CONFIG_SOC_IMX6SL) += pm-imx6q.o
|
||||
# i.MX6SL reuses i.MX6Q code
|
||||
obj-$(CONFIG_SOC_IMX6SL) += pm-imx6q.o headsmp.o
|
||||
endif
|
||||
|
||||
# i.MX5 based machines
|
||||
|
|
|
@ -122,13 +122,14 @@ static struct clk_div_table clk_enet_ref_table[] = {
|
|||
{ .val = 1, .div = 10, },
|
||||
{ .val = 2, .div = 5, },
|
||||
{ .val = 3, .div = 4, },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
static struct clk_div_table post_div_table[] = {
|
||||
{ .val = 2, .div = 1, },
|
||||
{ .val = 1, .div = 2, },
|
||||
{ .val = 0, .div = 4, },
|
||||
{ }
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
static struct clk_div_table video_div_table[] = {
|
||||
|
@ -136,7 +137,7 @@ static struct clk_div_table video_div_table[] = {
|
|||
{ .val = 1, .div = 2, },
|
||||
{ .val = 2, .div = 1, },
|
||||
{ .val = 3, .div = 4, },
|
||||
{ }
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
static void __init imx6q_clocks_init(struct device_node *ccm_node)
|
||||
|
@ -298,7 +299,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
|
|||
clk[asrc_podf] = imx_clk_divider("asrc_podf", "asrc_pred", base + 0x30, 9, 3);
|
||||
clk[spdif_pred] = imx_clk_divider("spdif_pred", "spdif_sel", base + 0x30, 25, 3);
|
||||
clk[spdif_podf] = imx_clk_divider("spdif_podf", "spdif_pred", base + 0x30, 22, 3);
|
||||
clk[can_root] = imx_clk_divider("can_root", "pll3_usb_otg", base + 0x20, 2, 6);
|
||||
clk[can_root] = imx_clk_divider("can_root", "pll3_60m", base + 0x20, 2, 6);
|
||||
clk[ecspi_root] = imx_clk_divider("ecspi_root", "pll3_60m", base + 0x38, 19, 6);
|
||||
clk[gpu2d_core_podf] = imx_clk_divider("gpu2d_core_podf", "gpu2d_core_sel", base + 0x18, 23, 3);
|
||||
clk[gpu3d_core_podf] = imx_clk_divider("gpu3d_core_podf", "gpu3d_core_sel", base + 0x18, 26, 3);
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/jiffies.h>
|
||||
|
@ -45,33 +46,49 @@ struct clk_pllv3 {
|
|||
|
||||
#define to_clk_pllv3(_hw) container_of(_hw, struct clk_pllv3, hw)
|
||||
|
||||
static int clk_pllv3_prepare(struct clk_hw *hw)
|
||||
static int clk_pllv3_wait_lock(struct clk_pllv3 *pll)
|
||||
{
|
||||
struct clk_pllv3 *pll = to_clk_pllv3(hw);
|
||||
unsigned long timeout;
|
||||
u32 val;
|
||||
unsigned long timeout = jiffies + msecs_to_jiffies(10);
|
||||
u32 val = readl_relaxed(pll->base) & BM_PLL_POWER;
|
||||
|
||||
val = readl_relaxed(pll->base);
|
||||
val &= ~BM_PLL_BYPASS;
|
||||
if (pll->powerup_set)
|
||||
val |= BM_PLL_POWER;
|
||||
else
|
||||
val &= ~BM_PLL_POWER;
|
||||
writel_relaxed(val, pll->base);
|
||||
/* No need to wait for lock when pll is not powered up */
|
||||
if ((pll->powerup_set && !val) || (!pll->powerup_set && val))
|
||||
return 0;
|
||||
|
||||
timeout = jiffies + msecs_to_jiffies(10);
|
||||
/* Wait for PLL to lock */
|
||||
do {
|
||||
if (readl_relaxed(pll->base) & BM_PLL_LOCK)
|
||||
break;
|
||||
if (time_after(jiffies, timeout))
|
||||
break;
|
||||
usleep_range(50, 500);
|
||||
} while (1);
|
||||
|
||||
if (readl_relaxed(pll->base) & BM_PLL_LOCK)
|
||||
return 0;
|
||||
return readl_relaxed(pll->base) & BM_PLL_LOCK ? 0 : -ETIMEDOUT;
|
||||
}
|
||||
|
||||
static int clk_pllv3_prepare(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_pllv3 *pll = to_clk_pllv3(hw);
|
||||
u32 val;
|
||||
int ret;
|
||||
|
||||
val = readl_relaxed(pll->base);
|
||||
if (pll->powerup_set)
|
||||
val |= BM_PLL_POWER;
|
||||
else
|
||||
return -ETIMEDOUT;
|
||||
val &= ~BM_PLL_POWER;
|
||||
writel_relaxed(val, pll->base);
|
||||
|
||||
ret = clk_pllv3_wait_lock(pll);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
val = readl_relaxed(pll->base);
|
||||
val &= ~BM_PLL_BYPASS;
|
||||
writel_relaxed(val, pll->base);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void clk_pllv3_unprepare(struct clk_hw *hw)
|
||||
|
@ -146,7 +163,7 @@ static int clk_pllv3_set_rate(struct clk_hw *hw, unsigned long rate,
|
|||
val |= div;
|
||||
writel_relaxed(val, pll->base);
|
||||
|
||||
return 0;
|
||||
return clk_pllv3_wait_lock(pll);
|
||||
}
|
||||
|
||||
static const struct clk_ops clk_pllv3_ops = {
|
||||
|
@ -202,7 +219,7 @@ static int clk_pllv3_sys_set_rate(struct clk_hw *hw, unsigned long rate,
|
|||
val |= div;
|
||||
writel_relaxed(val, pll->base);
|
||||
|
||||
return 0;
|
||||
return clk_pllv3_wait_lock(pll);
|
||||
}
|
||||
|
||||
static const struct clk_ops clk_pllv3_sys_ops = {
|
||||
|
@ -276,7 +293,7 @@ static int clk_pllv3_av_set_rate(struct clk_hw *hw, unsigned long rate,
|
|||
writel_relaxed(mfn, pll->base + PLL_NUM_OFFSET);
|
||||
writel_relaxed(mfd, pll->base + PLL_DENOM_OFFSET);
|
||||
|
||||
return 0;
|
||||
return clk_pllv3_wait_lock(pll);
|
||||
}
|
||||
|
||||
static const struct clk_ops clk_pllv3_av_ops = {
|
||||
|
|
|
@ -127,11 +127,6 @@ static inline void imx_smp_prepare(void) {}
|
|||
static inline void imx_scu_standby_enable(void) {}
|
||||
#endif
|
||||
void imx_src_init(void);
|
||||
#ifdef CONFIG_HAVE_IMX_SRC
|
||||
void imx_src_prepare_restart(void);
|
||||
#else
|
||||
static inline void imx_src_prepare_restart(void) {}
|
||||
#endif
|
||||
void imx_gpc_init(void);
|
||||
void imx_gpc_pre_suspend(void);
|
||||
void imx_gpc_post_resume(void);
|
||||
|
|
|
@ -115,21 +115,6 @@ void imx_set_cpu_arg(int cpu, u32 arg)
|
|||
writel_relaxed(arg, src_base + SRC_GPR1 + cpu * 8 + 4);
|
||||
}
|
||||
|
||||
void imx_src_prepare_restart(void)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
/* clear enable bits of secondary cores */
|
||||
spin_lock(&scr_lock);
|
||||
val = readl_relaxed(src_base + SRC_SCR);
|
||||
val &= ~(0x7 << BP_SRC_SCR_CORE1_ENABLE);
|
||||
writel_relaxed(val, src_base + SRC_SCR);
|
||||
spin_unlock(&scr_lock);
|
||||
|
||||
/* clear persistent entry register of primary core */
|
||||
writel_relaxed(0, src_base + SRC_GPR1);
|
||||
}
|
||||
|
||||
void __init imx_src_init(void)
|
||||
{
|
||||
struct device_node *np;
|
||||
|
|
|
@ -42,9 +42,6 @@ void mxc_restart(enum reboot_mode mode, const char *cmd)
|
|||
{
|
||||
unsigned int wcr_enable;
|
||||
|
||||
if (cpu_is_imx6q() || cpu_is_imx6dl())
|
||||
imx_src_prepare_restart();
|
||||
|
||||
if (wdog_clk)
|
||||
clk_enable(wdog_clk);
|
||||
|
||||
|
@ -55,7 +52,14 @@ void mxc_restart(enum reboot_mode mode, const char *cmd)
|
|||
|
||||
/* Assert SRS signal */
|
||||
__raw_writew(wcr_enable, wdog_base);
|
||||
/* write twice to ensure the request will not get ignored */
|
||||
/*
|
||||
* Due to imx6q errata ERR004346 (WDOG: WDOG SRS bit requires to be
|
||||
* written twice), we add another two writes to ensure there must be at
|
||||
* least two writes happen in the same one 32kHz clock period. We save
|
||||
* the target check here, since the writes shouldn't be a huge burden
|
||||
* for other platforms.
|
||||
*/
|
||||
__raw_writew(wcr_enable, wdog_base);
|
||||
__raw_writew(wcr_enable, wdog_base);
|
||||
|
||||
/* wait for reset to assert... */
|
||||
|
|
Loading…
Reference in a new issue