diff options
author | Colin Cross <ccross@android.com> | 2011-02-13 00:25:23 -0500 |
---|---|---|
committer | Colin Cross <ccross@android.com> | 2011-02-21 03:16:48 -0500 |
commit | 9c7dc562cd78784f54261b9bedb44e8b0056f729 (patch) | |
tree | 093020bc9cae61b7d2e39193efec26b6e3f4fad5 /arch | |
parent | c2f44a9df9e1f8974911ef538565e301b38e0680 (diff) |
ARM: tegra: clock: Miscellaneous clock updates
Correct max rates for pclk and sclk (Originally fixed by
Dima Zavin <dima@android.com>)
Correct max rate for plla (Originally fixed by
Stephen Warren <swarren@nvidia.com>)
Remove unnecessary no-op set_rate on audio clocks
Add clock lookup entries for grhost, bsea, and vde clocks
Update clock clookup entries for vcp, bsea, and vde clocks
Add shared clock entries for sclk and emc
Add a virtual cop clock to provide a reset op (Originally fixed by
Dima Zavin <dima@android.com>)
Pass set_rate on super clocks through to parent
Fix pllx frequency table entry for 608 MHz
Remove incorrect plla frequency table entries
Acked-by: Olof Johansson <olof@lixom.net>
Signed-off-by: Colin Cross <ccross@android.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/mach-tegra/tegra2_clocks.c | 98 |
1 files changed, 67 insertions, 31 deletions
diff --git a/arch/arm/mach-tegra/tegra2_clocks.c b/arch/arm/mach-tegra/tegra2_clocks.c index 260b77c41436..59e77ba95802 100644 --- a/arch/arm/mach-tegra/tegra2_clocks.c +++ b/arch/arm/mach-tegra/tegra2_clocks.c | |||
@@ -356,11 +356,24 @@ static int tegra2_super_clk_set_parent(struct clk *c, struct clk *p) | |||
356 | return -EINVAL; | 356 | return -EINVAL; |
357 | } | 357 | } |
358 | 358 | ||
359 | /* | ||
360 | * Super clocks have "clock skippers" instead of dividers. Dividing using | ||
361 | * a clock skipper does not allow the voltage to be scaled down, so instead | ||
362 | * adjust the rate of the parent clock. This requires that the parent of a | ||
363 | * super clock have no other children, otherwise the rate will change | ||
364 | * underneath the other children. | ||
365 | */ | ||
366 | static int tegra2_super_clk_set_rate(struct clk *c, unsigned long rate) | ||
367 | { | ||
368 | return clk_set_rate(c->parent, rate); | ||
369 | } | ||
370 | |||
359 | static struct clk_ops tegra_super_ops = { | 371 | static struct clk_ops tegra_super_ops = { |
360 | .init = tegra2_super_clk_init, | 372 | .init = tegra2_super_clk_init, |
361 | .enable = tegra2_super_clk_enable, | 373 | .enable = tegra2_super_clk_enable, |
362 | .disable = tegra2_super_clk_disable, | 374 | .disable = tegra2_super_clk_disable, |
363 | .set_parent = tegra2_super_clk_set_parent, | 375 | .set_parent = tegra2_super_clk_set_parent, |
376 | .set_rate = tegra2_super_clk_set_rate, | ||
364 | }; | 377 | }; |
365 | 378 | ||
366 | /* virtual cpu clock functions */ | 379 | /* virtual cpu clock functions */ |
@@ -429,6 +442,20 @@ static struct clk_ops tegra_cpu_ops = { | |||
429 | .set_rate = tegra2_cpu_clk_set_rate, | 442 | .set_rate = tegra2_cpu_clk_set_rate, |
430 | }; | 443 | }; |
431 | 444 | ||
445 | /* virtual cop clock functions. Used to acquire the fake 'cop' clock to | ||
446 | * reset the COP block (i.e. AVP) */ | ||
447 | static void tegra2_cop_clk_reset(struct clk *c, bool assert) | ||
448 | { | ||
449 | unsigned long reg = assert ? RST_DEVICES_SET : RST_DEVICES_CLR; | ||
450 | |||
451 | pr_debug("%s %s\n", __func__, assert ? "assert" : "deassert"); | ||
452 | clk_writel(1 << 1, reg); | ||
453 | } | ||
454 | |||
455 | static struct clk_ops tegra_cop_ops = { | ||
456 | .reset = tegra2_cop_clk_reset, | ||
457 | }; | ||
458 | |||
432 | /* bus clock functions */ | 459 | /* bus clock functions */ |
433 | static void tegra2_bus_clk_init(struct clk *c) | 460 | static void tegra2_bus_clk_init(struct clk *c) |
434 | { | 461 | { |
@@ -1199,30 +1226,10 @@ static int tegra2_audio_sync_clk_set_parent(struct clk *c, struct clk *p) | |||
1199 | return -EINVAL; | 1226 | return -EINVAL; |
1200 | } | 1227 | } |
1201 | 1228 | ||
1202 | static int tegra2_audio_sync_clk_set_rate(struct clk *c, unsigned long rate) | ||
1203 | { | ||
1204 | unsigned long parent_rate; | ||
1205 | if (!c->parent) { | ||
1206 | pr_err("%s: clock has no parent\n", __func__); | ||
1207 | return -EINVAL; | ||
1208 | } | ||
1209 | parent_rate = c->parent->rate; | ||
1210 | if (rate != parent_rate) { | ||
1211 | pr_err("%s: %s/%ld differs from parent %s/%ld\n", | ||
1212 | __func__, | ||
1213 | c->name, rate, | ||
1214 | c->parent->name, parent_rate); | ||
1215 | return -EINVAL; | ||
1216 | } | ||
1217 | c->rate = parent_rate; | ||
1218 | return 0; | ||
1219 | } | ||
1220 | |||
1221 | static struct clk_ops tegra_audio_sync_clk_ops = { | 1229 | static struct clk_ops tegra_audio_sync_clk_ops = { |
1222 | .init = tegra2_audio_sync_clk_init, | 1230 | .init = tegra2_audio_sync_clk_init, |
1223 | .enable = tegra2_audio_sync_clk_enable, | 1231 | .enable = tegra2_audio_sync_clk_enable, |
1224 | .disable = tegra2_audio_sync_clk_disable, | 1232 | .disable = tegra2_audio_sync_clk_disable, |
1225 | .set_rate = tegra2_audio_sync_clk_set_rate, | ||
1226 | .set_parent = tegra2_audio_sync_clk_set_parent, | 1233 | .set_parent = tegra2_audio_sync_clk_set_parent, |
1227 | }; | 1234 | }; |
1228 | 1235 | ||
@@ -1558,8 +1565,6 @@ static struct clk tegra_pll_p_out4 = { | |||
1558 | static struct clk_pll_freq_table tegra_pll_a_freq_table[] = { | 1565 | static struct clk_pll_freq_table tegra_pll_a_freq_table[] = { |
1559 | { 28800000, 56448000, 49, 25, 1, 1}, | 1566 | { 28800000, 56448000, 49, 25, 1, 1}, |
1560 | { 28800000, 73728000, 64, 25, 1, 1}, | 1567 | { 28800000, 73728000, 64, 25, 1, 1}, |
1561 | { 28800000, 11289600, 49, 25, 1, 1}, | ||
1562 | { 28800000, 12288000, 64, 25, 1, 1}, | ||
1563 | { 28800000, 24000000, 5, 6, 1, 1}, | 1568 | { 28800000, 24000000, 5, 6, 1, 1}, |
1564 | { 0, 0, 0, 0, 0, 0 }, | 1569 | { 0, 0, 0, 0, 0, 0 }, |
1565 | }; | 1570 | }; |
@@ -1570,7 +1575,7 @@ static struct clk tegra_pll_a = { | |||
1570 | .ops = &tegra_pll_ops, | 1575 | .ops = &tegra_pll_ops, |
1571 | .reg = 0xb0, | 1576 | .reg = 0xb0, |
1572 | .parent = &tegra_pll_p_out1, | 1577 | .parent = &tegra_pll_p_out1, |
1573 | .max_rate = 56448000, | 1578 | .max_rate = 73728000, |
1574 | .u.pll = { | 1579 | .u.pll = { |
1575 | .input_min = 2000000, | 1580 | .input_min = 2000000, |
1576 | .input_max = 31000000, | 1581 | .input_max = 31000000, |
@@ -1590,7 +1595,7 @@ static struct clk tegra_pll_a_out0 = { | |||
1590 | .parent = &tegra_pll_a, | 1595 | .parent = &tegra_pll_a, |
1591 | .reg = 0xb4, | 1596 | .reg = 0xb4, |
1592 | .reg_shift = 0, | 1597 | .reg_shift = 0, |
1593 | .max_rate = 56448000, | 1598 | .max_rate = 73728000, |
1594 | }; | 1599 | }; |
1595 | 1600 | ||
1596 | static struct clk_pll_freq_table tegra_pll_d_freq_table[] = { | 1601 | static struct clk_pll_freq_table tegra_pll_d_freq_table[] = { |
@@ -1692,10 +1697,10 @@ static struct clk_pll_freq_table tegra_pll_x_freq_table[] = { | |||
1692 | { 26000000, 760000000, 760, 26, 1, 12}, | 1697 | { 26000000, 760000000, 760, 26, 1, 12}, |
1693 | 1698 | ||
1694 | /* 608 MHz */ | 1699 | /* 608 MHz */ |
1695 | { 12000000, 608000000, 760, 12, 1, 12}, | 1700 | { 12000000, 608000000, 608, 12, 1, 12}, |
1696 | { 13000000, 608000000, 760, 13, 1, 12}, | 1701 | { 13000000, 608000000, 608, 13, 1, 12}, |
1697 | { 19200000, 608000000, 380, 12, 1, 8}, | 1702 | { 19200000, 608000000, 380, 12, 1, 8}, |
1698 | { 26000000, 608000000, 760, 26, 1, 12}, | 1703 | { 26000000, 608000000, 608, 26, 1, 12}, |
1699 | 1704 | ||
1700 | /* 456 MHz */ | 1705 | /* 456 MHz */ |
1701 | { 12000000, 456000000, 456, 12, 1, 12}, | 1706 | { 12000000, 456000000, 456, 12, 1, 12}, |
@@ -1808,7 +1813,7 @@ static struct clk tegra_clk_audio = { | |||
1808 | .name = "audio", | 1813 | .name = "audio", |
1809 | .inputs = mux_audio_sync_clk, | 1814 | .inputs = mux_audio_sync_clk, |
1810 | .reg = 0x38, | 1815 | .reg = 0x38, |
1811 | .max_rate = 24000000, | 1816 | .max_rate = 73728000, |
1812 | .ops = &tegra_audio_sync_clk_ops | 1817 | .ops = &tegra_audio_sync_clk_ops |
1813 | }; | 1818 | }; |
1814 | 1819 | ||
@@ -1894,7 +1899,8 @@ static struct clk tegra_clk_sclk = { | |||
1894 | .inputs = mux_sclk, | 1899 | .inputs = mux_sclk, |
1895 | .reg = 0x28, | 1900 | .reg = 0x28, |
1896 | .ops = &tegra_super_ops, | 1901 | .ops = &tegra_super_ops, |
1897 | .max_rate = 600000000, | 1902 | .max_rate = 240000000, |
1903 | .min_rate = 120000000, | ||
1898 | }; | 1904 | }; |
1899 | 1905 | ||
1900 | static struct clk tegra_clk_virtual_cpu = { | 1906 | static struct clk tegra_clk_virtual_cpu = { |
@@ -1908,6 +1914,13 @@ static struct clk tegra_clk_virtual_cpu = { | |||
1908 | }, | 1914 | }, |
1909 | }; | 1915 | }; |
1910 | 1916 | ||
1917 | static struct clk tegra_clk_cop = { | ||
1918 | .name = "cop", | ||
1919 | .parent = &tegra_clk_sclk, | ||
1920 | .ops = &tegra_cop_ops, | ||
1921 | .max_rate = 240000000, | ||
1922 | }; | ||
1923 | |||
1911 | static struct clk tegra_clk_hclk = { | 1924 | static struct clk tegra_clk_hclk = { |
1912 | .name = "hclk", | 1925 | .name = "hclk", |
1913 | .flags = DIV_BUS, | 1926 | .flags = DIV_BUS, |
@@ -1925,7 +1938,7 @@ static struct clk tegra_clk_pclk = { | |||
1925 | .reg = 0x30, | 1938 | .reg = 0x30, |
1926 | .reg_shift = 0, | 1939 | .reg_shift = 0, |
1927 | .ops = &tegra_bus_ops, | 1940 | .ops = &tegra_bus_ops, |
1928 | .max_rate = 108000000, | 1941 | .max_rate = 120000000, |
1929 | }; | 1942 | }; |
1930 | 1943 | ||
1931 | static struct clk tegra_clk_blink = { | 1944 | static struct clk tegra_clk_blink = { |
@@ -2082,7 +2095,10 @@ struct clk tegra_list_clks[] = { | |||
2082 | PERIPH_CLK("sdmmc2", "sdhci-tegra.1", NULL, 9, 0x154, 52000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage */ | 2095 | PERIPH_CLK("sdmmc2", "sdhci-tegra.1", NULL, 9, 0x154, 52000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage */ |
2083 | PERIPH_CLK("sdmmc3", "sdhci-tegra.2", NULL, 69, 0x1bc, 52000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage */ | 2096 | PERIPH_CLK("sdmmc3", "sdhci-tegra.2", NULL, 69, 0x1bc, 52000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage */ |
2084 | PERIPH_CLK("sdmmc4", "sdhci-tegra.3", NULL, 15, 0x164, 52000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage */ | 2097 | PERIPH_CLK("sdmmc4", "sdhci-tegra.3", NULL, 15, 0x164, 52000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage */ |
2085 | PERIPH_CLK("vde", "vde", NULL, 61, 0x1c8, 250000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage and process_id */ | 2098 | PERIPH_CLK("vcp", "tegra-avp", "vcp", 29, 0, 250000000, mux_clk_m, 0), |
2099 | PERIPH_CLK("bsea", "tegra-avp", "bsea", 62, 0, 250000000, mux_clk_m, 0), | ||
2100 | PERIPH_CLK("bsev", "tegra-aes", "bsev", 63, 0, 250000000, mux_clk_m, 0), | ||
2101 | PERIPH_CLK("vde", "tegra-avp", "vde", 61, 0x1c8, 250000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage and process_id */ | ||
2086 | PERIPH_CLK("csite", "csite", NULL, 73, 0x1d4, 144000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* max rate ??? */ | 2102 | PERIPH_CLK("csite", "csite", NULL, 73, 0x1d4, 144000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* max rate ??? */ |
2087 | /* FIXME: what is la? */ | 2103 | /* FIXME: what is la? */ |
2088 | PERIPH_CLK("la", "la", NULL, 76, 0x1f8, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), | 2104 | PERIPH_CLK("la", "la", NULL, 76, 0x1f8, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), |
@@ -2127,6 +2143,18 @@ struct clk tegra_list_clks[] = { | |||
2127 | PERIPH_CLK("pex", NULL, "pex", 70, 0, 26000000, mux_clk_m, PERIPH_MANUAL_RESET), | 2143 | PERIPH_CLK("pex", NULL, "pex", 70, 0, 26000000, mux_clk_m, PERIPH_MANUAL_RESET), |
2128 | PERIPH_CLK("afi", NULL, "afi", 72, 0, 26000000, mux_clk_m, PERIPH_MANUAL_RESET), | 2144 | PERIPH_CLK("afi", NULL, "afi", 72, 0, 26000000, mux_clk_m, PERIPH_MANUAL_RESET), |
2129 | PERIPH_CLK("pcie_xclk", NULL, "pcie_xclk", 74, 0, 26000000, mux_clk_m, PERIPH_MANUAL_RESET), | 2145 | PERIPH_CLK("pcie_xclk", NULL, "pcie_xclk", 74, 0, 26000000, mux_clk_m, PERIPH_MANUAL_RESET), |
2146 | |||
2147 | SHARED_CLK("avp.sclk", "tegra-avp", "sclk", &tegra_clk_sclk), | ||
2148 | SHARED_CLK("avp.emc", "tegra-avp", "emc", &tegra_clk_emc), | ||
2149 | SHARED_CLK("cpu.emc", "cpu", "emc", &tegra_clk_emc), | ||
2150 | SHARED_CLK("disp1.emc", "tegradc.0", "emc", &tegra_clk_emc), | ||
2151 | SHARED_CLK("disp2.emc", "tegradc.1", "emc", &tegra_clk_emc), | ||
2152 | SHARED_CLK("hdmi.emc", "hdmi", "emc", &tegra_clk_emc), | ||
2153 | SHARED_CLK("host.emc", "tegra_grhost", "emc", &tegra_clk_emc), | ||
2154 | SHARED_CLK("usbd.emc", "fsl-tegra-udc", "emc", &tegra_clk_emc), | ||
2155 | SHARED_CLK("usb1.emc", "tegra-ehci.0", "emc", &tegra_clk_emc), | ||
2156 | SHARED_CLK("usb2.emc", "tegra-ehci.1", "emc", &tegra_clk_emc), | ||
2157 | SHARED_CLK("usb3.emc", "tegra-ehci.2", "emc", &tegra_clk_emc), | ||
2130 | }; | 2158 | }; |
2131 | 2159 | ||
2132 | #define CLK_DUPLICATE(_name, _dev, _con) \ | 2160 | #define CLK_DUPLICATE(_name, _dev, _con) \ |
@@ -2157,6 +2185,13 @@ struct clk_duplicate tegra_clk_duplicates[] = { | |||
2157 | CLK_DUPLICATE("pwm", "tegra_pwm.1", NULL), | 2185 | CLK_DUPLICATE("pwm", "tegra_pwm.1", NULL), |
2158 | CLK_DUPLICATE("pwm", "tegra_pwm.2", NULL), | 2186 | CLK_DUPLICATE("pwm", "tegra_pwm.2", NULL), |
2159 | CLK_DUPLICATE("pwm", "tegra_pwm.3", NULL), | 2187 | CLK_DUPLICATE("pwm", "tegra_pwm.3", NULL), |
2188 | CLK_DUPLICATE("host1x", "tegra_grhost", "host1x"), | ||
2189 | CLK_DUPLICATE("2d", "tegra_grhost", "gr2d"), | ||
2190 | CLK_DUPLICATE("3d", "tegra_grhost", "gr3d"), | ||
2191 | CLK_DUPLICATE("epp", "tegra_grhost", "epp"), | ||
2192 | CLK_DUPLICATE("mpe", "tegra_grhost", "mpe"), | ||
2193 | CLK_DUPLICATE("cop", "tegra-avp", "cop"), | ||
2194 | CLK_DUPLICATE("vde", "tegra-aes", "vde"), | ||
2160 | }; | 2195 | }; |
2161 | 2196 | ||
2162 | #define CLK(dev, con, ck) \ | 2197 | #define CLK(dev, con, ck) \ |
@@ -2195,6 +2230,7 @@ struct clk *tegra_ptr_clks[] = { | |||
2195 | &tegra_dev2_clk, | 2230 | &tegra_dev2_clk, |
2196 | &tegra_clk_virtual_cpu, | 2231 | &tegra_clk_virtual_cpu, |
2197 | &tegra_clk_blink, | 2232 | &tegra_clk_blink, |
2233 | &tegra_clk_cop, | ||
2198 | &tegra_clk_emc, | 2234 | &tegra_clk_emc, |
2199 | }; | 2235 | }; |
2200 | 2236 | ||