/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Copyright (C) 2023 MediaTek Inc.
 *
 */

#ifndef __MTK_SEC_HEAP_CMA_HELPER_H__
#define __MTK_SEC_HEAP_CMA_HELPER_H__

/*
 * This helper can help to alloc buffer from reserved CMA memory efficiently.
 *
 * Brief introduce:
 * The reserved memory will be divided into several blocks(CMA_BLOCKS_MAX_NUM).
 * The variable "holded_size" will be checked every time allocate a buffer.
 * If "holded_size" is not enough for this allocation, some of those blocks
 * will be migrated from kernel to secure CMA dma_heap and maintained by
 * gen_pool. Besides, all blocks will be free back to kernel only when the
 * last buffer was released.
 */

enum MTK_CMA_MEMORY_ID {
	MTK_CMA_MEM_INV = -1,
	MTK_CMA_MEM_SVP = 0,
	MTK_CMA_MEM_NUM,
};

struct mtk_sec_heap_mem_info {
	enum MTK_CMA_MEMORY_ID	cma_mem_id;
	phys_addr_t		cma_mem_start;
	phys_addr_t		cma_mem_size;
	uint32_t		cma_block_size;
	uint32_t		cma_block_count;
};

int mtk_secure_heap_cma_query_mem_info(struct device *dev,
				       struct mtk_sec_heap_mem_info *info);

int mtk_secure_heap_cma_query_block_mask(enum MTK_CMA_MEMORY_ID mem_id,
					 uint32_t *holded_block_mask);

int mtk_secure_heap_cma_hold_blocks(enum MTK_CMA_MEMORY_ID mem_id,
				    unsigned int pagecnt);

void mtk_secure_heap_cma_free_blocks_all(enum MTK_CMA_MEMORY_ID mem_id);

struct page *mtk_secure_heap_cma_alloc_pages(enum MTK_CMA_MEMORY_ID mem_id,
					     unsigned int pagecount,
					     unsigned int align_size);

void mtk_secure_heap_cma_release_pages(enum MTK_CMA_MEMORY_ID mem_id,
				       struct page *pages,
				       unsigned int pagecount);

#endif /* __MTK_SEC_HEAP_CMA_HELPER_H__ */
