video: tegra: camera: squash changes for pll_d2_clk
Jihoon Bang [Thu, 17 Jan 2013 18:19:29 +0000 (10:19 -0800)]
Squash following changes. These changes are about
handling pll_d2_clk which is used to test pattern
generator in VI/CSI.

08c492d1d7d13: fix test pattern generator
60817b5005851: enable/disable pll_d2 in balance

Fix build error related for T148.
3beca1de87b49: fix build error

Fix uneven clk_enable/clk_disable.

Bug 1189789
Bug 1168336
Bug 1214620

Reviewed-on: http://git-master/r/192115
(cherry picked from commit b526c6cbed623f86b0c7ddba2796c40ffb489826)

Change-Id: Ie6dd1dcfb5e68e522eb5817369ef49eff59f46af
Signed-off-by: Jihoon Bang <jbang@nvidia.com>
Reviewed-on: http://git-master/r/194806
Reviewed-by: Automatic_Commit_Validation_User
GVS: Gerrit_Virtual_Submit
Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>

drivers/video/tegra/camera/camera.c
drivers/video/tegra/camera/camera_clk.c
drivers/video/tegra/camera/camera_clk.h
drivers/video/tegra/camera/camera_emc.c
drivers/video/tegra/camera/camera_priv_defs.h
drivers/video/tegra/host/vi/vi.c

index 9264d8f..67080a8 100644 (file)
 
 #define TEGRA_CAMERA_NAME "tegra_camera"
 
-static struct camera_clk tegra_camera_clk[] = {
-       { CAMERA_ISP_CLK, "isp"},
-       { CAMERA_VI_CLK, "vi"},
-       { CAMERA_VI_SENSOR_CLK, "vi_sensor"},
-       { CAMERA_CSUS_CLK, "csus"},
-       { CAMERA_CSI_CLK, "csi"},
-       { CAMERA_EMC_CLK, "emc"},
+static struct clock_data clock_init[] = {
+       { CAMERA_ISP_CLK, "isp", true},
+       { CAMERA_VI_CLK, "vi", true},
+       { CAMERA_VI_SENSOR_CLK, "vi_sensor", true},
+       { CAMERA_CSUS_CLK, "csus", true},
+       { CAMERA_CSI_CLK, "csi", true},
+       { CAMERA_EMC_CLK, "emc", true},
 #ifdef CONFIG_ARCH_TEGRA_11x_SOC
-       { CAMERA_CILAB_CLK, "cilab"},
-       { CAMERA_CILCD_CLK, "cilcd"},
-       { CAMERA_CILE_CLK, "cile"},
-       { CAMERA_PLL_D2_CLK, "pll_d2"}
+       { CAMERA_CILAB_CLK, "cilab", true},
+       { CAMERA_CILCD_CLK, "cilcd", true},
+       { CAMERA_CILE_CLK, "cile", true},
+       { CAMERA_PLL_D2_CLK, "pll_d2", false}
 #endif
 };
 
@@ -120,6 +120,10 @@ static int tegra_camera_open(struct inode *inode, struct file *file)
        ret = tegra_camera_enable_emc(camera);
        if (ret)
                goto enable_emc_fail;
+
+       /* read initial clock info */
+       tegra_camera_init_clk(camera, clock_init);
+
        /* enable camera HW clock */
        ret = tegra_camera_enable_clk(camera);
        if (ret)
@@ -245,8 +249,8 @@ struct tegra_camera *tegra_camera_register(struct platform_device *ndev)
        }
 
        for (i = 0; i < CAMERA_CLK_MAX; i++) {
-               ret = tegra_camera_clk_get(ndev, tegra_camera_clk[i].name,
-                               &camera->clk[tegra_camera_clk[i].index]);
+               ret = tegra_camera_clk_get(ndev, clock_init[i].name,
+                               &camera->clock[clock_init[i].index].clk);
                if (ret)
                        goto clk_get_fail;
        }
