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
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
29static isys_csi_rx_rsrc_t  isys_csi_rx_rsrc[N_CSI_RX_BACKEND_ID];
30
31void ia_css_isys_csi_rx_lut_rmgr_init(void)
32{
33	memset(isys_csi_rx_rsrc, 0, sizeof(isys_csi_rx_rsrc));
34}
35
36void ia_css_isys_csi_rx_lut_rmgr_uninit(void)
37{
38	memset(isys_csi_rx_rsrc, 0, sizeof(isys_csi_rx_rsrc));
39}
40
41bool 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
91void 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
129int 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
149int 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