xref: /linux/drivers/gpu/drm/imagination/pvr_power.c (revision fd073dffef041d6a2d11f00cd6cbd8ff46083396)
1 // SPDX-License-Identifier: GPL-2.0-only OR MIT
2 /* Copyright (c) 2023 Imagination Technologies Ltd. */
3 
4 #include "pvr_device.h"
5 #include "pvr_fw.h"
6 #include "pvr_fw_startstop.h"
7 #include "pvr_power.h"
8 #include "pvr_queue.h"
9 #include "pvr_rogue_fwif.h"
10 
11 #include <drm/drm_drv.h>
12 #include <drm/drm_managed.h>
13 #include <linux/cleanup.h>
14 #include <linux/clk.h>
15 #include <linux/interrupt.h>
16 #include <linux/mutex.h>
17 #include <linux/of.h>
18 #include <linux/platform_device.h>
19 #include <linux/pm_domain.h>
20 #include <linux/pm_runtime.h>
21 #include <linux/timer.h>
22 #include <linux/types.h>
23 #include <linux/workqueue.h>
24 
25 #define POWER_SYNC_TIMEOUT_US (1000000) /* 1s */
26 
27 #define WATCHDOG_TIME_MS (500)
28 
29 /**
30  * pvr_device_lost() - Mark GPU device as lost
31  * @pvr_dev: Target PowerVR device.
32  *
33  * This will cause the DRM device to be unplugged.
34  */
35 void
36 pvr_device_lost(struct pvr_device *pvr_dev)
37 {
38 	if (!pvr_dev->lost) {
39 		pvr_dev->lost = true;
40 		drm_dev_unplug(from_pvr_device(pvr_dev));
41 	}
42 }
43 
44 static int
45 pvr_power_send_command(struct pvr_device *pvr_dev, struct rogue_fwif_kccb_cmd *pow_cmd)
46 {
47 	struct pvr_fw_device *fw_dev = &pvr_dev->fw_dev;
48 	u32 slot_nr;
49 	u32 value;
50 	int err;
51 
52 	WRITE_ONCE(*fw_dev->power_sync, 0);
53 
54 	err = pvr_kccb_send_cmd_powered(pvr_dev, pow_cmd, &slot_nr);
55 	if (err)
56 		return err;
57 
58 	/* Wait for FW to acknowledge. */
59 	return readl_poll_timeout(pvr_dev->fw_dev.power_sync, value, value != 0, 100,
60 				  POWER_SYNC_TIMEOUT_US);
61 }
62 
63 static int
64 pvr_power_request_idle(struct pvr_device *pvr_dev)
65 {
66 	struct rogue_fwif_kccb_cmd pow_cmd;
67 
68 	/* Send FORCED_IDLE request to FW. */
69 	pow_cmd.cmd_type = ROGUE_FWIF_KCCB_CMD_POW;
70 	pow_cmd.cmd_data.pow_data.pow_type = ROGUE_FWIF_POW_FORCED_IDLE_REQ;
71 	pow_cmd.cmd_data.pow_data.power_req_data.pow_request_type = ROGUE_FWIF_POWER_FORCE_IDLE;
72 
73 	return pvr_power_send_command(pvr_dev, &pow_cmd);
74 }
75 
76 static int
77 pvr_power_request_pwr_off(struct pvr_device *pvr_dev)
78 {
79 	struct rogue_fwif_kccb_cmd pow_cmd;
80 
81 	/* Send POW_OFF request to firmware. */
82 	pow_cmd.cmd_type = ROGUE_FWIF_KCCB_CMD_POW;
83 	pow_cmd.cmd_data.pow_data.pow_type = ROGUE_FWIF_POW_OFF_REQ;
84 	pow_cmd.cmd_data.pow_data.power_req_data.forced = true;
85 
86 	return pvr_power_send_command(pvr_dev, &pow_cmd);
87 }
88 
89 static int
90 pvr_power_fw_disable(struct pvr_device *pvr_dev, bool hard_reset)
91 {
92 	if (!hard_reset) {
93 		int err;
94 
95 		cancel_delayed_work_sync(&pvr_dev->watchdog.work);
96 
97 		err = pvr_power_request_idle(pvr_dev);
98 		if (err)
99 			return err;
100 
101 		err = pvr_power_request_pwr_off(pvr_dev);
102 		if (err)
103 			return err;
104 	}
105 
106 	return pvr_fw_stop(pvr_dev);
107 }
108 
109 static int
110 pvr_power_fw_enable(struct pvr_device *pvr_dev)
111 {
112 	int err;
113 
114 	err = pvr_fw_start(pvr_dev);
115 	if (err)
116 		return err;
117 
118 	err = pvr_wait_for_fw_boot(pvr_dev);
119 	if (err) {
120 		drm_err(from_pvr_device(pvr_dev), "Firmware failed to boot\n");
121 		pvr_fw_stop(pvr_dev);
122 		return err;
123 	}
124 
125 	queue_delayed_work(pvr_dev->sched_wq, &pvr_dev->watchdog.work,
126 			   msecs_to_jiffies(WATCHDOG_TIME_MS));
127 
128 	return 0;
129 }
130 
131 bool
132 pvr_power_is_idle(struct pvr_device *pvr_dev)
133 {
134 	/*
135 	 * FW power state can be out of date if a KCCB command has been submitted but the FW hasn't
136 	 * started processing it yet. So also check the KCCB status.
137 	 */
138 	enum rogue_fwif_pow_state pow_state = READ_ONCE(pvr_dev->fw_dev.fwif_sysdata->pow_state);
139 	bool kccb_idle = pvr_kccb_is_idle(pvr_dev);
140 
141 	return (pow_state == ROGUE_FWIF_POW_IDLE) && kccb_idle;
142 }
143 
144 static bool
145 pvr_watchdog_kccb_stalled(struct pvr_device *pvr_dev)
146 {
147 	/* Check KCCB commands are progressing. */
148 	u32 kccb_cmds_executed = pvr_dev->fw_dev.fwif_osdata->kccb_cmds_executed;
149 	bool kccb_is_idle = pvr_kccb_is_idle(pvr_dev);
150 
151 	if (pvr_dev->watchdog.old_kccb_cmds_executed == kccb_cmds_executed && !kccb_is_idle) {
152 		pvr_dev->watchdog.kccb_stall_count++;
153 
154 		/*
155 		 * If we have commands pending with no progress for 2 consecutive polls then
156 		 * consider KCCB command processing stalled.
157 		 */
158 		if (pvr_dev->watchdog.kccb_stall_count == 2) {
159 			pvr_dev->watchdog.kccb_stall_count = 0;
160 			return true;
161 		}
162 	} else if (pvr_dev->watchdog.old_kccb_cmds_executed == kccb_cmds_executed) {
163 		bool has_active_contexts;
164 
165 		mutex_lock(&pvr_dev->queues.lock);
166 		has_active_contexts = list_empty(&pvr_dev->queues.active);
167 		mutex_unlock(&pvr_dev->queues.lock);
168 
169 		if (has_active_contexts) {
170 			/* Send a HEALTH_CHECK command so we can verify FW is still alive. */
171 			struct rogue_fwif_kccb_cmd health_check_cmd;
172 
173 			health_check_cmd.cmd_type = ROGUE_FWIF_KCCB_CMD_HEALTH_CHECK;
174 
175 			pvr_kccb_send_cmd_powered(pvr_dev, &health_check_cmd, NULL);
176 		}
177 	} else {
178 		pvr_dev->watchdog.old_kccb_cmds_executed = kccb_cmds_executed;
179 		pvr_dev->watchdog.kccb_stall_count = 0;
180 	}
181 
182 	return false;
183 }
184 
185 static void
186 pvr_watchdog_worker(struct work_struct *work)
187 {
188 	struct pvr_device *pvr_dev = container_of(work, struct pvr_device,
189 						  watchdog.work.work);
190 	bool stalled;
191 
192 	if (pvr_dev->lost)
193 		return;
194 
195 	if (pm_runtime_get_if_in_use(from_pvr_device(pvr_dev)->dev) <= 0)
196 		goto out_requeue;
197 
198 	if (!pvr_dev->fw_dev.booted)
199 		goto out_pm_runtime_put;
200 
201 	stalled = pvr_watchdog_kccb_stalled(pvr_dev);
202 
203 	if (stalled) {
204 		drm_err(from_pvr_device(pvr_dev), "FW stalled, trying hard reset");
205 
206 		pvr_power_reset(pvr_dev, true);
207 		/* Device may be lost at this point. */
208 	}
209 
210 out_pm_runtime_put:
211 	pm_runtime_put(from_pvr_device(pvr_dev)->dev);
212 
213 out_requeue:
214 	if (!pvr_dev->lost) {
215 		queue_delayed_work(pvr_dev->sched_wq, &pvr_dev->watchdog.work,
216 				   msecs_to_jiffies(WATCHDOG_TIME_MS));
217 	}
218 }
219 
220 /**
221  * pvr_watchdog_init() - Initialise watchdog for device
222  * @pvr_dev: Target PowerVR device.
223  *
224  * Returns:
225  *  * 0 on success, or
226  *  * -%ENOMEM on out of memory.
227  */
228 int
229 pvr_watchdog_init(struct pvr_device *pvr_dev)
230 {
231 	INIT_DELAYED_WORK(&pvr_dev->watchdog.work, pvr_watchdog_worker);
232 
233 	return 0;
234 }
235 
236 int
237 pvr_power_device_suspend(struct device *dev)
238 {
239 	struct platform_device *plat_dev = to_platform_device(dev);
240 	struct drm_device *drm_dev = platform_get_drvdata(plat_dev);
241 	struct pvr_device *pvr_dev = to_pvr_device(drm_dev);
242 	int err = 0;
243 	int idx;
244 
245 	if (!drm_dev_enter(drm_dev, &idx))
246 		return -EIO;
247 
248 	if (pvr_dev->fw_dev.booted) {
249 		err = pvr_power_fw_disable(pvr_dev, false);
250 		if (err)
251 			goto err_drm_dev_exit;
252 	}
253 
254 	clk_disable_unprepare(pvr_dev->mem_clk);
255 	clk_disable_unprepare(pvr_dev->sys_clk);
256 	clk_disable_unprepare(pvr_dev->core_clk);
257 
258 err_drm_dev_exit:
259 	drm_dev_exit(idx);
260 
261 	return err;
262 }
263 
264 int
265 pvr_power_device_resume(struct device *dev)
266 {
267 	struct platform_device *plat_dev = to_platform_device(dev);
268 	struct drm_device *drm_dev = platform_get_drvdata(plat_dev);
269 	struct pvr_device *pvr_dev = to_pvr_device(drm_dev);
270 	int idx;
271 	int err;
272 
273 	if (!drm_dev_enter(drm_dev, &idx))
274 		return -EIO;
275 
276 	err = clk_prepare_enable(pvr_dev->core_clk);
277 	if (err)
278 		goto err_drm_dev_exit;
279 
280 	err = clk_prepare_enable(pvr_dev->sys_clk);
281 	if (err)
282 		goto err_core_clk_disable;
283 
284 	err = clk_prepare_enable(pvr_dev->mem_clk);
285 	if (err)
286 		goto err_sys_clk_disable;
287 
288 	if (pvr_dev->fw_dev.booted) {
289 		err = pvr_power_fw_enable(pvr_dev);
290 		if (err)
291 			goto err_mem_clk_disable;
292 	}
293 
294 	drm_dev_exit(idx);
295 
296 	return 0;
297 
298 err_mem_clk_disable:
299 	clk_disable_unprepare(pvr_dev->mem_clk);
300 
301 err_sys_clk_disable:
302 	clk_disable_unprepare(pvr_dev->sys_clk);
303 
304 err_core_clk_disable:
305 	clk_disable_unprepare(pvr_dev->core_clk);
306 
307 err_drm_dev_exit:
308 	drm_dev_exit(idx);
309 
310 	return err;
311 }
312 
313 int
314 pvr_power_device_idle(struct device *dev)
315 {
316 	struct platform_device *plat_dev = to_platform_device(dev);
317 	struct drm_device *drm_dev = platform_get_drvdata(plat_dev);
318 	struct pvr_device *pvr_dev = to_pvr_device(drm_dev);
319 
320 	return pvr_power_is_idle(pvr_dev) ? 0 : -EBUSY;
321 }
322 
323 /**
324  * pvr_power_reset() - Reset the GPU
325  * @pvr_dev: Device pointer
326  * @hard_reset: %true for hard reset, %false for soft reset
327  *
328  * If @hard_reset is %false and the FW processor fails to respond during the reset process, this
329  * function will attempt a hard reset.
330  *
331  * If a hard reset fails then the GPU device is reported as lost.
332  *
333  * Returns:
334  *  * 0 on success, or
335  *  * Any error code returned by pvr_power_get, pvr_power_fw_disable or pvr_power_fw_enable().
336  */
337 int
338 pvr_power_reset(struct pvr_device *pvr_dev, bool hard_reset)
339 {
340 	bool queues_disabled = false;
341 	int err;
342 
343 	/*
344 	 * Take a power reference during the reset. This should prevent any interference with the
345 	 * power state during reset.
346 	 */
347 	WARN_ON(pvr_power_get(pvr_dev));
348 
349 	down_write(&pvr_dev->reset_sem);
350 
351 	if (pvr_dev->lost) {
352 		err = -EIO;
353 		goto err_up_write;
354 	}
355 
356 	/* Disable IRQs for the duration of the reset. */
357 	disable_irq(pvr_dev->irq);
358 
359 	do {
360 		if (hard_reset) {
361 			pvr_queue_device_pre_reset(pvr_dev);
362 			queues_disabled = true;
363 		}
364 
365 		err = pvr_power_fw_disable(pvr_dev, hard_reset);
366 		if (!err) {
367 			if (hard_reset) {
368 				pvr_dev->fw_dev.booted = false;
369 				WARN_ON(pm_runtime_force_suspend(from_pvr_device(pvr_dev)->dev));
370 
371 				err = pvr_fw_hard_reset(pvr_dev);
372 				if (err)
373 					goto err_device_lost;
374 
375 				err = pm_runtime_force_resume(from_pvr_device(pvr_dev)->dev);
376 				pvr_dev->fw_dev.booted = true;
377 				if (err)
378 					goto err_device_lost;
379 			} else {
380 				/* Clear the FW faulted flags. */
381 				pvr_dev->fw_dev.fwif_sysdata->hwr_state_flags &=
382 					~(ROGUE_FWIF_HWR_FW_FAULT |
383 					  ROGUE_FWIF_HWR_RESTART_REQUESTED);
384 			}
385 
386 			pvr_fw_irq_clear(pvr_dev);
387 
388 			err = pvr_power_fw_enable(pvr_dev);
389 		}
390 
391 		if (err && hard_reset)
392 			goto err_device_lost;
393 
394 		if (err && !hard_reset) {
395 			drm_err(from_pvr_device(pvr_dev), "FW stalled, trying hard reset");
396 			hard_reset = true;
397 		}
398 	} while (err);
399 
400 	if (queues_disabled)
401 		pvr_queue_device_post_reset(pvr_dev);
402 
403 	enable_irq(pvr_dev->irq);
404 
405 	up_write(&pvr_dev->reset_sem);
406 
407 	pvr_power_put(pvr_dev);
408 
409 	return 0;
410 
411 err_device_lost:
412 	drm_err(from_pvr_device(pvr_dev), "GPU device lost");
413 	pvr_device_lost(pvr_dev);
414 
415 	/* Leave IRQs disabled if the device is lost. */
416 
417 	if (queues_disabled)
418 		pvr_queue_device_post_reset(pvr_dev);
419 
420 err_up_write:
421 	up_write(&pvr_dev->reset_sem);
422 
423 	pvr_power_put(pvr_dev);
424 
425 	return err;
426 }
427 
428 /**
429  * pvr_watchdog_fini() - Shutdown watchdog for device
430  * @pvr_dev: Target PowerVR device.
431  */
432 void
433 pvr_watchdog_fini(struct pvr_device *pvr_dev)
434 {
435 	cancel_delayed_work_sync(&pvr_dev->watchdog.work);
436 }
437 
438 int pvr_power_domains_init(struct pvr_device *pvr_dev)
439 {
440 	struct device *dev = from_pvr_device(pvr_dev)->dev;
441 
442 	struct device_link **domain_links __free(kfree) = NULL;
443 	struct device **domain_devs __free(kfree) = NULL;
444 	int domain_count;
445 	int link_count;
446 
447 	char dev_name[2] = "a";
448 	int err;
449 	int i;
450 
451 	domain_count = of_count_phandle_with_args(dev->of_node, "power-domains",
452 						  "#power-domain-cells");
453 	if (domain_count < 0)
454 		return domain_count;
455 
456 	if (domain_count <= 1)
457 		return 0;
458 
459 	link_count = domain_count + (domain_count - 1);
460 
461 	domain_devs = kcalloc(domain_count, sizeof(*domain_devs), GFP_KERNEL);
462 	if (!domain_devs)
463 		return -ENOMEM;
464 
465 	domain_links = kcalloc(link_count, sizeof(*domain_links), GFP_KERNEL);
466 	if (!domain_links)
467 		return -ENOMEM;
468 
469 	for (i = 0; i < domain_count; i++) {
470 		struct device *domain_dev;
471 
472 		dev_name[0] = 'a' + i;
473 		domain_dev = dev_pm_domain_attach_by_name(dev, dev_name);
474 		if (IS_ERR_OR_NULL(domain_dev)) {
475 			err = domain_dev ? PTR_ERR(domain_dev) : -ENODEV;
476 			goto err_detach;
477 		}
478 
479 		domain_devs[i] = domain_dev;
480 	}
481 
482 	for (i = 0; i < domain_count; i++) {
483 		struct device_link *link;
484 
485 		link = device_link_add(dev, domain_devs[i], DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME);
486 		if (!link) {
487 			err = -ENODEV;
488 			goto err_unlink;
489 		}
490 
491 		domain_links[i] = link;
492 	}
493 
494 	for (i = domain_count; i < link_count; i++) {
495 		struct device_link *link;
496 
497 		link = device_link_add(domain_devs[i - domain_count + 1],
498 				       domain_devs[i - domain_count],
499 				       DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME);
500 		if (!link) {
501 			err = -ENODEV;
502 			goto err_unlink;
503 		}
504 
505 		domain_links[i] = link;
506 	}
507 
508 	pvr_dev->power = (struct pvr_device_power){
509 		.domain_devs = no_free_ptr(domain_devs),
510 		.domain_links = no_free_ptr(domain_links),
511 		.domain_count = domain_count,
512 	};
513 
514 	return 0;
515 
516 err_unlink:
517 	while (--i >= 0)
518 		device_link_del(domain_links[i]);
519 
520 	i = domain_count;
521 
522 err_detach:
523 	while (--i >= 0)
524 		dev_pm_domain_detach(domain_devs[i], true);
525 
526 	return err;
527 }
528 
529 void pvr_power_domains_fini(struct pvr_device *pvr_dev)
530 {
531 	const int domain_count = pvr_dev->power.domain_count;
532 
533 	int i = domain_count + (domain_count - 1);
534 
535 	while (--i >= 0)
536 		device_link_del(pvr_dev->power.domain_links[i]);
537 
538 	i = domain_count;
539 
540 	while (--i >= 0)
541 		dev_pm_domain_detach(pvr_dev->power.domain_devs[i], true);
542 
543 	kfree(pvr_dev->power.domain_links);
544 	kfree(pvr_dev->power.domain_devs);
545 
546 	pvr_dev->power = (struct pvr_device_power){ 0 };
547 }
548