613 lines · c
1/* SPDX-License-Identifier: MIT */2/*3 * Copyright 2023 Advanced Micro Devices, Inc.4 *5 * Permission is hereby granted, free of charge, to any person obtaining a6 * copy of this software and associated documentation files (the "Software"),7 * to deal in the Software without restriction, including without limitation8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,9 * and/or sell copies of the Software, and to permit persons to whom the10 * Software is furnished to do so, subject to the following conditions:11 *12 * The above copyright notice and this permission notice shall be included in13 * all copies or substantial portions of the Software.14 *15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL18 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR19 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,20 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR21 * OTHER DEALINGS IN THE SOFTWARE.22 *23 * Authors: AMD24 *25 */26 27 28#include "dcn30/dcn30_hubbub.h"29#include "dcn31/dcn31_hubbub.h"30#include "dcn32/dcn32_hubbub.h"31#include "dcn35_hubbub.h"32#include "dm_services.h"33#include "reg_helper.h"34 35 36#define CTX \37 hubbub2->base.ctx38#define DC_LOGGER \39 hubbub2->base.ctx->logger40#define REG(reg)\41 hubbub2->regs->reg42 43#undef FN44#define FN(reg_name, field_name) \45 hubbub2->shifts->field_name, hubbub2->masks->field_name46 47#define DCN35_CRB_SEGMENT_SIZE_KB 6448 49static void dcn35_init_crb(struct hubbub *hubbub)50{51 struct dcn20_hubbub *hubbub2 = TO_DCN20_HUBBUB(hubbub);52 53 REG_GET(DCHUBBUB_DET0_CTRL, DET0_SIZE_CURRENT,54 &hubbub2->det0_size);55 56 REG_GET(DCHUBBUB_DET1_CTRL, DET1_SIZE_CURRENT,57 &hubbub2->det1_size);58 59 REG_GET(DCHUBBUB_DET2_CTRL, DET2_SIZE_CURRENT,60 &hubbub2->det2_size);61 62 REG_GET(DCHUBBUB_DET3_CTRL, DET3_SIZE_CURRENT,63 &hubbub2->det3_size);64 65 REG_GET(DCHUBBUB_COMPBUF_CTRL, COMPBUF_SIZE_CURRENT,66 &hubbub2->compbuf_size_segments);67 68 REG_SET_2(COMPBUF_RESERVED_SPACE, 0,69 COMPBUF_RESERVED_SPACE_64B, hubbub2->pixel_chunk_size / 32,70 COMPBUF_RESERVED_SPACE_ZS, hubbub2->pixel_chunk_size / 128);71 REG_UPDATE(DCHUBBUB_DEBUG_CTRL_0, DET_DEPTH, 0x5FF);72}73 74static void dcn35_program_compbuf_size(struct hubbub *hubbub, unsigned int compbuf_size_kb, bool safe_to_increase)75{76 struct dcn20_hubbub *hubbub2 = TO_DCN20_HUBBUB(hubbub);77 unsigned int compbuf_size_segments = (compbuf_size_kb + DCN35_CRB_SEGMENT_SIZE_KB - 1) / DCN35_CRB_SEGMENT_SIZE_KB;78 79 if (safe_to_increase || compbuf_size_segments <= hubbub2->compbuf_size_segments) {80 if (compbuf_size_segments > hubbub2->compbuf_size_segments) {81 REG_WAIT(DCHUBBUB_DET0_CTRL, DET0_SIZE_CURRENT, hubbub2->det0_size, 1, 100);82 REG_WAIT(DCHUBBUB_DET1_CTRL, DET1_SIZE_CURRENT, hubbub2->det1_size, 1, 100);83 REG_WAIT(DCHUBBUB_DET2_CTRL, DET2_SIZE_CURRENT, hubbub2->det2_size, 1, 100);84 REG_WAIT(DCHUBBUB_DET3_CTRL, DET3_SIZE_CURRENT, hubbub2->det3_size, 1, 100);85 }86 /* Should never be hit, if it is we have an erroneous hw config*/87 ASSERT(hubbub2->det0_size + hubbub2->det1_size + hubbub2->det2_size88 + hubbub2->det3_size + compbuf_size_segments <= hubbub2->crb_size_segs);89 REG_UPDATE(DCHUBBUB_COMPBUF_CTRL, COMPBUF_SIZE, compbuf_size_segments);90 hubbub2->compbuf_size_segments = compbuf_size_segments;91 ASSERT(REG_GET(DCHUBBUB_COMPBUF_CTRL, CONFIG_ERROR, &compbuf_size_segments) && !compbuf_size_segments);92 }93}94 95static uint32_t convert_and_clamp(96 uint32_t wm_ns,97 uint32_t refclk_mhz,98 uint32_t clamp_value)99{100 uint32_t ret_val = 0;101 102 ret_val = wm_ns * refclk_mhz;103 104 ret_val /= 1000;105 106 if (ret_val > clamp_value)107 ret_val = clamp_value;108 109 return ret_val;110}111 112static bool hubbub35_program_stutter_z8_watermarks(113 struct hubbub *hubbub,114 union dcn_watermark_set *watermarks,115 unsigned int refclk_mhz,116 bool safe_to_lower)117{118 struct dcn20_hubbub *hubbub2 = TO_DCN20_HUBBUB(hubbub);119 uint32_t prog_wm_value;120 bool wm_pending = false;121 122 /* clock state A */123 if (watermarks->a.cstate_pstate.cstate_enter_plus_exit_z8_ns124 > hubbub2->watermarks.a.cstate_pstate.cstate_enter_plus_exit_z8_ns) {125 hubbub2->watermarks.a.cstate_pstate.cstate_enter_plus_exit_z8_ns =126 watermarks->a.cstate_pstate.cstate_enter_plus_exit_z8_ns;127 prog_wm_value = convert_and_clamp(128 watermarks->a.cstate_pstate.cstate_enter_plus_exit_z8_ns,129 refclk_mhz, 0xfffff);130 REG_SET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_A, 0,131 DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_A, prog_wm_value);132 DC_LOG_BANDWIDTH_CALCS("SR_ENTER_WATERMARK_Z8_A calculated =%d\n"133 "HW register value = 0x%x\n",134 watermarks->a.cstate_pstate.cstate_enter_plus_exit_z8_ns, prog_wm_value);135 } else if (watermarks->a.cstate_pstate.cstate_enter_plus_exit_z8_ns136 < hubbub2->watermarks.a.cstate_pstate.cstate_enter_plus_exit_z8_ns)137 wm_pending = true;138 139 if (safe_to_lower || watermarks->a.cstate_pstate.cstate_exit_z8_ns140 > hubbub2->watermarks.a.cstate_pstate.cstate_exit_z8_ns) {141 hubbub2->watermarks.a.cstate_pstate.cstate_exit_z8_ns =142 watermarks->a.cstate_pstate.cstate_exit_z8_ns;143 prog_wm_value = convert_and_clamp(144 watermarks->a.cstate_pstate.cstate_exit_z8_ns,145 refclk_mhz, 0xfffff);146 REG_SET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_A, 0,147 DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_A, prog_wm_value);148 DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_Z8_A calculated =%d\n"149 "HW register value = 0x%x\n",150 watermarks->a.cstate_pstate.cstate_exit_z8_ns, prog_wm_value);151 } else if (watermarks->a.cstate_pstate.cstate_exit_z8_ns152 < hubbub2->watermarks.a.cstate_pstate.cstate_exit_z8_ns)153 wm_pending = true;154 155 /* clock state B */156 157 if (safe_to_lower || watermarks->b.cstate_pstate.cstate_enter_plus_exit_z8_ns158 > hubbub2->watermarks.b.cstate_pstate.cstate_enter_plus_exit_z8_ns) {159 hubbub2->watermarks.b.cstate_pstate.cstate_enter_plus_exit_z8_ns =160 watermarks->b.cstate_pstate.cstate_enter_plus_exit_z8_ns;161 prog_wm_value = convert_and_clamp(162 watermarks->b.cstate_pstate.cstate_enter_plus_exit_z8_ns,163 refclk_mhz, 0xfffff);164 REG_SET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_B, 0,165 DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_B, prog_wm_value);166 DC_LOG_BANDWIDTH_CALCS("SR_ENTER_WATERMARK_Z8_B calculated =%d\n"167 "HW register value = 0x%x\n",168 watermarks->b.cstate_pstate.cstate_enter_plus_exit_z8_ns, prog_wm_value);169 } else if (watermarks->b.cstate_pstate.cstate_enter_plus_exit_z8_ns170 < hubbub2->watermarks.b.cstate_pstate.cstate_enter_plus_exit_z8_ns)171 wm_pending = true;172 173 if (safe_to_lower || watermarks->b.cstate_pstate.cstate_exit_z8_ns174 > hubbub2->watermarks.b.cstate_pstate.cstate_exit_z8_ns) {175 hubbub2->watermarks.b.cstate_pstate.cstate_exit_z8_ns =176 watermarks->b.cstate_pstate.cstate_exit_z8_ns;177 prog_wm_value = convert_and_clamp(178 watermarks->b.cstate_pstate.cstate_exit_z8_ns,179 refclk_mhz, 0xfffff);180 REG_SET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_B, 0,181 DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_B, prog_wm_value);182 DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_Z8_B calculated =%d\n"183 "HW register value = 0x%x\n",184 watermarks->b.cstate_pstate.cstate_exit_z8_ns, prog_wm_value);185 } else if (watermarks->b.cstate_pstate.cstate_exit_z8_ns186 < hubbub2->watermarks.b.cstate_pstate.cstate_exit_z8_ns)187 wm_pending = true;188 189 /* clock state C */190 if (safe_to_lower || watermarks->c.cstate_pstate.cstate_enter_plus_exit_z8_ns191 > hubbub2->watermarks.c.cstate_pstate.cstate_enter_plus_exit_z8_ns) {192 hubbub2->watermarks.c.cstate_pstate.cstate_enter_plus_exit_z8_ns =193 watermarks->c.cstate_pstate.cstate_enter_plus_exit_z8_ns;194 prog_wm_value = convert_and_clamp(195 watermarks->c.cstate_pstate.cstate_enter_plus_exit_z8_ns,196 refclk_mhz, 0xfffff);197 REG_SET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_C, 0,198 DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_C, prog_wm_value);199 DC_LOG_BANDWIDTH_CALCS("SR_ENTER_WATERMARK_Z8_C calculated =%d\n"200 "HW register value = 0x%x\n",201 watermarks->c.cstate_pstate.cstate_enter_plus_exit_z8_ns, prog_wm_value);202 } else if (watermarks->c.cstate_pstate.cstate_enter_plus_exit_z8_ns203 < hubbub2->watermarks.c.cstate_pstate.cstate_enter_plus_exit_z8_ns)204 wm_pending = true;205 206 if (safe_to_lower || watermarks->c.cstate_pstate.cstate_exit_z8_ns207 > hubbub2->watermarks.c.cstate_pstate.cstate_exit_z8_ns) {208 hubbub2->watermarks.c.cstate_pstate.cstate_exit_z8_ns =209 watermarks->c.cstate_pstate.cstate_exit_z8_ns;210 prog_wm_value = convert_and_clamp(211 watermarks->c.cstate_pstate.cstate_exit_z8_ns,212 refclk_mhz, 0xfffff);213 REG_SET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_C, 0,214 DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_C, prog_wm_value);215 DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_Z8_C calculated =%d\n"216 "HW register value = 0x%x\n",217 watermarks->c.cstate_pstate.cstate_exit_z8_ns, prog_wm_value);218 } else if (watermarks->c.cstate_pstate.cstate_exit_z8_ns219 < hubbub2->watermarks.c.cstate_pstate.cstate_exit_z8_ns)220 wm_pending = true;221 222 /* clock state D */223 if (safe_to_lower || watermarks->d.cstate_pstate.cstate_enter_plus_exit_z8_ns224 > hubbub2->watermarks.d.cstate_pstate.cstate_enter_plus_exit_z8_ns) {225 hubbub2->watermarks.d.cstate_pstate.cstate_enter_plus_exit_z8_ns =226 watermarks->d.cstate_pstate.cstate_enter_plus_exit_z8_ns;227 prog_wm_value = convert_and_clamp(228 watermarks->d.cstate_pstate.cstate_enter_plus_exit_z8_ns,229 refclk_mhz, 0xfffff);230 REG_SET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_D, 0,231 DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_D, prog_wm_value);232 DC_LOG_BANDWIDTH_CALCS("SR_ENTER_WATERMARK_Z8_D calculated =%d\n"233 "HW register value = 0x%x\n",234 watermarks->d.cstate_pstate.cstate_enter_plus_exit_z8_ns, prog_wm_value);235 } else if (watermarks->d.cstate_pstate.cstate_enter_plus_exit_z8_ns236 < hubbub2->watermarks.d.cstate_pstate.cstate_enter_plus_exit_z8_ns)237 wm_pending = true;238 239 if (safe_to_lower || watermarks->d.cstate_pstate.cstate_exit_z8_ns240 > hubbub2->watermarks.d.cstate_pstate.cstate_exit_z8_ns) {241 hubbub2->watermarks.d.cstate_pstate.cstate_exit_z8_ns =242 watermarks->d.cstate_pstate.cstate_exit_z8_ns;243 prog_wm_value = convert_and_clamp(244 watermarks->d.cstate_pstate.cstate_exit_z8_ns,245 refclk_mhz, 0xfffff);246 REG_SET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_D, 0,247 DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_D, prog_wm_value);248 DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_Z8_D calculated =%d\n"249 "HW register value = 0x%x\n",250 watermarks->d.cstate_pstate.cstate_exit_z8_ns, prog_wm_value);251 } else if (watermarks->d.cstate_pstate.cstate_exit_z8_ns252 < hubbub2->watermarks.d.cstate_pstate.cstate_exit_z8_ns)253 wm_pending = true;254 255 return wm_pending;256}257 258static void hubbub35_get_dchub_ref_freq(struct hubbub *hubbub,259 unsigned int dccg_ref_freq_inKhz,260 unsigned int *dchub_ref_freq_inKhz)261{262 struct dcn20_hubbub *hubbub2 = TO_DCN20_HUBBUB(hubbub);263 uint32_t ref_div = 0;264 uint32_t ref_en = 0;265 unsigned int dc_refclk_khz = 24000;266 267 REG_GET_2(DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_REFDIV, &ref_div,268 DCHUBBUB_GLOBAL_TIMER_ENABLE, &ref_en);269 270 if (ref_en) {271 if (ref_div == 2)272 *dchub_ref_freq_inKhz = dc_refclk_khz / 2;273 else274 *dchub_ref_freq_inKhz = dc_refclk_khz;275 276 /*277 * The external Reference Clock may change based on the board or278 * platform requirements and the programmable integer divide must279 * be programmed to provide a suitable DLG RefClk frequency between280 * a minimum of 20MHz and maximum of 50MHz281 */282 if (*dchub_ref_freq_inKhz < 20000 || *dchub_ref_freq_inKhz > 50000)283 ASSERT_CRITICAL(false);284 285 return;286 } else {287 *dchub_ref_freq_inKhz = dc_refclk_khz;288 /*init sequence issue on bringup patch*/289 REG_UPDATE_2(DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_REFDIV, 1,290 DCHUBBUB_GLOBAL_TIMER_ENABLE, 1);291 // HUBBUB global timer must be enabled.292 ASSERT_CRITICAL(false);293 return;294 }295}296 297 298static bool hubbub35_program_watermarks(299 struct hubbub *hubbub,300 union dcn_watermark_set *watermarks,301 unsigned int refclk_mhz,302 bool safe_to_lower)303{304 bool wm_pending = false;305 struct dcn20_hubbub *hubbub2 = TO_DCN20_HUBBUB(hubbub);306 307 if (hubbub32_program_urgent_watermarks(hubbub, watermarks, refclk_mhz, safe_to_lower))308 wm_pending = true;309 310 if (hubbub32_program_stutter_watermarks(hubbub, watermarks, refclk_mhz, safe_to_lower))311 wm_pending = true;312 313 if (hubbub32_program_pstate_watermarks(hubbub, watermarks, refclk_mhz, safe_to_lower))314 wm_pending = true;315 316 if (hubbub32_program_usr_watermarks(hubbub, watermarks, refclk_mhz, safe_to_lower))317 wm_pending = true;318 319 if (hubbub35_program_stutter_z8_watermarks(hubbub, watermarks, refclk_mhz, safe_to_lower))320 wm_pending = true;321 322 REG_SET(DCHUBBUB_ARB_SAT_LEVEL, 0,323 DCHUBBUB_ARB_SAT_LEVEL, 60 * refclk_mhz);324 REG_UPDATE_2(DCHUBBUB_ARB_DF_REQ_OUTSTAND,325 DCHUBBUB_ARB_MIN_REQ_OUTSTAND, 0xFF,326 DCHUBBUB_ARB_MIN_REQ_OUTSTAND_COMMIT_THRESHOLD, 0xA);/*hw delta*/327 REG_UPDATE(DCHUBBUB_ARB_HOSTVM_CNTL, DCHUBBUB_ARB_MAX_QOS_COMMIT_THRESHOLD, 0xF);328 329 hubbub1_allow_self_refresh_control(hubbub, !hubbub->ctx->dc->debug.disable_stutter);330 331 hubbub32_force_usr_retraining_allow(hubbub, hubbub->ctx->dc->debug.force_usr_allow);332 333 return wm_pending;334}335 336/* Copy values from WM set A to all other sets */337static void hubbub35_init_watermarks(struct hubbub *hubbub)338{339 struct dcn20_hubbub *hubbub2 = TO_DCN20_HUBBUB(hubbub);340 uint32_t reg;341 342 reg = REG_READ(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A);343 REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, reg);344 REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, reg);345 REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, reg);346 347 reg = REG_READ(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_A);348 REG_WRITE(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_B, reg);349 REG_WRITE(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_C, reg);350 REG_WRITE(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_D, reg);351 352 reg = REG_READ(DCHUBBUB_ARB_FRAC_URG_BW_NOM_A);353 REG_WRITE(DCHUBBUB_ARB_FRAC_URG_BW_NOM_B, reg);354 REG_WRITE(DCHUBBUB_ARB_FRAC_URG_BW_NOM_C, reg);355 REG_WRITE(DCHUBBUB_ARB_FRAC_URG_BW_NOM_D, reg);356 357 reg = REG_READ(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_A);358 REG_WRITE(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_B, reg);359 REG_WRITE(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_C, reg);360 REG_WRITE(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_D, reg);361 362 reg = REG_READ(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A);363 REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, reg);364 REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, reg);365 REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, reg);366 367 reg = REG_READ(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A);368 REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, reg);369 REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C, reg);370 REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D, reg);371 372 reg = REG_READ(DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_A);373 REG_WRITE(DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_B, reg);374 REG_WRITE(DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_C, reg);375 REG_WRITE(DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_D, reg);376 377 reg = REG_READ(DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_A);378 REG_WRITE(DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_B, reg);379 REG_WRITE(DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_C, reg);380 REG_WRITE(DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_D, reg);381 382 reg = REG_READ(DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_A);383 REG_WRITE(DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_B, reg);384 REG_WRITE(DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_C, reg);385 REG_WRITE(DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_D, reg);386 387 reg = REG_READ(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_A);388 REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_B, reg);389 REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_C, reg);390 REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_D, reg);391 392 reg = REG_READ(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_A);393 REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_B, reg);394 REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_C, reg);395 REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_D, reg);396 397}398 399static void hubbub35_wm_read_state(struct hubbub *hubbub,400 struct dcn_hubbub_wm *wm)401{402 struct dcn20_hubbub *hubbub2 = TO_DCN20_HUBBUB(hubbub);403 struct dcn_hubbub_wm_set *s;404 405 memset(wm, 0, sizeof(struct dcn_hubbub_wm));406 407 s = &wm->sets[0];408 s->wm_set = 0;409 REG_GET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A,410 DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, &s->data_urgent);411 412 REG_GET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A,413 DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A, &s->sr_enter);414 415 REG_GET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A,416 DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A, &s->sr_exit);417 418 REG_GET(DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_A,419 DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_A, &s->dram_clk_change);420 421 REG_GET(DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_A,422 DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_A, &s->usr_retrain);423 424 REG_GET(DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_A,425 DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_A, &s->fclk_pstate_change);426 427 REG_GET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_A,428 DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_A, &s->sr_enter_exit_Z8);429 430 REG_GET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_A,431 DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_A, &s->sr_enter_Z8);432 s = &wm->sets[1];433 s->wm_set = 1;434 REG_GET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B,435 DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, &s->data_urgent);436 437 REG_GET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B,438 DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, &s->sr_enter);439 440 REG_GET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B,441 DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, &s->sr_exit);442 443 REG_GET(DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_B,444 DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_B, &s->dram_clk_change);445 446 REG_GET(DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_B,447 DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_B, &s->usr_retrain);448 449 REG_GET(DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_B,450 DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_B, &s->fclk_pstate_change);451 452 REG_GET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_B,453 DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_B, &s->sr_enter_exit_Z8);454 455 REG_GET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_B,456 DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_B, &s->sr_enter_Z8);457 458 s = &wm->sets[2];459 s->wm_set = 2;460 REG_GET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C,461 DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, &s->data_urgent);462 463 REG_GET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C,464 DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, &s->sr_enter);465 466 REG_GET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C,467 DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C, &s->sr_exit);468 469 REG_GET(DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_C,470 DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_C, &s->dram_clk_change);471 472 REG_GET(DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_C,473 DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_C, &s->usr_retrain);474 475 REG_GET(DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_C,476 DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_C, &s->fclk_pstate_change);477 478 REG_GET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_C,479 DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_C, &s->sr_enter_exit_Z8);480 481 REG_GET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_C,482 DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_C, &s->sr_enter_Z8);483 484 s = &wm->sets[3];485 s->wm_set = 3;486 REG_GET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D,487 DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, &s->data_urgent);488 489 REG_GET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D,490 DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, &s->sr_enter);491 492 REG_GET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D,493 DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D, &s->sr_exit);494 495 REG_GET(DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_D,496 DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_D, &s->dram_clk_change);497 498 REG_GET(DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_D,499 DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_D, &s->usr_retrain);500 501 REG_GET(DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_D,502 DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_D, &s->fclk_pstate_change);503 504 REG_GET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_D,505 DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_D, &s->sr_enter_exit_Z8);506 507 REG_GET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_D,508 DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_D, &s->sr_enter_Z8);509}510 511static void hubbub35_set_fgcg(struct dcn20_hubbub *hubbub2, bool enable)512{513 REG_UPDATE(DCHUBBUB_CLOCK_CNTL, DCHUBBUB_FGCG_REP_DIS, !enable);514}515 516static void hubbub35_init(struct hubbub *hubbub)517{518 struct dcn20_hubbub *hubbub2 = TO_DCN20_HUBBUB(hubbub);519 /*Enable clock gaters*/520 if (hubbub->ctx->dc->debug.disable_clock_gate) {521 /*done in hwseq*/522 /*REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0);*/523 524 REG_UPDATE_2(DCHUBBUB_CLOCK_CNTL,525 DISPCLK_R_DCHUBBUB_GATE_DIS, 1,526 DCFCLK_R_DCHUBBUB_GATE_DIS, 1);527 }528 hubbub35_set_fgcg(hubbub2,529 hubbub->ctx->dc->debug.enable_fine_grain_clock_gating530 .bits.dchubbub);531 /*532 ignore the "df_pre_cstate_req" from the SDP port control.533 only the DCN will determine when to connect the SDP port534 */535 REG_UPDATE(DCHUBBUB_SDPIF_CFG0,536 SDPIF_PORT_CONTROL, 1);537 /*Set SDP's max outstanding request538 When set to 1: Max outstanding is 512539 When set to 0: Max outstanding is 256540 must set the register back to 0 (max outstanding = 256) in zero frame buffer mode*/541 REG_UPDATE(DCHUBBUB_SDPIF_CFG1,542 SDPIF_MAX_NUM_OUTSTANDING, 0);543 544 REG_UPDATE_2(DCHUBBUB_ARB_DF_REQ_OUTSTAND,545 DCHUBBUB_ARB_MAX_REQ_OUTSTAND, 256,546 DCHUBBUB_ARB_MIN_REQ_OUTSTAND, 256);547 548 memset(&hubbub2->watermarks.a.cstate_pstate, 0, sizeof(hubbub2->watermarks.a.cstate_pstate));549}550 551/*static void hubbub35_set_request_limit(struct hubbub *hubbub,552 int memory_channel_count,553 int words_per_channel)554{555 struct dcn20_hubbub *hubbub2 = TO_DCN20_HUBBUB(hubbub);556 557 uint32_t request_limit = 3 * memory_channel_count * words_per_channel / 4;558 559 ASSERT((request_limit & (~0xFFF)) == 0); //field is only 24 bits long560 ASSERT(request_limit > 0); //field is only 24 bits long561 562 if (request_limit > 0xFFF)563 request_limit = 0xFFF;564 565 if (request_limit > 0)566 REG_UPDATE(SDPIF_REQUEST_RATE_LIMIT, SDPIF_REQUEST_RATE_LIMIT, request_limit);567}*/568 569static const struct hubbub_funcs hubbub35_funcs = {570 .update_dchub = hubbub2_update_dchub,571 .init_dchub_sys_ctx = hubbub31_init_dchub_sys_ctx,572 .init_vm_ctx = hubbub2_init_vm_ctx,573 .dcc_support_swizzle = hubbub3_dcc_support_swizzle,574 .dcc_support_pixel_format = hubbub2_dcc_support_pixel_format,575 .get_dcc_compression_cap = hubbub3_get_dcc_compression_cap,576 .wm_read_state = hubbub35_wm_read_state,577 .get_dchub_ref_freq = hubbub35_get_dchub_ref_freq,578 .program_watermarks = hubbub35_program_watermarks,579 .allow_self_refresh_control = hubbub1_allow_self_refresh_control,580 .is_allow_self_refresh_enabled = hubbub1_is_allow_self_refresh_enabled,581 .verify_allow_pstate_change_high = hubbub1_verify_allow_pstate_change_high,582 .force_wm_propagate_to_pipes = hubbub32_force_wm_propagate_to_pipes,583 .force_pstate_change_control = hubbub3_force_pstate_change_control,584 .init_watermarks = hubbub35_init_watermarks,585 .program_det_size = dcn32_program_det_size,586 .program_compbuf_size = dcn35_program_compbuf_size,587 .init_crb = dcn35_init_crb,588 .hubbub_read_state = hubbub2_read_state,589 .force_usr_retraining_allow = hubbub32_force_usr_retraining_allow,590 .dchubbub_init = hubbub35_init,591};592 593void hubbub35_construct(struct dcn20_hubbub *hubbub2,594 struct dc_context *ctx,595 const struct dcn_hubbub_registers *hubbub_regs,596 const struct dcn_hubbub_shift *hubbub_shift,597 const struct dcn_hubbub_mask *hubbub_mask,598 int det_size_kb,599 int pixel_chunk_size_kb,600 int config_return_buffer_size_kb)601{602 hubbub2->base.ctx = ctx;603 hubbub2->base.funcs = &hubbub35_funcs;604 hubbub2->regs = hubbub_regs;605 hubbub2->shifts = hubbub_shift;606 hubbub2->masks = hubbub_mask;607 608 hubbub2->debug_test_index_pstate = 0xB;609 hubbub2->detile_buf_size = det_size_kb * 1024;610 hubbub2->pixel_chunk_size = pixel_chunk_size_kb * 1024;611 hubbub2->crb_size_segs = config_return_buffer_size_kb / DCN35_CRB_SEGMENT_SIZE_KB; /*todo*/612}613