265 lines · c
1/*2 * Copyright 2020 Advanced Micro Devices, Inc.3 *4 * Permission is hereby granted, free of charge, to any person obtaining a5 * copy of this software and associated documentation files (the "Software"),6 * to deal in the Software without restriction, including without limitation7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,8 * and/or sell copies of the Software, and to permit persons to whom the9 * Software is furnished to do so, subject to the following conditions:10 *11 * The above copyright notice and this permission notice shall be included in12 * all copies or substantial portions of the Software.13 *14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR18 * 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 OR20 * OTHER DEALINGS IN THE SOFTWARE.21 *22 * Authors: AMD23 *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->logger33 34#define REG(reg)\35 (vpg3->regs->reg)36 37#undef FN38#define FN(reg_name, field_name) \39 vpg3->vpg_shift->field_name, vpg3->vpg_mask->field_name40 41 42#define CTX \43 vpg3->base.ctx44 45 46void 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 lock56 * 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 signal64 * assume otg master lock will unlock it65 */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 memory78 */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 header86 * (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 contents95 * (we never use last 4 bytes)96 * there are 8 (0-7) mmDIG0_AFMT_GENERIC0_x registers97 */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 mode108 * (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 245static struct vpg_funcs dcn30_vpg_funcs = {246 .update_generic_info_packet = vpg3_update_generic_info_packet,247};248 249void 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