]> rtime.felk.cvut.cz Git - hercules2020/nv-tegra/linux-4.4.git/commitdiff
pwm: tegra: add support to set parent clok
authorR Raj Kumar <rrajk@nvidia.com>
Tue, 7 Mar 2017 08:37:47 +0000 (14:07 +0530)
committermobile promotions <svcmobile_promotions@nvidia.com>
Wed, 12 Apr 2017 18:44:32 +0000 (11:44 -0700)
Add support to configure parent clock source for PWM
controller. The parent clock information is provided from
DT.

This helps in getting maximum clock source frequency if
proper parent is not selected by bootloader.

Bug 200267484

Change-Id: I961cf2a8c71f4b756198ea641c2dc33ddf35ac96
Signed-off-by: R Raj Kumar <rrajk@nvidia.com>
Reviewed-on: http://git-master/r/1461444
Reviewed-by: svccoveritychecker <svccoveritychecker@nvidia.com>
GVS: Gerrit_Virtual_Submit
Reviewed-by: Laxman Dewangan <ldewangan@nvidia.com>
Tested-by: Laxman Dewangan <ldewangan@nvidia.com>
drivers/pwm/pwm-tegra.c

index e0e66ebc6399314d87c3364f1f96f19c48014e36..c74547379804d058212408a70201d9c214d3fafd 100644 (file)
@@ -40,6 +40,8 @@
 #define PWM_SCALE_WIDTH        13
 #define PWM_SCALE_SHIFT        0
 
+#define CLK_1MHz       1000000UL
+
 struct tegra_pwm_soc {
        unsigned int num_channels;
        unsigned long max_clk_limit;
@@ -264,6 +266,7 @@ static int tegra_pwm_probe(struct platform_device *pdev)
        struct tegra_pwm_chip *pwm;
        struct resource *r;
        bool no_clk_sleeping_in_ops;
+       struct clk *parent_clk;
        int ret;
 
        pwm = devm_kzalloc(&pdev->dev, sizeof(*pwm), GFP_KERNEL);
@@ -300,6 +303,34 @@ static int tegra_pwm_probe(struct platform_device *pdev)
                return PTR_ERR(pwm->clk);
        }
 
+       parent_clk = devm_clk_get(&pdev->dev, "parent");
+       if (!IS_ERR(parent_clk)) {
+               struct device *dev = &pdev->dev;
+
+               /*
+                * Set PWM frequency to lower so that it can switch
+                * to parent with higher clock rate.
+                */
+               ret = clk_set_rate(pwm->clk, CLK_1MHz);
+               if (ret < 0) {
+                       dev_err(dev, "Failed to set 1M clock rate: %d\n", ret);
+                       return ret;
+               }
+
+               ret = clk_set_parent(pwm->clk, parent_clk);
+               if (ret < 0) {
+                       dev_err(dev, "Failed to set parent clk: %d\n", ret);
+                       return ret;
+               }
+
+               /* Set clock to maximum clock limit */
+               ret = clk_set_rate(pwm->clk, pwm->soc->max_clk_limit);
+               if (ret < 0) {
+                       dev_err(dev, "Failed to set max clk rate: %d\n", ret);
+                       return ret;
+               }
+       }
+
        /* Get clock rate */
        pwm->src_rate = clk_get_rate(pwm->clk);
        pwm->parent_rate = clk_get_rate(clk_get_parent(pwm->clk));