From: Liqiang Jin Date: Mon, 9 Nov 2020 08:12:51 +0000 (+0800) Subject: linuxdriver: add Watermark flush mechanism [2/2] X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=d90639d007ff18c1a18829b81e62797b2d744d78;p=GitHub%2FLineageOS%2FG12%2Fandroid_hardware_amlogic_kernel-modules_optee.git linuxdriver: add Watermark flush mechanism [2/2] PD#SWPL-36395 Problem: 1) if Verimatrix Watermark enable, OSD flicker when the TV station changes 2) if screen resolution changes, NexGuard Watermark display is abnormal Solution: add Watermark flush mechanism Verify: Android Q + AH212(SC2) Change-Id: I096ecf01eca522cb3b6c2f943cd57ab813eb92ed Signed-off-by: Liqiang Jin --- diff --git a/optee/Makefile b/optee/Makefile index 8865e15..c563dfa 100644 --- a/optee/Makefile +++ b/optee/Makefile @@ -14,3 +14,4 @@ else optee_armtz-objs += smccc-call.o endif optee_armtz-objs += log.o +optee_armtz-objs += watermark.o diff --git a/optee/core.c b/optee/core.c index 45028a1..8cbfc3d 100644 --- a/optee/core.c +++ b/optee/core.c @@ -514,6 +514,8 @@ static int optee_probe(struct platform_device *pdev) optee_timer_init(&optee->timer); + optee_wm_irq_register(); + mutex_init(&optee->call_queue.mutex); INIT_LIST_HEAD(&optee->call_queue.waiters); optee_wait_queue_init(&optee->wait_queue); @@ -549,6 +551,8 @@ static int optee_remove(struct platform_device *pdev) { struct optee *optee = platform_get_drvdata(pdev); + optee_wm_irq_free(); + optee_timer_destroy(&optee->timer); optee_log_exit(optee->teedev); diff --git a/optee/optee_private.h b/optee/optee_private.h index 2bdf40e..7c5f8f5 100644 --- a/optee/optee_private.h +++ b/optee/optee_private.h @@ -192,4 +192,7 @@ void optee_timer_init(struct optee_timer *timer); void optee_timer_destroy(struct optee_timer *timer); void optee_timer_missed_destroy(struct tee_context *ctx, u32 session); +int optee_wm_irq_register(void); +void optee_wm_irq_free(void); + #endif /*OPTEE_PRIVATE_H*/ diff --git a/optee/optee_smc.h b/optee/optee_smc.h index bcf4ce2..a068199 100644 --- a/optee/optee_smc.h +++ b/optee/optee_smc.h @@ -426,6 +426,21 @@ struct optee_smc_disable_shm_cache_result { #define OPTEE_SMC_RETURN_RPC_CMD \ OPTEE_SMC_RPC_VAL(OPTEE_SMC_RPC_FUNC_CMD) +/* + * flush watermark + * + * Call register usage: + * a0 SMC Function ID, OPTEE_SMC_FLUSH_WM + * a1-7 Not used + * + * Normal return register usage: + * a0 result + * a1-7 Preserved + */ +#define OPTEE_SMC_FUNCID_FLUSH_WM 0xE000 +#define OPTEE_SMC_FLUSH_WM \ + OPTEE_SMC_FAST_CALL_VAL(OPTEE_SMC_FUNCID_FLUSH_WM) + /* * set logger * @@ -444,6 +459,21 @@ struct optee_smc_disable_shm_cache_result { #define OPTEE_SMC_SET_LOGGER \ OPTEE_SMC_FAST_CALL_VAL(OPTEE_SMC_FUNCID_SET_LOGGER) +/* + * check watermark status + * + * Call register usage: + * a0 SMC Function ID, OPTEE_SMC_CHECK_WM_STATUS + * a1-7 Not used + * + * Normal return register usage: + * a0 result + * a1-7 Preserved + */ +#define OPTEE_SMC_FUNCID_CHECK_WM_STATUS 0xE003 +#define OPTEE_SMC_CHECK_WM_STATUS \ + OPTEE_SMC_FAST_CALL_VAL(OPTEE_SMC_FUNCID_CHECK_WM_STATUS) + /* Returned in a0 */ #define OPTEE_SMC_RETURN_UNKNOWN_FUNCTION 0xFFFFFFFF diff --git a/optee/watermark.c b/optee/watermark.c new file mode 100644 index 0000000..36577dc --- /dev/null +++ b/optee/watermark.c @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2017, Amlogic, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include "optee_smc.h" +#include "optee_private.h" + +#define OPTEE_WM_DEBUG 0 + +#define SRC_IRQ_NAME "viu-vsync" +#define DST_IRQ_NAME "wm-vsync" + +static int g_irq_id = 0; + +static uint32_t check_wm_status(void) +{ + struct arm_smccc_res res; + + arm_smccc_smc(OPTEE_SMC_CHECK_WM_STATUS, 0, 0, 0, 0, 0, 0, 0, &res); + + return res.a0; +} + +static uint32_t flush_wm(void) +{ + struct arm_smccc_res res; + + arm_smccc_smc(OPTEE_SMC_FLUSH_WM, 0, 0, 0, 0, 0, 0, 0, &res); + + return res.a0; +} + +static irqreturn_t vsync_isr(int irq, void *dev_id) +{ + flush_wm(); + + return IRQ_HANDLED; +} + +static int get_wm_irq_id(void) +{ + int irq_id = 0; + struct device_node *root_node = of_find_node_by_path("/"); + struct property *root_prop = NULL; + char *soc = NULL; + char compatible_val[32] = {"amlogic, meson-"}; + struct device_node *compatible_node = NULL; + + for (root_prop = root_node->properties; root_prop; root_prop = root_prop->next) { + if (of_prop_cmp(root_prop->name, "compatible") == 0) { + soc = ((char *)root_prop->value) + strlen("amlogic, "); + strcat(compatible_val, soc); + compatible_node = of_find_compatible_node(NULL, NULL, compatible_val); + if (compatible_node) + irq_id = of_irq_get_byname(compatible_node, SRC_IRQ_NAME); + goto exit; + } + } + +exit: + if (irq_id <= 0) { + pr_err("SOC: %s; node: %p; node compatible value: %s; interrupt name: %s; interrupt id: %d;\n", + soc, compatible_node, compatible_val, + SRC_IRQ_NAME, irq_id); + pr_err("not found %s interrupt\n", SRC_IRQ_NAME); + } + + return irq_id; +} + +int optee_wm_irq_register(void) +{ + uint32_t wm_sts = 0; + int err_num = 0; + + wm_sts = check_wm_status(); + if (wm_sts) { +#ifdef OPTEE_WM_DEBUG + pr_info("checking watermark status return 0x%08X\n", wm_sts); +#endif + return -1; + } + + g_irq_id = get_wm_irq_id(); +#ifdef OPTEE_WM_DEBUG + pr_info("%s interrupt id: %d\n", DST_IRQ_NAME, g_irq_id); +#endif + + err_num = request_irq(g_irq_id, &vsync_isr, IRQF_SHARED, DST_IRQ_NAME, (void *)&g_irq_id); + if (err_num) + pr_err("can't request %s interrupt for vsync, err_num = %d\n", DST_IRQ_NAME, -err_num); + + return -1; +} + +void optee_wm_irq_free(void) +{ + if (g_irq_id > 0) + free_irq(g_irq_id, (void *)&g_irq_id); +}