162d591a8SYue Hin Lau /* 262d591a8SYue Hin Lau * Copyright 2016 Advanced Micro Devices, Inc. 362d591a8SYue Hin Lau * 462d591a8SYue Hin Lau * Permission is hereby granted, free of charge, to any person obtaining a 562d591a8SYue Hin Lau * copy of this software and associated documentation files (the "Software"), 662d591a8SYue Hin Lau * to deal in the Software without restriction, including without limitation 762d591a8SYue Hin Lau * the rights to use, copy, modify, merge, publish, distribute, sublicense, 862d591a8SYue Hin Lau * and/or sell copies of the Software, and to permit persons to whom the 962d591a8SYue Hin Lau * Software is furnished to do so, subject to the following conditions: 1062d591a8SYue Hin Lau * 1162d591a8SYue Hin Lau * The above copyright notice and this permission notice shall be included in 1262d591a8SYue Hin Lau * all copies or substantial portions of the Software. 1362d591a8SYue Hin Lau * 1462d591a8SYue Hin Lau * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1562d591a8SYue Hin Lau * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1662d591a8SYue Hin Lau * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 1762d591a8SYue Hin Lau * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 1862d591a8SYue Hin Lau * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 1962d591a8SYue Hin Lau * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 2062d591a8SYue Hin Lau * OTHER DEALINGS IN THE SOFTWARE. 2162d591a8SYue Hin Lau * 2262d591a8SYue Hin Lau * Authors: AMD 2362d591a8SYue Hin Lau * 2462d591a8SYue Hin Lau */ 2562d591a8SYue Hin Lau 2662d591a8SYue Hin Lau #include "dm_services.h" 2762d591a8SYue Hin Lau #include "dcn10_hubp.h" 2862d591a8SYue Hin Lau #include "dcn10_hubbub.h" 2962d591a8SYue Hin Lau #include "reg_helper.h" 3062d591a8SYue Hin Lau 3162d591a8SYue Hin Lau #define CTX \ 32c9ef081dSYue Hin Lau hubbub->ctx 3362d591a8SYue Hin Lau #define REG(reg)\ 34c9ef081dSYue Hin Lau hubbub->regs->reg 3562d591a8SYue Hin Lau 3662d591a8SYue Hin Lau #undef FN 3762d591a8SYue Hin Lau #define FN(reg_name, field_name) \ 38c9ef081dSYue Hin Lau hubbub->shifts->field_name, hubbub->masks->field_name 3962d591a8SYue Hin Lau 40c9ef081dSYue Hin Lau void hubbub1_wm_read_state(struct hubbub *hubbub, 4162d591a8SYue Hin Lau struct dcn_hubbub_wm *wm) 4262d591a8SYue Hin Lau { 4362d591a8SYue Hin Lau struct dcn_hubbub_wm_set *s; 4462d591a8SYue Hin Lau 4562d591a8SYue Hin Lau s = &wm->sets[0]; 4662d591a8SYue Hin Lau s->wm_set = 0; 4762d591a8SYue Hin Lau s->data_urgent = REG_READ(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A); 4862d591a8SYue Hin Lau s->pte_meta_urgent = REG_READ(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_A); 4962d591a8SYue Hin Lau s->sr_enter = REG_READ(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A); 5062d591a8SYue Hin Lau s->sr_exit = REG_READ(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A); 5162d591a8SYue Hin Lau s->dram_clk_chanage = REG_READ(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A); 5262d591a8SYue Hin Lau 5362d591a8SYue Hin Lau s = &wm->sets[1]; 5462d591a8SYue Hin Lau s->wm_set = 1; 5562d591a8SYue Hin Lau s->data_urgent = REG_READ(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B); 5662d591a8SYue Hin Lau s->pte_meta_urgent = REG_READ(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_B); 5762d591a8SYue Hin Lau s->sr_enter = REG_READ(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B); 5862d591a8SYue Hin Lau s->sr_exit = REG_READ(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B); 5962d591a8SYue Hin Lau s->dram_clk_chanage = REG_READ(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B); 6062d591a8SYue Hin Lau 6162d591a8SYue Hin Lau s = &wm->sets[2]; 6262d591a8SYue Hin Lau s->wm_set = 2; 6362d591a8SYue Hin Lau s->data_urgent = REG_READ(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C); 6462d591a8SYue Hin Lau s->pte_meta_urgent = REG_READ(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_C); 6562d591a8SYue Hin Lau s->sr_enter = REG_READ(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C); 6662d591a8SYue Hin Lau s->sr_exit = REG_READ(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C); 6762d591a8SYue Hin Lau s->dram_clk_chanage = REG_READ(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C); 6862d591a8SYue Hin Lau 6962d591a8SYue Hin Lau s = &wm->sets[3]; 7062d591a8SYue Hin Lau s->wm_set = 3; 7162d591a8SYue Hin Lau s->data_urgent = REG_READ(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D); 7262d591a8SYue Hin Lau s->pte_meta_urgent = REG_READ(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_D); 7362d591a8SYue Hin Lau s->sr_enter = REG_READ(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D); 7462d591a8SYue Hin Lau s->sr_exit = REG_READ(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D); 7562d591a8SYue Hin Lau s->dram_clk_chanage = REG_READ(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D); 7662d591a8SYue Hin Lau } 7762d591a8SYue Hin Lau 78ea00f297SYue Hin Lau bool hubbub1_verify_allow_pstate_change_high( 79c9ef081dSYue Hin Lau struct hubbub *hubbub) 8062d591a8SYue Hin Lau { 8162d591a8SYue Hin Lau /* pstate latency is ~20us so if we wait over 40us and pstate allow 8262d591a8SYue Hin Lau * still not asserted, we are probably stuck and going to hang 8362d591a8SYue Hin Lau * 8462d591a8SYue Hin Lau * TODO: Figure out why it takes ~100us on linux 8562d591a8SYue Hin Lau * pstate takes around ~100us on linux. Unknown currently as to 8662d591a8SYue Hin Lau * why it takes that long on linux 8762d591a8SYue Hin Lau */ 8862d591a8SYue Hin Lau static unsigned int pstate_wait_timeout_us = 200; 8962d591a8SYue Hin Lau static unsigned int pstate_wait_expected_timeout_us = 40; 9062d591a8SYue Hin Lau static unsigned int max_sampled_pstate_wait_us; /* data collection */ 9162d591a8SYue Hin Lau static bool forced_pstate_allow; /* help with revert wa */ 9262d591a8SYue Hin Lau 9362d591a8SYue Hin Lau unsigned int debug_index = 0x7; 9462d591a8SYue Hin Lau unsigned int debug_data; 9562d591a8SYue Hin Lau unsigned int i; 9662d591a8SYue Hin Lau 9762d591a8SYue Hin Lau if (forced_pstate_allow) { 9862d591a8SYue Hin Lau /* we hacked to force pstate allow to prevent hang last time 9962d591a8SYue Hin Lau * we verify_allow_pstate_change_high. so disable force 10062d591a8SYue Hin Lau * here so we can check status 10162d591a8SYue Hin Lau */ 10262d591a8SYue Hin Lau REG_UPDATE_2(DCHUBBUB_ARB_DRAM_STATE_CNTL, 10362d591a8SYue Hin Lau DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_VALUE, 0, 10462d591a8SYue Hin Lau DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_ENABLE, 0); 10562d591a8SYue Hin Lau forced_pstate_allow = false; 10662d591a8SYue Hin Lau } 10762d591a8SYue Hin Lau 10862d591a8SYue Hin Lau /* description "3-0: Pipe0 cursor0 QOS 10962d591a8SYue Hin Lau * 7-4: Pipe1 cursor0 QOS 11062d591a8SYue Hin Lau * 11-8: Pipe2 cursor0 QOS 11162d591a8SYue Hin Lau * 15-12: Pipe3 cursor0 QOS 11262d591a8SYue Hin Lau * 16: Pipe0 Plane0 Allow Pstate Change 11362d591a8SYue Hin Lau * 17: Pipe1 Plane0 Allow Pstate Change 11462d591a8SYue Hin Lau * 18: Pipe2 Plane0 Allow Pstate Change 11562d591a8SYue Hin Lau * 19: Pipe3 Plane0 Allow Pstate Change 11662d591a8SYue Hin Lau * 20: Pipe0 Plane1 Allow Pstate Change 11762d591a8SYue Hin Lau * 21: Pipe1 Plane1 Allow Pstate Change 11862d591a8SYue Hin Lau * 22: Pipe2 Plane1 Allow Pstate Change 11962d591a8SYue Hin Lau * 23: Pipe3 Plane1 Allow Pstate Change 12062d591a8SYue Hin Lau * 24: Pipe0 cursor0 Allow Pstate Change 12162d591a8SYue Hin Lau * 25: Pipe1 cursor0 Allow Pstate Change 12262d591a8SYue Hin Lau * 26: Pipe2 cursor0 Allow Pstate Change 12362d591a8SYue Hin Lau * 27: Pipe3 cursor0 Allow Pstate Change 12462d591a8SYue Hin Lau * 28: WB0 Allow Pstate Change 12562d591a8SYue Hin Lau * 29: WB1 Allow Pstate Change 12662d591a8SYue Hin Lau * 30: Arbiter's allow_pstate_change 12762d591a8SYue Hin Lau * 31: SOC pstate change request 12862d591a8SYue Hin Lau */ 12962d591a8SYue Hin Lau 13062d591a8SYue Hin Lau REG_WRITE(DCHUBBUB_TEST_DEBUG_INDEX, debug_index); 13162d591a8SYue Hin Lau 13262d591a8SYue Hin Lau for (i = 0; i < pstate_wait_timeout_us; i++) { 13362d591a8SYue Hin Lau debug_data = REG_READ(DCHUBBUB_TEST_DEBUG_DATA); 13462d591a8SYue Hin Lau 13562d591a8SYue Hin Lau if (debug_data & (1 << 30)) { 13662d591a8SYue Hin Lau 13762d591a8SYue Hin Lau if (i > pstate_wait_expected_timeout_us) 138c9ef081dSYue Hin Lau dm_logger_write(hubbub->ctx->logger, LOG_WARNING, 13962d591a8SYue Hin Lau "pstate took longer than expected ~%dus\n", 14062d591a8SYue Hin Lau i); 14162d591a8SYue Hin Lau 142ea00f297SYue Hin Lau return false; 14362d591a8SYue Hin Lau } 14462d591a8SYue Hin Lau if (max_sampled_pstate_wait_us < i) 14562d591a8SYue Hin Lau max_sampled_pstate_wait_us = i; 14662d591a8SYue Hin Lau 14762d591a8SYue Hin Lau udelay(1); 14862d591a8SYue Hin Lau } 14962d591a8SYue Hin Lau 15062d591a8SYue Hin Lau /* force pstate allow to prevent system hang 15162d591a8SYue Hin Lau * and break to debugger to investigate 15262d591a8SYue Hin Lau */ 15362d591a8SYue Hin Lau REG_UPDATE_2(DCHUBBUB_ARB_DRAM_STATE_CNTL, 15462d591a8SYue Hin Lau DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_VALUE, 1, 15562d591a8SYue Hin Lau DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_ENABLE, 1); 15662d591a8SYue Hin Lau forced_pstate_allow = true; 15762d591a8SYue Hin Lau 158c9ef081dSYue Hin Lau dm_logger_write(hubbub->ctx->logger, LOG_WARNING, 15962d591a8SYue Hin Lau "pstate TEST_DEBUG_DATA: 0x%X\n", 16062d591a8SYue Hin Lau debug_data); 161ea00f297SYue Hin Lau 162ea00f297SYue Hin Lau return true; 16362d591a8SYue Hin Lau } 16462d591a8SYue Hin Lau 16562d591a8SYue Hin Lau static uint32_t convert_and_clamp( 16662d591a8SYue Hin Lau uint32_t wm_ns, 16762d591a8SYue Hin Lau uint32_t refclk_mhz, 16862d591a8SYue Hin Lau uint32_t clamp_value) 16962d591a8SYue Hin Lau { 17062d591a8SYue Hin Lau uint32_t ret_val = 0; 17162d591a8SYue Hin Lau ret_val = wm_ns * refclk_mhz; 17262d591a8SYue Hin Lau ret_val /= 1000; 17362d591a8SYue Hin Lau 17462d591a8SYue Hin Lau if (ret_val > clamp_value) 17562d591a8SYue Hin Lau ret_val = clamp_value; 17662d591a8SYue Hin Lau 17762d591a8SYue Hin Lau return ret_val; 17862d591a8SYue Hin Lau } 17962d591a8SYue Hin Lau 18062d591a8SYue Hin Lau 181ea00f297SYue Hin Lau void hubbub1_program_watermarks( 182c9ef081dSYue Hin Lau struct hubbub *hubbub, 18362d591a8SYue Hin Lau struct dcn_watermark_set *watermarks, 18462d591a8SYue Hin Lau unsigned int refclk_mhz) 18562d591a8SYue Hin Lau { 186c9ef081dSYue Hin Lau uint32_t force_en = hubbub->ctx->dc->debug.disable_stutter ? 1 : 0; 18762d591a8SYue Hin Lau /* 18862d591a8SYue Hin Lau * Need to clamp to max of the register values (i.e. no wrap) 18962d591a8SYue Hin Lau * for dcn1, all wm registers are 21-bit wide 19062d591a8SYue Hin Lau */ 19162d591a8SYue Hin Lau uint32_t prog_wm_value; 19262d591a8SYue Hin Lau 19362d591a8SYue Hin Lau REG_UPDATE(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL, 19462d591a8SYue Hin Lau DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, 0); 19562d591a8SYue Hin Lau 19662d591a8SYue Hin Lau /* Repeat for water mark set A, B, C and D. */ 19762d591a8SYue Hin Lau /* clock state A */ 19862d591a8SYue Hin Lau prog_wm_value = convert_and_clamp(watermarks->a.urgent_ns, 19962d591a8SYue Hin Lau refclk_mhz, 0x1fffff); 20062d591a8SYue Hin Lau REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, prog_wm_value); 20162d591a8SYue Hin Lau 202c9ef081dSYue Hin Lau dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS, 20362d591a8SYue Hin Lau "URGENCY_WATERMARK_A calculated =%d\n" 20462d591a8SYue Hin Lau "HW register value = 0x%x\n", 20562d591a8SYue Hin Lau watermarks->a.urgent_ns, prog_wm_value); 20662d591a8SYue Hin Lau 20762d591a8SYue Hin Lau prog_wm_value = convert_and_clamp(watermarks->a.pte_meta_urgent_ns, 20862d591a8SYue Hin Lau refclk_mhz, 0x1fffff); 20962d591a8SYue Hin Lau REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_A, prog_wm_value); 210c9ef081dSYue Hin Lau dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS, 21162d591a8SYue Hin Lau "PTE_META_URGENCY_WATERMARK_A calculated =%d\n" 21262d591a8SYue Hin Lau "HW register value = 0x%x\n", 21362d591a8SYue Hin Lau watermarks->a.pte_meta_urgent_ns, prog_wm_value); 21462d591a8SYue Hin Lau 21562d591a8SYue Hin Lau if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A)) { 21662d591a8SYue Hin Lau prog_wm_value = convert_and_clamp( 21762d591a8SYue Hin Lau watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns, 21862d591a8SYue Hin Lau refclk_mhz, 0x1fffff); 21962d591a8SYue Hin Lau REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A, prog_wm_value); 220c9ef081dSYue Hin Lau dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS, 22162d591a8SYue Hin Lau "SR_ENTER_EXIT_WATERMARK_A calculated =%d\n" 22262d591a8SYue Hin Lau "HW register value = 0x%x\n", 22362d591a8SYue Hin Lau watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value); 22462d591a8SYue Hin Lau 22562d591a8SYue Hin Lau 22662d591a8SYue Hin Lau prog_wm_value = convert_and_clamp( 22762d591a8SYue Hin Lau watermarks->a.cstate_pstate.cstate_exit_ns, 22862d591a8SYue Hin Lau refclk_mhz, 0x1fffff); 22962d591a8SYue Hin Lau REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A, prog_wm_value); 230c9ef081dSYue Hin Lau dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS, 23162d591a8SYue Hin Lau "SR_EXIT_WATERMARK_A calculated =%d\n" 23262d591a8SYue Hin Lau "HW register value = 0x%x\n", 23362d591a8SYue Hin Lau watermarks->a.cstate_pstate.cstate_exit_ns, prog_wm_value); 23462d591a8SYue Hin Lau } 23562d591a8SYue Hin Lau 23662d591a8SYue Hin Lau prog_wm_value = convert_and_clamp( 23762d591a8SYue Hin Lau watermarks->a.cstate_pstate.pstate_change_ns, 23862d591a8SYue Hin Lau refclk_mhz, 0x1fffff); 23962d591a8SYue Hin Lau REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A, prog_wm_value); 240c9ef081dSYue Hin Lau dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS, 24162d591a8SYue Hin Lau "DRAM_CLK_CHANGE_WATERMARK_A calculated =%d\n" 24262d591a8SYue Hin Lau "HW register value = 0x%x\n\n", 24362d591a8SYue Hin Lau watermarks->a.cstate_pstate.pstate_change_ns, prog_wm_value); 24462d591a8SYue Hin Lau 24562d591a8SYue Hin Lau 24662d591a8SYue Hin Lau /* clock state B */ 24762d591a8SYue Hin Lau prog_wm_value = convert_and_clamp( 24862d591a8SYue Hin Lau watermarks->b.urgent_ns, refclk_mhz, 0x1fffff); 24962d591a8SYue Hin Lau REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, prog_wm_value); 250c9ef081dSYue Hin Lau dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS, 25162d591a8SYue Hin Lau "URGENCY_WATERMARK_B calculated =%d\n" 25262d591a8SYue Hin Lau "HW register value = 0x%x\n", 25362d591a8SYue Hin Lau watermarks->b.urgent_ns, prog_wm_value); 25462d591a8SYue Hin Lau 25562d591a8SYue Hin Lau 25662d591a8SYue Hin Lau prog_wm_value = convert_and_clamp( 25762d591a8SYue Hin Lau watermarks->b.pte_meta_urgent_ns, 25862d591a8SYue Hin Lau refclk_mhz, 0x1fffff); 25962d591a8SYue Hin Lau REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_B, prog_wm_value); 260c9ef081dSYue Hin Lau dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS, 26162d591a8SYue Hin Lau "PTE_META_URGENCY_WATERMARK_B calculated =%d\n" 26262d591a8SYue Hin Lau "HW register value = 0x%x\n", 26362d591a8SYue Hin Lau watermarks->b.pte_meta_urgent_ns, prog_wm_value); 26462d591a8SYue Hin Lau 26562d591a8SYue Hin Lau 26662d591a8SYue Hin Lau if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B)) { 26762d591a8SYue Hin Lau prog_wm_value = convert_and_clamp( 26862d591a8SYue Hin Lau watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns, 26962d591a8SYue Hin Lau refclk_mhz, 0x1fffff); 27062d591a8SYue Hin Lau REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, prog_wm_value); 271c9ef081dSYue Hin Lau dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS, 27262d591a8SYue Hin Lau "SR_ENTER_WATERMARK_B calculated =%d\n" 27362d591a8SYue Hin Lau "HW register value = 0x%x\n", 27462d591a8SYue Hin Lau watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value); 27562d591a8SYue Hin Lau 27662d591a8SYue Hin Lau 27762d591a8SYue Hin Lau prog_wm_value = convert_and_clamp( 27862d591a8SYue Hin Lau watermarks->b.cstate_pstate.cstate_exit_ns, 27962d591a8SYue Hin Lau refclk_mhz, 0x1fffff); 28062d591a8SYue Hin Lau REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, prog_wm_value); 281c9ef081dSYue Hin Lau dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS, 28262d591a8SYue Hin Lau "SR_EXIT_WATERMARK_B calculated =%d\n" 28362d591a8SYue Hin Lau "HW register value = 0x%x\n", 28462d591a8SYue Hin Lau watermarks->b.cstate_pstate.cstate_exit_ns, prog_wm_value); 28562d591a8SYue Hin Lau } 28662d591a8SYue Hin Lau 28762d591a8SYue Hin Lau prog_wm_value = convert_and_clamp( 28862d591a8SYue Hin Lau watermarks->b.cstate_pstate.pstate_change_ns, 28962d591a8SYue Hin Lau refclk_mhz, 0x1fffff); 29062d591a8SYue Hin Lau REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B, prog_wm_value); 291c9ef081dSYue Hin Lau dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS, 29262d591a8SYue Hin Lau "DRAM_CLK_CHANGE_WATERMARK_B calculated =%d\n\n" 29362d591a8SYue Hin Lau "HW register value = 0x%x\n", 29462d591a8SYue Hin Lau watermarks->b.cstate_pstate.pstate_change_ns, prog_wm_value); 29562d591a8SYue Hin Lau 29662d591a8SYue Hin Lau /* clock state C */ 29762d591a8SYue Hin Lau prog_wm_value = convert_and_clamp( 29862d591a8SYue Hin Lau watermarks->c.urgent_ns, refclk_mhz, 0x1fffff); 29962d591a8SYue Hin Lau REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, prog_wm_value); 300c9ef081dSYue Hin Lau dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS, 30162d591a8SYue Hin Lau "URGENCY_WATERMARK_C calculated =%d\n" 30262d591a8SYue Hin Lau "HW register value = 0x%x\n", 30362d591a8SYue Hin Lau watermarks->c.urgent_ns, prog_wm_value); 30462d591a8SYue Hin Lau 30562d591a8SYue Hin Lau 30662d591a8SYue Hin Lau prog_wm_value = convert_and_clamp( 30762d591a8SYue Hin Lau watermarks->c.pte_meta_urgent_ns, 30862d591a8SYue Hin Lau refclk_mhz, 0x1fffff); 30962d591a8SYue Hin Lau REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_C, prog_wm_value); 310c9ef081dSYue Hin Lau dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS, 31162d591a8SYue Hin Lau "PTE_META_URGENCY_WATERMARK_C calculated =%d\n" 31262d591a8SYue Hin Lau "HW register value = 0x%x\n", 31362d591a8SYue Hin Lau watermarks->c.pte_meta_urgent_ns, prog_wm_value); 31462d591a8SYue Hin Lau 31562d591a8SYue Hin Lau 31662d591a8SYue Hin Lau if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C)) { 31762d591a8SYue Hin Lau prog_wm_value = convert_and_clamp( 31862d591a8SYue Hin Lau watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns, 31962d591a8SYue Hin Lau refclk_mhz, 0x1fffff); 32062d591a8SYue Hin Lau REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, prog_wm_value); 321c9ef081dSYue Hin Lau dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS, 32262d591a8SYue Hin Lau "SR_ENTER_WATERMARK_C calculated =%d\n" 32362d591a8SYue Hin Lau "HW register value = 0x%x\n", 32462d591a8SYue Hin Lau watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value); 32562d591a8SYue Hin Lau 32662d591a8SYue Hin Lau 32762d591a8SYue Hin Lau prog_wm_value = convert_and_clamp( 32862d591a8SYue Hin Lau watermarks->c.cstate_pstate.cstate_exit_ns, 32962d591a8SYue Hin Lau refclk_mhz, 0x1fffff); 33062d591a8SYue Hin Lau REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C, prog_wm_value); 331c9ef081dSYue Hin Lau dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS, 33262d591a8SYue Hin Lau "SR_EXIT_WATERMARK_C calculated =%d\n" 33362d591a8SYue Hin Lau "HW register value = 0x%x\n", 33462d591a8SYue Hin Lau watermarks->c.cstate_pstate.cstate_exit_ns, prog_wm_value); 33562d591a8SYue Hin Lau } 33662d591a8SYue Hin Lau 33762d591a8SYue Hin Lau prog_wm_value = convert_and_clamp( 33862d591a8SYue Hin Lau watermarks->c.cstate_pstate.pstate_change_ns, 33962d591a8SYue Hin Lau refclk_mhz, 0x1fffff); 34062d591a8SYue Hin Lau REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C, prog_wm_value); 341c9ef081dSYue Hin Lau dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS, 34262d591a8SYue Hin Lau "DRAM_CLK_CHANGE_WATERMARK_C calculated =%d\n\n" 34362d591a8SYue Hin Lau "HW register value = 0x%x\n", 34462d591a8SYue Hin Lau watermarks->c.cstate_pstate.pstate_change_ns, prog_wm_value); 34562d591a8SYue Hin Lau 34662d591a8SYue Hin Lau /* clock state D */ 34762d591a8SYue Hin Lau prog_wm_value = convert_and_clamp( 34862d591a8SYue Hin Lau watermarks->d.urgent_ns, refclk_mhz, 0x1fffff); 34962d591a8SYue Hin Lau REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, prog_wm_value); 350c9ef081dSYue Hin Lau dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS, 35162d591a8SYue Hin Lau "URGENCY_WATERMARK_D calculated =%d\n" 35262d591a8SYue Hin Lau "HW register value = 0x%x\n", 35362d591a8SYue Hin Lau watermarks->d.urgent_ns, prog_wm_value); 35462d591a8SYue Hin Lau 35562d591a8SYue Hin Lau prog_wm_value = convert_and_clamp( 35662d591a8SYue Hin Lau watermarks->d.pte_meta_urgent_ns, 35762d591a8SYue Hin Lau refclk_mhz, 0x1fffff); 35862d591a8SYue Hin Lau REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_D, prog_wm_value); 359c9ef081dSYue Hin Lau dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS, 36062d591a8SYue Hin Lau "PTE_META_URGENCY_WATERMARK_D calculated =%d\n" 36162d591a8SYue Hin Lau "HW register value = 0x%x\n", 36262d591a8SYue Hin Lau watermarks->d.pte_meta_urgent_ns, prog_wm_value); 36362d591a8SYue Hin Lau 36462d591a8SYue Hin Lau 36562d591a8SYue Hin Lau if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D)) { 36662d591a8SYue Hin Lau prog_wm_value = convert_and_clamp( 36762d591a8SYue Hin Lau watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns, 36862d591a8SYue Hin Lau refclk_mhz, 0x1fffff); 36962d591a8SYue Hin Lau REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, prog_wm_value); 370c9ef081dSYue Hin Lau dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS, 37162d591a8SYue Hin Lau "SR_ENTER_WATERMARK_D calculated =%d\n" 37262d591a8SYue Hin Lau "HW register value = 0x%x\n", 37362d591a8SYue Hin Lau watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value); 37462d591a8SYue Hin Lau 37562d591a8SYue Hin Lau 37662d591a8SYue Hin Lau prog_wm_value = convert_and_clamp( 37762d591a8SYue Hin Lau watermarks->d.cstate_pstate.cstate_exit_ns, 37862d591a8SYue Hin Lau refclk_mhz, 0x1fffff); 37962d591a8SYue Hin Lau REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D, prog_wm_value); 380c9ef081dSYue Hin Lau dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS, 38162d591a8SYue Hin Lau "SR_EXIT_WATERMARK_D calculated =%d\n" 38262d591a8SYue Hin Lau "HW register value = 0x%x\n", 38362d591a8SYue Hin Lau watermarks->d.cstate_pstate.cstate_exit_ns, prog_wm_value); 38462d591a8SYue Hin Lau } 38562d591a8SYue Hin Lau 38662d591a8SYue Hin Lau 38762d591a8SYue Hin Lau prog_wm_value = convert_and_clamp( 38862d591a8SYue Hin Lau watermarks->d.cstate_pstate.pstate_change_ns, 38962d591a8SYue Hin Lau refclk_mhz, 0x1fffff); 39062d591a8SYue Hin Lau REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D, prog_wm_value); 391c9ef081dSYue Hin Lau dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS, 39262d591a8SYue Hin Lau "DRAM_CLK_CHANGE_WATERMARK_D calculated =%d\n" 39362d591a8SYue Hin Lau "HW register value = 0x%x\n\n", 39462d591a8SYue Hin Lau watermarks->d.cstate_pstate.pstate_change_ns, prog_wm_value); 39562d591a8SYue Hin Lau 39662d591a8SYue Hin Lau REG_UPDATE(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL, 39762d591a8SYue Hin Lau DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, 1); 39862d591a8SYue Hin Lau 39962d591a8SYue Hin Lau REG_UPDATE(DCHUBBUB_ARB_SAT_LEVEL, 40062d591a8SYue Hin Lau DCHUBBUB_ARB_SAT_LEVEL, 60 * refclk_mhz); 40162d591a8SYue Hin Lau REG_UPDATE(DCHUBBUB_ARB_DF_REQ_OUTSTAND, 40262d591a8SYue Hin Lau DCHUBBUB_ARB_MIN_REQ_OUTSTAND, 68); 40362d591a8SYue Hin Lau 40462d591a8SYue Hin Lau REG_UPDATE_2(DCHUBBUB_ARB_DRAM_STATE_CNTL, 40562d591a8SYue Hin Lau DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_VALUE, 0, 40662d591a8SYue Hin Lau DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_ENABLE, force_en); 40762d591a8SYue Hin Lau 40862d591a8SYue Hin Lau #if 0 40962d591a8SYue Hin Lau REG_UPDATE_2(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL, 41062d591a8SYue Hin Lau DCHUBBUB_ARB_WATERMARK_CHANGE_DONE_INTERRUPT_DISABLE, 1, 41162d591a8SYue Hin Lau DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, 1); 41262d591a8SYue Hin Lau #endif 41362d591a8SYue Hin Lau } 41462d591a8SYue Hin Lau 415c9ef081dSYue Hin Lau void hubbub1_update_dchub( 416c9ef081dSYue Hin Lau struct hubbub *hubbub, 41762d591a8SYue Hin Lau struct dchub_init_data *dh_data) 41862d591a8SYue Hin Lau { 41962d591a8SYue Hin Lau /* TODO: port code from dal2 */ 42062d591a8SYue Hin Lau switch (dh_data->fb_mode) { 42162d591a8SYue Hin Lau case FRAME_BUFFER_MODE_ZFB_ONLY: 42262d591a8SYue Hin Lau /*For ZFB case need to put DCHUB FB BASE and TOP upside down to indicate ZFB mode*/ 42362d591a8SYue Hin Lau REG_UPDATE(DCHUBBUB_SDPIF_FB_TOP, 42462d591a8SYue Hin Lau SDPIF_FB_TOP, 0); 42562d591a8SYue Hin Lau 42662d591a8SYue Hin Lau REG_UPDATE(DCHUBBUB_SDPIF_FB_BASE, 42762d591a8SYue Hin Lau SDPIF_FB_BASE, 0x0FFFF); 42862d591a8SYue Hin Lau 42962d591a8SYue Hin Lau REG_UPDATE(DCHUBBUB_SDPIF_AGP_BASE, 43062d591a8SYue Hin Lau SDPIF_AGP_BASE, dh_data->zfb_phys_addr_base >> 22); 43162d591a8SYue Hin Lau 43262d591a8SYue Hin Lau REG_UPDATE(DCHUBBUB_SDPIF_AGP_BOT, 43362d591a8SYue Hin Lau SDPIF_AGP_BOT, dh_data->zfb_mc_base_addr >> 22); 43462d591a8SYue Hin Lau 43562d591a8SYue Hin Lau REG_UPDATE(DCHUBBUB_SDPIF_AGP_TOP, 43662d591a8SYue Hin Lau SDPIF_AGP_TOP, (dh_data->zfb_mc_base_addr + 43762d591a8SYue Hin Lau dh_data->zfb_size_in_byte - 1) >> 22); 43862d591a8SYue Hin Lau break; 43962d591a8SYue Hin Lau case FRAME_BUFFER_MODE_MIXED_ZFB_AND_LOCAL: 44062d591a8SYue Hin Lau /*Should not touch FB LOCATION (done by VBIOS on AsicInit table)*/ 44162d591a8SYue Hin Lau 44262d591a8SYue Hin Lau REG_UPDATE(DCHUBBUB_SDPIF_AGP_BASE, 44362d591a8SYue Hin Lau SDPIF_AGP_BASE, dh_data->zfb_phys_addr_base >> 22); 44462d591a8SYue Hin Lau 44562d591a8SYue Hin Lau REG_UPDATE(DCHUBBUB_SDPIF_AGP_BOT, 44662d591a8SYue Hin Lau SDPIF_AGP_BOT, dh_data->zfb_mc_base_addr >> 22); 44762d591a8SYue Hin Lau 44862d591a8SYue Hin Lau REG_UPDATE(DCHUBBUB_SDPIF_AGP_TOP, 44962d591a8SYue Hin Lau SDPIF_AGP_TOP, (dh_data->zfb_mc_base_addr + 45062d591a8SYue Hin Lau dh_data->zfb_size_in_byte - 1) >> 22); 45162d591a8SYue Hin Lau break; 45262d591a8SYue Hin Lau case FRAME_BUFFER_MODE_LOCAL_ONLY: 45362d591a8SYue Hin Lau /*Should not touch FB LOCATION (done by VBIOS on AsicInit table)*/ 45462d591a8SYue Hin Lau REG_UPDATE(DCHUBBUB_SDPIF_AGP_BASE, 45562d591a8SYue Hin Lau SDPIF_AGP_BASE, 0); 45662d591a8SYue Hin Lau 45762d591a8SYue Hin Lau REG_UPDATE(DCHUBBUB_SDPIF_AGP_BOT, 45862d591a8SYue Hin Lau SDPIF_AGP_BOT, 0X03FFFF); 45962d591a8SYue Hin Lau 46062d591a8SYue Hin Lau REG_UPDATE(DCHUBBUB_SDPIF_AGP_TOP, 46162d591a8SYue Hin Lau SDPIF_AGP_TOP, 0); 46262d591a8SYue Hin Lau break; 46362d591a8SYue Hin Lau default: 46462d591a8SYue Hin Lau break; 46562d591a8SYue Hin Lau } 46662d591a8SYue Hin Lau 46762d591a8SYue Hin Lau dh_data->dchub_initialzied = true; 46862d591a8SYue Hin Lau dh_data->dchub_info_valid = false; 46962d591a8SYue Hin Lau } 47062d591a8SYue Hin Lau 471ea00f297SYue Hin Lau void hubbub1_toggle_watermark_change_req(struct hubbub *hubbub) 47262d591a8SYue Hin Lau { 47362d591a8SYue Hin Lau uint32_t watermark_change_req; 47462d591a8SYue Hin Lau 47562d591a8SYue Hin Lau REG_GET(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL, 47662d591a8SYue Hin Lau DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, &watermark_change_req); 47762d591a8SYue Hin Lau 47862d591a8SYue Hin Lau if (watermark_change_req) 47962d591a8SYue Hin Lau watermark_change_req = 0; 48062d591a8SYue Hin Lau else 48162d591a8SYue Hin Lau watermark_change_req = 1; 48262d591a8SYue Hin Lau 48362d591a8SYue Hin Lau REG_UPDATE(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL, 48462d591a8SYue Hin Lau DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, watermark_change_req); 48562d591a8SYue Hin Lau } 48662d591a8SYue Hin Lau 487c9ef081dSYue Hin Lau static const struct hubbub_funcs hubbub1_funcs = { 488c9ef081dSYue Hin Lau .update_dchub = hubbub1_update_dchub 489c9ef081dSYue Hin Lau }; 490c9ef081dSYue Hin Lau 491c9ef081dSYue Hin Lau void hubbub1_construct(struct hubbub *hubbub, 492c9ef081dSYue Hin Lau struct dc_context *ctx, 493c9ef081dSYue Hin Lau const struct dcn_hubbub_registers *hubbub_regs, 494c9ef081dSYue Hin Lau const struct dcn_hubbub_shift *hubbub_shift, 495c9ef081dSYue Hin Lau const struct dcn_hubbub_mask *hubbub_mask) 496c9ef081dSYue Hin Lau { 497c9ef081dSYue Hin Lau hubbub->ctx = ctx; 498c9ef081dSYue Hin Lau 499c9ef081dSYue Hin Lau hubbub->funcs = &hubbub1_funcs; 500c9ef081dSYue Hin Lau 501c9ef081dSYue Hin Lau hubbub->regs = hubbub_regs; 502c9ef081dSYue Hin Lau hubbub->shifts = hubbub_shift; 503c9ef081dSYue Hin Lau hubbub->masks = hubbub_mask; 504c9ef081dSYue Hin Lau 505c9ef081dSYue Hin Lau } 50662d591a8SYue Hin Lau 507