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 2019 Collabora ltd. */ 5 6 #include <linux/bitfield.h> 7 #include <linux/bitmap.h> 8 #include <linux/delay.h> 9 #include <linux/dma-mapping.h> 10 #include <linux/interrupt.h> 11 #include <linux/io.h> 12 #include <linux/iopoll.h> 13 #include <linux/platform_device.h> 14 #include <linux/pm_runtime.h> 15 16 #include <drm/drm_drv.h> 17 #include <drm/drm_managed.h> 18 #include <drm/drm_print.h> 19 20 #include "panthor_device.h" 21 #include "panthor_gpu.h" 22 #include "panthor_gpu_regs.h" 23 #include "panthor_hw.h" 24 25 #define CREATE_TRACE_POINTS 26 #include "panthor_trace.h" 27 28 /** 29 * struct panthor_gpu - GPU block management data. 30 */ 31 struct panthor_gpu { 32 /** @iomem: CPU mapping of GPU_CONTROL iomem region */ 33 void __iomem *iomem; 34 35 /** @irq: GPU irq. */ 36 struct panthor_irq irq; 37 38 /** @reqs_lock: Lock protecting access to pending_reqs. */ 39 spinlock_t reqs_lock; 40 41 /** @pending_reqs: Pending GPU requests. */ 42 u32 pending_reqs; 43 44 /** @reqs_acked: GPU request wait queue. */ 45 wait_queue_head_t reqs_acked; 46 47 /** @cache_flush_lock: Lock to serialize cache flushes */ 48 struct mutex cache_flush_lock; 49 }; 50 51 #define GPU_INTERRUPTS_MASK \ 52 (GPU_IRQ_FAULT | \ 53 GPU_IRQ_PROTM_FAULT | \ 54 GPU_IRQ_RESET_COMPLETED | \ 55 GPU_IRQ_CLEAN_CACHES_COMPLETED) 56 57 #define GPU_POWER_INTERRUPTS_MASK \ 58 (GPU_IRQ_POWER_CHANGED | GPU_IRQ_POWER_CHANGED_ALL) 59 60 static void panthor_gpu_coherency_set(struct panthor_device *ptdev) 61 { 62 gpu_write(ptdev->gpu->iomem, GPU_COHERENCY_PROTOCOL, 63 ptdev->gpu_info.selected_coherency); 64 } 65 66 static void panthor_gpu_l2_config_set(struct panthor_device *ptdev) 67 { 68 struct panthor_gpu *gpu = ptdev->gpu; 69 const struct panthor_soc_data *data = ptdev->soc_data; 70 u32 l2_config; 71 u32 i; 72 73 if (!data || !data->asn_hash_enable) 74 return; 75 76 if (GPU_ARCH_MAJOR(ptdev->gpu_info.gpu_id) < 11) { 77 drm_err(&ptdev->base, "Custom ASN hash not supported by the device"); 78 return; 79 } 80 81 for (i = 0; i < ARRAY_SIZE(data->asn_hash); i++) 82 gpu_write(gpu->iomem, GPU_ASN_HASH(i), data->asn_hash[i]); 83 84 l2_config = gpu_read(gpu->iomem, GPU_L2_CONFIG); 85 l2_config |= GPU_L2_CONFIG_ASN_HASH_ENABLE; 86 gpu_write(gpu->iomem, GPU_L2_CONFIG, l2_config); 87 } 88 89 static void panthor_gpu_irq_handler(struct panthor_device *ptdev, u32 status) 90 { 91 struct panthor_gpu *gpu = ptdev->gpu; 92 93 gpu_write(gpu->irq.iomem, INT_CLEAR, status); 94 95 if (tracepoint_enabled(gpu_power_status) && (status & GPU_POWER_INTERRUPTS_MASK)) 96 trace_gpu_power_status(ptdev->base.dev, 97 gpu_read64(gpu->iomem, SHADER_READY), 98 gpu_read64(gpu->iomem, TILER_READY), 99 gpu_read64(gpu->iomem, L2_READY)); 100 101 if (status & GPU_IRQ_FAULT) { 102 u32 fault_status = gpu_read(gpu->iomem, GPU_FAULT_STATUS); 103 u64 address = gpu_read64(gpu->iomem, GPU_FAULT_ADDR); 104 105 drm_warn(&ptdev->base, "GPU Fault 0x%08x (%s) at 0x%016llx\n", 106 fault_status, panthor_exception_name(ptdev, fault_status & 0xFF), 107 address); 108 } 109 if (status & GPU_IRQ_PROTM_FAULT) 110 drm_warn(&ptdev->base, "GPU Fault in protected mode\n"); 111 112 spin_lock(&ptdev->gpu->reqs_lock); 113 if (status & ptdev->gpu->pending_reqs) { 114 ptdev->gpu->pending_reqs &= ~status; 115 wake_up_all(&ptdev->gpu->reqs_acked); 116 } 117 spin_unlock(&ptdev->gpu->reqs_lock); 118 } 119 PANTHOR_IRQ_HANDLER(gpu, panthor_gpu_irq_handler); 120 121 /** 122 * panthor_gpu_unplug() - Called when the GPU is unplugged. 123 * @ptdev: Device to unplug. 124 */ 125 void panthor_gpu_unplug(struct panthor_device *ptdev) 126 { 127 unsigned long flags; 128 129 /* Make sure the IRQ handler is not running after that point. */ 130 if (!IS_ENABLED(CONFIG_PM) || pm_runtime_active(ptdev->base.dev)) 131 panthor_gpu_irq_suspend(&ptdev->gpu->irq); 132 133 /* Wake-up all waiters. */ 134 spin_lock_irqsave(&ptdev->gpu->reqs_lock, flags); 135 ptdev->gpu->pending_reqs = 0; 136 wake_up_all(&ptdev->gpu->reqs_acked); 137 spin_unlock_irqrestore(&ptdev->gpu->reqs_lock, flags); 138 } 139 140 /** 141 * panthor_gpu_init() - Initialize the GPU block 142 * @ptdev: Device. 143 * 144 * Return: 0 on success, a negative error code otherwise. 145 */ 146 int panthor_gpu_init(struct panthor_device *ptdev) 147 { 148 struct panthor_gpu *gpu; 149 u32 pa_bits; 150 int ret, irq; 151 152 gpu = drmm_kzalloc(&ptdev->base, sizeof(*gpu), GFP_KERNEL); 153 if (!gpu) 154 return -ENOMEM; 155 156 gpu->iomem = ptdev->iomem + GPU_CONTROL_BASE; 157 spin_lock_init(&gpu->reqs_lock); 158 init_waitqueue_head(&gpu->reqs_acked); 159 mutex_init(&gpu->cache_flush_lock); 160 ptdev->gpu = gpu; 161 162 dma_set_max_seg_size(ptdev->base.dev, UINT_MAX); 163 pa_bits = GPU_MMU_FEATURES_PA_BITS(ptdev->gpu_info.mmu_features); 164 ret = dma_set_mask_and_coherent(ptdev->base.dev, DMA_BIT_MASK(pa_bits)); 165 if (ret) 166 return ret; 167 168 irq = platform_get_irq_byname(to_platform_device(ptdev->base.dev), "gpu"); 169 if (irq < 0) 170 return irq; 171 172 ret = panthor_request_gpu_irq(ptdev, &ptdev->gpu->irq, irq, 173 GPU_INTERRUPTS_MASK, 174 ptdev->iomem + GPU_INT_BASE); 175 if (ret) 176 return ret; 177 178 return 0; 179 } 180 181 int panthor_gpu_power_changed_on(struct panthor_device *ptdev) 182 { 183 guard(pm_runtime_active)(ptdev->base.dev); 184 185 panthor_gpu_irq_enable_events(&ptdev->gpu->irq, GPU_POWER_INTERRUPTS_MASK); 186 187 return 0; 188 } 189 190 void panthor_gpu_power_changed_off(struct panthor_device *ptdev) 191 { 192 guard(pm_runtime_active)(ptdev->base.dev); 193 194 panthor_gpu_irq_disable_events(&ptdev->gpu->irq, GPU_POWER_INTERRUPTS_MASK); 195 } 196 197 /** 198 * panthor_gpu_block_power_off() - Power-off a specific block of the GPU 199 * @ptdev: Device. 200 * @blk_name: Block name. 201 * @pwroff_reg: Power-off register for this block. 202 * @pwrtrans_reg: Power transition register for this block. 203 * @mask: Sub-elements to power-off. 204 * @timeout_us: Timeout in microseconds. 205 * 206 * Return: 0 on success, a negative error code otherwise. 207 */ 208 int panthor_gpu_block_power_off(struct panthor_device *ptdev, 209 const char *blk_name, 210 u32 pwroff_reg, u32 pwrtrans_reg, 211 u64 mask, u32 timeout_us) 212 { 213 struct panthor_gpu *gpu = ptdev->gpu; 214 u32 val; 215 int ret; 216 217 ret = gpu_read64_relaxed_poll_timeout(gpu->iomem, pwrtrans_reg, val, 218 !(mask & val), 100, timeout_us); 219 if (ret) { 220 drm_err(&ptdev->base, 221 "timeout waiting on %s:%llx power transition", blk_name, 222 mask); 223 return ret; 224 } 225 226 gpu_write64(gpu->iomem, pwroff_reg, mask); 227 228 ret = gpu_read64_relaxed_poll_timeout(gpu->iomem, pwrtrans_reg, val, 229 !(mask & val), 100, timeout_us); 230 if (ret) { 231 drm_err(&ptdev->base, 232 "timeout waiting on %s:%llx power transition", blk_name, 233 mask); 234 return ret; 235 } 236 237 return 0; 238 } 239 240 /** 241 * panthor_gpu_block_power_on() - Power-on a specific block of the GPU 242 * @ptdev: Device. 243 * @blk_name: Block name. 244 * @pwron_reg: Power-on register for this block. 245 * @pwrtrans_reg: Power transition register for this block. 246 * @rdy_reg: Power transition ready register. 247 * @mask: Sub-elements to power-on. 248 * @timeout_us: Timeout in microseconds. 249 * 250 * Return: 0 on success, a negative error code otherwise. 251 */ 252 int panthor_gpu_block_power_on(struct panthor_device *ptdev, 253 const char *blk_name, 254 u32 pwron_reg, u32 pwrtrans_reg, 255 u32 rdy_reg, u64 mask, u32 timeout_us) 256 { 257 struct panthor_gpu *gpu = ptdev->gpu; 258 u32 val; 259 int ret; 260 261 ret = gpu_read64_relaxed_poll_timeout(gpu->iomem, pwrtrans_reg, val, 262 !(mask & val), 100, timeout_us); 263 if (ret) { 264 drm_err(&ptdev->base, 265 "timeout waiting on %s:%llx power transition", blk_name, 266 mask); 267 return ret; 268 } 269 270 gpu_write64(gpu->iomem, pwron_reg, mask); 271 272 ret = gpu_read64_relaxed_poll_timeout(gpu->iomem, rdy_reg, val, 273 (mask & val) == val, 274 100, timeout_us); 275 if (ret) { 276 drm_err(&ptdev->base, "timeout waiting on %s:%llx readiness", 277 blk_name, mask); 278 return ret; 279 } 280 281 return 0; 282 } 283 284 void panthor_gpu_l2_power_off(struct panthor_device *ptdev) 285 { 286 panthor_gpu_power_off(ptdev, L2, ptdev->gpu_info.l2_present, 20000); 287 } 288 289 /** 290 * panthor_gpu_l2_power_on() - Power-on the L2-cache 291 * @ptdev: Device. 292 * 293 * Return: 0 on success, a negative error code otherwise. 294 */ 295 int panthor_gpu_l2_power_on(struct panthor_device *ptdev) 296 { 297 if (ptdev->gpu_info.l2_present != 1) { 298 /* 299 * Only support one core group now. 300 * ~(l2_present - 1) unsets all bits in l2_present except 301 * the bottom bit. (l2_present - 2) has all the bits in 302 * the first core group set. AND them together to generate 303 * a mask of cores in the first core group. 304 */ 305 u64 core_mask = ~(ptdev->gpu_info.l2_present - 1) & 306 (ptdev->gpu_info.l2_present - 2); 307 drm_info_once(&ptdev->base, "using only 1st core group (%lu cores from %lu)\n", 308 hweight64(core_mask), 309 hweight64(ptdev->gpu_info.shader_present)); 310 } 311 312 /* Set the desired coherency mode and L2 config before the power up of L2 */ 313 panthor_gpu_coherency_set(ptdev); 314 panthor_gpu_l2_config_set(ptdev); 315 316 return panthor_gpu_power_on(ptdev, L2, 1, 20000); 317 } 318 319 /** 320 * panthor_gpu_flush_caches() - Flush caches 321 * @ptdev: Device. 322 * @l2: L2 flush type. 323 * @lsc: LSC flush type. 324 * @other: Other flush type. 325 * 326 * Return: 0 on success, a negative error code otherwise. 327 */ 328 int panthor_gpu_flush_caches(struct panthor_device *ptdev, 329 u32 l2, u32 lsc, u32 other) 330 { 331 struct panthor_gpu *gpu = ptdev->gpu; 332 unsigned long flags; 333 int ret = 0; 334 335 /* Serialize cache flush operations. */ 336 guard(mutex)(&ptdev->gpu->cache_flush_lock); 337 338 spin_lock_irqsave(&ptdev->gpu->reqs_lock, flags); 339 if (!(ptdev->gpu->pending_reqs & GPU_IRQ_CLEAN_CACHES_COMPLETED)) { 340 ptdev->gpu->pending_reqs |= GPU_IRQ_CLEAN_CACHES_COMPLETED; 341 gpu_write(gpu->iomem, GPU_CMD, GPU_FLUSH_CACHES(l2, lsc, other)); 342 } else { 343 ret = -EIO; 344 } 345 spin_unlock_irqrestore(&ptdev->gpu->reqs_lock, flags); 346 347 if (ret) 348 return ret; 349 350 if (!wait_event_timeout(ptdev->gpu->reqs_acked, 351 !(ptdev->gpu->pending_reqs & GPU_IRQ_CLEAN_CACHES_COMPLETED), 352 msecs_to_jiffies(100))) { 353 spin_lock_irqsave(&ptdev->gpu->reqs_lock, flags); 354 if ((ptdev->gpu->pending_reqs & GPU_IRQ_CLEAN_CACHES_COMPLETED) != 0 && 355 !(gpu_read(gpu->irq.iomem, INT_RAWSTAT) & GPU_IRQ_CLEAN_CACHES_COMPLETED)) 356 ret = -ETIMEDOUT; 357 else 358 ptdev->gpu->pending_reqs &= ~GPU_IRQ_CLEAN_CACHES_COMPLETED; 359 spin_unlock_irqrestore(&ptdev->gpu->reqs_lock, flags); 360 } 361 362 if (ret) { 363 panthor_device_schedule_reset(ptdev); 364 drm_err(&ptdev->base, "Flush caches timeout"); 365 } 366 367 return ret; 368 } 369 370 /** 371 * panthor_gpu_soft_reset() - Issue a soft-reset 372 * @ptdev: Device. 373 * 374 * Return: 0 on success, a negative error code otherwise. 375 */ 376 int panthor_gpu_soft_reset(struct panthor_device *ptdev) 377 { 378 struct panthor_gpu *gpu = ptdev->gpu; 379 bool timedout = false; 380 unsigned long flags; 381 382 spin_lock_irqsave(&ptdev->gpu->reqs_lock, flags); 383 if (!drm_WARN_ON(&ptdev->base, 384 ptdev->gpu->pending_reqs & GPU_IRQ_RESET_COMPLETED)) { 385 ptdev->gpu->pending_reqs |= GPU_IRQ_RESET_COMPLETED; 386 gpu_write(gpu->irq.iomem, INT_CLEAR, GPU_IRQ_RESET_COMPLETED); 387 gpu_write(gpu->iomem, GPU_CMD, GPU_SOFT_RESET); 388 } 389 spin_unlock_irqrestore(&ptdev->gpu->reqs_lock, flags); 390 391 if (!wait_event_timeout(ptdev->gpu->reqs_acked, 392 !(ptdev->gpu->pending_reqs & GPU_IRQ_RESET_COMPLETED), 393 msecs_to_jiffies(100))) { 394 spin_lock_irqsave(&ptdev->gpu->reqs_lock, flags); 395 if ((ptdev->gpu->pending_reqs & GPU_IRQ_RESET_COMPLETED) != 0 && 396 !(gpu_read(gpu->irq.iomem, INT_RAWSTAT) & GPU_IRQ_RESET_COMPLETED)) 397 timedout = true; 398 else 399 ptdev->gpu->pending_reqs &= ~GPU_IRQ_RESET_COMPLETED; 400 spin_unlock_irqrestore(&ptdev->gpu->reqs_lock, flags); 401 } 402 403 if (timedout) { 404 drm_err(&ptdev->base, "Soft reset timeout"); 405 return -ETIMEDOUT; 406 } 407 408 ptdev->gpu->pending_reqs = 0; 409 return 0; 410 } 411 412 /** 413 * panthor_gpu_suspend() - Suspend the GPU block. 414 * @ptdev: Device. 415 * 416 * Suspend the GPU irq. This should be called last in the suspend procedure, 417 * after all other blocks have been suspented. 418 */ 419 void panthor_gpu_suspend(struct panthor_device *ptdev) 420 { 421 /* On a fast reset, simply power down the L2. */ 422 if (!ptdev->reset.fast) 423 panthor_hw_soft_reset(ptdev); 424 else 425 panthor_hw_l2_power_off(ptdev); 426 427 panthor_gpu_irq_suspend(&ptdev->gpu->irq); 428 } 429 430 /** 431 * panthor_gpu_resume() - Resume the GPU block. 432 * @ptdev: Device. 433 * 434 * Resume the IRQ handler and power-on the L2-cache. 435 * The FW takes care of powering the other blocks. 436 */ 437 void panthor_gpu_resume(struct panthor_device *ptdev) 438 { 439 panthor_gpu_irq_resume(&ptdev->gpu->irq); 440 panthor_hw_l2_power_on(ptdev); 441 } 442 443 u64 panthor_gpu_get_timestamp(struct panthor_device *ptdev) 444 { 445 return gpu_read64_counter(ptdev->gpu->iomem, GPU_TIMESTAMP); 446 } 447 448 u64 panthor_gpu_get_timestamp_offset(struct panthor_device *ptdev) 449 { 450 return gpu_read64(ptdev->gpu->iomem, GPU_TIMESTAMP_OFFSET); 451 } 452 453 u64 panthor_gpu_get_cycle_count(struct panthor_device *ptdev) 454 { 455 return gpu_read64_counter(ptdev->gpu->iomem, GPU_CYCLE_COUNT); 456 } 457 458 int panthor_gpu_coherency_init(struct panthor_device *ptdev) 459 { 460 BUILD_BUG_ON(GPU_COHERENCY_NONE != DRM_PANTHOR_GPU_COHERENCY_NONE); 461 BUILD_BUG_ON(GPU_COHERENCY_ACE_LITE != DRM_PANTHOR_GPU_COHERENCY_ACE_LITE); 462 BUILD_BUG_ON(GPU_COHERENCY_ACE != DRM_PANTHOR_GPU_COHERENCY_ACE); 463 464 /* Start with no coherency, and update it if the device is flagged coherent. */ 465 ptdev->gpu_info.selected_coherency = GPU_COHERENCY_NONE; 466 ptdev->coherent = device_get_dma_attr(ptdev->base.dev) == DEV_DMA_COHERENT; 467 468 if (!ptdev->coherent) 469 return 0; 470 471 /* Check if the ACE-Lite coherency protocol is actually supported by the GPU. 472 * ACE protocol has never been supported for command stream frontend GPUs. 473 */ 474 if ((gpu_read(ptdev->gpu->iomem, GPU_COHERENCY_FEATURES) & 475 GPU_COHERENCY_PROT_BIT(ACE_LITE))) { 476 ptdev->gpu_info.selected_coherency = GPU_COHERENCY_ACE_LITE; 477 return 0; 478 } 479 480 drm_err(&ptdev->base, "Coherency not supported by the device"); 481 return -ENOTSUPP; 482 } 483