diff options
author | Simon Que <sque@chromium.org> | 2011-12-16 14:11:22 -0500 |
---|---|---|
committer | Stephen Warren <swarren@nvidia.com> | 2012-07-02 17:01:18 -0400 |
commit | bb1dccfc63f7a007c6347c75ba597d866749d9d2 (patch) | |
tree | eb4a95c539840c1a115788b3a4685857f2d694b0 /arch/arm/mach-tegra | |
parent | 72d967eda2fd69a6cac01498585bc019ade4f8ff (diff) |
ARM: tegra: Fix PWM clock programming
PWM clock source registers in Tegra 2 have different clock source selection bit
fields than other registers. PWM clock source bits in CLK_SOURCE_PWM_0 register
are located at bit field bit[30:28] while others are at bit field bit[31:30] in
their respective clock source register.
This patch updates the clock programming to correctly reflect that, by adding a
flag to indicate the alternate bit field format and checking for it when
selecting a clock source (parent clock).
Signed-off-by: Bill Huang <bilhuang@nvidia.com>
Signed-off-by: Simon Que <sque@chromium.org>
Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
Diffstat (limited to 'arch/arm/mach-tegra')
-rw-r--r-- | arch/arm/mach-tegra/tegra2_clocks.c | 32 |
1 files changed, 28 insertions, 4 deletions
diff --git a/arch/arm/mach-tegra/tegra2_clocks.c b/arch/arm/mach-tegra/tegra2_clocks.c index b79cb93ffd54..2016ba095816 100644 --- a/arch/arm/mach-tegra/tegra2_clocks.c +++ b/arch/arm/mach-tegra/tegra2_clocks.c | |||
@@ -69,6 +69,8 @@ | |||
69 | 69 | ||
70 | #define PERIPH_CLK_SOURCE_MASK (3<<30) | 70 | #define PERIPH_CLK_SOURCE_MASK (3<<30) |
71 | #define PERIPH_CLK_SOURCE_SHIFT 30 | 71 | #define PERIPH_CLK_SOURCE_SHIFT 30 |
72 | #define PERIPH_CLK_SOURCE_PWM_MASK (7<<28) | ||
73 | #define PERIPH_CLK_SOURCE_PWM_SHIFT 28 | ||
72 | #define PERIPH_CLK_SOURCE_ENABLE (1<<28) | 74 | #define PERIPH_CLK_SOURCE_ENABLE (1<<28) |
73 | #define PERIPH_CLK_SOURCE_DIVU71_MASK 0xFF | 75 | #define PERIPH_CLK_SOURCE_DIVU71_MASK 0xFF |
74 | #define PERIPH_CLK_SOURCE_DIVU16_MASK 0xFFFF | 76 | #define PERIPH_CLK_SOURCE_DIVU16_MASK 0xFFFF |
@@ -908,9 +910,20 @@ static void tegra2_periph_clk_init(struct clk *c) | |||
908 | u32 val = clk_readl(c->reg); | 910 | u32 val = clk_readl(c->reg); |
909 | const struct clk_mux_sel *mux = NULL; | 911 | const struct clk_mux_sel *mux = NULL; |
910 | const struct clk_mux_sel *sel; | 912 | const struct clk_mux_sel *sel; |
913 | u32 shift; | ||
914 | u32 mask; | ||
915 | |||
916 | if (c->flags & MUX_PWM) { | ||
917 | shift = PERIPH_CLK_SOURCE_PWM_SHIFT; | ||
918 | mask = PERIPH_CLK_SOURCE_PWM_MASK; | ||
919 | } else { | ||
920 | shift = PERIPH_CLK_SOURCE_SHIFT; | ||
921 | mask = PERIPH_CLK_SOURCE_MASK; | ||
922 | } | ||
923 | |||
911 | if (c->flags & MUX) { | 924 | if (c->flags & MUX) { |
912 | for (sel = c->inputs; sel->input != NULL; sel++) { | 925 | for (sel = c->inputs; sel->input != NULL; sel++) { |
913 | if (val >> PERIPH_CLK_SOURCE_SHIFT == sel->value) | 926 | if ((val & mask) >> shift == sel->value) |
914 | mux = sel; | 927 | mux = sel; |
915 | } | 928 | } |
916 | BUG_ON(!mux); | 929 | BUG_ON(!mux); |
@@ -1023,12 +1036,23 @@ static int tegra2_periph_clk_set_parent(struct clk *c, struct clk *p) | |||
1023 | { | 1036 | { |
1024 | u32 val; | 1037 | u32 val; |
1025 | const struct clk_mux_sel *sel; | 1038 | const struct clk_mux_sel *sel; |
1039 | u32 mask, shift; | ||
1040 | |||
1026 | pr_debug("%s: %s %s\n", __func__, c->name, p->name); | 1041 | pr_debug("%s: %s %s\n", __func__, c->name, p->name); |
1042 | |||
1043 | if (c->flags & MUX_PWM) { | ||
1044 | shift = PERIPH_CLK_SOURCE_PWM_SHIFT; | ||
1045 | mask = PERIPH_CLK_SOURCE_PWM_MASK; | ||
1046 | } else { | ||
1047 | shift = PERIPH_CLK_SOURCE_SHIFT; | ||
1048 | mask = PERIPH_CLK_SOURCE_MASK; | ||
1049 | } | ||
1050 | |||
1027 | for (sel = c->inputs; sel->input != NULL; sel++) { | 1051 | for (sel = c->inputs; sel->input != NULL; sel++) { |
1028 | if (sel->input == p) { | 1052 | if (sel->input == p) { |
1029 | val = clk_readl(c->reg); | 1053 | val = clk_readl(c->reg); |
1030 | val &= ~PERIPH_CLK_SOURCE_MASK; | 1054 | val &= ~mask; |
1031 | val |= (sel->value) << PERIPH_CLK_SOURCE_SHIFT; | 1055 | val |= (sel->value) << shift; |
1032 | 1056 | ||
1033 | if (c->refcnt) | 1057 | if (c->refcnt) |
1034 | clk_enable(p); | 1058 | clk_enable(p); |
@@ -2156,7 +2180,7 @@ static struct clk tegra_list_clks[] = { | |||
2156 | PERIPH_CLK("i2s2", "tegra20-i2s.1", NULL, 18, 0x104, 26000000, mux_pllaout0_audio2x_pllp_clkm, MUX | DIV_U71), | 2180 | PERIPH_CLK("i2s2", "tegra20-i2s.1", NULL, 18, 0x104, 26000000, mux_pllaout0_audio2x_pllp_clkm, MUX | DIV_U71), |
2157 | PERIPH_CLK("spdif_out", "spdif_out", NULL, 10, 0x108, 100000000, mux_pllaout0_audio2x_pllp_clkm, MUX | DIV_U71), | 2181 | PERIPH_CLK("spdif_out", "spdif_out", NULL, 10, 0x108, 100000000, mux_pllaout0_audio2x_pllp_clkm, MUX | DIV_U71), |
2158 | PERIPH_CLK("spdif_in", "spdif_in", NULL, 10, 0x10c, 100000000, mux_pllp_pllc_pllm, MUX | DIV_U71), | 2182 | PERIPH_CLK("spdif_in", "spdif_in", NULL, 10, 0x10c, 100000000, mux_pllp_pllc_pllm, MUX | DIV_U71), |
2159 | PERIPH_CLK("pwm", "pwm", NULL, 17, 0x110, 432000000, mux_pllp_pllc_audio_clkm_clk32, MUX | DIV_U71), | 2183 | PERIPH_CLK("pwm", "pwm", NULL, 17, 0x110, 432000000, mux_pllp_pllc_audio_clkm_clk32, MUX | DIV_U71 | MUX_PWM), |
2160 | PERIPH_CLK("spi", "spi", NULL, 43, 0x114, 40000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), | 2184 | PERIPH_CLK("spi", "spi", NULL, 43, 0x114, 40000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), |
2161 | PERIPH_CLK("xio", "xio", NULL, 45, 0x120, 150000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), | 2185 | PERIPH_CLK("xio", "xio", NULL, 45, 0x120, 150000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), |
2162 | PERIPH_CLK("twc", "twc", NULL, 16, 0x12c, 150000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), | 2186 | PERIPH_CLK("twc", "twc", NULL, 16, 0x12c, 150000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), |