ARM: Tegra: Add smp_twd clock for Tegra20
authorPrashant Gaikwad <pgaikwad@nvidia.com>
Thu, 13 Sep 2012 09:34:33 +0000 (15:04 +0530)
committerStephen Warren <swarren@nvidia.com>
Thu, 13 Sep 2012 17:34:29 +0000 (11:34 -0600)
Clockevent's frequency is changed upon cpufreq change
notification. It fetches local timer's rate to update the
clockevent frequency. This patch adds local timer clock
for Tegra20.

Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
arch/arm/mach-tegra/tegra20_clocks.c
arch/arm/mach-tegra/tegra20_clocks.h
arch/arm/mach-tegra/tegra20_clocks_data.c

index d9ce0087f6a6f186e03287952d8b21ac0b082020..840ab262272a67b82b7354a7a476dc601c6cd96f 100644 (file)
@@ -376,6 +376,25 @@ struct clk_ops tegra_super_ops = {
        .recalc_rate = tegra20_super_clk_recalc_rate,
 };
 
+static unsigned long tegra20_twd_clk_recalc_rate(struct clk_hw *hw,
+               unsigned long parent_rate)
+{
+       struct clk_tegra *c = to_clk_tegra(hw);
+       u64 rate = parent_rate;
+
+       if (c->mul != 0 && c->div != 0) {
+               rate *= c->mul;
+               rate += c->div - 1; /* round up */
+               do_div(rate, c->div);
+       }
+
+       return rate;
+}
+
+struct clk_ops tegra_twd_ops = {
+       .recalc_rate = tegra20_twd_clk_recalc_rate,
+};
+
 static u8 tegra20_cop_clk_get_parent(struct clk_hw *hw)
 {
        return 0;
index 0e42ec065d4a89314f4ce32720b7dfed9911c41a..8bfd31bcc490dbd9cb1bb0b795b94eccf3747ae0 100644 (file)
@@ -28,6 +28,7 @@ extern struct clk_ops tegra_cdev_clk_ops;
 extern struct clk_ops tegra_audio_sync_clk_ops;
 extern struct clk_ops tegra_super_ops;
 extern struct clk_ops tegra_cpu_ops;
+extern struct clk_ops tegra_twd_ops;
 extern struct clk_ops tegra_cop_ops;
 extern struct clk_ops tegra_bus_ops;
 extern struct clk_ops tegra_blink_clk_ops;
index 1eb50674721ee0d175d57c336655af0f39930140..1a35c003fba8488c996f839f943bd5731197a67a 100644 (file)
@@ -583,6 +583,34 @@ static struct clk_tegra tegra_cclk_hw = {
 DEFINE_CLK_TEGRA(cclk, 0, &tegra_super_ops, 0, mux_cclk,
                mux_cclk_p, NULL);
 
+static const char *mux_twd[] = {
+       "cclk",
+};
+
+static struct clk *mux_twd_p[] = {
+       &tegra_cclk,
+};
+
+static struct clk tegra_clk_twd;
+static struct clk_tegra tegra_clk_twd_hw = {
+       .hw = {
+               .clk = &tegra_clk_twd,
+       },
+       .max_rate = 1000000000,
+       .mul = 1,
+       .div = 4,
+};
+
+static struct clk tegra_clk_twd = {
+       .name = "twd",
+       .ops = &tegra_twd_ops,
+       .hw = &tegra_clk_twd_hw.hw,
+       .parent = &tegra_cclk,
+       .parent_names = mux_twd,
+       .parents = mux_twd_p,
+       .num_parents = ARRAY_SIZE(mux_twd),
+};
+
 static struct clk tegra_sclk;
 static struct clk_tegra tegra_sclk_hw = {
        .hw = {
@@ -1027,6 +1055,7 @@ static struct clk_duplicate tegra_clk_duplicates[] = {
        CLK_DUPLICATE("cop",    "tegra-avp",    "cop"),
        CLK_DUPLICATE("vde",    "tegra-aes",    "vde"),
        CLK_DUPLICATE("cclk",   NULL,           "cpu"),
+       CLK_DUPLICATE("twd",    "smp_twd",      NULL),
 };
 
 #define CLK(dev, con, ck)      \
@@ -1057,6 +1086,7 @@ static struct clk *tegra_ptr_clks[] = {
        &tegra_pll_x,
        &tegra_pll_e,
        &tegra_cclk,
+       &tegra_clk_twd,
        &tegra_sclk,
        &tegra_hclk,
        &tegra_pclk,