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 "system_global.h"
8 
9 
10 #include "assert_support.h"
11 #include "platform_support.h"
12 #include "ia_css_isys.h"
13 #include "bitop_support.h"
14 #include "ia_css_pipeline.h"	/* ia_css_pipeline_get_pipe_io_status() */
15 #include "sh_css_internal.h"	/* sh_css_sp_pipeline_io_status
16 				 * SH_CSS_MAX_SP_THREADS
17 				 */
18 #include "csi_rx_rmgr.h"
19 
20 static isys_csi_rx_rsrc_t  isys_csi_rx_rsrc[N_CSI_RX_BACKEND_ID];
21 
ia_css_isys_csi_rx_lut_rmgr_init(void)22 void ia_css_isys_csi_rx_lut_rmgr_init(void)
23 {
24 	memset(isys_csi_rx_rsrc, 0, sizeof(isys_csi_rx_rsrc));
25 }
26 
ia_css_isys_csi_rx_lut_rmgr_uninit(void)27 void ia_css_isys_csi_rx_lut_rmgr_uninit(void)
28 {
29 	memset(isys_csi_rx_rsrc, 0, sizeof(isys_csi_rx_rsrc));
30 }
31 
ia_css_isys_csi_rx_lut_rmgr_acquire(csi_rx_backend_ID_t backend,csi_mipi_packet_type_t packet_type,csi_rx_backend_lut_entry_t * entry)32 bool ia_css_isys_csi_rx_lut_rmgr_acquire(
33     csi_rx_backend_ID_t		backend,
34     csi_mipi_packet_type_t		packet_type,
35     csi_rx_backend_lut_entry_t	*entry)
36 {
37 	bool retval = false;
38 	u32 max_num_packets_of_type;
39 	u32 num_active_of_type;
40 	isys_csi_rx_rsrc_t *cur_rsrc = NULL;
41 	u16 i;
42 
43 	assert(backend < N_CSI_RX_BACKEND_ID);
44 	assert((packet_type == CSI_MIPI_PACKET_TYPE_LONG) ||
45 	       (packet_type == CSI_MIPI_PACKET_TYPE_SHORT));
46 	assert(entry);
47 
48 	if ((backend < N_CSI_RX_BACKEND_ID) && (entry)) {
49 		cur_rsrc = &isys_csi_rx_rsrc[backend];
50 		if (packet_type == CSI_MIPI_PACKET_TYPE_LONG) {
51 			max_num_packets_of_type = N_LONG_PACKET_LUT_ENTRIES[backend];
52 			num_active_of_type = cur_rsrc->num_long_packets;
53 		} else {
54 			max_num_packets_of_type = N_SHORT_PACKET_LUT_ENTRIES[backend];
55 			num_active_of_type = cur_rsrc->num_short_packets;
56 		}
57 
58 		if (num_active_of_type < max_num_packets_of_type) {
59 			for (i = 0; i < max_num_packets_of_type; i++) {
60 				if (bitop_getbit(cur_rsrc->active_table, i) == 0) {
61 					bitop_setbit(cur_rsrc->active_table, i);
62 
63 					if (packet_type == CSI_MIPI_PACKET_TYPE_LONG) {
64 						entry->long_packet_entry = i;
65 						entry->short_packet_entry = 0;
66 						cur_rsrc->num_long_packets++;
67 					} else {
68 						entry->long_packet_entry = 0;
69 						entry->short_packet_entry = i;
70 						cur_rsrc->num_short_packets++;
71 					}
72 					cur_rsrc->num_active++;
73 					retval = true;
74 					break;
75 				}
76 			}
77 		}
78 	}
79 	return retval;
80 }
81 
ia_css_isys_csi_rx_lut_rmgr_release(csi_rx_backend_ID_t backend,csi_mipi_packet_type_t packet_type,csi_rx_backend_lut_entry_t * entry)82 void ia_css_isys_csi_rx_lut_rmgr_release(
83     csi_rx_backend_ID_t		backend,
84     csi_mipi_packet_type_t		packet_type,
85     csi_rx_backend_lut_entry_t	*entry)
86 {
87 	u32 max_num_packets;
88 	isys_csi_rx_rsrc_t *cur_rsrc = NULL;
89 	u32 packet_entry = 0;
90 
91 	assert(backend < N_CSI_RX_BACKEND_ID);
92 	assert(entry);
93 	assert((packet_type >= CSI_MIPI_PACKET_TYPE_LONG) ||
94 	       (packet_type <= CSI_MIPI_PACKET_TYPE_SHORT));
95 
96 	if ((backend < N_CSI_RX_BACKEND_ID) && (entry)) {
97 		if (packet_type == CSI_MIPI_PACKET_TYPE_LONG) {
98 			max_num_packets = N_LONG_PACKET_LUT_ENTRIES[backend];
99 			packet_entry = entry->long_packet_entry;
100 		} else {
101 			max_num_packets = N_SHORT_PACKET_LUT_ENTRIES[backend];
102 			packet_entry = entry->short_packet_entry;
103 		}
104 
105 		cur_rsrc = &isys_csi_rx_rsrc[backend];
106 		if ((packet_entry < max_num_packets) && (cur_rsrc->num_active > 0)) {
107 			if (bitop_getbit(cur_rsrc->active_table, packet_entry) == 1) {
108 				bitop_clearbit(cur_rsrc->active_table, packet_entry);
109 
110 				if (packet_type == CSI_MIPI_PACKET_TYPE_LONG)
111 					cur_rsrc->num_long_packets--;
112 				else
113 					cur_rsrc->num_short_packets--;
114 				cur_rsrc->num_active--;
115 			}
116 		}
117 	}
118 }
119 
ia_css_isys_csi_rx_register_stream(enum mipi_port_id port,uint32_t isys_stream_id)120 int ia_css_isys_csi_rx_register_stream(
121     enum mipi_port_id port,
122     uint32_t isys_stream_id)
123 {
124 	int retval = -EINVAL;
125 
126 	if ((port < N_INPUT_SYSTEM_CSI_PORT) &&
127 	    (isys_stream_id < SH_CSS_MAX_ISYS_CHANNEL_NODES)) {
128 		struct sh_css_sp_pipeline_io_status *pipe_io_status;
129 
130 		pipe_io_status = ia_css_pipeline_get_pipe_io_status();
131 		if (bitop_getbit(pipe_io_status->active[port], isys_stream_id) == 0) {
132 			bitop_setbit(pipe_io_status->active[port], isys_stream_id);
133 			pipe_io_status->running[port] = 0;
134 			retval = 0;
135 		}
136 	}
137 	return retval;
138 }
139 
ia_css_isys_csi_rx_unregister_stream(enum mipi_port_id port,uint32_t isys_stream_id)140 int ia_css_isys_csi_rx_unregister_stream(
141     enum mipi_port_id port,
142     uint32_t isys_stream_id)
143 {
144 	int retval = -EINVAL;
145 
146 	if ((port < N_INPUT_SYSTEM_CSI_PORT) &&
147 	    (isys_stream_id < SH_CSS_MAX_ISYS_CHANNEL_NODES)) {
148 		struct sh_css_sp_pipeline_io_status *pipe_io_status;
149 
150 		pipe_io_status = ia_css_pipeline_get_pipe_io_status();
151 		if (bitop_getbit(pipe_io_status->active[port], isys_stream_id) == 1) {
152 			bitop_clearbit(pipe_io_status->active[port], isys_stream_id);
153 			retval = 0;
154 		}
155 	}
156 	return retval;
157 }
158