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
23static ibuf_rsrc_t	ibuf_rsrc;
24
25static 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
34void 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
40void 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
46bool 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
106void 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