1 /* 2 * Copyright 2020 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 "dcn302_hwseq.h" 27 28 #include "dce/dce_hwseq.h" 29 30 #include "reg_helper.h" 31 #include "dc.h" 32 33 #define DC_LOGGER_INIT(logger) 34 35 #define CTX \ 36 hws->ctx 37 #define REG(reg)\ 38 hws->regs->reg 39 40 #undef FN 41 #define FN(reg_name, field_name) \ 42 hws->shifts->field_name, hws->masks->field_name 43 44 45 void dcn302_dpp_pg_control(struct dce_hwseq *hws, unsigned int dpp_inst, bool power_on) 46 { 47 uint32_t power_gate = power_on ? 0 : 1; 48 uint32_t pwr_status = power_on ? 0 : 2; 49 50 if (hws->ctx->dc->debug.disable_dpp_power_gate) 51 return; 52 if (REG(DOMAIN1_PG_CONFIG) == 0) 53 return; 54 55 switch (dpp_inst) { 56 case 0: /* DPP0 */ 57 REG_UPDATE(DOMAIN1_PG_CONFIG, 58 DOMAIN1_POWER_GATE, power_gate); 59 60 REG_WAIT(DOMAIN1_PG_STATUS, 61 DOMAIN1_PGFSM_PWR_STATUS, pwr_status, 62 1, 1000); 63 break; 64 case 1: /* DPP1 */ 65 REG_UPDATE(DOMAIN3_PG_CONFIG, 66 DOMAIN3_POWER_GATE, power_gate); 67 68 REG_WAIT(DOMAIN3_PG_STATUS, 69 DOMAIN3_PGFSM_PWR_STATUS, pwr_status, 70 1, 1000); 71 break; 72 case 2: /* DPP2 */ 73 REG_UPDATE(DOMAIN5_PG_CONFIG, 74 DOMAIN5_POWER_GATE, power_gate); 75 76 REG_WAIT(DOMAIN5_PG_STATUS, 77 DOMAIN5_PGFSM_PWR_STATUS, pwr_status, 78 1, 1000); 79 break; 80 case 3: /* DPP3 */ 81 REG_UPDATE(DOMAIN7_PG_CONFIG, 82 DOMAIN7_POWER_GATE, power_gate); 83 84 REG_WAIT(DOMAIN7_PG_STATUS, 85 DOMAIN7_PGFSM_PWR_STATUS, pwr_status, 86 1, 1000); 87 break; 88 case 4: /* DPP4 */ 89 REG_UPDATE(DOMAIN9_PG_CONFIG, 90 DOMAIN9_POWER_GATE, power_gate); 91 92 REG_WAIT(DOMAIN9_PG_STATUS, 93 DOMAIN9_PGFSM_PWR_STATUS, pwr_status, 94 1, 1000); 95 break; 96 default: 97 BREAK_TO_DEBUGGER(); 98 break; 99 } 100 } 101 102 void dcn302_hubp_pg_control(struct dce_hwseq *hws, unsigned int hubp_inst, bool power_on) 103 { 104 uint32_t power_gate = power_on ? 0 : 1; 105 uint32_t pwr_status = power_on ? 0 : 2; 106 107 if (hws->ctx->dc->debug.disable_hubp_power_gate) 108 return; 109 if (REG(DOMAIN0_PG_CONFIG) == 0) 110 return; 111 112 switch (hubp_inst) { 113 case 0: /* DCHUBP0 */ 114 REG_UPDATE(DOMAIN0_PG_CONFIG, 115 DOMAIN0_POWER_GATE, power_gate); 116 117 REG_WAIT(DOMAIN0_PG_STATUS, 118 DOMAIN0_PGFSM_PWR_STATUS, pwr_status, 119 1, 1000); 120 break; 121 case 1: /* DCHUBP1 */ 122 REG_UPDATE(DOMAIN2_PG_CONFIG, 123 DOMAIN2_POWER_GATE, power_gate); 124 125 REG_WAIT(DOMAIN2_PG_STATUS, 126 DOMAIN2_PGFSM_PWR_STATUS, pwr_status, 127 1, 1000); 128 break; 129 case 2: /* DCHUBP2 */ 130 REG_UPDATE(DOMAIN4_PG_CONFIG, 131 DOMAIN4_POWER_GATE, power_gate); 132 133 REG_WAIT(DOMAIN4_PG_STATUS, 134 DOMAIN4_PGFSM_PWR_STATUS, pwr_status, 135 1, 1000); 136 break; 137 case 3: /* DCHUBP3 */ 138 REG_UPDATE(DOMAIN6_PG_CONFIG, 139 DOMAIN6_POWER_GATE, power_gate); 140 141 REG_WAIT(DOMAIN6_PG_STATUS, 142 DOMAIN6_PGFSM_PWR_STATUS, pwr_status, 143 1, 1000); 144 break; 145 case 4: /* DCHUBP4 */ 146 REG_UPDATE(DOMAIN8_PG_CONFIG, 147 DOMAIN8_POWER_GATE, power_gate); 148 149 REG_WAIT(DOMAIN8_PG_STATUS, 150 DOMAIN8_PGFSM_PWR_STATUS, pwr_status, 151 1, 1000); 152 break; 153 default: 154 BREAK_TO_DEBUGGER(); 155 break; 156 } 157 } 158 159 void dcn302_dsc_pg_control(struct dce_hwseq *hws, unsigned int dsc_inst, bool power_on) 160 { 161 uint32_t power_gate = power_on ? 0 : 1; 162 uint32_t pwr_status = power_on ? 0 : 2; 163 uint32_t org_ip_request_cntl = 0; 164 165 if (hws->ctx->dc->debug.disable_dsc_power_gate) 166 return; 167 168 if (REG(DOMAIN16_PG_CONFIG) == 0) 169 return; 170 171 REG_GET(DC_IP_REQUEST_CNTL, IP_REQUEST_EN, &org_ip_request_cntl); 172 if (org_ip_request_cntl == 0) 173 REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 1); 174 175 switch (dsc_inst) { 176 case 0: /* DSC0 */ 177 REG_UPDATE(DOMAIN16_PG_CONFIG, 178 DOMAIN16_POWER_GATE, power_gate); 179 180 REG_WAIT(DOMAIN16_PG_STATUS, 181 DOMAIN16_PGFSM_PWR_STATUS, pwr_status, 182 1, 1000); 183 break; 184 case 1: /* DSC1 */ 185 REG_UPDATE(DOMAIN17_PG_CONFIG, 186 DOMAIN17_POWER_GATE, power_gate); 187 188 REG_WAIT(DOMAIN17_PG_STATUS, 189 DOMAIN17_PGFSM_PWR_STATUS, pwr_status, 190 1, 1000); 191 break; 192 case 2: /* DSC2 */ 193 REG_UPDATE(DOMAIN18_PG_CONFIG, 194 DOMAIN18_POWER_GATE, power_gate); 195 196 REG_WAIT(DOMAIN18_PG_STATUS, 197 DOMAIN18_PGFSM_PWR_STATUS, pwr_status, 198 1, 1000); 199 break; 200 case 3: /* DSC3 */ 201 REG_UPDATE(DOMAIN19_PG_CONFIG, 202 DOMAIN19_POWER_GATE, power_gate); 203 204 REG_WAIT(DOMAIN19_PG_STATUS, 205 DOMAIN19_PGFSM_PWR_STATUS, pwr_status, 206 1, 1000); 207 break; 208 case 4: /* DSC4 */ 209 REG_UPDATE(DOMAIN20_PG_CONFIG, 210 DOMAIN20_POWER_GATE, power_gate); 211 212 REG_WAIT(DOMAIN20_PG_STATUS, 213 DOMAIN20_PGFSM_PWR_STATUS, pwr_status, 214 1, 1000); 215 break; 216 default: 217 BREAK_TO_DEBUGGER(); 218 break; 219 } 220 221 if (org_ip_request_cntl == 0) 222 REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 0); 223 } 224