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_firmware.h"
9 #include "iris_core.h"
10 #include "iris_hfi_common.h"
11 #include "iris_vpu_common.h"
12 
iris_hfi_get_v4l2_color_primaries(u32 hfi_primaries)13 u32 iris_hfi_get_v4l2_color_primaries(u32 hfi_primaries)
14 {
15 	switch (hfi_primaries) {
16 	case HFI_PRIMARIES_RESERVED:
17 		return V4L2_COLORSPACE_DEFAULT;
18 	case HFI_PRIMARIES_BT709:
19 		return V4L2_COLORSPACE_REC709;
20 	case HFI_PRIMARIES_BT470_SYSTEM_M:
21 		return V4L2_COLORSPACE_470_SYSTEM_M;
22 	case HFI_PRIMARIES_BT470_SYSTEM_BG:
23 		return V4L2_COLORSPACE_470_SYSTEM_BG;
24 	case HFI_PRIMARIES_BT601_525:
25 		return V4L2_COLORSPACE_SMPTE170M;
26 	case HFI_PRIMARIES_SMPTE_ST240M:
27 		return V4L2_COLORSPACE_SMPTE240M;
28 	case HFI_PRIMARIES_BT2020:
29 		return V4L2_COLORSPACE_BT2020;
30 	case V4L2_COLORSPACE_DCI_P3:
31 		return HFI_PRIMARIES_SMPTE_RP431_2;
32 	default:
33 		return V4L2_COLORSPACE_DEFAULT;
34 	}
35 }
36 
iris_hfi_get_v4l2_transfer_char(u32 hfi_characterstics)37 u32 iris_hfi_get_v4l2_transfer_char(u32 hfi_characterstics)
38 {
39 	switch (hfi_characterstics) {
40 	case HFI_TRANSFER_RESERVED:
41 		return V4L2_XFER_FUNC_DEFAULT;
42 	case HFI_TRANSFER_BT709:
43 		return V4L2_XFER_FUNC_709;
44 	case HFI_TRANSFER_SMPTE_ST240M:
45 		return V4L2_XFER_FUNC_SMPTE240M;
46 	case HFI_TRANSFER_SRGB_SYCC:
47 		return V4L2_XFER_FUNC_SRGB;
48 	case HFI_TRANSFER_SMPTE_ST2084_PQ:
49 		return V4L2_XFER_FUNC_SMPTE2084;
50 	default:
51 		return V4L2_XFER_FUNC_DEFAULT;
52 	}
53 }
54 
iris_hfi_get_v4l2_matrix_coefficients(u32 hfi_coefficients)55 u32 iris_hfi_get_v4l2_matrix_coefficients(u32 hfi_coefficients)
56 {
57 	switch (hfi_coefficients) {
58 	case HFI_MATRIX_COEFF_RESERVED:
59 		return V4L2_YCBCR_ENC_DEFAULT;
60 	case HFI_MATRIX_COEFF_BT709:
61 		return V4L2_YCBCR_ENC_709;
62 	case HFI_MATRIX_COEFF_BT470_SYS_BG_OR_BT601_625:
63 		return V4L2_YCBCR_ENC_XV601;
64 	case HFI_MATRIX_COEFF_BT601_525_BT1358_525_OR_625:
65 		return V4L2_YCBCR_ENC_601;
66 	case HFI_MATRIX_COEFF_SMPTE_ST240:
67 		return V4L2_YCBCR_ENC_SMPTE240M;
68 	case HFI_MATRIX_COEFF_BT2020_NON_CONSTANT:
69 		return V4L2_YCBCR_ENC_BT2020;
70 	case HFI_MATRIX_COEFF_BT2020_CONSTANT:
71 		return V4L2_YCBCR_ENC_BT2020_CONST_LUM;
72 	default:
73 		return V4L2_YCBCR_ENC_DEFAULT;
74 	}
75 }
76 
iris_hfi_core_init(struct iris_core * core)77 int iris_hfi_core_init(struct iris_core *core)
78 {
79 	const struct iris_hfi_command_ops *hfi_ops = core->hfi_ops;
80 	int ret;
81 
82 	ret = hfi_ops->sys_init(core);
83 	if (ret)
84 		return ret;
85 
86 	ret = hfi_ops->sys_image_version(core);
87 	if (ret)
88 		return ret;
89 
90 	return hfi_ops->sys_interframe_powercollapse(core);
91 }
92 
iris_hfi_isr(int irq,void * data)93 irqreturn_t iris_hfi_isr(int irq, void *data)
94 {
95 	disable_irq_nosync(irq);
96 
97 	return IRQ_WAKE_THREAD;
98 }
99 
iris_hfi_isr_handler(int irq,void * data)100 irqreturn_t iris_hfi_isr_handler(int irq, void *data)
101 {
102 	struct iris_core *core = data;
103 
104 	if (!core)
105 		return IRQ_NONE;
106 
107 	mutex_lock(&core->lock);
108 	pm_runtime_mark_last_busy(core->dev);
109 	iris_vpu_clear_interrupt(core);
110 	mutex_unlock(&core->lock);
111 
112 	core->hfi_response_ops->hfi_response_handler(core);
113 
114 	if (!iris_vpu_watchdog(core, core->intr_status))
115 		enable_irq(irq);
116 
117 	return IRQ_HANDLED;
118 }
119 
iris_hfi_pm_suspend(struct iris_core * core)120 int iris_hfi_pm_suspend(struct iris_core *core)
121 {
122 	int ret;
123 
124 	ret = iris_vpu_prepare_pc(core);
125 	if (ret) {
126 		pm_runtime_mark_last_busy(core->dev);
127 		ret = -EAGAIN;
128 		goto error;
129 	}
130 
131 	ret = iris_set_hw_state(core, false);
132 	if (ret)
133 		goto error;
134 
135 	iris_vpu_power_off(core);
136 
137 	return 0;
138 
139 error:
140 	dev_err(core->dev, "failed to suspend\n");
141 
142 	return ret;
143 }
144 
iris_hfi_pm_resume(struct iris_core * core)145 int iris_hfi_pm_resume(struct iris_core *core)
146 {
147 	const struct iris_hfi_command_ops *ops = core->hfi_ops;
148 	int ret;
149 
150 	ret = iris_vpu_power_on(core);
151 	if (ret)
152 		goto error;
153 
154 	ret = iris_set_hw_state(core, true);
155 	if (ret)
156 		goto err_power_off;
157 
158 	ret = iris_vpu_boot_firmware(core);
159 	if (ret)
160 		goto err_suspend_hw;
161 
162 	ret = ops->sys_interframe_powercollapse(core);
163 	if (ret)
164 		goto err_suspend_hw;
165 
166 	return 0;
167 
168 err_suspend_hw:
169 	iris_set_hw_state(core, false);
170 err_power_off:
171 	iris_vpu_power_off(core);
172 error:
173 	dev_err(core->dev, "failed to resume\n");
174 
175 	return -EBUSY;
176 }
177