Files
android/drivers/misc/mediatek/apusys/mem/1.0/mdla_ion.c
T
threeeye bc1d038eac REVVL 6 Pro kernel bring-up: full working tree snapshot (2026-09-12)
Squashed backup commit (no shallow-clone history issues) of
xiaomi-mt6833-dev/kernel_xiaomi_mt6833 (lineage-23.2 branch, upstream
commit 9eece662e) plus all fixes applied to get everpal_defconfig building
clean against a modern (GCC 15.2.0) toolchain -- see the previous commit
message on the lineage-23.2 branch (also in this repo history is not
available here since this is a squashed snapshot; full incremental history
lives in the local DL380 checkout and the upstream GitHub remote).

Upstream: https://github.com/xiaomi-mt6833-dev/kernel_xiaomi_mt6833 (lineage-23.2)
2026-09-12 13:36:46 +00:00

167 lines
4.2 KiB
C

/*
* Copyright (C) 2018 MediaTek Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/types.h>
#include <ion.h>
#include <mtk/ion_drv.h>
#include <mtk/mtk_ion.h>
#include <linux/uaccess.h>
#include <linux/err.h>
#include "mdla_ioctl.h"
#include "mdla.h"
#include "mdla_ion.h"
#include "mdla_debug.h"
#ifdef CONFIG_MTK_MDLA_ION
//#include <m4u.h>
static struct ion_client *ion_client;
void mdla_ion_init(void)
{
ion_client = ion_client_create(g_ion_device, "mdla");
mdla_drv_debug("%s: ion_client_create(): %p\n", __func__, ion_client);
}
void mdla_ion_exit(void)
{
if (ion_client) {
mdla_drv_debug("%s: %p\n", __func__, ion_client);
ion_client_destroy(ion_client);
ion_client = NULL;
}
}
int mdla_ion_kmap(unsigned long arg)
{
struct ioctl_ion ion_data;
struct ion_mm_data mm_data;
struct ion_handle *hndl;
void *kva;
int ret;
if (!ion_client)
return -ENOENT;
if (copy_from_user(&ion_data, (void * __user) arg, sizeof(ion_data)))
return -EFAULT;
mdla_mem_debug("%s: share fd: %d\n", __func__, ion_data.fd);
hndl = ion_import_dma_buf_fd(ion_client, ion_data.fd);
if (IS_ERR_OR_NULL(hndl)) {
mdla_mem_debug("%s: ion_import_dma_buf_fd(): failed: %ld\n",
__func__, PTR_ERR(hndl));
return -EINVAL;
}
mdla_mem_debug("%s: ion_import_dma_buf_fd(): %p\n", __func__, hndl);
/* use get_iova replace config_buffer & get_phys*/
memset((void *)&mm_data, 0, sizeof(struct ion_mm_data));
mm_data.mm_cmd = ION_MM_GET_IOVA;
mm_data.get_phys_param.kernel_handle = hndl;
// mm_data.get_phys_param.module_id = M4U_PORT_VPU;
mm_data.get_phys_param.len = ion_data.len;
ret = ion_kernel_ioctl(ion_client, ION_CMD_MULTIMEDIA,
(unsigned long) &mm_data);
if (ret < 0) {
mdla_mem_debug("%s: ion_phys(%p, %p): %d\n",
__func__, ion_client, hndl, ret);
return -EINVAL;
}
/* map to to kernel virtual address */
kva = ion_map_kernel(ion_client, hndl);
if (IS_ERR_OR_NULL(kva)) {
mdla_mem_debug("%s: ion_map_kernel(%p, %p): %d\n",
__func__, ion_client, hndl, ret);
return -EINVAL;
}
ion_data.kva = (__u64) kva;
ion_data.mva = mm_data.get_phys_param.phy_addr;
ion_data.khandle = (__u64) hndl;
ion_data.len = mm_data.get_phys_param.len;
if (copy_to_user((void * __user) arg, &ion_data, sizeof(ion_data)))
return -EFAULT;
mdla_mem_debug("%s: mva=%llxh, kva=%llxh, kernel_handle=%llxh\n",
__func__, ion_data.mva, ion_data.kva, ion_data.khandle);
return 0;
}
int mdla_ion_kunmap(unsigned long arg)
{
struct ioctl_ion ion_data;
struct ion_handle *hndl;
if (!ion_client)
return -ENOENT;
if (copy_from_user(&ion_data, (void * __user) arg, sizeof(ion_data)))
return -EFAULT;
mdla_mem_debug("%s: mva=%llxh, kva=%llxh, kernel_handle=%llxh\n",
__func__, ion_data.mva, ion_data.kva, ion_data.khandle);
hndl = ion_drv_get_handle(ion_client, ion_data.fd, NULL, false);
if (IS_ERR_OR_NULL(hndl))
return -EINVAL;
if (hndl != (struct ion_handle *)ion_data.khandle) {
mdla_mem_debug("%s: user_handle=%d, get khandle=%llxh\n",
__func__, ion_data.fd, hndl);
LOG_ERR("%s: invalid ion kernel handle\n", __func__);
return -EINVAL;
}
ion_unmap_kernel(ion_client, hndl);
ion_free(ion_client, hndl);
return 0;
}
void mdla_ion_sync(u64 hndl, void *kva, u32 size)
{
struct ion_sys_data sys_data;
int ret;
sys_data.sys_cmd = ION_SYS_CACHE_SYNC;
sys_data.cache_sync_param.kernel_handle =
(struct ion_handle *)hndl;
sys_data.cache_sync_param.sync_type = ION_CACHE_FLUSH_BY_RANGE;
sys_data.cache_sync_param.va = kva;
sys_data.cache_sync_param.size = size;
ret = ion_kernel_ioctl(ion_client, ION_CMD_SYSTEM,
(unsigned long)&sys_data);
mdla_mem_debug("%s: ion_kernel_ioctl kernel_handle=%llx\n",
__func__, (unsigned long long)hndl);
if (ret) {
mdla_mem_debug("%s: ion_kernel_ioctl(hndl=%llx): %d failed\n",
__func__, (unsigned long long)hndl, ret);
}
}
#endif