@@ -275,7 +279,7 @@ struct tegra_camera *tegra_camera_register(struct platform_device *ndev)
 
 clk_get_fail:
        for (; i > 0; i--)
-               clk_put(camera->clk[i-1]);
+               clk_put(camera->clock[clock_init[i].index].clk);
        misc_deregister(&camera->misc_dev);
 misc_register_fail:
        regulator_put(camera->reg);
@@ -287,8 +291,13 @@ regulator_fail:
 
 int tegra_camera_unregister(struct tegra_camera *camera)
 {
+       int i;
+
        dev_info(camera->dev, "%s: ++\n", __func__);
 
+       for (i = 0; i < CAMERA_CLK_MAX; i++)
+               clk_put(camera->clock[i].clk);
+
 #ifdef CONFIG_ARCH_TEGRA_11x_SOC
        /*
         * Return memory bandwidth to isomgr.
index d3668c9..e6e75fb 100644 (file)
@@ -20,7 +20,9 @@ int tegra_camera_enable_clk(struct tegra_camera *camera)
 {
        int i;
        for (i = 0; i < CAMERA_CLK_MAX; i++)
-               clk_prepare_enable(camera->clk[i]);
+               if (camera->clock[i].on)
+                       clk_prepare_enable(camera->clock[i].clk);
+
        return 0;
 }
 
@@ -28,7 +30,18 @@ int tegra_camera_disable_clk(struct tegra_camera *camera)
 {
        int i;
        for (i = CAMERA_CLK_MAX; i > 0; i--)
-               clk_prepare_enable(camera->clk[i-1]);
+               if (camera->clock[i-1].on)
+                       clk_disable_unprepare(camera->clock[i-1].clk);
+
+       return 0;
+}
+
+int tegra_camera_init_clk(struct tegra_camera *camera,
+               struct clock_data *clock_init)
+{
+       int i;
+       for (i = 0; i < CAMERA_CLK_MAX; i++)
+               camera->clock[clock_init[i].index].on = clock_init[i].init;
        return 0;
 }
 
@@ -55,13 +68,32 @@ int tegra_camera_clk_set_rate(struct tegra_camera *camera)
 
        switch (info->clk_id) {
        case TEGRA_CAMERA_VI_CLK:
-               clk = camera->clk[CAMERA_VI_CLK];
+#if defined(CONFIG_ARCH_TEGRA_11x_SOC) || defined(CONFIG_ARCH_TEGRA_14x_SOC)
+               if (info->flag == TEGRA_CAMERA_ENABLE_PD2VI_CLK) {
+                       if (camera->clock[CAMERA_PLL_D2_CLK].clk) {
+                               clk_prepare_enable(
+                                       camera->clock[CAMERA_PLL_D2_CLK].clk);
+                               clk = camera->clock[CAMERA_PLL_D2_CLK].clk;
+                               camera->clock[CAMERA_PLL_D2_CLK].on = true;
+                       } else {
+                               /*
+                                * PowerSaving: enable pll_d2 for camera only
+                                * when required. pll_d2 will be disabled when
+                                * camera will be released.
+                                */
+                               return -EINVAL;
+                       }
+               } else
+#endif
+               {
+                       clk = camera->clock[CAMERA_VI_CLK].clk;
+               }
                break;
        case TEGRA_CAMERA_VI_SENSOR_CLK:
-               clk = camera->clk[CAMERA_VI_SENSOR_CLK];
+               clk = camera->clock[CAMERA_VI_SENSOR_CLK].clk;
                break;
        case TEGRA_CAMERA_EMC_CLK:
