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  * This program is free software; you can redistribute it and/or modify it
7  * under the terms and conditions of the GNU General Public License,
8  * version 2, as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13  * more details.
14  */
15 
16 #include "system_global.h"
17 
18 #ifdef ISP2401
19 
20 #include "assert_support.h"
21 #include "platform_support.h"
22 #include "ia_css_isys.h"
23 #include "bitop_support.h"
24 #include "ia_css_pipeline.h"	/* ia_css_pipeline_get_pipe_io_status() */
25 #include "sh_css_internal.h"	/* sh_css_sp_pipeline_io_status
26 				 * SH_CSS_MAX_SP_THREADS
27 				 */
28 #include "csi_rx_rmgr.h"
29 
30 static isys_csi_rx_rsrc_t  isys_csi_rx_rsrc[N_CSI_RX_BACKEND_ID];
31 
32 void ia_css_isys_csi_rx_lut_rmgr_init(void)
33 {
34 	memset(isys_csi_rx_rsrc, 0, sizeof(isys_csi_rx_rsrc));
35 }
36 
37 void ia_css_isys_csi_rx_lut_rmgr_uninit(void)
38 {
39 	memset(isys_csi_rx_rsrc, 0, sizeof(isys_csi_rx_rsrc));
40 }
41 
42 bool ia_css_isys_csi_rx_lut_rmgr_acquire(
43     csi_rx_backend_ID_t		backend,
44     csi_mipi_packet_type_t		packet_type,
45     csi_rx_backend_lut_entry_t	*entry)
46 {
47 	bool retval = false;
48 	u32 max_num_packets_of_type;
49 	u32 num_active_of_type;
50 	isys_csi_rx_rsrc_t *cur_rsrc = NULL;
51 	u16 i;
52 
53 	assert(backend < N_CSI_RX_BACKEND_ID);
54 	assert((packet_type == CSI_MIPI_PACKET_TYPE_LONG) ||
55 	       (packet_type == CSI_MIPI_PACKET_TYPE_SHORT));
56 	assert(entry);
57 
58 	if ((backend < N_CSI_RX_BACKEND_ID) && (entry)) {
59 		cur_rsrc = &isys_csi_rx_rsrc[backend];
60 		if (packet_type == CSI_MIPI_PACKET_TYPE_LONG) {
61 			max_num_packets_of_type = N_LONG_PACKET_LUT_ENTRIES[backend];
62 			num_active_of_type = cur_rsrc->num_long_packets;
63 		} else {
64 			max_num_packets_of_type = N_SHORT_PACKET_LUT_ENTRIES[backend];
65 			num_active_of_type = cur_rsrc->num_short_packets;
66 		}
67 
68 		if (num_active_of_type < max_num_packets_of_type) {
69 			for (i = 0; i < max_num_packets_of_type; i++) {
70 				if (bitop_getbit(cur_rsrc->active_table, i) == 0) {
71 					bitop_setbit(cur_rsrc->active_table, i);
72 
73 					if (packet_type == CSI_MIPI_PACKET_TYPE_LONG) {
74 						entry->long_packet_entry = i;
75 						entry->short_packet_entry = 0;
76 						cur_rsrc->num_long_packets++;
77 					} else {
78 						entry->long_packet_entry = 0;
79 						entry->short_packet_entry = i;
80 						cur_rsrc->num_short_packets++;
81 					}
82 					cur_rsrc->num_active++;
83 					retval = true;
84 					break;
85 				}
86 			}
87 		}
88 	}
89 	return retval;
90 }
91 
92 void ia_css_isys_csi_rx_lut_rmgr_release(
93     csi_rx_backend_ID_t		backend,
94     csi_mipi_packet_type_t		packet_type,
95     csi_rx_backend_lut_entry_t	*entry)
96 {
97 	u32 max_num_packets;
98 	isys_csi_rx_rsrc_t *cur_rsrc = NULL;
99 	u32 packet_entry = 0;
100 
101 	assert(backend < N_CSI_RX_BACKEND_ID);
102 	assert(entry);
103 	assert((packet_type >= CSI_MIPI_PACKET_TYPE_LONG) ||
104 	       (packet_type <= CSI_MIPI_PACKET_TYPE_SHORT));
105 
106 	if ((backend < N_CSI_RX_BACKEND_ID) && (entry)) {
107 		if (packet_type == CSI_MIPI_PACKET_TYPE_LONG) {
108 			max_num_packets = N_LONG_PACKET_LUT_ENTRIES[backend];
109 			packet_entry = entry->long_packet_entry;
110 		} else {
111 			max_num_packets = N_SHORT_PACKET_LUT_ENTRIES[backend];
112 			packet_entry = entry->short_packet_entry;
113 		}
114 
115 		cur_rsrc = &isys_csi_rx_rsrc[backend];
116 		if ((packet_entry < max_num_packets) && (cur_rsrc->num_active > 0)) {
117 			if (bitop_getbit(cur_rsrc->active_table, packet_entry) == 1) {
118 				bitop_clearbit(cur_rsrc->active_table, packet_entry);
119 
120 				if (packet_type == CSI_MIPI_PACKET_TYPE_LONG)
121 					cur_rsrc->num_long_packets--;
122 				else
123 					cur_rsrc->num_short_packets--;
124 				cur_rsrc->num_active--;
125 			}
126 		}
127 	}
128 }
129 
130 int ia_css_isys_csi_rx_register_stream(
131     enum mipi_port_id port,
132     uint32_t isys_stream_id)
133 {
134 	int retval = -EINVAL;
135 
136 	if ((port < N_INPUT_SYSTEM_CSI_PORT) &&
137 	    (isys_stream_id < SH_CSS_MAX_ISYS_CHANNEL_NODES)) {
138 		struct sh_css_sp_pipeline_io_status *pipe_io_status;
139 
140 		pipe_io_status = ia_css_pipeline_get_pipe_io_status();
141 		if (bitop_getbit(pipe_io_status->active[port], isys_stream_id) == 0) {
142 			bitop_setbit(pipe_io_status->active[port], isys_stream_id);
143 			pipe_io_status->running[port] = 0;
144 			retval = 0;
145 		}
146 	}
147 	return retval;
148 }
149 
150 int ia_css_isys_csi_rx_unregister_stream(
151     enum mipi_port_id port,
152     uint32_t isys_stream_id)
153 {
154 	int retval = -EINVAL;
155 
156 	if ((port < N_INPUT_SYSTEM_CSI_PORT) &&
157 	    (isys_stream_id < SH_CSS_MAX_ISYS_CHANNEL_NODES)) {
158 		struct sh_css_sp_pipeline_io_status *pipe_io_status;
159 
160 		pipe_io_status = ia_css_pipeline_get_pipe_io_status();
161 		if (bitop_getbit(pipe_io_status->active[port], isys_stream_id) == 1) {
162 			bitop_clearbit(pipe_io_status->active[port], isys_stream_id);
163 			retval = 0;
164 		}
165 	}
166 	return retval;
167 }
168 #endif
169