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