![]() |
|
|||
0001 // SPDX-License-Identifier: MIT 0002 /* 0003 * Copyright 2021 Advanced Micro Devices, Inc. 0004 * 0005 * Permission is hereby granted, free of charge, to any person obtaining a 0006 * copy of this software and associated documentation files (the "Software"), 0007 * to deal in the Software without restriction, including without limitation 0008 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 0009 * and/or sell copies of the Software, and to permit persons to whom the 0010 * Software is furnished to do so, subject to the following conditions: 0011 * 0012 * The above copyright notice and this permission notice shall be included in 0013 * all copies or substantial portions of the Software. 0014 * 0015 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 0016 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 0017 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 0018 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 0019 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 0020 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 0021 * OTHER DEALINGS IN THE SOFTWARE. 0022 * 0023 * Authors: AMD 0024 * 0025 */ 0026 0027 #include "dc_trace.h" 0028 0029 #if defined(CONFIG_X86) 0030 #include <asm/fpu/api.h> 0031 #elif defined(CONFIG_PPC64) 0032 #include <asm/switch_to.h> 0033 #include <asm/cputable.h> 0034 #endif 0035 0036 /** 0037 * DOC: DC FPU manipulation overview 0038 * 0039 * DC core uses FPU operations in multiple parts of the code, which requires a 0040 * more specialized way to manage these areas' entrance. To fulfill this 0041 * requirement, we created some wrapper functions that encapsulate 0042 * kernel_fpu_begin/end to better fit our need in the display component. In 0043 * summary, in this file, you can find functions related to FPU operation 0044 * management. 0045 */ 0046 0047 static DEFINE_PER_CPU(int, fpu_recursion_depth); 0048 0049 /** 0050 * dc_assert_fp_enabled - Check if FPU protection is enabled 0051 * 0052 * This function tells if the code is already under FPU protection or not. A 0053 * function that works as an API for a set of FPU operations can use this 0054 * function for checking if the caller invoked it after DC_FP_START(). For 0055 * example, take a look at dcn20_fpu.c file. 0056 */ 0057 inline void dc_assert_fp_enabled(void) 0058 { 0059 int *pcpu, depth = 0; 0060 0061 pcpu = get_cpu_ptr(&fpu_recursion_depth); 0062 depth = *pcpu; 0063 put_cpu_ptr(&fpu_recursion_depth); 0064 0065 ASSERT(depth >= 1); 0066 } 0067 0068 /** 0069 * dc_fpu_begin - Enables FPU protection 0070 * @function_name: A string containing the function name for debug purposes 0071 * (usually __func__) 0072 * 0073 * @line: A line number where DC_FP_START was invoked for debug purpose 0074 * (usually __LINE__) 0075 * 0076 * This function is responsible for managing the use of kernel_fpu_begin() with 0077 * the advantage of providing an event trace for debugging. 0078 * 0079 * Note: Do not call this function directly; always use DC_FP_START(). 0080 */ 0081 void dc_fpu_begin(const char *function_name, const int line) 0082 { 0083 int *pcpu; 0084 0085 pcpu = get_cpu_ptr(&fpu_recursion_depth); 0086 *pcpu += 1; 0087 0088 if (*pcpu == 1) { 0089 #if defined(CONFIG_X86) 0090 kernel_fpu_begin(); 0091 #elif defined(CONFIG_PPC64) 0092 if (cpu_has_feature(CPU_FTR_VSX_COMP)) { 0093 preempt_disable(); 0094 enable_kernel_vsx(); 0095 } else if (cpu_has_feature(CPU_FTR_ALTIVEC_COMP)) { 0096 preempt_disable(); 0097 enable_kernel_altivec(); 0098 } else if (!cpu_has_feature(CPU_FTR_FPU_UNAVAILABLE)) { 0099 preempt_disable(); 0100 enable_kernel_fp(); 0101 } 0102 #endif 0103 } 0104 0105 TRACE_DCN_FPU(true, function_name, line, *pcpu); 0106 put_cpu_ptr(&fpu_recursion_depth); 0107 } 0108 0109 /** 0110 * dc_fpu_end - Disable FPU protection 0111 * @function_name: A string containing the function name for debug purposes 0112 * @line: A-line number where DC_FP_END was invoked for debug purpose 0113 * 0114 * This function is responsible for managing the use of kernel_fpu_end() with 0115 * the advantage of providing an event trace for debugging. 0116 * 0117 * Note: Do not call this function directly; always use DC_FP_END(). 0118 */ 0119 void dc_fpu_end(const char *function_name, const int line) 0120 { 0121 int *pcpu; 0122 0123 pcpu = get_cpu_ptr(&fpu_recursion_depth); 0124 *pcpu -= 1; 0125 if (*pcpu <= 0) { 0126 #if defined(CONFIG_X86) 0127 kernel_fpu_end(); 0128 #elif defined(CONFIG_PPC64) 0129 if (cpu_has_feature(CPU_FTR_VSX_COMP)) { 0130 disable_kernel_vsx(); 0131 preempt_enable(); 0132 } else if (cpu_has_feature(CPU_FTR_ALTIVEC_COMP)) { 0133 disable_kernel_altivec(); 0134 preempt_enable(); 0135 } else if (!cpu_has_feature(CPU_FTR_FPU_UNAVAILABLE)) { 0136 disable_kernel_fp(); 0137 preempt_enable(); 0138 } 0139 #endif 0140 } 0141 0142 TRACE_DCN_FPU(false, function_name, line, *pcpu); 0143 put_cpu_ptr(&fpu_recursion_depth); 0144 }
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.1.0 LXR engine. The LXR team |
![]() ![]() |