1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Support for Intel Camera Imaging ISP subsystem.
4  * Copyright (c) 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 #include "assert_support.h"
19 #include "platform_support.h"
20 #include "ia_css_isys.h"
21 #include "ibuf_ctrl_rmgr.h"
22 
23 static ibuf_rsrc_t	ibuf_rsrc;
24 
getHandle(uint16_t index)25 static ibuf_handle_t *getHandle(uint16_t index)
26 {
27 	ibuf_handle_t *handle = NULL;
28 
29 	if (index < MAX_IBUF_HANDLES)
30 		handle = &ibuf_rsrc.handles[index];
31 	return handle;
32 }
33 
ia_css_isys_ibuf_rmgr_init(void)34 void ia_css_isys_ibuf_rmgr_init(void)
35 {
36 	memset(&ibuf_rsrc, 0, sizeof(ibuf_rsrc));
37 	ibuf_rsrc.free_size = MAX_INPUT_BUFFER_SIZE;
38 }
39 
ia_css_isys_ibuf_rmgr_uninit(void)40 void ia_css_isys_ibuf_rmgr_uninit(void)
41 {
42 	memset(&ibuf_rsrc, 0, sizeof(ibuf_rsrc));
43 	ibuf_rsrc.free_size = MAX_INPUT_BUFFER_SIZE;
44 }
45 
ia_css_isys_ibuf_rmgr_acquire(u32 size,uint32_t * start_addr)46 bool ia_css_isys_ibuf_rmgr_acquire(
47     u32	size,
48     uint32_t	*start_addr)
49 {
50 	bool retval = false;
51 	bool input_buffer_found = false;
52 	u32 aligned_size;
53 	ibuf_handle_t *handle = NULL;
54 	u16 i;
55 
56 	assert(start_addr);
57 	assert(size > 0);
58 
59 	aligned_size = (size + (IBUF_ALIGN - 1)) & ~(IBUF_ALIGN - 1);
60 
61 	/* Check if there is an available un-used handle with the size
62 	 * that will fulfill the request.
63 	 */
64 	if (ibuf_rsrc.num_active < ibuf_rsrc.num_allocated) {
65 		for (i = 0; i < ibuf_rsrc.num_allocated; i++) {
66 			handle = getHandle(i);
67 			if (!handle->active) {
68 				if (handle->size >= aligned_size) {
69 					handle->active = true;
70 					input_buffer_found = true;
71 					ibuf_rsrc.num_active++;
72 					break;
73 				}
74 			}
75 		}
76 	}
77 
78 	if (!input_buffer_found) {
79 		/* There were no available handles that fulfilled the
80 		 * request. Allocate a new handle with the requested size.
81 		 */
82 		if ((ibuf_rsrc.num_allocated < MAX_IBUF_HANDLES) &&
83 		    (ibuf_rsrc.free_size >= aligned_size)) {
84 			handle = getHandle(ibuf_rsrc.num_allocated);
85 			handle->start_addr	= ibuf_rsrc.free_start_addr;
86 			handle->size		= aligned_size;
87 			handle->active		= true;
88 
89 			ibuf_rsrc.free_start_addr += aligned_size;
90 			ibuf_rsrc.free_size -= aligned_size;
91 			ibuf_rsrc.num_active++;
92 			ibuf_rsrc.num_allocated++;
93 
94 			input_buffer_found = true;
95 		}
96 	}
97 
98 	if (input_buffer_found && handle) {
99 		*start_addr = handle->start_addr;
100 		retval = true;
101 	}
102 
103 	return retval;
104 }
105 
ia_css_isys_ibuf_rmgr_release(uint32_t * start_addr)106 void ia_css_isys_ibuf_rmgr_release(
107     uint32_t	*start_addr)
108 {
109 	u16 i;
110 	ibuf_handle_t *handle = NULL;
111 
112 	assert(start_addr);
113 
114 	for (i = 0; i < ibuf_rsrc.num_allocated; i++) {
115 		handle = getHandle(i);
116 		if (handle->active && handle->start_addr == *start_addr) {
117 			handle->active = false;
118 			ibuf_rsrc.num_active--;
119 			break;
120 		}
121 	}
122 }
123