-               clk = camera->clk[CAMERA_EMC_CLK];
+               clk = camera->clock[CAMERA_EMC_CLK].clk;
 #ifndef CONFIG_ARCH_TEGRA_2x_SOC
                {
                        /*
@@ -117,16 +149,21 @@ int tegra_camera_clk_set_rate(struct tegra_camera *camera)
        parent_div_rate = parent_rate;
        parent_div_rate_pre = parent_rate;
 
-       /*
-        * The requested clock rate from user space should be respected.
-        * This loop is to search the clock rate that is higher than requested
-        * clock.
-        */
-       while (parent_div_rate >= info->rate) {
-               parent_div_rate_pre = parent_div_rate;
-               parent_div_rate = clk_round_rate(clk, parent_div_rate-1);
+       if (info->flag != TEGRA_CAMERA_ENABLE_PD2VI_CLK) {
+               /*
+                * The requested clock rate from user space should be respected.
+                * This loop is to search the clock rate that is higher than
+                * requested clock.
+                * However, for camera pattern generator, since we share the
+                * clk source with display, we would not want to change the
+                * display clock.
+                */
+               while (parent_div_rate >= info->rate) {
+                       parent_div_rate_pre = parent_div_rate;
+                       parent_div_rate = clk_round_rate(clk,
+                               parent_div_rate-1);
+               }
        }
-
        dev_dbg(camera->dev, "%s: set_rate=%lu",
                        __func__, parent_div_rate_pre);
 
@@ -143,9 +180,11 @@ int tegra_camera_clk_set_rate(struct tegra_camera *camera)
                }
 #endif
                if (info->flag == TEGRA_CAMERA_ENABLE_PD2VI_CLK) {
-#ifdef CONFIG_ARCH_TEGRA_11x_SOC
-                       tegra_clk_cfg_ex(camera->clk[CAMERA_PLL_D2_CLK],
+#if defined(CONFIG_ARCH_TEGRA_11x_SOC) || defined(CONFIG_ARCH_TEGRA_14x_SOC)
+                       tegra_clk_cfg_ex(camera->clock[CAMERA_PLL_D2_CLK].clk,
                                                TEGRA_CLK_PLLD_CSI_OUT_ENB, 1);
+                       tegra_clk_cfg_ex(camera->clock[CAMERA_PLL_D2_CLK].clk,
+                                               TEGRA_CLK_PLLD_DSI_OUT_ENB, 1);
 #else
                /*
                 * bit 25: 0 = pd2vi_Clk, 1 = vi_sensor_clk
@@ -154,10 +193,12 @@ int tegra_camera_clk_set_rate(struct tegra_camera *camera)
                        tegra_clk_cfg_ex(clk, TEGRA_CLK_VI_INP_SEL, 2);
 #endif
                }
-#ifdef CONFIG_ARCH_TEGRA_11x_SOC
+#if defined(CONFIG_ARCH_TEGRA_11x_SOC) || defined(CONFIG_ARCH_TEGRA_14x_SOC)
                else {
-                       tegra_clk_cfg_ex(camera->clk[CAMERA_PLL_D2_CLK],
+                       tegra_clk_cfg_ex(camera->clock[CAMERA_PLL_D2_CLK].clk,
                                                TEGRA_CLK_PLLD_CSI_OUT_ENB, 0);
+                       tegra_clk_cfg_ex(camera->clock[CAMERA_PLL_D2_CLK].clk,
+                                               TEGRA_CLK_PLLD_DSI_OUT_ENB, 0);
                }
 #endif
        }
index 19fc9db..a912eee 100644 (file)
@@ -21,5 +21,7 @@
 int tegra_camera_enable_clk(struct tegra_camera *camera);
 int tegra_camera_disable_clk(struct tegra_camera *camera);
 int tegra_camera_clk_set_rate(struct tegra_camera *camera);
+int tegra_camera_init_clk(struct tegra_camera *camera,
+               struct clock_data *clock_init);
 
 #endif
index 44208c1..ad28fc3 100644 (file)
@@ -21,9 +21,9 @@ int tegra_camera_enable_emc(struct tegra_camera *camera)
        int ret = tegra_emc_disable_eack();
 
        dev_dbg(camera->dev, "%s++\n", __func__);
-       clk_prepare_enable(camera->clk[CAMERA_EMC_CLK]);
+       clk_prepare_enable(camera->clock[CAMERA_EMC_CLK].clk);
 #ifdef CONFIG_ARCH_TEGRA_2x_SOC
-       clk_set_rate(camera->clk[TEGRA_CAMERA_EMC_CLK], 300000000);
+       clk_set_rate(camera->clock[TEGRA_CAMERA_EMC_CLK].clk, 300000000);
 #endif
        return ret;
 }
@@ -31,6 +31,6 @@ int tegra_camera_enable_emc(struct tegra_camera *camera)
 int tegra_camera_disable_emc(struct tegra_camera *camera)
 {
        dev_dbg(camera->dev, "%s++\n", __func__);
-       clk_disable_unprepare(camera->clk[CAMERA_EMC_CLK]);
+       clk_disable_unprepare(camera->clock[CAMERA_EMC_CLK].clk);
        return tegra_emc_enable_eack();
 }
index 19dbb7c..e10fdf1 100644 (file)
@@ -52,7 +52,7 @@ enum {
        CAMERA_ISP_CLK,
        CAMERA_CSUS_CLK,
        CAMERA_CSI_CLK,
-#ifdef CONFIG_ARCH_TEGRA_11x_SOC
+#if defined(CONFIG_ARCH_TEGRA_11x_SOC) || defined(CONFIG_ARCH_TEGRA_14x_SOC)
        CAMERA_CILAB_CLK,
        CAMERA_CILCD_CLK,
        CAMERA_CILE_CLK,
@@ -61,10 +61,15 @@ enum {
        CAMERA_CLK_MAX,
 };
 
+struct clock {
+       struct clk *clk;
+       bool on;
+};
+
 struct tegra_camera {
        struct device *dev;
        struct miscdevice misc_dev;
-       struct clk *clk[CAMERA_CLK_MAX];
+       struct clock clock[CAMERA_CLK_MAX];
        struct regulator *reg;
        struct tegra_camera_clk_info info;
        struct mutex tegra_camera_lock;
@@ -75,9 +80,10 @@ struct tegra_camera {
 #endif
 };
 
-struct camera_clk {
+struct clock_data {
        int index;
        char *name;
+       bool init;
 };
 
 struct tegra_camera *tegra_camera_register(struct platform_device *ndev);
index f18d9ce..ec9b677 100644 (file)
@@ -108,7 +108,7 @@ static int __exit vi_remove(struct platform_device *dev)
 #ifdef CONFIG_TEGRA_CAMERA
        int err = 0;
        struct nvhost_device_data *pdata =
-               (struct nvhost_device_data *)dev->dev.platform_data;
+               (struct nvhost_device_data *)platform_get_drvdata(dev);
        struct vi *tegra_vi = (struct vi *)pdata->private_data;
 #endif
 
@@ -127,8 +127,9 @@ static int __exit vi_remove(struct platform_device *dev)
 static int vi_suspend(struct device *dev)
 {
 #ifdef CONFIG_TEGRA_CAMERA
+       struct platform_device *pdev = to_platform_device(dev);
        struct nvhost_device_data *pdata =
-               (struct nvhost_device_data *)dev->platform_data;
+               (struct nvhost_device_data *)platform_get_drvdata(pdev);
        struct vi *tegra_vi = (struct vi *)pdata->private_data;
 #endif
 
@@ -144,9 +145,9 @@ static int vi_suspend(struct device *dev)
 static int vi_resume(struct device *dev)
 {
 #ifdef CONFIG_TEGRA_CAMERA
+       struct platform_device *pdev = to_platform_device(dev);
        struct nvhost_device_data *pdata =
-               (struct nvhost_device_data *)dev->platform_data;
-
+               (struct nvhost_device_data *)platform_get_drvdata(pdev);
        struct vi *tegra_vi = (struct vi *)pdata->private_data;
 #endif