xref: /linux/drivers/gpu/drm/panthor/panthor_gpu.c (revision c06b6cde2a1c3bcbb561bd57bb6f34eae9030921)
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