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