1 // SPDX-License-Identifier: GPL-2.0 or MIT 2 /* Copyright 2018 Marty E. Plummer <hanetzer@startmail.com> */ 3 /* Copyright 2019 Linaro, Ltd, Rob Herring <robh@kernel.org> */ 4 /* Copyright 2023 Collabora ltd. */ 5 /* Copyright 2025 ARM Limited. All rights reserved. */ 6 7 #include <linux/clk.h> 8 #include <linux/mm.h> 9 #include <linux/platform_device.h> 10 #include <linux/pm_domain.h> 11 #include <linux/pm_runtime.h> 12 #include <linux/regulator/consumer.h> 13 #include <linux/reset.h> 14 15 #include <drm/drm_drv.h> 16 #include <drm/drm_managed.h> 17 #include <drm/drm_print.h> 18 19 #include "panthor_devfreq.h" 20 #include "panthor_device.h" 21 #include "panthor_fw.h" 22 #include "panthor_fw_regs.h" 23 #include "panthor_gem.h" 24 #include "panthor_gpu.h" 25 #include "panthor_hw.h" 26 #include "panthor_mmu.h" 27 #include "panthor_pwr.h" 28 #include "panthor_sched.h" 29 30 static int panthor_clk_init(struct panthor_device *ptdev) 31 { 32 ptdev->clks.core = devm_clk_get(ptdev->base.dev, NULL); 33 if (IS_ERR(ptdev->clks.core)) 34 return dev_err_probe(ptdev->base.dev, 35 PTR_ERR(ptdev->clks.core), 36 "get 'core' clock failed"); 37 38 ptdev->clks.stacks = devm_clk_get_optional(ptdev->base.dev, "stacks"); 39 if (IS_ERR(ptdev->clks.stacks)) 40 return dev_err_probe(ptdev->base.dev, 41 PTR_ERR(ptdev->clks.stacks), 42 "get 'stacks' clock failed"); 43 44 ptdev->clks.coregroup = devm_clk_get_optional(ptdev->base.dev, "coregroup"); 45 if (IS_ERR(ptdev->clks.coregroup)) 46 return dev_err_probe(ptdev->base.dev, 47 PTR_ERR(ptdev->clks.coregroup), 48 "get 'coregroup' clock failed"); 49 50 drm_info(&ptdev->base, "clock rate = %lu\n", clk_get_rate(ptdev->clks.core)); 51 return 0; 52 } 53 54 static int panthor_init_power(struct device *dev) 55 { 56 struct dev_pm_domain_list *pd_list = NULL; 57 58 if (dev->pm_domain) 59 return 0; 60 61 return devm_pm_domain_attach_list(dev, NULL, &pd_list); 62 } 63 64 void panthor_device_unplug(struct panthor_device *ptdev) 65 { 66 /* This function can be called from two different path: the reset work 67 * and the platform device remove callback. drm_dev_unplug() doesn't 68 * deal with concurrent callers, so we have to protect drm_dev_unplug() 69 * calls with our own lock, and bail out if the device is already 70 * unplugged. 71 */ 72 mutex_lock(&ptdev->unplug.lock); 73 if (drm_dev_is_unplugged(&ptdev->base)) { 74 /* Someone beat us, release the lock and wait for the unplug 75 * operation to be reported as done. 76 **/ 77 mutex_unlock(&ptdev->unplug.lock); 78 wait_for_completion(&ptdev->unplug.done); 79 return; 80 } 81 82 drm_WARN_ON(&ptdev->base, pm_runtime_get_sync(ptdev->base.dev) < 0); 83 84 /* Call drm_dev_unplug() so any access to HW blocks happening after 85 * that point get rejected. 86 */ 87 drm_dev_unplug(&ptdev->base); 88 89 /* We do the rest of the unplug with the unplug lock released, 90 * future callers will wait on ptdev->unplug.done anyway. 91 */ 92 mutex_unlock(&ptdev->unplug.lock); 93 94 /* Now, try to cleanly shutdown the GPU before the device resources 95 * get reclaimed. 96 */ 97 panthor_sched_unplug(ptdev); 98 panthor_fw_unplug(ptdev); 99 panthor_mmu_unplug(ptdev); 100 panthor_gem_shrinker_unplug(ptdev); 101 panthor_gpu_unplug(ptdev); 102 panthor_pwr_unplug(ptdev); 103 104 pm_runtime_dont_use_autosuspend(ptdev->base.dev); 105 pm_runtime_put_sync_suspend(ptdev->base.dev); 106 107 /* If PM is disabled, we need to call the suspend handler manually. */ 108 if (!IS_ENABLED(CONFIG_PM)) 109 panthor_device_suspend(ptdev->base.dev); 110 111 /* Report the unplug operation as done to unblock concurrent 112 * panthor_device_unplug() callers. 113 */ 114 complete_all(&ptdev->unplug.done); 115 } 116 117 static void panthor_device_reset_cleanup(struct drm_device *ddev, void *data) 118 { 119 struct panthor_device *ptdev = container_of(ddev, struct panthor_device, base); 120 121 disable_work_sync(&ptdev->reset.work); 122 destroy_workqueue(ptdev->reset.wq); 123 } 124 125 static void panthor_device_reset_work(struct work_struct *work) 126 { 127 struct panthor_device *ptdev = container_of(work, struct panthor_device, reset.work); 128 int ret = 0, cookie; 129 130 /* If the device is entering suspend, we don't reset. A slow reset will 131 * be forced at resume time instead. 132 */ 133 if (atomic_read(&ptdev->pm.state) != PANTHOR_DEVICE_PM_STATE_ACTIVE) 134 return; 135 136 if (!drm_dev_enter(&ptdev->base, &cookie)) 137 return; 138 139 panthor_sched_pre_reset(ptdev); 140 panthor_fw_pre_reset(ptdev, true); 141 panthor_mmu_pre_reset(ptdev); 142 panthor_hw_soft_reset(ptdev); 143 panthor_hw_l2_power_on(ptdev); 144 panthor_mmu_post_reset(ptdev); 145 ret = panthor_fw_post_reset(ptdev); 146 atomic_set(&ptdev->reset.pending, 0); 147 panthor_sched_post_reset(ptdev, ret != 0); 148 drm_dev_exit(cookie); 149 150 if (ret) { 151 panthor_device_unplug(ptdev); 152 drm_err(&ptdev->base, "Failed to boot MCU after reset, making device unusable."); 153 } 154 } 155 156 static bool panthor_device_is_initialized(struct panthor_device *ptdev) 157 { 158 return !!ptdev->scheduler; 159 } 160 161 static void panthor_device_free_page(struct drm_device *ddev, void *data) 162 { 163 __free_page(data); 164 } 165 166 int panthor_device_init(struct panthor_device *ptdev) 167 { 168 u32 *dummy_page_virt; 169 struct resource *res; 170 struct page *p; 171 int ret; 172 173 ptdev->soc_data = of_device_get_match_data(ptdev->base.dev); 174 175 init_completion(&ptdev->unplug.done); 176 ret = drmm_mutex_init(&ptdev->base, &ptdev->unplug.lock); 177 if (ret) 178 return ret; 179 180 ret = drmm_mutex_init(&ptdev->base, &ptdev->pm.mmio_lock); 181 if (ret) 182 return ret; 183 184 #ifdef CONFIG_DEBUG_FS 185 ret = drmm_mutex_init(&ptdev->base, &ptdev->gems.lock); 186 if (ret) 187 return ret; 188 189 INIT_LIST_HEAD(&ptdev->gems.node); 190 #endif 191 192 atomic_set(&ptdev->pm.state, PANTHOR_DEVICE_PM_STATE_SUSPENDED); 193 p = alloc_page(GFP_KERNEL | __GFP_ZERO); 194 if (!p) 195 return -ENOMEM; 196 197 ptdev->pm.dummy_latest_flush = p; 198 dummy_page_virt = page_address(p); 199 ret = drmm_add_action_or_reset(&ptdev->base, panthor_device_free_page, 200 ptdev->pm.dummy_latest_flush); 201 if (ret) 202 return ret; 203 204 /* 205 * Set the dummy page holding the latest flush to 1. This will cause the 206 * flush to avoided as we know it isn't necessary if the submission 207 * happens while the dummy page is mapped. Zero cannot be used because 208 * that means 'always flush'. 209 */ 210 *dummy_page_virt = 1; 211 212 INIT_WORK(&ptdev->reset.work, panthor_device_reset_work); 213 disable_work(&ptdev->reset.work); 214 ptdev->reset.wq = alloc_ordered_workqueue("panthor-reset-wq", 0); 215 if (!ptdev->reset.wq) 216 return -ENOMEM; 217 218 ret = drmm_add_action_or_reset(&ptdev->base, panthor_device_reset_cleanup, NULL); 219 if (ret) 220 return ret; 221 222 ret = panthor_clk_init(ptdev); 223 if (ret) 224 return ret; 225 226 ret = panthor_init_power(ptdev->base.dev); 227 if (ret < 0) { 228 drm_err(&ptdev->base, "init power domains failed, ret=%d", ret); 229 return ret; 230 } 231 232 ret = panthor_devfreq_init(ptdev); 233 if (ret) 234 return ret; 235 236 ptdev->iomem = devm_platform_get_and_ioremap_resource(to_platform_device(ptdev->base.dev), 237 0, &res); 238 if (IS_ERR(ptdev->iomem)) 239 return PTR_ERR(ptdev->iomem); 240 241 ptdev->phys_addr = res->start; 242 243 ret = devm_pm_runtime_enable(ptdev->base.dev); 244 if (ret) 245 return ret; 246 247 ret = pm_runtime_resume_and_get(ptdev->base.dev); 248 if (ret) 249 return ret; 250 251 /* If PM is disabled, we need to call panthor_device_resume() manually. */ 252 if (!IS_ENABLED(CONFIG_PM)) { 253 ret = panthor_device_resume(ptdev->base.dev); 254 if (ret) 255 return ret; 256 } 257 258 ret = panthor_hw_init(ptdev); 259 if (ret) 260 goto err_rpm_put; 261 262 ret = panthor_pwr_init(ptdev); 263 if (ret) 264 goto err_rpm_put; 265 266 ret = panthor_gpu_init(ptdev); 267 if (ret) 268 goto err_unplug_pwr; 269 270 ret = panthor_gpu_coherency_init(ptdev); 271 if (ret) 272 goto err_unplug_gpu; 273 274 ret = panthor_gem_shrinker_init(ptdev); 275 if (ret) 276 goto err_unplug_gpu; 277 278 ret = panthor_mmu_init(ptdev); 279 if (ret) 280 goto err_unplug_shrinker; 281 282 ret = panthor_fw_init(ptdev); 283 if (ret) 284 goto err_unplug_mmu; 285 286 ret = panthor_sched_init(ptdev); 287 if (ret) 288 goto err_unplug_fw; 289 290 panthor_gem_init(ptdev); 291 292 /* Now that everything is initialized, we can enable the reset work. */ 293 enable_work(&ptdev->reset.work); 294 295 /* ~3 frames */ 296 pm_runtime_set_autosuspend_delay(ptdev->base.dev, 50); 297 pm_runtime_use_autosuspend(ptdev->base.dev); 298 299 ret = drm_dev_register(&ptdev->base, 0); 300 if (ret) 301 goto err_disable_autosuspend; 302 303 pm_runtime_put_autosuspend(ptdev->base.dev); 304 return 0; 305 306 err_disable_autosuspend: 307 pm_runtime_dont_use_autosuspend(ptdev->base.dev); 308 panthor_sched_unplug(ptdev); 309 310 err_unplug_fw: 311 panthor_fw_unplug(ptdev); 312 313 err_unplug_mmu: 314 panthor_mmu_unplug(ptdev); 315 316 err_unplug_shrinker: 317 panthor_gem_shrinker_unplug(ptdev); 318 319 err_unplug_gpu: 320 panthor_gpu_unplug(ptdev); 321 322 err_unplug_pwr: 323 panthor_pwr_unplug(ptdev); 324 325 err_rpm_put: 326 pm_runtime_put_sync_suspend(ptdev->base.dev); 327 return ret; 328 } 329 330 #define PANTHOR_EXCEPTION(id) \ 331 [DRM_PANTHOR_EXCEPTION_ ## id] = { \ 332 .name = #id, \ 333 } 334 335 struct panthor_exception_info { 336 const char *name; 337 }; 338 339 static const struct panthor_exception_info panthor_exception_infos[] = { 340 PANTHOR_EXCEPTION(OK), 341 PANTHOR_EXCEPTION(TERMINATED), 342 PANTHOR_EXCEPTION(KABOOM), 343 PANTHOR_EXCEPTION(EUREKA), 344 PANTHOR_EXCEPTION(ACTIVE), 345 PANTHOR_EXCEPTION(CS_RES_TERM), 346 PANTHOR_EXCEPTION(CS_CONFIG_FAULT), 347 PANTHOR_EXCEPTION(CS_UNRECOVERABLE), 348 PANTHOR_EXCEPTION(CS_ENDPOINT_FAULT), 349 PANTHOR_EXCEPTION(CS_BUS_FAULT), 350 PANTHOR_EXCEPTION(CS_INSTR_INVALID), 351 PANTHOR_EXCEPTION(CS_CALL_STACK_OVERFLOW), 352 PANTHOR_EXCEPTION(CS_INHERIT_FAULT), 353 PANTHOR_EXCEPTION(INSTR_INVALID_PC), 354 PANTHOR_EXCEPTION(INSTR_INVALID_ENC), 355 PANTHOR_EXCEPTION(INSTR_BARRIER_FAULT), 356 PANTHOR_EXCEPTION(DATA_INVALID_FAULT), 357 PANTHOR_EXCEPTION(TILE_RANGE_FAULT), 358 PANTHOR_EXCEPTION(ADDR_RANGE_FAULT), 359 PANTHOR_EXCEPTION(IMPRECISE_FAULT), 360 PANTHOR_EXCEPTION(OOM), 361 PANTHOR_EXCEPTION(CSF_FW_INTERNAL_ERROR), 362 PANTHOR_EXCEPTION(CSF_RES_EVICTION_TIMEOUT), 363 PANTHOR_EXCEPTION(GPU_BUS_FAULT), 364 PANTHOR_EXCEPTION(GPU_SHAREABILITY_FAULT), 365 PANTHOR_EXCEPTION(SYS_SHAREABILITY_FAULT), 366 PANTHOR_EXCEPTION(GPU_CACHEABILITY_FAULT), 367 PANTHOR_EXCEPTION(TRANSLATION_FAULT_0), 368 PANTHOR_EXCEPTION(TRANSLATION_FAULT_1), 369 PANTHOR_EXCEPTION(TRANSLATION_FAULT_2), 370 PANTHOR_EXCEPTION(TRANSLATION_FAULT_3), 371 PANTHOR_EXCEPTION(TRANSLATION_FAULT_4), 372 PANTHOR_EXCEPTION(PERM_FAULT_0), 373 PANTHOR_EXCEPTION(PERM_FAULT_1), 374 PANTHOR_EXCEPTION(PERM_FAULT_2), 375 PANTHOR_EXCEPTION(PERM_FAULT_3), 376 PANTHOR_EXCEPTION(ACCESS_FLAG_1), 377 PANTHOR_EXCEPTION(ACCESS_FLAG_2), 378 PANTHOR_EXCEPTION(ACCESS_FLAG_3), 379 PANTHOR_EXCEPTION(ADDR_SIZE_FAULT_IN), 380 PANTHOR_EXCEPTION(ADDR_SIZE_FAULT_OUT0), 381 PANTHOR_EXCEPTION(ADDR_SIZE_FAULT_OUT1), 382 PANTHOR_EXCEPTION(ADDR_SIZE_FAULT_OUT2), 383 PANTHOR_EXCEPTION(ADDR_SIZE_FAULT_OUT3), 384 PANTHOR_EXCEPTION(MEM_ATTR_FAULT_0), 385 PANTHOR_EXCEPTION(MEM_ATTR_FAULT_1), 386 PANTHOR_EXCEPTION(MEM_ATTR_FAULT_2), 387 PANTHOR_EXCEPTION(MEM_ATTR_FAULT_3), 388 }; 389 390 const char *panthor_exception_name(struct panthor_device *ptdev, u32 exception_code) 391 { 392 if (exception_code >= ARRAY_SIZE(panthor_exception_infos) || 393 !panthor_exception_infos[exception_code].name) 394 return "Unknown exception type"; 395 396 return panthor_exception_infos[exception_code].name; 397 } 398 399 static vm_fault_t panthor_mmio_vm_fault(struct vm_fault *vmf) 400 { 401 struct vm_area_struct *vma = vmf->vma; 402 struct panthor_device *ptdev = vma->vm_private_data; 403 u64 offset = (u64)vma->vm_pgoff << PAGE_SHIFT; 404 unsigned long pfn; 405 pgprot_t pgprot; 406 vm_fault_t ret; 407 bool active; 408 int cookie; 409 410 if (!drm_dev_enter(&ptdev->base, &cookie)) 411 return VM_FAULT_SIGBUS; 412 413 mutex_lock(&ptdev->pm.mmio_lock); 414 active = atomic_read(&ptdev->pm.state) == PANTHOR_DEVICE_PM_STATE_ACTIVE; 415 416 switch (offset) { 417 case DRM_PANTHOR_USER_FLUSH_ID_MMIO_OFFSET: 418 if (active) 419 pfn = __phys_to_pfn(ptdev->phys_addr + CSF_GPU_LATEST_FLUSH_ID); 420 else 421 pfn = page_to_pfn(ptdev->pm.dummy_latest_flush); 422 break; 423 424 default: 425 ret = VM_FAULT_SIGBUS; 426 goto out_unlock; 427 } 428 429 pgprot = vma->vm_page_prot; 430 if (active) 431 pgprot = pgprot_noncached(pgprot); 432 433 ret = vmf_insert_pfn_prot(vma, vmf->address, pfn, pgprot); 434 435 out_unlock: 436 mutex_unlock(&ptdev->pm.mmio_lock); 437 drm_dev_exit(cookie); 438 return ret; 439 } 440 441 static const struct vm_operations_struct panthor_mmio_vm_ops = { 442 .fault = panthor_mmio_vm_fault, 443 }; 444 445 int panthor_device_mmap_io(struct panthor_device *ptdev, struct vm_area_struct *vma) 446 { 447 u64 offset = (u64)vma->vm_pgoff << PAGE_SHIFT; 448 449 if ((vma->vm_flags & VM_SHARED) == 0) 450 return -EINVAL; 451 452 switch (offset) { 453 case DRM_PANTHOR_USER_FLUSH_ID_MMIO_OFFSET: 454 if (vma->vm_end - vma->vm_start != PAGE_SIZE || 455 (vma->vm_flags & (VM_WRITE | VM_EXEC))) 456 return -EINVAL; 457 vm_flags_clear(vma, VM_MAYWRITE); 458 459 break; 460 461 default: 462 return -EINVAL; 463 } 464 465 /* Defer actual mapping to the fault handler. */ 466 vma->vm_private_data = ptdev; 467 vma->vm_ops = &panthor_mmio_vm_ops; 468 vm_flags_set(vma, 469 VM_IO | VM_DONTCOPY | VM_DONTEXPAND | 470 VM_NORESERVE | VM_DONTDUMP | VM_PFNMAP); 471 return 0; 472 } 473 474 static int panthor_device_resume_hw_components(struct panthor_device *ptdev) 475 { 476 int ret; 477 478 panthor_pwr_resume(ptdev); 479 panthor_gpu_resume(ptdev); 480 panthor_mmu_resume(ptdev); 481 482 ret = panthor_fw_resume(ptdev); 483 if (!ret) 484 return 0; 485 486 panthor_mmu_suspend(ptdev); 487 panthor_gpu_suspend(ptdev); 488 panthor_pwr_suspend(ptdev); 489 return ret; 490 } 491 492 int panthor_device_resume(struct device *dev) 493 { 494 struct panthor_device *ptdev = dev_get_drvdata(dev); 495 int ret, cookie; 496 497 if (atomic_read(&ptdev->pm.state) != PANTHOR_DEVICE_PM_STATE_SUSPENDED) 498 return -EINVAL; 499 500 atomic_set(&ptdev->pm.state, PANTHOR_DEVICE_PM_STATE_RESUMING); 501 502 ret = clk_prepare_enable(ptdev->clks.core); 503 if (ret) 504 goto err_set_suspended; 505 506 ret = clk_prepare_enable(ptdev->clks.stacks); 507 if (ret) 508 goto err_disable_core_clk; 509 510 ret = clk_prepare_enable(ptdev->clks.coregroup); 511 if (ret) 512 goto err_disable_stacks_clk; 513 514 panthor_devfreq_resume(ptdev); 515 516 if (panthor_device_is_initialized(ptdev) && 517 drm_dev_enter(&ptdev->base, &cookie)) { 518 /* If there was a reset pending at the time we suspended the 519 * device, we force a slow reset. 520 */ 521 if (atomic_read(&ptdev->reset.pending)) { 522 ptdev->reset.fast = false; 523 atomic_set(&ptdev->reset.pending, 0); 524 } 525 526 ret = panthor_device_resume_hw_components(ptdev); 527 if (ret && ptdev->reset.fast) { 528 drm_err(&ptdev->base, "Fast reset failed, trying a slow reset"); 529 ptdev->reset.fast = false; 530 ret = panthor_device_resume_hw_components(ptdev); 531 } 532 533 if (!ret) 534 panthor_sched_resume(ptdev); 535 536 drm_dev_exit(cookie); 537 538 if (ret) 539 goto err_suspend_devfreq; 540 } 541 542 /* Clear all IOMEM mappings pointing to this device after we've 543 * resumed. This way the fake mappings pointing to the dummy pages 544 * are removed and the real iomem mapping will be restored on next 545 * access. 546 */ 547 mutex_lock(&ptdev->pm.mmio_lock); 548 unmap_mapping_range(ptdev->base.anon_inode->i_mapping, 549 DRM_PANTHOR_USER_MMIO_OFFSET, 0, 1); 550 atomic_set(&ptdev->pm.state, PANTHOR_DEVICE_PM_STATE_ACTIVE); 551 mutex_unlock(&ptdev->pm.mmio_lock); 552 return 0; 553 554 err_suspend_devfreq: 555 panthor_devfreq_suspend(ptdev); 556 clk_disable_unprepare(ptdev->clks.coregroup); 557 558 err_disable_stacks_clk: 559 clk_disable_unprepare(ptdev->clks.stacks); 560 561 err_disable_core_clk: 562 clk_disable_unprepare(ptdev->clks.core); 563 564 err_set_suspended: 565 atomic_set(&ptdev->pm.state, PANTHOR_DEVICE_PM_STATE_SUSPENDED); 566 atomic_set(&ptdev->pm.recovery_needed, 1); 567 return ret; 568 } 569 570 int panthor_device_suspend(struct device *dev) 571 { 572 struct panthor_device *ptdev = dev_get_drvdata(dev); 573 int cookie; 574 575 if (atomic_read(&ptdev->pm.state) != PANTHOR_DEVICE_PM_STATE_ACTIVE) 576 return -EINVAL; 577 578 /* Clear all IOMEM mappings pointing to this device before we 579 * shutdown the power-domain and clocks. Failing to do that results 580 * in external aborts when the process accesses the iomem region. 581 * We change the state and call unmap_mapping_range() with the 582 * mmio_lock held to make sure the vm_fault handler won't set up 583 * invalid mappings. 584 */ 585 mutex_lock(&ptdev->pm.mmio_lock); 586 atomic_set(&ptdev->pm.state, PANTHOR_DEVICE_PM_STATE_SUSPENDING); 587 unmap_mapping_range(ptdev->base.anon_inode->i_mapping, 588 DRM_PANTHOR_USER_MMIO_OFFSET, 0, 1); 589 mutex_unlock(&ptdev->pm.mmio_lock); 590 591 if (panthor_device_is_initialized(ptdev) && 592 drm_dev_enter(&ptdev->base, &cookie)) { 593 cancel_work_sync(&ptdev->reset.work); 594 595 /* We prepare everything as if we were resetting the GPU. 596 * The end of the reset will happen in the resume path though. 597 */ 598 panthor_sched_suspend(ptdev); 599 panthor_fw_suspend(ptdev); 600 panthor_mmu_suspend(ptdev); 601 panthor_gpu_suspend(ptdev); 602 panthor_pwr_suspend(ptdev); 603 drm_dev_exit(cookie); 604 } 605 606 panthor_devfreq_suspend(ptdev); 607 608 clk_disable_unprepare(ptdev->clks.coregroup); 609 clk_disable_unprepare(ptdev->clks.stacks); 610 clk_disable_unprepare(ptdev->clks.core); 611 atomic_set(&ptdev->pm.state, PANTHOR_DEVICE_PM_STATE_SUSPENDED); 612 return 0; 613 } 614