Linux-libre 4.15.7-gnu
[librecmc/linux-libre.git] / drivers / gpu / drm / amd / powerplay / hwmgr / cz_clockpowergating.c
1 /*
2  * Copyright 2015 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  */
23
24 #include "hwmgr.h"
25 #include "cz_clockpowergating.h"
26 #include "cz_ppsmc.h"
27
28 /* PhyID -> Status Mapping in DDI_PHY_GEN_STATUS
29     0    GFX0L (3:0),                  (27:24),
30     1    GFX0H (7:4),                  (31:28),
31     2    GFX1L (3:0),                  (19:16),
32     3    GFX1H (7:4),                  (23:20),
33     4    DDIL   (3:0),                   (11: 8),
34     5    DDIH  (7:4),                   (15:12),
35     6    DDI2L (3:0),                   ( 3: 0),
36     7    DDI2H (7:4),                   ( 7: 4),
37 */
38 #define DDI_PHY_GEN_STATUS_VAL(phyID)   (1 << ((3 - ((phyID & 0x07)/2))*8 + (phyID & 0x01)*4))
39 #define IS_PHY_ID_USED_BY_PLL(PhyID)    (((0xF3 & (1 << PhyID)) & 0xFF) ? true : false)
40
41
42 int cz_phm_set_asic_block_gating(struct pp_hwmgr *hwmgr, enum PHM_AsicBlock block, enum PHM_ClockGateSetting gating)
43 {
44         int ret = 0;
45
46         switch (block) {
47         case PHM_AsicBlock_UVD_MVC:
48         case PHM_AsicBlock_UVD:
49         case PHM_AsicBlock_UVD_HD:
50         case PHM_AsicBlock_UVD_SD:
51                 if (gating == PHM_ClockGateSetting_StaticOff)
52                         ret = cz_dpm_powerdown_uvd(hwmgr);
53                 else
54                         ret = cz_dpm_powerup_uvd(hwmgr);
55                 break;
56         case PHM_AsicBlock_GFX:
57         default:
58                 break;
59         }
60
61         return ret;
62 }
63
64
65 bool cz_phm_is_safe_for_asic_block(struct pp_hwmgr *hwmgr, const struct pp_hw_power_state *state, enum PHM_AsicBlock block)
66 {
67         return true;
68 }
69
70
71 int cz_phm_enable_disable_gfx_power_gating(struct pp_hwmgr *hwmgr, bool enable)
72 {
73         return 0;
74 }
75
76 int cz_phm_smu_power_up_down_pcie(struct pp_hwmgr *hwmgr, uint32_t target, bool up, uint32_t args)
77 {
78         /* TODO */
79         return 0;
80 }
81
82 int cz_phm_initialize_display_phy_access(struct pp_hwmgr *hwmgr, bool initialize, bool accesshw)
83 {
84         /* TODO */
85         return 0;
86 }
87
88 int cz_phm_get_display_phy_access_info(struct pp_hwmgr *hwmgr)
89 {
90         /* TODO */
91         return 0;
92 }
93
94 int cz_phm_gate_unused_display_phys(struct pp_hwmgr *hwmgr)
95 {
96         /* TODO */
97         return 0;
98 }
99
100 int cz_phm_ungate_all_display_phys(struct pp_hwmgr *hwmgr)
101 {
102         /* TODO */
103         return 0;
104 }
105
106 int cz_enable_disable_uvd_dpm(struct pp_hwmgr *hwmgr, bool enable)
107 {
108         struct cz_hwmgr *cz_hwmgr = (struct cz_hwmgr *)(hwmgr->backend);
109         uint32_t dpm_features = 0;
110
111         if (enable &&
112                 phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
113                                   PHM_PlatformCaps_UVDDPM)) {
114                 cz_hwmgr->dpm_flags |= DPMFlags_UVD_Enabled;
115                 dpm_features |= UVD_DPM_MASK;
116                 smum_send_msg_to_smc_with_parameter(hwmgr,
117                             PPSMC_MSG_EnableAllSmuFeatures, dpm_features);
118         } else {
119                 dpm_features |= UVD_DPM_MASK;
120                 cz_hwmgr->dpm_flags &= ~DPMFlags_UVD_Enabled;
121                 smum_send_msg_to_smc_with_parameter(hwmgr,
122                            PPSMC_MSG_DisableAllSmuFeatures, dpm_features);
123         }
124         return 0;
125 }
126
127 int cz_enable_disable_vce_dpm(struct pp_hwmgr *hwmgr, bool enable)
128 {
129         struct cz_hwmgr *cz_hwmgr = (struct cz_hwmgr *)(hwmgr->backend);
130         uint32_t dpm_features = 0;
131
132         if (enable && phm_cap_enabled(
133                                 hwmgr->platform_descriptor.platformCaps,
134                                 PHM_PlatformCaps_VCEDPM)) {
135                 cz_hwmgr->dpm_flags |= DPMFlags_VCE_Enabled;
136                 dpm_features |= VCE_DPM_MASK;
137                 smum_send_msg_to_smc_with_parameter(hwmgr,
138                             PPSMC_MSG_EnableAllSmuFeatures, dpm_features);
139         } else {
140                 dpm_features |= VCE_DPM_MASK;
141                 cz_hwmgr->dpm_flags &= ~DPMFlags_VCE_Enabled;
142                 smum_send_msg_to_smc_with_parameter(hwmgr,
143                            PPSMC_MSG_DisableAllSmuFeatures, dpm_features);
144         }
145
146         return 0;
147 }
148
149
150 void cz_dpm_powergate_uvd(struct pp_hwmgr *hwmgr, bool bgate)
151 {
152         struct cz_hwmgr *cz_hwmgr = (struct cz_hwmgr *)(hwmgr->backend);
153
154         cz_hwmgr->uvd_power_gated = bgate;
155
156         if (bgate) {
157                 cgs_set_powergating_state(hwmgr->device,
158                                                 AMD_IP_BLOCK_TYPE_UVD,
159                                                 AMD_PG_STATE_GATE);
160                 cgs_set_clockgating_state(hwmgr->device,
161                                                 AMD_IP_BLOCK_TYPE_UVD,
162                                                 AMD_CG_STATE_GATE);
163                 cz_dpm_update_uvd_dpm(hwmgr, true);
164                 cz_dpm_powerdown_uvd(hwmgr);
165         } else {
166                 cz_dpm_powerup_uvd(hwmgr);
167                 cgs_set_clockgating_state(hwmgr->device,
168                                                 AMD_IP_BLOCK_TYPE_UVD,
169                                                 AMD_PG_STATE_UNGATE);
170                 cgs_set_powergating_state(hwmgr->device,
171                                                 AMD_IP_BLOCK_TYPE_UVD,
172                                                 AMD_CG_STATE_UNGATE);
173                 cz_dpm_update_uvd_dpm(hwmgr, false);
174         }
175
176 }
177
178 void cz_dpm_powergate_vce(struct pp_hwmgr *hwmgr, bool bgate)
179 {
180         struct cz_hwmgr *cz_hwmgr = (struct cz_hwmgr *)(hwmgr->backend);
181
182         if (bgate) {
183                 cgs_set_powergating_state(
184                                         hwmgr->device,
185                                         AMD_IP_BLOCK_TYPE_VCE,
186                                         AMD_PG_STATE_GATE);
187                 cgs_set_clockgating_state(
188                                         hwmgr->device,
189                                         AMD_IP_BLOCK_TYPE_VCE,
190                                         AMD_CG_STATE_GATE);
191                 cz_enable_disable_vce_dpm(hwmgr, false);
192                 cz_dpm_powerdown_vce(hwmgr);
193                 cz_hwmgr->vce_power_gated = true;
194         } else {
195                 cz_dpm_powerup_vce(hwmgr);
196                 cz_hwmgr->vce_power_gated = false;
197                 cgs_set_clockgating_state(
198                                         hwmgr->device,
199                                         AMD_IP_BLOCK_TYPE_VCE,
200                                         AMD_PG_STATE_UNGATE);
201                 cgs_set_powergating_state(
202                                         hwmgr->device,
203                                         AMD_IP_BLOCK_TYPE_VCE,
204                                         AMD_CG_STATE_UNGATE);
205                 cz_dpm_update_vce_dpm(hwmgr);
206                 cz_enable_disable_vce_dpm(hwmgr, true);
207         }
208 }
209