kernel_samsung_a53x/drivers/vision3/dsp/dl/dsp-pm-manager.c
2024-06-15 16:02:09 -03:00

185 lines
3.9 KiB
C
Executable file

// SPDX-License-Identifier: GPL-2.0
/*
* Samsung Exynos SoC series dsp driver
*
* Copyright (c) 2019 Samsung Electronics Co., Ltd.
* http://www.samsung.com/
*/
#include "dl/dsp-pm-manager.h"
#include "dl/dsp-tlsf-allocator.h"
#include "dl/dsp-lib-manager.h"
#define DL_PM_ALIGN (64)
static struct dsp_tlsf *pm_manager;
static unsigned long dsp_pm_start_addr;
static size_t dsp_pm_total_size;
static struct dsp_lib *pm_init_lib;
unsigned long dsp_pm_manager_get_pm_start_addr(void)
{
return dsp_pm_start_addr;
}
size_t dsp_pm_manager_get_pm_total_size(void)
{
return dsp_pm_total_size;
}
int dsp_pm_manager_init(unsigned long start_addr, size_t size,
unsigned int pm_offset)
{
int ret;
struct dsp_tlsf_mem *init_mem;
DL_DEBUG("PM manager init\n");
pm_manager = (struct dsp_tlsf *)dsp_dl_malloc(
sizeof(struct dsp_tlsf),
"PM manager");
pm_init_lib = (struct dsp_lib *)dsp_dl_malloc(
sizeof(struct dsp_lib),
"PM Boot lib");
dsp_pm_start_addr = start_addr;
dsp_pm_total_size = size;
ret = dsp_tlsf_init(pm_manager, start_addr, size, DL_PM_ALIGN);
if (ret == -1) {
DL_ERROR("TLSF init is failed\n");
dsp_dl_free(pm_manager);
dsp_dl_free(pm_init_lib);
return -1;
}
DL_DEBUG("PM init mem size : %u\n", pm_offset);
ret = dsp_tlsf_malloc(pm_offset, &init_mem, pm_manager);
if (ret == -1) {
DL_ERROR("[%s] CHK_ERR\n", __func__);
dsp_dl_free(pm_manager);
dsp_dl_free(pm_init_lib);
return -1;
}
pm_init_lib->name = (char *)dsp_dl_malloc(
strlen("Boot/main pm") + 1,
"Boot/main pm");
strcpy(pm_init_lib->name, "Boot/main pm");
pm_init_lib->ref_cnt = 1;
pm_init_lib->loaded = 1;
init_mem->lib = pm_init_lib;
return 0;
}
void dsp_pm_manager_free(void)
{
dsp_tlsf_delete(pm_manager);
dsp_dl_free(pm_manager);
dsp_dl_free(pm_init_lib->name);
dsp_dl_free(pm_init_lib);
}
void dsp_pm_manager_print(void)
{
DL_INFO(DL_BORDER);
DL_INFO("Program memory manager\n");
DL_INFO("Start address: %#lx, size %#zx\n",
dsp_pm_start_addr, dsp_pm_total_size);
DL_INFO("\n");
dsp_tlsf_print(pm_manager);
}
int dsp_pm_manager_alloc_libs(struct dsp_lib **libs, int libs_size,
int *pm_inv)
{
int ret, idx;
DL_DEBUG("Alloc PM\n");
*pm_inv = 0;
for (idx = 0; idx < libs_size; idx++) {
if (!libs[idx]->pm) {
size_t text_size;
DL_DEBUG("Alloc PM for library %s\n",
libs[idx]->name);
text_size = dsp_elf32_get_text_size(libs[idx]->elf);
DL_DEBUG("PM alloc libs_size : %zu\n", text_size);
ret = dsp_pm_alloc(text_size, libs[idx], pm_inv);
if (ret == -1) {
DL_ERROR("PM manager allocation failed\n");
return -1;
}
}
}
return 0;
}
int dsp_pm_alloc(size_t size, struct dsp_lib *lib,
int *pm_inv)
{
int alloc_ret;
if (!lib) {
DL_ERROR("struct dsp_lib is null\n");
return -1;
}
DL_DEBUG("Allocate PM pm for lib %s(size : %zu)\n",
lib->name, size);
alloc_ret = dsp_tlsf_malloc(size, &lib->pm, pm_manager);
if (alloc_ret == -1) {
if (dsp_tlsf_can_be_loaded(pm_manager, size)) {
DL_INFO("PM I-cache invalidation set\n");
dsp_lib_manager_delete_no_ref();
*pm_inv = 1;
return dsp_pm_alloc(size, lib, pm_inv);
}
DL_ERROR("Can not be loaded\n");
return -1;
}
DL_DEBUG("Lib(%s) allocation success\n", lib->name);
lib->pm->lib = lib;
return 0;
}
void dsp_pm_free(struct dsp_lib *lib)
{
if (lib->pm) {
//DL_DEBUG("PM free for %s\n", lib->info->name);
dsp_tlsf_free(lib->pm, pm_manager);
lib->pm = NULL;
}
}
void dsp_pm_print(struct dsp_lib *lib)
{
unsigned int *text = (unsigned int *)lib->pm->start_addr;
unsigned long offset = ((unsigned long)text - dsp_pm_start_addr) / 4;
unsigned int idx;
for (idx = 0; idx < lib->pm->size / sizeof(unsigned int);
idx++, offset++) {
if (idx % 4 == 0) {
if (idx != 0) {
DL_BUF_STR("\n");
DL_PRINT_BUF(DEBUG);
}
DL_BUF_STR("0x%lx : ", offset);
}
DL_BUF_STR("0x");
DL_BUF_STR("%08x ", *(unsigned int *)(text + idx));
}
DL_BUF_STR("\n");
DL_PRINT_BUF(DEBUG);
}