1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. 4 */ 5 6 #define pr_fmt(fmt) "[drm-dp] %s: " fmt, __func__ 7 8 #include <linux/clk.h> 9 #include <linux/clk-provider.h> 10 #include <linux/regulator/consumer.h> 11 #include <linux/pm_opp.h> 12 #include "dp_power.h" 13 #include "msm_drv.h" 14 15 struct dp_power_private { 16 struct dp_parser *parser; 17 struct platform_device *pdev; 18 struct device *dev; 19 struct drm_device *drm_dev; 20 struct clk *link_clk_src; 21 struct clk *pixel_provider; 22 struct clk *link_provider; 23 struct regulator_bulk_data supplies[DP_DEV_REGULATOR_MAX]; 24 25 struct dp_power dp_power; 26 }; 27 28 static void dp_power_regulator_disable(struct dp_power_private *power) 29 { 30 struct regulator_bulk_data *s = power->supplies; 31 const struct dp_reg_entry *regs = power->parser->regulator_cfg->regs; 32 int num = power->parser->regulator_cfg->num; 33 int i; 34 35 DBG(""); 36 for (i = num - 1; i >= 0; i--) 37 if (regs[i].disable_load >= 0) 38 regulator_set_load(s[i].consumer, 39 regs[i].disable_load); 40 41 regulator_bulk_disable(num, s); 42 } 43 44 static int dp_power_regulator_enable(struct dp_power_private *power) 45 { 46 struct regulator_bulk_data *s = power->supplies; 47 const struct dp_reg_entry *regs = power->parser->regulator_cfg->regs; 48 int num = power->parser->regulator_cfg->num; 49 int ret, i; 50 51 DBG(""); 52 for (i = 0; i < num; i++) { 53 if (regs[i].enable_load >= 0) { 54 ret = regulator_set_load(s[i].consumer, 55 regs[i].enable_load); 56 if (ret < 0) { 57 pr_err("regulator %d set op mode failed, %d\n", 58 i, ret); 59 goto fail; 60 } 61 } 62 } 63 64 ret = regulator_bulk_enable(num, s); 65 if (ret < 0) { 66 pr_err("regulator enable failed, %d\n", ret); 67 goto fail; 68 } 69 70 return 0; 71 72 fail: 73 for (i--; i >= 0; i--) 74 regulator_set_load(s[i].consumer, regs[i].disable_load); 75 return ret; 76 } 77 78 static int dp_power_regulator_init(struct dp_power_private *power) 79 { 80 struct regulator_bulk_data *s = power->supplies; 81 const struct dp_reg_entry *regs = power->parser->regulator_cfg->regs; 82 struct platform_device *pdev = power->pdev; 83 int num = power->parser->regulator_cfg->num; 84 int i, ret; 85 86 for (i = 0; i < num; i++) 87 s[i].supply = regs[i].name; 88 89 ret = devm_regulator_bulk_get(&pdev->dev, num, s); 90 if (ret < 0) { 91 pr_err("%s: failed to init regulator, ret=%d\n", 92 __func__, ret); 93 return ret; 94 } 95 96 return 0; 97 } 98 99 static int dp_power_clk_init(struct dp_power_private *power) 100 { 101 int rc = 0; 102 struct dss_module_power *core, *ctrl, *stream; 103 struct device *dev = &power->pdev->dev; 104 105 core = &power->parser->mp[DP_CORE_PM]; 106 ctrl = &power->parser->mp[DP_CTRL_PM]; 107 stream = &power->parser->mp[DP_STREAM_PM]; 108 109 rc = devm_clk_bulk_get(dev, core->num_clk, core->clocks); 110 if (rc) { 111 DRM_ERROR("failed to get %s clk. err=%d\n", 112 dp_parser_pm_name(DP_CORE_PM), rc); 113 return rc; 114 } 115 116 rc = devm_clk_bulk_get(dev, ctrl->num_clk, ctrl->clocks); 117 if (rc) { 118 DRM_ERROR("failed to get %s clk. err=%d\n", 119 dp_parser_pm_name(DP_CTRL_PM), rc); 120 return -ENODEV; 121 } 122 123 rc = devm_clk_bulk_get(dev, stream->num_clk, stream->clocks); 124 if (rc) { 125 DRM_ERROR("failed to get %s clk. err=%d\n", 126 dp_parser_pm_name(DP_CTRL_PM), rc); 127 return -ENODEV; 128 } 129 130 return 0; 131 } 132 133 int dp_power_clk_status(struct dp_power *dp_power, enum dp_pm_type pm_type) 134 { 135 struct dp_power_private *power; 136 137 power = container_of(dp_power, struct dp_power_private, dp_power); 138 139 drm_dbg_dp(power->drm_dev, 140 "core_clk_on=%d link_clk_on=%d stream_clk_on=%d\n", 141 dp_power->core_clks_on, dp_power->link_clks_on, dp_power->stream_clks_on); 142 143 if (pm_type == DP_CORE_PM) 144 return dp_power->core_clks_on; 145 146 if (pm_type == DP_CTRL_PM) 147 return dp_power->link_clks_on; 148 149 if (pm_type == DP_STREAM_PM) 150 return dp_power->stream_clks_on; 151 152 return 0; 153 } 154 155 int dp_power_clk_enable(struct dp_power *dp_power, 156 enum dp_pm_type pm_type, bool enable) 157 { 158 int rc = 0; 159 struct dp_power_private *power; 160 struct dss_module_power *mp; 161 162 power = container_of(dp_power, struct dp_power_private, dp_power); 163 164 if (pm_type != DP_CORE_PM && pm_type != DP_CTRL_PM && 165 pm_type != DP_STREAM_PM) { 166 DRM_ERROR("unsupported power module: %s\n", 167 dp_parser_pm_name(pm_type)); 168 return -EINVAL; 169 } 170 171 if (enable) { 172 if (pm_type == DP_CORE_PM && dp_power->core_clks_on) { 173 drm_dbg_dp(power->drm_dev, 174 "core clks already enabled\n"); 175 return 0; 176 } 177 178 if (pm_type == DP_CTRL_PM && dp_power->link_clks_on) { 179 drm_dbg_dp(power->drm_dev, 180 "links clks already enabled\n"); 181 return 0; 182 } 183 184 if (pm_type == DP_STREAM_PM && dp_power->stream_clks_on) { 185 drm_dbg_dp(power->drm_dev, 186 "pixel clks already enabled\n"); 187 return 0; 188 } 189 190 if ((pm_type == DP_CTRL_PM) && (!dp_power->core_clks_on)) { 191 drm_dbg_dp(power->drm_dev, 192 "Enable core clks before link clks\n"); 193 mp = &power->parser->mp[DP_CORE_PM]; 194 195 rc = clk_bulk_prepare_enable(mp->num_clk, mp->clocks); 196 if (rc) { 197 DRM_ERROR("fail to enable clks: %s. err=%d\n", 198 dp_parser_pm_name(DP_CORE_PM), rc); 199 return rc; 200 } 201 dp_power->core_clks_on = true; 202 } 203 } 204 205 mp = &power->parser->mp[pm_type]; 206 if (enable) { 207 rc = clk_bulk_prepare_enable(mp->num_clk, mp->clocks); 208 if (rc) { 209 DRM_ERROR("failed to enable clks, err: %d\n", rc); 210 return rc; 211 } 212 } else { 213 clk_bulk_disable_unprepare(mp->num_clk, mp->clocks); 214 } 215 216 if (pm_type == DP_CORE_PM) 217 dp_power->core_clks_on = enable; 218 else if (pm_type == DP_STREAM_PM) 219 dp_power->stream_clks_on = enable; 220 else 221 dp_power->link_clks_on = enable; 222 223 drm_dbg_dp(power->drm_dev, "%s clocks for %s\n", 224 enable ? "enable" : "disable", 225 dp_parser_pm_name(pm_type)); 226 drm_dbg_dp(power->drm_dev, 227 "strem_clks:%s link_clks:%s core_clks:%s\n", 228 dp_power->stream_clks_on ? "on" : "off", 229 dp_power->link_clks_on ? "on" : "off", 230 dp_power->core_clks_on ? "on" : "off"); 231 232 return 0; 233 } 234 235 int dp_power_client_init(struct dp_power *dp_power) 236 { 237 int rc = 0; 238 struct dp_power_private *power; 239 240 if (!dp_power) { 241 DRM_ERROR("invalid power data\n"); 242 return -EINVAL; 243 } 244 245 power = container_of(dp_power, struct dp_power_private, dp_power); 246 247 pm_runtime_enable(&power->pdev->dev); 248 249 rc = dp_power_regulator_init(power); 250 if (rc) { 251 DRM_ERROR("failed to init regulators %d\n", rc); 252 goto error; 253 } 254 255 rc = dp_power_clk_init(power); 256 if (rc) { 257 DRM_ERROR("failed to init clocks %d\n", rc); 258 goto error; 259 } 260 return 0; 261 262 error: 263 pm_runtime_disable(&power->pdev->dev); 264 return rc; 265 } 266 267 void dp_power_client_deinit(struct dp_power *dp_power) 268 { 269 struct dp_power_private *power; 270 271 if (!dp_power) { 272 DRM_ERROR("invalid power data\n"); 273 return; 274 } 275 276 power = container_of(dp_power, struct dp_power_private, dp_power); 277 278 pm_runtime_disable(&power->pdev->dev); 279 } 280 281 int dp_power_init(struct dp_power *dp_power, bool flip) 282 { 283 int rc = 0; 284 struct dp_power_private *power = NULL; 285 286 if (!dp_power) { 287 DRM_ERROR("invalid power data\n"); 288 return -EINVAL; 289 } 290 291 power = container_of(dp_power, struct dp_power_private, dp_power); 292 293 pm_runtime_get_sync(&power->pdev->dev); 294 rc = dp_power_regulator_enable(power); 295 if (rc) { 296 DRM_ERROR("failed to enable regulators, %d\n", rc); 297 goto exit; 298 } 299 300 rc = dp_power_clk_enable(dp_power, DP_CORE_PM, true); 301 if (rc) { 302 DRM_ERROR("failed to enable DP core clocks, %d\n", rc); 303 goto err_clk; 304 } 305 306 return 0; 307 308 err_clk: 309 dp_power_regulator_disable(power); 310 exit: 311 pm_runtime_put_sync(&power->pdev->dev); 312 return rc; 313 } 314 315 int dp_power_deinit(struct dp_power *dp_power) 316 { 317 struct dp_power_private *power; 318 319 power = container_of(dp_power, struct dp_power_private, dp_power); 320 321 dp_power_clk_enable(dp_power, DP_CORE_PM, false); 322 dp_power_regulator_disable(power); 323 pm_runtime_put_sync(&power->pdev->dev); 324 return 0; 325 } 326 327 struct dp_power *dp_power_get(struct device *dev, struct dp_parser *parser) 328 { 329 struct dp_power_private *power; 330 struct dp_power *dp_power; 331 332 if (!parser) { 333 DRM_ERROR("invalid input\n"); 334 return ERR_PTR(-EINVAL); 335 } 336 337 power = devm_kzalloc(&parser->pdev->dev, sizeof(*power), GFP_KERNEL); 338 if (!power) 339 return ERR_PTR(-ENOMEM); 340 341 power->parser = parser; 342 power->pdev = parser->pdev; 343 power->dev = dev; 344 345 dp_power = &power->dp_power; 346 347 return dp_power; 348 } 349