1419b0af8Sopenharmony_ci/* 2419b0af8Sopenharmony_ci * Copyright (C) 2022 Huawei Technologies Co., Ltd. 3419b0af8Sopenharmony_ci * Decription: tui agent for tui display and interact 4419b0af8Sopenharmony_ci * 5419b0af8Sopenharmony_ci * This software is licensed under the terms of the GNU General Public 6419b0af8Sopenharmony_ci * License version 2, as published by the Free Software Foundation, and 7419b0af8Sopenharmony_ci * may be copied, distributed, and modified under those terms. 8419b0af8Sopenharmony_ci * 9419b0af8Sopenharmony_ci * This program is distributed in the hope that it will be useful, 10419b0af8Sopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 11419b0af8Sopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12419b0af8Sopenharmony_ci * GNU General Public License for more details. 13419b0af8Sopenharmony_ci */ 14419b0af8Sopenharmony_ci#include "tui.h" 15419b0af8Sopenharmony_ci#include <linux/kthread.h> 16419b0af8Sopenharmony_ci#include <linux/sched.h> 17419b0af8Sopenharmony_ci#if (KERNEL_VERSION(5, 10, 0) <= LINUX_VERSION_CODE) 18419b0af8Sopenharmony_ci#include <linux/sched/types.h> 19419b0af8Sopenharmony_ci#include <uapi/linux/sched/types.h> 20419b0af8Sopenharmony_ci#else 21419b0af8Sopenharmony_ci#include <linux/sched/types.h> 22419b0af8Sopenharmony_ci#endif 23419b0af8Sopenharmony_ci#include <linux/sched/rt.h> 24419b0af8Sopenharmony_ci#include <linux/printk.h> 25419b0af8Sopenharmony_ci#include <linux/slab.h> 26419b0af8Sopenharmony_ci#include <linux/spinlock.h> 27419b0af8Sopenharmony_ci#include <linux/debugfs.h> 28419b0af8Sopenharmony_ci#include <linux/string.h> 29419b0af8Sopenharmony_ci#include <linux/kernel.h> 30419b0af8Sopenharmony_ci#include <linux/atomic.h> 31419b0af8Sopenharmony_ci#include <linux/time.h> 32419b0af8Sopenharmony_ci#include <linux/timer.h> 33419b0af8Sopenharmony_ci#include <linux/wait.h> 34419b0af8Sopenharmony_ci#include <linux/version.h> 35419b0af8Sopenharmony_ci#ifndef CONFIG_DMABUF_MM 36419b0af8Sopenharmony_ci#include <linux/ion.h> 37419b0af8Sopenharmony_ci#endif 38419b0af8Sopenharmony_ci#include <linux/cma.h> 39419b0af8Sopenharmony_ci#include <linux/module.h> 40419b0af8Sopenharmony_ci#include <linux/init.h> 41419b0af8Sopenharmony_ci#include <linux/workqueue.h> 42419b0af8Sopenharmony_ci#include <linux/sysfs.h> 43419b0af8Sopenharmony_ci#ifdef CONFIG_TEE_TUI_MTK 44419b0af8Sopenharmony_ci#include <linux/sched/task.h> 45419b0af8Sopenharmony_ci#include <linux/uaccess.h> 46419b0af8Sopenharmony_ci#include <linux/scatterlist.h> 47419b0af8Sopenharmony_ci#endif 48419b0af8Sopenharmony_ci/* add for CMA malloc framebuffer */ 49419b0af8Sopenharmony_ci#include <linux/of.h> 50419b0af8Sopenharmony_ci#include <linux/of_fdt.h> 51419b0af8Sopenharmony_ci#include <linux/of_reserved_mem.h> 52419b0af8Sopenharmony_ci#include <linux/fs.h> 53419b0af8Sopenharmony_ci#include <linux/mm.h> 54419b0af8Sopenharmony_ci#include <asm/tlbflush.h> 55419b0af8Sopenharmony_ci#include <asm/cacheflush.h> 56419b0af8Sopenharmony_ci#include <linux/kmemleak.h> 57419b0af8Sopenharmony_ci#include <securec.h> 58419b0af8Sopenharmony_ci#include "teek_client_constants.h" 59419b0af8Sopenharmony_ci#include "agent.h" 60419b0af8Sopenharmony_ci#include "mem.h" 61419b0af8Sopenharmony_ci#include "teek_ns_client.h" 62419b0af8Sopenharmony_ci#include "smc_smp.h" 63419b0af8Sopenharmony_ci#include "tc_ns_client.h" 64419b0af8Sopenharmony_ci#include "tc_ns_log.h" 65419b0af8Sopenharmony_ci#include "mailbox_mempool.h" 66419b0af8Sopenharmony_ci#ifndef CONFIG_TEE_TUI_MTK 67419b0af8Sopenharmony_ci#include <platform_include/basicplatform/linux/powerkey_event.h> 68419b0af8Sopenharmony_ci#ifdef CONFIG_DMABUF_MM 69419b0af8Sopenharmony_ci#include <linux/dmabuf/mm_dma_heap.h> 70419b0af8Sopenharmony_ci#else 71419b0af8Sopenharmony_ci#include <linux/ion/mm_ion.h> 72419b0af8Sopenharmony_ci#endif 73419b0af8Sopenharmony_ci#ifdef CONFIG_TEE_TUI_DISPLAY_3_0 74419b0af8Sopenharmony_ci#include "dpu_comp_mgr.h" 75419b0af8Sopenharmony_ci#else 76419b0af8Sopenharmony_ci#include <hisi_fb.h> 77419b0af8Sopenharmony_ci#endif 78419b0af8Sopenharmony_ci#endif 79419b0af8Sopenharmony_ci#include "dynamic_ion_mem.h" 80419b0af8Sopenharmony_ci#ifdef CONFIG_TEE_TUI_MTK 81419b0af8Sopenharmony_ci#include "teek_client_type.h" 82419b0af8Sopenharmony_ci#include "teek_client_api.h" 83419b0af8Sopenharmony_ci#include <memory_ssmr.h> 84419b0af8Sopenharmony_ci#include <linux/dma-mapping.h> 85419b0af8Sopenharmony_ci#ifdef CONFIG_HW_SECMEM 86419b0af8Sopenharmony_ci#include "secmem_api.h" 87419b0af8Sopenharmony_ci#endif 88419b0af8Sopenharmony_ci#ifdef CONFIG_ITRUSTEE_TRUSTED_UI 89419b0af8Sopenharmony_ci#include <mtk_debug.h> 90419b0af8Sopenharmony_ci#endif 91419b0af8Sopenharmony_ci 92419b0af8Sopenharmony_ci#ifdef CONFIG_HW_COMB_KEY 93419b0af8Sopenharmony_ci#include <huawei_platform/comb_key/power_key_event.h> 94419b0af8Sopenharmony_ci#endif 95419b0af8Sopenharmony_ci 96419b0af8Sopenharmony_ci#ifndef CONFIG_ITRUSTEE_TRUSTED_UI 97419b0af8Sopenharmony_ci#include <lcd_kit_utils.h> 98419b0af8Sopenharmony_cistruct mtk_fb_data_type { 99419b0af8Sopenharmony_ci bool panel_power_on; 100419b0af8Sopenharmony_ci struct mtk_panel_info panel_info; 101419b0af8Sopenharmony_ci}; 102419b0af8Sopenharmony_ci#endif 103419b0af8Sopenharmony_ci#endif 104419b0af8Sopenharmony_ci#include "internal_functions.h" 105419b0af8Sopenharmony_ci 106419b0af8Sopenharmony_cistatic void tui_poweroff_work_func(struct work_struct *work); 107419b0af8Sopenharmony_cistatic ssize_t tui_status_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf); 108419b0af8Sopenharmony_cistatic void tui_msg_del(const char *name); 109419b0af8Sopenharmony_cistatic DECLARE_DELAYED_WORK(tui_poweroff_work, tui_poweroff_work_func); 110419b0af8Sopenharmony_cistatic struct kobject *g_tui_kobj = NULL; 111419b0af8Sopenharmony_cistatic struct kobj_attribute tui_attribute = 112419b0af8Sopenharmony_ci __ATTR(c_state, 0440, tui_status_show, NULL); 113419b0af8Sopenharmony_cistatic struct attribute *attrs[] = { 114419b0af8Sopenharmony_ci &tui_attribute.attr, 115419b0af8Sopenharmony_ci NULL, 116419b0af8Sopenharmony_ci}; 117419b0af8Sopenharmony_ci 118419b0af8Sopenharmony_cistatic struct attribute_group g_tui_attr_group = { 119419b0af8Sopenharmony_ci .attrs = attrs, 120419b0af8Sopenharmony_ci}; 121419b0af8Sopenharmony_ci 122419b0af8Sopenharmony_ciDEFINE_MUTEX(g_tui_drv_lock); 123419b0af8Sopenharmony_cistatic struct task_struct *g_tui_task = NULL; 124419b0af8Sopenharmony_cistatic struct tui_ctl_shm *g_tui_ctl = NULL; 125419b0af8Sopenharmony_cistatic atomic_t g_tui_usage = ATOMIC_INIT(0); 126419b0af8Sopenharmony_cistatic atomic_t g_tui_state = ATOMIC_INIT(TUI_STATE_UNUSED); 127419b0af8Sopenharmony_cistatic struct list_head g_tui_drv_head = LIST_HEAD_INIT(g_tui_drv_head); 128419b0af8Sopenharmony_cistatic atomic_t g_tui_attached_device = ATOMIC_INIT(TUI_PID_CLEAR); 129419b0af8Sopenharmony_cistatic atomic_t g_tui_pid = ATOMIC_INIT(TUI_PID_CLEAR); 130419b0af8Sopenharmony_cistatic bool g_normal_load_flag = false; 131419b0af8Sopenharmony_ci 132419b0af8Sopenharmony_cistatic spinlock_t g_tui_msg_lock; 133419b0af8Sopenharmony_cistatic struct list_head g_tui_msg_head; 134419b0af8Sopenharmony_cistatic wait_queue_head_t g_tui_state_wq; 135419b0af8Sopenharmony_cistatic int g_tui_state_flag; 136419b0af8Sopenharmony_cistatic wait_queue_head_t g_tui_msg_wq; 137419b0af8Sopenharmony_cistatic int32_t g_tui_msg_flag; 138419b0af8Sopenharmony_ci#ifdef CONFIG_TEE_TUI_MTK 139419b0af8Sopenharmony_cistatic struct mtk_fb_data_type *g_dss_fd; 140419b0af8Sopenharmony_ci#elif defined CONFIG_TEE_TUI_DISPLAY_3_0 141419b0af8Sopenharmony_cistatic struct dpu_composer *g_dss_fd; 142419b0af8Sopenharmony_ci#else 143419b0af8Sopenharmony_cistatic struct hisi_fb_data_type *g_dss_fd; 144419b0af8Sopenharmony_ci#endif 145419b0af8Sopenharmony_ci#define TUI_DSS_NAME "DSS" 146419b0af8Sopenharmony_ci#define TUI_GPIO_NAME "fff0d000.gpio" 147419b0af8Sopenharmony_ci#define TUI_TP_NAME "tp" 148419b0af8Sopenharmony_ci#define TUI_FP_NAME "fp" 149419b0af8Sopenharmony_ci 150419b0af8Sopenharmony_ci/* EMUI 11.1 need use the ttf of HarmonyOSHans.ttf */ 151419b0af8Sopenharmony_ci#define TTF_NORMAL_BUFF_SIZE (20 * 1024 * 1024) 152419b0af8Sopenharmony_ci 153419b0af8Sopenharmony_ci#ifdef TUI_DAEMON_UID_IN_OH 154419b0af8Sopenharmony_ci#define TTF_NORMAL_FILE_PATH "/system/fonts/HarmonyOS_Sans_SC_Regular.ttf" 155419b0af8Sopenharmony_ci#else 156419b0af8Sopenharmony_ci#define TTF_NORMAL_FILE_PATH "/system/fonts/HarmonyOS_Sans_SC.ttf" 157419b0af8Sopenharmony_ci#endif 158419b0af8Sopenharmony_ci 159419b0af8Sopenharmony_ci/* 2M memory size is 2^21 */ 160419b0af8Sopenharmony_ci#define ALIGN_SIZE 21 161419b0af8Sopenharmony_ci#define ALIGN_M (1 << 21) 162419b0af8Sopenharmony_ci#define MAX_SCREEN_RESOLUTION 8192 163419b0af8Sopenharmony_ci#define TP_BASE_VALUE 10 164419b0af8Sopenharmony_ci 165419b0af8Sopenharmony_ci/* dss and tp couple mode: 0 is init dss and tp; 1 is only init dss; 2 is only init tp */ 166419b0af8Sopenharmony_ci#define DSS_TP_COUPLE_MODE 0 167419b0af8Sopenharmony_ci#define NORMAL_MODE 0 /* init all driver */ 168419b0af8Sopenharmony_ci#define ONLY_INIT_DSS 1 /* only init dss */ 169419b0af8Sopenharmony_ci#define ONLY_INIT_TP 2 /* only init tp */ 170419b0af8Sopenharmony_ci 171419b0af8Sopenharmony_ci/* 172419b0af8Sopenharmony_ci * do fp init(disable fp irq) before gpio init in order not response 173419b0af8Sopenharmony_ci * sensor in normal world(when gpio secure status is set) 174419b0af8Sopenharmony_ci */ 175419b0af8Sopenharmony_ci#if ONLY_INIT_DSS == DSS_TP_COUPLE_MODE 176419b0af8Sopenharmony_ci#define DRIVER_NUM 1 177419b0af8Sopenharmony_cistatic char *g_init_driver[DRIVER_NUM] = {TUI_DSS_NAME}; 178419b0af8Sopenharmony_cistatic char *g_deinit_driver[DRIVER_NUM] = {TUI_DSS_NAME}; 179419b0af8Sopenharmony_ci#endif 180419b0af8Sopenharmony_ci 181419b0af8Sopenharmony_ci#if ONLY_INIT_TP == DSS_TP_COUPLE_MODE 182419b0af8Sopenharmony_ci#define DRIVER_NUM 3 183419b0af8Sopenharmony_cistatic char *g_init_driver[DRIVER_NUM] = {TUI_TP_NAME, TUI_FP_NAME, TUI_GPIO_NAME}; 184419b0af8Sopenharmony_cistatic char *g_deinit_driver[DRIVER_NUM] = {TUI_TP_NAME, TUI_FP_NAME, TUI_GPIO_NAME}; 185419b0af8Sopenharmony_ci#endif 186419b0af8Sopenharmony_ci 187419b0af8Sopenharmony_ci#if NORMAL_MODE == DSS_TP_COUPLE_MODE 188419b0af8Sopenharmony_ci#define DRIVER_NUM 4 189419b0af8Sopenharmony_cistatic char *g_init_driver[DRIVER_NUM] = {TUI_DSS_NAME, TUI_TP_NAME, TUI_FP_NAME, TUI_GPIO_NAME}; 190419b0af8Sopenharmony_cistatic char *g_deinit_driver[DRIVER_NUM] = {TUI_DSS_NAME, TUI_TP_NAME, TUI_FP_NAME, TUI_GPIO_NAME}; 191419b0af8Sopenharmony_ci#endif 192419b0af8Sopenharmony_ci 193419b0af8Sopenharmony_ci#define TIME_OUT_FOWER_ON 100 194419b0af8Sopenharmony_ci#define DOWN_VAL 22 /* 4M */ 195419b0af8Sopenharmony_ci#define UP_VAL 27 /* 64M */ 196419b0af8Sopenharmony_ci#define COLOR_TYPE 4 /* ARGB */ 197419b0af8Sopenharmony_ci#define BUFFER_NUM 2 198419b0af8Sopenharmony_ci#define UID_MAX_VAL 1000 199419b0af8Sopenharmony_ci#define HIGH_VALUES 32 200419b0af8Sopenharmony_ci#define ION_NENTS_FLAG 1 201419b0af8Sopenharmony_ci#define INVALID_CFG_NAME (-2) 202419b0af8Sopenharmony_ci 203419b0af8Sopenharmony_cistatic tui_ion_mem g_tui_display_mem; 204419b0af8Sopenharmony_cistatic tui_ion_mem g_normal_font_mem; 205419b0af8Sopenharmony_ci 206419b0af8Sopenharmony_ciunsigned int get_frame_size(unsigned int num) 207419b0af8Sopenharmony_ci{ 208419b0af8Sopenharmony_ci if (num % ALIGN_M != 0) 209419b0af8Sopenharmony_ci return (((num >> ALIGN_SIZE) + 1) << ALIGN_SIZE); 210419b0af8Sopenharmony_ci else 211419b0af8Sopenharmony_ci return num; 212419b0af8Sopenharmony_ci} 213419b0af8Sopenharmony_ci 214419b0af8Sopenharmony_ciunsigned int get_tui_size(unsigned int num) 215419b0af8Sopenharmony_ci{ 216419b0af8Sopenharmony_ci unsigned int i; 217419b0af8Sopenharmony_ci for (i = DOWN_VAL; i < UP_VAL; i++) 218419b0af8Sopenharmony_ci if ((num >> i) == 0) 219419b0af8Sopenharmony_ci break; 220419b0af8Sopenharmony_ci return (unsigned int)1 << i; 221419b0af8Sopenharmony_ci} 222419b0af8Sopenharmony_ci 223419b0af8Sopenharmony_ci/* 224419b0af8Sopenharmony_ci * alloc order: 4M-font, framebuffer, 20M-unusualfont 225419b0af8Sopenharmony_ci * 1.4M alloc when boot so from ION_TUI_HEAP_ID 226419b0af8Sopenharmony_ci * 2.20M and frambuffer alloc when tui init so from ION_MISC_HEAP_ID 227419b0af8Sopenharmony_ci */ 228419b0af8Sopenharmony_cistatic size_t get_tui_font_file_size(void) 229419b0af8Sopenharmony_ci{ 230419b0af8Sopenharmony_ci int ret; 231419b0af8Sopenharmony_ci struct kstat ttf_file_stat; 232419b0af8Sopenharmony_ci mm_segment_t old_fs; 233419b0af8Sopenharmony_ci 234419b0af8Sopenharmony_ci old_fs = get_fs(); 235419b0af8Sopenharmony_ci set_fs(KERNEL_DS); 236419b0af8Sopenharmony_ci /* get ttf file size */ 237419b0af8Sopenharmony_ci ret = vfs_stat(TTF_NORMAL_FILE_PATH, &ttf_file_stat); 238419b0af8Sopenharmony_ci if (ret < 0) { 239419b0af8Sopenharmony_ci tloge("Failed to get ttf extend file size, ret is %d\n", ret); 240419b0af8Sopenharmony_ci set_fs(old_fs); 241419b0af8Sopenharmony_ci return 0; 242419b0af8Sopenharmony_ci } 243419b0af8Sopenharmony_ci set_fs(old_fs); 244419b0af8Sopenharmony_ci 245419b0af8Sopenharmony_ci return ttf_file_stat.size; 246419b0af8Sopenharmony_ci} 247419b0af8Sopenharmony_ci 248419b0af8Sopenharmony_cistatic int check_ion_sg_table(const struct sg_table *sg_table) 249419b0af8Sopenharmony_ci{ 250419b0af8Sopenharmony_ci if (sg_table == NULL) { 251419b0af8Sopenharmony_ci tloge("invalid sgtable\n"); 252419b0af8Sopenharmony_ci return -1; 253419b0af8Sopenharmony_ci } 254419b0af8Sopenharmony_ci 255419b0af8Sopenharmony_ci /* nent must be 1, because ion addr for tui is continuous */ 256419b0af8Sopenharmony_ci if (sg_table->nents != ION_NENTS_FLAG) { 257419b0af8Sopenharmony_ci tloge("nent is invalid\n"); 258419b0af8Sopenharmony_ci return -1; 259419b0af8Sopenharmony_ci } 260419b0af8Sopenharmony_ci return 0; 261419b0af8Sopenharmony_ci} 262419b0af8Sopenharmony_ci 263419b0af8Sopenharmony_cistatic int get_tui_ion_sglist(tui_ion_mem *tui_mem) 264419b0af8Sopenharmony_ci{ 265419b0af8Sopenharmony_ci struct sglist *tmp_tui_sglist = NULL; 266419b0af8Sopenharmony_ci struct scatterlist *tui_sg = NULL; 267419b0af8Sopenharmony_ci struct page *tui_page = NULL; 268419b0af8Sopenharmony_ci uint32_t tui_sglist_size; 269419b0af8Sopenharmony_ci uint32_t i = 0; 270419b0af8Sopenharmony_ci 271419b0af8Sopenharmony_ci struct sg_table *tui_ion_sg_table = tui_mem->tui_sg_table; 272419b0af8Sopenharmony_ci if (check_ion_sg_table(tui_ion_sg_table) != 0) 273419b0af8Sopenharmony_ci return -1; 274419b0af8Sopenharmony_ci 275419b0af8Sopenharmony_ci tui_sglist_size = sizeof(struct ion_page_info) * tui_ion_sg_table->nents + 276419b0af8Sopenharmony_ci sizeof(struct sglist); 277419b0af8Sopenharmony_ci tmp_tui_sglist = (struct sglist *)mailbox_alloc(tui_sglist_size, MB_FLAG_ZERO); 278419b0af8Sopenharmony_ci if (tmp_tui_sglist == NULL) { 279419b0af8Sopenharmony_ci tloge("in %s err: mailbox_alloc failed\n", __func__); 280419b0af8Sopenharmony_ci return -1; 281419b0af8Sopenharmony_ci } 282419b0af8Sopenharmony_ci 283419b0af8Sopenharmony_ci tmp_tui_sglist->sglist_size = (uint64_t)tui_sglist_size; 284419b0af8Sopenharmony_ci tmp_tui_sglist->ion_size = (uint64_t)tui_mem->len; 285419b0af8Sopenharmony_ci tmp_tui_sglist->info_length = (uint64_t)tui_ion_sg_table->nents; 286419b0af8Sopenharmony_ci tui_mem->info_length = (uint64_t)tui_ion_sg_table->nents; 287419b0af8Sopenharmony_ci 288419b0af8Sopenharmony_ci /* get tui_sg to fetch ion for tui */ 289419b0af8Sopenharmony_ci for_each_sg(tui_ion_sg_table->sgl, tui_sg, tui_ion_sg_table->nents, i) { 290419b0af8Sopenharmony_ci if (tui_sg == NULL) { 291419b0af8Sopenharmony_ci tloge("tui sg is NULL"); 292419b0af8Sopenharmony_ci mailbox_free(tmp_tui_sglist); 293419b0af8Sopenharmony_ci return -1; 294419b0af8Sopenharmony_ci } 295419b0af8Sopenharmony_ci tui_page = sg_page(tui_sg); 296419b0af8Sopenharmony_ci tmp_tui_sglist->page_info[0].phys_addr = page_to_phys(tui_page); 297419b0af8Sopenharmony_ci tmp_tui_sglist->page_info[0].npages = tui_sg->length / PAGE_SIZE; 298419b0af8Sopenharmony_ci tui_mem->npages = tmp_tui_sglist->page_info[0].npages; 299419b0af8Sopenharmony_ci tui_mem->tui_ion_virt_addr = phys_to_virt(tmp_tui_sglist->page_info[0].phys_addr); 300419b0af8Sopenharmony_ci tui_mem->fb_phys_addr = tmp_tui_sglist->page_info[0].phys_addr; 301419b0af8Sopenharmony_ci } 302419b0af8Sopenharmony_ci 303419b0af8Sopenharmony_ci tui_mem->tui_ion_phys_addr = mailbox_virt_to_phys((uintptr_t)(void *)tmp_tui_sglist); // sglist phys-addr 304419b0af8Sopenharmony_ci if (tui_mem->tui_ion_phys_addr == 0) { 305419b0af8Sopenharmony_ci tloge("Failed to get tmp_tui_sglist physaddr, configid=%d\n", 306419b0af8Sopenharmony_ci tui_mem->configid); 307419b0af8Sopenharmony_ci mailbox_free(tmp_tui_sglist); 308419b0af8Sopenharmony_ci return -1; 309419b0af8Sopenharmony_ci } 310419b0af8Sopenharmony_ci tui_mem->size = tui_sglist_size; 311419b0af8Sopenharmony_ci return 0; 312419b0af8Sopenharmony_ci} 313419b0af8Sopenharmony_ci 314419b0af8Sopenharmony_cistatic int alloc_ion_mem(tui_ion_mem *tui_mem) 315419b0af8Sopenharmony_ci{ 316419b0af8Sopenharmony_ci struct sg_table *tui_ion_sg_table = NULL; 317419b0af8Sopenharmony_ci if (tui_mem == NULL) { 318419b0af8Sopenharmony_ci tloge("bad input params\n"); 319419b0af8Sopenharmony_ci return -1; 320419b0af8Sopenharmony_ci } 321419b0af8Sopenharmony_ci#ifdef CONFIG_HW_SECMEM 322419b0af8Sopenharmony_ci tui_ion_sg_table = cma_secmem_alloc(SEC_TUI, tui_mem->len); 323419b0af8Sopenharmony_ci#endif 324419b0af8Sopenharmony_ci#ifndef CONFIG_TEE_TUI_MTK 325419b0af8Sopenharmony_ci tui_ion_sg_table = mm_secmem_alloc(SEC_TUI, tui_mem->len); 326419b0af8Sopenharmony_ci#endif 327419b0af8Sopenharmony_ci if (tui_ion_sg_table == NULL) { 328419b0af8Sopenharmony_ci tloge("failed to get ion page for tui, configid is %d\n", tui_mem->configid); 329419b0af8Sopenharmony_ci return -1; 330419b0af8Sopenharmony_ci } 331419b0af8Sopenharmony_ci tui_mem->tui_sg_table = tui_ion_sg_table; 332419b0af8Sopenharmony_ci return 0; 333419b0af8Sopenharmony_ci} 334419b0af8Sopenharmony_ci 335419b0af8Sopenharmony_cistatic void free_ion_mem(tui_ion_mem *tui_mem) 336419b0af8Sopenharmony_ci{ 337419b0af8Sopenharmony_ci if (tui_mem->tui_sg_table == NULL || tui_mem->tui_ion_phys_addr == 0) { 338419b0af8Sopenharmony_ci tloge("bad input params\n"); 339419b0af8Sopenharmony_ci return; 340419b0af8Sopenharmony_ci } 341419b0af8Sopenharmony_ci#ifdef CONFIG_HW_SECMEM 342419b0af8Sopenharmony_ci cma_secmem_free(SEC_TUI, tui_mem->tui_sg_table); 343419b0af8Sopenharmony_ci#endif 344419b0af8Sopenharmony_ci#ifndef CONFIG_TEE_TUI_MTK 345419b0af8Sopenharmony_ci mm_secmem_free(SEC_TUI, tui_mem->tui_sg_table); 346419b0af8Sopenharmony_ci#endif 347419b0af8Sopenharmony_ci tui_mem->tui_ion_phys_addr = 0; 348419b0af8Sopenharmony_ci return; 349419b0af8Sopenharmony_ci} 350419b0af8Sopenharmony_ci 351419b0af8Sopenharmony_cistatic void free_tui_font_mem(void) 352419b0af8Sopenharmony_ci{ 353419b0af8Sopenharmony_ci free_ion_mem(&g_normal_font_mem); 354419b0af8Sopenharmony_ci g_normal_load_flag = false; 355419b0af8Sopenharmony_ci tloge("normal tui font file freed\n"); 356419b0af8Sopenharmony_ci} 357419b0af8Sopenharmony_ci 358419b0af8Sopenharmony_cistatic int get_tui_font_mem(tui_ion_mem *tui_font_mem) 359419b0af8Sopenharmony_ci{ 360419b0af8Sopenharmony_ci int ret; 361419b0af8Sopenharmony_ci 362419b0af8Sopenharmony_ci ret = alloc_ion_mem(tui_font_mem); 363419b0af8Sopenharmony_ci if (ret < 0) { 364419b0af8Sopenharmony_ci tloge("Failed to alloc cma mem for tui font lib\n"); 365419b0af8Sopenharmony_ci return -ENOMEM; 366419b0af8Sopenharmony_ci } 367419b0af8Sopenharmony_ci 368419b0af8Sopenharmony_ci return 0; 369419b0af8Sopenharmony_ci} 370419b0af8Sopenharmony_ci 371419b0af8Sopenharmony_ci/* size is calculated dynamically according to the screen resolution */ 372419b0af8Sopenharmony_ci#ifdef CONFIG_TEE_TUI_DISPLAY_3_0 373419b0af8Sopenharmony_cistatic phys_addr_t get_frame_addr(void) 374419b0af8Sopenharmony_ci{ 375419b0af8Sopenharmony_ci int screen_r; 376419b0af8Sopenharmony_ci int ret; 377419b0af8Sopenharmony_ci bool check_params = false; 378419b0af8Sopenharmony_ci if (g_dss_fd == NULL) 379419b0af8Sopenharmony_ci return 0; 380419b0af8Sopenharmony_ci 381419b0af8Sopenharmony_ci check_params = (g_dss_fd->comp.base.xres > MAX_SCREEN_RESOLUTION) || 382419b0af8Sopenharmony_ci (g_dss_fd->comp.base.yres > MAX_SCREEN_RESOLUTION); 383419b0af8Sopenharmony_ci if (check_params) { 384419b0af8Sopenharmony_ci tloge("Horizontal resolution or Vertical resolution is too large\n"); 385419b0af8Sopenharmony_ci return 0; 386419b0af8Sopenharmony_ci } 387419b0af8Sopenharmony_ci screen_r = g_dss_fd->comp.base.xres * g_dss_fd->comp.base.yres * COLOR_TYPE * BUFFER_NUM; 388419b0af8Sopenharmony_ci g_tui_display_mem.len = get_frame_size(screen_r); 389419b0af8Sopenharmony_ci ret = alloc_ion_mem(&g_tui_display_mem); 390419b0af8Sopenharmony_ci if (ret) { 391419b0af8Sopenharmony_ci tloge("Failed to alloc mem for tui display\n"); 392419b0af8Sopenharmony_ci return 0; 393419b0af8Sopenharmony_ci } 394419b0af8Sopenharmony_ci 395419b0af8Sopenharmony_ci if (get_tui_ion_sglist(&g_tui_display_mem)) { 396419b0af8Sopenharmony_ci tloge("get sglist failed\n"); 397419b0af8Sopenharmony_ci free_ion_mem(&g_tui_display_mem); 398419b0af8Sopenharmony_ci return 0; 399419b0af8Sopenharmony_ci } 400419b0af8Sopenharmony_ci 401419b0af8Sopenharmony_ci return g_tui_display_mem.fb_phys_addr; 402419b0af8Sopenharmony_ci} 403419b0af8Sopenharmony_ci#else 404419b0af8Sopenharmony_cistatic phys_addr_t get_frame_addr(void) 405419b0af8Sopenharmony_ci{ 406419b0af8Sopenharmony_ci int screen_r; 407419b0af8Sopenharmony_ci int ret; 408419b0af8Sopenharmony_ci bool check_params = false; 409419b0af8Sopenharmony_ci if (g_dss_fd == NULL) 410419b0af8Sopenharmony_ci return 0; 411419b0af8Sopenharmony_ci 412419b0af8Sopenharmony_ci check_params = (g_dss_fd->panel_info.xres > MAX_SCREEN_RESOLUTION) || 413419b0af8Sopenharmony_ci (g_dss_fd->panel_info.yres > MAX_SCREEN_RESOLUTION); 414419b0af8Sopenharmony_ci if (check_params) { 415419b0af8Sopenharmony_ci tloge("Horizontal resolution or Vertical resolution is too large\n"); 416419b0af8Sopenharmony_ci return 0; 417419b0af8Sopenharmony_ci } 418419b0af8Sopenharmony_ci screen_r = g_dss_fd->panel_info.xres * g_dss_fd->panel_info.yres * COLOR_TYPE * BUFFER_NUM; 419419b0af8Sopenharmony_ci g_tui_display_mem.len = get_frame_size(screen_r); 420419b0af8Sopenharmony_ci ret = alloc_ion_mem(&g_tui_display_mem); 421419b0af8Sopenharmony_ci if (ret != 0) { 422419b0af8Sopenharmony_ci tloge("Failed to alloc mem for tui display\n"); 423419b0af8Sopenharmony_ci return 0; 424419b0af8Sopenharmony_ci } 425419b0af8Sopenharmony_ci 426419b0af8Sopenharmony_ci if (get_tui_ion_sglist(&g_tui_display_mem) != 0) { 427419b0af8Sopenharmony_ci tloge("get sglist failed\n"); 428419b0af8Sopenharmony_ci free_ion_mem(&g_tui_display_mem); 429419b0af8Sopenharmony_ci return 0; 430419b0af8Sopenharmony_ci } 431419b0af8Sopenharmony_ci 432419b0af8Sopenharmony_ci return g_tui_display_mem.fb_phys_addr; 433419b0af8Sopenharmony_ci} 434419b0af8Sopenharmony_ci#endif 435419b0af8Sopenharmony_ci 436419b0af8Sopenharmony_civoid free_frame_addr(void) 437419b0af8Sopenharmony_ci{ 438419b0af8Sopenharmony_ci mailbox_free(phys_to_virt(g_tui_display_mem.tui_ion_phys_addr)); 439419b0af8Sopenharmony_ci free_ion_mem(&g_tui_display_mem); 440419b0af8Sopenharmony_ci return; 441419b0af8Sopenharmony_ci} 442419b0af8Sopenharmony_ci 443419b0af8Sopenharmony_cistatic int32_t tc_ns_register_tui_font_mem(tui_ion_mem *tui_font_mem, 444419b0af8Sopenharmony_ci size_t font_file_size) 445419b0af8Sopenharmony_ci{ 446419b0af8Sopenharmony_ci struct tc_ns_smc_cmd smc_cmd = { {0}, 0}; 447419b0af8Sopenharmony_ci int ret = 0; 448419b0af8Sopenharmony_ci struct mb_cmd_pack *mb_pack = NULL; 449419b0af8Sopenharmony_ci 450419b0af8Sopenharmony_ci mb_pack = mailbox_alloc_cmd_pack(); 451419b0af8Sopenharmony_ci if (!mb_pack) { 452419b0af8Sopenharmony_ci tloge("alloc cmd pack failed\n"); 453419b0af8Sopenharmony_ci return -ENOMEM; 454419b0af8Sopenharmony_ci } 455419b0af8Sopenharmony_ci 456419b0af8Sopenharmony_ci smc_cmd.cmd_type = CMD_TYPE_GLOBAL; 457419b0af8Sopenharmony_ci smc_cmd.cmd_id = GLOBAL_CMD_ID_REGISTER_TTF_MEM; 458419b0af8Sopenharmony_ci 459419b0af8Sopenharmony_ci mb_pack->operation.paramtypes = teec_param_types( 460419b0af8Sopenharmony_ci TEEC_MEMREF_TEMP_INPUT, 461419b0af8Sopenharmony_ci TEEC_VALUE_INPUT, 462419b0af8Sopenharmony_ci TEEC_NONE, 463419b0af8Sopenharmony_ci TEEC_NONE 464419b0af8Sopenharmony_ci ); 465419b0af8Sopenharmony_ci 466419b0af8Sopenharmony_ci mb_pack->operation.params[0].memref.size = (uint32_t)(tui_font_mem->size); 467419b0af8Sopenharmony_ci mb_pack->operation.params[0].memref.buffer = (uint32_t)(tui_font_mem->tui_ion_phys_addr & 0xFFFFFFFF); 468419b0af8Sopenharmony_ci mb_pack->operation.buffer_h_addr[0] = tui_font_mem->tui_ion_phys_addr >> HIGH_VALUES; 469419b0af8Sopenharmony_ci mb_pack->operation.params[1].value.a = font_file_size; 470419b0af8Sopenharmony_ci 471419b0af8Sopenharmony_ci smc_cmd.operation_phys = (unsigned int)mailbox_virt_to_phys((uintptr_t)&mb_pack->operation); 472419b0af8Sopenharmony_ci smc_cmd.operation_h_phys = mailbox_virt_to_phys((uintptr_t)&mb_pack->operation) >> HIGH_VALUES; 473419b0af8Sopenharmony_ci if (tc_ns_smc(&smc_cmd)) { 474419b0af8Sopenharmony_ci ret = -EPERM; 475419b0af8Sopenharmony_ci tloge("send ttf mem info failed. ret = 0x%x\n", smc_cmd.ret_val); 476419b0af8Sopenharmony_ci } 477419b0af8Sopenharmony_ci mailbox_free(mb_pack); 478419b0af8Sopenharmony_ci 479419b0af8Sopenharmony_ci return ret; 480419b0af8Sopenharmony_ci} 481419b0af8Sopenharmony_ci 482419b0af8Sopenharmony_cistatic int32_t copy_tui_font_file(size_t font_file_size, const void *font_virt_addr) 483419b0af8Sopenharmony_ci{ 484419b0af8Sopenharmony_ci struct file *filep = NULL; 485419b0af8Sopenharmony_ci mm_segment_t old_fs; 486419b0af8Sopenharmony_ci loff_t pos = 0; 487419b0af8Sopenharmony_ci unsigned int count; 488419b0af8Sopenharmony_ci int ret = 0; 489419b0af8Sopenharmony_ci 490419b0af8Sopenharmony_ci if (font_virt_addr == NULL) 491419b0af8Sopenharmony_ci return -1; 492419b0af8Sopenharmony_ci 493419b0af8Sopenharmony_ci filep = filp_open(TTF_NORMAL_FILE_PATH, O_RDONLY, 0); 494419b0af8Sopenharmony_ci if (IS_ERR(filep) || filep == NULL) { 495419b0af8Sopenharmony_ci tloge("Failed to open ttf file\n"); 496419b0af8Sopenharmony_ci return -1; 497419b0af8Sopenharmony_ci } 498419b0af8Sopenharmony_ci 499419b0af8Sopenharmony_ci old_fs = get_fs(); 500419b0af8Sopenharmony_ci set_fs(KERNEL_DS); 501419b0af8Sopenharmony_ci 502419b0af8Sopenharmony_ci count = (unsigned int)vfs_read(filep, (char __user *)font_virt_addr, font_file_size, &pos); 503419b0af8Sopenharmony_ci 504419b0af8Sopenharmony_ci if (font_file_size != count) { 505419b0af8Sopenharmony_ci tloge("read ttf file failed\n"); 506419b0af8Sopenharmony_ci ret = -1; 507419b0af8Sopenharmony_ci } 508419b0af8Sopenharmony_ci 509419b0af8Sopenharmony_ci set_fs(old_fs); 510419b0af8Sopenharmony_ci filp_close(filep, 0); 511419b0af8Sopenharmony_ci filep = NULL; 512419b0af8Sopenharmony_ci return ret; 513419b0af8Sopenharmony_ci} 514419b0af8Sopenharmony_ci 515419b0af8Sopenharmony_cistatic int32_t send_ttf_mem(tui_ion_mem *tui_ttf_mem) 516419b0af8Sopenharmony_ci{ 517419b0af8Sopenharmony_ci int ret; 518419b0af8Sopenharmony_ci size_t tui_font_file_size; 519419b0af8Sopenharmony_ci bool check_params = false; 520419b0af8Sopenharmony_ci 521419b0af8Sopenharmony_ci tui_font_file_size = get_tui_font_file_size(); 522419b0af8Sopenharmony_ci check_params = (tui_font_file_size == 0) || (tui_font_file_size > tui_ttf_mem->len); 523419b0af8Sopenharmony_ci if (check_params) { 524419b0af8Sopenharmony_ci tloge("Failed to get the tui font file size or the tui_font_file_size is too big\n"); 525419b0af8Sopenharmony_ci return -1; 526419b0af8Sopenharmony_ci } 527419b0af8Sopenharmony_ci 528419b0af8Sopenharmony_ci __dma_map_area(tui_ttf_mem->tui_ion_virt_addr, tui_ttf_mem->len, DMA_BIDIRECTIONAL); 529419b0af8Sopenharmony_ci ret = copy_tui_font_file(tui_font_file_size, tui_ttf_mem->tui_ion_virt_addr); 530419b0af8Sopenharmony_ci if (ret < 0) { 531419b0af8Sopenharmony_ci tloge("Failed to do ttf file copy\n"); 532419b0af8Sopenharmony_ci return -1; 533419b0af8Sopenharmony_ci } 534419b0af8Sopenharmony_ci 535419b0af8Sopenharmony_ci __dma_map_area(tui_ttf_mem->tui_ion_virt_addr, tui_ttf_mem->len, DMA_BIDIRECTIONAL); 536419b0af8Sopenharmony_ci __dma_map_area(tui_ttf_mem->tui_ion_virt_addr, tui_ttf_mem->len, DMA_FROM_DEVICE); 537419b0af8Sopenharmony_ci 538419b0af8Sopenharmony_ci ret = tc_ns_register_tui_font_mem(tui_ttf_mem, tui_font_file_size); 539419b0af8Sopenharmony_ci if (ret != 0) { 540419b0af8Sopenharmony_ci tloge("Failed to do ttf file register ret is 0x%x\n", ret); 541419b0af8Sopenharmony_ci return -1; 542419b0af8Sopenharmony_ci } 543419b0af8Sopenharmony_ci 544419b0af8Sopenharmony_ci return 0; 545419b0af8Sopenharmony_ci} 546419b0af8Sopenharmony_ci 547419b0af8Sopenharmony_cistatic int32_t load_tui_font_file(void) 548419b0af8Sopenharmony_ci{ 549419b0af8Sopenharmony_ci int ret = 0; 550419b0af8Sopenharmony_ci tui_ion_mem *tui_ttf_mem = NULL; 551419b0af8Sopenharmony_ci 552419b0af8Sopenharmony_ci tloge("====load ttf start =====\n"); 553419b0af8Sopenharmony_ci 554419b0af8Sopenharmony_ci mutex_lock(&g_tui_drv_lock); 555419b0af8Sopenharmony_ci if (g_normal_load_flag) { 556419b0af8Sopenharmony_ci tloge("normal tui font file has been loaded\n"); 557419b0af8Sopenharmony_ci mutex_unlock(&g_tui_drv_lock); 558419b0af8Sopenharmony_ci return 0; 559419b0af8Sopenharmony_ci } 560419b0af8Sopenharmony_ci 561419b0af8Sopenharmony_ci g_normal_font_mem.len = TTF_NORMAL_BUFF_SIZE; 562419b0af8Sopenharmony_ci ret = get_tui_font_mem(&g_normal_font_mem); 563419b0af8Sopenharmony_ci tui_ttf_mem = &g_normal_font_mem; 564419b0af8Sopenharmony_ci if (ret != 0) { 565419b0af8Sopenharmony_ci tloge("Failed to get tui font memory\n"); 566419b0af8Sopenharmony_ci mutex_unlock(&g_tui_drv_lock); 567419b0af8Sopenharmony_ci return -1; 568419b0af8Sopenharmony_ci } 569419b0af8Sopenharmony_ci 570419b0af8Sopenharmony_ci if (get_tui_ion_sglist(tui_ttf_mem) != 0) { 571419b0af8Sopenharmony_ci tloge("get tui sglist failed\n"); 572419b0af8Sopenharmony_ci free_tui_font_mem(); 573419b0af8Sopenharmony_ci mutex_unlock(&g_tui_drv_lock); 574419b0af8Sopenharmony_ci return -1; 575419b0af8Sopenharmony_ci } 576419b0af8Sopenharmony_ci 577419b0af8Sopenharmony_ci ret = send_ttf_mem(tui_ttf_mem); 578419b0af8Sopenharmony_ci if (ret != 0) { 579419b0af8Sopenharmony_ci mailbox_free(phys_to_virt(tui_ttf_mem->tui_ion_phys_addr)); 580419b0af8Sopenharmony_ci free_tui_font_mem(); 581419b0af8Sopenharmony_ci mutex_unlock(&g_tui_drv_lock); 582419b0af8Sopenharmony_ci return -1; 583419b0af8Sopenharmony_ci } 584419b0af8Sopenharmony_ci 585419b0af8Sopenharmony_ci tloge("normal tui font file loaded\n"); 586419b0af8Sopenharmony_ci g_normal_load_flag = true; 587419b0af8Sopenharmony_ci mutex_unlock(&g_tui_drv_lock); 588419b0af8Sopenharmony_ci 589419b0af8Sopenharmony_ci mailbox_free(phys_to_virt(tui_ttf_mem->tui_ion_phys_addr)); 590419b0af8Sopenharmony_ci tloge("=====load ttf end=====\n"); 591419b0af8Sopenharmony_ci return ret; 592419b0af8Sopenharmony_ci} 593419b0af8Sopenharmony_ci 594419b0af8Sopenharmony_ciint register_tui_driver(tui_drv_init fun, const char *name, 595419b0af8Sopenharmony_ci void *pdata) 596419b0af8Sopenharmony_ci{ 597419b0af8Sopenharmony_ci struct tui_drv_node *tui_drv = NULL; 598419b0af8Sopenharmony_ci struct tui_drv_node *pos = NULL; 599419b0af8Sopenharmony_ci 600419b0af8Sopenharmony_ci /* Return error if name is invalid */ 601419b0af8Sopenharmony_ci if (name == NULL || fun == NULL) { 602419b0af8Sopenharmony_ci tloge("name or func is null"); 603419b0af8Sopenharmony_ci return -EINVAL; 604419b0af8Sopenharmony_ci } 605419b0af8Sopenharmony_ci 606419b0af8Sopenharmony_ci if (strncmp(name, TUI_DSS_NAME, (size_t)TUI_DRV_NAME_MAX) == 0) { 607419b0af8Sopenharmony_ci if (pdata == NULL) 608419b0af8Sopenharmony_ci return -1; 609419b0af8Sopenharmony_ci else 610419b0af8Sopenharmony_ci#ifdef CONFIG_TEE_TUI_MTK 611419b0af8Sopenharmony_ci g_dss_fd = (struct mtk_fb_data_type *)pdata; 612419b0af8Sopenharmony_ci#elif defined CONFIG_TEE_TUI_DISPLAY_3_0 613419b0af8Sopenharmony_ci g_dss_fd = (struct dpu_composer *)pdata; 614419b0af8Sopenharmony_ci#else 615419b0af8Sopenharmony_ci g_dss_fd = (struct hisi_fb_data_type *)pdata; 616419b0af8Sopenharmony_ci#endif 617419b0af8Sopenharmony_ci } 618419b0af8Sopenharmony_ci 619419b0af8Sopenharmony_ci if ((strncmp(name, TUI_TP_NAME, (size_t)TUI_DRV_NAME_MAX) == 0) && pdata == NULL) 620419b0af8Sopenharmony_ci return -1; 621419b0af8Sopenharmony_ci 622419b0af8Sopenharmony_ci mutex_lock(&g_tui_drv_lock); 623419b0af8Sopenharmony_ci 624419b0af8Sopenharmony_ci /* name should not have been registered */ 625419b0af8Sopenharmony_ci list_for_each_entry(pos, &g_tui_drv_head, list) { 626419b0af8Sopenharmony_ci if (!strncmp(pos->name, name, TUI_DRV_NAME_MAX - 1)) { 627419b0af8Sopenharmony_ci tloge("this drv(%s) have registered\n", name); 628419b0af8Sopenharmony_ci mutex_unlock(&g_tui_drv_lock); 629419b0af8Sopenharmony_ci return -EINVAL; 630419b0af8Sopenharmony_ci } 631419b0af8Sopenharmony_ci } 632419b0af8Sopenharmony_ci mutex_unlock(&g_tui_drv_lock); 633419b0af8Sopenharmony_ci 634419b0af8Sopenharmony_ci /* Alllovate memory for tui_drv */ 635419b0af8Sopenharmony_ci tui_drv = kzalloc(sizeof(struct tui_drv_node), GFP_KERNEL); 636419b0af8Sopenharmony_ci if (tui_drv == NULL) 637419b0af8Sopenharmony_ci return -ENOMEM; 638419b0af8Sopenharmony_ci 639419b0af8Sopenharmony_ci if (memset_s(tui_drv, sizeof(struct tui_drv_node), 0, sizeof(struct tui_drv_node)) != 0) { 640419b0af8Sopenharmony_ci tloge("tui_drv memset failed"); 641419b0af8Sopenharmony_ci kfree(tui_drv); 642419b0af8Sopenharmony_ci return -1; 643419b0af8Sopenharmony_ci } 644419b0af8Sopenharmony_ci /* Assign content for tui_drv */ 645419b0af8Sopenharmony_ci tui_drv->init_func = fun; 646419b0af8Sopenharmony_ci tui_drv->pdata = pdata; 647419b0af8Sopenharmony_ci 648419b0af8Sopenharmony_ci if (strncpy_s(tui_drv->name, TUI_DRV_NAME_MAX, name, TUI_DRV_NAME_MAX - 1) != 0) { 649419b0af8Sopenharmony_ci tloge("strncpy_s error\n"); 650419b0af8Sopenharmony_ci kfree(tui_drv); 651419b0af8Sopenharmony_ci return -1; 652419b0af8Sopenharmony_ci } 653419b0af8Sopenharmony_ci 654419b0af8Sopenharmony_ci INIT_LIST_HEAD(&tui_drv->list); 655419b0af8Sopenharmony_ci 656419b0af8Sopenharmony_ci /* link the new tui_drv to the list */ 657419b0af8Sopenharmony_ci mutex_lock(&g_tui_drv_lock); 658419b0af8Sopenharmony_ci list_add_tail(&tui_drv->list, &g_tui_drv_head); 659419b0af8Sopenharmony_ci mutex_unlock(&g_tui_drv_lock); 660419b0af8Sopenharmony_ci 661419b0af8Sopenharmony_ci return 0; 662419b0af8Sopenharmony_ci} 663419b0af8Sopenharmony_ciEXPORT_SYMBOL(register_tui_driver); 664419b0af8Sopenharmony_ci 665419b0af8Sopenharmony_civoid unregister_tui_driver(const char *name) 666419b0af8Sopenharmony_ci{ 667419b0af8Sopenharmony_ci struct tui_drv_node *pos = NULL, *tmp = NULL; 668419b0af8Sopenharmony_ci 669419b0af8Sopenharmony_ci /* Return error if name is invalid */ 670419b0af8Sopenharmony_ci if (name == NULL) { 671419b0af8Sopenharmony_ci tloge("name is null"); 672419b0af8Sopenharmony_ci return; 673419b0af8Sopenharmony_ci } 674419b0af8Sopenharmony_ci 675419b0af8Sopenharmony_ci mutex_lock(&g_tui_drv_lock); 676419b0af8Sopenharmony_ci list_for_each_entry_safe(pos, tmp, &g_tui_drv_head, list) { 677419b0af8Sopenharmony_ci if (!strncmp(pos->name, name, TUI_DRV_NAME_MAX)) { 678419b0af8Sopenharmony_ci list_del(&pos->list); 679419b0af8Sopenharmony_ci kfree(pos); 680419b0af8Sopenharmony_ci break; 681419b0af8Sopenharmony_ci } 682419b0af8Sopenharmony_ci } 683419b0af8Sopenharmony_ci mutex_unlock(&g_tui_drv_lock); 684419b0af8Sopenharmony_ci} 685419b0af8Sopenharmony_ciEXPORT_SYMBOL(unregister_tui_driver); 686419b0af8Sopenharmony_ci 687419b0af8Sopenharmony_cistatic int add_tui_msg(int type, int val, void *data) 688419b0af8Sopenharmony_ci{ 689419b0af8Sopenharmony_ci struct tui_msg_node *tui_msg = NULL; 690419b0af8Sopenharmony_ci unsigned long flags; 691419b0af8Sopenharmony_ci 692419b0af8Sopenharmony_ci /* Return error if pdata is invalid */ 693419b0af8Sopenharmony_ci if (data == NULL) { 694419b0af8Sopenharmony_ci tloge("data is null"); 695419b0af8Sopenharmony_ci return -EINVAL; 696419b0af8Sopenharmony_ci } 697419b0af8Sopenharmony_ci 698419b0af8Sopenharmony_ci /* Allocate memory for tui_msg */ 699419b0af8Sopenharmony_ci tui_msg = kzalloc(sizeof(*tui_msg), GFP_KERNEL); 700419b0af8Sopenharmony_ci if (tui_msg == NULL) 701419b0af8Sopenharmony_ci return -ENOMEM; 702419b0af8Sopenharmony_ci 703419b0af8Sopenharmony_ci if (memset_s(tui_msg, sizeof(*tui_msg), 0, sizeof(*tui_msg)) != 0) { 704419b0af8Sopenharmony_ci tloge("tui_msg memset failed"); 705419b0af8Sopenharmony_ci kfree(tui_msg); 706419b0af8Sopenharmony_ci return -1; 707419b0af8Sopenharmony_ci } 708419b0af8Sopenharmony_ci 709419b0af8Sopenharmony_ci /* Assign the content of tui_msg */ 710419b0af8Sopenharmony_ci tui_msg->type = type; 711419b0af8Sopenharmony_ci tui_msg->val = val; 712419b0af8Sopenharmony_ci tui_msg->data = data; 713419b0af8Sopenharmony_ci INIT_LIST_HEAD(&tui_msg->list); 714419b0af8Sopenharmony_ci 715419b0af8Sopenharmony_ci /* Link the new tui_msg to the list */ 716419b0af8Sopenharmony_ci spin_lock_irqsave(&g_tui_msg_lock, flags); 717419b0af8Sopenharmony_ci list_add_tail(&tui_msg->list, &g_tui_msg_head); 718419b0af8Sopenharmony_ci g_tui_msg_flag = 1; 719419b0af8Sopenharmony_ci spin_unlock_irqrestore(&g_tui_msg_lock, flags); 720419b0af8Sopenharmony_ci return 0; 721419b0af8Sopenharmony_ci} 722419b0af8Sopenharmony_ci 723419b0af8Sopenharmony_cistatic int32_t init_each_tui_driver(struct tui_drv_node *pos, int32_t secure) 724419b0af8Sopenharmony_ci{ 725419b0af8Sopenharmony_ci if (secure == 0) { 726419b0af8Sopenharmony_ci tlogi("drv(%s) state=%d,%d\n", pos->name, secure, pos->state); 727419b0af8Sopenharmony_ci if (pos->state == 0) 728419b0af8Sopenharmony_ci return 0; 729419b0af8Sopenharmony_ci if (pos->init_func(pos->pdata, secure) != 0) 730419b0af8Sopenharmony_ci pos->state = -1; /* Process init_func() fail */ 731419b0af8Sopenharmony_ci 732419b0af8Sopenharmony_ci /* set secure state will be proceed in tui msg */ 733419b0af8Sopenharmony_ci pos->state = 0; 734419b0af8Sopenharmony_ci } else { 735419b0af8Sopenharmony_ci tlogi("init tui drv(%s) state=%d\n", pos->name, secure); 736419b0af8Sopenharmony_ci /* when init, tp and dss should be async */ 737419b0af8Sopenharmony_ci if (pos->init_func(pos->pdata, secure) != 0) { 738419b0af8Sopenharmony_ci pos->state = -1; 739419b0af8Sopenharmony_ci return -1; 740419b0af8Sopenharmony_ci } else { 741419b0af8Sopenharmony_ci#ifndef CONFIG_TEE_TUI_MTK 742419b0af8Sopenharmony_ci if (strncmp(TUI_DSS_NAME, pos->name, TUI_DRV_NAME_MAX) != 0) 743419b0af8Sopenharmony_ci#endif 744419b0af8Sopenharmony_ci pos->state = 1; 745419b0af8Sopenharmony_ci } 746419b0af8Sopenharmony_ci } 747419b0af8Sopenharmony_ci return 0; 748419b0af8Sopenharmony_ci} 749419b0af8Sopenharmony_ci 750419b0af8Sopenharmony_cienum tui_driver_env { 751419b0af8Sopenharmony_ci UNSECURE_ENV = 0, 752419b0af8Sopenharmony_ci SECURE_ENV = 1, 753419b0af8Sopenharmony_ci}; 754419b0af8Sopenharmony_ci 755419b0af8Sopenharmony_ci#define WAIT_POWER_ON_SLEEP_SPAN 20 756419b0af8Sopenharmony_cistatic int init_tui_dss_msg(const struct tui_drv_node *pos, int secure, int *count) 757419b0af8Sopenharmony_ci{ 758419b0af8Sopenharmony_ci if ((strncmp(TUI_DSS_NAME, pos->name, TUI_DRV_NAME_MAX) == 0) && (secure != 0)) { 759419b0af8Sopenharmony_ci tloge("init_tui_driver wait power on status---\n"); 760419b0af8Sopenharmony_ci#ifdef CONFIG_TEE_TUI_DISPLAY_3_0 761419b0af8Sopenharmony_ci while (!g_dss_fd->comp.power_on && (*count) < TIME_OUT_FOWER_ON) { 762419b0af8Sopenharmony_ci#else 763419b0af8Sopenharmony_ci while (!g_dss_fd->panel_power_on && (*count) < TIME_OUT_FOWER_ON) { 764419b0af8Sopenharmony_ci#endif 765419b0af8Sopenharmony_ci (*count)++; 766419b0af8Sopenharmony_ci msleep(WAIT_POWER_ON_SLEEP_SPAN); 767419b0af8Sopenharmony_ci } 768419b0af8Sopenharmony_ci if ((*count) == TIME_OUT_FOWER_ON) { 769419b0af8Sopenharmony_ci /* Time out. So return error. */ 770419b0af8Sopenharmony_ci tloge("wait status time out\n"); 771419b0af8Sopenharmony_ci return -1; 772419b0af8Sopenharmony_ci } 773419b0af8Sopenharmony_ci spin_lock(&g_tui_msg_lock); 774419b0af8Sopenharmony_ci tui_msg_del(TUI_DSS_NAME); 775419b0af8Sopenharmony_ci spin_unlock(&g_tui_msg_lock); 776419b0af8Sopenharmony_ci } 777419b0af8Sopenharmony_ci return 0; 778419b0af8Sopenharmony_ci} 779419b0af8Sopenharmony_ci 780419b0af8Sopenharmony_cistatic bool is_dss_registered(void) 781419b0af8Sopenharmony_ci{ 782419b0af8Sopenharmony_ci struct tui_drv_node *pos = NULL; 783419b0af8Sopenharmony_ci#if ONLY_INIT_TP == DSS_TP_COUPLE_MODE 784419b0af8Sopenharmony_ci return true; 785419b0af8Sopenharmony_ci#endif 786419b0af8Sopenharmony_ci list_for_each_entry(pos, &g_tui_drv_head, list) { 787419b0af8Sopenharmony_ci if (strncmp(TUI_DSS_NAME, pos->name, TUI_DRV_NAME_MAX) == 0) 788419b0af8Sopenharmony_ci return true; 789419b0af8Sopenharmony_ci } 790419b0af8Sopenharmony_ci return false; 791419b0af8Sopenharmony_ci} 792419b0af8Sopenharmony_ci 793419b0af8Sopenharmony_ci/* WARNING: Too many leading tabs - consider code refactoring */ 794419b0af8Sopenharmony_ci/* secure : 0-unsecure, 1-secure */ 795419b0af8Sopenharmony_cistatic int init_tui_driver(int secure) 796419b0af8Sopenharmony_ci{ 797419b0af8Sopenharmony_ci struct tui_drv_node *pos = NULL; 798419b0af8Sopenharmony_ci char *drv_name = NULL; 799419b0af8Sopenharmony_ci char **drv_array = g_deinit_driver; 800419b0af8Sopenharmony_ci int count = 0; 801419b0af8Sopenharmony_ci int i = 0; 802419b0af8Sopenharmony_ci int ret = 0; 803419b0af8Sopenharmony_ci if (g_dss_fd == NULL) 804419b0af8Sopenharmony_ci return -1; 805419b0af8Sopenharmony_ci 806419b0af8Sopenharmony_ci if (secure != 0) 807419b0af8Sopenharmony_ci drv_array = g_init_driver; 808419b0af8Sopenharmony_ci 809419b0af8Sopenharmony_ci while (i < DRIVER_NUM) { 810419b0af8Sopenharmony_ci drv_name = drv_array[i]; 811419b0af8Sopenharmony_ci i++; 812419b0af8Sopenharmony_ci mutex_lock(&g_tui_drv_lock); 813419b0af8Sopenharmony_ci 814419b0af8Sopenharmony_ci if (!is_dss_registered()) { 815419b0af8Sopenharmony_ci tloge("dss not registered\n"); 816419b0af8Sopenharmony_ci mutex_unlock(&g_tui_drv_lock); 817419b0af8Sopenharmony_ci return -1; 818419b0af8Sopenharmony_ci } 819419b0af8Sopenharmony_ci 820419b0af8Sopenharmony_ci /* Search all the tui_drv in their list */ 821419b0af8Sopenharmony_ci list_for_each_entry(pos, &g_tui_drv_head, list) { 822419b0af8Sopenharmony_ci if (strncmp(drv_name, pos->name, TUI_DRV_NAME_MAX) != 0) 823419b0af8Sopenharmony_ci continue; 824419b0af8Sopenharmony_ci 825419b0af8Sopenharmony_ci if (!strncmp(TUI_TP_NAME, pos->name, TUI_DRV_NAME_MAX)) { 826419b0af8Sopenharmony_ci /* If the name is "tp", assign pos->pdata to g_tui_ctl */ 827419b0af8Sopenharmony_ci g_tui_ctl->n2s.tp_info = (int)virt_to_phys(pos->pdata); 828419b0af8Sopenharmony_ci g_tui_ctl->n2s.tp_info_h_addr = virt_to_phys(pos->pdata) >> HIGH_VALUES; 829419b0af8Sopenharmony_ci } 830419b0af8Sopenharmony_ci if (pos->init_func == 0) 831419b0af8Sopenharmony_ci continue; 832419b0af8Sopenharmony_ci 833419b0af8Sopenharmony_ci ret = init_tui_dss_msg(pos, secure, &count); 834419b0af8Sopenharmony_ci if (ret != 0) { 835419b0af8Sopenharmony_ci mutex_unlock(&g_tui_drv_lock); 836419b0af8Sopenharmony_ci return ret; 837419b0af8Sopenharmony_ci } 838419b0af8Sopenharmony_ci 839419b0af8Sopenharmony_ci if (init_each_tui_driver(pos, secure) != 0) { 840419b0af8Sopenharmony_ci mutex_unlock(&g_tui_drv_lock); 841419b0af8Sopenharmony_ci return -1; 842419b0af8Sopenharmony_ci } 843419b0af8Sopenharmony_ci } 844419b0af8Sopenharmony_ci mutex_unlock(&g_tui_drv_lock); 845419b0af8Sopenharmony_ci } 846419b0af8Sopenharmony_ci 847419b0af8Sopenharmony_ci return 0; 848419b0af8Sopenharmony_ci} 849419b0af8Sopenharmony_ci 850419b0af8Sopenharmony_ci/* Only after all drivers cfg ok or some one failed, it need 851419b0af8Sopenharmony_ci * to add_tui_msg. 852419b0af8Sopenharmony_ci * ret val: 1 - all cfg ok 853419b0af8Sopenharmony_ci * 0 - cfg is not complete, or have done 854419b0af8Sopenharmony_ci * -1 - cfg failed 855419b0af8Sopenharmony_ci * -2 - invalid name 856419b0af8Sopenharmony_ci */ 857419b0af8Sopenharmony_cistatic int tui_cfg_filter(const char *name, bool ok) 858419b0af8Sopenharmony_ci{ 859419b0af8Sopenharmony_ci struct tui_drv_node *pos = NULL; 860419b0af8Sopenharmony_ci int find = 0; 861419b0af8Sopenharmony_ci int lock_flag = 0; 862419b0af8Sopenharmony_ci 863419b0af8Sopenharmony_ci /* Return error if name is invalid */ 864419b0af8Sopenharmony_ci if (name == NULL) { 865419b0af8Sopenharmony_ci tloge("name is null"); 866419b0af8Sopenharmony_ci return INVALID_CFG_NAME; 867419b0af8Sopenharmony_ci } 868419b0af8Sopenharmony_ci 869419b0af8Sopenharmony_ci /* some drivers may call send_tui_msg_config at the end 870419b0af8Sopenharmony_ci * of drv_init_func which had got the lock. 871419b0af8Sopenharmony_ci */ 872419b0af8Sopenharmony_ci if (mutex_is_locked(&g_tui_drv_lock)) 873419b0af8Sopenharmony_ci lock_flag = 1; 874419b0af8Sopenharmony_ci if (!lock_flag) 875419b0af8Sopenharmony_ci mutex_lock(&g_tui_drv_lock); 876419b0af8Sopenharmony_ci list_for_each_entry(pos, &g_tui_drv_head, list) { 877419b0af8Sopenharmony_ci if (strncmp(pos->name, name, TUI_DRV_NAME_MAX) != 0) 878419b0af8Sopenharmony_ci continue; 879419b0af8Sopenharmony_ci 880419b0af8Sopenharmony_ci find = 1; 881419b0af8Sopenharmony_ci if (ok) { 882419b0af8Sopenharmony_ci pos->state = 1; 883419b0af8Sopenharmony_ci } else { 884419b0af8Sopenharmony_ci if (!lock_flag) 885419b0af8Sopenharmony_ci mutex_unlock(&g_tui_drv_lock); 886419b0af8Sopenharmony_ci return -1; 887419b0af8Sopenharmony_ci } 888419b0af8Sopenharmony_ci } 889419b0af8Sopenharmony_ci if (!lock_flag) 890419b0af8Sopenharmony_ci mutex_unlock(&g_tui_drv_lock); 891419b0af8Sopenharmony_ci 892419b0af8Sopenharmony_ci if (find == 0) 893419b0af8Sopenharmony_ci return INVALID_CFG_NAME; 894419b0af8Sopenharmony_ci 895419b0af8Sopenharmony_ci return 1; 896419b0af8Sopenharmony_ci} 897419b0af8Sopenharmony_ci 898419b0af8Sopenharmony_cienum poll_class { 899419b0af8Sopenharmony_ci CLASS_POLL_CONFIG, 900419b0af8Sopenharmony_ci CLASS_POLL_RUNNING, 901419b0af8Sopenharmony_ci CLASS_POLL_COMMON, 902419b0af8Sopenharmony_ci CLASS_POLL_INVALID 903419b0af8Sopenharmony_ci}; 904419b0af8Sopenharmony_ci 905419b0af8Sopenharmony_cistatic enum poll_class tui_poll_class(int event_type) 906419b0af8Sopenharmony_ci{ 907419b0af8Sopenharmony_ci enum poll_class class = CLASS_POLL_INVALID; 908419b0af8Sopenharmony_ci 909419b0af8Sopenharmony_ci switch (event_type) { 910419b0af8Sopenharmony_ci case TUI_POLL_CFG_OK: 911419b0af8Sopenharmony_ci case TUI_POLL_CFG_FAIL: 912419b0af8Sopenharmony_ci case TUI_POLL_RESUME_TUI: 913419b0af8Sopenharmony_ci class = CLASS_POLL_CONFIG; 914419b0af8Sopenharmony_ci break; 915419b0af8Sopenharmony_ci case TUI_POLL_TP: 916419b0af8Sopenharmony_ci case TUI_POLL_TICK: 917419b0af8Sopenharmony_ci case TUI_POLL_DELAYED_WORK: 918419b0af8Sopenharmony_ci class = CLASS_POLL_RUNNING; 919419b0af8Sopenharmony_ci break; 920419b0af8Sopenharmony_ci case TUI_POLL_CANCEL: 921419b0af8Sopenharmony_ci class = CLASS_POLL_COMMON; 922419b0af8Sopenharmony_ci break; 923419b0af8Sopenharmony_ci default: 924419b0af8Sopenharmony_ci break; 925419b0af8Sopenharmony_ci } 926419b0af8Sopenharmony_ci return class; 927419b0af8Sopenharmony_ci} 928419b0af8Sopenharmony_ci 929419b0af8Sopenharmony_ciint send_tui_msg_config(int type, int val, void *data) 930419b0af8Sopenharmony_ci{ 931419b0af8Sopenharmony_ci int ret; 932419b0af8Sopenharmony_ci 933419b0af8Sopenharmony_ci if (type >= TUI_POLL_MAX || type < 0 || data == NULL) { 934419b0af8Sopenharmony_ci tloge("invalid tui event type\n"); 935419b0af8Sopenharmony_ci return -EINVAL; 936419b0af8Sopenharmony_ci } 937419b0af8Sopenharmony_ci 938419b0af8Sopenharmony_ci /* The g_tui_state should be CONFIG */ 939419b0af8Sopenharmony_ci if (atomic_read(&g_tui_state) != TUI_STATE_CONFIG) { 940419b0af8Sopenharmony_ci tloge("failed to send tui msg(%s)\n", poll_event_type_name[type]); 941419b0af8Sopenharmony_ci return -EINVAL; 942419b0af8Sopenharmony_ci } 943419b0af8Sopenharmony_ci 944419b0af8Sopenharmony_ci if (tui_poll_class(type) == CLASS_POLL_RUNNING) { 945419b0af8Sopenharmony_ci tloge("invalid tui event type(%s) in config state\n", poll_event_type_name[type]); 946419b0af8Sopenharmony_ci return -EINVAL; 947419b0af8Sopenharmony_ci } 948419b0af8Sopenharmony_ci 949419b0af8Sopenharmony_ci tlogi("send config event type %s(%s)\n", poll_event_type_name[type], (char *)data); 950419b0af8Sopenharmony_ci 951419b0af8Sopenharmony_ci if (type == TUI_POLL_CFG_OK || type == TUI_POLL_CFG_FAIL) { 952419b0af8Sopenharmony_ci int cfg_ret; 953419b0af8Sopenharmony_ci 954419b0af8Sopenharmony_ci cfg_ret = tui_cfg_filter((const char *)data, TUI_POLL_CFG_OK == type); 955419b0af8Sopenharmony_ci tlogd("tui driver(%s) cfg ret = %d\n", (char *)data, cfg_ret); 956419b0af8Sopenharmony_ci if (cfg_ret == INVALID_CFG_NAME) { 957419b0af8Sopenharmony_ci tloge("tui cfg filter failed, cfg_ret = %d\n", cfg_ret); 958419b0af8Sopenharmony_ci return -EINVAL; 959419b0af8Sopenharmony_ci } 960419b0af8Sopenharmony_ci } 961419b0af8Sopenharmony_ci 962419b0af8Sopenharmony_ci ret = add_tui_msg(type, val, data); 963419b0af8Sopenharmony_ci if (ret != 0) { 964419b0af8Sopenharmony_ci tloge("add tui msg ret=%d\n", ret); 965419b0af8Sopenharmony_ci return ret; 966419b0af8Sopenharmony_ci } 967419b0af8Sopenharmony_ci 968419b0af8Sopenharmony_ci tlogi("add config msg type %s\n", poll_event_type_name[type]); 969419b0af8Sopenharmony_ci 970419b0af8Sopenharmony_ci /* wake up tui kthread */ 971419b0af8Sopenharmony_ci wake_up(&g_tui_msg_wq); 972419b0af8Sopenharmony_ci 973419b0af8Sopenharmony_ci return 0; 974419b0af8Sopenharmony_ci} 975419b0af8Sopenharmony_ci 976419b0af8Sopenharmony_ci#define make32(high, low) ((((uint32_t)(high)) << 16) | (uint16_t)(low)) 977419b0af8Sopenharmony_ci 978419b0af8Sopenharmony_cistatic bool package_notch_msg(struct mb_cmd_pack *mb_pack, uint8_t **buf_to_tee, 979419b0af8Sopenharmony_ci struct teec_tui_parameter *tui_param) 980419b0af8Sopenharmony_ci{ 981419b0af8Sopenharmony_ci uint32_t buf_len = sizeof(*tui_param) - sizeof(tui_param->event_type); 982419b0af8Sopenharmony_ci *buf_to_tee = mailbox_alloc(buf_len, 0); 983419b0af8Sopenharmony_ci if (*buf_to_tee == NULL) { 984419b0af8Sopenharmony_ci tloge("failed to alloc memory!\n"); 985419b0af8Sopenharmony_ci return false; 986419b0af8Sopenharmony_ci } 987419b0af8Sopenharmony_ci if (memcpy_s(*buf_to_tee, buf_len, &tui_param->value, 988419b0af8Sopenharmony_ci sizeof(*tui_param) - sizeof(tui_param->event_type)) != EOK) { 989419b0af8Sopenharmony_ci tloge("copy notch data failed"); 990419b0af8Sopenharmony_ci mailbox_free(*buf_to_tee); 991419b0af8Sopenharmony_ci return false; 992419b0af8Sopenharmony_ci } 993419b0af8Sopenharmony_ci mb_pack->operation.paramtypes = 994419b0af8Sopenharmony_ci TEE_PARAM_TYPE_VALUE_INPUT | 995419b0af8Sopenharmony_ci (TEE_PARAM_TYPE_VALUE_INPUT << TEE_PARAM_NUM); 996419b0af8Sopenharmony_ci mb_pack->operation.params[0].value.a = 997419b0af8Sopenharmony_ci (uint32_t)mailbox_virt_to_phys((uintptr_t)*buf_to_tee); 998419b0af8Sopenharmony_ci mb_pack->operation.params[0].value.b = 999419b0af8Sopenharmony_ci (uint64_t)mailbox_virt_to_phys((uintptr_t)*buf_to_tee) >> ADDR_TRANS_NUM; 1000419b0af8Sopenharmony_ci mb_pack->operation.params[1].value.a = buf_len; 1001419b0af8Sopenharmony_ci return true; 1002419b0af8Sopenharmony_ci} 1003419b0af8Sopenharmony_ci 1004419b0af8Sopenharmony_cistatic void package_fold_msg(struct mb_cmd_pack *mb_pack, 1005419b0af8Sopenharmony_ci const struct teec_tui_parameter *tui_param) 1006419b0af8Sopenharmony_ci{ 1007419b0af8Sopenharmony_ci mb_pack->operation.paramtypes = teec_param_types(TEE_PARAM_TYPE_VALUE_INPUT, 1008419b0af8Sopenharmony_ci TEE_PARAM_TYPE_VALUE_INPUT, 1009419b0af8Sopenharmony_ci TEE_PARAM_TYPE_VALUE_INPUT, 1010419b0af8Sopenharmony_ci TEE_PARAM_TYPE_VALUE_INPUT); 1011419b0af8Sopenharmony_ci mb_pack->operation.params[0].value.a = tui_param->notch; 1012419b0af8Sopenharmony_ci#ifdef CONFIG_TEE_TUI_DISPLAY_3_0 1013419b0af8Sopenharmony_ci mb_pack->operation.params[0].value.b = make32(g_dss_fd->comp.base.xres, g_dss_fd->comp.base.yres); 1014419b0af8Sopenharmony_ci#else 1015419b0af8Sopenharmony_ci mb_pack->operation.params[0].value.b = make32(g_dss_fd->panel_info.xres, g_dss_fd->panel_info.yres); 1016419b0af8Sopenharmony_ci#endif 1017419b0af8Sopenharmony_ci mb_pack->operation.params[1].value.a = tui_param->phy_width; 1018419b0af8Sopenharmony_ci mb_pack->operation.params[1].value.b = tui_param->phy_height; 1019419b0af8Sopenharmony_ci mb_pack->operation.params[2].value.a = tui_param->width; 1020419b0af8Sopenharmony_ci mb_pack->operation.params[2].value.b = tui_param->height; 1021419b0af8Sopenharmony_ci mb_pack->operation.params[3].value.a = tui_param->fold_state; 1022419b0af8Sopenharmony_ci mb_pack->operation.params[3].value.b = tui_param->display_state; 1023419b0af8Sopenharmony_ci} 1024419b0af8Sopenharmony_ci 1025419b0af8Sopenharmony_cistatic bool check_uid_valid(uint32_t uid) 1026419b0af8Sopenharmony_ci{ 1027419b0af8Sopenharmony_ci#ifdef TUI_DAEMON_UID_IN_OH 1028419b0af8Sopenharmony_ci return (uid == TUI_DAEMON_UID_IN_OH || uid == 0); 1029419b0af8Sopenharmony_ci#else 1030419b0af8Sopenharmony_ci return uid <= UID_MAX_VAL; 1031419b0af8Sopenharmony_ci#endif 1032419b0af8Sopenharmony_ci} 1033419b0af8Sopenharmony_ci 1034419b0af8Sopenharmony_cistatic int32_t tui_send_smc_cmd(int32_t event, struct mb_cmd_pack *mb_pack, struct tc_ns_smc_cmd smc_cmd) 1035419b0af8Sopenharmony_ci{ 1036419b0af8Sopenharmony_ci uint32_t uid; 1037419b0af8Sopenharmony_ci kuid_t kuid; 1038419b0af8Sopenharmony_ci 1039419b0af8Sopenharmony_ci kuid = current_uid(); 1040419b0af8Sopenharmony_ci uid = kuid.val; 1041419b0af8Sopenharmony_ci 1042419b0af8Sopenharmony_ci if (check_uid_valid(uid) == false) { 1043419b0af8Sopenharmony_ci tloge("get invalid uid = %d\n", uid); 1044419b0af8Sopenharmony_ci return -1; 1045419b0af8Sopenharmony_ci } 1046419b0af8Sopenharmony_ci 1047419b0af8Sopenharmony_ci if ((event != TUI_POLL_CANCEL) && (event != TUI_POLL_NOTCH) && (event != TUI_POLL_FOLD)) { 1048419b0af8Sopenharmony_ci tloge("no permission to send msg\n"); 1049419b0af8Sopenharmony_ci return -1; 1050419b0af8Sopenharmony_ci } 1051419b0af8Sopenharmony_ci 1052419b0af8Sopenharmony_ci smc_cmd.cmd_type = CMD_TYPE_GLOBAL; 1053419b0af8Sopenharmony_ci smc_cmd.operation_phys = mailbox_virt_to_phys((uintptr_t)&mb_pack->operation); 1054419b0af8Sopenharmony_ci smc_cmd.operation_h_phys = mailbox_virt_to_phys((uintptr_t)&mb_pack->operation) >> HIGH_VALUES; 1055419b0af8Sopenharmony_ci smc_cmd.agent_id = event; 1056419b0af8Sopenharmony_ci smc_cmd.uid = uid; 1057419b0af8Sopenharmony_ci livepatch_down_read_sem(); 1058419b0af8Sopenharmony_ci int32_t ret = tc_ns_smc(&smc_cmd); 1059419b0af8Sopenharmony_ci livepatch_up_read_sem(); 1060419b0af8Sopenharmony_ci if (ret != 0) { 1061419b0af8Sopenharmony_ci tloge("tc ns smc fail 0x%x", ret); 1062419b0af8Sopenharmony_ci return ret; 1063419b0af8Sopenharmony_ci } 1064419b0af8Sopenharmony_ci 1065419b0af8Sopenharmony_ci return 0; 1066419b0af8Sopenharmony_ci} 1067419b0af8Sopenharmony_ci 1068419b0af8Sopenharmony_ci/* Send tui event by smc_cmd */ 1069419b0af8Sopenharmony_ciint tui_send_event(int event, struct teec_tui_parameter *tui_param) 1070419b0af8Sopenharmony_ci{ 1071419b0af8Sopenharmony_ci int status_temp; 1072419b0af8Sopenharmony_ci bool check_value = false; 1073419b0af8Sopenharmony_ci uint8_t *buf_to_tee = NULL; 1074419b0af8Sopenharmony_ci 1075419b0af8Sopenharmony_ci if (tui_param == NULL) 1076419b0af8Sopenharmony_ci return -1; 1077419b0af8Sopenharmony_ci 1078419b0af8Sopenharmony_ci if (event == TUI_POLL_NOTCH) { 1079419b0af8Sopenharmony_ci check_value = true; 1080419b0af8Sopenharmony_ci } else { 1081419b0af8Sopenharmony_ci if (g_dss_fd == NULL) 1082419b0af8Sopenharmony_ci return -1; 1083419b0af8Sopenharmony_ci 1084419b0af8Sopenharmony_ci status_temp = atomic_read(&g_tui_state); 1085419b0af8Sopenharmony_ci#ifdef CONFIG_TEE_TUI_DISPLAY_3_0 1086419b0af8Sopenharmony_ci check_value = (status_temp != TUI_STATE_UNUSED && g_dss_fd->comp.power_on) || event == TUI_POLL_FOLD; 1087419b0af8Sopenharmony_ci#else 1088419b0af8Sopenharmony_ci check_value = (status_temp != TUI_STATE_UNUSED && g_dss_fd->panel_power_on) || event == TUI_POLL_FOLD; 1089419b0af8Sopenharmony_ci#endif 1090419b0af8Sopenharmony_ci } 1091419b0af8Sopenharmony_ci 1092419b0af8Sopenharmony_ci if (check_value) { 1093419b0af8Sopenharmony_ci struct tc_ns_smc_cmd smc_cmd = { {0}, 0 }; 1094419b0af8Sopenharmony_ci struct mb_cmd_pack *mb_pack = NULL; 1095419b0af8Sopenharmony_ci int ret = 0; 1096419b0af8Sopenharmony_ci 1097419b0af8Sopenharmony_ci mb_pack = mailbox_alloc_cmd_pack(); 1098419b0af8Sopenharmony_ci if (mb_pack == NULL) { 1099419b0af8Sopenharmony_ci tloge("alloc cmd pack failed\n"); 1100419b0af8Sopenharmony_ci return -1; 1101419b0af8Sopenharmony_ci } 1102419b0af8Sopenharmony_ci 1103419b0af8Sopenharmony_ci switch (event) { 1104419b0af8Sopenharmony_ci case TUI_POLL_CANCEL: 1105419b0af8Sopenharmony_ci smc_cmd.cmd_id = GLOBAL_CMD_ID_TUI_EXCEPTION; 1106419b0af8Sopenharmony_ci break; 1107419b0af8Sopenharmony_ci case TUI_POLL_NOTCH: 1108419b0af8Sopenharmony_ci if (!package_notch_msg(mb_pack, &buf_to_tee, 1109419b0af8Sopenharmony_ci tui_param)) { 1110419b0af8Sopenharmony_ci mailbox_free(mb_pack); 1111419b0af8Sopenharmony_ci tloge("package notch msg failed\n"); 1112419b0af8Sopenharmony_ci return -1; 1113419b0af8Sopenharmony_ci } 1114419b0af8Sopenharmony_ci smc_cmd.cmd_id = GLOBAL_CMD_ID_TUI_NOTCH; 1115419b0af8Sopenharmony_ci break; 1116419b0af8Sopenharmony_ci case TUI_POLL_FOLD: 1117419b0af8Sopenharmony_ci package_fold_msg(mb_pack, tui_param); 1118419b0af8Sopenharmony_ci smc_cmd.cmd_id = GLOBAL_CMD_ID_TUI_FOLD; 1119419b0af8Sopenharmony_ci break; 1120419b0af8Sopenharmony_ci default: 1121419b0af8Sopenharmony_ci tloge("invalid event type : %d\n", event); 1122419b0af8Sopenharmony_ci break; 1123419b0af8Sopenharmony_ci } 1124419b0af8Sopenharmony_ci 1125419b0af8Sopenharmony_ci ret = tui_send_smc_cmd(event, mb_pack, smc_cmd); 1126419b0af8Sopenharmony_ci if (ret != 0) 1127419b0af8Sopenharmony_ci tloge("tui_send_smc_cmd error 0x%x", ret); 1128419b0af8Sopenharmony_ci 1129419b0af8Sopenharmony_ci mailbox_free(mb_pack); 1130419b0af8Sopenharmony_ci if (buf_to_tee != NULL) 1131419b0af8Sopenharmony_ci mailbox_free(buf_to_tee); 1132419b0af8Sopenharmony_ci return ret; 1133419b0af8Sopenharmony_ci } else { 1134419b0af8Sopenharmony_ci tlogi("tui unused no need send tui event!\n"); 1135419b0af8Sopenharmony_ci return 0; 1136419b0af8Sopenharmony_ci } 1137419b0af8Sopenharmony_ci} 1138419b0af8Sopenharmony_ci 1139419b0af8Sopenharmony_cistatic void tui_poweroff_work_func(struct work_struct *work) 1140419b0af8Sopenharmony_ci{ 1141419b0af8Sopenharmony_ci struct teec_tui_parameter tui_param = {0}; 1142419b0af8Sopenharmony_ci tui_send_event(TUI_POLL_CANCEL, &tui_param); 1143419b0af8Sopenharmony_ci} 1144419b0af8Sopenharmony_ci 1145419b0af8Sopenharmony_civoid tui_poweroff_work_start(void) 1146419b0af8Sopenharmony_ci{ 1147419b0af8Sopenharmony_ci tlogi("tui_poweroff_work_start----------\n"); 1148419b0af8Sopenharmony_ci if (g_dss_fd == NULL) 1149419b0af8Sopenharmony_ci return; 1150419b0af8Sopenharmony_ci 1151419b0af8Sopenharmony_ci#ifdef CONFIG_TEE_TUI_DISPLAY_3_0 1152419b0af8Sopenharmony_ci if (atomic_read(&g_tui_state) != TUI_STATE_UNUSED && g_dss_fd->comp.power_on) { 1153419b0af8Sopenharmony_ci#else 1154419b0af8Sopenharmony_ci if (atomic_read(&g_tui_state) != TUI_STATE_UNUSED && g_dss_fd->panel_power_on) { 1155419b0af8Sopenharmony_ci#endif 1156419b0af8Sopenharmony_ci tlogi("come in tui_poweroff_work_start state=%d--\n", 1157419b0af8Sopenharmony_ci atomic_read(&g_tui_state)); 1158419b0af8Sopenharmony_ci queue_work(system_wq, &tui_poweroff_work.work); 1159419b0af8Sopenharmony_ci } 1160419b0af8Sopenharmony_ci} 1161419b0af8Sopenharmony_ci 1162419b0af8Sopenharmony_cistatic void wait_tui_msg(void) 1163419b0af8Sopenharmony_ci{ 1164419b0af8Sopenharmony_ci#ifndef CONFIG_TEE_TUI_MTK 1165419b0af8Sopenharmony_ci if (wait_event_interruptible(g_tui_msg_wq, g_tui_msg_flag)) 1166419b0af8Sopenharmony_ci tloge("get tui state is interrupted\n"); 1167419b0af8Sopenharmony_ci#endif 1168419b0af8Sopenharmony_ci /* mtk is sync mess, don't need wait */ 1169419b0af8Sopenharmony_ci} 1170419b0af8Sopenharmony_ci 1171419b0af8Sopenharmony_cistatic int valid_msg(int msg_type) 1172419b0af8Sopenharmony_ci{ 1173419b0af8Sopenharmony_ci switch (msg_type) { 1174419b0af8Sopenharmony_ci case TUI_POLL_RESUME_TUI: 1175419b0af8Sopenharmony_ci if (atomic_read(&g_tui_state) == TUI_STATE_RUNNING) 1176419b0af8Sopenharmony_ci return 0; 1177419b0af8Sopenharmony_ci break; 1178419b0af8Sopenharmony_ci case TUI_POLL_CANCEL: 1179419b0af8Sopenharmony_ci if (atomic_read(&g_tui_state) == TUI_STATE_UNUSED) 1180419b0af8Sopenharmony_ci return 0; 1181419b0af8Sopenharmony_ci break; 1182419b0af8Sopenharmony_ci default: 1183419b0af8Sopenharmony_ci break; 1184419b0af8Sopenharmony_ci } 1185419b0af8Sopenharmony_ci 1186419b0af8Sopenharmony_ci return 1; 1187419b0af8Sopenharmony_ci} 1188419b0af8Sopenharmony_ci 1189419b0af8Sopenharmony_ci/* 1190419b0af8Sopenharmony_ci * 1: init ok 1191419b0af8Sopenharmony_ci * 0: still do init 1192419b0af8Sopenharmony_ci * -1: init failed 1193419b0af8Sopenharmony_ci */ 1194419b0af8Sopenharmony_cistatic int get_cfg_state(const char *name) 1195419b0af8Sopenharmony_ci{ 1196419b0af8Sopenharmony_ci const struct tui_msg_node *tui_msg = NULL; 1197419b0af8Sopenharmony_ci 1198419b0af8Sopenharmony_ci /* Return error if name is invalid */ 1199419b0af8Sopenharmony_ci if (name == NULL) { 1200419b0af8Sopenharmony_ci tloge("name is null"); 1201419b0af8Sopenharmony_ci return -1; 1202419b0af8Sopenharmony_ci } 1203419b0af8Sopenharmony_ci 1204419b0af8Sopenharmony_ci list_for_each_entry(tui_msg, &g_tui_msg_head, list) { 1205419b0af8Sopenharmony_ci /* Names match */ 1206419b0af8Sopenharmony_ci if (!strncmp(tui_msg->data, name, TUI_DRV_NAME_MAX)) { 1207419b0af8Sopenharmony_ci if (TUI_POLL_CFG_OK == tui_msg->type) 1208419b0af8Sopenharmony_ci return 1; 1209419b0af8Sopenharmony_ci else if (TUI_POLL_CFG_FAIL == tui_msg->type) 1210419b0af8Sopenharmony_ci return -1; 1211419b0af8Sopenharmony_ci else 1212419b0af8Sopenharmony_ci tloge("other state\n"); 1213419b0af8Sopenharmony_ci } 1214419b0af8Sopenharmony_ci } 1215419b0af8Sopenharmony_ci 1216419b0af8Sopenharmony_ci return 0; 1217419b0af8Sopenharmony_ci} 1218419b0af8Sopenharmony_ci 1219419b0af8Sopenharmony_cistatic void tui_msg_del(const char *name) 1220419b0af8Sopenharmony_ci{ 1221419b0af8Sopenharmony_ci struct tui_msg_node *tui_msg = NULL, *tmp = NULL; 1222419b0af8Sopenharmony_ci 1223419b0af8Sopenharmony_ci /* Return error if name is invalid */ 1224419b0af8Sopenharmony_ci if (name == NULL) { 1225419b0af8Sopenharmony_ci tloge("name is null"); 1226419b0af8Sopenharmony_ci return; 1227419b0af8Sopenharmony_ci } 1228419b0af8Sopenharmony_ci 1229419b0af8Sopenharmony_ci list_for_each_entry_safe(tui_msg, tmp, &g_tui_msg_head, list) { 1230419b0af8Sopenharmony_ci /* Names match */ 1231419b0af8Sopenharmony_ci if (!strncmp(tui_msg->data, name, TUI_DRV_NAME_MAX)) { 1232419b0af8Sopenharmony_ci list_del(&tui_msg->list); 1233419b0af8Sopenharmony_ci kfree(tui_msg); 1234419b0af8Sopenharmony_ci } 1235419b0af8Sopenharmony_ci } 1236419b0af8Sopenharmony_ci} 1237419b0af8Sopenharmony_ci#define DSS_CONFIG_INDEX 1 1238419b0af8Sopenharmony_ci#define TP_CONFIG_INDEX 2 1239419b0af8Sopenharmony_ci 1240419b0af8Sopenharmony_cistatic int32_t process_tui_poll_cfg(int32_t type) 1241419b0af8Sopenharmony_ci{ 1242419b0af8Sopenharmony_ci /* pre-process tui poll event if needed */ 1243419b0af8Sopenharmony_ci switch(type) { 1244419b0af8Sopenharmony_ci case TUI_POLL_CFG_OK: 1245419b0af8Sopenharmony_ci if (DSS_CONFIG_INDEX == g_tui_ctl->s2n.value) { 1246419b0af8Sopenharmony_ci phys_addr_t tui_addr_t; 1247419b0af8Sopenharmony_ci tui_addr_t = get_frame_addr(); 1248419b0af8Sopenharmony_ci if (tui_addr_t == 0) 1249419b0af8Sopenharmony_ci tloge("get frame addr error\n"); 1250419b0af8Sopenharmony_ci 1251419b0af8Sopenharmony_ci g_tui_ctl->n2s.addr = (unsigned int)tui_addr_t; 1252419b0af8Sopenharmony_ci g_tui_ctl->n2s.addr_h = tui_addr_t >> HIGH_VALUES; 1253419b0af8Sopenharmony_ci g_tui_ctl->n2s.npages = g_tui_display_mem.npages; 1254419b0af8Sopenharmony_ci g_tui_ctl->n2s.info_length = g_tui_display_mem.info_length; 1255419b0af8Sopenharmony_ci g_tui_ctl->n2s.phy_size = g_tui_display_mem.len; 1256419b0af8Sopenharmony_ci if (g_tui_ctl->n2s.addr == 0) 1257419b0af8Sopenharmony_ci return -1; 1258419b0af8Sopenharmony_ci } 1259419b0af8Sopenharmony_ci break; 1260419b0af8Sopenharmony_ci default: 1261419b0af8Sopenharmony_ci break; 1262419b0af8Sopenharmony_ci } 1263419b0af8Sopenharmony_ci 1264419b0af8Sopenharmony_ci return 0; 1265419b0af8Sopenharmony_ci} 1266419b0af8Sopenharmony_ci 1267419b0af8Sopenharmony_cistatic int32_t process_tui_msg_dss(void) 1268419b0af8Sopenharmony_ci{ 1269419b0af8Sopenharmony_ci int32_t type = TUI_POLL_CFG_OK; 1270419b0af8Sopenharmony_ci 1271419b0af8Sopenharmony_ci#if ONLY_INIT_TP != DSS_TP_COUPLE_MODE 1272419b0af8Sopenharmony_ci /* Wait, until DSS init finishs */ 1273419b0af8Sopenharmony_ci spin_lock(&g_tui_msg_lock); 1274419b0af8Sopenharmony_ci#ifdef CONFIG_TEE_TUI_MTK 1275419b0af8Sopenharmony_ci if (get_cfg_state(TUI_DSS_NAME) == 0) { 1276419b0af8Sopenharmony_ci#else 1277419b0af8Sopenharmony_ci while (get_cfg_state(TUI_DSS_NAME) == 0) { 1278419b0af8Sopenharmony_ci#endif 1279419b0af8Sopenharmony_ci tlogi("waiting for dss tui msg\n"); 1280419b0af8Sopenharmony_ci g_tui_msg_flag = 0; 1281419b0af8Sopenharmony_ci spin_unlock(&g_tui_msg_lock); 1282419b0af8Sopenharmony_ci wait_tui_msg(); 1283419b0af8Sopenharmony_ci tlogi("get dss init ok tui msg\n"); 1284419b0af8Sopenharmony_ci spin_lock(&g_tui_msg_lock); 1285419b0af8Sopenharmony_ci } 1286419b0af8Sopenharmony_ci if (get_cfg_state(TUI_DSS_NAME) == -1) { 1287419b0af8Sopenharmony_ci tloge("dss init failed\n"); 1288419b0af8Sopenharmony_ci type = TUI_POLL_CFG_FAIL; 1289419b0af8Sopenharmony_ci } 1290419b0af8Sopenharmony_ci /* Delete DSS msg from g_tui_msg_head */ 1291419b0af8Sopenharmony_ci tui_msg_del(TUI_DSS_NAME); 1292419b0af8Sopenharmony_ci spin_unlock(&g_tui_msg_lock); 1293419b0af8Sopenharmony_ci#endif 1294419b0af8Sopenharmony_ci 1295419b0af8Sopenharmony_ci return type; 1296419b0af8Sopenharmony_ci} 1297419b0af8Sopenharmony_ci 1298419b0af8Sopenharmony_cistatic int32_t process_tui_msg_tp(void) 1299419b0af8Sopenharmony_ci{ 1300419b0af8Sopenharmony_ci int32_t type = 0; 1301419b0af8Sopenharmony_ci 1302419b0af8Sopenharmony_ci spin_lock(&g_tui_msg_lock); 1303419b0af8Sopenharmony_ci#if ONLY_INIT_DSS != DSS_TP_COUPLE_MODE 1304419b0af8Sopenharmony_ci while (get_cfg_state(TUI_TP_NAME) == 0) { 1305419b0af8Sopenharmony_ci tlogi("waiting for tp tui msg\n"); 1306419b0af8Sopenharmony_ci g_tui_msg_flag = 0; 1307419b0af8Sopenharmony_ci spin_unlock(&g_tui_msg_lock); 1308419b0af8Sopenharmony_ci wait_tui_msg(); 1309419b0af8Sopenharmony_ci tlogi("get tp init ok tui msg\n"); 1310419b0af8Sopenharmony_ci spin_lock(&g_tui_msg_lock); 1311419b0af8Sopenharmony_ci } 1312419b0af8Sopenharmony_ci if (get_cfg_state(TUI_TP_NAME) == -1) { 1313419b0af8Sopenharmony_ci tloge("tp failed to do init\n"); 1314419b0af8Sopenharmony_ci tui_msg_del(TUI_TP_NAME); 1315419b0af8Sopenharmony_ci spin_unlock(&g_tui_msg_lock); 1316419b0af8Sopenharmony_ci return TUI_POLL_CFG_FAIL; 1317419b0af8Sopenharmony_ci } 1318419b0af8Sopenharmony_ci tui_msg_del(TUI_TP_NAME); 1319419b0af8Sopenharmony_ci#if defined CONFIG_TEE_TUI_FP 1320419b0af8Sopenharmony_ci if (init_tui_driver(1) == 0) { 1321419b0af8Sopenharmony_ci while (get_cfg_state(TUI_GPIO_NAME) == 0 || 1322419b0af8Sopenharmony_ci get_cfg_state(TUI_FP_NAME) == 0) { 1323419b0af8Sopenharmony_ci tlogd("waiting for gpio/fp tui msg\n"); 1324419b0af8Sopenharmony_ci g_tui_msg_flag = 0; 1325419b0af8Sopenharmony_ci spin_unlock(&g_tui_msg_lock); 1326419b0af8Sopenharmony_ci wait_tui_msg(); 1327419b0af8Sopenharmony_ci tlogd("get gpio/fp init ok tui msg\n"); 1328419b0af8Sopenharmony_ci spin_lock(&g_tui_msg_lock); 1329419b0af8Sopenharmony_ci } 1330419b0af8Sopenharmony_ci if (get_cfg_state(TUI_GPIO_NAME) == -1 || 1331419b0af8Sopenharmony_ci get_cfg_state(TUI_FP_NAME) == -1) { 1332419b0af8Sopenharmony_ci tloge("one of gpio/fp failed to do init\n"); 1333419b0af8Sopenharmony_ci type = TUI_POLL_CFG_FAIL; 1334419b0af8Sopenharmony_ci } 1335419b0af8Sopenharmony_ci } 1336419b0af8Sopenharmony_ci tui_msg_del(TUI_GPIO_NAME); 1337419b0af8Sopenharmony_ci tui_msg_del(TUI_FP_NAME); 1338419b0af8Sopenharmony_ci#endif 1339419b0af8Sopenharmony_ci tlogd("tp/gpio/fp is config result:type = 0x%x\n", type); 1340419b0af8Sopenharmony_ci#endif 1341419b0af8Sopenharmony_ci spin_unlock(&g_tui_msg_lock); 1342419b0af8Sopenharmony_ci return type; 1343419b0af8Sopenharmony_ci} 1344419b0af8Sopenharmony_ci 1345419b0af8Sopenharmony_cistatic void process_tui_msg(void) 1346419b0af8Sopenharmony_ci{ 1347419b0af8Sopenharmony_ci int32_t val = 0; 1348419b0af8Sopenharmony_ci int32_t type = TUI_POLL_CFG_OK; 1349419b0af8Sopenharmony_ci 1350419b0af8Sopenharmony_cifetch_msg: 1351419b0af8Sopenharmony_ci if (g_tui_ctl->s2n.value == DSS_CONFIG_INDEX) 1352419b0af8Sopenharmony_ci type = process_tui_msg_dss(); 1353419b0af8Sopenharmony_ci else if (g_tui_ctl->s2n.value == TP_CONFIG_INDEX) 1354419b0af8Sopenharmony_ci type = process_tui_msg_tp(); 1355419b0af8Sopenharmony_ci else 1356419b0af8Sopenharmony_ci tloge("wait others dev\n"); 1357419b0af8Sopenharmony_ci 1358419b0af8Sopenharmony_ci val = process_tui_poll_cfg(type); 1359419b0af8Sopenharmony_ci 1360419b0af8Sopenharmony_ci g_tui_ctl->n2s.event_type = type; 1361419b0af8Sopenharmony_ci g_tui_ctl->n2s.value = val; 1362419b0af8Sopenharmony_ci 1363419b0af8Sopenharmony_ci if (!valid_msg(g_tui_ctl->n2s.event_type)) { 1364419b0af8Sopenharmony_ci tlogi("refetch tui msg\n"); 1365419b0af8Sopenharmony_ci goto fetch_msg; 1366419b0af8Sopenharmony_ci } 1367419b0af8Sopenharmony_ci} 1368419b0af8Sopenharmony_ci 1369419b0af8Sopenharmony_cistatic int init_tui_agent(void) 1370419b0af8Sopenharmony_ci{ 1371419b0af8Sopenharmony_ci int ret; 1372419b0af8Sopenharmony_ci 1373419b0af8Sopenharmony_ci ret = tc_ns_register_agent(NULL, TEE_TUI_AGENT_ID, SZ_4K, (void **)(&g_tui_ctl), false); 1374419b0af8Sopenharmony_ci if (ret != 0) { 1375419b0af8Sopenharmony_ci tloge("register tui agent failed, ret = 0x%x\n", ret); 1376419b0af8Sopenharmony_ci g_tui_ctl = NULL; 1377419b0af8Sopenharmony_ci return -EFAULT; 1378419b0af8Sopenharmony_ci } 1379419b0af8Sopenharmony_ci 1380419b0af8Sopenharmony_ci return 0; 1381419b0af8Sopenharmony_ci} 1382419b0af8Sopenharmony_ci 1383419b0af8Sopenharmony_cistatic void exit_tui_agent(void) 1384419b0af8Sopenharmony_ci{ 1385419b0af8Sopenharmony_ci if (tc_ns_unregister_agent(TEE_TUI_AGENT_ID) != 0) 1386419b0af8Sopenharmony_ci tloge("unregister tui agent failed\n"); 1387419b0af8Sopenharmony_ci 1388419b0af8Sopenharmony_ci g_tui_ctl = NULL; 1389419b0af8Sopenharmony_ci} 1390419b0af8Sopenharmony_ci 1391419b0af8Sopenharmony_cistatic void set_tui_state(int state) 1392419b0af8Sopenharmony_ci{ 1393419b0af8Sopenharmony_ci if (state < TUI_STATE_UNUSED || state > TUI_STATE_ERROR) { 1394419b0af8Sopenharmony_ci tloge("state=%d is invalid\n", state); 1395419b0af8Sopenharmony_ci return; 1396419b0af8Sopenharmony_ci } 1397419b0af8Sopenharmony_ci if (atomic_read(&g_tui_state) != state) { 1398419b0af8Sopenharmony_ci atomic_set(&g_tui_state, state); 1399419b0af8Sopenharmony_ci tloge("set ree tui state is %d, 0: unused, 1:config, 2:running\n", state); 1400419b0af8Sopenharmony_ci g_tui_state_flag = 1; 1401419b0af8Sopenharmony_ci wake_up(&g_tui_state_wq); 1402419b0af8Sopenharmony_ci } 1403419b0af8Sopenharmony_ci} 1404419b0af8Sopenharmony_ci 1405419b0af8Sopenharmony_ciint is_tui_in_use(int pid_value) 1406419b0af8Sopenharmony_ci{ 1407419b0af8Sopenharmony_ci if (pid_value == atomic_read(&g_tui_pid)) 1408419b0af8Sopenharmony_ci return 1; 1409419b0af8Sopenharmony_ci return 0; 1410419b0af8Sopenharmony_ci} 1411419b0af8Sopenharmony_ci 1412419b0af8Sopenharmony_civoid free_tui_caller_info(void) 1413419b0af8Sopenharmony_ci{ 1414419b0af8Sopenharmony_ci atomic_set(&g_tui_attached_device, TUI_PID_CLEAR); 1415419b0af8Sopenharmony_ci atomic_set(&g_tui_pid, TUI_PID_CLEAR); 1416419b0af8Sopenharmony_ci} 1417419b0af8Sopenharmony_ci 1418419b0af8Sopenharmony_cistatic int agent_process_work_tui(void) 1419419b0af8Sopenharmony_ci{ 1420419b0af8Sopenharmony_ci struct smc_event_data *event_data = NULL; 1421419b0af8Sopenharmony_ci 1422419b0af8Sopenharmony_ci event_data = find_event_control(TEE_TUI_AGENT_ID); 1423419b0af8Sopenharmony_ci if (event_data == NULL || atomic_read(&event_data->agent_ready) == AGENT_CRASHED) { 1424419b0af8Sopenharmony_ci /* if return, the pending task in S can't be resumed!! */ 1425419b0af8Sopenharmony_ci tloge("tui agent is not exist\n"); 1426419b0af8Sopenharmony_ci put_agent_event(event_data); 1427419b0af8Sopenharmony_ci return TEEC_ERROR_GENERIC; 1428419b0af8Sopenharmony_ci } 1429419b0af8Sopenharmony_ci 1430419b0af8Sopenharmony_ci isb(); 1431419b0af8Sopenharmony_ci wmb(); 1432419b0af8Sopenharmony_ci event_data->ret_flag = 1; 1433419b0af8Sopenharmony_ci /* Wake up tui agent that will process the command */ 1434419b0af8Sopenharmony_ci wake_up(&event_data->wait_event_wq); 1435419b0af8Sopenharmony_ci 1436419b0af8Sopenharmony_ci tlogi("agent 0x%x request, goto sleep, pe->run=%d\n", 1437419b0af8Sopenharmony_ci TEE_TUI_AGENT_ID, atomic_read(&event_data->ca_run)); 1438419b0af8Sopenharmony_ci wait_event(event_data->ca_pending_wq, atomic_read(&event_data->ca_run)); 1439419b0af8Sopenharmony_ci atomic_set(&event_data->ca_run, 0); 1440419b0af8Sopenharmony_ci put_agent_event(event_data); 1441419b0af8Sopenharmony_ci 1442419b0af8Sopenharmony_ci return TEEC_SUCCESS; 1443419b0af8Sopenharmony_ci} 1444419b0af8Sopenharmony_ci 1445419b0af8Sopenharmony_civoid do_ns_tui_release(void) 1446419b0af8Sopenharmony_ci{ 1447419b0af8Sopenharmony_ci if (atomic_read(&g_tui_state) != TUI_STATE_UNUSED) { 1448419b0af8Sopenharmony_ci g_tui_ctl->s2n.command = TUI_CMD_EXIT; 1449419b0af8Sopenharmony_ci g_tui_ctl->s2n.ret = -1; 1450419b0af8Sopenharmony_ci tloge("exec tui do_ns_tui_release\n"); 1451419b0af8Sopenharmony_ci if (agent_process_work_tui() != 0) 1452419b0af8Sopenharmony_ci tloge("wake up tui agent error\n"); 1453419b0af8Sopenharmony_ci } 1454419b0af8Sopenharmony_ci} 1455419b0af8Sopenharmony_ci 1456419b0af8Sopenharmony_cistatic int32_t do_tui_ttf_work(void) 1457419b0af8Sopenharmony_ci{ 1458419b0af8Sopenharmony_ci int ret = 0; 1459419b0af8Sopenharmony_ci switch (g_tui_ctl->s2n.command) { 1460419b0af8Sopenharmony_ci case TUI_CMD_LOAD_TTF: 1461419b0af8Sopenharmony_ci ret = load_tui_font_file(); 1462419b0af8Sopenharmony_ci if (ret == 0) { 1463419b0af8Sopenharmony_ci tlogi("=======succeed to load ttf\n"); 1464419b0af8Sopenharmony_ci g_tui_ctl->n2s.event_type = TUI_POLL_CFG_OK; 1465419b0af8Sopenharmony_ci } else { 1466419b0af8Sopenharmony_ci tloge("Failed to load normal ttf ret is 0x%x\n", ret); 1467419b0af8Sopenharmony_ci g_tui_ctl->n2s.event_type = TUI_POLL_CFG_FAIL; 1468419b0af8Sopenharmony_ci } 1469419b0af8Sopenharmony_ci break; 1470419b0af8Sopenharmony_ci case TUI_CMD_EXIT: 1471419b0af8Sopenharmony_ci if (atomic_read(&g_tui_state) != TUI_STATE_UNUSED && 1472419b0af8Sopenharmony_ci atomic_dec_and_test(&g_tui_usage)) { 1473419b0af8Sopenharmony_ci tlogi("tui disable\n"); 1474419b0af8Sopenharmony_ci (void)init_tui_driver(UNSECURE_ENV); 1475419b0af8Sopenharmony_ci free_frame_addr(); 1476419b0af8Sopenharmony_ci free_tui_font_mem(); 1477419b0af8Sopenharmony_ci free_tui_caller_info(); 1478419b0af8Sopenharmony_ci set_tui_state(TUI_STATE_UNUSED); 1479419b0af8Sopenharmony_ci } 1480419b0af8Sopenharmony_ci break; 1481419b0af8Sopenharmony_ci case TUI_CMD_FREE_TTF_MEM: 1482419b0af8Sopenharmony_ci free_tui_font_mem(); 1483419b0af8Sopenharmony_ci ret = 0; 1484419b0af8Sopenharmony_ci break; 1485419b0af8Sopenharmony_ci default: 1486419b0af8Sopenharmony_ci ret = -EINVAL; 1487419b0af8Sopenharmony_ci tloge("get error ttf tui command(0x%x)\n", g_tui_ctl->s2n.command); 1488419b0af8Sopenharmony_ci break; 1489419b0af8Sopenharmony_ci } 1490419b0af8Sopenharmony_ci return ret; 1491419b0af8Sopenharmony_ci} 1492419b0af8Sopenharmony_ci 1493419b0af8Sopenharmony_cistatic void process_tui_enable(void) 1494419b0af8Sopenharmony_ci{ 1495419b0af8Sopenharmony_ci if (atomic_read(&g_tui_state) == TUI_STATE_CONFIG) 1496419b0af8Sopenharmony_ci return; 1497419b0af8Sopenharmony_ci 1498419b0af8Sopenharmony_ci tlogi("tui enable\n"); 1499419b0af8Sopenharmony_ci set_tui_state(TUI_STATE_CONFIG); 1500419b0af8Sopenharmony_ci /* do dss and tp init */ 1501419b0af8Sopenharmony_ci if (init_tui_driver(SECURE_ENV) != 0) { 1502419b0af8Sopenharmony_ci g_tui_ctl->s2n.ret = -1; 1503419b0af8Sopenharmony_ci set_tui_state(TUI_STATE_ERROR); 1504419b0af8Sopenharmony_ci (void)init_tui_driver(UNSECURE_ENV); 1505419b0af8Sopenharmony_ci free_tui_caller_info(); 1506419b0af8Sopenharmony_ci set_tui_state(TUI_STATE_UNUSED); 1507419b0af8Sopenharmony_ci return; 1508419b0af8Sopenharmony_ci } 1509419b0af8Sopenharmony_ci atomic_inc(&g_tui_usage); 1510419b0af8Sopenharmony_ci} 1511419b0af8Sopenharmony_ci 1512419b0af8Sopenharmony_cistatic void process_tui_disable(void) 1513419b0af8Sopenharmony_ci{ 1514419b0af8Sopenharmony_ci if (atomic_read(&g_tui_state) == TUI_STATE_UNUSED || 1515419b0af8Sopenharmony_ci !atomic_dec_and_test(&g_tui_usage)) 1516419b0af8Sopenharmony_ci return; 1517419b0af8Sopenharmony_ci 1518419b0af8Sopenharmony_ci tlogi("tui disable\n"); 1519419b0af8Sopenharmony_ci (void)init_tui_driver(UNSECURE_ENV); 1520419b0af8Sopenharmony_ci free_frame_addr(); 1521419b0af8Sopenharmony_ci free_tui_caller_info(); 1522419b0af8Sopenharmony_ci set_tui_state(TUI_STATE_UNUSED); 1523419b0af8Sopenharmony_ci} 1524419b0af8Sopenharmony_ci 1525419b0af8Sopenharmony_cistatic void process_tui_pause(void) 1526419b0af8Sopenharmony_ci{ 1527419b0af8Sopenharmony_ci if (atomic_read(&g_tui_state) == TUI_STATE_UNUSED) 1528419b0af8Sopenharmony_ci return; 1529419b0af8Sopenharmony_ci 1530419b0af8Sopenharmony_ci tlogi("tui pause\n"); 1531419b0af8Sopenharmony_ci (void)init_tui_driver(UNSECURE_ENV); 1532419b0af8Sopenharmony_ci set_tui_state(TUI_STATE_CONFIG); 1533419b0af8Sopenharmony_ci} 1534419b0af8Sopenharmony_ci 1535419b0af8Sopenharmony_cistatic int do_tui_config_work(void) 1536419b0af8Sopenharmony_ci{ 1537419b0af8Sopenharmony_ci int ret = 0; 1538419b0af8Sopenharmony_ci 1539419b0af8Sopenharmony_ci switch (g_tui_ctl->s2n.command) { 1540419b0af8Sopenharmony_ci case TUI_CMD_ENABLE: 1541419b0af8Sopenharmony_ci process_tui_enable(); 1542419b0af8Sopenharmony_ci break; 1543419b0af8Sopenharmony_ci case TUI_CMD_DISABLE: 1544419b0af8Sopenharmony_ci process_tui_disable(); 1545419b0af8Sopenharmony_ci break; 1546419b0af8Sopenharmony_ci case TUI_CMD_PAUSE: 1547419b0af8Sopenharmony_ci process_tui_pause(); 1548419b0af8Sopenharmony_ci break; 1549419b0af8Sopenharmony_ci case TUI_CMD_POLL: 1550419b0af8Sopenharmony_ci process_tui_msg(); 1551419b0af8Sopenharmony_ci break; 1552419b0af8Sopenharmony_ci case TUI_CMD_DO_SYNC: 1553419b0af8Sopenharmony_ci tlogd("enable tp irq cmd\n"); 1554419b0af8Sopenharmony_ci break; 1555419b0af8Sopenharmony_ci case TUI_CMD_SET_STATE: 1556419b0af8Sopenharmony_ci tlogi("tui set state %d\n", g_tui_ctl->s2n.value); 1557419b0af8Sopenharmony_ci set_tui_state(g_tui_ctl->s2n.value); 1558419b0af8Sopenharmony_ci break; 1559419b0af8Sopenharmony_ci case TUI_CMD_START_DELAY_WORK: 1560419b0af8Sopenharmony_ci tlogd("start delay work\n"); 1561419b0af8Sopenharmony_ci break; 1562419b0af8Sopenharmony_ci case TUI_CMD_CANCEL_DELAY_WORK: 1563419b0af8Sopenharmony_ci tlogd("cancel delay work\n"); 1564419b0af8Sopenharmony_ci break; 1565419b0af8Sopenharmony_ci default: 1566419b0af8Sopenharmony_ci ret = -EINVAL; 1567419b0af8Sopenharmony_ci tloge("get error config tui command(0x%x)\n", g_tui_ctl->s2n.command); 1568419b0af8Sopenharmony_ci break; 1569419b0af8Sopenharmony_ci } 1570419b0af8Sopenharmony_ci return ret; 1571419b0af8Sopenharmony_ci} 1572419b0af8Sopenharmony_ci 1573419b0af8Sopenharmony_cistatic int do_tui_work(void) 1574419b0af8Sopenharmony_ci{ 1575419b0af8Sopenharmony_ci int ret = 0; 1576419b0af8Sopenharmony_ci 1577419b0af8Sopenharmony_ci /* clear s2n cmd ret */ 1578419b0af8Sopenharmony_ci g_tui_ctl->s2n.ret = 0; 1579419b0af8Sopenharmony_ci switch (g_tui_ctl->s2n.command) { 1580419b0af8Sopenharmony_ci case TUI_CMD_ENABLE: 1581419b0af8Sopenharmony_ci case TUI_CMD_DISABLE: 1582419b0af8Sopenharmony_ci case TUI_CMD_PAUSE: 1583419b0af8Sopenharmony_ci case TUI_CMD_POLL: 1584419b0af8Sopenharmony_ci case TUI_CMD_DO_SYNC: 1585419b0af8Sopenharmony_ci case TUI_CMD_SET_STATE: 1586419b0af8Sopenharmony_ci case TUI_CMD_START_DELAY_WORK: 1587419b0af8Sopenharmony_ci case TUI_CMD_CANCEL_DELAY_WORK: 1588419b0af8Sopenharmony_ci ret = do_tui_config_work(); 1589419b0af8Sopenharmony_ci break; 1590419b0af8Sopenharmony_ci case TUI_CMD_LOAD_TTF: 1591419b0af8Sopenharmony_ci case TUI_CMD_EXIT: 1592419b0af8Sopenharmony_ci case TUI_CMD_FREE_TTF_MEM: 1593419b0af8Sopenharmony_ci ret = do_tui_ttf_work(); 1594419b0af8Sopenharmony_ci break; 1595419b0af8Sopenharmony_ci default: 1596419b0af8Sopenharmony_ci ret = -EINVAL; 1597419b0af8Sopenharmony_ci tloge("get error tui command\n"); 1598419b0af8Sopenharmony_ci break; 1599419b0af8Sopenharmony_ci } 1600419b0af8Sopenharmony_ci return ret; 1601419b0af8Sopenharmony_ci} 1602419b0af8Sopenharmony_ci 1603419b0af8Sopenharmony_civoid set_tui_caller_info(unsigned int devid, int pid) 1604419b0af8Sopenharmony_ci{ 1605419b0af8Sopenharmony_ci atomic_set(&g_tui_attached_device, (int)devid); 1606419b0af8Sopenharmony_ci atomic_set(&g_tui_pid, pid); 1607419b0af8Sopenharmony_ci} 1608419b0af8Sopenharmony_ci 1609419b0af8Sopenharmony_ciunsigned int tui_attach_device(void) 1610419b0af8Sopenharmony_ci{ 1611419b0af8Sopenharmony_ci return (unsigned int)atomic_read(&g_tui_attached_device); 1612419b0af8Sopenharmony_ci} 1613419b0af8Sopenharmony_ci 1614419b0af8Sopenharmony_cistatic int tui_kthread_work_fn(void *data) 1615419b0af8Sopenharmony_ci{ 1616419b0af8Sopenharmony_ci int ret; 1617419b0af8Sopenharmony_ci ret = init_tui_agent(); 1618419b0af8Sopenharmony_ci if (ret != 0) { 1619419b0af8Sopenharmony_ci tloge("init tui agent error, ret = %d\n", ret); 1620419b0af8Sopenharmony_ci return ret; 1621419b0af8Sopenharmony_ci } 1622419b0af8Sopenharmony_ci 1623419b0af8Sopenharmony_ci while (1) { 1624419b0af8Sopenharmony_ci tc_ns_wait_event(TEE_TUI_AGENT_ID); 1625419b0af8Sopenharmony_ci 1626419b0af8Sopenharmony_ci if (kthread_should_stop()) 1627419b0af8Sopenharmony_ci break; 1628419b0af8Sopenharmony_ci 1629419b0af8Sopenharmony_ci do_tui_work(); 1630419b0af8Sopenharmony_ci 1631419b0af8Sopenharmony_ci if (tc_ns_send_event_response(TEE_TUI_AGENT_ID) != 0) 1632419b0af8Sopenharmony_ci tloge("send event response error\n"); 1633419b0af8Sopenharmony_ci } 1634419b0af8Sopenharmony_ci 1635419b0af8Sopenharmony_ci exit_tui_agent(); 1636419b0af8Sopenharmony_ci 1637419b0af8Sopenharmony_ci return 0; 1638419b0af8Sopenharmony_ci} 1639419b0af8Sopenharmony_ci 1640419b0af8Sopenharmony_ci#define READ_BUF 128 1641419b0af8Sopenharmony_cistatic ssize_t tui_dbg_state_read(struct file *filp, char __user *ubuf, 1642419b0af8Sopenharmony_ci size_t cnt, loff_t *ppos) 1643419b0af8Sopenharmony_ci{ 1644419b0af8Sopenharmony_ci char buf[READ_BUF] = {0}; 1645419b0af8Sopenharmony_ci unsigned int r; 1646419b0af8Sopenharmony_ci int ret; 1647419b0af8Sopenharmony_ci struct tui_drv_node *pos = NULL; 1648419b0af8Sopenharmony_ci 1649419b0af8Sopenharmony_ci if (filp == NULL || ubuf == NULL || ppos == NULL) 1650419b0af8Sopenharmony_ci return -EINVAL; 1651419b0af8Sopenharmony_ci 1652419b0af8Sopenharmony_ci ret = snprintf_s(buf, READ_BUF, READ_BUF - 1, "tui state:%s\n", 1653419b0af8Sopenharmony_ci state_name[atomic_read(&g_tui_state)]); 1654419b0af8Sopenharmony_ci if (ret < 0) { 1655419b0af8Sopenharmony_ci tloge("tui dbg state read 1 snprintf is failed, ret = 0x%x\n", ret); 1656419b0af8Sopenharmony_ci return -EINVAL; 1657419b0af8Sopenharmony_ci } 1658419b0af8Sopenharmony_ci r = (unsigned int)ret; 1659419b0af8Sopenharmony_ci 1660419b0af8Sopenharmony_ci ret = snprintf_s(buf + r, READ_BUF - r, READ_BUF - r - 1, "%s", "drv config state:"); 1661419b0af8Sopenharmony_ci if (ret < 0) { 1662419b0af8Sopenharmony_ci tloge("tui dbg state read 2 snprintf is failed, ret = 0x%x\n", ret); 1663419b0af8Sopenharmony_ci return -EINVAL; 1664419b0af8Sopenharmony_ci } 1665419b0af8Sopenharmony_ci r += (unsigned int)ret; 1666419b0af8Sopenharmony_ci 1667419b0af8Sopenharmony_ci mutex_lock(&g_tui_drv_lock); 1668419b0af8Sopenharmony_ci list_for_each_entry(pos, &g_tui_drv_head, list) { 1669419b0af8Sopenharmony_ci ret = snprintf_s(buf + r, READ_BUF - r, READ_BUF - r - 1, "%s-%s,", pos->name, 1 == pos->state ? "ok" : "no ok"); 1670419b0af8Sopenharmony_ci if (ret < 0) { 1671419b0af8Sopenharmony_ci tloge("tui dbg state read 3 snprintf is failed, ret = 0x%x\n", ret); 1672419b0af8Sopenharmony_ci mutex_unlock(&g_tui_drv_lock); 1673419b0af8Sopenharmony_ci return -EINVAL; 1674419b0af8Sopenharmony_ci } 1675419b0af8Sopenharmony_ci r += (unsigned int)ret; 1676419b0af8Sopenharmony_ci } 1677419b0af8Sopenharmony_ci mutex_unlock(&g_tui_drv_lock); 1678419b0af8Sopenharmony_ci if (r < READ_BUF) 1679419b0af8Sopenharmony_ci buf[r - 1] = '\n'; 1680419b0af8Sopenharmony_ci 1681419b0af8Sopenharmony_ci return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); 1682419b0af8Sopenharmony_ci} 1683419b0af8Sopenharmony_ci 1684419b0af8Sopenharmony_cistatic const struct file_operations tui_dbg_state_fops = { 1685419b0af8Sopenharmony_ci .owner = THIS_MODULE, 1686419b0af8Sopenharmony_ci .read = tui_dbg_state_read, 1687419b0af8Sopenharmony_ci}; 1688419b0af8Sopenharmony_ci 1689419b0af8Sopenharmony_ci#define MAX_SHOW_BUFF_LEN 32 1690419b0af8Sopenharmony_cistatic ssize_t tui_status_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) 1691419b0af8Sopenharmony_ci{ 1692419b0af8Sopenharmony_ci int r; 1693419b0af8Sopenharmony_ci size_t buf_len = 0; 1694419b0af8Sopenharmony_ci if (kobj == NULL || attr == NULL || buf == NULL) 1695419b0af8Sopenharmony_ci return -EINVAL; 1696419b0af8Sopenharmony_ci 1697419b0af8Sopenharmony_ci g_tui_state_flag = 0; 1698419b0af8Sopenharmony_ci r = wait_event_interruptible(g_tui_state_wq, g_tui_state_flag); 1699419b0af8Sopenharmony_ci if (r != 0) { 1700419b0af8Sopenharmony_ci tloge("get tui state is interrupted\n"); 1701419b0af8Sopenharmony_ci return r; 1702419b0af8Sopenharmony_ci } 1703419b0af8Sopenharmony_ci buf_len = MAX_SHOW_BUFF_LEN; 1704419b0af8Sopenharmony_ci r = snprintf_s(buf, buf_len, buf_len - 1, "%s", state_name[atomic_read(&g_tui_state)]); 1705419b0af8Sopenharmony_ci if (r < 0) { 1706419b0af8Sopenharmony_ci tloge("tui status show snprintf is failed, ret = 0x%x\n", r); 1707419b0af8Sopenharmony_ci return -1; 1708419b0af8Sopenharmony_ci } 1709419b0af8Sopenharmony_ci 1710419b0af8Sopenharmony_ci return r; 1711419b0af8Sopenharmony_ci} 1712419b0af8Sopenharmony_ci 1713419b0af8Sopenharmony_ci#define MSG_BUF 512 1714419b0af8Sopenharmony_cistatic ssize_t tui_dbg_msg_read(struct file *filp, char __user *ubuf, 1715419b0af8Sopenharmony_ci size_t cnt, loff_t *ppos) 1716419b0af8Sopenharmony_ci{ 1717419b0af8Sopenharmony_ci char buf[MSG_BUF] = {0}; 1718419b0af8Sopenharmony_ci int ret; 1719419b0af8Sopenharmony_ci int i; 1720419b0af8Sopenharmony_ci struct tui_drv_node *pos = NULL; 1721419b0af8Sopenharmony_ci 1722419b0af8Sopenharmony_ci if (filp == NULL || ubuf == NULL || ppos == NULL) 1723419b0af8Sopenharmony_ci return -EINVAL; 1724419b0af8Sopenharmony_ci 1725419b0af8Sopenharmony_ci ret = snprintf_s(buf, MSG_BUF, MSG_BUF - 1, "%s", "event format: event_type:val\n" 1726419b0af8Sopenharmony_ci "event type:\n"); 1727419b0af8Sopenharmony_ci if (ret < 0) 1728419b0af8Sopenharmony_ci return -EINVAL; 1729419b0af8Sopenharmony_ci 1730419b0af8Sopenharmony_ci unsigned int r = (unsigned int)ret; 1731419b0af8Sopenharmony_ci 1732419b0af8Sopenharmony_ci /* event type list */ 1733419b0af8Sopenharmony_ci for (i = 0; i < TUI_POLL_MAX - 1; i++) { 1734419b0af8Sopenharmony_ci ret = snprintf_s(buf + r, MSG_BUF - r, MSG_BUF - r - 1, "%s, ", 1735419b0af8Sopenharmony_ci poll_event_type_name[i]); 1736419b0af8Sopenharmony_ci if (ret < 0) { 1737419b0af8Sopenharmony_ci tloge("tui db msg read 2 snprint is error, ret = 0x%x\n", ret); 1738419b0af8Sopenharmony_ci return -EINVAL; 1739419b0af8Sopenharmony_ci } 1740419b0af8Sopenharmony_ci r += (unsigned int)ret; 1741419b0af8Sopenharmony_ci } 1742419b0af8Sopenharmony_ci ret = snprintf_s(buf + r, MSG_BUF - r, MSG_BUF - r - 1, "%s\n", poll_event_type_name[i]); 1743419b0af8Sopenharmony_ci if (ret < 0) { 1744419b0af8Sopenharmony_ci tloge("tui db msg read 3 snprint is error, ret = 0x%x\n", ret); 1745419b0af8Sopenharmony_ci return -EINVAL; 1746419b0af8Sopenharmony_ci } 1747419b0af8Sopenharmony_ci r += (unsigned int)ret; 1748419b0af8Sopenharmony_ci 1749419b0af8Sopenharmony_ci /* cfg drv type list */ 1750419b0af8Sopenharmony_ci ret = snprintf_s(buf + r, MSG_BUF - r, MSG_BUF - r - 1, "val type for %s or %s:\n", 1751419b0af8Sopenharmony_ci poll_event_type_name[TUI_POLL_CFG_OK], poll_event_type_name[TUI_POLL_CFG_FAIL]); 1752419b0af8Sopenharmony_ci if (ret < 0) { 1753419b0af8Sopenharmony_ci tloge("tui db msg read 4 snprint is error, ret = 0x%x\n", ret); 1754419b0af8Sopenharmony_ci return -EINVAL; 1755419b0af8Sopenharmony_ci } 1756419b0af8Sopenharmony_ci r += (unsigned int)ret; 1757419b0af8Sopenharmony_ci 1758419b0af8Sopenharmony_ci mutex_lock(&g_tui_drv_lock); 1759419b0af8Sopenharmony_ci list_for_each_entry(pos, &g_tui_drv_head, list) { 1760419b0af8Sopenharmony_ci ret = snprintf_s(buf + r, MSG_BUF - r, MSG_BUF - r - 1, "%s,", pos->name); 1761419b0af8Sopenharmony_ci if (ret < 0) { 1762419b0af8Sopenharmony_ci tloge("tui db msg read 5 snprint is error, ret = 0x%x\n", ret); 1763419b0af8Sopenharmony_ci mutex_unlock(&g_tui_drv_lock); 1764419b0af8Sopenharmony_ci return -EINVAL; 1765419b0af8Sopenharmony_ci } 1766419b0af8Sopenharmony_ci r += (unsigned int)ret; 1767419b0af8Sopenharmony_ci } 1768419b0af8Sopenharmony_ci mutex_unlock(&g_tui_drv_lock); 1769419b0af8Sopenharmony_ci if (r < MSG_BUF) 1770419b0af8Sopenharmony_ci buf[r - 1] = '\n'; 1771419b0af8Sopenharmony_ci 1772419b0af8Sopenharmony_ci return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); 1773419b0af8Sopenharmony_ci} 1774419b0af8Sopenharmony_ci 1775419b0af8Sopenharmony_cistatic ssize_t tui_dbg_process_tp(const char *tokens, char **begins) 1776419b0af8Sopenharmony_ci{ 1777419b0af8Sopenharmony_ci long value = 0; 1778419b0af8Sopenharmony_ci int base = TP_BASE_VALUE; 1779419b0af8Sopenharmony_ci 1780419b0af8Sopenharmony_ci /* simple_strtol is obsolete, use kstrtol instead */ 1781419b0af8Sopenharmony_ci int32_t ret = kstrtol(tokens, base, &value); 1782419b0af8Sopenharmony_ci if (ret != 0) 1783419b0af8Sopenharmony_ci return -EFAULT; 1784419b0af8Sopenharmony_ci g_tui_ctl->n2s.status = (int)value; 1785419b0af8Sopenharmony_ci 1786419b0af8Sopenharmony_ci tokens = strsep(begins, ":"); 1787419b0af8Sopenharmony_ci if (tokens == NULL) 1788419b0af8Sopenharmony_ci return -EFAULT; 1789419b0af8Sopenharmony_ci 1790419b0af8Sopenharmony_ci ret = kstrtol(tokens, base, &value); 1791419b0af8Sopenharmony_ci if (ret != 0) 1792419b0af8Sopenharmony_ci return -EFAULT; 1793419b0af8Sopenharmony_ci g_tui_ctl->n2s.x = (int)value; 1794419b0af8Sopenharmony_ci 1795419b0af8Sopenharmony_ci tokens = strsep(begins, ":"); 1796419b0af8Sopenharmony_ci if (tokens == NULL) 1797419b0af8Sopenharmony_ci return -EFAULT; 1798419b0af8Sopenharmony_ci 1799419b0af8Sopenharmony_ci int32_t ret = kstrtol(tokens, base, &value); 1800419b0af8Sopenharmony_ci if (ret != 0) 1801419b0af8Sopenharmony_ci return -EINVAL; 1802419b0af8Sopenharmony_ci g_tui_ctl->n2s.y = (int)value; 1803419b0af8Sopenharmony_ci return 0; 1804419b0af8Sopenharmony_ci} 1805419b0af8Sopenharmony_ci 1806419b0af8Sopenharmony_cistatic ssize_t tui_dbg_msg_write(struct file *filp, 1807419b0af8Sopenharmony_ci const char __user *ubuf, size_t cnt, 1808419b0af8Sopenharmony_ci loff_t *ppos) 1809419b0af8Sopenharmony_ci{ 1810419b0af8Sopenharmony_ci char buf[64]; 1811419b0af8Sopenharmony_ci int i; 1812419b0af8Sopenharmony_ci int event_type = -1; 1813419b0af8Sopenharmony_ci char *tokens = NULL, *begins = NULL; 1814419b0af8Sopenharmony_ci struct teec_tui_parameter tui_param = {0}; 1815419b0af8Sopenharmony_ci 1816419b0af8Sopenharmony_ci if (ubuf == NULL || filp == NULL || ppos == NULL) 1817419b0af8Sopenharmony_ci return -EINVAL; 1818419b0af8Sopenharmony_ci 1819419b0af8Sopenharmony_ci if (cnt >= sizeof(buf)/sizeof(char)) 1820419b0af8Sopenharmony_ci return -EINVAL; 1821419b0af8Sopenharmony_ci 1822419b0af8Sopenharmony_ci if (copy_from_user(buf, ubuf, cnt) != 0) 1823419b0af8Sopenharmony_ci return -EFAULT; 1824419b0af8Sopenharmony_ci 1825419b0af8Sopenharmony_ci buf[cnt] = 0; 1826419b0af8Sopenharmony_ci begins = buf; 1827419b0af8Sopenharmony_ci 1828419b0af8Sopenharmony_ci /* event type */ 1829419b0af8Sopenharmony_ci tokens = strsep(&begins, ":"); 1830419b0af8Sopenharmony_ci if (tokens == NULL) 1831419b0af8Sopenharmony_ci return -EFAULT; 1832419b0af8Sopenharmony_ci 1833419b0af8Sopenharmony_ci tlogd("1: tokens:%s\n", tokens); 1834419b0af8Sopenharmony_ci for (i = 0; i < TUI_POLL_MAX; i++) { 1835419b0af8Sopenharmony_ci if (strncmp(tokens, poll_event_type_name[i], strlen(poll_event_type_name[i])) == 0) { 1836419b0af8Sopenharmony_ci event_type = i; 1837419b0af8Sopenharmony_ci break; 1838419b0af8Sopenharmony_ci } 1839419b0af8Sopenharmony_ci } 1840419b0af8Sopenharmony_ci 1841419b0af8Sopenharmony_ci /* only for tp and cancel */ 1842419b0af8Sopenharmony_ci if (event_type != TUI_POLL_TP && event_type != TUI_POLL_CANCEL) 1843419b0af8Sopenharmony_ci return -EFAULT; 1844419b0af8Sopenharmony_ci /* drv type */ 1845419b0af8Sopenharmony_ci tokens = strsep(&begins, ":"); 1846419b0af8Sopenharmony_ci if (tokens == NULL) 1847419b0af8Sopenharmony_ci return -EFAULT; 1848419b0af8Sopenharmony_ci 1849419b0af8Sopenharmony_ci tlogd("2: tokens:%s\n", tokens); 1850419b0af8Sopenharmony_ci if (event_type == TUI_POLL_TP) { 1851419b0af8Sopenharmony_ci if (tui_dbg_process_tp((const char *)tokens, &begins) != 0) 1852419b0af8Sopenharmony_ci return -EFAULT; 1853419b0af8Sopenharmony_ci } 1854419b0af8Sopenharmony_ci tlogd("status=%d x=%d y=%d\n", g_tui_ctl->n2s.status, g_tui_ctl->n2s.x, g_tui_ctl->n2s.y); 1855419b0af8Sopenharmony_ci 1856419b0af8Sopenharmony_ci if (tui_send_event(event_type, &tui_param)) 1857419b0af8Sopenharmony_ci return -EFAULT; 1858419b0af8Sopenharmony_ci 1859419b0af8Sopenharmony_ci *ppos += cnt; 1860419b0af8Sopenharmony_ci 1861419b0af8Sopenharmony_ci return cnt; 1862419b0af8Sopenharmony_ci} 1863419b0af8Sopenharmony_ci 1864419b0af8Sopenharmony_cistatic const struct file_operations tui_dbg_msg_fops = { 1865419b0af8Sopenharmony_ci .owner = THIS_MODULE, 1866419b0af8Sopenharmony_ci .read = tui_dbg_msg_read, 1867419b0af8Sopenharmony_ci .write = tui_dbg_msg_write, 1868419b0af8Sopenharmony_ci}; 1869419b0af8Sopenharmony_ci 1870419b0af8Sopenharmony_cistatic struct dentry *g_dbg_dentry = NULL; 1871419b0af8Sopenharmony_ci 1872419b0af8Sopenharmony_cistatic int tui_powerkey_notifier_call(struct notifier_block *powerkey_nb, unsigned long event, void *data) 1873419b0af8Sopenharmony_ci{ 1874419b0af8Sopenharmony_ci#ifndef CONFIG_TEE_TUI_MTK 1875419b0af8Sopenharmony_ci if (event == PRESS_KEY_DOWN) { 1876419b0af8Sopenharmony_ci tui_poweroff_work_start(); 1877419b0af8Sopenharmony_ci } else if (event == PRESS_KEY_UP) { 1878419b0af8Sopenharmony_ci } else if (event == PRESS_KEY_1S) { 1879419b0af8Sopenharmony_ci } else if (event == PRESS_KEY_6S) { 1880419b0af8Sopenharmony_ci } else if (event == PRESS_KEY_8S) { 1881419b0af8Sopenharmony_ci } else if (event == PRESS_KEY_10S) { 1882419b0af8Sopenharmony_ci } else { 1883419b0af8Sopenharmony_ci tloge("[%s]invalid event %ld !\n", __func__, event); 1884419b0af8Sopenharmony_ci } 1885419b0af8Sopenharmony_ci#endif 1886419b0af8Sopenharmony_ci#ifdef CONFIG_HW_COMB_KEY 1887419b0af8Sopenharmony_ci if (event == POWER_KEY_PRESS_DOWN) { 1888419b0af8Sopenharmony_ci tui_poweroff_work_start(); 1889419b0af8Sopenharmony_ci } else { 1890419b0af8Sopenharmony_ci tloge("[%s]invalid event %ld !\n", __func__, event); 1891419b0af8Sopenharmony_ci } 1892419b0af8Sopenharmony_ci#endif 1893419b0af8Sopenharmony_ci return 0; 1894419b0af8Sopenharmony_ci} 1895419b0af8Sopenharmony_ci 1896419b0af8Sopenharmony_cistatic struct notifier_block tui_powerkey_nb; 1897419b0af8Sopenharmony_ciint register_tui_powerkey_listener(void) 1898419b0af8Sopenharmony_ci{ 1899419b0af8Sopenharmony_ci tui_powerkey_nb.notifier_call = tui_powerkey_notifier_call; 1900419b0af8Sopenharmony_ci#ifdef CONFIG_HW_COMB_KEY 1901419b0af8Sopenharmony_ci return power_key_register_notifier(&tui_powerkey_nb); 1902419b0af8Sopenharmony_ci#else 1903419b0af8Sopenharmony_ci return powerkey_register_notifier(&tui_powerkey_nb); 1904419b0af8Sopenharmony_ci#endif 1905419b0af8Sopenharmony_ci} 1906419b0af8Sopenharmony_ci 1907419b0af8Sopenharmony_ciint unregister_tui_powerkey_listener(void) 1908419b0af8Sopenharmony_ci{ 1909419b0af8Sopenharmony_ci tui_powerkey_nb.notifier_call = tui_powerkey_notifier_call; 1910419b0af8Sopenharmony_ci#ifdef CONFIG_HW_COMB_KEY 1911419b0af8Sopenharmony_ci return power_key_unregister_notifier(&tui_powerkey_nb); 1912419b0af8Sopenharmony_ci#else 1913419b0af8Sopenharmony_ci return powerkey_unregister_notifier(&tui_powerkey_nb); 1914419b0af8Sopenharmony_ci#endif 1915419b0af8Sopenharmony_ci} 1916419b0af8Sopenharmony_ci 1917419b0af8Sopenharmony_ciint __init init_tui(const struct device *class_dev) 1918419b0af8Sopenharmony_ci{ 1919419b0af8Sopenharmony_ci int retval; 1920419b0af8Sopenharmony_ci struct sched_param param; 1921419b0af8Sopenharmony_ci param.sched_priority = MAX_RT_PRIO - 1; 1922419b0af8Sopenharmony_ci 1923419b0af8Sopenharmony_ci if (class_dev == NULL) 1924419b0af8Sopenharmony_ci return -1; 1925419b0af8Sopenharmony_ci 1926419b0af8Sopenharmony_ci g_tui_task = kthread_create(tui_kthread_work_fn, NULL, "tuid"); 1927419b0af8Sopenharmony_ci if (IS_ERR_OR_NULL(g_tui_task)) { 1928419b0af8Sopenharmony_ci tloge("kthread create is error\n"); 1929419b0af8Sopenharmony_ci return PTR_ERR(g_tui_task); 1930419b0af8Sopenharmony_ci } 1931419b0af8Sopenharmony_ci 1932419b0af8Sopenharmony_ci sched_setscheduler_nocheck(g_tui_task, SCHED_FIFO, ¶m); 1933419b0af8Sopenharmony_ci get_task_struct(g_tui_task); 1934419b0af8Sopenharmony_ci 1935419b0af8Sopenharmony_ci tz_kthread_bind_mask(g_tui_task); 1936419b0af8Sopenharmony_ci wake_up_process(g_tui_task); 1937419b0af8Sopenharmony_ci 1938419b0af8Sopenharmony_ci INIT_LIST_HEAD(&g_tui_msg_head); 1939419b0af8Sopenharmony_ci spin_lock_init(&g_tui_msg_lock); 1940419b0af8Sopenharmony_ci 1941419b0af8Sopenharmony_ci init_waitqueue_head(&g_tui_state_wq); 1942419b0af8Sopenharmony_ci init_waitqueue_head(&g_tui_msg_wq); 1943419b0af8Sopenharmony_ci g_dbg_dentry = debugfs_create_dir("tui", NULL); 1944419b0af8Sopenharmony_ci#ifdef DEBUG_TUI 1945419b0af8Sopenharmony_ci debugfs_create_file("message", 0440, g_dbg_dentry, NULL, &tui_dbg_msg_fops); 1946419b0af8Sopenharmony_ci#endif 1947419b0af8Sopenharmony_ci debugfs_create_file("d_state", 0440, g_dbg_dentry, NULL, &tui_dbg_state_fops); 1948419b0af8Sopenharmony_ci g_tui_kobj = kobject_create_and_add("tui", kernel_kobj); 1949419b0af8Sopenharmony_ci if (g_tui_kobj == NULL) { 1950419b0af8Sopenharmony_ci tloge("tui kobj create error\n"); 1951419b0af8Sopenharmony_ci retval = -ENOMEM; 1952419b0af8Sopenharmony_ci goto error2; 1953419b0af8Sopenharmony_ci } 1954419b0af8Sopenharmony_ci retval = sysfs_create_group(g_tui_kobj, &g_tui_attr_group); 1955419b0af8Sopenharmony_ci 1956419b0af8Sopenharmony_ci if (retval) { 1957419b0af8Sopenharmony_ci tloge("sysfs_create_group error, retval = 0x%x\n", retval); 1958419b0af8Sopenharmony_ci goto error1; 1959419b0af8Sopenharmony_ci } 1960419b0af8Sopenharmony_ci 1961419b0af8Sopenharmony_ci retval = register_tui_powerkey_listener(); 1962419b0af8Sopenharmony_ci if (retval != 0) { 1963419b0af8Sopenharmony_ci tloge("tui register failed, retval = 0x%x\n", retval); 1964419b0af8Sopenharmony_ci goto error1; 1965419b0af8Sopenharmony_ci } 1966419b0af8Sopenharmony_ci return 0; 1967419b0af8Sopenharmony_cierror1: 1968419b0af8Sopenharmony_ci kobject_put(g_tui_kobj); 1969419b0af8Sopenharmony_cierror2: 1970419b0af8Sopenharmony_ci kthread_stop(g_tui_task); 1971419b0af8Sopenharmony_ci return retval; 1972419b0af8Sopenharmony_ci} 1973419b0af8Sopenharmony_ci 1974419b0af8Sopenharmony_civoid free_tui(void) 1975419b0af8Sopenharmony_ci{ 1976419b0af8Sopenharmony_ci if (unregister_tui_powerkey_listener() < 0) 1977419b0af8Sopenharmony_ci tloge("tui power key unregister failed\n"); 1978419b0af8Sopenharmony_ci kthread_stop(g_tui_task); 1979419b0af8Sopenharmony_ci put_task_struct(g_tui_task); 1980419b0af8Sopenharmony_ci debugfs_remove(g_dbg_dentry); 1981419b0af8Sopenharmony_ci sysfs_remove_group(g_tui_kobj, &g_tui_attr_group); 1982419b0af8Sopenharmony_ci kobject_put(g_tui_kobj); 1983419b0af8Sopenharmony_ci} 1984419b0af8Sopenharmony_ci 1985419b0af8Sopenharmony_ciint tc_ns_tui_event(struct tc_ns_dev_file *dev_file, const void *argp) 1986419b0af8Sopenharmony_ci{ 1987419b0af8Sopenharmony_ci struct teec_tui_parameter tui_param = {0}; 1988419b0af8Sopenharmony_ci int ret; 1989419b0af8Sopenharmony_ci 1990419b0af8Sopenharmony_ci if (!dev_file || !argp) { 1991419b0af8Sopenharmony_ci tloge("argp or dev is NULL\n"); 1992419b0af8Sopenharmony_ci return -EINVAL; 1993419b0af8Sopenharmony_ci } 1994419b0af8Sopenharmony_ci 1995419b0af8Sopenharmony_ci if (copy_from_user(&tui_param, argp, sizeof(tui_param))) { 1996419b0af8Sopenharmony_ci tloge("copy from user failed\n"); 1997419b0af8Sopenharmony_ci return -ENOMEM; 1998419b0af8Sopenharmony_ci } 1999419b0af8Sopenharmony_ci 2000419b0af8Sopenharmony_ci if (tui_param.event_type == TUI_POLL_CANCEL || 2001419b0af8Sopenharmony_ci tui_param.event_type == TUI_POLL_NOTCH || 2002419b0af8Sopenharmony_ci tui_param.event_type == TUI_POLL_FOLD) { 2003419b0af8Sopenharmony_ci ret = tui_send_event(tui_param.event_type, &tui_param); 2004419b0af8Sopenharmony_ci } else { 2005419b0af8Sopenharmony_ci tloge("no permission to send event\n"); 2006419b0af8Sopenharmony_ci ret = -EACCES; 2007419b0af8Sopenharmony_ci } 2008419b0af8Sopenharmony_ci 2009419b0af8Sopenharmony_ci return ret; 2010419b0af8Sopenharmony_ci} 2011419b0af8Sopenharmony_ci 2012419b0af8Sopenharmony_cibool is_tui_agent(unsigned int agent_id) 2013419b0af8Sopenharmony_ci{ 2014419b0af8Sopenharmony_ci return agent_id == TEE_TUI_AGENT_ID; 2015419b0af8Sopenharmony_ci}