FILE
dcn401_hubp.c
File preview with syntax highlighting.
linux-6.19.14/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c
1/* 2 * Copyright 2023 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 "dm_services.h" 27#include "dce_calcs.h" 28#include "reg_helper.h" 29#include "basics/conversion.h" 30#include "dcn401_hubp.h" 31#include "dal_asic_id.h" 32 33#define REG(reg)\ 34 hubp2->hubp_regs->reg 35 36#define CTX \ 37 hubp2->base.ctx 38 39#undef FN 40#define FN(reg_name, field_name) \ 41 hubp2->hubp_shift->field_name, hubp2->hubp_mask->field_name 42 43void hubp401_program_3dlut_fl_addr(struct hubp *hubp, 44 const struct dc_plane_address address) 45{ 46 struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); 47 48 REG_UPDATE(HUBP_3DLUT_ADDRESS_HIGH, HUBP_3DLUT_ADDRESS_HIGH, address.lut3d.addr.high_part); 49 REG_WRITE(HUBP_3DLUT_ADDRESS_LOW, address.lut3d.addr.low_part); 50} 51 52void hubp401_program_3dlut_fl_dlg_param(struct hubp *hubp, int refcyc_per_3dlut_group) 53{ 54 struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); 55 56 REG_UPDATE(HUBP_3DLUT_DLG_PARAM, REFCYC_PER_3DLUT_GROUP, refcyc_per_3dlut_group); 57} 58 59void hubp401_enable_3dlut_fl(struct hubp *hubp, bool enable) 60{ 61 struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); 62 63 REG_UPDATE(HUBP_3DLUT_CONTROL, HUBP_3DLUT_ENABLE, enable ? 1 : 0); 64} 65 66int hubp401_get_3dlut_fl_done(struct hubp *hubp) 67{ 68 struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); 69 int ret; 70 71 REG_GET(HUBP_3DLUT_CONTROL, HUBP_3DLUT_DONE, &ret); 72 return ret; 73} 74 75void hubp401_program_3dlut_fl_addressing_mode(struct hubp *hubp, enum hubp_3dlut_fl_addressing_mode addr_mode) 76{ 77 struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); 78 79 REG_UPDATE(HUBP_3DLUT_CONTROL, HUBP_3DLUT_ADDRESSING_MODE, addr_mode); 80} 81 82void hubp401_program_3dlut_fl_width(struct hubp *hubp, enum hubp_3dlut_fl_width width) 83{ 84 struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); 85 86 REG_UPDATE(HUBP_3DLUT_CONTROL, HUBP_3DLUT_WIDTH, width); 87} 88 89void hubp401_program_3dlut_fl_tmz_protected(struct hubp *hubp, uint8_t protection_bits) 90{ 91 struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); 92 93 REG_UPDATE(HUBP_3DLUT_CONTROL, HUBP_3DLUT_TMZ, protection_bits); 94} 95 96void hubp401_program_3dlut_fl_crossbar(struct hubp *hubp, 97 enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_y_g, 98 enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_cb_b, 99 enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_cr_r) 100{ 101 struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); 102 103 REG_UPDATE_3(HUBP_3DLUT_CONTROL, 104 HUBP_3DLUT_CROSSBAR_SELECT_Y_G, bit_slice_y_g, 105 HUBP_3DLUT_CROSSBAR_SELECT_CB_B, bit_slice_cb_b, 106 HUBP_3DLUT_CROSSBAR_SELECT_CR_R, bit_slice_cr_r); 107} 108 109void hubp401_update_3dlut_fl_bias_scale(struct hubp *hubp, uint16_t bias, uint16_t scale) 110{ 111 struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); 112 113 REG_UPDATE_2(_3DLUT_FL_BIAS_SCALE, HUBP0_3DLUT_FL_BIAS, bias, HUBP0_3DLUT_FL_SCALE, scale); 114} 115 116void hubp401_program_3dlut_fl_mode(struct hubp *hubp, enum hubp_3dlut_fl_mode mode) 117{ 118 struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); 119 120 REG_UPDATE(_3DLUT_FL_CONFIG, HUBP0_3DLUT_FL_MODE, mode); 121} 122 123void hubp401_program_3dlut_fl_format(struct hubp *hubp, enum hubp_3dlut_fl_format format) 124{ 125 struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); 126 127 REG_UPDATE(_3DLUT_FL_CONFIG, HUBP0_3DLUT_FL_FORMAT, format); 128} 129 130void hubp401_program_3dlut_fl_config( 131 struct hubp *hubp, 132 struct hubp_fl_3dlut_config *cfg) 133{ 134 struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); 135 136 uint32_t mpc_width = {(cfg->width == 17) ? 0 : 1}; 137 uint32_t width = {cfg->width}; 138 139 if (cfg->layout == DC_CM2_GPU_MEM_LAYOUT_1D_PACKED_LINEAR) 140 width = (cfg->width == 17) ? 4916 : 35940; 141 142 REG_UPDATE_2(_3DLUT_FL_CONFIG, 143 HUBP0_3DLUT_FL_MODE, cfg->mode, 144 HUBP0_3DLUT_FL_FORMAT, cfg->format); 145 146 REG_UPDATE_2(_3DLUT_FL_BIAS_SCALE, 147 HUBP0_3DLUT_FL_BIAS, cfg->bias, 148 HUBP0_3DLUT_FL_SCALE, cfg->scale); 149 150 REG_UPDATE(HUBP_3DLUT_ADDRESS_HIGH, 151 HUBP_3DLUT_ADDRESS_HIGH, cfg->address.lut3d.addr.high_part); 152 REG_UPDATE(HUBP_3DLUT_ADDRESS_LOW, 153 HUBP_3DLUT_ADDRESS_LOW, cfg->address.lut3d.addr.low_part); 154 155 //cross bar 156 REG_UPDATE_8(HUBP_3DLUT_CONTROL, 157 HUBP_3DLUT_MPC_WIDTH, mpc_width, 158 HUBP_3DLUT_WIDTH, width, 159 HUBP_3DLUT_CROSSBAR_SELECT_CR_R, cfg->crossbar_bit_slice_cr_r, 160 HUBP_3DLUT_CROSSBAR_SELECT_Y_G, cfg->crossbar_bit_slice_y_g, 161 HUBP_3DLUT_CROSSBAR_SELECT_CB_B, cfg->crossbar_bit_slice_cb_b, 162 HUBP_3DLUT_ADDRESSING_MODE, cfg->addr_mode, 163 HUBP_3DLUT_TMZ, cfg->protection_bits, 164 HUBP_3DLUT_ENABLE, cfg->enabled ? 1 : 0); 165} 166 167void hubp401_update_mall_sel(struct hubp *hubp, uint32_t mall_sel, bool c_cursor) 168{ 169 struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); 170 171 // Also cache cursor in MALL if using MALL for SS 172 REG_UPDATE_2(DCHUBP_MALL_CONFIG, USE_MALL_SEL, mall_sel, 173 USE_MALL_FOR_CURSOR, c_cursor); 174 175 REG_UPDATE_2(DCHUBP_MALL_CONFIG, MALL_PREF_CMD_TYPE, 1, MALL_PREF_MODE, 0); 176} 177 178 179void hubp401_init(struct hubp *hubp) 180{ 181 hubp_reset(hubp); 182} 183 184void hubp401_vready_at_or_After_vsync(struct hubp *hubp, 185 union dml2_global_sync_programming *pipe_global_sync, 186 struct dc_crtc_timing *timing) 187{ 188 unsigned int vstartup_lines = pipe_global_sync->dcn4x.vstartup_lines; 189 unsigned int vupdate_offset_pixels = pipe_global_sync->dcn4x.vupdate_offset_pixels; 190 unsigned int vupdate_width_pixels = pipe_global_sync->dcn4x.vupdate_vupdate_width_pixels; 191 unsigned int vready_offset_pixels = pipe_global_sync->dcn4x.vready_offset_pixels; 192 unsigned int htotal = timing->h_total; 193 unsigned int vblank_start = 0; 194 unsigned int vblank_end = 0; 195 unsigned int pixel_width = 0; 196 uint32_t reg_value = 0; 197 bool is_vready_at_or_after_vsync = false; 198 struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); 199 200 /* 201 * if (VSTARTUP_START - (VREADY_OFFSET+VUPDATE_WIDTH+VUPDATE_OFFSET)/htotal) <= OTG_V_BLANK_END 202 * Set HUBP_VREADY_AT_OR_AFTER_VSYNC = 1 203 * else 204 * Set HUBP_VREADY_AT_OR_AFTER_VSYNC = 0 205 */ 206 if (htotal != 0) { 207 vblank_start = timing->v_total - timing->v_front_porch; 208 vblank_end = vblank_start - timing->v_addressable - timing->v_border_top - timing->v_border_bottom; 209 pixel_width = vready_offset_pixels + vupdate_width_pixels + vupdate_offset_pixels; 210 211 is_vready_at_or_after_vsync = (vstartup_lines - pixel_width / htotal) <= vblank_end; 212 213 if (is_vready_at_or_after_vsync) 214 reg_value = 1; 215 } 216 217 REG_UPDATE(DCHUBP_CNTL, HUBP_VREADY_AT_OR_AFTER_VSYNC, reg_value); 218} 219 220void hubp401_program_requestor( 221 struct hubp *hubp, 222 struct dml2_display_rq_regs *rq_regs) 223{ 224 struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); 225 226 REG_UPDATE(HUBPRET_CONTROL, 227 DET_BUF_PLANE1_BASE_ADDRESS, rq_regs->plane1_base_address); 228 REG_SET_4(DCN_EXPANSION_MODE, 0, 229 DRQ_EXPANSION_MODE, rq_regs->drq_expansion_mode, 230 PRQ_EXPANSION_MODE, rq_regs->prq_expansion_mode, 231 MRQ_EXPANSION_MODE, rq_regs->mrq_expansion_mode, 232 CRQ_EXPANSION_MODE, rq_regs->crq_expansion_mode); 233 REG_SET_6(DCHUBP_REQ_SIZE_CONFIG, 0, 234 CHUNK_SIZE, rq_regs->rq_regs_l.chunk_size, 235 MIN_CHUNK_SIZE, rq_regs->rq_regs_l.min_chunk_size, 236 DPTE_GROUP_SIZE, rq_regs->rq_regs_l.dpte_group_size, 237 VM_GROUP_SIZE, rq_regs->rq_regs_l.mpte_group_size, 238 SWATH_HEIGHT, rq_regs->rq_regs_l.swath_height, 239 PTE_ROW_HEIGHT_LINEAR, rq_regs->rq_regs_l.pte_row_height_linear); 240 REG_SET_5(DCHUBP_REQ_SIZE_CONFIG_C, 0, 241 CHUNK_SIZE_C, rq_regs->rq_regs_c.chunk_size, 242 MIN_CHUNK_SIZE_C, rq_regs->rq_regs_c.min_chunk_size, 243 DPTE_GROUP_SIZE_C, rq_regs->rq_regs_c.dpte_group_size, 244 SWATH_HEIGHT_C, rq_regs->rq_regs_c.swath_height, 245 PTE_ROW_HEIGHT_LINEAR_C, rq_regs->rq_regs_c.pte_row_height_linear); 246} 247 248void hubp401_program_deadline( 249 struct hubp *hubp, 250 struct dml2_display_dlg_regs *dlg_attr, 251 struct dml2_display_ttu_regs *ttu_attr) 252{ 253 struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); 254 255 /* put DLG in mission mode */ 256 REG_WRITE(HUBPREQ_DEBUG_DB, 1 << 8); 257 258 /* DLG - Per hubp */ 259 REG_SET_2(BLANK_OFFSET_0, 0, 260 REFCYC_H_BLANK_END, dlg_attr->refcyc_h_blank_end, 261 DLG_V_BLANK_END, dlg_attr->dlg_vblank_end); 262 263 REG_SET(BLANK_OFFSET_1, 0, 264 MIN_DST_Y_NEXT_START, dlg_attr->min_dst_y_next_start); 265 266 REG_SET(DST_DIMENSIONS, 0, 267 REFCYC_PER_HTOTAL, dlg_attr->refcyc_per_htotal); 268 269 REG_SET_2(DST_AFTER_SCALER, 0, 270 REFCYC_X_AFTER_SCALER, dlg_attr->refcyc_x_after_scaler, 271 DST_Y_AFTER_SCALER, dlg_attr->dst_y_after_scaler); 272 273 REG_SET(REF_FREQ_TO_PIX_FREQ, 0, 274 REF_FREQ_TO_PIX_FREQ, dlg_attr->ref_freq_to_pix_freq); 275 276 /* DLG - Per luma/chroma */ 277 REG_SET(VBLANK_PARAMETERS_1, 0, 278 REFCYC_PER_PTE_GROUP_VBLANK_L, dlg_attr->refcyc_per_pte_group_vblank_l); 279 280 if (REG(NOM_PARAMETERS_0)) 281 REG_SET(NOM_PARAMETERS_0, 0, 282 DST_Y_PER_PTE_ROW_NOM_L, dlg_attr->dst_y_per_pte_row_nom_l); 283 284 if (REG(NOM_PARAMETERS_1)) 285 REG_SET(NOM_PARAMETERS_1, 0, 286 REFCYC_PER_PTE_GROUP_NOM_L, dlg_attr->refcyc_per_pte_group_nom_l); 287 288 REG_SET(NOM_PARAMETERS_4, 0, 289 DST_Y_PER_META_ROW_NOM_L, dlg_attr->dst_y_per_meta_row_nom_l); 290 291 REG_SET(NOM_PARAMETERS_5, 0, 292 REFCYC_PER_META_CHUNK_NOM_L, dlg_attr->refcyc_per_meta_chunk_nom_l); 293 294 REG_SET_2(PER_LINE_DELIVERY, 0, 295 REFCYC_PER_LINE_DELIVERY_L, dlg_attr->refcyc_per_line_delivery_l, 296 REFCYC_PER_LINE_DELIVERY_C, dlg_attr->refcyc_per_line_delivery_c); 297 298 REG_SET(VBLANK_PARAMETERS_2, 0, 299 REFCYC_PER_PTE_GROUP_VBLANK_C, dlg_attr->refcyc_per_pte_group_vblank_c); 300 301 if (REG(NOM_PARAMETERS_2)) 302 REG_SET(NOM_PARAMETERS_2, 0, 303 DST_Y_PER_PTE_ROW_NOM_C, dlg_attr->dst_y_per_pte_row_nom_c); 304 305 if (REG(NOM_PARAMETERS_3)) 306 REG_SET(NOM_PARAMETERS_3, 0, 307 REFCYC_PER_PTE_GROUP_NOM_C, dlg_attr->refcyc_per_pte_group_nom_c); 308 309 REG_SET(NOM_PARAMETERS_6, 0, 310 DST_Y_PER_META_ROW_NOM_C, dlg_attr->dst_y_per_meta_row_nom_c); 311 312 REG_SET(NOM_PARAMETERS_7, 0, 313 REFCYC_PER_META_CHUNK_NOM_C, dlg_attr->refcyc_per_meta_chunk_nom_c); 314 315 /* TTU - per hubp */ 316 REG_SET_2(DCN_TTU_QOS_WM, 0, 317 QoS_LEVEL_LOW_WM, ttu_attr->qos_level_low_wm, 318 QoS_LEVEL_HIGH_WM, ttu_attr->qos_level_high_wm); 319 320 /* TTU - per luma/chroma */ 321 /* Assumed surf0 is luma and 1 is chroma */ 322 323 REG_SET_3(DCN_SURF0_TTU_CNTL0, 0, 324 REFCYC_PER_REQ_DELIVERY, ttu_attr->refcyc_per_req_delivery_l, 325 QoS_LEVEL_FIXED, ttu_attr->qos_level_fixed_l, 326 QoS_RAMP_DISABLE, ttu_attr->qos_ramp_disable_l); 327 328 REG_SET_3(DCN_SURF1_TTU_CNTL0, 0, 329 REFCYC_PER_REQ_DELIVERY, ttu_attr->refcyc_per_req_delivery_c, 330 QoS_LEVEL_FIXED, ttu_attr->qos_level_fixed_c, 331 QoS_RAMP_DISABLE, ttu_attr->qos_ramp_disable_c); 332 333 REG_SET_3(DCN_CUR0_TTU_CNTL0, 0, 334 REFCYC_PER_REQ_DELIVERY, ttu_attr->refcyc_per_req_delivery_cur0, 335 QoS_LEVEL_FIXED, ttu_attr->qos_level_fixed_cur0, 336 QoS_RAMP_DISABLE, ttu_attr->qos_ramp_disable_cur0); 337 338 REG_SET(FLIP_PARAMETERS_1, 0, 339 REFCYC_PER_PTE_GROUP_FLIP_L, dlg_attr->refcyc_per_pte_group_flip_l); 340 REG_SET(HUBP_3DLUT_DLG_PARAM, 0, REFCYC_PER_3DLUT_GROUP, dlg_attr->refcyc_per_tdlut_group); 341 342 REG_UPDATE(DCN_DMDATA_VM_CNTL, 343 REFCYC_PER_VM_DMDATA, dlg_attr->refcyc_per_vm_dmdata); 344} 345 346void hubp401_setup( 347 struct hubp *hubp, 348 struct dml2_dchub_per_pipe_register_set *pipe_regs, 349 union dml2_global_sync_programming *pipe_global_sync, 350 struct dc_crtc_timing *timing) 351{ 352 /* otg is locked when this func is called. Register are double buffered. 353 * disable the requestors is not needed 354 */ 355 hubp401_vready_at_or_After_vsync(hubp, pipe_global_sync, timing); 356 hubp401_program_requestor(hubp, &pipe_regs->rq_regs); 357 hubp401_program_deadline(hubp, &pipe_regs->dlg_regs, &pipe_regs->ttu_regs); 358} 359 360void hubp401_setup_interdependent( 361 struct hubp *hubp, 362 struct dml2_dchub_per_pipe_register_set *pipe_regs) 363{ 364 struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); 365 366 REG_SET_2(PREFETCH_SETTINGS, 0, 367 DST_Y_PREFETCH, pipe_regs->dlg_regs.dst_y_prefetch, 368 VRATIO_PREFETCH, pipe_regs->dlg_regs.vratio_prefetch); 369 370 REG_SET(PREFETCH_SETTINGS_C, 0, 371 VRATIO_PREFETCH_C, pipe_regs->dlg_regs.vratio_prefetch_c); 372 373 REG_SET_2(VBLANK_PARAMETERS_0, 0, 374 DST_Y_PER_VM_VBLANK, pipe_regs->dlg_regs.dst_y_per_vm_vblank, 375 DST_Y_PER_ROW_VBLANK, pipe_regs->dlg_regs.dst_y_per_row_vblank); 376 377 REG_SET_2(FLIP_PARAMETERS_0, 0, 378 DST_Y_PER_VM_FLIP, pipe_regs->dlg_regs.dst_y_per_vm_flip, 379 DST_Y_PER_ROW_FLIP, pipe_regs->dlg_regs.dst_y_per_row_flip); 380 381 REG_SET(VBLANK_PARAMETERS_3, 0, 382 REFCYC_PER_META_CHUNK_VBLANK_L, pipe_regs->dlg_regs.refcyc_per_meta_chunk_vblank_l); 383 384 REG_SET(VBLANK_PARAMETERS_4, 0, 385 REFCYC_PER_META_CHUNK_VBLANK_C, pipe_regs->dlg_regs.refcyc_per_meta_chunk_vblank_c); 386 387 REG_SET(FLIP_PARAMETERS_2, 0, 388 REFCYC_PER_META_CHUNK_FLIP_L, pipe_regs->dlg_regs.refcyc_per_meta_chunk_flip_l); 389 390 REG_SET_2(PER_LINE_DELIVERY_PRE, 0, 391 REFCYC_PER_LINE_DELIVERY_PRE_L, pipe_regs->dlg_regs.refcyc_per_line_delivery_pre_l, 392 REFCYC_PER_LINE_DELIVERY_PRE_C, pipe_regs->dlg_regs.refcyc_per_line_delivery_pre_c); 393 394 REG_SET(DCN_SURF0_TTU_CNTL1, 0, 395 REFCYC_PER_REQ_DELIVERY_PRE, 396 pipe_regs->ttu_regs.refcyc_per_req_delivery_pre_l); 397 REG_SET(DCN_SURF1_TTU_CNTL1, 0, 398 REFCYC_PER_REQ_DELIVERY_PRE, 399 pipe_regs->ttu_regs.refcyc_per_req_delivery_pre_c); 400 REG_SET(DCN_CUR0_TTU_CNTL1, 0, 401 REFCYC_PER_REQ_DELIVERY_PRE, pipe_regs->ttu_regs.refcyc_per_req_delivery_pre_cur0); 402 403 REG_SET_2(DCN_GLOBAL_TTU_CNTL, 0, 404 MIN_TTU_VBLANK, pipe_regs->ttu_regs.min_ttu_vblank, 405 QoS_LEVEL_FLIP, pipe_regs->ttu_regs.qos_level_flip); 406} 407 408 409bool hubp401_program_surface_flip_and_addr( 410 struct hubp *hubp, 411 const struct dc_plane_address *address, 412 bool flip_immediate) 413{ 414 struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); 415 416 //program flip type 417 REG_UPDATE(DCSURF_FLIP_CONTROL, 418 SURFACE_FLIP_TYPE, flip_immediate); 419 420 // Program VMID reg 421 if (flip_immediate == 0) 422 REG_UPDATE(VMID_SETTINGS_0, 423 VMID, address->vmid); 424 425 if (address->type == PLN_ADDR_TYPE_GRPH_STEREO) { 426 REG_UPDATE(DCSURF_FLIP_CONTROL, SURFACE_FLIP_MODE_FOR_STEREOSYNC, 0); 427 REG_UPDATE(DCSURF_FLIP_CONTROL, SURFACE_FLIP_IN_STEREOSYNC, 0x1); 428 429 } else { 430 // turn off stereo if not in stereo 431 REG_UPDATE(DCSURF_FLIP_CONTROL, SURFACE_FLIP_MODE_FOR_STEREOSYNC, 0x0); 432 REG_UPDATE(DCSURF_FLIP_CONTROL, SURFACE_FLIP_IN_STEREOSYNC, 0x0); 433 } 434 435 /* HW automatically latch rest of address register on write to 436 * DCSURF_PRIMARY_SURFACE_ADDRESS if SURFACE_UPDATE_LOCK is not used 437 * 438 * program high first and then the low addr, order matters! 439 */ 440 switch (address->type) { 441 case PLN_ADDR_TYPE_GRAPHICS: 442 if (address->grph.addr.quad_part == 0) 443 break; 444 445 REG_UPDATE(DCSURF_SURFACE_CONTROL, 446 PRIMARY_SURFACE_TMZ, address->tmz_surface); 447 448 REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH, 0, 449 PRIMARY_SURFACE_ADDRESS_HIGH, 450 address->grph.addr.high_part); 451 452 REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS, 0, 453 PRIMARY_SURFACE_ADDRESS, 454 address->grph.addr.low_part); 455 break; 456 case PLN_ADDR_TYPE_VIDEO_PROGRESSIVE: 457 if (address->video_progressive.luma_addr.quad_part == 0 458 || address->video_progressive.chroma_addr.quad_part == 0) 459 break; 460 461 REG_UPDATE_2(DCSURF_SURFACE_CONTROL, 462 PRIMARY_SURFACE_TMZ, address->tmz_surface, 463 PRIMARY_SURFACE_TMZ_C, address->tmz_surface); 464 465 REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_C, 0, 466 PRIMARY_SURFACE_ADDRESS_HIGH_C, 467 address->video_progressive.chroma_addr.high_part); 468 469 REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_C, 0, 470 PRIMARY_SURFACE_ADDRESS_C, 471 address->video_progressive.chroma_addr.low_part); 472 473 REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH, 0, 474 PRIMARY_SURFACE_ADDRESS_HIGH, 475 address->video_progressive.luma_addr.high_part); 476 477 REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS, 0, 478 PRIMARY_SURFACE_ADDRESS, 479 address->video_progressive.luma_addr.low_part); 480 break; 481 case PLN_ADDR_TYPE_GRPH_STEREO: 482 if (address->grph_stereo.left_addr.quad_part == 0) 483 break; 484 if (address->grph_stereo.right_addr.quad_part == 0) 485 break; 486 487 REG_UPDATE_4(DCSURF_SURFACE_CONTROL, 488 PRIMARY_SURFACE_TMZ, address->tmz_surface, 489 PRIMARY_SURFACE_TMZ_C, address->tmz_surface, 490 SECONDARY_SURFACE_TMZ, address->tmz_surface, 491 SECONDARY_SURFACE_TMZ_C, address->tmz_surface); 492 493 REG_SET(DCSURF_SECONDARY_SURFACE_ADDRESS_HIGH_C, 0, 494 SECONDARY_SURFACE_ADDRESS_HIGH_C, 495 address->grph_stereo.right_alpha_addr.high_part); 496 497 REG_SET(DCSURF_SECONDARY_SURFACE_ADDRESS_C, 0, 498 SECONDARY_SURFACE_ADDRESS_C, 499 address->grph_stereo.right_alpha_addr.low_part); 500 501 REG_SET(DCSURF_SECONDARY_SURFACE_ADDRESS_HIGH, 0, 502 SECONDARY_SURFACE_ADDRESS_HIGH, 503 address->grph_stereo.right_addr.high_part); 504 505 REG_SET(DCSURF_SECONDARY_SURFACE_ADDRESS, 0, 506 SECONDARY_SURFACE_ADDRESS, 507 address->grph_stereo.right_addr.low_part); 508 509 REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_C, 0, 510 PRIMARY_SURFACE_ADDRESS_HIGH_C, 511 address->grph_stereo.left_alpha_addr.high_part); 512 513 REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_C, 0, 514 PRIMARY_SURFACE_ADDRESS_C, 515 address->grph_stereo.left_alpha_addr.low_part); 516 517 REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH, 0, 518 PRIMARY_SURFACE_ADDRESS_HIGH, 519 address->grph_stereo.left_addr.high_part); 520 521 REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS, 0, 522 PRIMARY_SURFACE_ADDRESS, 523 address->grph_stereo.left_addr.low_part); 524 break; 525 case PLN_ADDR_TYPE_RGBEA: 526 if (address->rgbea.addr.quad_part == 0 527 || address->rgbea.alpha_addr.quad_part == 0) 528 break; 529 530 REG_UPDATE_2(DCSURF_SURFACE_CONTROL, 531 PRIMARY_SURFACE_TMZ, address->tmz_surface, 532 PRIMARY_SURFACE_TMZ_C, address->tmz_surface); 533 534 REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_C, 0, 535 PRIMARY_SURFACE_ADDRESS_HIGH_C, 536 address->rgbea.alpha_addr.high_part); 537 538 REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_C, 0, 539 PRIMARY_SURFACE_ADDRESS_C, 540 address->rgbea.alpha_addr.low_part); 541 542 REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH, 0, 543 PRIMARY_SURFACE_ADDRESS_HIGH, 544 address->rgbea.addr.high_part); 545 546 REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS, 0, 547 PRIMARY_SURFACE_ADDRESS, 548 address->rgbea.addr.low_part); 549 break; 550 default: 551 BREAK_TO_DEBUGGER(); 552 break; 553 } 554 555 hubp->request_address = *address; 556 557 return true; 558} 559 560void hubp401_clear_tiling(struct hubp *hubp) 561{ 562 struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); 563 564 REG_UPDATE(DCHUBP_REQ_SIZE_CONFIG, SWATH_HEIGHT, 0); 565 REG_UPDATE(DCSURF_TILING_CONFIG, SW_MODE, DC_SW_LINEAR); 566 567 REG_UPDATE_2(DCSURF_SURFACE_CONTROL, 568 PRIMARY_SURFACE_DCC_EN, 0, 569 SECONDARY_SURFACE_DCC_EN, 0); 570} 571 572void hubp401_dcc_control(struct hubp *hubp, 573 struct dc_plane_dcc_param *dcc) 574{ 575 struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); 576 577 REG_UPDATE_2(DCSURF_SURFACE_CONTROL, 578 PRIMARY_SURFACE_DCC_EN, dcc->enable, 579 SECONDARY_SURFACE_DCC_EN, dcc->enable); 580} 581 582void hubp401_program_tiling( 583 struct dcn20_hubp *hubp2, 584 const struct dc_tiling_info *info, 585 const enum surface_pixel_format pixel_format) 586{ 587 /* DCSURF_ADDR_CONFIG still shows up in reg spec, but does not need to be programmed for DCN4x 588 * All 4 fields NUM_PIPES, PIPE_INTERLEAVE, MAX_COMPRESSED_FRAGS and NUM_PKRS are irrelevant. 589 * 590 * DIM_TYPE field in DCSURF_TILING for Display is always 1 (2D dimension) which is HW default. 591 */ 592 REG_UPDATE(DCSURF_TILING_CONFIG, SW_MODE, info->gfx_addr3.swizzle); 593} 594 595void hubp401_program_size( 596 struct hubp *hubp, 597 enum surface_pixel_format format, 598 const struct plane_size *plane_size, 599 struct dc_plane_dcc_param *dcc) 600{ 601 struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); 602 uint32_t pitch, pitch_c; 603 bool use_pitch_c = false; 604 605 /* Program data pitch (calculation from addrlib) 606 * 444 or 420 luma 607 */ 608 use_pitch_c = format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN 609 && format < SURFACE_PIXEL_FORMAT_SUBSAMPLE_END; 610 use_pitch_c = use_pitch_c 611 || (format == SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA); 612 if (use_pitch_c) { 613 ASSERT(plane_size->chroma_pitch != 0); 614 /* Chroma pitch zero can cause system hang! */ 615 616 pitch = plane_size->surface_pitch - 1; 617 pitch_c = plane_size->chroma_pitch - 1; 618 } else { 619 pitch = plane_size->surface_pitch - 1; 620 pitch_c = 0; 621 } 622 623 REG_UPDATE(DCSURF_SURFACE_PITCH, PITCH, pitch); 624 625 if (use_pitch_c) 626 REG_UPDATE(DCSURF_SURFACE_PITCH_C, PITCH_C, pitch_c); 627} 628 629void hubp401_program_surface_config( 630 struct hubp *hubp, 631 enum surface_pixel_format format, 632 struct dc_tiling_info *tiling_info, 633 struct plane_size *plane_size, 634 enum dc_rotation_angle rotation, 635 struct dc_plane_dcc_param *dcc, 636 bool horizontal_mirror, 637 unsigned int compat_level) 638{ 639 struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); 640 641 hubp401_dcc_control(hubp, dcc); 642 hubp401_program_tiling(hubp2, tiling_info, format); 643 hubp401_program_size(hubp, format, plane_size, dcc); 644 hubp2_program_rotation(hubp, rotation, horizontal_mirror); 645 hubp2_program_pixel_format(hubp, format); 646} 647 648void hubp401_set_viewport( 649 struct hubp *hubp, 650 const struct rect *viewport, 651 const struct rect *viewport_c) 652{ 653 struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); 654 655 REG_SET_2(DCSURF_PRI_VIEWPORT_DIMENSION, 0, 656 PRI_VIEWPORT_WIDTH, viewport->width, 657 PRI_VIEWPORT_HEIGHT, viewport->height); 658 659 REG_SET_2(DCSURF_PRI_VIEWPORT_START, 0, 660 PRI_VIEWPORT_X_START, viewport->x, 661 PRI_VIEWPORT_Y_START, viewport->y); 662 663 /*for stereo*/ 664 REG_SET_2(DCSURF_SEC_VIEWPORT_DIMENSION, 0, 665 SEC_VIEWPORT_WIDTH, viewport->width, 666 SEC_VIEWPORT_HEIGHT, viewport->height); 667 668 REG_SET_2(DCSURF_SEC_VIEWPORT_START, 0, 669 SEC_VIEWPORT_X_START, viewport->x, 670 SEC_VIEWPORT_Y_START, viewport->y); 671 672 /* DC supports NV12 only at the moment */ 673 REG_SET_2(DCSURF_PRI_VIEWPORT_DIMENSION_C, 0, 674 PRI_VIEWPORT_WIDTH_C, viewport_c->width, 675 PRI_VIEWPORT_HEIGHT_C, viewport_c->height); 676 677 REG_SET_2(DCSURF_PRI_VIEWPORT_START_C, 0, 678 PRI_VIEWPORT_X_START_C, viewport_c->x, 679 PRI_VIEWPORT_Y_START_C, viewport_c->y); 680 681 REG_SET_2(DCSURF_SEC_VIEWPORT_DIMENSION_C, 0, 682 SEC_VIEWPORT_WIDTH_C, viewport_c->width, 683 SEC_VIEWPORT_HEIGHT_C, viewport_c->height); 684 685 REG_SET_2(DCSURF_SEC_VIEWPORT_START_C, 0, 686 SEC_VIEWPORT_X_START_C, viewport_c->x, 687 SEC_VIEWPORT_Y_START_C, viewport_c->y); 688} 689 690void hubp401_program_mcache_id_and_split_coordinate( 691 struct hubp *hubp, 692 struct dml2_hubp_pipe_mcache_regs *mcache_regs) 693{ 694 struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); 695 696 REG_SET_8(DCHUBP_MCACHEID_CONFIG, 0, 697 MCACHEID_REG_READ_1H_P0, mcache_regs->main.p0.mcache_id_first, 698 MCACHEID_REG_READ_2H_P0, mcache_regs->main.p0.mcache_id_second, 699 MCACHEID_REG_READ_1H_P1, mcache_regs->main.p1.mcache_id_first, 700 MCACHEID_REG_READ_2H_P1, mcache_regs->main.p1.mcache_id_second, 701 MCACHEID_MALL_PREF_1H_P0, mcache_regs->mall.p0.mcache_id_first, 702 MCACHEID_MALL_PREF_2H_P0, mcache_regs->mall.p0.mcache_id_second, 703 MCACHEID_MALL_PREF_1H_P1, mcache_regs->mall.p1.mcache_id_first, 704 MCACHEID_MALL_PREF_2H_P1, mcache_regs->mall.p1.mcache_id_second); 705 706 REG_SET_2(DCSURF_VIEWPORT_MCACHE_SPLIT_COORDINATE, 0, 707 VIEWPORT_MCACHE_SPLIT_COORDINATE, mcache_regs->main.p0.split_location, 708 VIEWPORT_MCACHE_SPLIT_COORDINATE_C, mcache_regs->main.p1.split_location); 709} 710void hubp401_set_flip_int(struct hubp *hubp) 711{ 712 struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); 713 714 REG_UPDATE(DCSURF_SURFACE_FLIP_INTERRUPT, 715 SURFACE_FLIP_INT_MASK, 1); 716 717 return; 718} 719 720bool hubp401_in_blank(struct hubp *hubp) 721{ 722 struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); 723 uint32_t in_blank; 724 725 REG_GET(DCHUBP_CNTL, HUBP_IN_BLANK, &in_blank); 726 return in_blank ? true : false; 727} 728 729 730void hubp401_cursor_set_position( 731 struct hubp *hubp, 732 const struct dc_cursor_position *pos, 733 const struct dc_cursor_mi_param *param) 734{ 735 struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); 736 int rec_x_offset = pos->x - pos->x_hotspot; 737 int rec_y_offset = pos->y - pos->y_hotspot; 738 int dst_x_offset; 739 int x_pos_viewport = 0; 740 int x_hot_viewport = 0; 741 uint32_t cur_en = pos->enable ? 1 : 0; 742 743 hubp->curs_pos = *pos; 744 745 /* Recout is zero for pipes if the entire dst_rect is contained 746 * within preceeding ODM slices. 747 */ 748 if (param->recout.width) { 749 x_pos_viewport = pos->x * param->viewport.width / param->recout.width; 750 x_hot_viewport = pos->x_hotspot * param->viewport.width / param->recout.width; 751 } else { 752 ASSERT(!cur_en || pos->x == 0); 753 ASSERT(!cur_en || pos->x_hotspot == 0); 754 } 755 756 /* 757 * Guard aganst cursor_set_position() from being called with invalid 758 * attributes 759 */ 760 if (hubp->curs_attr.address.quad_part == 0) 761 return; 762 763 /* Translate the x position of the cursor from rect 764 * space into viewport space. CURSOR_DST_X_OFFSET 765 * is the offset relative to viewport start position. 766 */ 767 dst_x_offset = x_pos_viewport - x_hot_viewport * 768 (1 + hubp->curs_attr.attribute_flags.bits.ENABLE_MAGNIFICATION); 769 dst_x_offset = (dst_x_offset >= 0) ? dst_x_offset : 0; 770 dst_x_offset *= param->ref_clk_khz; 771 dst_x_offset /= param->pixel_clk_khz; 772 773 ASSERT(param->h_scale_ratio.value); 774 775 if (param->h_scale_ratio.value) 776 dst_x_offset = dc_fixpt_floor(dc_fixpt_div( 777 dc_fixpt_from_int(dst_x_offset), 778 param->h_scale_ratio)); 779 780 if (hubp->pos.cur_ctl.bits.cur_enable != cur_en) { 781 if (cur_en && REG_READ(CURSOR_SURFACE_ADDRESS) == 0) 782 hubp->funcs->set_cursor_attributes(hubp, &hubp->curs_attr); 783 784 if (!hubp->cursor_offload) 785 REG_UPDATE(CURSOR_CONTROL, 786 CURSOR_ENABLE, cur_en); 787 } 788 789 if (!hubp->cursor_offload) { 790 REG_SET_2(CURSOR_POSITION, 0, 791 CURSOR_X_POSITION, pos->x, 792 CURSOR_Y_POSITION, pos->y); 793 794 REG_SET_2(CURSOR_HOT_SPOT, 0, 795 CURSOR_HOT_SPOT_X, pos->x_hotspot, 796 CURSOR_HOT_SPOT_Y, pos->y_hotspot); 797 798 REG_SET(CURSOR_DST_OFFSET, 0, 799 CURSOR_DST_X_OFFSET, dst_x_offset); 800 } 801 /* Cursor Position Register Config */ 802 hubp->pos.cur_ctl.bits.cur_enable = cur_en; 803 hubp->pos.position.bits.x_pos = pos->x; 804 hubp->pos.position.bits.y_pos = pos->y; 805 hubp->pos.hot_spot.bits.x_hot = pos->x_hotspot; 806 hubp->pos.hot_spot.bits.y_hot = pos->y_hotspot; 807 hubp->pos.dst_offset.bits.dst_x_offset = dst_x_offset; 808 /* Cursor Rectangle Cache 809 * Cursor bitmaps have different hotspot values 810 * There's a possibility that the above logic returns a negative value, 811 * so we clamp them to 0 812 */ 813 if (rec_x_offset < 0) 814 rec_x_offset = 0; 815 if (rec_y_offset < 0) 816 rec_y_offset = 0; 817 /* Save necessary cursor info x, y position. w, h is saved in attribute func. */ 818 hubp->cur_rect.x = rec_x_offset + param->recout.x; 819 hubp->cur_rect.y = rec_y_offset + param->recout.y; 820} 821 822void hubp401_read_state(struct hubp *hubp) 823{ 824 struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); 825 struct dcn_hubp_state *s = &hubp2->state; 826 struct _vcs_dpi_display_dlg_regs_st *dlg_attr = &s->dlg_attr; 827 struct _vcs_dpi_display_ttu_regs_st *ttu_attr = &s->ttu_attr; 828 struct _vcs_dpi_display_rq_regs_st *rq_regs = &s->rq_regs; 829 830 /* Requester */ 831 REG_GET(HUBPRET_CONTROL, 832 DET_BUF_PLANE1_BASE_ADDRESS, &rq_regs->plane1_base_address); 833 REG_GET_4(DCN_EXPANSION_MODE, 834 DRQ_EXPANSION_MODE, &rq_regs->drq_expansion_mode, 835 PRQ_EXPANSION_MODE, &rq_regs->prq_expansion_mode, 836 MRQ_EXPANSION_MODE, &rq_regs->mrq_expansion_mode, 837 CRQ_EXPANSION_MODE, &rq_regs->crq_expansion_mode); 838 839 REG_GET_5(DCHUBP_REQ_SIZE_CONFIG, 840 CHUNK_SIZE, &rq_regs->rq_regs_l.chunk_size, 841 MIN_CHUNK_SIZE, &rq_regs->rq_regs_l.min_chunk_size, 842 DPTE_GROUP_SIZE, &rq_regs->rq_regs_l.dpte_group_size, 843 SWATH_HEIGHT, &rq_regs->rq_regs_l.swath_height, 844 PTE_ROW_HEIGHT_LINEAR, &rq_regs->rq_regs_l.pte_row_height_linear); 845 846 REG_GET_5(DCHUBP_REQ_SIZE_CONFIG_C, 847 CHUNK_SIZE_C, &rq_regs->rq_regs_c.chunk_size, 848 MIN_CHUNK_SIZE_C, &rq_regs->rq_regs_c.min_chunk_size, 849 DPTE_GROUP_SIZE_C, &rq_regs->rq_regs_c.dpte_group_size, 850 SWATH_HEIGHT_C, &rq_regs->rq_regs_c.swath_height, 851 PTE_ROW_HEIGHT_LINEAR_C, &rq_regs->rq_regs_c.pte_row_height_linear); 852 853 REG_GET(DCN_VM_SYSTEM_APERTURE_HIGH_ADDR, 854 MC_VM_SYSTEM_APERTURE_HIGH_ADDR, &rq_regs->aperture_high_addr); 855 856 REG_GET(DCN_VM_SYSTEM_APERTURE_LOW_ADDR, 857 MC_VM_SYSTEM_APERTURE_LOW_ADDR, &rq_regs->aperture_low_addr); 858 859 /* DLG - Per hubp */ 860 REG_GET_2(BLANK_OFFSET_0, 861 REFCYC_H_BLANK_END, &dlg_attr->refcyc_h_blank_end, 862 DLG_V_BLANK_END, &dlg_attr->dlg_vblank_end); 863 864 REG_GET(BLANK_OFFSET_1, 865 MIN_DST_Y_NEXT_START, &dlg_attr->min_dst_y_next_start); 866 867 REG_GET(DST_DIMENSIONS, 868 REFCYC_PER_HTOTAL, &dlg_attr->refcyc_per_htotal); 869 870 REG_GET_2(DST_AFTER_SCALER, 871 REFCYC_X_AFTER_SCALER, &dlg_attr->refcyc_x_after_scaler, 872 DST_Y_AFTER_SCALER, &dlg_attr->dst_y_after_scaler); 873 874 REG_GET_2(PREFETCH_SETTINGS, 875 DST_Y_PREFETCH, &dlg_attr->dst_y_prefetch, 876 VRATIO_PREFETCH, &dlg_attr->vratio_prefetch); 877 878 REG_GET_2(VBLANK_PARAMETERS_0, 879 DST_Y_PER_VM_VBLANK, &dlg_attr->dst_y_per_vm_vblank, 880 DST_Y_PER_ROW_VBLANK, &dlg_attr->dst_y_per_row_vblank); 881 882 REG_GET(REF_FREQ_TO_PIX_FREQ, 883 REF_FREQ_TO_PIX_FREQ, &dlg_attr->ref_freq_to_pix_freq); 884 885 /* DLG - Per luma/chroma */ 886 REG_GET(VBLANK_PARAMETERS_1, 887 REFCYC_PER_PTE_GROUP_VBLANK_L, &dlg_attr->refcyc_per_pte_group_vblank_l); 888 889 REG_GET(VBLANK_PARAMETERS_3, 890 REFCYC_PER_META_CHUNK_VBLANK_L, &dlg_attr->refcyc_per_meta_chunk_vblank_l); 891 892 REG_GET(NOM_PARAMETERS_0, 893 DST_Y_PER_PTE_ROW_NOM_L, &dlg_attr->dst_y_per_pte_row_nom_l); 894 895 REG_GET(NOM_PARAMETERS_1, 896 REFCYC_PER_PTE_GROUP_NOM_L, &dlg_attr->refcyc_per_pte_group_nom_l); 897 898 REG_GET(NOM_PARAMETERS_4, 899 DST_Y_PER_META_ROW_NOM_L, &dlg_attr->dst_y_per_meta_row_nom_l); 900 901 REG_GET(NOM_PARAMETERS_5, 902 REFCYC_PER_META_CHUNK_NOM_L, &dlg_attr->refcyc_per_meta_chunk_nom_l); 903 904 REG_GET_2(PER_LINE_DELIVERY_PRE, 905 REFCYC_PER_LINE_DELIVERY_PRE_L, &dlg_attr->refcyc_per_line_delivery_pre_l, 906 REFCYC_PER_LINE_DELIVERY_PRE_C, &dlg_attr->refcyc_per_line_delivery_pre_c); 907 908 REG_GET_2(PER_LINE_DELIVERY, 909 REFCYC_PER_LINE_DELIVERY_L, &dlg_attr->refcyc_per_line_delivery_l, 910 REFCYC_PER_LINE_DELIVERY_C, &dlg_attr->refcyc_per_line_delivery_c); 911 912 REG_GET(PREFETCH_SETTINGS_C, 913 VRATIO_PREFETCH_C, &dlg_attr->vratio_prefetch_c); 914 915 REG_GET(VBLANK_PARAMETERS_2, 916 REFCYC_PER_PTE_GROUP_VBLANK_C, &dlg_attr->refcyc_per_pte_group_vblank_c); 917 918 REG_GET(VBLANK_PARAMETERS_4, 919 REFCYC_PER_META_CHUNK_VBLANK_C, &dlg_attr->refcyc_per_meta_chunk_vblank_c); 920 921 REG_GET(NOM_PARAMETERS_2, 922 DST_Y_PER_PTE_ROW_NOM_C, &dlg_attr->dst_y_per_pte_row_nom_c); 923 924 REG_GET(NOM_PARAMETERS_3, 925 REFCYC_PER_PTE_GROUP_NOM_C, &dlg_attr->refcyc_per_pte_group_nom_c); 926 927 REG_GET(NOM_PARAMETERS_6, 928 DST_Y_PER_META_ROW_NOM_C, &dlg_attr->dst_y_per_meta_row_nom_c); 929 930 REG_GET(NOM_PARAMETERS_7, 931 REFCYC_PER_META_CHUNK_NOM_C, &dlg_attr->refcyc_per_meta_chunk_nom_c); 932 933 /* TTU - per hubp */ 934 REG_GET_2(DCN_TTU_QOS_WM, 935 QoS_LEVEL_LOW_WM, &ttu_attr->qos_level_low_wm, 936 QoS_LEVEL_HIGH_WM, &ttu_attr->qos_level_high_wm); 937 938 REG_GET_2(DCN_GLOBAL_TTU_CNTL, 939 MIN_TTU_VBLANK, &ttu_attr->min_ttu_vblank, 940 QoS_LEVEL_FLIP, &ttu_attr->qos_level_flip); 941 942 /* TTU - per luma/chroma */ 943 /* Assumed surf0 is luma and 1 is chroma */ 944 945 REG_GET_3(DCN_SURF0_TTU_CNTL0, 946 REFCYC_PER_REQ_DELIVERY, &ttu_attr->refcyc_per_req_delivery_l, 947 QoS_LEVEL_FIXED, &ttu_attr->qos_level_fixed_l, 948 QoS_RAMP_DISABLE, &ttu_attr->qos_ramp_disable_l); 949 950 REG_GET(DCN_SURF0_TTU_CNTL1, 951 REFCYC_PER_REQ_DELIVERY_PRE, 952 &ttu_attr->refcyc_per_req_delivery_pre_l); 953 954 REG_GET_3(DCN_SURF1_TTU_CNTL0, 955 REFCYC_PER_REQ_DELIVERY, &ttu_attr->refcyc_per_req_delivery_c, 956 QoS_LEVEL_FIXED, &ttu_attr->qos_level_fixed_c, 957 QoS_RAMP_DISABLE, &ttu_attr->qos_ramp_disable_c); 958 959 REG_GET(DCN_SURF1_TTU_CNTL1, 960 REFCYC_PER_REQ_DELIVERY_PRE, 961 &ttu_attr->refcyc_per_req_delivery_pre_c); 962 963 /* Rest of hubp */ 964 REG_GET(DCSURF_SURFACE_CONFIG, 965 SURFACE_PIXEL_FORMAT, &s->pixel_format); 966 967 REG_GET(DCSURF_SURFACE_EARLIEST_INUSE_HIGH, 968 SURFACE_EARLIEST_INUSE_ADDRESS_HIGH, &s->inuse_addr_hi); 969 970 REG_GET(DCSURF_SURFACE_EARLIEST_INUSE, 971 SURFACE_EARLIEST_INUSE_ADDRESS, &s->inuse_addr_lo); 972 973 REG_GET_2(DCSURF_PRI_VIEWPORT_DIMENSION, 974 PRI_VIEWPORT_WIDTH, &s->viewport_width, 975 PRI_VIEWPORT_HEIGHT, &s->viewport_height); 976 977 REG_GET_2(DCSURF_SURFACE_CONFIG, 978 ROTATION_ANGLE, &s->rotation_angle, 979 H_MIRROR_EN, &s->h_mirror_en); 980 981 REG_GET(DCSURF_TILING_CONFIG, 982 SW_MODE, &s->sw_mode); 983 984 REG_GET(DCSURF_SURFACE_CONTROL, 985 PRIMARY_SURFACE_DCC_EN, &s->dcc_en); 986 987 REG_GET_3(DCHUBP_CNTL, 988 HUBP_BLANK_EN, &s->blank_en, 989 HUBP_TTU_DISABLE, &s->ttu_disable, 990 HUBP_UNDERFLOW_STATUS, &s->underflow_status); 991 992 REG_GET(HUBP_CLK_CNTL, 993 HUBP_CLOCK_ENABLE, &s->clock_en); 994 995 REG_GET(DCN_GLOBAL_TTU_CNTL, 996 MIN_TTU_VBLANK, &s->min_ttu_vblank); 997 998 REG_GET_2(DCN_TTU_QOS_WM, 999 QoS_LEVEL_LOW_WM, &s->qos_level_low_wm, 1000 QoS_LEVEL_HIGH_WM, &s->qos_level_high_wm); 1001 1002 REG_GET(DCSURF_PRIMARY_SURFACE_ADDRESS, 1003 PRIMARY_SURFACE_ADDRESS, &s->primary_surface_addr_lo); 1004 1005 REG_GET(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH, 1006 PRIMARY_SURFACE_ADDRESS, &s->primary_surface_addr_hi); 1007 1008 s->uclk_pstate_force = REG_READ(UCLK_PSTATE_FORCE); 1009 1010 s->hubp_cntl = REG_READ(DCHUBP_CNTL); 1011 s->flip_control = REG_READ(DCSURF_FLIP_CONTROL); 1012} 1013 1014void hubp401_set_unbounded_requesting(struct hubp *hubp, bool enable) 1015{ 1016 struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); 1017 1018 REG_UPDATE(DCHUBP_CNTL, HUBP_UNBOUNDED_REQ_MODE, enable); 1019 1020 /* To ensure that cursor fetching starts as early as possible in 1021 * the display prefetch, set CURSOR_REQ_MODE = 1 always. 1022 * The setting of CURSOR_REQ_MODE = 0 is no longer supported in 1023 * DCN4x as a fall back to legacy behavior of fetching cursor 1024 * just before it appears on the screen. 1025 */ 1026 REG_UPDATE(CURSOR_CONTROL, CURSOR_REQ_MODE, 1); 1027} 1028 1029static struct hubp_funcs dcn401_hubp_funcs = { 1030 .hubp_enable_tripleBuffer = hubp2_enable_triplebuffer, 1031 .hubp_is_triplebuffer_enabled = hubp2_is_triplebuffer_enabled, 1032 .hubp_program_surface_flip_and_addr = hubp401_program_surface_flip_and_addr, 1033 .hubp_program_surface_config = hubp401_program_surface_config, 1034 .hubp_is_flip_pending = hubp2_is_flip_pending, 1035 .hubp_setup2 = hubp401_setup, 1036 .hubp_setup_interdependent2 = hubp401_setup_interdependent, 1037 .hubp_set_vm_system_aperture_settings = hubp3_set_vm_system_aperture_settings, 1038 .set_blank = hubp2_set_blank, 1039 .set_blank_regs = hubp2_set_blank_regs, 1040 .hubp_reset = hubp_reset, 1041 .mem_program_viewport = hubp401_set_viewport, 1042 .set_cursor_attributes = hubp32_cursor_set_attributes, 1043 .set_cursor_position = hubp401_cursor_set_position, 1044 .hubp_clk_cntl = hubp2_clk_cntl, 1045 .hubp_vtg_sel = hubp2_vtg_sel, 1046 .dmdata_set_attributes = hubp3_dmdata_set_attributes, 1047 .dmdata_load = hubp2_dmdata_load, 1048 .dmdata_status_done = hubp2_dmdata_status_done, 1049 .hubp_read_state = hubp401_read_state, 1050 .hubp_clear_underflow = hubp2_clear_underflow, 1051 .hubp_set_flip_control_surface_gsl = hubp2_set_flip_control_surface_gsl, 1052 .hubp_init = hubp401_init, 1053 .set_unbounded_requesting = hubp401_set_unbounded_requesting, 1054 .hubp_soft_reset = hubp31_soft_reset, 1055 .hubp_set_flip_int = hubp401_set_flip_int, 1056 .hubp_in_blank = hubp401_in_blank, 1057 .phantom_hubp_post_enable = hubp32_phantom_hubp_post_enable, 1058 .hubp_update_mall_sel = hubp401_update_mall_sel, 1059 .hubp_prepare_subvp_buffering = hubp32_prepare_subvp_buffering, 1060 .hubp_program_mcache_id_and_split_coordinate = hubp401_program_mcache_id_and_split_coordinate, 1061 .hubp_update_3dlut_fl_bias_scale = hubp401_update_3dlut_fl_bias_scale, 1062 .hubp_program_3dlut_fl_mode = hubp401_program_3dlut_fl_mode, 1063 .hubp_program_3dlut_fl_format = hubp401_program_3dlut_fl_format, 1064 .hubp_program_3dlut_fl_addr = hubp401_program_3dlut_fl_addr, 1065 .hubp_program_3dlut_fl_dlg_param = hubp401_program_3dlut_fl_dlg_param, 1066 .hubp_enable_3dlut_fl = hubp401_enable_3dlut_fl, 1067 .hubp_program_3dlut_fl_addressing_mode = hubp401_program_3dlut_fl_addressing_mode, 1068 .hubp_program_3dlut_fl_width = hubp401_program_3dlut_fl_width, 1069 .hubp_program_3dlut_fl_tmz_protected = hubp401_program_3dlut_fl_tmz_protected, 1070 .hubp_program_3dlut_fl_crossbar = hubp401_program_3dlut_fl_crossbar, 1071 .hubp_get_3dlut_fl_done = hubp401_get_3dlut_fl_done, 1072 .hubp_clear_tiling = hubp401_clear_tiling, 1073 .hubp_program_3dlut_fl_config = hubp401_program_3dlut_fl_config, 1074 .hubp_read_reg_state = hubp3_read_reg_state 1075}; 1076 1077bool hubp401_construct( 1078 struct dcn20_hubp *hubp2, 1079 struct dc_context *ctx, 1080 uint32_t inst, 1081 const struct dcn_hubp2_registers *hubp_regs, 1082 const struct dcn_hubp2_shift *hubp_shift, 1083 const struct dcn_hubp2_mask *hubp_mask) 1084{ 1085 hubp2->base.funcs = &dcn401_hubp_funcs; 1086 hubp2->base.ctx = ctx; 1087 hubp2->hubp_regs = hubp_regs; 1088 hubp2->hubp_shift = hubp_shift; 1089 hubp2->hubp_mask = hubp_mask; 1090 hubp2->base.inst = inst; 1091 hubp2->base.opp_id = OPP_ID_INVALID; 1092 hubp2->base.mpcc_id = 0xf; 1093 1094 return true; 1095}
~/
Read-only file preview.