clk: tegra: cclk: Handle thermal DIV2 CPU frequency throttling
authorDmitry Osipenko <digetx@gmail.com>
Sun, 16 May 2021 16:30:38 +0000 (19:30 +0300)
committerThierry Reding <treding@nvidia.com>
Mon, 31 May 2021 13:16:26 +0000 (15:16 +0200)
Check whether thermal DIV2 throttle is active in order to report
the CPU frequency properly. This very useful for userspace tools
like cpufreq-info which show actual frequency asserted from hardware.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
Signed-off-by: Thierry Reding <treding@nvidia.com>
drivers/clk/tegra/clk-tegra-super-cclk.c
drivers/clk/tegra/clk-tegra30.c

index a03119c..68d7bcd 100644 (file)
@@ -25,6 +25,8 @@
 
 #define SUPER_CDIV_ENB         BIT(31)
 
+#define TSENSOR_SLOWDOWN       BIT(23)
+
 static struct tegra_clk_super_mux *cclk_super;
 static bool cclk_on_pllx;
 
@@ -47,10 +49,20 @@ static int cclk_super_set_rate(struct clk_hw *hw, unsigned long rate,
 static unsigned long cclk_super_recalc_rate(struct clk_hw *hw,
                                            unsigned long parent_rate)
 {
+       struct tegra_clk_super_mux *super = to_clk_super_mux(hw);
+       u32 val = readl_relaxed(super->reg);
+       unsigned int div2;
+
+       /* check whether thermal throttling is active */
+       if (val & TSENSOR_SLOWDOWN)
+               div2 = 1;
+       else
+               div2 = 0;
+
        if (cclk_super_get_parent(hw) == PLLX_INDEX)
-               return parent_rate;
+               return parent_rate >> div2;
 
-       return tegra_clk_super_ops.recalc_rate(hw, parent_rate);
+       return tegra_clk_super_ops.recalc_rate(hw, parent_rate) >> div2;
 }
 
 static int cclk_super_determine_rate(struct clk_hw *hw,
index a33688b..5b6bd13 100644 (file)
@@ -930,7 +930,7 @@ static void __init tegra30_super_clk_init(void)
        /* CCLKG */
        clk = tegra_clk_register_super_cclk("cclk_g", cclk_g_parents,
                                  ARRAY_SIZE(cclk_g_parents),
-                                 CLK_SET_RATE_PARENT,
+                                 CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
                                  clk_base + CCLKG_BURST_POLICY,
                                  0, NULL);
        clks[TEGRA30_CLK_CCLK_G] = clk;