aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-tegra/tegra2_clocks.c64
1 files changed, 63 insertions, 1 deletions
diff --git a/arch/arm/mach-tegra/tegra2_clocks.c b/arch/arm/mach-tegra/tegra2_clocks.c
index f6f685c4f339..7f7068714049 100644
--- a/arch/arm/mach-tegra/tegra2_clocks.c
+++ b/arch/arm/mach-tegra/tegra2_clocks.c
@@ -31,6 +31,7 @@
31 31
32#include "clock.h" 32#include "clock.h"
33#include "fuse.h" 33#include "fuse.h"
34#include "tegra2_emc.h"
34 35
35#define RST_DEVICES 0x004 36#define RST_DEVICES 0x004
36#define RST_DEVICES_SET 0x300 37#define RST_DEVICES_SET 0x300
@@ -1051,6 +1052,55 @@ static struct clk_ops tegra_periph_clk_ops = {
1051 .reset = &tegra2_periph_clk_reset, 1052 .reset = &tegra2_periph_clk_reset,
1052}; 1053};
1053 1054
1055/* External memory controller clock ops */
1056static void tegra2_emc_clk_init(struct clk *c)
1057{
1058 tegra2_periph_clk_init(c);
1059 c->max_rate = clk_get_rate_locked(c);
1060}
1061
1062static long tegra2_emc_clk_round_rate(struct clk *c, unsigned long rate)
1063{
1064 long new_rate = rate;
1065
1066 new_rate = tegra_emc_round_rate(new_rate);
1067 if (new_rate < 0)
1068 return c->max_rate;
1069
1070 BUG_ON(new_rate != tegra2_periph_clk_round_rate(c, new_rate));
1071
1072 return new_rate;
1073}
1074
1075static int tegra2_emc_clk_set_rate(struct clk *c, unsigned long rate)
1076{
1077 int ret;
1078 /*
1079 * The Tegra2 memory controller has an interlock with the clock
1080 * block that allows memory shadowed registers to be updated,
1081 * and then transfer them to the main registers at the same
1082 * time as the clock update without glitches.
1083 */
1084 ret = tegra_emc_set_rate(rate);
1085 if (ret < 0)
1086 return ret;
1087
1088 ret = tegra2_periph_clk_set_rate(c, rate);
1089 udelay(1);
1090
1091 return ret;
1092}
1093
1094static struct clk_ops tegra_emc_clk_ops = {
1095 .init = &tegra2_emc_clk_init,
1096 .enable = &tegra2_periph_clk_enable,
1097 .disable = &tegra2_periph_clk_disable,
1098 .set_parent = &tegra2_periph_clk_set_parent,
1099 .set_rate = &tegra2_emc_clk_set_rate,
1100 .round_rate = &tegra2_emc_clk_round_rate,
1101 .reset = &tegra2_periph_clk_reset,
1102};
1103
1054/* Clock doubler ops */ 1104/* Clock doubler ops */
1055static void tegra2_clk_double_init(struct clk *c) 1105static void tegra2_clk_double_init(struct clk *c)
1056{ 1106{
@@ -1948,6 +1998,18 @@ static struct clk_mux_sel mux_pclk[] = {
1948 { 0, 0}, 1998 { 0, 0},
1949}; 1999};
1950 2000
2001static struct clk tegra_clk_emc = {
2002 .name = "emc",
2003 .ops = &tegra_emc_clk_ops,
2004 .reg = 0x19c,
2005 .max_rate = 800000000,
2006 .inputs = mux_pllm_pllc_pllp_clkm,
2007 .flags = MUX | DIV_U71 | PERIPH_EMC_ENB,
2008 .u.periph = {
2009 .clk_num = 57,
2010 },
2011};
2012
1951#define PERIPH_CLK(_name, _dev, _con, _clk_num, _reg, _max, _inputs, _flags) \ 2013#define PERIPH_CLK(_name, _dev, _con, _clk_num, _reg, _max, _inputs, _flags) \
1952 { \ 2014 { \
1953 .name = _name, \ 2015 .name = _name, \
@@ -2039,7 +2101,6 @@ struct clk tegra_list_clks[] = {
2039 PERIPH_CLK("usbd", "fsl-tegra-udc", NULL, 22, 0, 480000000, mux_clk_m, 0), /* requires min voltage */ 2101 PERIPH_CLK("usbd", "fsl-tegra-udc", NULL, 22, 0, 480000000, mux_clk_m, 0), /* requires min voltage */
2040 PERIPH_CLK("usb2", "tegra-ehci.1", NULL, 58, 0, 480000000, mux_clk_m, 0), /* requires min voltage */ 2102 PERIPH_CLK("usb2", "tegra-ehci.1", NULL, 58, 0, 480000000, mux_clk_m, 0), /* requires min voltage */
2041 PERIPH_CLK("usb3", "tegra-ehci.2", NULL, 59, 0, 480000000, mux_clk_m, 0), /* requires min voltage */ 2103 PERIPH_CLK("usb3", "tegra-ehci.2", NULL, 59, 0, 480000000, mux_clk_m, 0), /* requires min voltage */
2042 PERIPH_CLK("emc", "emc", NULL, 57, 0x19c, 800000000, mux_pllm_pllc_pllp_clkm, MUX | DIV_U71 | PERIPH_EMC_ENB),
2043 PERIPH_CLK("dsi", "dsi", NULL, 48, 0, 500000000, mux_plld, 0), /* scales with voltage */ 2104 PERIPH_CLK("dsi", "dsi", NULL, 48, 0, 500000000, mux_plld, 0), /* scales with voltage */
2044 PERIPH_CLK("csi", "tegra_camera", "csi", 52, 0, 72000000, mux_pllp_out3, 0), 2105 PERIPH_CLK("csi", "tegra_camera", "csi", 52, 0, 72000000, mux_pllp_out3, 0),
2045 PERIPH_CLK("isp", "tegra_camera", "isp", 23, 0, 150000000, mux_clk_m, 0), /* same frequency as VI */ 2106 PERIPH_CLK("isp", "tegra_camera", "isp", 23, 0, 150000000, mux_clk_m, 0), /* same frequency as VI */
@@ -2115,6 +2176,7 @@ struct clk *tegra_ptr_clks[] = {
2115 &tegra_dev2_clk, 2176 &tegra_dev2_clk,
2116 &tegra_clk_virtual_cpu, 2177 &tegra_clk_virtual_cpu,
2117 &tegra_clk_blink, 2178 &tegra_clk_blink,
2179 &tegra_clk_emc,
2118}; 2180};
2119 2181
2120static void tegra2_init_one_clock(struct clk *c) 2182static void tegra2_init_one_clock(struct clk *c)