1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright 2018 Marty E. Plummer <hanetzer@startmail.com> */ 3 /* Copyright 2019 Linaro, Ltd, Rob Herring <robh@kernel.org> */ 4 5 #include <linux/clk.h> 6 #include <linux/reset.h> 7 #include <linux/platform_device.h> 8 #include <linux/pm_domain.h> 9 #include <linux/regulator/consumer.h> 10 11 #include "panfrost_device.h" 12 #include "panfrost_devfreq.h" 13 #include "panfrost_features.h" 14 #include "panfrost_issues.h" 15 #include "panfrost_gpu.h" 16 #include "panfrost_job.h" 17 #include "panfrost_mmu.h" 18 #include "panfrost_perfcnt.h" 19 20 static int panfrost_reset_init(struct panfrost_device *pfdev) 21 { 22 pfdev->rstc = devm_reset_control_array_get_optional_exclusive(pfdev->dev); 23 if (IS_ERR(pfdev->rstc)) { 24 dev_err(pfdev->dev, "get reset failed %ld\n", PTR_ERR(pfdev->rstc)); 25 return PTR_ERR(pfdev->rstc); 26 } 27 28 return reset_control_deassert(pfdev->rstc); 29 } 30 31 static void panfrost_reset_fini(struct panfrost_device *pfdev) 32 { 33 reset_control_assert(pfdev->rstc); 34 } 35 36 static int panfrost_clk_init(struct panfrost_device *pfdev) 37 { 38 int err; 39 unsigned long rate; 40 41 pfdev->clock = devm_clk_get(pfdev->dev, NULL); 42 if (IS_ERR(pfdev->clock)) { 43 dev_err(pfdev->dev, "get clock failed %ld\n", PTR_ERR(pfdev->clock)); 44 return PTR_ERR(pfdev->clock); 45 } 46 47 rate = clk_get_rate(pfdev->clock); 48 dev_info(pfdev->dev, "clock rate = %lu\n", rate); 49 50 err = clk_prepare_enable(pfdev->clock); 51 if (err) 52 return err; 53 54 pfdev->bus_clock = devm_clk_get_optional(pfdev->dev, "bus"); 55 if (IS_ERR(pfdev->bus_clock)) { 56 dev_err(pfdev->dev, "get bus_clock failed %ld\n", 57 PTR_ERR(pfdev->bus_clock)); 58 err = PTR_ERR(pfdev->bus_clock); 59 goto disable_clock; 60 } 61 62 if (pfdev->bus_clock) { 63 rate = clk_get_rate(pfdev->bus_clock); 64 dev_info(pfdev->dev, "bus_clock rate = %lu\n", rate); 65 66 err = clk_prepare_enable(pfdev->bus_clock); 67 if (err) 68 goto disable_clock; 69 } 70 71 return 0; 72 73 disable_clock: 74 clk_disable_unprepare(pfdev->clock); 75 76 return err; 77 } 78 79 static void panfrost_clk_fini(struct panfrost_device *pfdev) 80 { 81 clk_disable_unprepare(pfdev->bus_clock); 82 clk_disable_unprepare(pfdev->clock); 83 } 84 85 static int panfrost_regulator_init(struct panfrost_device *pfdev) 86 { 87 int ret, i; 88 89 pfdev->regulators = devm_kcalloc(pfdev->dev, pfdev->comp->num_supplies, 90 sizeof(*pfdev->regulators), 91 GFP_KERNEL); 92 if (!pfdev->regulators) 93 return -ENOMEM; 94 95 for (i = 0; i < pfdev->comp->num_supplies; i++) 96 pfdev->regulators[i].supply = pfdev->comp->supply_names[i]; 97 98 ret = devm_regulator_bulk_get(pfdev->dev, 99 pfdev->comp->num_supplies, 100 pfdev->regulators); 101 if (ret < 0) { 102 if (ret != -EPROBE_DEFER) 103 dev_err(pfdev->dev, "failed to get regulators: %d\n", 104 ret); 105 return ret; 106 } 107 108 ret = regulator_bulk_enable(pfdev->comp->num_supplies, 109 pfdev->regulators); 110 if (ret < 0) { 111 dev_err(pfdev->dev, "failed to enable regulators: %d\n", ret); 112 return ret; 113 } 114 115 return 0; 116 } 117 118 static void panfrost_regulator_fini(struct panfrost_device *pfdev) 119 { 120 if (!pfdev->regulators) 121 return; 122 123 regulator_bulk_disable(pfdev->comp->num_supplies, pfdev->regulators); 124 } 125 126 static void panfrost_pm_domain_fini(struct panfrost_device *pfdev) 127 { 128 int i; 129 130 for (i = 0; i < ARRAY_SIZE(pfdev->pm_domain_devs); i++) { 131 if (!pfdev->pm_domain_devs[i]) 132 break; 133 134 if (pfdev->pm_domain_links[i]) 135 device_link_del(pfdev->pm_domain_links[i]); 136 137 dev_pm_domain_detach(pfdev->pm_domain_devs[i], true); 138 } 139 } 140 141 static int panfrost_pm_domain_init(struct panfrost_device *pfdev) 142 { 143 int err; 144 int i, num_domains; 145 146 num_domains = of_count_phandle_with_args(pfdev->dev->of_node, 147 "power-domains", 148 "#power-domain-cells"); 149 150 /* 151 * Single domain is handled by the core, and, if only a single power 152 * the power domain is requested, the property is optional. 153 */ 154 if (num_domains < 2 && pfdev->comp->num_pm_domains < 2) 155 return 0; 156 157 if (num_domains != pfdev->comp->num_pm_domains) { 158 dev_err(pfdev->dev, 159 "Incorrect number of power domains: %d provided, %d needed\n", 160 num_domains, pfdev->comp->num_pm_domains); 161 return -EINVAL; 162 } 163 164 if (WARN(num_domains > ARRAY_SIZE(pfdev->pm_domain_devs), 165 "Too many supplies in compatible structure.\n")) 166 return -EINVAL; 167 168 for (i = 0; i < num_domains; i++) { 169 pfdev->pm_domain_devs[i] = 170 dev_pm_domain_attach_by_name(pfdev->dev, 171 pfdev->comp->pm_domain_names[i]); 172 if (IS_ERR_OR_NULL(pfdev->pm_domain_devs[i])) { 173 err = PTR_ERR(pfdev->pm_domain_devs[i]) ? : -ENODATA; 174 pfdev->pm_domain_devs[i] = NULL; 175 dev_err(pfdev->dev, 176 "failed to get pm-domain %s(%d): %d\n", 177 pfdev->comp->pm_domain_names[i], i, err); 178 goto err; 179 } 180 181 pfdev->pm_domain_links[i] = device_link_add(pfdev->dev, 182 pfdev->pm_domain_devs[i], DL_FLAG_PM_RUNTIME | 183 DL_FLAG_STATELESS | DL_FLAG_RPM_ACTIVE); 184 if (!pfdev->pm_domain_links[i]) { 185 dev_err(pfdev->pm_domain_devs[i], 186 "adding device link failed!\n"); 187 err = -ENODEV; 188 goto err; 189 } 190 } 191 192 return 0; 193 194 err: 195 panfrost_pm_domain_fini(pfdev); 196 return err; 197 } 198 199 int panfrost_device_init(struct panfrost_device *pfdev) 200 { 201 int err; 202 203 mutex_init(&pfdev->sched_lock); 204 INIT_LIST_HEAD(&pfdev->scheduled_jobs); 205 INIT_LIST_HEAD(&pfdev->as_lru_list); 206 207 spin_lock_init(&pfdev->as_lock); 208 209 err = panfrost_clk_init(pfdev); 210 if (err) { 211 dev_err(pfdev->dev, "clk init failed %d\n", err); 212 return err; 213 } 214 215 err = panfrost_devfreq_init(pfdev); 216 if (err) { 217 if (err != -EPROBE_DEFER) 218 dev_err(pfdev->dev, "devfreq init failed %d\n", err); 219 goto out_clk; 220 } 221 222 /* OPP will handle regulators */ 223 if (!pfdev->pfdevfreq.opp_of_table_added) { 224 err = panfrost_regulator_init(pfdev); 225 if (err) 226 goto out_devfreq; 227 } 228 229 err = panfrost_reset_init(pfdev); 230 if (err) { 231 dev_err(pfdev->dev, "reset init failed %d\n", err); 232 goto out_regulator; 233 } 234 235 err = panfrost_pm_domain_init(pfdev); 236 if (err) 237 goto out_reset; 238 239 pfdev->iomem = devm_platform_ioremap_resource(pfdev->pdev, 0); 240 if (IS_ERR(pfdev->iomem)) { 241 err = PTR_ERR(pfdev->iomem); 242 goto out_pm_domain; 243 } 244 245 err = panfrost_gpu_init(pfdev); 246 if (err) 247 goto out_pm_domain; 248 249 err = panfrost_mmu_init(pfdev); 250 if (err) 251 goto out_gpu; 252 253 err = panfrost_job_init(pfdev); 254 if (err) 255 goto out_mmu; 256 257 err = panfrost_perfcnt_init(pfdev); 258 if (err) 259 goto out_job; 260 261 return 0; 262 out_job: 263 panfrost_job_fini(pfdev); 264 out_mmu: 265 panfrost_mmu_fini(pfdev); 266 out_gpu: 267 panfrost_gpu_fini(pfdev); 268 out_pm_domain: 269 panfrost_pm_domain_fini(pfdev); 270 out_reset: 271 panfrost_reset_fini(pfdev); 272 out_regulator: 273 panfrost_regulator_fini(pfdev); 274 out_devfreq: 275 panfrost_devfreq_fini(pfdev); 276 out_clk: 277 panfrost_clk_fini(pfdev); 278 return err; 279 } 280 281 void panfrost_device_fini(struct panfrost_device *pfdev) 282 { 283 panfrost_perfcnt_fini(pfdev); 284 panfrost_job_fini(pfdev); 285 panfrost_mmu_fini(pfdev); 286 panfrost_gpu_fini(pfdev); 287 panfrost_pm_domain_fini(pfdev); 288 panfrost_reset_fini(pfdev); 289 panfrost_devfreq_fini(pfdev); 290 panfrost_regulator_fini(pfdev); 291 panfrost_clk_fini(pfdev); 292 } 293 294 #define PANFROST_EXCEPTION(id) \ 295 [DRM_PANFROST_EXCEPTION_ ## id] = { \ 296 .name = #id, \ 297 } 298 299 struct panfrost_exception_info { 300 const char *name; 301 }; 302 303 static const struct panfrost_exception_info panfrost_exception_infos[] = { 304 PANFROST_EXCEPTION(OK), 305 PANFROST_EXCEPTION(DONE), 306 PANFROST_EXCEPTION(INTERRUPTED), 307 PANFROST_EXCEPTION(STOPPED), 308 PANFROST_EXCEPTION(TERMINATED), 309 PANFROST_EXCEPTION(KABOOM), 310 PANFROST_EXCEPTION(EUREKA), 311 PANFROST_EXCEPTION(ACTIVE), 312 PANFROST_EXCEPTION(JOB_CONFIG_FAULT), 313 PANFROST_EXCEPTION(JOB_POWER_FAULT), 314 PANFROST_EXCEPTION(JOB_READ_FAULT), 315 PANFROST_EXCEPTION(JOB_WRITE_FAULT), 316 PANFROST_EXCEPTION(JOB_AFFINITY_FAULT), 317 PANFROST_EXCEPTION(JOB_BUS_FAULT), 318 PANFROST_EXCEPTION(INSTR_INVALID_PC), 319 PANFROST_EXCEPTION(INSTR_INVALID_ENC), 320 PANFROST_EXCEPTION(INSTR_TYPE_MISMATCH), 321 PANFROST_EXCEPTION(INSTR_OPERAND_FAULT), 322 PANFROST_EXCEPTION(INSTR_TLS_FAULT), 323 PANFROST_EXCEPTION(INSTR_BARRIER_FAULT), 324 PANFROST_EXCEPTION(INSTR_ALIGN_FAULT), 325 PANFROST_EXCEPTION(DATA_INVALID_FAULT), 326 PANFROST_EXCEPTION(TILE_RANGE_FAULT), 327 PANFROST_EXCEPTION(ADDR_RANGE_FAULT), 328 PANFROST_EXCEPTION(IMPRECISE_FAULT), 329 PANFROST_EXCEPTION(OOM), 330 PANFROST_EXCEPTION(OOM_AFBC), 331 PANFROST_EXCEPTION(UNKNOWN), 332 PANFROST_EXCEPTION(DELAYED_BUS_FAULT), 333 PANFROST_EXCEPTION(GPU_SHAREABILITY_FAULT), 334 PANFROST_EXCEPTION(SYS_SHAREABILITY_FAULT), 335 PANFROST_EXCEPTION(GPU_CACHEABILITY_FAULT), 336 PANFROST_EXCEPTION(TRANSLATION_FAULT_0), 337 PANFROST_EXCEPTION(TRANSLATION_FAULT_1), 338 PANFROST_EXCEPTION(TRANSLATION_FAULT_2), 339 PANFROST_EXCEPTION(TRANSLATION_FAULT_3), 340 PANFROST_EXCEPTION(TRANSLATION_FAULT_4), 341 PANFROST_EXCEPTION(TRANSLATION_FAULT_IDENTITY), 342 PANFROST_EXCEPTION(PERM_FAULT_0), 343 PANFROST_EXCEPTION(PERM_FAULT_1), 344 PANFROST_EXCEPTION(PERM_FAULT_2), 345 PANFROST_EXCEPTION(PERM_FAULT_3), 346 PANFROST_EXCEPTION(TRANSTAB_BUS_FAULT_0), 347 PANFROST_EXCEPTION(TRANSTAB_BUS_FAULT_1), 348 PANFROST_EXCEPTION(TRANSTAB_BUS_FAULT_2), 349 PANFROST_EXCEPTION(TRANSTAB_BUS_FAULT_3), 350 PANFROST_EXCEPTION(ACCESS_FLAG_0), 351 PANFROST_EXCEPTION(ACCESS_FLAG_1), 352 PANFROST_EXCEPTION(ACCESS_FLAG_2), 353 PANFROST_EXCEPTION(ACCESS_FLAG_3), 354 PANFROST_EXCEPTION(ADDR_SIZE_FAULT_IN0), 355 PANFROST_EXCEPTION(ADDR_SIZE_FAULT_IN1), 356 PANFROST_EXCEPTION(ADDR_SIZE_FAULT_IN2), 357 PANFROST_EXCEPTION(ADDR_SIZE_FAULT_IN3), 358 PANFROST_EXCEPTION(ADDR_SIZE_FAULT_OUT0), 359 PANFROST_EXCEPTION(ADDR_SIZE_FAULT_OUT1), 360 PANFROST_EXCEPTION(ADDR_SIZE_FAULT_OUT2), 361 PANFROST_EXCEPTION(ADDR_SIZE_FAULT_OUT3), 362 PANFROST_EXCEPTION(MEM_ATTR_FAULT_0), 363 PANFROST_EXCEPTION(MEM_ATTR_FAULT_1), 364 PANFROST_EXCEPTION(MEM_ATTR_FAULT_2), 365 PANFROST_EXCEPTION(MEM_ATTR_FAULT_3), 366 PANFROST_EXCEPTION(MEM_ATTR_NONCACHE_0), 367 PANFROST_EXCEPTION(MEM_ATTR_NONCACHE_1), 368 PANFROST_EXCEPTION(MEM_ATTR_NONCACHE_2), 369 PANFROST_EXCEPTION(MEM_ATTR_NONCACHE_3), 370 }; 371 372 const char *panfrost_exception_name(u32 exception_code) 373 { 374 if (WARN_ON(exception_code >= ARRAY_SIZE(panfrost_exception_infos) || 375 !panfrost_exception_infos[exception_code].name)) 376 return "Unknown exception type"; 377 378 return panfrost_exception_infos[exception_code].name; 379 } 380 381 bool panfrost_exception_needs_reset(const struct panfrost_device *pfdev, 382 u32 exception_code) 383 { 384 /* If an occlusion query write causes a bus fault on affected GPUs, 385 * future fragment jobs may hang. Reset to workaround. 386 */ 387 if (exception_code == DRM_PANFROST_EXCEPTION_JOB_BUS_FAULT) 388 return panfrost_has_hw_issue(pfdev, HW_ISSUE_TTRX_3076); 389 390 /* No other GPUs we support need a reset */ 391 return false; 392 } 393 394 void panfrost_device_reset(struct panfrost_device *pfdev) 395 { 396 panfrost_gpu_soft_reset(pfdev); 397 398 panfrost_gpu_power_on(pfdev); 399 panfrost_mmu_reset(pfdev); 400 panfrost_job_enable_interrupts(pfdev); 401 } 402 403 #ifdef CONFIG_PM 404 int panfrost_device_resume(struct device *dev) 405 { 406 struct panfrost_device *pfdev = dev_get_drvdata(dev); 407 408 panfrost_device_reset(pfdev); 409 panfrost_devfreq_resume(pfdev); 410 411 return 0; 412 } 413 414 int panfrost_device_suspend(struct device *dev) 415 { 416 struct panfrost_device *pfdev = dev_get_drvdata(dev); 417 418 if (!panfrost_job_is_idle(pfdev)) 419 return -EBUSY; 420 421 panfrost_devfreq_suspend(pfdev); 422 panfrost_gpu_power_off(pfdev); 423 424 return 0; 425 } 426 #endif 427