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 331296423bSBhawanpreet Lakha #define DC_LOGGER \ 341296423bSBhawanpreet Lakha hubbub->ctx->logger 3562d591a8SYue Hin Lau #define REG(reg)\ 36c9ef081dSYue Hin Lau hubbub->regs->reg 3762d591a8SYue Hin Lau 3862d591a8SYue Hin Lau #undef FN 3962d591a8SYue Hin Lau #define FN(reg_name, field_name) \ 40c9ef081dSYue Hin Lau hubbub->shifts->field_name, hubbub->masks->field_name 4162d591a8SYue Hin Lau 42c9ef081dSYue Hin Lau void hubbub1_wm_read_state(struct hubbub *hubbub, 4362d591a8SYue Hin Lau struct dcn_hubbub_wm *wm) 4462d591a8SYue Hin Lau { 4562d591a8SYue Hin Lau struct dcn_hubbub_wm_set *s; 4662d591a8SYue Hin Lau 47d39b3acbSKen Chalmers memset(wm, 0, sizeof(struct dcn_hubbub_wm)); 48d39b3acbSKen Chalmers 4962d591a8SYue Hin Lau s = &wm->sets[0]; 5062d591a8SYue Hin Lau s->wm_set = 0; 5162d591a8SYue Hin Lau s->data_urgent = REG_READ(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A); 5262d591a8SYue Hin Lau s->pte_meta_urgent = REG_READ(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_A); 53d39b3acbSKen Chalmers if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A)) { 5462d591a8SYue Hin Lau s->sr_enter = REG_READ(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A); 5562d591a8SYue Hin Lau s->sr_exit = REG_READ(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A); 56d39b3acbSKen Chalmers } 5762d591a8SYue Hin Lau s->dram_clk_chanage = REG_READ(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A); 5862d591a8SYue Hin Lau 5962d591a8SYue Hin Lau s = &wm->sets[1]; 6062d591a8SYue Hin Lau s->wm_set = 1; 6162d591a8SYue Hin Lau s->data_urgent = REG_READ(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B); 6262d591a8SYue Hin Lau s->pte_meta_urgent = REG_READ(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_B); 63d39b3acbSKen Chalmers if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B)) { 6462d591a8SYue Hin Lau s->sr_enter = REG_READ(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B); 6562d591a8SYue Hin Lau s->sr_exit = REG_READ(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B); 66d39b3acbSKen Chalmers } 6762d591a8SYue Hin Lau s->dram_clk_chanage = REG_READ(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B); 6862d591a8SYue Hin Lau 6962d591a8SYue Hin Lau s = &wm->sets[2]; 7062d591a8SYue Hin Lau s->wm_set = 2; 7162d591a8SYue Hin Lau s->data_urgent = REG_READ(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C); 7262d591a8SYue Hin Lau s->pte_meta_urgent = REG_READ(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_C); 73d39b3acbSKen Chalmers if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C)) { 7462d591a8SYue Hin Lau s->sr_enter = REG_READ(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C); 7562d591a8SYue Hin Lau s->sr_exit = REG_READ(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C); 76d39b3acbSKen Chalmers } 7762d591a8SYue Hin Lau s->dram_clk_chanage = REG_READ(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C); 7862d591a8SYue Hin Lau 7962d591a8SYue Hin Lau s = &wm->sets[3]; 8062d591a8SYue Hin Lau s->wm_set = 3; 8162d591a8SYue Hin Lau s->data_urgent = REG_READ(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D); 8262d591a8SYue Hin Lau s->pte_meta_urgent = REG_READ(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_D); 83d39b3acbSKen Chalmers if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D)) { 8462d591a8SYue Hin Lau s->sr_enter = REG_READ(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D); 8562d591a8SYue Hin Lau s->sr_exit = REG_READ(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D); 86d39b3acbSKen Chalmers } 8762d591a8SYue Hin Lau s->dram_clk_chanage = REG_READ(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D); 8862d591a8SYue Hin Lau } 8962d591a8SYue Hin Lau 90ea00f297SYue Hin Lau bool hubbub1_verify_allow_pstate_change_high( 91c9ef081dSYue Hin Lau struct hubbub *hubbub) 9262d591a8SYue Hin Lau { 9362d591a8SYue Hin Lau /* pstate latency is ~20us so if we wait over 40us and pstate allow 9462d591a8SYue Hin Lau * still not asserted, we are probably stuck and going to hang 9562d591a8SYue Hin Lau * 9662d591a8SYue Hin Lau * TODO: Figure out why it takes ~100us on linux 9762d591a8SYue Hin Lau * pstate takes around ~100us on linux. Unknown currently as to 9862d591a8SYue Hin Lau * why it takes that long on linux 9962d591a8SYue Hin Lau */ 10062d591a8SYue Hin Lau static unsigned int pstate_wait_timeout_us = 200; 10162d591a8SYue Hin Lau static unsigned int pstate_wait_expected_timeout_us = 40; 10262d591a8SYue Hin Lau static unsigned int max_sampled_pstate_wait_us; /* data collection */ 10362d591a8SYue Hin Lau static bool forced_pstate_allow; /* help with revert wa */ 10462d591a8SYue Hin Lau 10562d591a8SYue Hin Lau unsigned int debug_data; 10662d591a8SYue Hin Lau unsigned int i; 10762d591a8SYue Hin Lau 10862d591a8SYue Hin Lau if (forced_pstate_allow) { 10962d591a8SYue Hin Lau /* we hacked to force pstate allow to prevent hang last time 11062d591a8SYue Hin Lau * we verify_allow_pstate_change_high. so disable force 11162d591a8SYue Hin Lau * here so we can check status 11262d591a8SYue Hin Lau */ 11362d591a8SYue Hin Lau REG_UPDATE_2(DCHUBBUB_ARB_DRAM_STATE_CNTL, 11462d591a8SYue Hin Lau DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_VALUE, 0, 11562d591a8SYue Hin Lau DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_ENABLE, 0); 11662d591a8SYue Hin Lau forced_pstate_allow = false; 11762d591a8SYue Hin Lau } 11862d591a8SYue Hin Lau 119cf1df90fSHersen Wu /* RV1: 120cf1df90fSHersen Wu * dchubbubdebugind, at: 0x7 121cf1df90fSHersen Wu * description "3-0: Pipe0 cursor0 QOS 12262d591a8SYue Hin Lau * 7-4: Pipe1 cursor0 QOS 12362d591a8SYue Hin Lau * 11-8: Pipe2 cursor0 QOS 12462d591a8SYue Hin Lau * 15-12: Pipe3 cursor0 QOS 12562d591a8SYue Hin Lau * 16: Pipe0 Plane0 Allow Pstate Change 12662d591a8SYue Hin Lau * 17: Pipe1 Plane0 Allow Pstate Change 12762d591a8SYue Hin Lau * 18: Pipe2 Plane0 Allow Pstate Change 12862d591a8SYue Hin Lau * 19: Pipe3 Plane0 Allow Pstate Change 12962d591a8SYue Hin Lau * 20: Pipe0 Plane1 Allow Pstate Change 13062d591a8SYue Hin Lau * 21: Pipe1 Plane1 Allow Pstate Change 13162d591a8SYue Hin Lau * 22: Pipe2 Plane1 Allow Pstate Change 13262d591a8SYue Hin Lau * 23: Pipe3 Plane1 Allow Pstate Change 13362d591a8SYue Hin Lau * 24: Pipe0 cursor0 Allow Pstate Change 13462d591a8SYue Hin Lau * 25: Pipe1 cursor0 Allow Pstate Change 13562d591a8SYue Hin Lau * 26: Pipe2 cursor0 Allow Pstate Change 13662d591a8SYue Hin Lau * 27: Pipe3 cursor0 Allow Pstate Change 13762d591a8SYue Hin Lau * 28: WB0 Allow Pstate Change 13862d591a8SYue Hin Lau * 29: WB1 Allow Pstate Change 13962d591a8SYue Hin Lau * 30: Arbiter's allow_pstate_change 14062d591a8SYue Hin Lau * 31: SOC pstate change request 14162d591a8SYue Hin Lau */ 14262d591a8SYue Hin Lau 143cf1df90fSHersen Wu 144cf1df90fSHersen Wu REG_WRITE(DCHUBBUB_TEST_DEBUG_INDEX, hubbub->debug_test_index_pstate); 14562d591a8SYue Hin Lau 14662d591a8SYue Hin Lau for (i = 0; i < pstate_wait_timeout_us; i++) { 14762d591a8SYue Hin Lau debug_data = REG_READ(DCHUBBUB_TEST_DEBUG_DATA); 14862d591a8SYue Hin Lau 14962d591a8SYue Hin Lau if (debug_data & (1 << 30)) { 15062d591a8SYue Hin Lau 15162d591a8SYue Hin Lau if (i > pstate_wait_expected_timeout_us) 1521296423bSBhawanpreet Lakha DC_LOG_WARNING("pstate took longer than expected ~%dus\n", 15362d591a8SYue Hin Lau i); 15462d591a8SYue Hin Lau 155e70fe3b1SYue Hin Lau return true; 15662d591a8SYue Hin Lau } 15762d591a8SYue Hin Lau if (max_sampled_pstate_wait_us < i) 15862d591a8SYue Hin Lau max_sampled_pstate_wait_us = i; 15962d591a8SYue Hin Lau 16062d591a8SYue Hin Lau udelay(1); 16162d591a8SYue Hin Lau } 16262d591a8SYue Hin Lau 16362d591a8SYue Hin Lau /* force pstate allow to prevent system hang 16462d591a8SYue Hin Lau * and break to debugger to investigate 16562d591a8SYue Hin Lau */ 16662d591a8SYue Hin Lau REG_UPDATE_2(DCHUBBUB_ARB_DRAM_STATE_CNTL, 16762d591a8SYue Hin Lau DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_VALUE, 1, 16862d591a8SYue Hin Lau DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_ENABLE, 1); 16962d591a8SYue Hin Lau forced_pstate_allow = true; 17062d591a8SYue Hin Lau 1711296423bSBhawanpreet Lakha DC_LOG_WARNING("pstate TEST_DEBUG_DATA: 0x%X\n", 17262d591a8SYue Hin Lau debug_data); 173ea00f297SYue Hin Lau 174e70fe3b1SYue Hin Lau return false; 17562d591a8SYue Hin Lau } 17662d591a8SYue Hin Lau 17762d591a8SYue Hin Lau static uint32_t convert_and_clamp( 17862d591a8SYue Hin Lau uint32_t wm_ns, 17962d591a8SYue Hin Lau uint32_t refclk_mhz, 18062d591a8SYue Hin Lau uint32_t clamp_value) 18162d591a8SYue Hin Lau { 18262d591a8SYue Hin Lau uint32_t ret_val = 0; 18362d591a8SYue Hin Lau ret_val = wm_ns * refclk_mhz; 18462d591a8SYue Hin Lau ret_val /= 1000; 18562d591a8SYue Hin Lau 18662d591a8SYue Hin Lau if (ret_val > clamp_value) 18762d591a8SYue Hin Lau ret_val = clamp_value; 18862d591a8SYue Hin Lau 18962d591a8SYue Hin Lau return ret_val; 19062d591a8SYue Hin Lau } 19162d591a8SYue Hin Lau 19262d591a8SYue Hin Lau 193ea00f297SYue Hin Lau void hubbub1_program_watermarks( 194c9ef081dSYue Hin Lau struct hubbub *hubbub, 19562d591a8SYue Hin Lau struct dcn_watermark_set *watermarks, 196d7b539d3SDmytro Laktyushkin unsigned int refclk_mhz, 197d7b539d3SDmytro Laktyushkin bool safe_to_lower) 19862d591a8SYue Hin Lau { 199c9ef081dSYue Hin Lau uint32_t force_en = hubbub->ctx->dc->debug.disable_stutter ? 1 : 0; 20062d591a8SYue Hin Lau /* 20162d591a8SYue Hin Lau * Need to clamp to max of the register values (i.e. no wrap) 20262d591a8SYue Hin Lau * for dcn1, all wm registers are 21-bit wide 20362d591a8SYue Hin Lau */ 20462d591a8SYue Hin Lau uint32_t prog_wm_value; 20562d591a8SYue Hin Lau 20662d591a8SYue Hin Lau REG_UPDATE(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL, 20762d591a8SYue Hin Lau DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, 0); 20862d591a8SYue Hin Lau 20962d591a8SYue Hin Lau /* Repeat for water mark set A, B, C and D. */ 21062d591a8SYue Hin Lau /* clock state A */ 211d7b539d3SDmytro Laktyushkin if (safe_to_lower || watermarks->a.urgent_ns > hubbub->watermarks.a.urgent_ns) { 212d7b539d3SDmytro Laktyushkin hubbub->watermarks.a.urgent_ns = watermarks->a.urgent_ns; 21362d591a8SYue Hin Lau prog_wm_value = convert_and_clamp(watermarks->a.urgent_ns, 21462d591a8SYue Hin Lau refclk_mhz, 0x1fffff); 21562d591a8SYue Hin Lau REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, prog_wm_value); 21662d591a8SYue Hin Lau 2171296423bSBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_A calculated =%d\n" 21862d591a8SYue Hin Lau "HW register value = 0x%x\n", 21962d591a8SYue Hin Lau watermarks->a.urgent_ns, prog_wm_value); 220d7b539d3SDmytro Laktyushkin } 22162d591a8SYue Hin Lau 222d7b539d3SDmytro Laktyushkin if (safe_to_lower || watermarks->a.pte_meta_urgent_ns > hubbub->watermarks.a.pte_meta_urgent_ns) { 223d7b539d3SDmytro Laktyushkin hubbub->watermarks.a.pte_meta_urgent_ns = watermarks->a.pte_meta_urgent_ns; 22462d591a8SYue Hin Lau prog_wm_value = convert_and_clamp(watermarks->a.pte_meta_urgent_ns, 22562d591a8SYue Hin Lau refclk_mhz, 0x1fffff); 22662d591a8SYue Hin Lau REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_A, prog_wm_value); 2271296423bSBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("PTE_META_URGENCY_WATERMARK_A calculated =%d\n" 22862d591a8SYue Hin Lau "HW register value = 0x%x\n", 22962d591a8SYue Hin Lau watermarks->a.pte_meta_urgent_ns, prog_wm_value); 230d7b539d3SDmytro Laktyushkin } 23162d591a8SYue Hin Lau 23262d591a8SYue Hin Lau if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A)) { 233d7b539d3SDmytro Laktyushkin if (safe_to_lower || watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns 234d7b539d3SDmytro Laktyushkin > hubbub->watermarks.a.cstate_pstate.cstate_enter_plus_exit_ns) { 235d7b539d3SDmytro Laktyushkin hubbub->watermarks.a.cstate_pstate.cstate_enter_plus_exit_ns = 236d7b539d3SDmytro Laktyushkin watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns; 23762d591a8SYue Hin Lau prog_wm_value = convert_and_clamp( 23862d591a8SYue Hin Lau watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns, 23962d591a8SYue Hin Lau refclk_mhz, 0x1fffff); 24062d591a8SYue Hin Lau REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A, prog_wm_value); 2411296423bSBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_A calculated =%d\n" 24262d591a8SYue Hin Lau "HW register value = 0x%x\n", 24362d591a8SYue Hin Lau watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value); 244d7b539d3SDmytro Laktyushkin } 24562d591a8SYue Hin Lau 246d7b539d3SDmytro Laktyushkin if (safe_to_lower || watermarks->a.cstate_pstate.cstate_exit_ns 247d7b539d3SDmytro Laktyushkin > hubbub->watermarks.a.cstate_pstate.cstate_exit_ns) { 248d7b539d3SDmytro Laktyushkin hubbub->watermarks.a.cstate_pstate.cstate_exit_ns = 249d7b539d3SDmytro Laktyushkin watermarks->a.cstate_pstate.cstate_exit_ns; 25062d591a8SYue Hin Lau prog_wm_value = convert_and_clamp( 25162d591a8SYue Hin Lau watermarks->a.cstate_pstate.cstate_exit_ns, 25262d591a8SYue Hin Lau refclk_mhz, 0x1fffff); 25362d591a8SYue Hin Lau REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A, prog_wm_value); 2541296423bSBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_A calculated =%d\n" 25562d591a8SYue Hin Lau "HW register value = 0x%x\n", 25662d591a8SYue Hin Lau watermarks->a.cstate_pstate.cstate_exit_ns, prog_wm_value); 25762d591a8SYue Hin Lau } 258d7b539d3SDmytro Laktyushkin } 25962d591a8SYue Hin Lau 260d7b539d3SDmytro Laktyushkin if (safe_to_lower || watermarks->a.cstate_pstate.pstate_change_ns 261d7b539d3SDmytro Laktyushkin > hubbub->watermarks.a.cstate_pstate.pstate_change_ns) { 262d7b539d3SDmytro Laktyushkin hubbub->watermarks.a.cstate_pstate.pstate_change_ns = 263d7b539d3SDmytro Laktyushkin watermarks->a.cstate_pstate.pstate_change_ns; 26462d591a8SYue Hin Lau prog_wm_value = convert_and_clamp( 26562d591a8SYue Hin Lau watermarks->a.cstate_pstate.pstate_change_ns, 26662d591a8SYue Hin Lau refclk_mhz, 0x1fffff); 26762d591a8SYue Hin Lau REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A, prog_wm_value); 2681296423bSBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_A calculated =%d\n" 26962d591a8SYue Hin Lau "HW register value = 0x%x\n\n", 27062d591a8SYue Hin Lau watermarks->a.cstate_pstate.pstate_change_ns, prog_wm_value); 271d7b539d3SDmytro Laktyushkin } 27262d591a8SYue Hin Lau 27362d591a8SYue Hin Lau /* clock state B */ 274d7b539d3SDmytro Laktyushkin if (safe_to_lower || watermarks->b.urgent_ns > hubbub->watermarks.b.urgent_ns) { 275d7b539d3SDmytro Laktyushkin hubbub->watermarks.b.urgent_ns = watermarks->b.urgent_ns; 276d7b539d3SDmytro Laktyushkin prog_wm_value = convert_and_clamp(watermarks->b.urgent_ns, 277d7b539d3SDmytro Laktyushkin refclk_mhz, 0x1fffff); 27862d591a8SYue Hin Lau REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, prog_wm_value); 279d7b539d3SDmytro Laktyushkin 2801296423bSBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_B calculated =%d\n" 28162d591a8SYue Hin Lau "HW register value = 0x%x\n", 28262d591a8SYue Hin Lau watermarks->b.urgent_ns, prog_wm_value); 283d7b539d3SDmytro Laktyushkin } 28462d591a8SYue Hin Lau 285d7b539d3SDmytro Laktyushkin if (safe_to_lower || watermarks->b.pte_meta_urgent_ns > hubbub->watermarks.b.pte_meta_urgent_ns) { 286d7b539d3SDmytro Laktyushkin hubbub->watermarks.b.pte_meta_urgent_ns = watermarks->b.pte_meta_urgent_ns; 287d7b539d3SDmytro Laktyushkin prog_wm_value = convert_and_clamp(watermarks->b.pte_meta_urgent_ns, 28862d591a8SYue Hin Lau refclk_mhz, 0x1fffff); 28962d591a8SYue Hin Lau REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_B, prog_wm_value); 2901296423bSBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("PTE_META_URGENCY_WATERMARK_B calculated =%d\n" 29162d591a8SYue Hin Lau "HW register value = 0x%x\n", 29262d591a8SYue Hin Lau watermarks->b.pte_meta_urgent_ns, prog_wm_value); 293d7b539d3SDmytro Laktyushkin } 29462d591a8SYue Hin Lau 29562d591a8SYue Hin Lau if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B)) { 296d7b539d3SDmytro Laktyushkin if (safe_to_lower || watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns 297d7b539d3SDmytro Laktyushkin > hubbub->watermarks.b.cstate_pstate.cstate_enter_plus_exit_ns) { 298d7b539d3SDmytro Laktyushkin hubbub->watermarks.b.cstate_pstate.cstate_enter_plus_exit_ns = 299d7b539d3SDmytro Laktyushkin watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns; 30062d591a8SYue Hin Lau prog_wm_value = convert_and_clamp( 30162d591a8SYue Hin Lau watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns, 30262d591a8SYue Hin Lau refclk_mhz, 0x1fffff); 30362d591a8SYue Hin Lau REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, prog_wm_value); 304d7b539d3SDmytro Laktyushkin DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_B calculated =%d\n" 30562d591a8SYue Hin Lau "HW register value = 0x%x\n", 30662d591a8SYue Hin Lau watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value); 307d7b539d3SDmytro Laktyushkin } 30862d591a8SYue Hin Lau 309d7b539d3SDmytro Laktyushkin if (safe_to_lower || watermarks->b.cstate_pstate.cstate_exit_ns 310d7b539d3SDmytro Laktyushkin > hubbub->watermarks.b.cstate_pstate.cstate_exit_ns) { 311d7b539d3SDmytro Laktyushkin hubbub->watermarks.b.cstate_pstate.cstate_exit_ns = 312d7b539d3SDmytro Laktyushkin watermarks->b.cstate_pstate.cstate_exit_ns; 31362d591a8SYue Hin Lau prog_wm_value = convert_and_clamp( 31462d591a8SYue Hin Lau watermarks->b.cstate_pstate.cstate_exit_ns, 31562d591a8SYue Hin Lau refclk_mhz, 0x1fffff); 31662d591a8SYue Hin Lau REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, prog_wm_value); 3171296423bSBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_B calculated =%d\n" 31862d591a8SYue Hin Lau "HW register value = 0x%x\n", 31962d591a8SYue Hin Lau watermarks->b.cstate_pstate.cstate_exit_ns, prog_wm_value); 32062d591a8SYue Hin Lau } 321d7b539d3SDmytro Laktyushkin } 32262d591a8SYue Hin Lau 323d7b539d3SDmytro Laktyushkin if (safe_to_lower || watermarks->b.cstate_pstate.pstate_change_ns 324d7b539d3SDmytro Laktyushkin > hubbub->watermarks.b.cstate_pstate.pstate_change_ns) { 325d7b539d3SDmytro Laktyushkin hubbub->watermarks.b.cstate_pstate.pstate_change_ns = 326d7b539d3SDmytro Laktyushkin watermarks->b.cstate_pstate.pstate_change_ns; 32762d591a8SYue Hin Lau prog_wm_value = convert_and_clamp( 32862d591a8SYue Hin Lau watermarks->b.cstate_pstate.pstate_change_ns, 32962d591a8SYue Hin Lau refclk_mhz, 0x1fffff); 33062d591a8SYue Hin Lau REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B, prog_wm_value); 331d7b539d3SDmytro Laktyushkin DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_B calculated =%d\n" 332d7b539d3SDmytro Laktyushkin "HW register value = 0x%x\n\n", 33362d591a8SYue Hin Lau watermarks->b.cstate_pstate.pstate_change_ns, prog_wm_value); 334d7b539d3SDmytro Laktyushkin } 33562d591a8SYue Hin Lau 33662d591a8SYue Hin Lau /* clock state C */ 337d7b539d3SDmytro Laktyushkin if (safe_to_lower || watermarks->c.urgent_ns > hubbub->watermarks.c.urgent_ns) { 338d7b539d3SDmytro Laktyushkin hubbub->watermarks.c.urgent_ns = watermarks->c.urgent_ns; 339d7b539d3SDmytro Laktyushkin prog_wm_value = convert_and_clamp(watermarks->c.urgent_ns, 340d7b539d3SDmytro Laktyushkin refclk_mhz, 0x1fffff); 34162d591a8SYue Hin Lau REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, prog_wm_value); 342d7b539d3SDmytro Laktyushkin 3431296423bSBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_C calculated =%d\n" 34462d591a8SYue Hin Lau "HW register value = 0x%x\n", 34562d591a8SYue Hin Lau watermarks->c.urgent_ns, prog_wm_value); 346d7b539d3SDmytro Laktyushkin } 34762d591a8SYue Hin Lau 348d7b539d3SDmytro Laktyushkin if (safe_to_lower || watermarks->c.pte_meta_urgent_ns > hubbub->watermarks.c.pte_meta_urgent_ns) { 349d7b539d3SDmytro Laktyushkin hubbub->watermarks.c.pte_meta_urgent_ns = watermarks->c.pte_meta_urgent_ns; 350d7b539d3SDmytro Laktyushkin prog_wm_value = convert_and_clamp(watermarks->c.pte_meta_urgent_ns, 35162d591a8SYue Hin Lau refclk_mhz, 0x1fffff); 35262d591a8SYue Hin Lau REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_C, prog_wm_value); 3531296423bSBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("PTE_META_URGENCY_WATERMARK_C calculated =%d\n" 35462d591a8SYue Hin Lau "HW register value = 0x%x\n", 35562d591a8SYue Hin Lau watermarks->c.pte_meta_urgent_ns, prog_wm_value); 356d7b539d3SDmytro Laktyushkin } 35762d591a8SYue Hin Lau 35862d591a8SYue Hin Lau if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C)) { 359d7b539d3SDmytro Laktyushkin if (safe_to_lower || watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns 360d7b539d3SDmytro Laktyushkin > hubbub->watermarks.c.cstate_pstate.cstate_enter_plus_exit_ns) { 361d7b539d3SDmytro Laktyushkin hubbub->watermarks.c.cstate_pstate.cstate_enter_plus_exit_ns = 362d7b539d3SDmytro Laktyushkin watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns; 36362d591a8SYue Hin Lau prog_wm_value = convert_and_clamp( 36462d591a8SYue Hin Lau watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns, 36562d591a8SYue Hin Lau refclk_mhz, 0x1fffff); 36662d591a8SYue Hin Lau REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, prog_wm_value); 367d7b539d3SDmytro Laktyushkin DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_C calculated =%d\n" 36862d591a8SYue Hin Lau "HW register value = 0x%x\n", 36962d591a8SYue Hin Lau watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value); 370d7b539d3SDmytro Laktyushkin } 37162d591a8SYue Hin Lau 372d7b539d3SDmytro Laktyushkin if (safe_to_lower || watermarks->c.cstate_pstate.cstate_exit_ns 373d7b539d3SDmytro Laktyushkin > hubbub->watermarks.c.cstate_pstate.cstate_exit_ns) { 374d7b539d3SDmytro Laktyushkin hubbub->watermarks.c.cstate_pstate.cstate_exit_ns = 375d7b539d3SDmytro Laktyushkin watermarks->c.cstate_pstate.cstate_exit_ns; 37662d591a8SYue Hin Lau prog_wm_value = convert_and_clamp( 37762d591a8SYue Hin Lau watermarks->c.cstate_pstate.cstate_exit_ns, 37862d591a8SYue Hin Lau refclk_mhz, 0x1fffff); 37962d591a8SYue Hin Lau REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C, prog_wm_value); 3801296423bSBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_C calculated =%d\n" 38162d591a8SYue Hin Lau "HW register value = 0x%x\n", 38262d591a8SYue Hin Lau watermarks->c.cstate_pstate.cstate_exit_ns, prog_wm_value); 38362d591a8SYue Hin Lau } 384d7b539d3SDmytro Laktyushkin } 38562d591a8SYue Hin Lau 386d7b539d3SDmytro Laktyushkin if (safe_to_lower || watermarks->c.cstate_pstate.pstate_change_ns 387d7b539d3SDmytro Laktyushkin > hubbub->watermarks.c.cstate_pstate.pstate_change_ns) { 388d7b539d3SDmytro Laktyushkin hubbub->watermarks.c.cstate_pstate.pstate_change_ns = 389d7b539d3SDmytro Laktyushkin watermarks->c.cstate_pstate.pstate_change_ns; 39062d591a8SYue Hin Lau prog_wm_value = convert_and_clamp( 39162d591a8SYue Hin Lau watermarks->c.cstate_pstate.pstate_change_ns, 39262d591a8SYue Hin Lau refclk_mhz, 0x1fffff); 39362d591a8SYue Hin Lau REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C, prog_wm_value); 394d7b539d3SDmytro Laktyushkin DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_C calculated =%d\n" 395d7b539d3SDmytro Laktyushkin "HW register value = 0x%x\n\n", 39662d591a8SYue Hin Lau watermarks->c.cstate_pstate.pstate_change_ns, prog_wm_value); 397d7b539d3SDmytro Laktyushkin } 39862d591a8SYue Hin Lau 39962d591a8SYue Hin Lau /* clock state D */ 400d7b539d3SDmytro Laktyushkin if (safe_to_lower || watermarks->d.urgent_ns > hubbub->watermarks.d.urgent_ns) { 401d7b539d3SDmytro Laktyushkin hubbub->watermarks.d.urgent_ns = watermarks->d.urgent_ns; 402d7b539d3SDmytro Laktyushkin prog_wm_value = convert_and_clamp(watermarks->d.urgent_ns, 403d7b539d3SDmytro Laktyushkin refclk_mhz, 0x1fffff); 40462d591a8SYue Hin Lau REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, prog_wm_value); 405d7b539d3SDmytro Laktyushkin 4061296423bSBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_D calculated =%d\n" 40762d591a8SYue Hin Lau "HW register value = 0x%x\n", 40862d591a8SYue Hin Lau watermarks->d.urgent_ns, prog_wm_value); 409d7b539d3SDmytro Laktyushkin } 41062d591a8SYue Hin Lau 411d7b539d3SDmytro Laktyushkin if (safe_to_lower || watermarks->d.pte_meta_urgent_ns > hubbub->watermarks.d.pte_meta_urgent_ns) { 412d7b539d3SDmytro Laktyushkin hubbub->watermarks.d.pte_meta_urgent_ns = watermarks->d.pte_meta_urgent_ns; 413d7b539d3SDmytro Laktyushkin prog_wm_value = convert_and_clamp(watermarks->d.pte_meta_urgent_ns, 41462d591a8SYue Hin Lau refclk_mhz, 0x1fffff); 41562d591a8SYue Hin Lau REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_D, prog_wm_value); 4161296423bSBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("PTE_META_URGENCY_WATERMARK_D calculated =%d\n" 41762d591a8SYue Hin Lau "HW register value = 0x%x\n", 41862d591a8SYue Hin Lau watermarks->d.pte_meta_urgent_ns, prog_wm_value); 419d7b539d3SDmytro Laktyushkin } 42062d591a8SYue Hin Lau 42162d591a8SYue Hin Lau if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D)) { 422d7b539d3SDmytro Laktyushkin if (safe_to_lower || watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns 423d7b539d3SDmytro Laktyushkin > hubbub->watermarks.d.cstate_pstate.cstate_enter_plus_exit_ns) { 424d7b539d3SDmytro Laktyushkin hubbub->watermarks.d.cstate_pstate.cstate_enter_plus_exit_ns = 425d7b539d3SDmytro Laktyushkin watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns; 42662d591a8SYue Hin Lau prog_wm_value = convert_and_clamp( 42762d591a8SYue Hin Lau watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns, 42862d591a8SYue Hin Lau refclk_mhz, 0x1fffff); 42962d591a8SYue Hin Lau REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, prog_wm_value); 430d7b539d3SDmytro Laktyushkin DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_D calculated =%d\n" 43162d591a8SYue Hin Lau "HW register value = 0x%x\n", 43262d591a8SYue Hin Lau watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value); 433d7b539d3SDmytro Laktyushkin } 43462d591a8SYue Hin Lau 435d7b539d3SDmytro Laktyushkin if (safe_to_lower || watermarks->d.cstate_pstate.cstate_exit_ns 436d7b539d3SDmytro Laktyushkin > hubbub->watermarks.d.cstate_pstate.cstate_exit_ns) { 437d7b539d3SDmytro Laktyushkin hubbub->watermarks.d.cstate_pstate.cstate_exit_ns = 438d7b539d3SDmytro Laktyushkin watermarks->d.cstate_pstate.cstate_exit_ns; 43962d591a8SYue Hin Lau prog_wm_value = convert_and_clamp( 44062d591a8SYue Hin Lau watermarks->d.cstate_pstate.cstate_exit_ns, 44162d591a8SYue Hin Lau refclk_mhz, 0x1fffff); 44262d591a8SYue Hin Lau REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D, prog_wm_value); 4431296423bSBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_D calculated =%d\n" 44462d591a8SYue Hin Lau "HW register value = 0x%x\n", 44562d591a8SYue Hin Lau watermarks->d.cstate_pstate.cstate_exit_ns, prog_wm_value); 44662d591a8SYue Hin Lau } 447d7b539d3SDmytro Laktyushkin } 44862d591a8SYue Hin Lau 449d7b539d3SDmytro Laktyushkin if (safe_to_lower || watermarks->d.cstate_pstate.pstate_change_ns 450d7b539d3SDmytro Laktyushkin > hubbub->watermarks.d.cstate_pstate.pstate_change_ns) { 451d7b539d3SDmytro Laktyushkin hubbub->watermarks.d.cstate_pstate.pstate_change_ns = 452d7b539d3SDmytro Laktyushkin watermarks->d.cstate_pstate.pstate_change_ns; 45362d591a8SYue Hin Lau prog_wm_value = convert_and_clamp( 45462d591a8SYue Hin Lau watermarks->d.cstate_pstate.pstate_change_ns, 45562d591a8SYue Hin Lau refclk_mhz, 0x1fffff); 45662d591a8SYue Hin Lau REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D, prog_wm_value); 4571296423bSBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_D calculated =%d\n" 45862d591a8SYue Hin Lau "HW register value = 0x%x\n\n", 45962d591a8SYue Hin Lau watermarks->d.cstate_pstate.pstate_change_ns, prog_wm_value); 460d7b539d3SDmytro Laktyushkin } 46162d591a8SYue Hin Lau 46262d591a8SYue Hin Lau REG_UPDATE(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL, 46362d591a8SYue Hin Lau DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, 1); 46462d591a8SYue Hin Lau 46562d591a8SYue Hin Lau REG_UPDATE(DCHUBBUB_ARB_SAT_LEVEL, 46662d591a8SYue Hin Lau DCHUBBUB_ARB_SAT_LEVEL, 60 * refclk_mhz); 46762d591a8SYue Hin Lau REG_UPDATE(DCHUBBUB_ARB_DF_REQ_OUTSTAND, 46862d591a8SYue Hin Lau DCHUBBUB_ARB_MIN_REQ_OUTSTAND, 68); 46962d591a8SYue Hin Lau 47062d591a8SYue Hin Lau REG_UPDATE_2(DCHUBBUB_ARB_DRAM_STATE_CNTL, 47162d591a8SYue Hin Lau DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_VALUE, 0, 47262d591a8SYue Hin Lau DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_ENABLE, force_en); 47362d591a8SYue Hin Lau 47462d591a8SYue Hin Lau #if 0 47562d591a8SYue Hin Lau REG_UPDATE_2(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL, 47662d591a8SYue Hin Lau DCHUBBUB_ARB_WATERMARK_CHANGE_DONE_INTERRUPT_DISABLE, 1, 47762d591a8SYue Hin Lau DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, 1); 47862d591a8SYue Hin Lau #endif 47962d591a8SYue Hin Lau } 48062d591a8SYue Hin Lau 481c9ef081dSYue Hin Lau void hubbub1_update_dchub( 482c9ef081dSYue Hin Lau struct hubbub *hubbub, 48362d591a8SYue Hin Lau struct dchub_init_data *dh_data) 48462d591a8SYue Hin Lau { 48562d591a8SYue Hin Lau /* TODO: port code from dal2 */ 48662d591a8SYue Hin Lau switch (dh_data->fb_mode) { 48762d591a8SYue Hin Lau case FRAME_BUFFER_MODE_ZFB_ONLY: 48862d591a8SYue Hin Lau /*For ZFB case need to put DCHUB FB BASE and TOP upside down to indicate ZFB mode*/ 48962d591a8SYue Hin Lau REG_UPDATE(DCHUBBUB_SDPIF_FB_TOP, 49062d591a8SYue Hin Lau SDPIF_FB_TOP, 0); 49162d591a8SYue Hin Lau 49262d591a8SYue Hin Lau REG_UPDATE(DCHUBBUB_SDPIF_FB_BASE, 49362d591a8SYue Hin Lau SDPIF_FB_BASE, 0x0FFFF); 49462d591a8SYue Hin Lau 49562d591a8SYue Hin Lau REG_UPDATE(DCHUBBUB_SDPIF_AGP_BASE, 49662d591a8SYue Hin Lau SDPIF_AGP_BASE, dh_data->zfb_phys_addr_base >> 22); 49762d591a8SYue Hin Lau 49862d591a8SYue Hin Lau REG_UPDATE(DCHUBBUB_SDPIF_AGP_BOT, 49962d591a8SYue Hin Lau SDPIF_AGP_BOT, dh_data->zfb_mc_base_addr >> 22); 50062d591a8SYue Hin Lau 50162d591a8SYue Hin Lau REG_UPDATE(DCHUBBUB_SDPIF_AGP_TOP, 50262d591a8SYue Hin Lau SDPIF_AGP_TOP, (dh_data->zfb_mc_base_addr + 50362d591a8SYue Hin Lau dh_data->zfb_size_in_byte - 1) >> 22); 50462d591a8SYue Hin Lau break; 50562d591a8SYue Hin Lau case FRAME_BUFFER_MODE_MIXED_ZFB_AND_LOCAL: 50662d591a8SYue Hin Lau /*Should not touch FB LOCATION (done by VBIOS on AsicInit table)*/ 50762d591a8SYue Hin Lau 50862d591a8SYue Hin Lau REG_UPDATE(DCHUBBUB_SDPIF_AGP_BASE, 50962d591a8SYue Hin Lau SDPIF_AGP_BASE, dh_data->zfb_phys_addr_base >> 22); 51062d591a8SYue Hin Lau 51162d591a8SYue Hin Lau REG_UPDATE(DCHUBBUB_SDPIF_AGP_BOT, 51262d591a8SYue Hin Lau SDPIF_AGP_BOT, dh_data->zfb_mc_base_addr >> 22); 51362d591a8SYue Hin Lau 51462d591a8SYue Hin Lau REG_UPDATE(DCHUBBUB_SDPIF_AGP_TOP, 51562d591a8SYue Hin Lau SDPIF_AGP_TOP, (dh_data->zfb_mc_base_addr + 51662d591a8SYue Hin Lau dh_data->zfb_size_in_byte - 1) >> 22); 51762d591a8SYue Hin Lau break; 51862d591a8SYue Hin Lau case FRAME_BUFFER_MODE_LOCAL_ONLY: 51962d591a8SYue Hin Lau /*Should not touch FB LOCATION (done by VBIOS on AsicInit table)*/ 52062d591a8SYue Hin Lau REG_UPDATE(DCHUBBUB_SDPIF_AGP_BASE, 52162d591a8SYue Hin Lau SDPIF_AGP_BASE, 0); 52262d591a8SYue Hin Lau 52362d591a8SYue Hin Lau REG_UPDATE(DCHUBBUB_SDPIF_AGP_BOT, 52462d591a8SYue Hin Lau SDPIF_AGP_BOT, 0X03FFFF); 52562d591a8SYue Hin Lau 52662d591a8SYue Hin Lau REG_UPDATE(DCHUBBUB_SDPIF_AGP_TOP, 52762d591a8SYue Hin Lau SDPIF_AGP_TOP, 0); 52862d591a8SYue Hin Lau break; 52962d591a8SYue Hin Lau default: 53062d591a8SYue Hin Lau break; 53162d591a8SYue Hin Lau } 53262d591a8SYue Hin Lau 53362d591a8SYue Hin Lau dh_data->dchub_initialzied = true; 53462d591a8SYue Hin Lau dh_data->dchub_info_valid = false; 53562d591a8SYue Hin Lau } 53662d591a8SYue Hin Lau 537ea00f297SYue Hin Lau void hubbub1_toggle_watermark_change_req(struct hubbub *hubbub) 53862d591a8SYue Hin Lau { 53962d591a8SYue Hin Lau uint32_t watermark_change_req; 54062d591a8SYue Hin Lau 54162d591a8SYue Hin Lau REG_GET(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL, 54262d591a8SYue Hin Lau DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, &watermark_change_req); 54362d591a8SYue Hin Lau 54462d591a8SYue Hin Lau if (watermark_change_req) 54562d591a8SYue Hin Lau watermark_change_req = 0; 54662d591a8SYue Hin Lau else 54762d591a8SYue Hin Lau watermark_change_req = 1; 54862d591a8SYue Hin Lau 54962d591a8SYue Hin Lau REG_UPDATE(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL, 55062d591a8SYue Hin Lau DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, watermark_change_req); 55162d591a8SYue Hin Lau } 55262d591a8SYue Hin Lau 5533ba43a59SCharlene Liu void hubbub1_soft_reset(struct hubbub *hubbub, bool reset) 5543ba43a59SCharlene Liu { 5553ba43a59SCharlene Liu uint32_t reset_en = reset ? 1 : 0; 5563ba43a59SCharlene Liu 5573ba43a59SCharlene Liu REG_UPDATE(DCHUBBUB_SOFT_RESET, 5583ba43a59SCharlene Liu DCHUBBUB_GLOBAL_SOFT_RESET, reset_en); 5593ba43a59SCharlene Liu } 5603ba43a59SCharlene Liu 5615ebfb7a5SEric Bernstein static bool hubbub1_dcc_support_swizzle( 5625ebfb7a5SEric Bernstein enum swizzle_mode_values swizzle, 5635ebfb7a5SEric Bernstein unsigned int bytes_per_element, 5645ebfb7a5SEric Bernstein enum segment_order *segment_order_horz, 5655ebfb7a5SEric Bernstein enum segment_order *segment_order_vert) 5665ebfb7a5SEric Bernstein { 5675ebfb7a5SEric Bernstein bool standard_swizzle = false; 5685ebfb7a5SEric Bernstein bool display_swizzle = false; 5695ebfb7a5SEric Bernstein 5705ebfb7a5SEric Bernstein switch (swizzle) { 5715ebfb7a5SEric Bernstein case DC_SW_4KB_S: 5725ebfb7a5SEric Bernstein case DC_SW_64KB_S: 5735ebfb7a5SEric Bernstein case DC_SW_VAR_S: 5745ebfb7a5SEric Bernstein case DC_SW_4KB_S_X: 5755ebfb7a5SEric Bernstein case DC_SW_64KB_S_X: 5765ebfb7a5SEric Bernstein case DC_SW_VAR_S_X: 5775ebfb7a5SEric Bernstein standard_swizzle = true; 5785ebfb7a5SEric Bernstein break; 5795ebfb7a5SEric Bernstein case DC_SW_4KB_D: 5805ebfb7a5SEric Bernstein case DC_SW_64KB_D: 5815ebfb7a5SEric Bernstein case DC_SW_VAR_D: 5825ebfb7a5SEric Bernstein case DC_SW_4KB_D_X: 5835ebfb7a5SEric Bernstein case DC_SW_64KB_D_X: 5845ebfb7a5SEric Bernstein case DC_SW_VAR_D_X: 5855ebfb7a5SEric Bernstein display_swizzle = true; 5865ebfb7a5SEric Bernstein break; 5875ebfb7a5SEric Bernstein default: 5885ebfb7a5SEric Bernstein break; 5895ebfb7a5SEric Bernstein } 5905ebfb7a5SEric Bernstein 5915ebfb7a5SEric Bernstein if (bytes_per_element == 1 && standard_swizzle) { 5925ebfb7a5SEric Bernstein *segment_order_horz = segment_order__contiguous; 5935ebfb7a5SEric Bernstein *segment_order_vert = segment_order__na; 5945ebfb7a5SEric Bernstein return true; 5955ebfb7a5SEric Bernstein } 5965ebfb7a5SEric Bernstein if (bytes_per_element == 2 && standard_swizzle) { 5975ebfb7a5SEric Bernstein *segment_order_horz = segment_order__non_contiguous; 5985ebfb7a5SEric Bernstein *segment_order_vert = segment_order__contiguous; 5995ebfb7a5SEric Bernstein return true; 6005ebfb7a5SEric Bernstein } 6015ebfb7a5SEric Bernstein if (bytes_per_element == 4 && standard_swizzle) { 6025ebfb7a5SEric Bernstein *segment_order_horz = segment_order__non_contiguous; 6035ebfb7a5SEric Bernstein *segment_order_vert = segment_order__contiguous; 6045ebfb7a5SEric Bernstein return true; 6055ebfb7a5SEric Bernstein } 6065ebfb7a5SEric Bernstein if (bytes_per_element == 8 && standard_swizzle) { 6075ebfb7a5SEric Bernstein *segment_order_horz = segment_order__na; 6085ebfb7a5SEric Bernstein *segment_order_vert = segment_order__contiguous; 6095ebfb7a5SEric Bernstein return true; 6105ebfb7a5SEric Bernstein } 6115ebfb7a5SEric Bernstein if (bytes_per_element == 8 && display_swizzle) { 6125ebfb7a5SEric Bernstein *segment_order_horz = segment_order__contiguous; 6135ebfb7a5SEric Bernstein *segment_order_vert = segment_order__non_contiguous; 6145ebfb7a5SEric Bernstein return true; 6155ebfb7a5SEric Bernstein } 6165ebfb7a5SEric Bernstein 6175ebfb7a5SEric Bernstein return false; 6185ebfb7a5SEric Bernstein } 6195ebfb7a5SEric Bernstein 6205ebfb7a5SEric Bernstein static bool hubbub1_dcc_support_pixel_format( 6215ebfb7a5SEric Bernstein enum surface_pixel_format format, 6225ebfb7a5SEric Bernstein unsigned int *bytes_per_element) 6235ebfb7a5SEric Bernstein { 6245ebfb7a5SEric Bernstein /* DML: get_bytes_per_element */ 6255ebfb7a5SEric Bernstein switch (format) { 6265ebfb7a5SEric Bernstein case SURFACE_PIXEL_FORMAT_GRPH_ARGB1555: 6275ebfb7a5SEric Bernstein case SURFACE_PIXEL_FORMAT_GRPH_RGB565: 6285ebfb7a5SEric Bernstein *bytes_per_element = 2; 6295ebfb7a5SEric Bernstein return true; 6305ebfb7a5SEric Bernstein case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888: 6315ebfb7a5SEric Bernstein case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888: 6325ebfb7a5SEric Bernstein case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010: 6335ebfb7a5SEric Bernstein case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010: 6345ebfb7a5SEric Bernstein *bytes_per_element = 4; 6355ebfb7a5SEric Bernstein return true; 6365ebfb7a5SEric Bernstein case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616: 6375ebfb7a5SEric Bernstein case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F: 6385ebfb7a5SEric Bernstein case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F: 6395ebfb7a5SEric Bernstein *bytes_per_element = 8; 6405ebfb7a5SEric Bernstein return true; 6415ebfb7a5SEric Bernstein default: 6425ebfb7a5SEric Bernstein return false; 6435ebfb7a5SEric Bernstein } 6445ebfb7a5SEric Bernstein } 6455ebfb7a5SEric Bernstein 6465ebfb7a5SEric Bernstein static void hubbub1_get_blk256_size(unsigned int *blk256_width, unsigned int *blk256_height, 6475ebfb7a5SEric Bernstein unsigned int bytes_per_element) 6485ebfb7a5SEric Bernstein { 6495ebfb7a5SEric Bernstein /* copied from DML. might want to refactor DML to leverage from DML */ 6505ebfb7a5SEric Bernstein /* DML : get_blk256_size */ 6515ebfb7a5SEric Bernstein if (bytes_per_element == 1) { 6525ebfb7a5SEric Bernstein *blk256_width = 16; 6535ebfb7a5SEric Bernstein *blk256_height = 16; 6545ebfb7a5SEric Bernstein } else if (bytes_per_element == 2) { 6555ebfb7a5SEric Bernstein *blk256_width = 16; 6565ebfb7a5SEric Bernstein *blk256_height = 8; 6575ebfb7a5SEric Bernstein } else if (bytes_per_element == 4) { 6585ebfb7a5SEric Bernstein *blk256_width = 8; 6595ebfb7a5SEric Bernstein *blk256_height = 8; 6605ebfb7a5SEric Bernstein } else if (bytes_per_element == 8) { 6615ebfb7a5SEric Bernstein *blk256_width = 8; 6625ebfb7a5SEric Bernstein *blk256_height = 4; 6635ebfb7a5SEric Bernstein } 6645ebfb7a5SEric Bernstein } 6655ebfb7a5SEric Bernstein 6665ebfb7a5SEric Bernstein static void hubbub1_det_request_size( 6675ebfb7a5SEric Bernstein unsigned int height, 6685ebfb7a5SEric Bernstein unsigned int width, 6695ebfb7a5SEric Bernstein unsigned int bpe, 6705ebfb7a5SEric Bernstein bool *req128_horz_wc, 6715ebfb7a5SEric Bernstein bool *req128_vert_wc) 6725ebfb7a5SEric Bernstein { 6735ebfb7a5SEric Bernstein unsigned int detile_buf_size = 164 * 1024; /* 164KB for DCN1.0 */ 6745ebfb7a5SEric Bernstein 6755ebfb7a5SEric Bernstein unsigned int blk256_height = 0; 6765ebfb7a5SEric Bernstein unsigned int blk256_width = 0; 6775ebfb7a5SEric Bernstein unsigned int swath_bytes_horz_wc, swath_bytes_vert_wc; 6785ebfb7a5SEric Bernstein 6795ebfb7a5SEric Bernstein hubbub1_get_blk256_size(&blk256_width, &blk256_height, bpe); 6805ebfb7a5SEric Bernstein 6815ebfb7a5SEric Bernstein swath_bytes_horz_wc = height * blk256_height * bpe; 6825ebfb7a5SEric Bernstein swath_bytes_vert_wc = width * blk256_width * bpe; 6835ebfb7a5SEric Bernstein 6845ebfb7a5SEric Bernstein *req128_horz_wc = (2 * swath_bytes_horz_wc <= detile_buf_size) ? 6855ebfb7a5SEric Bernstein false : /* full 256B request */ 6865ebfb7a5SEric Bernstein true; /* half 128b request */ 6875ebfb7a5SEric Bernstein 6885ebfb7a5SEric Bernstein *req128_vert_wc = (2 * swath_bytes_vert_wc <= detile_buf_size) ? 6895ebfb7a5SEric Bernstein false : /* full 256B request */ 6905ebfb7a5SEric Bernstein true; /* half 128b request */ 6915ebfb7a5SEric Bernstein } 6925ebfb7a5SEric Bernstein 6935ebfb7a5SEric Bernstein static bool hubbub1_get_dcc_compression_cap(struct hubbub *hubbub, 6945ebfb7a5SEric Bernstein const struct dc_dcc_surface_param *input, 6955ebfb7a5SEric Bernstein struct dc_surface_dcc_cap *output) 6965ebfb7a5SEric Bernstein { 6975ebfb7a5SEric Bernstein struct dc *dc = hubbub->ctx->dc; 6985ebfb7a5SEric Bernstein /* implement section 1.6.2.1 of DCN1_Programming_Guide.docx */ 6995ebfb7a5SEric Bernstein enum dcc_control dcc_control; 7005ebfb7a5SEric Bernstein unsigned int bpe; 7015ebfb7a5SEric Bernstein enum segment_order segment_order_horz, segment_order_vert; 7025ebfb7a5SEric Bernstein bool req128_horz_wc, req128_vert_wc; 7035ebfb7a5SEric Bernstein 7045ebfb7a5SEric Bernstein memset(output, 0, sizeof(*output)); 7055ebfb7a5SEric Bernstein 7065ebfb7a5SEric Bernstein if (dc->debug.disable_dcc == DCC_DISABLE) 7075ebfb7a5SEric Bernstein return false; 7085ebfb7a5SEric Bernstein 7095ebfb7a5SEric Bernstein if (!hubbub->funcs->dcc_support_pixel_format(input->format, &bpe)) 7105ebfb7a5SEric Bernstein return false; 7115ebfb7a5SEric Bernstein 7125ebfb7a5SEric Bernstein if (!hubbub->funcs->dcc_support_swizzle(input->swizzle_mode, bpe, 7135ebfb7a5SEric Bernstein &segment_order_horz, &segment_order_vert)) 7145ebfb7a5SEric Bernstein return false; 7155ebfb7a5SEric Bernstein 7165ebfb7a5SEric Bernstein hubbub1_det_request_size(input->surface_size.height, input->surface_size.width, 7175ebfb7a5SEric Bernstein bpe, &req128_horz_wc, &req128_vert_wc); 7185ebfb7a5SEric Bernstein 7195ebfb7a5SEric Bernstein if (!req128_horz_wc && !req128_vert_wc) { 7205ebfb7a5SEric Bernstein dcc_control = dcc_control__256_256_xxx; 7215ebfb7a5SEric Bernstein } else if (input->scan == SCAN_DIRECTION_HORIZONTAL) { 7225ebfb7a5SEric Bernstein if (!req128_horz_wc) 7235ebfb7a5SEric Bernstein dcc_control = dcc_control__256_256_xxx; 7245ebfb7a5SEric Bernstein else if (segment_order_horz == segment_order__contiguous) 7255ebfb7a5SEric Bernstein dcc_control = dcc_control__128_128_xxx; 7265ebfb7a5SEric Bernstein else 7275ebfb7a5SEric Bernstein dcc_control = dcc_control__256_64_64; 7285ebfb7a5SEric Bernstein } else if (input->scan == SCAN_DIRECTION_VERTICAL) { 7295ebfb7a5SEric Bernstein if (!req128_vert_wc) 7305ebfb7a5SEric Bernstein dcc_control = dcc_control__256_256_xxx; 7315ebfb7a5SEric Bernstein else if (segment_order_vert == segment_order__contiguous) 7325ebfb7a5SEric Bernstein dcc_control = dcc_control__128_128_xxx; 7335ebfb7a5SEric Bernstein else 7345ebfb7a5SEric Bernstein dcc_control = dcc_control__256_64_64; 7355ebfb7a5SEric Bernstein } else { 7365ebfb7a5SEric Bernstein if ((req128_horz_wc && 7375ebfb7a5SEric Bernstein segment_order_horz == segment_order__non_contiguous) || 7385ebfb7a5SEric Bernstein (req128_vert_wc && 7395ebfb7a5SEric Bernstein segment_order_vert == segment_order__non_contiguous)) 7405ebfb7a5SEric Bernstein /* access_dir not known, must use most constraining */ 7415ebfb7a5SEric Bernstein dcc_control = dcc_control__256_64_64; 7425ebfb7a5SEric Bernstein else 7435ebfb7a5SEric Bernstein /* reg128 is true for either horz and vert 7445ebfb7a5SEric Bernstein * but segment_order is contiguous 7455ebfb7a5SEric Bernstein */ 7465ebfb7a5SEric Bernstein dcc_control = dcc_control__128_128_xxx; 7475ebfb7a5SEric Bernstein } 7485ebfb7a5SEric Bernstein 7495ebfb7a5SEric Bernstein if (dc->debug.disable_dcc == DCC_HALF_REQ_DISALBE && 7505ebfb7a5SEric Bernstein dcc_control != dcc_control__256_256_xxx) 7515ebfb7a5SEric Bernstein return false; 7525ebfb7a5SEric Bernstein 7535ebfb7a5SEric Bernstein switch (dcc_control) { 7545ebfb7a5SEric Bernstein case dcc_control__256_256_xxx: 7555ebfb7a5SEric Bernstein output->grph.rgb.max_uncompressed_blk_size = 256; 7565ebfb7a5SEric Bernstein output->grph.rgb.max_compressed_blk_size = 256; 7575ebfb7a5SEric Bernstein output->grph.rgb.independent_64b_blks = false; 7585ebfb7a5SEric Bernstein break; 7595ebfb7a5SEric Bernstein case dcc_control__128_128_xxx: 7605ebfb7a5SEric Bernstein output->grph.rgb.max_uncompressed_blk_size = 128; 7615ebfb7a5SEric Bernstein output->grph.rgb.max_compressed_blk_size = 128; 7625ebfb7a5SEric Bernstein output->grph.rgb.independent_64b_blks = false; 7635ebfb7a5SEric Bernstein break; 7645ebfb7a5SEric Bernstein case dcc_control__256_64_64: 7655ebfb7a5SEric Bernstein output->grph.rgb.max_uncompressed_blk_size = 256; 7665ebfb7a5SEric Bernstein output->grph.rgb.max_compressed_blk_size = 64; 7675ebfb7a5SEric Bernstein output->grph.rgb.independent_64b_blks = true; 7685ebfb7a5SEric Bernstein break; 7695ebfb7a5SEric Bernstein } 7705ebfb7a5SEric Bernstein 7715ebfb7a5SEric Bernstein output->capable = true; 7725ebfb7a5SEric Bernstein output->const_color_support = false; 7735ebfb7a5SEric Bernstein 7745ebfb7a5SEric Bernstein return true; 7755ebfb7a5SEric Bernstein } 7765ebfb7a5SEric Bernstein 777c9ef081dSYue Hin Lau static const struct hubbub_funcs hubbub1_funcs = { 7785ebfb7a5SEric Bernstein .update_dchub = hubbub1_update_dchub, 7795ebfb7a5SEric Bernstein .dcc_support_swizzle = hubbub1_dcc_support_swizzle, 7805ebfb7a5SEric Bernstein .dcc_support_pixel_format = hubbub1_dcc_support_pixel_format, 7815ebfb7a5SEric Bernstein .get_dcc_compression_cap = hubbub1_get_dcc_compression_cap, 782c9ef081dSYue Hin Lau }; 783c9ef081dSYue Hin Lau 784c9ef081dSYue Hin Lau void hubbub1_construct(struct hubbub *hubbub, 785c9ef081dSYue Hin Lau struct dc_context *ctx, 786c9ef081dSYue Hin Lau const struct dcn_hubbub_registers *hubbub_regs, 787c9ef081dSYue Hin Lau const struct dcn_hubbub_shift *hubbub_shift, 788c9ef081dSYue Hin Lau const struct dcn_hubbub_mask *hubbub_mask) 789c9ef081dSYue Hin Lau { 790c9ef081dSYue Hin Lau hubbub->ctx = ctx; 791c9ef081dSYue Hin Lau 792c9ef081dSYue Hin Lau hubbub->funcs = &hubbub1_funcs; 793c9ef081dSYue Hin Lau 794c9ef081dSYue Hin Lau hubbub->regs = hubbub_regs; 795c9ef081dSYue Hin Lau hubbub->shifts = hubbub_shift; 796c9ef081dSYue Hin Lau hubbub->masks = hubbub_mask; 797c9ef081dSYue Hin Lau 798cf1df90fSHersen Wu hubbub->debug_test_index_pstate = 0x7; 799c9ef081dSYue Hin Lau } 80062d591a8SYue Hin Lau 801