]> rtime.felk.cvut.cz Git - sojka/nv-tegra/linux-3.10.git/commitdiff
ARM: tegra14: clock: Add virtual mclk for camera
authorFrank Chen <frankc@nvidia.com>
Wed, 10 Jul 2013 01:43:59 +0000 (18:43 -0700)
committerDan Willemsen <dwillemsen@nvidia.com>
Sat, 14 Sep 2013 20:33:35 +0000 (13:33 -0700)
Add a virtual clock to control sensor mclk and
clock gate.

Bug 1306878

Change-Id: I8f9ecde5e522b504df0ab66655ce5e9181106a85
Signed-off-by: Frank Chen <frankc@nvidia.com>
Signed-off-by: David Schalig <dschalig@nvidia.com>
Reviewed-on: http://git-master/r/246951
(cherry picked from commit 024e9b8f3c53e0bd99d1e2e544170e8493f19b11)
Reviewed-on: http://git-master/r/253167
Reviewed-by: Automatic_Commit_Validation_User
GVS: Gerrit_Virtual_Submit
Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com>
Reviewed-by: Aleksandr Frid <afrid@nvidia.com>
arch/arm/mach-tegra/tegra14_clocks.c

index b7b60d46c75d79b5e103f8fc2311196f29e1770b..871233ddfd58ad05f94869fa1439de4492524b7c 100644 (file)
@@ -6235,6 +6235,52 @@ static struct clk tegra_clk_cbus = {
 };
 #endif
 
+static void tegra14_camera_mclk_init(struct clk *c)
+{
+       c->state = OFF;
+       c->set = true;
+
+       if (!strcmp(c->name, "mclk")) {
+               c->parent = tegra_get_clock_by_name("vi_sensor");
+               c->max_rate = c->parent->max_rate;
+       }
+
+       if (!strcmp(c->name, "mclk2")) {
+               c->parent = tegra_get_clock_by_name("vi_sensor2");
+               c->max_rate = c->parent->max_rate;
+       }
+}
+
+static int tegra14_camera_mclk_set_rate(struct clk *c, unsigned long rate)
+{
+       return clk_set_rate(c->parent, rate);
+}
+
+static struct clk_ops tegra_camera_mclk_ops = {
+       .init     = tegra14_camera_mclk_init,
+       .enable   = tegra14_periph_clk_enable,
+       .disable  = tegra14_periph_clk_disable,
+       .set_rate = tegra14_camera_mclk_set_rate,
+};
+
+static struct clk tegra_camera_mclk = {
+       .name = "mclk",
+       .ops = &tegra_camera_mclk_ops,
+       .u.periph = {
+               .clk_num = 92,
+       },
+       .flags = PERIPH_NO_RESET,
+};
+
+static struct clk tegra_camera_mclk2 = {
+       .name = "mclk2",
+       .ops = &tegra_camera_mclk_ops,
+       .u.periph = {
+               .clk_num = 171,
+       },
+       .flags = PERIPH_NO_RESET,
+};
+
 #define PERIPH_CLK(_name, _dev, _con, _clk_num, _reg, _max, _inputs, _flags) \
        {                                               \
                .name      = _name,                     \
@@ -6594,7 +6640,7 @@ struct clk_duplicate tegra_clk_duplicates[] = {
        CLK_DUPLICATE("csus", "touch_clk", "e1680_ts_clk_con"),
        CLK_DUPLICATE("dmic0", "tegra-dmic.0", NULL),
        CLK_DUPLICATE("dmic1", "tegra-dmic.1", NULL),
-       CLK_DUPLICATE("vi_sensor2", NULL, "default_mclk"),
+       CLK_DUPLICATE("mclk2", NULL, "default_mclk"),
 };
 
 struct clk *tegra_ptr_clks[] = {
@@ -6653,6 +6699,11 @@ struct clk *tegra_ptr_clks[] = {
 #endif
 };
 
+struct clk *tegra_ptr_camera_mclks[] = {
+       &tegra_camera_mclk,
+       &tegra_camera_mclk2,
+};
+
 /* Return true from this function if the target rate can be locked without
    switching pll clients to back-up source */
 static bool tegra14_is_dyn_ramp(
@@ -7317,6 +7368,9 @@ void __init tegra14x_init_clocks(void)
        for (i = 0; i < ARRAY_SIZE(tegra_list_clks); i++)
                tegra14_init_one_clock(&tegra_list_clks[i]);
 
+       for (i = 0; i < ARRAY_SIZE(tegra_ptr_camera_mclks); i++)
+               tegra14_init_one_clock(tegra_ptr_camera_mclks[i]);
+
        for (i = 0; i < ARRAY_SIZE(tegra_clk_duplicates); i++) {
                c = tegra_get_clock_by_name(tegra_clk_duplicates[i].name);
                if (!c) {