root/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr_vbios_smu.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. rn_vbios_smu_send_msg_with_param
  2. rn_vbios_smu_get_smu_version
  3. rn_vbios_smu_set_dispclk
  4. rn_vbios_smu_set_dprefclk
  5. rn_vbios_smu_set_hard_min_dcfclk
  6. rn_vbios_smu_set_min_deep_sleep_dcfclk
  7. rn_vbios_smu_set_phyclk
  8. rn_vbios_smu_set_dppclk
  9. rn_vbios_smu_set_display_count
  10. rn_vbios_smu_enable_48mhz_tmdp_refclk_pwrdwn
  11. rn_vbios_smu_enable_pme_wa

   1 /*
   2  * Copyright 2012-16 Advanced Micro Devices, Inc.
   3  *
   4  * Permission is hereby granted, free of charge, to any person obtaining a
   5  * copy of this software and associated documentation files (the "Software"),
   6  * to deal in the Software without restriction, including without limitation
   7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
   8  * and/or sell copies of the Software, and to permit persons to whom the
   9  * Software is furnished to do so, subject to the following conditions:
  10  *
  11  * The above copyright notice and this permission notice shall be included in
  12  * all copies or substantial portions of the Software.
  13  *
  14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  17  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
  18  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  20  * OTHER DEALINGS IN THE SOFTWARE.
  21  *
  22  * Authors: AMD
  23  *
  24  */
  25 
  26 #include "core_types.h"
  27 #include "clk_mgr_internal.h"
  28 #include "reg_helper.h"
  29 
  30 #include "renoir_ip_offset.h"
  31 
  32 #include "mp/mp_12_0_0_offset.h"
  33 #include "mp/mp_12_0_0_sh_mask.h"
  34 
  35 #define REG(reg_name) \
  36         (MP0_BASE.instance[0].segment[mm ## reg_name ## _BASE_IDX] + mm ## reg_name)
  37 
  38 #define FN(reg_name, field) \
  39         FD(reg_name##__##field)
  40 
  41 #define VBIOSSMC_MSG_TestMessage                  0x1
  42 #define VBIOSSMC_MSG_GetSmuVersion                0x2
  43 #define VBIOSSMC_MSG_PowerUpGfx                   0x3
  44 #define VBIOSSMC_MSG_SetDispclkFreq               0x4
  45 #define VBIOSSMC_MSG_SetDprefclkFreq              0x5
  46 #define VBIOSSMC_MSG_PowerDownGfx                 0x6
  47 #define VBIOSSMC_MSG_SetDppclkFreq                0x7
  48 #define VBIOSSMC_MSG_SetHardMinDcfclkByFreq       0x8
  49 #define VBIOSSMC_MSG_SetMinDeepSleepDcfclk        0x9
  50 #define VBIOSSMC_MSG_SetPhyclkVoltageByFreq       0xA
  51 #define VBIOSSMC_MSG_GetFclkFrequency             0xB
  52 #define VBIOSSMC_MSG_SetDisplayCount              0xC
  53 #define VBIOSSMC_MSG_EnableTmdp48MHzRefclkPwrDown 0xD
  54 #define VBIOSSMC_MSG_UpdatePmeRestore                     0xE
  55 
  56 int rn_vbios_smu_send_msg_with_param(struct clk_mgr_internal *clk_mgr, unsigned int msg_id, unsigned int param)
  57 {
  58         /* First clear response register */
  59         REG_WRITE(MP1_SMN_C2PMSG_91, 0);
  60 
  61         /* Set the parameter register for the SMU message, unit is Mhz */
  62         REG_WRITE(MP1_SMN_C2PMSG_83, param);
  63 
  64         /* Trigger the message transaction by writing the message ID */
  65         REG_WRITE(MP1_SMN_C2PMSG_67, msg_id);
  66 
  67         REG_WAIT(MP1_SMN_C2PMSG_91, CONTENT, 1, 10, 200000);
  68 
  69         /* Actual dispclk set is returned in the parameter register */
  70         return REG_READ(MP1_SMN_C2PMSG_83);
  71 }
  72 
  73 int rn_vbios_smu_get_smu_version(struct clk_mgr_internal *clk_mgr)
  74 {
  75         return rn_vbios_smu_send_msg_with_param(
  76                         clk_mgr,
  77                         VBIOSSMC_MSG_GetSmuVersion,
  78                         0);
  79 }
  80 
  81 
  82 int rn_vbios_smu_set_dispclk(struct clk_mgr_internal *clk_mgr, int requested_dispclk_khz)
  83 {
  84         int actual_dispclk_set_mhz = -1;
  85         struct dc *core_dc = clk_mgr->base.ctx->dc;
  86         struct dmcu *dmcu = core_dc->res_pool->dmcu;
  87         uint32_t clk = requested_dispclk_khz / 1000;
  88 
  89         if (clk <= 100)
  90                 clk = 101;
  91 
  92         /*  Unit of SMU msg parameter is Mhz */
  93         actual_dispclk_set_mhz = rn_vbios_smu_send_msg_with_param(
  94                         clk_mgr,
  95                         VBIOSSMC_MSG_SetDispclkFreq,
  96                         clk);
  97 
  98         if (!IS_FPGA_MAXIMUS_DC(core_dc->ctx->dce_environment)) {
  99                 if (dmcu && dmcu->funcs->is_dmcu_initialized(dmcu)) {
 100                         if (clk_mgr->dfs_bypass_disp_clk != actual_dispclk_set_mhz)
 101                                 dmcu->funcs->set_psr_wait_loop(dmcu,
 102                                                 actual_dispclk_set_mhz / 7);
 103                 }
 104         }
 105 
 106         return actual_dispclk_set_mhz * 1000;
 107 }
 108 
 109 int rn_vbios_smu_set_dprefclk(struct clk_mgr_internal *clk_mgr)
 110 {
 111         int actual_dprefclk_set_mhz = -1;
 112 
 113         actual_dprefclk_set_mhz = rn_vbios_smu_send_msg_with_param(
 114                         clk_mgr,
 115                         VBIOSSMC_MSG_SetDprefclkFreq,
 116                         clk_mgr->base.dprefclk_khz / 1000);
 117 
 118         /* TODO: add code for programing DP DTO, currently this is down by command table */
 119 
 120         return actual_dprefclk_set_mhz * 1000;
 121 }
 122 
 123 int rn_vbios_smu_set_hard_min_dcfclk(struct clk_mgr_internal *clk_mgr, int requested_dcfclk_khz)
 124 {
 125         int actual_dcfclk_set_mhz = -1;
 126 
 127         if (clk_mgr->smu_ver < 0xFFFFFFFF)
 128                 return actual_dcfclk_set_mhz;
 129 
 130         actual_dcfclk_set_mhz = rn_vbios_smu_send_msg_with_param(
 131                         clk_mgr,
 132                         VBIOSSMC_MSG_SetHardMinDcfclkByFreq,
 133                         requested_dcfclk_khz / 1000);
 134 
 135         return actual_dcfclk_set_mhz * 1000;
 136 }
 137 
 138 int rn_vbios_smu_set_min_deep_sleep_dcfclk(struct clk_mgr_internal *clk_mgr, int requested_min_ds_dcfclk_khz)
 139 {
 140         int actual_min_ds_dcfclk_mhz = -1;
 141 
 142         if (clk_mgr->smu_ver < 0xFFFFFFFF)
 143                 return actual_min_ds_dcfclk_mhz;
 144 
 145         actual_min_ds_dcfclk_mhz = rn_vbios_smu_send_msg_with_param(
 146                         clk_mgr,
 147                         VBIOSSMC_MSG_SetMinDeepSleepDcfclk,
 148                         requested_min_ds_dcfclk_khz / 1000);
 149 
 150         return actual_min_ds_dcfclk_mhz * 1000;
 151 }
 152 
 153 void rn_vbios_smu_set_phyclk(struct clk_mgr_internal *clk_mgr, int requested_phyclk_khz)
 154 {
 155         rn_vbios_smu_send_msg_with_param(
 156                         clk_mgr,
 157                         VBIOSSMC_MSG_SetPhyclkVoltageByFreq,
 158                         requested_phyclk_khz / 1000);
 159 }
 160 
 161 int rn_vbios_smu_set_dppclk(struct clk_mgr_internal *clk_mgr, int requested_dpp_khz)
 162 {
 163         int actual_dppclk_set_mhz = -1;
 164 
 165         uint32_t clk = requested_dpp_khz / 1000;
 166 
 167         if (clk <= 100)
 168                 clk = 101;
 169 
 170         actual_dppclk_set_mhz = rn_vbios_smu_send_msg_with_param(
 171                         clk_mgr,
 172                         VBIOSSMC_MSG_SetDppclkFreq,
 173                         clk);
 174 
 175         return actual_dppclk_set_mhz * 1000;
 176 }
 177 
 178 void rn_vbios_smu_set_display_count(struct clk_mgr_internal *clk_mgr, int display_count)
 179 {
 180         rn_vbios_smu_send_msg_with_param(
 181                         clk_mgr,
 182                         VBIOSSMC_MSG_SetDisplayCount,
 183                         display_count);
 184 }
 185 
 186 void rn_vbios_smu_enable_48mhz_tmdp_refclk_pwrdwn(struct clk_mgr_internal *clk_mgr)
 187 {
 188         rn_vbios_smu_send_msg_with_param(
 189                         clk_mgr,
 190                         VBIOSSMC_MSG_EnableTmdp48MHzRefclkPwrDown,
 191                         0);
 192 }
 193 
 194 void rn_vbios_smu_enable_pme_wa(struct clk_mgr_internal *clk_mgr)
 195 {
 196         rn_vbios_smu_send_msg_with_param(
 197                         clk_mgr,
 198                         VBIOSSMC_MSG_UpdatePmeRestore,
 199                         0);
 200 }

/* [<][>][^][v][top][bottom][index][help] */