1 // SPDX-License-Identifier: GPL-2.0-only 2 3 #include <linux/clk.h> 4 #include <linux/clk-provider.h> 5 #include <linux/mutex.h> 6 #include <linux/platform_device.h> 7 #include <linux/pm_domain.h> 8 #include <linux/pm_opp.h> 9 #include <linux/pm_runtime.h> 10 #include <linux/slab.h> 11 12 #include <soc/tegra/common.h> 13 14 #include "clk.h" 15 16 /* 17 * This driver manages performance state of the core power domain for the 18 * independent PLLs and system clocks. We created a virtual clock device 19 * for such clocks, see tegra_clk_dev_register(). 20 */ 21 22 struct tegra_clk_device { 23 struct notifier_block clk_nb; 24 struct device *dev; 25 struct clk_hw *hw; 26 struct mutex lock; 27 }; 28 29 static int tegra_clock_set_pd_state(struct tegra_clk_device *clk_dev, 30 unsigned long rate) 31 { 32 struct device *dev = clk_dev->dev; 33 struct dev_pm_opp *opp; 34 unsigned int pstate; 35 36 opp = dev_pm_opp_find_freq_ceil(dev, &rate); 37 if (opp == ERR_PTR(-ERANGE)) { 38 /* 39 * Some clocks may be unused by a particular board and they 40 * may have uninitiated clock rate that is overly high. In 41 * this case clock is expected to be disabled, but still we 42 * need to set up performance state of the power domain and 43 * not error out clk initialization. A typical example is 44 * a PCIe clock on Android tablets. 45 */ 46 dev_dbg(dev, "failed to find ceil OPP for %luHz\n", rate); 47 opp = dev_pm_opp_find_freq_floor(dev, &rate); 48 } 49 50 if (IS_ERR(opp)) { 51 dev_err(dev, "failed to find OPP for %luHz: %pe\n", rate, opp); 52 return PTR_ERR(opp); 53 } 54 55 pstate = dev_pm_opp_get_required_pstate(opp, 0); 56 dev_pm_opp_put(opp); 57 58 return dev_pm_genpd_set_performance_state(dev, pstate); 59 } 60 61 static int tegra_clock_change_notify(struct notifier_block *nb, 62 unsigned long msg, void *data) 63 { 64 struct clk_notifier_data *cnd = data; 65 struct tegra_clk_device *clk_dev; 66 int err = 0; 67 68 clk_dev = container_of(nb, struct tegra_clk_device, clk_nb); 69 70 mutex_lock(&clk_dev->lock); 71 switch (msg) { 72 case PRE_RATE_CHANGE: 73 if (cnd->new_rate > cnd->old_rate) 74 err = tegra_clock_set_pd_state(clk_dev, cnd->new_rate); 75 break; 76 77 case ABORT_RATE_CHANGE: 78 err = tegra_clock_set_pd_state(clk_dev, cnd->old_rate); 79 break; 80 81 case POST_RATE_CHANGE: 82 if (cnd->new_rate < cnd->old_rate) 83 err = tegra_clock_set_pd_state(clk_dev, cnd->new_rate); 84 break; 85 86 default: 87 break; 88 } 89 mutex_unlock(&clk_dev->lock); 90 91 return notifier_from_errno(err); 92 } 93 94 static int tegra_clock_sync_pd_state(struct tegra_clk_device *clk_dev) 95 { 96 unsigned long rate; 97 int ret; 98 99 mutex_lock(&clk_dev->lock); 100 101 rate = clk_hw_get_rate(clk_dev->hw); 102 ret = tegra_clock_set_pd_state(clk_dev, rate); 103 104 mutex_unlock(&clk_dev->lock); 105 106 return ret; 107 } 108 109 static int tegra_clock_probe(struct platform_device *pdev) 110 { 111 struct tegra_core_opp_params opp_params = {}; 112 struct tegra_clk_device *clk_dev; 113 struct device *dev = &pdev->dev; 114 struct clk *clk; 115 int err; 116 117 if (!dev->pm_domain) 118 return -EINVAL; 119 120 clk_dev = devm_kzalloc(dev, sizeof(*clk_dev), GFP_KERNEL); 121 if (!clk_dev) 122 return -ENOMEM; 123 124 clk = devm_clk_get(dev, NULL); 125 if (IS_ERR(clk)) 126 return PTR_ERR(clk); 127 128 clk_dev->dev = dev; 129 clk_dev->hw = __clk_get_hw(clk); 130 clk_dev->clk_nb.notifier_call = tegra_clock_change_notify; 131 mutex_init(&clk_dev->lock); 132 133 platform_set_drvdata(pdev, clk_dev); 134 135 /* 136 * Runtime PM was already enabled for this device by the parent clk 137 * driver and power domain state should be synced under clk_dev lock, 138 * hence we don't use the common OPP helper that initializes OPP 139 * state. For some clocks common OPP helper may fail to find ceil 140 * rate, it's handled by this driver. 141 */ 142 err = devm_tegra_core_dev_init_opp_table(dev, &opp_params); 143 if (err) 144 return err; 145 146 err = clk_notifier_register(clk, &clk_dev->clk_nb); 147 if (err) { 148 dev_err(dev, "failed to register clk notifier: %d\n", err); 149 return err; 150 } 151 152 /* 153 * The driver is attaching to a potentially active/resumed clock, hence 154 * we need to sync the power domain performance state in a accordance to 155 * the clock rate if clock is resumed. 156 */ 157 err = tegra_clock_sync_pd_state(clk_dev); 158 if (err) 159 goto unreg_clk; 160 161 return 0; 162 163 unreg_clk: 164 clk_notifier_unregister(clk, &clk_dev->clk_nb); 165 166 return err; 167 } 168 169 /* 170 * Tegra GENPD driver enables clocks during NOIRQ phase. It can't be done 171 * for clocks served by this driver because runtime PM is unavailable in 172 * NOIRQ phase. We will keep clocks resumed during suspend to mitigate this 173 * problem. In practice this makes no difference from a power management 174 * perspective since voltage is kept at a nominal level during suspend anyways. 175 */ 176 static inline int tegra_clock_suspend(struct device *dev) 177 { 178 int ret; 179 180 ret = pm_runtime_resume(dev); 181 if (ret < 0) 182 return ret; 183 184 return 0; 185 } 186 187 static const struct dev_pm_ops tegra_clock_pm = { 188 SET_SYSTEM_SLEEP_PM_OPS(tegra_clock_suspend, NULL) 189 }; 190 191 static const struct of_device_id tegra_clock_match[] = { 192 { .compatible = "nvidia,tegra20-sclk" }, 193 { .compatible = "nvidia,tegra30-sclk" }, 194 { .compatible = "nvidia,tegra30-pllc" }, 195 { .compatible = "nvidia,tegra30-plle" }, 196 { .compatible = "nvidia,tegra30-pllm" }, 197 { } 198 }; 199 200 static struct platform_driver tegra_clock_driver = { 201 .driver = { 202 .name = "tegra-clock", 203 .of_match_table = tegra_clock_match, 204 .pm = &tegra_clock_pm, 205 .suppress_bind_attrs = true, 206 }, 207 .probe = tegra_clock_probe, 208 }; 209 builtin_platform_driver(tegra_clock_driver); 210