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