Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright 2018 Advanced Micro Devices, Inc.
0003  *
0004  * Permission is hereby granted, free of charge, to any person obtaining a
0005  * copy of this software and associated documentation files (the "Software"),
0006  * to deal in the Software without restriction, including without limitation
0007  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
0008  * and/or sell copies of the Software, and to permit persons to whom the
0009  * Software is furnished to do so, subject to the following conditions:
0010  *
0011  * The above copyright notice and this permission notice shall be included in
0012  * all copies or substantial portions of the Software.
0013  *
0014  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0015  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0016  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
0017  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
0018  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
0019  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
0020  * OTHER DEALINGS IN THE SOFTWARE.
0021  *
0022  */
0023 
0024 #include "smumgr.h"
0025 #include "smu9_smumgr.h"
0026 #include "vega10_inc.h"
0027 #include "soc15_common.h"
0028 #include "pp_debug.h"
0029 
0030 
0031 /* MP Apertures */
0032 #define MP0_Public                  0x03800000
0033 #define MP0_SRAM                    0x03900000
0034 #define MP1_Public                  0x03b00000
0035 #define MP1_SRAM                    0x03c00004
0036 
0037 #define smnMP1_FIRMWARE_FLAGS                                                                           0x3010028
0038 
0039 bool smu9_is_smc_ram_running(struct pp_hwmgr *hwmgr)
0040 {
0041     struct amdgpu_device *adev = hwmgr->adev;
0042     uint32_t mp1_fw_flags;
0043 
0044     mp1_fw_flags = RREG32_PCIE(MP1_Public |
0045                    (smnMP1_FIRMWARE_FLAGS & 0xffffffff));
0046 
0047     if (mp1_fw_flags & MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED_MASK)
0048         return true;
0049 
0050     return false;
0051 }
0052 
0053 /*
0054  * Check if SMC has responded to previous message.
0055  *
0056  * @param    smumgr  the address of the powerplay hardware manager.
0057  * @return   TRUE    SMC has responded, FALSE otherwise.
0058  */
0059 static uint32_t smu9_wait_for_response(struct pp_hwmgr *hwmgr)
0060 {
0061     struct amdgpu_device *adev = hwmgr->adev;
0062     uint32_t reg;
0063     uint32_t ret;
0064 
0065     if (hwmgr->pp_one_vf) {
0066         reg = SOC15_REG_OFFSET(MP1, 0, mmMP1_SMN_C2PMSG_103);
0067 
0068         ret = phm_wait_for_register_unequal(hwmgr, reg,
0069                 0, MP1_C2PMSG_103__CONTENT_MASK);
0070 
0071         if (ret)
0072             pr_err("No response from smu\n");
0073 
0074         return RREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_103);
0075     } else {
0076         reg = SOC15_REG_OFFSET(MP1, 0, mmMP1_SMN_C2PMSG_90);
0077 
0078         ret = phm_wait_for_register_unequal(hwmgr, reg,
0079                 0, MP1_C2PMSG_90__CONTENT_MASK);
0080 
0081         if (ret)
0082             pr_err("No response from smu\n");
0083         return RREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_90);
0084     }
0085 }
0086 
0087 /*
0088  * Send a message to the SMC, and do not wait for its response.
0089  * @param    smumgr  the address of the powerplay hardware manager.
0090  * @param    msg the message to send.
0091  * @return   Always return 0.
0092  */
0093 static int smu9_send_msg_to_smc_without_waiting(struct pp_hwmgr *hwmgr,
0094                         uint16_t msg)
0095 {
0096     struct amdgpu_device *adev = hwmgr->adev;
0097 
0098     if (hwmgr->pp_one_vf) {
0099         WREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_101, msg);
0100     } else {
0101         WREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_66, msg);
0102     }
0103 
0104     return 0;
0105 }
0106 
0107 /*
0108  * Send a message to the SMC, and wait for its response.
0109  * @param    hwmgr  the address of the powerplay hardware manager.
0110  * @param    msg the message to send.
0111  * @return   Always return 0.
0112  */
0113 int smu9_send_msg_to_smc(struct pp_hwmgr *hwmgr, uint16_t msg)
0114 {
0115     struct amdgpu_device *adev = hwmgr->adev;
0116     uint32_t ret;
0117 
0118     smu9_wait_for_response(hwmgr);
0119 
0120     if (hwmgr->pp_one_vf)
0121         WREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_103, 0);
0122     else
0123         WREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_90, 0);
0124 
0125     smu9_send_msg_to_smc_without_waiting(hwmgr, msg);
0126 
0127     ret = smu9_wait_for_response(hwmgr);
0128     if (ret != 1)
0129         dev_err(adev->dev, "Failed to send message: 0x%x, ret value: 0x%x\n", msg, ret);
0130 
0131     return 0;
0132 }
0133 
0134 /*
0135  * Send a message to the SMC with parameter
0136  * @param    hwmgr:  the address of the powerplay hardware manager.
0137  * @param    msg: the message to send.
0138  * @param    parameter: the parameter to send
0139  * @return   Always return 0.
0140  */
0141 int smu9_send_msg_to_smc_with_parameter(struct pp_hwmgr *hwmgr,
0142                     uint16_t msg, uint32_t parameter)
0143 {
0144     struct amdgpu_device *adev = hwmgr->adev;
0145     uint32_t ret;
0146 
0147     smu9_wait_for_response(hwmgr);
0148 
0149     if (hwmgr->pp_one_vf) {
0150         WREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_103, 0);
0151         WREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_102, parameter);
0152     } else {
0153         WREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_90, 0);
0154         WREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_82, parameter);
0155     }
0156 
0157     smu9_send_msg_to_smc_without_waiting(hwmgr, msg);
0158 
0159     ret = smu9_wait_for_response(hwmgr);
0160     if (ret != 1)
0161         pr_err("Failed message: 0x%x, input parameter: 0x%x, error code: 0x%x\n", msg, parameter, ret);
0162 
0163     return 0;
0164 }
0165 
0166 uint32_t smu9_get_argument(struct pp_hwmgr *hwmgr)
0167 {
0168     struct amdgpu_device *adev = hwmgr->adev;
0169 
0170     if (hwmgr->pp_one_vf)
0171         return RREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_102);
0172     else
0173         return RREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_82);
0174 }