aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-tegra
diff options
context:
space:
mode:
authorSimon Que <sque@chromium.org>2011-12-16 14:11:22 -0500
committerStephen Warren <swarren@nvidia.com>2012-07-02 17:01:18 -0400
commitbb1dccfc63f7a007c6347c75ba597d866749d9d2 (patch)
treeeb4a95c539840c1a115788b3a4685857f2d694b0 /arch/arm/mach-tegra
parent72d967eda2fd69a6cac01498585bc019ade4f8ff (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.c32
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),