xref: /linux/drivers/media/platform/qcom/iris/iris_core.c (revision 2ace52718376fdb56aca863da2eebe70d7e2ddb1)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
4  */
5 
6 #include <linux/pm_runtime.h>
7 
8 #include "iris_core.h"
9 #include "iris_firmware.h"
10 #include "iris_state.h"
11 #include "iris_vpu_common.h"
12 
iris_core_deinit(struct iris_core * core)13 void iris_core_deinit(struct iris_core *core)
14 {
15 	pm_runtime_resume_and_get(core->dev);
16 
17 	mutex_lock(&core->lock);
18 	if (core->state != IRIS_CORE_DEINIT) {
19 		iris_fw_unload(core);
20 		iris_vpu_power_off(core);
21 		iris_hfi_queues_deinit(core);
22 		core->state = IRIS_CORE_DEINIT;
23 	}
24 	mutex_unlock(&core->lock);
25 
26 	pm_runtime_put_sync(core->dev);
27 }
28 
iris_wait_for_system_response(struct iris_core * core)29 static int iris_wait_for_system_response(struct iris_core *core)
30 {
31 	u32 hw_response_timeout_val = core->iris_platform_data->hw_response_timeout;
32 	int ret;
33 
34 	if (core->state == IRIS_CORE_ERROR)
35 		return -EIO;
36 
37 	ret = wait_for_completion_timeout(&core->core_init_done,
38 					  msecs_to_jiffies(hw_response_timeout_val));
39 	if (!ret) {
40 		core->state = IRIS_CORE_ERROR;
41 		return -ETIMEDOUT;
42 	}
43 
44 	return 0;
45 }
46 
iris_core_init(struct iris_core * core)47 int iris_core_init(struct iris_core *core)
48 {
49 	int ret;
50 
51 	mutex_lock(&core->lock);
52 	if (core->state == IRIS_CORE_INIT) {
53 		ret = 0;
54 		goto exit;
55 	} else if (core->state == IRIS_CORE_ERROR) {
56 		ret = -EINVAL;
57 		goto error;
58 	}
59 
60 	core->state = IRIS_CORE_INIT;
61 
62 	ret = iris_hfi_queues_init(core);
63 	if (ret)
64 		goto error;
65 
66 	ret = iris_vpu_power_on(core);
67 	if (ret)
68 		goto error_queue_deinit;
69 
70 	ret = iris_fw_load(core);
71 	if (ret)
72 		goto error_power_off;
73 
74 	ret = iris_vpu_boot_firmware(core);
75 	if (ret)
76 		goto error_unload_fw;
77 
78 	ret = iris_hfi_core_init(core);
79 	if (ret)
80 		goto error_unload_fw;
81 
82 	mutex_unlock(&core->lock);
83 
84 	return iris_wait_for_system_response(core);
85 
86 error_unload_fw:
87 	iris_fw_unload(core);
88 error_power_off:
89 	iris_vpu_power_off(core);
90 error_queue_deinit:
91 	iris_hfi_queues_deinit(core);
92 error:
93 	core->state = IRIS_CORE_DEINIT;
94 exit:
95 	mutex_unlock(&core->lock);
96 
97 	return ret;
98 }
99