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 	iris_fw_unload(core);
19 	iris_vpu_power_off(core);
20 	iris_hfi_queues_deinit(core);
21 	core->state = IRIS_CORE_DEINIT;
22 	mutex_unlock(&core->lock);
23 
24 	pm_runtime_put_sync(core->dev);
25 }
26 
iris_wait_for_system_response(struct iris_core * core)27 static int iris_wait_for_system_response(struct iris_core *core)
28 {
29 	u32 hw_response_timeout_val = core->iris_platform_data->hw_response_timeout;
30 	int ret;
31 
32 	if (core->state == IRIS_CORE_ERROR)
33 		return -EIO;
34 
35 	ret = wait_for_completion_timeout(&core->core_init_done,
36 					  msecs_to_jiffies(hw_response_timeout_val));
37 	if (!ret) {
38 		core->state = IRIS_CORE_ERROR;
39 		return -ETIMEDOUT;
40 	}
41 
42 	return 0;
43 }
44 
iris_core_init(struct iris_core * core)45 int iris_core_init(struct iris_core *core)
46 {
47 	int ret;
48 
49 	mutex_lock(&core->lock);
50 	if (core->state == IRIS_CORE_INIT) {
51 		ret = 0;
52 		goto exit;
53 	} else if (core->state == IRIS_CORE_ERROR) {
54 		ret = -EINVAL;
55 		goto error;
56 	}
57 
58 	core->state = IRIS_CORE_INIT;
59 
60 	ret = iris_hfi_queues_init(core);
61 	if (ret)
62 		goto error;
63 
64 	ret = iris_vpu_power_on(core);
65 	if (ret)
66 		goto error_queue_deinit;
67 
68 	ret = iris_fw_load(core);
69 	if (ret)
70 		goto error_power_off;
71 
72 	ret = iris_vpu_boot_firmware(core);
73 	if (ret)
74 		goto error_unload_fw;
75 
76 	ret = iris_hfi_core_init(core);
77 	if (ret)
78 		goto error_unload_fw;
79 
80 	mutex_unlock(&core->lock);
81 
82 	return iris_wait_for_system_response(core);
83 
84 error_unload_fw:
85 	iris_fw_unload(core);
86 error_power_off:
87 	iris_vpu_power_off(core);
88 error_queue_deinit:
89 	iris_hfi_queues_deinit(core);
90 error:
91 	core->state = IRIS_CORE_DEINIT;
92 exit:
93 	mutex_unlock(&core->lock);
94 
95 	return ret;
96 }
97