summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Frid <afrid@nvidia.com>2011-05-13 23:58:33 -0700
committerDan Willemsen <dwillemsen@nvidia.com>2011-11-30 21:47:06 -0800
commit7359d83b54df8dc87e33833d5fedf76415ac8871 (patch)
treeae9e2d38a992c4c6a2edc099350d2c89df2865fb
parentcad4f00d69356e5610073298e833b40004b08fd1 (diff)
ARM: tegra: clock: Synchronize Tegra3 clocks scaling
On Tegra3 clocks of major h/w engines - 2D/EPP/3D/MPE/VDE/SE - are sourced from PLLC through integer dividers. Low resolution of these dividers does not allow to set scaling frequency levels matching intermediate voltage steps within core voltage range. Only changing the source frequency can achieve it. However, re-locking common PLL while engines are running requires synchronization of engines clock control, and complex operations including switching to backup sources during PLL stabilization time. This commit introduces a new virtual clock "cbus" to support clocks synchronization and PLLC re-locking procedures. The dvfs table for cbus clock is constructed from frequency steps close to maximum rates for each characterized core voltage level. Engine clocks exposed to the drivers are no longer physical module clocks, but shared cbus users. Setting the rate for such clock specifies the clock floor. The final cbus rate is determined as maximum floor setting for all enabled engines, and rounded up along the cbus dvfs ladder. Actual engine clock rate is set equal to the cbus clock rate. Hence, engines will be running close to maximum frequency for minimum voltage that satisfies all floor requests. Special case: Host1x. This clock will be always configured at 1/2 of cbus clock rate, and its shared user floor request is ignored by cbus target frequency calculations. Added cbus dvfs tables and updated VDE engine dvfs data. Original-Change-Id: Ic02ea08227f920dc4f47b2389c311a23cea472f6 Reviewed-on: http://git-master/r/36199 Reviewed-by: Niket Sirsi <nsirsi@nvidia.com> Tested-by: Niket Sirsi <nsirsi@nvidia.com> Rebase-Id: R1b7556f1cca12987e4f7c8c6342778da1cec1915
-rw-r--r--arch/arm/mach-tegra/clock.c5
-rw-r--r--arch/arm/mach-tegra/clock.h4
-rw-r--r--arch/arm/mach-tegra/common.c12
-rw-r--r--arch/arm/mach-tegra/tegra3_clocks.c254
-rw-r--r--arch/arm/mach-tegra/tegra3_dvfs.c11
5 files changed, 239 insertions, 47 deletions
diff --git a/arch/arm/mach-tegra/clock.c b/arch/arm/mach-tegra/clock.c
index 65d92e1bca1a..294c289b6a21 100644
--- a/arch/arm/mach-tegra/clock.c
+++ b/arch/arm/mach-tegra/clock.c
@@ -359,7 +359,7 @@ int clk_set_parent(struct clk *c, struct clk *parent)
* setting enable clock while setting parent.
*/
if ((c->refcnt == 0) && (c->flags & MUX)) {
- pr_warn("Setting parent of clock %s with refcnt 0", c->name);
+ pr_debug("Setting parent of clock %s with refcnt 0\n", c->name);
disable = true;
ret = clk_enable_locked(c);
if (ret)
@@ -427,7 +427,7 @@ int clk_set_rate_locked(struct clk *c, unsigned long rate)
*/
if ((c->refcnt == 0) && (c->flags & (DIV_U71 | DIV_U16)) &&
clk_is_auto_dvfs(c)) {
- pr_warn("Setting rate of clock %s with refcnt 0", c->name);
+ pr_debug("Setting rate of clock %s with refcnt 0\n", c->name);
disable = true;
ret = clk_enable_locked(c);
if (ret)
@@ -639,6 +639,7 @@ void __init tegra_init_max_rate(struct clk *c, unsigned long max_rate)
c->max_rate = max_rate;
list_for_each_entry(shared_bus_user,
&c->shared_bus_list, u.shared_bus_user.node) {
+ shared_bus_user->u.shared_bus_user.rate = max_rate;
shared_bus_user->max_rate = max_rate;
}
}
diff --git a/arch/arm/mach-tegra/clock.h b/arch/arm/mach-tegra/clock.h
index f33818caecbe..e7d93a5634a5 100644
--- a/arch/arm/mach-tegra/clock.h
+++ b/arch/arm/mach-tegra/clock.h
@@ -141,6 +141,7 @@ struct clk {
u32 reg_shift;
struct list_head shared_bus_list;
+ struct clk_mux_sel shared_bus_backup;
union {
struct {
@@ -177,6 +178,9 @@ struct clk {
struct list_head node;
bool enabled;
unsigned long rate;
+ const char *client_id;
+ struct clk *client;
+ u32 client_div;
} shared_bus_user;
} u;
diff --git a/arch/arm/mach-tegra/common.c b/arch/arm/mach-tegra/common.c
index 00fd120ae2d1..6d62efd1dd49 100644
--- a/arch/arm/mach-tegra/common.c
+++ b/arch/arm/mach-tegra/common.c
@@ -136,8 +136,6 @@ static __initdata struct tegra_clk_init_table common_clk_init_table[] = {
{ "pll_p_out2", "pll_p", 48000000, true },
{ "pll_p_out3", "pll_p", 102000000, true },
{ "pll_m_out1", "pll_m", 275000000, true },
- { "pll_c", NULL, ULONG_MAX, false },
- { "pll_c_out1", "pll_c", 208000000, false },
{ "pll_p_out4", "pll_p", 102000000, true },
{ "sclk", "pll_p_out4", 102000000, true },
{ "hclk", "sclk", 102000000, true },
@@ -165,14 +163,8 @@ static __initdata struct tegra_clk_init_table common_clk_init_table[] = {
{ "sdmmc3", "pll_p", 48000000, false},
{ "sdmmc4", "clk_m", 12000000, true},
#ifndef CONFIG_ARCH_TEGRA_2x_SOC
- { "vde", "pll_c", ULONG_MAX, false },
- { "host1x", "pll_c", 0, false },
- { "mpe", "pll_c", 0, false },
- { "3d", "pll_c", 0, false },
- { "3d2", "pll_c", 0, false },
- { "2d", "pll_c", 0, false },
- { "epp", "pll_c", 0, false },
- { "se", "pll_c", 0, false },
+ { "cbus", "pll_c", ULONG_MAX, false },
+ { "pll_c_out1", "pll_c", 208000000, false },
#endif
{ NULL, NULL, 0, 0},
};
diff --git a/arch/arm/mach-tegra/tegra3_clocks.c b/arch/arm/mach-tegra/tegra3_clocks.c
index 4b338e9ca037..e8d520fe1663 100644
--- a/arch/arm/mach-tegra/tegra3_clocks.c
+++ b/arch/arm/mach-tegra/tegra3_clocks.c
@@ -350,7 +350,7 @@ static int tegra_periph_clk_enable_refcount[CLK_OUT_ENB_NUM * 32];
} while (0)
-static inline int clk_set_div(struct clk *c, int n)
+static inline int clk_set_div(struct clk *c, u32 n)
{
return clk_set_rate(c, (clk_get_rate(c->parent) + n-1) / n);
}
@@ -2491,6 +2491,150 @@ static struct clk_ops tegra_cml_clk_ops = {
.disable = &tegra3_cml_clk_disable,
};
+
+/* cbus ops */
+/*
+ * Some clocks require dynamic re-locking of source PLL in order to
+ * achieve frequency scaling granularity that matches characterized
+ * core voltage steps. The cbus clock creates a shared bus that
+ * provides a virtual root for such clocks to hide and synchronize
+ * parent PLL re-locking as well as backup operations.
+*/
+
+static void tegra3_clk_cbus_init(struct clk *c)
+{
+ c->state = OFF;
+ c->set = true;
+}
+
+static int tegra3_clk_cbus_enable(struct clk *c)
+{
+ return 0;
+}
+
+static long tegra3_clk_cbus_round_rate(struct clk *c, unsigned long rate)
+{
+ int i;
+
+ if (!c->dvfs)
+ return rate;
+
+ for (i = 0; i < (c->dvfs->num_freqs - 1); i++) {
+ unsigned long f = c->dvfs->freqs[i];
+ if (f >= rate)
+ break;
+ }
+ return c->dvfs->freqs[i];
+}
+
+static int cbus_switch_one(struct clk *c, struct clk *p, u32 div, bool abort)
+{
+ int ret = 0;
+
+ /* set new divider if it is bigger than the current one */
+ if (c->div < c->mul * div) {
+ ret = clk_set_div(c, div);
+ if (ret) {
+ pr_err("%s: failed to set %s clock divider %u: %d\n",
+ __func__, c->name, div, ret);
+ if (abort)
+ return ret;
+ }
+ }
+
+ ret = clk_set_parent(c, p);
+ if (ret) {
+ pr_err("%s: failed to set %s clock parent %s: %d\n",
+ __func__, c->name, p->name, ret);
+ if (abort)
+ return ret;
+ }
+
+ /* set new divider if it is smaller than the current one */
+ if (c->div > c->mul * div) {
+ ret = clk_set_div(c, div);
+ if (ret)
+ pr_err("%s: failed to set %s clock divider %u: %d\n",
+ __func__, c->name, div, ret);
+ }
+
+ return ret;
+}
+
+static int cbus_backup(struct clk *c)
+{
+ int ret;
+ struct clk *user;
+
+ list_for_each_entry(user, &c->shared_bus_list,
+ u.shared_bus_user.node) {
+ bool enabled = user->u.shared_bus_user.enabled ||
+ user->u.shared_bus_user.client->refcnt;
+ if (enabled) {
+ ret = cbus_switch_one(user->u.shared_bus_user.client,
+ c->shared_bus_backup.input,
+ c->shared_bus_backup.value *
+ user->div, true);
+ if (ret)
+ return ret;
+ }
+ }
+ return 0;
+}
+
+static void cbus_restore(struct clk *c)
+{
+ struct clk *user;
+
+ list_for_each_entry(user, &c->shared_bus_list,
+ u.shared_bus_user.node) {
+ bool back = (c->parent !=
+ user->u.shared_bus_user.client->parent);
+ if (back)
+ cbus_switch_one(user->u.shared_bus_user.client,
+ c->parent, user->div, false);
+ }
+}
+
+static int tegra3_clk_cbus_set_rate(struct clk *c, unsigned long rate)
+{
+ int ret;
+
+ if (rate == 0)
+ return 0;
+
+ ret = clk_enable(c->parent);
+ if (ret) {
+ pr_err("%s: failed to enable %s clock: %d\n",
+ __func__, c->name, ret);
+ return ret;
+ }
+
+ ret = cbus_backup(c);
+ if (ret)
+ goto out;
+
+ ret = clk_set_rate(c->parent, rate);
+ if (ret) {
+ pr_err("%s: failed to set %s clock rate %lu: %d\n",
+ __func__, c->name, rate, ret);
+ goto out;
+ }
+
+ cbus_restore(c);
+
+out:
+ clk_disable(c->parent);
+ return ret;
+}
+
+static struct clk_ops tegra_clk_cbus_ops = {
+ .init = tegra3_clk_cbus_init,
+ .enable = tegra3_clk_cbus_enable,
+ .set_rate = tegra3_clk_cbus_set_rate,
+ .round_rate = tegra3_clk_cbus_round_rate,
+};
+
/* shared bus ops */
/*
* Some clocks may have multiple downstream users that need to request a
@@ -2509,7 +2653,10 @@ static void tegra_clk_shared_bus_update(struct clk *bus)
list_for_each_entry(c, &bus->shared_bus_list,
u.shared_bus_user.node) {
- if (c->u.shared_bus_user.enabled)
+ /* Ignore requests from disabled users and from users with
+ fixed bus-to-client ratio */
+ if ((c->u.shared_bus_user.enabled) &&
+ (!c->u.shared_bus_user.client_div))
rate = max(c->u.shared_bus_user.rate, rate);
}
@@ -2524,6 +2671,18 @@ static void tegra_clk_shared_bus_init(struct clk *c)
c->state = OFF;
c->set = true;
+ if (c->u.shared_bus_user.client_id) {
+ c->u.shared_bus_user.client =
+ tegra_get_clock_by_name(c->u.shared_bus_user.client_id);
+ if (!c->u.shared_bus_user.client) {
+ pr_err("%s: could not find clk %s\n", __func__,
+ c->u.shared_bus_user.client_id);
+ return;
+ }
+ c->div = c->u.shared_bus_user.client_div ? : 1;
+ c->mul = 1;
+ }
+
list_add_tail(&c->u.shared_bus_user.node,
&c->parent->shared_bus_list);
}
@@ -2544,21 +2703,37 @@ static int tegra_clk_shared_bus_enable(struct clk *c)
{
c->u.shared_bus_user.enabled = true;
tegra_clk_shared_bus_update(c->parent);
+ if (c->u.shared_bus_user.client) {
+ return clk_enable(c->u.shared_bus_user.client);
+ }
return 0;
}
static void tegra_clk_shared_bus_disable(struct clk *c)
{
+ if (c->u.shared_bus_user.client)
+ clk_disable(c->u.shared_bus_user.client);
c->u.shared_bus_user.enabled = false;
tegra_clk_shared_bus_update(c->parent);
}
+static void tegra_clk_shared_bus_reset(struct clk *c, bool assert)
+{
+ if (c->u.shared_bus_user.client) {
+ if (c->u.shared_bus_user.client->ops &&
+ c->u.shared_bus_user.client->ops->reset)
+ c->u.shared_bus_user.client->ops->reset(
+ c->u.shared_bus_user.client, assert);
+ }
+}
+
static struct clk_ops tegra_clk_shared_bus_ops = {
.init = tegra_clk_shared_bus_init,
.enable = tegra_clk_shared_bus_enable,
.disable = tegra_clk_shared_bus_disable,
.set_rate = tegra_clk_shared_bus_set_rate,
.round_rate = tegra_clk_shared_bus_round_rate,
+ .reset = tegra_clk_shared_bus_reset,
};
@@ -3374,7 +3549,7 @@ static struct clk_mux_sel mux_pllm_pllc_pllp_plla[] = {
static struct clk_mux_sel mux_pllm_pllc_pllp_clkm[] = {
{ .input = &tegra_pll_m, .value = 0},
- { .input = &tegra_pll_c, .value = 1},
+ /* { .input = &tegra_pll_c, .value = 1}, not used on tegra3 */
{ .input = &tegra_pll_p, .value = 2},
{ .input = &tegra_clk_m, .value = 3},
{ 0, 0},
@@ -3478,6 +3653,17 @@ static struct clk tegra_clk_emc = {
},
};
+static struct clk tegra_clk_cbus = {
+ .name = "cbus",
+ .parent = &tegra_pll_c,
+ .ops = &tegra_clk_cbus_ops,
+ .max_rate = 700000000,
+ .shared_bus_backup = {
+ .input = &tegra_pll_p,
+ .value = 2,
+ }
+};
+
#define PERIPH_CLK(_name, _dev, _con, _clk_num, _reg, _max, _inputs, _flags) \
{ \
.name = _name, \
@@ -3513,7 +3699,7 @@ static struct clk tegra_clk_emc = {
}, \
}
-#define SHARED_CLK(_name, _dev, _con, _parent) \
+#define SHARED_CLK(_name, _dev, _con, _parent, _id, _div)\
{ \
.name = _name, \
.lookup = { \
@@ -3522,6 +3708,10 @@ static struct clk tegra_clk_emc = {
}, \
.ops = &tegra_clk_shared_bus_ops, \
.parent = _parent, \
+ .u.shared_bus_user = { \
+ .client_id = _id, \
+ .client_div = _div, \
+ }, \
}
struct clk tegra_list_clks[] = {
PERIPH_CLK("apbdma", "tegra-dma", NULL, 34, 0, 26000000, mux_clk_m, 0),
@@ -3566,7 +3756,7 @@ struct clk tegra_list_clks[] = {
PERIPH_CLK("vcp", "tegra-avp", "vcp", 29, 0, 250000000, mux_clk_m, 0),
PERIPH_CLK("bsea", "tegra-avp", "bsea", 62, 0, 250000000, mux_clk_m, 0),
PERIPH_CLK("bsev", "tegra-aes", "bsev", 63, 0, 250000000, mux_clk_m, 0),
- PERIPH_CLK("vde", "tegra-avp", "vde", 61, 0x1c8, 520000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | DIV_U71_INT),
+ PERIPH_CLK("vde", "vde", NULL, 61, 0x1c8, 520000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | DIV_U71_INT),
PERIPH_CLK("csite", "csite", NULL, 73, 0x1d4, 144000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* max rate ??? */
PERIPH_CLK("la", "la", NULL, 76, 0x1f8, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
PERIPH_CLK("owr", "tegra_w1", NULL, 71, 0x1cc, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | PERIPH_ON_APB),
@@ -3589,7 +3779,7 @@ struct clk tegra_list_clks[] = {
PERIPH_CLK("vi_sensor", "tegra_camera", "vi_sensor", 20, 0x1a8, 150000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71 | PERIPH_NO_RESET),
PERIPH_CLK("epp", "epp", NULL, 19, 0x16c, 520000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71 | DIV_U71_INT),
PERIPH_CLK("mpe", "mpe", NULL, 60, 0x170, 520000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71 | DIV_U71_INT),
- PERIPH_CLK("host1x", "host1x", NULL, 28, 0x180, 208000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71 | DIV_U71_INT),
+ PERIPH_CLK("host1x", "host1x", NULL, 28, 0x180, 260000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71 | DIV_U71_INT),
PERIPH_CLK("cve", "cve", NULL, 49, 0x140, 250000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), /* requires min voltage */
PERIPH_CLK("tvo", "tvo", NULL, 49, 0x188, 250000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), /* requires min voltage */
PERIPH_CLK_EX("dtv", "dtv", NULL, 79, 0x1dc, 250000000, mux_clk_m, 0, &tegra_dtv_clk_ops),
@@ -3613,24 +3803,33 @@ struct clk tegra_list_clks[] = {
PERIPH_CLK("i2cslow", "i2cslow", NULL, 81, 0x3fc, 26000000, mux_pllp_pllc_clk32_clkm, MUX | DIV_U71 | PERIPH_ON_APB),
PERIPH_CLK("pcie", "tegra-pcie", "pcie", 70, 0, 250000000, mux_clk_m, 0),
PERIPH_CLK("afi", "tegra-pcie", "afi", 72, 0, 250000000, mux_clk_m, 0),
- PERIPH_CLK("se", "tegra-se", NULL, 127, 0x42c, 520000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71| DIV_U71_INT),
-
- SHARED_CLK("avp.sclk", "tegra-avp", "sclk", &tegra_clk_sbus_cmplx),
- SHARED_CLK("bsea.sclk", "tegra-aes", "sclk", &tegra_clk_sbus_cmplx),
- SHARED_CLK("usbd.sclk", "fsl-tegra-udc", "sclk", &tegra_clk_sbus_cmplx),
- SHARED_CLK("usb1.sclk", "tegra-ehci.0", "sclk", &tegra_clk_sbus_cmplx),
- SHARED_CLK("usb2.sclk", "tegra-ehci.1", "sclk", &tegra_clk_sbus_cmplx),
- SHARED_CLK("usb3.sclk", "tegra-ehci.2", "sclk", &tegra_clk_sbus_cmplx),
- SHARED_CLK("avp.emc", "tegra-avp", "emc", &tegra_clk_emc),
- SHARED_CLK("cpu.emc", "cpu", "emc", &tegra_clk_emc),
- SHARED_CLK("disp1.emc", "tegradc.0", "emc", &tegra_clk_emc),
- SHARED_CLK("disp2.emc", "tegradc.1", "emc", &tegra_clk_emc),
- SHARED_CLK("hdmi.emc", "hdmi", "emc", &tegra_clk_emc),
- SHARED_CLK("host.emc", "tegra_grhost", "emc", &tegra_clk_emc),
- SHARED_CLK("usbd.emc", "fsl-tegra-udc", "emc", &tegra_clk_emc),
- SHARED_CLK("usb1.emc", "tegra-ehci.0", "emc", &tegra_clk_emc),
- SHARED_CLK("usb2.emc", "tegra-ehci.1", "emc", &tegra_clk_emc),
- SHARED_CLK("usb3.emc", "tegra-ehci.2", "emc", &tegra_clk_emc),
+ PERIPH_CLK("se", "se", NULL, 127, 0x42c, 520000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71| DIV_U71_INT),
+
+ SHARED_CLK("avp.sclk", "tegra-avp", "sclk", &tegra_clk_sbus_cmplx, NULL, 0),
+ SHARED_CLK("bsea.sclk", "tegra-aes", "sclk", &tegra_clk_sbus_cmplx, NULL, 0),
+ SHARED_CLK("usbd.sclk", "fsl-tegra-udc", "sclk", &tegra_clk_sbus_cmplx, NULL, 0),
+ SHARED_CLK("usb1.sclk", "tegra-ehci.0", "sclk", &tegra_clk_sbus_cmplx, NULL, 0),
+ SHARED_CLK("usb2.sclk", "tegra-ehci.1", "sclk", &tegra_clk_sbus_cmplx, NULL, 0),
+ SHARED_CLK("usb3.sclk", "tegra-ehci.2", "sclk", &tegra_clk_sbus_cmplx, NULL, 0),
+ SHARED_CLK("avp.emc", "tegra-avp", "emc", &tegra_clk_emc, NULL, 0),
+ SHARED_CLK("cpu.emc", "cpu", "emc", &tegra_clk_emc, NULL, 0),
+ SHARED_CLK("disp1.emc", "tegradc.0", "emc", &tegra_clk_emc, NULL, 0),
+ SHARED_CLK("disp2.emc", "tegradc.1", "emc", &tegra_clk_emc, NULL, 0),
+ SHARED_CLK("hdmi.emc", "hdmi", "emc", &tegra_clk_emc, NULL, 0),
+ SHARED_CLK("host.emc", "tegra_grhost", "emc", &tegra_clk_emc, NULL, 0),
+ SHARED_CLK("usbd.emc", "fsl-tegra-udc", "emc", &tegra_clk_emc, NULL, 0),
+ SHARED_CLK("usb1.emc", "tegra-ehci.0", "emc", &tegra_clk_emc, NULL, 0),
+ SHARED_CLK("usb2.emc", "tegra-ehci.1", "emc", &tegra_clk_emc, NULL, 0),
+ SHARED_CLK("usb3.emc", "tegra-ehci.2", "emc", &tegra_clk_emc, NULL, 0),
+
+ SHARED_CLK("host1x.cbus","tegra_grhost", "host1x", &tegra_clk_cbus, "host1x", 2),
+ SHARED_CLK("3d.cbus", "tegra_grhost", "gr3d", &tegra_clk_cbus, "3d", 0),
+ SHARED_CLK("3d2.cbus", "tegra_grhost", "gr3d2",&tegra_clk_cbus, "3d2", 0),
+ SHARED_CLK("2d.cbus", "tegra_grhost", "gr2d", &tegra_clk_cbus, "2d", 0),
+ SHARED_CLK("epp.cbus", "tegra_grhost", "epp", &tegra_clk_cbus, "epp", 0),
+ SHARED_CLK("mpe.cbus", "tegra_grhost", "mpe", &tegra_clk_cbus, "mpe", 0),
+ SHARED_CLK("vde.cbus", "tegra-avp", "vde", &tegra_clk_cbus, "vde", 0),
+ SHARED_CLK("se.cbus", "tegra-se", NULL, &tegra_clk_cbus, "se", 0),
};
#define CLK_DUPLICATE(_name, _dev, _con) \
@@ -3663,12 +3862,6 @@ struct clk_duplicate tegra_clk_duplicates[] = {
CLK_DUPLICATE("pwm", "tegra_pwm.1", NULL),
CLK_DUPLICATE("pwm", "tegra_pwm.2", NULL),
CLK_DUPLICATE("pwm", "tegra_pwm.3", NULL),
- CLK_DUPLICATE("host1x", "tegra_grhost", "host1x"),
- CLK_DUPLICATE("2d", "tegra_grhost", "gr2d"),
- CLK_DUPLICATE("3d", "tegra_grhost", "gr3d"),
- CLK_DUPLICATE("3d2", "tegra_grhost", "gr3d2"),
- CLK_DUPLICATE("epp", "tegra_grhost", "epp"),
- CLK_DUPLICATE("mpe", "tegra_grhost", "mpe"),
CLK_DUPLICATE("cop", "tegra-avp", "cop"),
CLK_DUPLICATE("vde", "tegra-aes", "vde"),
CLK_DUPLICATE("cml1", "tegra_sata_cml", NULL),
@@ -3729,6 +3922,7 @@ struct clk *tegra_ptr_clks[] = {
&tegra_clk_sbus_cmplx,
&tegra_clk_emc,
&tegra3_clk_twd,
+ &tegra_clk_cbus,
};
static struct tegra_edp_limits default_cpu_edp_limits[] = {
diff --git a/arch/arm/mach-tegra/tegra3_dvfs.c b/arch/arm/mach-tegra/tegra3_dvfs.c
index 92e8e476beb7..c9572a1cf756 100644
--- a/arch/arm/mach-tegra/tegra3_dvfs.c
+++ b/arch/arm/mach-tegra/tegra3_dvfs.c
@@ -166,7 +166,7 @@ static struct dvfs core_dvfs_table[] = {
CORE_DVFS("sbus", 1, 1, KHZ, 136000, 163000, 191000, 216000, 245000, 245000, 245000),
CORE_DVFS("sbus", 2, 1, KHZ, 140000, 169000, 203000, 228000, 254000, 279000, 300000),
- CORE_DVFS("vde", 0, 1, KHZ, 216000, 270000, 332000, 380000, 416000, 416000, 416000),
+ CORE_DVFS("vde", 0, 1, KHZ, 228000, 275000, 332000, 380000, 416000, 416000, 416000),
CORE_DVFS("mpe", 0, 1, KHZ, 234000, 285000, 332000, 380000, 416000, 416000, 416000),
CORE_DVFS("2d", 0, 1, KHZ, 267000, 285000, 332000, 380000, 416000, 416000, 416000),
CORE_DVFS("epp", 0, 1, KHZ, 267000, 285000, 332000, 380000, 416000, 416000, 416000),
@@ -175,7 +175,7 @@ static struct dvfs core_dvfs_table[] = {
CORE_DVFS("vi", 0, 1, KHZ, 216000, 285000, 300000, 300000, 300000, 300000, 300000),
CORE_DVFS("se", 0, 1, KHZ, 267000, 285000, 332000, 380000, 416000, 416000, 416000),
- CORE_DVFS("vde", 1, 1, KHZ, 216000, 270000, 332000, 380000, 416000, 416000, 416000),
+ CORE_DVFS("vde", 1, 1, KHZ, 228000, 275000, 332000, 380000, 416000, 416000, 416000),
CORE_DVFS("mpe", 1, 1, KHZ, 234000, 285000, 332000, 380000, 416000, 416000, 416000),
CORE_DVFS("2d", 1, 1, KHZ, 267000, 285000, 332000, 380000, 416000, 416000, 416000),
CORE_DVFS("epp", 1, 1, KHZ, 267000, 285000, 332000, 380000, 416000, 416000, 416000),
@@ -195,10 +195,11 @@ static struct dvfs core_dvfs_table[] = {
CORE_DVFS("host1x",-1, 1, KHZ, 152000, 188000, 222000, 254000, 267000, 267000, 267000),
- CORE_DVFS("pll_c", 0, 1, KHZ, 466000, 564000, 664000, 760000, 832000, 832000, 832000),
- CORE_DVFS("pll_c", 1, 1, KHZ, 466000, 564000, 664000, 760000, 832000, 832000, 832000),
- CORE_DVFS("pll_c", 2, 1, KHZ, 494000, 608000, 722000, 816000, 892000, 968000, 1040000),
+ CORE_DVFS("cbus", 0, 1, KHZ, 228000, 275000, 332000, 380000, 416000, 416000, 416000),
+ CORE_DVFS("cbus", 1, 1, KHZ, 228000, 275000, 332000, 380000, 416000, 416000, 416000),
+ CORE_DVFS("cbus", 2, 1, KHZ, 247000, 304000, 361000, 408000, 446000, 484000, 520000),
+ CORE_DVFS("pll_c", -1, 1, KHZ, 600000, 600000, 800000, 800000, 1066000, 1066000, 1066000),
CORE_DVFS("pll_m", -1, 1, KHZ, 600000, 600000, 800000, 800000, 1066000, 1066000, 1066000),
/* Core voltages (mV): 1000, 1050, 1100, 1150, 1200, 1250, 1300 */