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 27 #include "dc_bios_types.h" 28 #include "dcn30_vpg.h" 29 #include "reg_helper.h" 30 31 #define DC_LOGGER \ 32 vpg3->base.ctx->logger 33 34 #define REG(reg)\ 35 (vpg3->regs->reg) 36 37 #undef FN 38 #define FN(reg_name, field_name) \ 39 vpg3->vpg_shift->field_name, vpg3->vpg_mask->field_name 40 41 42 #define CTX \ 43 vpg3->base.ctx 44 45 46 void vpg3_update_generic_info_packet( 47 struct vpg *vpg, 48 uint32_t packet_index, 49 const struct dc_info_packet *info_packet, 50 bool immediate_update) 51 { 52 struct dcn30_vpg *vpg3 = DCN30_VPG_FROM_VPG(vpg); 53 uint32_t i; 54 55 /* TODOFPGA Figure out a proper number for max_retries polling for lock 56 * use 50 for now. 57 */ 58 uint32_t max_retries = 50; 59 60 if (packet_index > 14) 61 ASSERT(0); 62 63 /* poll dig_update_lock is not locked -> asic internal signal 64 * assume otg master lock will unlock it 65 */ 66 /* REG_WAIT(AFMT_VBI_PACKET_CONTROL, AFMT_GENERIC_LOCK_STATUS, 67 * 0, 10, max_retries); 68 */ 69 70 /* TODO: Check if this is required */ 71 /* check if HW reading GSP memory */ 72 REG_WAIT(VPG_GENERIC_STATUS, VPG_GENERIC_CONFLICT_OCCURED, 73 0, 10, max_retries); 74 75 /* HW does is not reading GSP memory not reading too long -> 76 * something wrong. clear GPS memory access and notify? 77 * hw SW is writing to GSP memory 78 */ 79 REG_UPDATE(VPG_GENERIC_STATUS, VPG_GENERIC_CONFLICT_CLR, 1); 80 81 /* choose which generic packet to use */ 82 REG_UPDATE(VPG_GENERIC_PACKET_ACCESS_CTRL, 83 VPG_GENERIC_DATA_INDEX, packet_index*9); 84 85 /* write generic packet header 86 * (4th byte is for GENERIC0 only) 87 */ 88 REG_SET_4(VPG_GENERIC_PACKET_DATA, 0, 89 VPG_GENERIC_DATA_BYTE0, info_packet->hb0, 90 VPG_GENERIC_DATA_BYTE1, info_packet->hb1, 91 VPG_GENERIC_DATA_BYTE2, info_packet->hb2, 92 VPG_GENERIC_DATA_BYTE3, info_packet->hb3); 93 94 /* write generic packet contents 95 * (we never use last 4 bytes) 96 * there are 8 (0-7) mmDIG0_AFMT_GENERIC0_x registers 97 */ 98 { 99 const uint32_t *content = 100 (const uint32_t *) &info_packet->sb[0]; 101 102 for (i = 0; i < 8; i++) { 103 REG_WRITE(VPG_GENERIC_PACKET_DATA, *content++); 104 } 105 } 106 107 /* atomically update double-buffered GENERIC0 registers in immediate mode 108 * (update at next block_update when block_update_lock == 0). 109 */ 110 if (immediate_update) { 111 switch (packet_index) { 112 case 0: 113 REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, 114 VPG_GENERIC0_IMMEDIATE_UPDATE, 1); 115 break; 116 case 1: 117 REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, 118 VPG_GENERIC1_IMMEDIATE_UPDATE, 1); 119 break; 120 case 2: 121 REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, 122 VPG_GENERIC2_IMMEDIATE_UPDATE, 1); 123 break; 124 case 3: 125 REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, 126 VPG_GENERIC3_IMMEDIATE_UPDATE, 1); 127 break; 128 case 4: 129 REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, 130 VPG_GENERIC4_IMMEDIATE_UPDATE, 1); 131 break; 132 case 5: 133 REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, 134 VPG_GENERIC5_IMMEDIATE_UPDATE, 1); 135 break; 136 case 6: 137 REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, 138 VPG_GENERIC6_IMMEDIATE_UPDATE, 1); 139 break; 140 case 7: 141 REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, 142 VPG_GENERIC7_IMMEDIATE_UPDATE, 1); 143 break; 144 case 8: 145 REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, 146 VPG_GENERIC8_IMMEDIATE_UPDATE, 1); 147 break; 148 case 9: 149 REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, 150 VPG_GENERIC9_IMMEDIATE_UPDATE, 1); 151 break; 152 case 10: 153 REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, 154 VPG_GENERIC10_IMMEDIATE_UPDATE, 1); 155 break; 156 case 11: 157 REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, 158 VPG_GENERIC11_IMMEDIATE_UPDATE, 1); 159 break; 160 case 12: 161 REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, 162 VPG_GENERIC12_IMMEDIATE_UPDATE, 1); 163 break; 164 case 13: 165 REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, 166 VPG_GENERIC13_IMMEDIATE_UPDATE, 1); 167 break; 168 case 14: 169 REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, 170 VPG_GENERIC14_IMMEDIATE_UPDATE, 1); 171 break; 172 default: 173 break; 174 } 175 } else { 176 switch (packet_index) { 177 case 0: 178 REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL, 179 VPG_GENERIC0_FRAME_UPDATE, 1); 180 break; 181 case 1: 182 REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL, 183 VPG_GENERIC1_FRAME_UPDATE, 1); 184 break; 185 case 2: 186 REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL, 187 VPG_GENERIC2_FRAME_UPDATE, 1); 188 break; 189 case 3: 190 REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL, 191 VPG_GENERIC3_FRAME_UPDATE, 1); 192 break; 193 case 4: 194 REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL, 195 VPG_GENERIC4_FRAME_UPDATE, 1); 196 break; 197 case 5: 198 REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL, 199 VPG_GENERIC5_FRAME_UPDATE, 1); 200 break; 201 case 6: 202 REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL, 203 VPG_GENERIC6_FRAME_UPDATE, 1); 204 break; 205 case 7: 206 REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL, 207 VPG_GENERIC7_FRAME_UPDATE, 1); 208 break; 209 case 8: 210 REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL, 211 VPG_GENERIC8_FRAME_UPDATE, 1); 212 break; 213 case 9: 214 REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL, 215 VPG_GENERIC9_FRAME_UPDATE, 1); 216 break; 217 case 10: 218 REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL, 219 VPG_GENERIC10_FRAME_UPDATE, 1); 220 break; 221 case 11: 222 REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL, 223 VPG_GENERIC11_FRAME_UPDATE, 1); 224 break; 225 case 12: 226 REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL, 227 VPG_GENERIC12_FRAME_UPDATE, 1); 228 break; 229 case 13: 230 REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL, 231 VPG_GENERIC13_FRAME_UPDATE, 1); 232 break; 233 case 14: 234 REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL, 235 VPG_GENERIC14_FRAME_UPDATE, 1); 236 break; 237 238 default: 239 break; 240 } 241 242 } 243 } 244 245 static struct vpg_funcs dcn30_vpg_funcs = { 246 .update_generic_info_packet = vpg3_update_generic_info_packet, 247 }; 248 249 void vpg3_construct(struct dcn30_vpg *vpg3, 250 struct dc_context *ctx, 251 uint32_t inst, 252 const struct dcn30_vpg_registers *vpg_regs, 253 const struct dcn30_vpg_shift *vpg_shift, 254 const struct dcn30_vpg_mask *vpg_mask) 255 { 256 vpg3->base.ctx = ctx; 257 258 vpg3->base.inst = inst; 259 vpg3->base.funcs = &dcn30_vpg_funcs; 260 261 vpg3->regs = vpg_regs; 262 vpg3->vpg_shift = vpg_shift; 263 vpg3->vpg_mask = vpg_mask; 264 } 265