diff options
Diffstat (limited to 'arch/arm/mach-tegra')
-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 260b77c4143..59e77ba9580 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 | ||