/* SPDX-License-Identifier: GPL-2.0 */ /* * (C) COPYRIGHT 2021 Samsung Electronics Inc. All rights reserved. * * This program is free software and is provided to you under the terms of the * GNU General Public License version 2 as published by the Free Software * Foundation, and any use by you of this program is subject to the terms * of such GNU licence. * * 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. * * You should have received a copy of the GNU General Public License * along with this program; if not, you can access it online at * http://www.gnu.org/licenses/gpl-2.0.html. */ /* Implements */ #include /* Uses */ #include #include #include #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 4, 0) #include #else #include #endif #include struct _smc_info { bool protection_enabled; spinlock_t lock; }; static struct _smc_info smc_info; int gpexbe_smc_protection_enable() { int err; unsigned long flags; spin_lock_irqsave(&smc_info.lock, flags); if (smc_info.protection_enabled) { spin_unlock_irqrestore(&smc_info.lock, flags); return 0; } err = exynos_smc(SMC_PROTECTION_SET, 0, PROT_G3D, SMC_PROTECTION_ENABLE); if (!err) smc_info.protection_enabled = true; spin_unlock_irqrestore(&smc_info.lock, flags); if (!err) GPU_LOG(MALI_EXYNOS_INFO, "%s: Enter Secure World by GPU\n", __func__); else GPU_LOG_DETAILED(MALI_EXYNOS_ERROR, LSI_GPU_SECURE, 0u, 0u, "%s: failed to enter secure world ret : %d\n", __func__, err); return err; } int gpexbe_smc_protection_disable() { int err; unsigned long flags; spin_lock_irqsave(&smc_info.lock, flags); if (!smc_info.protection_enabled) { spin_unlock_irqrestore(&smc_info.lock, flags); return 0; } err = exynos_smc(SMC_PROTECTION_SET, 0, PROT_G3D, SMC_PROTECTION_DISABLE); if (!err) smc_info.protection_enabled = false; spin_unlock_irqrestore(&smc_info.lock, flags); if (!err) GPU_LOG(MALI_EXYNOS_INFO, "%s: Exit Secure World by GPU\n", __func__); else GPU_LOG_DETAILED(MALI_EXYNOS_ERROR, LSI_GPU_SECURE, 0u, 0u, "%s: failed to exit secure world ret : %d\n", __func__, err); return err; } #if IS_ENABLED(CONFIG_MALI_EXYNOS_SECURE_SMC_NOTIFY_GPU) #ifndef SMC_DRM_G3D_POWER_ON /* Older kernel versions have SMC_DRM_G3D_POWER_ON as SMC_DRM_G3D_PPCFW_RESTORE * but they share same value */ #define SMC_DRM_G3D_POWER_ON SMC_DRM_G3D_PPCFW_RESTORE #endif void gpexbe_smc_notify_power_on() { exynos_smc(SMC_DRM_G3D_POWER_ON, 0, 0, 0); } void gpexbe_smc_notify_power_off() { exynos_smc(SMC_DRM_G3D_POWER_OFF, 0, 0, 0); } #else void gpexbe_smc_notify_power_on() { } void gpexbe_smc_notify_power_off() { } #endif int gpexbe_smc_init(void) { spin_lock_init(&smc_info.lock); smc_info.protection_enabled = false; gpex_utils_get_exynos_context()->smc_info = &smc_info; return 0; } void gpexbe_smc_term(void) { gpexbe_smc_protection_disable(); smc_info.protection_enabled = false; }