1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Support for Intel Camera Imaging ISP subsystem.
4  * Copyright (c) 2010-2015, Intel Corporation.
5  */
6 
7 #include "assert_support.h"
8 #include "irq.h"
9 
10 #ifndef __INLINE_GP_DEVICE__
11 #define __INLINE_GP_DEVICE__
12 #endif
13 #include "gp_device.h"	/* _REG_GP_IRQ_REQUEST_ADDR */
14 
15 static inline void irq_wait_for_write_complete(
16     const irq_ID_t		ID);
17 
18 static inline bool any_irq_channel_enabled(
19     const irq_ID_t				ID);
20 
21 static inline irq_ID_t virq_get_irq_id(const enum virq_id irq_ID,
22 				       unsigned int *channel_ID);
23 
24 #ifndef __INLINE_IRQ__
25 #include "irq_private.h"
26 #endif /* __INLINE_IRQ__ */
27 
28 static unsigned short IRQ_N_CHANNEL[N_IRQ_ID] = {
29 	IRQ0_ID_N_CHANNEL,
30 	IRQ1_ID_N_CHANNEL,
31 	IRQ2_ID_N_CHANNEL,
32 	IRQ3_ID_N_CHANNEL
33 };
34 
35 static unsigned short IRQ_N_ID_OFFSET[N_IRQ_ID + 1] = {
36 	IRQ0_ID_OFFSET,
37 	IRQ1_ID_OFFSET,
38 	IRQ2_ID_OFFSET,
39 	IRQ3_ID_OFFSET,
40 	IRQ_END_OFFSET
41 };
42 
43 static enum virq_id IRQ_NESTING_ID[N_IRQ_ID] = {
44 	N_virq_id,
45 	virq_ifmt,
46 	virq_isys,
47 	virq_isel
48 };
49 
irq_clear_all(const irq_ID_t ID)50 void irq_clear_all(
51     const irq_ID_t				ID)
52 {
53 	hrt_data	mask = 0xFFFFFFFF;
54 
55 	assert(ID < N_IRQ_ID);
56 	assert(IRQ_N_CHANNEL[ID] <= HRT_DATA_WIDTH);
57 
58 	if (IRQ_N_CHANNEL[ID] < HRT_DATA_WIDTH) {
59 		mask = ~((~(hrt_data)0) >> IRQ_N_CHANNEL[ID]);
60 	}
61 
62 	irq_reg_store(ID,
63 		      _HRT_IRQ_CONTROLLER_CLEAR_REG_IDX, mask);
64 	return;
65 }
66 
67 /*
68  * Do we want the user to be able to set the signalling method ?
69  */
irq_enable_channel(const irq_ID_t ID,const unsigned int irq_id)70 void irq_enable_channel(
71     const irq_ID_t				ID,
72     const unsigned int			irq_id)
73 {
74 	unsigned int mask = irq_reg_load(ID,
75 					 _HRT_IRQ_CONTROLLER_MASK_REG_IDX);
76 	unsigned int enable = irq_reg_load(ID,
77 					   _HRT_IRQ_CONTROLLER_ENABLE_REG_IDX);
78 	unsigned int edge_in = irq_reg_load(ID,
79 					    _HRT_IRQ_CONTROLLER_EDGE_REG_IDX);
80 	unsigned int me = 1U << irq_id;
81 
82 	assert(ID < N_IRQ_ID);
83 	assert(irq_id < IRQ_N_CHANNEL[ID]);
84 
85 	mask |= me;
86 	enable |= me;
87 	edge_in |= me;	/* rising edge */
88 
89 	/* to avoid mishaps configuration must follow the following order */
90 
91 	/* mask this interrupt */
92 	irq_reg_store(ID,
93 		      _HRT_IRQ_CONTROLLER_MASK_REG_IDX, mask & ~me);
94 	/* rising edge at input */
95 	irq_reg_store(ID,
96 		      _HRT_IRQ_CONTROLLER_EDGE_REG_IDX, edge_in);
97 	/* enable interrupt to output */
98 	irq_reg_store(ID,
99 		      _HRT_IRQ_CONTROLLER_ENABLE_REG_IDX, enable);
100 	/* clear current irq only */
101 	irq_reg_store(ID,
102 		      _HRT_IRQ_CONTROLLER_CLEAR_REG_IDX, me);
103 	/* unmask interrupt from input */
104 	irq_reg_store(ID,
105 		      _HRT_IRQ_CONTROLLER_MASK_REG_IDX, mask);
106 
107 	irq_wait_for_write_complete(ID);
108 
109 	return;
110 }
111 
irq_enable_pulse(const irq_ID_t ID,bool pulse)112 void irq_enable_pulse(
113     const irq_ID_t	ID,
114     bool			pulse)
115 {
116 	unsigned int edge_out = 0x0;
117 
118 	if (pulse) {
119 		edge_out = 0xffffffff;
120 	}
121 	/* output is given as edge, not pulse */
122 	irq_reg_store(ID,
123 		      _HRT_IRQ_CONTROLLER_EDGE_NOT_PULSE_REG_IDX, edge_out);
124 	return;
125 }
126 
irq_disable_channel(const irq_ID_t ID,const unsigned int irq_id)127 void irq_disable_channel(
128     const irq_ID_t				ID,
129     const unsigned int			irq_id)
130 {
131 	unsigned int mask = irq_reg_load(ID,
132 					 _HRT_IRQ_CONTROLLER_MASK_REG_IDX);
133 	unsigned int enable = irq_reg_load(ID,
134 					   _HRT_IRQ_CONTROLLER_ENABLE_REG_IDX);
135 	unsigned int me = 1U << irq_id;
136 
137 	assert(ID < N_IRQ_ID);
138 	assert(irq_id < IRQ_N_CHANNEL[ID]);
139 
140 	mask &= ~me;
141 	enable &= ~me;
142 
143 	/* enable interrupt to output */
144 	irq_reg_store(ID,
145 		      _HRT_IRQ_CONTROLLER_ENABLE_REG_IDX, enable);
146 	/* unmask interrupt from input */
147 	irq_reg_store(ID,
148 		      _HRT_IRQ_CONTROLLER_MASK_REG_IDX, mask);
149 	/* clear current irq only */
150 	irq_reg_store(ID,
151 		      _HRT_IRQ_CONTROLLER_CLEAR_REG_IDX, me);
152 
153 	irq_wait_for_write_complete(ID);
154 
155 	return;
156 }
157 
irq_get_channel_id(const irq_ID_t ID,unsigned int * irq_id)158 enum hrt_isp_css_irq_status irq_get_channel_id(
159     const irq_ID_t				ID,
160     unsigned int				*irq_id)
161 {
162 	unsigned int irq_status = irq_reg_load(ID,
163 					       _HRT_IRQ_CONTROLLER_STATUS_REG_IDX);
164 	unsigned int idx;
165 	enum hrt_isp_css_irq_status status = hrt_isp_css_irq_status_success;
166 
167 	assert(ID < N_IRQ_ID);
168 	assert(irq_id);
169 
170 	/* find the first irq bit */
171 	for (idx = 0; idx < IRQ_N_CHANNEL[ID]; idx++) {
172 		if (irq_status & (1U << idx))
173 			break;
174 	}
175 	if (idx == IRQ_N_CHANNEL[ID])
176 		return hrt_isp_css_irq_status_error;
177 
178 	/* now check whether there are more bits set */
179 	if (irq_status != (1U << idx))
180 		status = hrt_isp_css_irq_status_more_irqs;
181 
182 	irq_reg_store(ID,
183 		      _HRT_IRQ_CONTROLLER_CLEAR_REG_IDX, 1U << idx);
184 
185 	irq_wait_for_write_complete(ID);
186 
187 	if (irq_id)
188 		*irq_id = (unsigned int)idx;
189 
190 	return status;
191 }
192 
193 static const hrt_address IRQ_REQUEST_ADDR[N_IRQ_SW_CHANNEL_ID] = {
194 	_REG_GP_IRQ_REQUEST0_ADDR,
195 	_REG_GP_IRQ_REQUEST1_ADDR
196 };
197 
irq_raise(const irq_ID_t ID,const irq_sw_channel_id_t irq_id)198 void irq_raise(
199     const irq_ID_t				ID,
200     const irq_sw_channel_id_t	irq_id)
201 {
202 	hrt_address		addr;
203 
204 	OP___assert(ID == IRQ0_ID);
205 	OP___assert(IRQ_BASE[ID] != (hrt_address)-1);
206 	OP___assert(irq_id < N_IRQ_SW_CHANNEL_ID);
207 
208 	(void)ID;
209 
210 	addr = IRQ_REQUEST_ADDR[irq_id];
211 	/* The SW IRQ pins are remapped to offset zero */
212 	gp_device_reg_store(GP_DEVICE0_ID,
213 			    (unsigned int)addr, 1);
214 	gp_device_reg_store(GP_DEVICE0_ID,
215 			    (unsigned int)addr, 0);
216 	return;
217 }
218 
any_virq_signal(void)219 bool any_virq_signal(void)
220 {
221 	unsigned int irq_status = irq_reg_load(IRQ0_ID,
222 					       _HRT_IRQ_CONTROLLER_STATUS_REG_IDX);
223 
224 	return (irq_status != 0);
225 }
226 
cnd_virq_enable_channel(const enum virq_id irq_ID,const bool en)227 void cnd_virq_enable_channel(
228     const enum virq_id				irq_ID,
229     const bool					en)
230 {
231 	irq_ID_t		i;
232 	unsigned int	channel_ID;
233 	irq_ID_t		ID = virq_get_irq_id(irq_ID, &channel_ID);
234 
235 	assert(ID < N_IRQ_ID);
236 
237 	for (i = IRQ1_ID; i < N_IRQ_ID; i++) {
238 		/* It is not allowed to enable the pin of a nested IRQ directly */
239 		assert(irq_ID != IRQ_NESTING_ID[i]);
240 	}
241 
242 	if (en) {
243 		irq_enable_channel(ID, channel_ID);
244 		if (IRQ_NESTING_ID[ID] != N_virq_id) {
245 			/* Single level nesting, otherwise we'd need to recurse */
246 			irq_enable_channel(IRQ0_ID, IRQ_NESTING_ID[ID]);
247 		}
248 	} else {
249 		irq_disable_channel(ID, channel_ID);
250 		if ((IRQ_NESTING_ID[ID] != N_virq_id) && !any_irq_channel_enabled(ID)) {
251 			/* Only disable the top if the nested ones are empty */
252 			irq_disable_channel(IRQ0_ID, IRQ_NESTING_ID[ID]);
253 		}
254 	}
255 	return;
256 }
257 
virq_clear_all(void)258 void virq_clear_all(void)
259 {
260 	irq_ID_t	irq_id;
261 
262 	for (irq_id = (irq_ID_t)0; irq_id < N_IRQ_ID; irq_id++) {
263 		irq_clear_all(irq_id);
264 	}
265 	return;
266 }
267 
268 enum hrt_isp_css_irq_status
virq_get_channel_signals(struct virq_info * irq_info)269 virq_get_channel_signals(struct virq_info *irq_info)
270 {
271 	enum hrt_isp_css_irq_status irq_status = hrt_isp_css_irq_status_error;
272 	irq_ID_t ID;
273 
274 	assert(irq_info);
275 
276 	for (ID = (irq_ID_t)0 ; ID < N_IRQ_ID; ID++) {
277 		if (any_irq_channel_enabled(ID)) {
278 			hrt_data	irq_data = irq_reg_load(ID,
279 							    _HRT_IRQ_CONTROLLER_STATUS_REG_IDX);
280 
281 			if (irq_data != 0) {
282 				/* The error condition is an IRQ pulse received with no IRQ status written */
283 				irq_status = hrt_isp_css_irq_status_success;
284 			}
285 
286 			irq_info->irq_status_reg[ID] |= irq_data;
287 
288 			irq_reg_store(ID,
289 				      _HRT_IRQ_CONTROLLER_CLEAR_REG_IDX, irq_data);
290 
291 			irq_wait_for_write_complete(ID);
292 		}
293 	}
294 
295 	return irq_status;
296 }
297 
virq_clear_info(struct virq_info * irq_info)298 void virq_clear_info(struct virq_info *irq_info)
299 {
300 	irq_ID_t ID;
301 
302 	assert(irq_info);
303 
304 	for (ID = (irq_ID_t)0 ; ID < N_IRQ_ID; ID++) {
305 		irq_info->irq_status_reg[ID] = 0;
306 	}
307 	return;
308 }
309 
virq_get_channel_id(enum virq_id * irq_id)310 enum hrt_isp_css_irq_status virq_get_channel_id(
311     enum virq_id					*irq_id)
312 {
313 	unsigned int irq_status = irq_reg_load(IRQ0_ID,
314 					       _HRT_IRQ_CONTROLLER_STATUS_REG_IDX);
315 	unsigned int idx;
316 	enum hrt_isp_css_irq_status status = hrt_isp_css_irq_status_success;
317 	irq_ID_t ID;
318 
319 	assert(irq_id);
320 
321 	/* find the first irq bit on device 0 */
322 	for (idx = 0; idx < IRQ_N_CHANNEL[IRQ0_ID]; idx++) {
323 		if (irq_status & (1U << idx))
324 			break;
325 	}
326 
327 	if (idx == IRQ_N_CHANNEL[IRQ0_ID]) {
328 		return hrt_isp_css_irq_status_error;
329 	}
330 
331 	/* Check whether there are more bits set on device 0 */
332 	if (irq_status != (1U << idx)) {
333 		status = hrt_isp_css_irq_status_more_irqs;
334 	}
335 
336 	/* Check whether we have an IRQ on one of the nested devices */
337 	for (ID = N_IRQ_ID - 1 ; ID > (irq_ID_t)0; ID--) {
338 		if (IRQ_NESTING_ID[ID] == (enum virq_id)idx) {
339 			break;
340 		}
341 	}
342 
343 	/* If we have a nested IRQ, load that state, discard the device 0 state */
344 	if (ID != IRQ0_ID) {
345 		irq_status = irq_reg_load(ID,
346 					  _HRT_IRQ_CONTROLLER_STATUS_REG_IDX);
347 		/* find the first irq bit on device "id" */
348 		for (idx = 0; idx < IRQ_N_CHANNEL[ID]; idx++) {
349 			if (irq_status & (1U << idx))
350 				break;
351 		}
352 
353 		if (idx == IRQ_N_CHANNEL[ID]) {
354 			return hrt_isp_css_irq_status_error;
355 		}
356 
357 		/* Alternatively check whether there are more bits set on this device */
358 		if (irq_status != (1U << idx)) {
359 			status = hrt_isp_css_irq_status_more_irqs;
360 		} else {
361 			/* If this device is empty, clear the state on device 0 */
362 			irq_reg_store(IRQ0_ID,
363 				      _HRT_IRQ_CONTROLLER_CLEAR_REG_IDX, 1U << IRQ_NESTING_ID[ID]);
364 		}
365 	} /* if (ID != IRQ0_ID) */
366 
367 	/* Here we proceed to clear the IRQ on detected device, if no nested IRQ, this is device 0 */
368 	irq_reg_store(ID,
369 		      _HRT_IRQ_CONTROLLER_CLEAR_REG_IDX, 1U << idx);
370 
371 	irq_wait_for_write_complete(ID);
372 
373 	idx += IRQ_N_ID_OFFSET[ID];
374 	if (irq_id)
375 		*irq_id = (enum virq_id)idx;
376 
377 	return status;
378 }
379 
irq_wait_for_write_complete(const irq_ID_t ID)380 static inline void irq_wait_for_write_complete(
381     const irq_ID_t		ID)
382 {
383 	assert(ID < N_IRQ_ID);
384 	assert(IRQ_BASE[ID] != (hrt_address)-1);
385 	(void)ia_css_device_load_uint32(IRQ_BASE[ID] +
386 					_HRT_IRQ_CONTROLLER_ENABLE_REG_IDX * sizeof(hrt_data));
387 }
388 
any_irq_channel_enabled(const irq_ID_t ID)389 static inline bool any_irq_channel_enabled(
390     const irq_ID_t				ID)
391 {
392 	hrt_data	en_reg;
393 
394 	assert(ID < N_IRQ_ID);
395 
396 	en_reg = irq_reg_load(ID,
397 			      _HRT_IRQ_CONTROLLER_ENABLE_REG_IDX);
398 
399 	return (en_reg != 0);
400 }
401 
virq_get_irq_id(const enum virq_id irq_ID,unsigned int * channel_ID)402 static inline irq_ID_t virq_get_irq_id(
403     const enum virq_id		irq_ID,
404     unsigned int		*channel_ID)
405 {
406 	irq_ID_t ID;
407 
408 	assert(channel_ID);
409 
410 	for (ID = (irq_ID_t)0 ; ID < N_IRQ_ID; ID++) {
411 		if (irq_ID < IRQ_N_ID_OFFSET[ID + 1]) {
412 			break;
413 		}
414 	}
415 
416 	*channel_ID = (unsigned int)irq_ID - IRQ_N_ID_OFFSET[ID];
417 
418 	return ID;
419 }
420