xref: /linux/drivers/gpu/drm/panthor/panthor_gpu.c (revision 88b8c6ae2ccb3ef9dbb04c8e13a4d1a98c42e922)
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 				      ptdev->iomem + GPU_INT_BASE);
174 	if (ret)
175 		return ret;
176 
177 	panthor_gpu_irq_enable_events(&ptdev->gpu->irq, GPU_INTERRUPTS_MASK);
178 	panthor_gpu_irq_resume(&ptdev->gpu->irq);
179 	return 0;
180 }
181 
182 int panthor_gpu_power_changed_on(struct panthor_device *ptdev)
183 {
184 	guard(pm_runtime_active)(ptdev->base.dev);
185 
186 	panthor_gpu_irq_enable_events(&ptdev->gpu->irq, GPU_POWER_INTERRUPTS_MASK);
187 
188 	return 0;
189 }
190 
191 void panthor_gpu_power_changed_off(struct panthor_device *ptdev)
192 {
193 	guard(pm_runtime_active)(ptdev->base.dev);
194 
195 	panthor_gpu_irq_disable_events(&ptdev->gpu->irq, GPU_POWER_INTERRUPTS_MASK);
196 }
197 
198 /**
199  * panthor_gpu_block_power_off() - Power-off a specific block of the GPU
200  * @ptdev: Device.
201  * @blk_name: Block name.
202  * @pwroff_reg: Power-off register for this block.
203  * @pwrtrans_reg: Power transition register for this block.
204  * @mask: Sub-elements to power-off.
205  * @timeout_us: Timeout in microseconds.
206  *
207  * Return: 0 on success, a negative error code otherwise.
208  */
209 int panthor_gpu_block_power_off(struct panthor_device *ptdev,
210 				const char *blk_name,
211 				u32 pwroff_reg, u32 pwrtrans_reg,
212 				u64 mask, u32 timeout_us)
213 {
214 	struct panthor_gpu *gpu = ptdev->gpu;
215 	u32 val;
216 	int ret;
217 
218 	ret = gpu_read64_relaxed_poll_timeout(gpu->iomem, pwrtrans_reg, val,
219 					      !(mask & val), 100, timeout_us);
220 	if (ret) {
221 		drm_err(&ptdev->base,
222 			"timeout waiting on %s:%llx power transition", blk_name,
223 			mask);
224 		return ret;
225 	}
226 
227 	gpu_write64(gpu->iomem, pwroff_reg, mask);
228 
229 	ret = gpu_read64_relaxed_poll_timeout(gpu->iomem, pwrtrans_reg, val,
230 					      !(mask & val), 100, timeout_us);
231 	if (ret) {
232 		drm_err(&ptdev->base,
233 			"timeout waiting on %s:%llx power transition", blk_name,
234 			mask);
235 		return ret;
236 	}
237 
238 	return 0;
239 }
240 
241 /**
242  * panthor_gpu_block_power_on() - Power-on a specific block of the GPU
243  * @ptdev: Device.
244  * @blk_name: Block name.
245  * @pwron_reg: Power-on register for this block.
246  * @pwrtrans_reg: Power transition register for this block.
247  * @rdy_reg: Power transition ready register.
248  * @mask: Sub-elements to power-on.
249  * @timeout_us: Timeout in microseconds.
250  *
251  * Return: 0 on success, a negative error code otherwise.
252  */
253 int panthor_gpu_block_power_on(struct panthor_device *ptdev,
254 			       const char *blk_name,
255 			       u32 pwron_reg, u32 pwrtrans_reg,
256 			       u32 rdy_reg, u64 mask, u32 timeout_us)
257 {
258 	struct panthor_gpu *gpu = ptdev->gpu;
259 	u32 val;
260 	int ret;
261 
262 	ret = gpu_read64_relaxed_poll_timeout(gpu->iomem, pwrtrans_reg, val,
263 					      !(mask & val), 100, timeout_us);
264 	if (ret) {
265 		drm_err(&ptdev->base,
266 			"timeout waiting on %s:%llx power transition", blk_name,
267 			mask);
268 		return ret;
269 	}
270 
271 	gpu_write64(gpu->iomem, pwron_reg, mask);
272 
273 	ret = gpu_read64_relaxed_poll_timeout(gpu->iomem, rdy_reg, val,
274 					      (mask & val) == val,
275 					      100, timeout_us);
276 	if (ret) {
277 		drm_err(&ptdev->base, "timeout waiting on %s:%llx readiness",
278 			blk_name, mask);
279 		return ret;
280 	}
281 
282 	return 0;
283 }
284 
285 void panthor_gpu_l2_power_off(struct panthor_device *ptdev)
286 {
287 	panthor_gpu_power_off(ptdev, L2, ptdev->gpu_info.l2_present, 20000);
288 }
289 
290 /**
291  * panthor_gpu_l2_power_on() - Power-on the L2-cache
292  * @ptdev: Device.
293  *
294  * Return: 0 on success, a negative error code otherwise.
295  */
296 int panthor_gpu_l2_power_on(struct panthor_device *ptdev)
297 {
298 	if (ptdev->gpu_info.l2_present != 1) {
299 		/*
300 		 * Only support one core group now.
301 		 * ~(l2_present - 1) unsets all bits in l2_present except
302 		 * the bottom bit. (l2_present - 2) has all the bits in
303 		 * the first core group set. AND them together to generate
304 		 * a mask of cores in the first core group.
305 		 */
306 		u64 core_mask = ~(ptdev->gpu_info.l2_present - 1) &
307 				(ptdev->gpu_info.l2_present - 2);
308 		drm_info_once(&ptdev->base, "using only 1st core group (%lu cores from %lu)\n",
309 			      hweight64(core_mask),
310 			      hweight64(ptdev->gpu_info.shader_present));
311 	}
312 
313 	/* Set the desired coherency mode and L2 config before the power up of L2 */
314 	panthor_gpu_coherency_set(ptdev);
315 	panthor_gpu_l2_config_set(ptdev);
316 
317 	return panthor_gpu_power_on(ptdev, L2, 1, 20000);
318 }
319 
320 /**
321  * panthor_gpu_flush_caches() - Flush caches
322  * @ptdev: Device.
323  * @l2: L2 flush type.
324  * @lsc: LSC flush type.
325  * @other: Other flush type.
326  *
327  * Return: 0 on success, a negative error code otherwise.
328  */
329 int panthor_gpu_flush_caches(struct panthor_device *ptdev,
330 			     u32 l2, u32 lsc, u32 other)
331 {
332 	struct panthor_gpu *gpu = ptdev->gpu;
333 	unsigned long flags;
334 	int ret = 0;
335 
336 	/* Serialize cache flush operations. */
337 	guard(mutex)(&ptdev->gpu->cache_flush_lock);
338 
339 	spin_lock_irqsave(&ptdev->gpu->reqs_lock, flags);
340 	if (!(ptdev->gpu->pending_reqs & GPU_IRQ_CLEAN_CACHES_COMPLETED)) {
341 		ptdev->gpu->pending_reqs |= GPU_IRQ_CLEAN_CACHES_COMPLETED;
342 		gpu_write(gpu->iomem, GPU_CMD, GPU_FLUSH_CACHES(l2, lsc, other));
343 	} else {
344 		ret = -EIO;
345 	}
346 	spin_unlock_irqrestore(&ptdev->gpu->reqs_lock, flags);
347 
348 	if (ret)
349 		return ret;
350 
351 	if (!wait_event_timeout(ptdev->gpu->reqs_acked,
352 				!(ptdev->gpu->pending_reqs & GPU_IRQ_CLEAN_CACHES_COMPLETED),
353 				msecs_to_jiffies(100))) {
354 		spin_lock_irqsave(&ptdev->gpu->reqs_lock, flags);
355 		if ((ptdev->gpu->pending_reqs & GPU_IRQ_CLEAN_CACHES_COMPLETED) != 0 &&
356 		    !(gpu_read(gpu->irq.iomem, INT_RAWSTAT) & GPU_IRQ_CLEAN_CACHES_COMPLETED))
357 			ret = -ETIMEDOUT;
358 		else
359 			ptdev->gpu->pending_reqs &= ~GPU_IRQ_CLEAN_CACHES_COMPLETED;
360 		spin_unlock_irqrestore(&ptdev->gpu->reqs_lock, flags);
361 	}
362 
363 	if (ret) {
364 		panthor_device_schedule_reset(ptdev);
365 		drm_err(&ptdev->base, "Flush caches timeout");
366 	}
367 
368 	return ret;
369 }
370 
371 /**
372  * panthor_gpu_soft_reset() - Issue a soft-reset
373  * @ptdev: Device.
374  *
375  * Return: 0 on success, a negative error code otherwise.
376  */
377 int panthor_gpu_soft_reset(struct panthor_device *ptdev)
378 {
379 	struct panthor_gpu *gpu = ptdev->gpu;
380 	bool timedout = false;
381 	unsigned long flags;
382 
383 	spin_lock_irqsave(&ptdev->gpu->reqs_lock, flags);
384 	if (!drm_WARN_ON(&ptdev->base,
385 			 ptdev->gpu->pending_reqs & GPU_IRQ_RESET_COMPLETED)) {
386 		ptdev->gpu->pending_reqs |= GPU_IRQ_RESET_COMPLETED;
387 		gpu_write(gpu->irq.iomem, INT_CLEAR, GPU_IRQ_RESET_COMPLETED);
388 		gpu_write(gpu->iomem, GPU_CMD, GPU_SOFT_RESET);
389 	}
390 	spin_unlock_irqrestore(&ptdev->gpu->reqs_lock, flags);
391 
392 	if (!wait_event_timeout(ptdev->gpu->reqs_acked,
393 				!(ptdev->gpu->pending_reqs & GPU_IRQ_RESET_COMPLETED),
394 				msecs_to_jiffies(100))) {
395 		spin_lock_irqsave(&ptdev->gpu->reqs_lock, flags);
396 		if ((ptdev->gpu->pending_reqs & GPU_IRQ_RESET_COMPLETED) != 0 &&
397 		    !(gpu_read(gpu->irq.iomem, INT_RAWSTAT) & GPU_IRQ_RESET_COMPLETED))
398 			timedout = true;
399 		else
400 			ptdev->gpu->pending_reqs &= ~GPU_IRQ_RESET_COMPLETED;
401 		spin_unlock_irqrestore(&ptdev->gpu->reqs_lock, flags);
402 	}
403 
404 	if (timedout) {
405 		drm_err(&ptdev->base, "Soft reset timeout");
406 		return -ETIMEDOUT;
407 	}
408 
409 	ptdev->gpu->pending_reqs = 0;
410 	return 0;
411 }
412 
413 /**
414  * panthor_gpu_suspend() - Suspend the GPU block.
415  * @ptdev: Device.
416  *
417  * Suspend the GPU irq. This should be called last in the suspend procedure,
418  * after all other blocks have been suspented.
419  */
420 void panthor_gpu_suspend(struct panthor_device *ptdev)
421 {
422 	/* On a fast reset, simply power down the L2. */
423 	if (!ptdev->reset.fast)
424 		panthor_hw_soft_reset(ptdev);
425 	else
426 		panthor_hw_l2_power_off(ptdev);
427 
428 	panthor_gpu_irq_suspend(&ptdev->gpu->irq);
429 }
430 
431 /**
432  * panthor_gpu_resume() - Resume the GPU block.
433  * @ptdev: Device.
434  *
435  * Resume the IRQ handler and power-on the L2-cache.
436  * The FW takes care of powering the other blocks.
437  */
438 void panthor_gpu_resume(struct panthor_device *ptdev)
439 {
440 	panthor_gpu_irq_resume(&ptdev->gpu->irq);
441 	panthor_hw_l2_power_on(ptdev);
442 }
443 
444 u64 panthor_gpu_get_timestamp(struct panthor_device *ptdev)
445 {
446 	return gpu_read64_counter(ptdev->gpu->iomem, GPU_TIMESTAMP);
447 }
448 
449 u64 panthor_gpu_get_timestamp_offset(struct panthor_device *ptdev)
450 {
451 	return gpu_read64(ptdev->gpu->iomem, GPU_TIMESTAMP_OFFSET);
452 }
453 
454 u64 panthor_gpu_get_cycle_count(struct panthor_device *ptdev)
455 {
456 	return gpu_read64_counter(ptdev->gpu->iomem, GPU_CYCLE_COUNT);
457 }
458 
459 int panthor_gpu_coherency_init(struct panthor_device *ptdev)
460 {
461 	BUILD_BUG_ON(GPU_COHERENCY_NONE != DRM_PANTHOR_GPU_COHERENCY_NONE);
462 	BUILD_BUG_ON(GPU_COHERENCY_ACE_LITE != DRM_PANTHOR_GPU_COHERENCY_ACE_LITE);
463 	BUILD_BUG_ON(GPU_COHERENCY_ACE != DRM_PANTHOR_GPU_COHERENCY_ACE);
464 
465 	/* Start with no coherency, and update it if the device is flagged coherent. */
466 	ptdev->gpu_info.selected_coherency = GPU_COHERENCY_NONE;
467 	ptdev->coherent = device_get_dma_attr(ptdev->base.dev) == DEV_DMA_COHERENT;
468 
469 	if (!ptdev->coherent)
470 		return 0;
471 
472 	/* Check if the ACE-Lite coherency protocol is actually supported by the GPU.
473 	 * ACE protocol has never been supported for command stream frontend GPUs.
474 	 */
475 	if ((gpu_read(ptdev->gpu->iomem, GPU_COHERENCY_FEATURES) &
476 		      GPU_COHERENCY_PROT_BIT(ACE_LITE))) {
477 		ptdev->gpu_info.selected_coherency = GPU_COHERENCY_ACE_LITE;
478 		return 0;
479 	}
480 
481 	drm_err(&ptdev->base, "Coherency not supported by the device");
482 	return -ENOTSUPP;
483 }
484