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 /* 90 * Do not power gate DPP4, should be left at HW default, power on permanently. 91 * PG on Pipe4 is De-featured, attempting to put it to PG state may result in hard 92 * reset. 93 * REG_UPDATE(DOMAIN9_PG_CONFIG, 94 * DOMAIN9_POWER_GATE, power_gate); 95 * 96 * REG_WAIT(DOMAIN9_PG_STATUS, 97 * DOMAIN9_PGFSM_PWR_STATUS, pwr_status, 98 * 1, 1000); 99 */ 100 break; 101 default: 102 BREAK_TO_DEBUGGER(); 103 break; 104 } 105 } 106 107 void dcn302_hubp_pg_control(struct dce_hwseq *hws, unsigned int hubp_inst, bool power_on) 108 { 109 uint32_t power_gate = power_on ? 0 : 1; 110 uint32_t pwr_status = power_on ? 0 : 2; 111 112 if (hws->ctx->dc->debug.disable_hubp_power_gate) 113 return; 114 if (REG(DOMAIN0_PG_CONFIG) == 0) 115 return; 116 117 switch (hubp_inst) { 118 case 0: /* DCHUBP0 */ 119 REG_UPDATE(DOMAIN0_PG_CONFIG, 120 DOMAIN0_POWER_GATE, power_gate); 121 122 REG_WAIT(DOMAIN0_PG_STATUS, 123 DOMAIN0_PGFSM_PWR_STATUS, pwr_status, 124 1, 1000); 125 break; 126 case 1: /* DCHUBP1 */ 127 REG_UPDATE(DOMAIN2_PG_CONFIG, 128 DOMAIN2_POWER_GATE, power_gate); 129 130 REG_WAIT(DOMAIN2_PG_STATUS, 131 DOMAIN2_PGFSM_PWR_STATUS, pwr_status, 132 1, 1000); 133 break; 134 case 2: /* DCHUBP2 */ 135 REG_UPDATE(DOMAIN4_PG_CONFIG, 136 DOMAIN4_POWER_GATE, power_gate); 137 138 REG_WAIT(DOMAIN4_PG_STATUS, 139 DOMAIN4_PGFSM_PWR_STATUS, pwr_status, 140 1, 1000); 141 break; 142 case 3: /* DCHUBP3 */ 143 REG_UPDATE(DOMAIN6_PG_CONFIG, 144 DOMAIN6_POWER_GATE, power_gate); 145 146 REG_WAIT(DOMAIN6_PG_STATUS, 147 DOMAIN6_PGFSM_PWR_STATUS, pwr_status, 148 1, 1000); 149 break; 150 case 4: /* DCHUBP4 */ 151 /* 152 * Do not power gate DCHUB4, should be left at HW default, power on permanently. 153 * PG on Pipe4 is De-featured, attempting to put it to PG state may result in hard 154 * reset. 155 * REG_UPDATE(DOMAIN8_PG_CONFIG, 156 * DOMAIN8_POWER_GATE, power_gate); 157 * 158 * REG_WAIT(DOMAIN8_PG_STATUS, 159 * DOMAIN8_PGFSM_PWR_STATUS, pwr_status, 160 * 1, 1000); 161 */ 162 break; 163 default: 164 BREAK_TO_DEBUGGER(); 165 break; 166 } 167 } 168 169 void dcn302_dsc_pg_control(struct dce_hwseq *hws, unsigned int dsc_inst, bool power_on) 170 { 171 uint32_t power_gate = power_on ? 0 : 1; 172 uint32_t pwr_status = power_on ? 0 : 2; 173 uint32_t org_ip_request_cntl = 0; 174 175 if (hws->ctx->dc->debug.disable_dsc_power_gate) 176 return; 177 178 if (REG(DOMAIN16_PG_CONFIG) == 0) 179 return; 180 181 REG_GET(DC_IP_REQUEST_CNTL, IP_REQUEST_EN, &org_ip_request_cntl); 182 if (org_ip_request_cntl == 0) 183 REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 1); 184 185 switch (dsc_inst) { 186 case 0: /* DSC0 */ 187 REG_UPDATE(DOMAIN16_PG_CONFIG, 188 DOMAIN16_POWER_GATE, power_gate); 189 190 REG_WAIT(DOMAIN16_PG_STATUS, 191 DOMAIN16_PGFSM_PWR_STATUS, pwr_status, 192 1, 1000); 193 break; 194 case 1: /* DSC1 */ 195 REG_UPDATE(DOMAIN17_PG_CONFIG, 196 DOMAIN17_POWER_GATE, power_gate); 197 198 REG_WAIT(DOMAIN17_PG_STATUS, 199 DOMAIN17_PGFSM_PWR_STATUS, pwr_status, 200 1, 1000); 201 break; 202 case 2: /* DSC2 */ 203 REG_UPDATE(DOMAIN18_PG_CONFIG, 204 DOMAIN18_POWER_GATE, power_gate); 205 206 REG_WAIT(DOMAIN18_PG_STATUS, 207 DOMAIN18_PGFSM_PWR_STATUS, pwr_status, 208 1, 1000); 209 break; 210 case 3: /* DSC3 */ 211 REG_UPDATE(DOMAIN19_PG_CONFIG, 212 DOMAIN19_POWER_GATE, power_gate); 213 214 REG_WAIT(DOMAIN19_PG_STATUS, 215 DOMAIN19_PGFSM_PWR_STATUS, pwr_status, 216 1, 1000); 217 break; 218 case 4: /* DSC4 */ 219 REG_UPDATE(DOMAIN20_PG_CONFIG, 220 DOMAIN20_POWER_GATE, power_gate); 221 222 REG_WAIT(DOMAIN20_PG_STATUS, 223 DOMAIN20_PGFSM_PWR_STATUS, pwr_status, 224 1, 1000); 225 break; 226 default: 227 BREAK_TO_DEBUGGER(); 228 break; 229 } 230 231 if (org_ip_request_cntl == 0) 232 REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 0); 233 } 234