diff options
author | Jong Kim <jongk@nvidia.com> | 2012-02-29 17:26:05 -0800 |
---|---|---|
committer | Simone Willett <swillett@nvidia.com> | 2012-03-06 21:16:18 -0800 |
commit | bced65d187c0e46389a389be1d701720c028b159 (patch) | |
tree | fab73232f9d201a9e59675ad315de7d1d2837d51 /arch/arm/mach-tegra/tegra3_clocks.c | |
parent | 5143b51f02f1f33a0633b11ac1b16f879fc02032 (diff) |
ARM: tegra: clock: Put Cardhu clocks to known state
Add TEGRA_PREINIT_CLOCKS option to put host1x, disp1, and audio clocks
into known state, so that L4T Cardhu works on u-boot.
BUG 931602
Change-Id: I7c5aaff340a072fe6587822eccc89df72b2b1d79
Signed-off-by: Jong Kim <jongk@nvidia.com>
Reviewed-on: http://git-master/r/86725
Reviewed-by: Simone Willett <swillett@nvidia.com>
Tested-by: Simone Willett <swillett@nvidia.com>
Diffstat (limited to 'arch/arm/mach-tegra/tegra3_clocks.c')
-rw-r--r-- | arch/arm/mach-tegra/tegra3_clocks.c | 172 |
1 files changed, 172 insertions, 0 deletions
diff --git a/arch/arm/mach-tegra/tegra3_clocks.c b/arch/arm/mach-tegra/tegra3_clocks.c index de51b1e7627e..99878dd6fb3a 100644 --- a/arch/arm/mach-tegra/tegra3_clocks.c +++ b/arch/arm/mach-tegra/tegra3_clocks.c @@ -4983,11 +4983,183 @@ static struct syscore_ops tegra_clk_syscore_ops = { .resume = tegra_clk_resume, }; +#ifdef CONFIG_TEGRA_PREINIT_CLOCKS + +#define CLK_RSTENB_DEV_V_0_DAM2_BIT (1 << 14) +#define CLK_RSTENB_DEV_V_0_DAM1_BIT (1 << 13) +#define CLK_RSTENB_DEV_V_0_DAM0_BIT (1 << 12) +#define CLK_RSTENB_DEV_V_0_AUDIO_BIT (1 << 10) + +#define CLK_RSTENB_DEV_L_0_HOST1X_BIT (1 << 28) +#define CLK_RSTENB_DEV_L_0_DISP1_BIT (1 << 27) + +#define DISP1_CLK_REG_OFFSET 0x138 +#define DISP1_CLK_SRC_SHIFT 29 +#define DISP1_CLK_SRC_MASK (0x7 << DISP1_CLK_SRC_SHIFT) +#define DISP1_CLK_SRC_PLLP_OUT0 0 +#define DISP1_CLK_SRC_PLLM_OUT0 1 +#define DISP1_CLK_SRC_PLLD_OUT0 2 +#define DISP1_CLK_SRC_PLLA_OUT0 3 +#define DISP1_CLK_SRC_PLLC_OUT0 4 +#define DISP1_CLK_SRC_PLLD2_OUT0 5 +#define DISP1_CLK_SRC_CLKM 6 +#define DISP1_CLK_SRC_DEFAULT (DISP1_CLK_SRC_PLLP_OUT0 << DISP1_CLK_SRC_SHIFT) + +#define HOST1X_CLK_REG_OFFSET 0x180 +#define HOST1X_CLK_SRC_SHIFT 30 +#define HOST1X_CLK_SRC_MASK (0x3 << HOST1X_CLK_SRC_SHIFT) +#define HOST1X_CLK_SRC_PLLM_OUT0 0 +#define HOST1X_CLK_SRC_PLLC_OUT0 1 +#define HOST1X_CLK_SRC_PLLP_OUT0 2 +#define HOST1X_CLK_SRC_PLLA_OUT0 3 +#define HOST1X_CLK_SRC_DEFAULT (\ + HOST1X_CLK_SRC_PLLP_OUT0 << HOST1X_CLK_SRC_SHIFT) +#define HOST1X_CLK_IDLE_DIV_SHIFT 8 +#define HOST1X_CLK_IDLE_DIV_MASK (0xff << HOST1X_CLK_IDLE_DIV_SHIFT) +#define HOST1X_CLK_IDLE_DIV_DEFAULT (0 << HOST1X_CLK_IDLE_DIV_SHIFT) +#define HOST1X_CLK_DIV_SHIFT 0 +#define HOST1X_CLK_DIV_MASK (0xff << HOST1X_CLK_DIV_SHIFT) +#define HOST1X_CLK_DIV_DEFAULT (3 << HOST1X_CLK_DIV_SHIFT) + +#define AUDIO_CLK_REG_OFFSET 0x3d0 +#define DAM0_CLK_REG_OFFSET 0x3d8 +#define DAM1_CLK_REG_OFFSET 0x3dc +#define DAM2_CLK_REG_OFFSET 0x3e0 +#define AUDIO_CLK_SRC_SHIFT 28 +#define AUDIO_CLK_SRC_MASK (0x0f << AUDIO_CLK_SRC_SHIFT) +#define AUDIO_CLK_SRC_PLLA_OUT0 0x01 +#define AUDIO_CLK_SRC_PLLC_OUT0 0x05 +#define AUDIO_CLK_SRC_PLLP_OUT0 0x09 +#define AUDIO_CLK_SRC_CLKM 0x0d +#define AUDIO_CLK_SRC_DEFAULT (\ + AUDIO_CLK_SRC_CLKM << AUDIO_CLK_SRC_SHIFT) +#define AUDIO_CLK_DIV_SHIFT 0 +#define AUDIO_CLK_DIV_MASK (0xff << AUDIO_CLK_DIV_SHIFT) +#define AUDIO_CLK_DIV_DEFAULT (\ + (0 << AUDIO_CLK_DIV_SHIFT)) + +static void __init clk_setbit(u32 reg, u32 bit) +{ + u32 val = clk_readl(reg); + + if ((val & bit) == bit) + return; + val |= bit; + clk_writel(val, reg); + udelay(2); +} + +static void __init clk_clrbit(u32 reg, u32 bit) +{ + u32 val = clk_readl(reg); + + if ((val & bit) == 0) + return; + val &= ~bit; + clk_writel(val, reg); + udelay(2); +} + +static void __init clk_setbits(u32 reg, u32 bits, u32 mask) +{ + u32 val = clk_readl(reg); + + if ((val & mask) == bits) + return; + val &= ~mask; + val |= bits; + clk_writel(val, reg); + udelay(2); +} + +static int __init tegra_soc_preinit_clocks(void) +{ + /* + * Make sure host1x clock configuration has: + * HOST1X_CLK_SRC : PLLP_OUT0. + * HOST1X_CLK_DIVISOR: >2 to start from safe enough frequency. + */ + clk_setbit(RST_DEVICES_L, CLK_RSTENB_DEV_L_0_HOST1X_BIT); + clk_setbit(CLK_OUT_ENB_L, CLK_RSTENB_DEV_L_0_HOST1X_BIT); + clk_setbits(HOST1X_CLK_REG_OFFSET, + HOST1X_CLK_DIV_DEFAULT, HOST1X_CLK_DIV_MASK); + clk_setbits(HOST1X_CLK_REG_OFFSET, + HOST1X_CLK_IDLE_DIV_DEFAULT, HOST1X_CLK_IDLE_DIV_MASK); + clk_setbits(HOST1X_CLK_REG_OFFSET, + HOST1X_CLK_SRC_DEFAULT, HOST1X_CLK_SRC_MASK); + clk_clrbit(RST_DEVICES_L, CLK_RSTENB_DEV_L_0_HOST1X_BIT); + + /* + * Make sure disp1 clock configuration ha: + * DISP1_CLK_SRC: DISP1_CLK_SRC_PLLP_OUT0 + */ + clk_setbit(RST_DEVICES_L, CLK_RSTENB_DEV_L_0_DISP1_BIT); + clk_setbit(CLK_OUT_ENB_L, CLK_RSTENB_DEV_L_0_DISP1_BIT); + clk_setbits(DISP1_CLK_REG_OFFSET, + DISP1_CLK_SRC_DEFAULT, DISP1_CLK_SRC_MASK); + clk_clrbit(RST_DEVICES_L, CLK_RSTENB_DEV_L_0_DISP1_BIT); + + /* + * Make sure dam2 clock configuration has: + * DAM2_CLK_SRC: AUDIO_CLK_SRC_CLKM + */ + clk_setbit(RST_DEVICES_V, CLK_RSTENB_DEV_V_0_DAM2_BIT); + clk_setbit(CLK_OUT_ENB_V, CLK_RSTENB_DEV_V_0_DAM2_BIT); + clk_setbits(DAM2_CLK_REG_OFFSET, + AUDIO_CLK_DIV_DEFAULT, AUDIO_CLK_DIV_MASK); + clk_setbits(DAM2_CLK_REG_OFFSET, + AUDIO_CLK_SRC_DEFAULT, AUDIO_CLK_SRC_MASK); + clk_clrbit(RST_DEVICES_V, CLK_RSTENB_DEV_V_0_DAM2_BIT); + + /* + * Make sure dam1 clock configuration has: + * DAM1_CLK_SRC: AUDIO_CLK_SRC_CLKM + */ + clk_setbit(RST_DEVICES_V, CLK_RSTENB_DEV_V_0_DAM1_BIT); + clk_setbit(CLK_OUT_ENB_V, CLK_RSTENB_DEV_V_0_DAM1_BIT); + clk_setbits(DAM1_CLK_REG_OFFSET, + AUDIO_CLK_DIV_DEFAULT, AUDIO_CLK_DIV_MASK); + clk_setbits(DAM1_CLK_REG_OFFSET, + AUDIO_CLK_SRC_DEFAULT, AUDIO_CLK_SRC_MASK); + clk_clrbit(RST_DEVICES_V, CLK_RSTENB_DEV_V_0_DAM1_BIT); + + /* + * Make sure dam0 clock configuration has: + * DAM0_CLK_SRC: AUDIO_CLK_SRC_CLKM + */ + clk_setbit(RST_DEVICES_V, CLK_RSTENB_DEV_V_0_DAM0_BIT); + clk_setbit(CLK_OUT_ENB_V, CLK_RSTENB_DEV_V_0_DAM0_BIT); + clk_setbits(DAM0_CLK_REG_OFFSET, + AUDIO_CLK_DIV_DEFAULT, AUDIO_CLK_DIV_MASK); + clk_setbits(DAM0_CLK_REG_OFFSET, + AUDIO_CLK_SRC_DEFAULT, AUDIO_CLK_SRC_MASK); + clk_clrbit(RST_DEVICES_V, CLK_RSTENB_DEV_V_0_DAM0_BIT); + + /* + * Make sure d_audio clock configuration has: + * AUDIO_CLK_SRC: AUDIO_CLK_SRC_CLKM + */ + clk_setbit(RST_DEVICES_V, CLK_RSTENB_DEV_V_0_AUDIO_BIT); + clk_setbit(CLK_OUT_ENB_V, CLK_RSTENB_DEV_V_0_AUDIO_BIT); + clk_setbits(AUDIO_CLK_REG_OFFSET, + AUDIO_CLK_DIV_DEFAULT, AUDIO_CLK_DIV_MASK); + clk_setbits(AUDIO_CLK_REG_OFFSET, + AUDIO_CLK_SRC_DEFAULT, AUDIO_CLK_SRC_MASK); + clk_clrbit(RST_DEVICES_V, CLK_RSTENB_DEV_V_0_AUDIO_BIT); + + return 0; +} +#endif /* CONFIG_TEGRA_PREINIT_CLOCKS */ + void __init tegra_soc_init_clocks(void) { int i; struct clk *c; +#ifdef CONFIG_TEGRA_PREINIT_CLOCKS + tegra_soc_preinit_clocks(); +#endif /* CONFIG_TEGRA_PREINIT_CLOCKS */ + for (i = 0; i < ARRAY_SIZE(tegra_ptr_clks); i++) tegra3_init_one_clock(tegra_ptr_clks[i]); |