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 1937144d3cfSDmytro Laktyushkin void hubbub1_wm_change_req_wa(struct hubbub *hubbub) 1947144d3cfSDmytro Laktyushkin { 1957144d3cfSDmytro Laktyushkin REG_UPDATE_SEQ(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL, 1967144d3cfSDmytro Laktyushkin DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, 0, 1); 1977144d3cfSDmytro Laktyushkin } 1987144d3cfSDmytro Laktyushkin 199ea00f297SYue Hin Lau void hubbub1_program_watermarks( 200c9ef081dSYue Hin Lau struct hubbub *hubbub, 20162d591a8SYue Hin Lau struct dcn_watermark_set *watermarks, 202d7b539d3SDmytro Laktyushkin unsigned int refclk_mhz, 203d7b539d3SDmytro Laktyushkin bool safe_to_lower) 20462d591a8SYue Hin Lau { 205c9ef081dSYue Hin Lau uint32_t force_en = hubbub->ctx->dc->debug.disable_stutter ? 1 : 0; 20662d591a8SYue Hin Lau /* 20762d591a8SYue Hin Lau * Need to clamp to max of the register values (i.e. no wrap) 20862d591a8SYue Hin Lau * for dcn1, all wm registers are 21-bit wide 20962d591a8SYue Hin Lau */ 21062d591a8SYue Hin Lau uint32_t prog_wm_value; 21162d591a8SYue Hin Lau 21262d591a8SYue Hin Lau 21362d591a8SYue Hin Lau /* Repeat for water mark set A, B, C and D. */ 21462d591a8SYue Hin Lau /* clock state A */ 215d7b539d3SDmytro Laktyushkin if (safe_to_lower || watermarks->a.urgent_ns > hubbub->watermarks.a.urgent_ns) { 216d7b539d3SDmytro Laktyushkin hubbub->watermarks.a.urgent_ns = watermarks->a.urgent_ns; 21762d591a8SYue Hin Lau prog_wm_value = convert_and_clamp(watermarks->a.urgent_ns, 21862d591a8SYue Hin Lau refclk_mhz, 0x1fffff); 21962d591a8SYue Hin Lau REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, prog_wm_value); 22062d591a8SYue Hin Lau 2211296423bSBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_A calculated =%d\n" 22262d591a8SYue Hin Lau "HW register value = 0x%x\n", 22362d591a8SYue Hin Lau watermarks->a.urgent_ns, prog_wm_value); 224d7b539d3SDmytro Laktyushkin } 22562d591a8SYue Hin Lau 226d7b539d3SDmytro Laktyushkin if (safe_to_lower || watermarks->a.pte_meta_urgent_ns > hubbub->watermarks.a.pte_meta_urgent_ns) { 227d7b539d3SDmytro Laktyushkin hubbub->watermarks.a.pte_meta_urgent_ns = watermarks->a.pte_meta_urgent_ns; 22862d591a8SYue Hin Lau prog_wm_value = convert_and_clamp(watermarks->a.pte_meta_urgent_ns, 22962d591a8SYue Hin Lau refclk_mhz, 0x1fffff); 23062d591a8SYue Hin Lau REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_A, prog_wm_value); 2311296423bSBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("PTE_META_URGENCY_WATERMARK_A calculated =%d\n" 23262d591a8SYue Hin Lau "HW register value = 0x%x\n", 23362d591a8SYue Hin Lau watermarks->a.pte_meta_urgent_ns, prog_wm_value); 234d7b539d3SDmytro Laktyushkin } 23562d591a8SYue Hin Lau 23662d591a8SYue Hin Lau if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A)) { 237d7b539d3SDmytro Laktyushkin if (safe_to_lower || watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns 238d7b539d3SDmytro Laktyushkin > hubbub->watermarks.a.cstate_pstate.cstate_enter_plus_exit_ns) { 239d7b539d3SDmytro Laktyushkin hubbub->watermarks.a.cstate_pstate.cstate_enter_plus_exit_ns = 240d7b539d3SDmytro Laktyushkin watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns; 24162d591a8SYue Hin Lau prog_wm_value = convert_and_clamp( 24262d591a8SYue Hin Lau watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns, 24362d591a8SYue Hin Lau refclk_mhz, 0x1fffff); 24462d591a8SYue Hin Lau REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A, prog_wm_value); 2451296423bSBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_A calculated =%d\n" 24662d591a8SYue Hin Lau "HW register value = 0x%x\n", 24762d591a8SYue Hin Lau watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value); 248d7b539d3SDmytro Laktyushkin } 24962d591a8SYue Hin Lau 250d7b539d3SDmytro Laktyushkin if (safe_to_lower || watermarks->a.cstate_pstate.cstate_exit_ns 251d7b539d3SDmytro Laktyushkin > hubbub->watermarks.a.cstate_pstate.cstate_exit_ns) { 252d7b539d3SDmytro Laktyushkin hubbub->watermarks.a.cstate_pstate.cstate_exit_ns = 253d7b539d3SDmytro Laktyushkin watermarks->a.cstate_pstate.cstate_exit_ns; 25462d591a8SYue Hin Lau prog_wm_value = convert_and_clamp( 25562d591a8SYue Hin Lau watermarks->a.cstate_pstate.cstate_exit_ns, 25662d591a8SYue Hin Lau refclk_mhz, 0x1fffff); 25762d591a8SYue Hin Lau REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A, prog_wm_value); 2581296423bSBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_A calculated =%d\n" 25962d591a8SYue Hin Lau "HW register value = 0x%x\n", 26062d591a8SYue Hin Lau watermarks->a.cstate_pstate.cstate_exit_ns, prog_wm_value); 26162d591a8SYue Hin Lau } 262d7b539d3SDmytro Laktyushkin } 26362d591a8SYue Hin Lau 264d7b539d3SDmytro Laktyushkin if (safe_to_lower || watermarks->a.cstate_pstate.pstate_change_ns 265d7b539d3SDmytro Laktyushkin > hubbub->watermarks.a.cstate_pstate.pstate_change_ns) { 266d7b539d3SDmytro Laktyushkin hubbub->watermarks.a.cstate_pstate.pstate_change_ns = 267d7b539d3SDmytro Laktyushkin watermarks->a.cstate_pstate.pstate_change_ns; 26862d591a8SYue Hin Lau prog_wm_value = convert_and_clamp( 26962d591a8SYue Hin Lau watermarks->a.cstate_pstate.pstate_change_ns, 27062d591a8SYue Hin Lau refclk_mhz, 0x1fffff); 27162d591a8SYue Hin Lau REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A, prog_wm_value); 2721296423bSBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_A calculated =%d\n" 27362d591a8SYue Hin Lau "HW register value = 0x%x\n\n", 27462d591a8SYue Hin Lau watermarks->a.cstate_pstate.pstate_change_ns, prog_wm_value); 275d7b539d3SDmytro Laktyushkin } 27662d591a8SYue Hin Lau 27762d591a8SYue Hin Lau /* clock state B */ 278d7b539d3SDmytro Laktyushkin if (safe_to_lower || watermarks->b.urgent_ns > hubbub->watermarks.b.urgent_ns) { 279d7b539d3SDmytro Laktyushkin hubbub->watermarks.b.urgent_ns = watermarks->b.urgent_ns; 280d7b539d3SDmytro Laktyushkin prog_wm_value = convert_and_clamp(watermarks->b.urgent_ns, 281d7b539d3SDmytro Laktyushkin refclk_mhz, 0x1fffff); 28262d591a8SYue Hin Lau REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, prog_wm_value); 283d7b539d3SDmytro Laktyushkin 2841296423bSBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_B calculated =%d\n" 28562d591a8SYue Hin Lau "HW register value = 0x%x\n", 28662d591a8SYue Hin Lau watermarks->b.urgent_ns, prog_wm_value); 287d7b539d3SDmytro Laktyushkin } 28862d591a8SYue Hin Lau 289d7b539d3SDmytro Laktyushkin if (safe_to_lower || watermarks->b.pte_meta_urgent_ns > hubbub->watermarks.b.pte_meta_urgent_ns) { 290d7b539d3SDmytro Laktyushkin hubbub->watermarks.b.pte_meta_urgent_ns = watermarks->b.pte_meta_urgent_ns; 291d7b539d3SDmytro Laktyushkin prog_wm_value = convert_and_clamp(watermarks->b.pte_meta_urgent_ns, 29262d591a8SYue Hin Lau refclk_mhz, 0x1fffff); 29362d591a8SYue Hin Lau REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_B, prog_wm_value); 2941296423bSBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("PTE_META_URGENCY_WATERMARK_B calculated =%d\n" 29562d591a8SYue Hin Lau "HW register value = 0x%x\n", 29662d591a8SYue Hin Lau watermarks->b.pte_meta_urgent_ns, prog_wm_value); 297d7b539d3SDmytro Laktyushkin } 29862d591a8SYue Hin Lau 29962d591a8SYue Hin Lau if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B)) { 300d7b539d3SDmytro Laktyushkin if (safe_to_lower || watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns 301d7b539d3SDmytro Laktyushkin > hubbub->watermarks.b.cstate_pstate.cstate_enter_plus_exit_ns) { 302d7b539d3SDmytro Laktyushkin hubbub->watermarks.b.cstate_pstate.cstate_enter_plus_exit_ns = 303d7b539d3SDmytro Laktyushkin watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns; 30462d591a8SYue Hin Lau prog_wm_value = convert_and_clamp( 30562d591a8SYue Hin Lau watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns, 30662d591a8SYue Hin Lau refclk_mhz, 0x1fffff); 30762d591a8SYue Hin Lau REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, prog_wm_value); 308d7b539d3SDmytro Laktyushkin DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_B calculated =%d\n" 30962d591a8SYue Hin Lau "HW register value = 0x%x\n", 31062d591a8SYue Hin Lau watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value); 311d7b539d3SDmytro Laktyushkin } 31262d591a8SYue Hin Lau 313d7b539d3SDmytro Laktyushkin if (safe_to_lower || watermarks->b.cstate_pstate.cstate_exit_ns 314d7b539d3SDmytro Laktyushkin > hubbub->watermarks.b.cstate_pstate.cstate_exit_ns) { 315d7b539d3SDmytro Laktyushkin hubbub->watermarks.b.cstate_pstate.cstate_exit_ns = 316d7b539d3SDmytro Laktyushkin watermarks->b.cstate_pstate.cstate_exit_ns; 31762d591a8SYue Hin Lau prog_wm_value = convert_and_clamp( 31862d591a8SYue Hin Lau watermarks->b.cstate_pstate.cstate_exit_ns, 31962d591a8SYue Hin Lau refclk_mhz, 0x1fffff); 32062d591a8SYue Hin Lau REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, prog_wm_value); 3211296423bSBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_B calculated =%d\n" 32262d591a8SYue Hin Lau "HW register value = 0x%x\n", 32362d591a8SYue Hin Lau watermarks->b.cstate_pstate.cstate_exit_ns, prog_wm_value); 32462d591a8SYue Hin Lau } 325d7b539d3SDmytro Laktyushkin } 32662d591a8SYue Hin Lau 327d7b539d3SDmytro Laktyushkin if (safe_to_lower || watermarks->b.cstate_pstate.pstate_change_ns 328d7b539d3SDmytro Laktyushkin > hubbub->watermarks.b.cstate_pstate.pstate_change_ns) { 329d7b539d3SDmytro Laktyushkin hubbub->watermarks.b.cstate_pstate.pstate_change_ns = 330d7b539d3SDmytro Laktyushkin watermarks->b.cstate_pstate.pstate_change_ns; 33162d591a8SYue Hin Lau prog_wm_value = convert_and_clamp( 33262d591a8SYue Hin Lau watermarks->b.cstate_pstate.pstate_change_ns, 33362d591a8SYue Hin Lau refclk_mhz, 0x1fffff); 33462d591a8SYue Hin Lau REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B, prog_wm_value); 335d7b539d3SDmytro Laktyushkin DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_B calculated =%d\n" 336d7b539d3SDmytro Laktyushkin "HW register value = 0x%x\n\n", 33762d591a8SYue Hin Lau watermarks->b.cstate_pstate.pstate_change_ns, prog_wm_value); 338d7b539d3SDmytro Laktyushkin } 33962d591a8SYue Hin Lau 34062d591a8SYue Hin Lau /* clock state C */ 341d7b539d3SDmytro Laktyushkin if (safe_to_lower || watermarks->c.urgent_ns > hubbub->watermarks.c.urgent_ns) { 342d7b539d3SDmytro Laktyushkin hubbub->watermarks.c.urgent_ns = watermarks->c.urgent_ns; 343d7b539d3SDmytro Laktyushkin prog_wm_value = convert_and_clamp(watermarks->c.urgent_ns, 344d7b539d3SDmytro Laktyushkin refclk_mhz, 0x1fffff); 34562d591a8SYue Hin Lau REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, prog_wm_value); 346d7b539d3SDmytro Laktyushkin 3471296423bSBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_C calculated =%d\n" 34862d591a8SYue Hin Lau "HW register value = 0x%x\n", 34962d591a8SYue Hin Lau watermarks->c.urgent_ns, prog_wm_value); 350d7b539d3SDmytro Laktyushkin } 35162d591a8SYue Hin Lau 352d7b539d3SDmytro Laktyushkin if (safe_to_lower || watermarks->c.pte_meta_urgent_ns > hubbub->watermarks.c.pte_meta_urgent_ns) { 353d7b539d3SDmytro Laktyushkin hubbub->watermarks.c.pte_meta_urgent_ns = watermarks->c.pte_meta_urgent_ns; 354d7b539d3SDmytro Laktyushkin prog_wm_value = convert_and_clamp(watermarks->c.pte_meta_urgent_ns, 35562d591a8SYue Hin Lau refclk_mhz, 0x1fffff); 35662d591a8SYue Hin Lau REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_C, prog_wm_value); 3571296423bSBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("PTE_META_URGENCY_WATERMARK_C calculated =%d\n" 35862d591a8SYue Hin Lau "HW register value = 0x%x\n", 35962d591a8SYue Hin Lau watermarks->c.pte_meta_urgent_ns, prog_wm_value); 360d7b539d3SDmytro Laktyushkin } 36162d591a8SYue Hin Lau 36262d591a8SYue Hin Lau if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C)) { 363d7b539d3SDmytro Laktyushkin if (safe_to_lower || watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns 364d7b539d3SDmytro Laktyushkin > hubbub->watermarks.c.cstate_pstate.cstate_enter_plus_exit_ns) { 365d7b539d3SDmytro Laktyushkin hubbub->watermarks.c.cstate_pstate.cstate_enter_plus_exit_ns = 366d7b539d3SDmytro Laktyushkin watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns; 36762d591a8SYue Hin Lau prog_wm_value = convert_and_clamp( 36862d591a8SYue Hin Lau watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns, 36962d591a8SYue Hin Lau refclk_mhz, 0x1fffff); 37062d591a8SYue Hin Lau REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, prog_wm_value); 371d7b539d3SDmytro Laktyushkin DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_C calculated =%d\n" 37262d591a8SYue Hin Lau "HW register value = 0x%x\n", 37362d591a8SYue Hin Lau watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value); 374d7b539d3SDmytro Laktyushkin } 37562d591a8SYue Hin Lau 376d7b539d3SDmytro Laktyushkin if (safe_to_lower || watermarks->c.cstate_pstate.cstate_exit_ns 377d7b539d3SDmytro Laktyushkin > hubbub->watermarks.c.cstate_pstate.cstate_exit_ns) { 378d7b539d3SDmytro Laktyushkin hubbub->watermarks.c.cstate_pstate.cstate_exit_ns = 379d7b539d3SDmytro Laktyushkin watermarks->c.cstate_pstate.cstate_exit_ns; 38062d591a8SYue Hin Lau prog_wm_value = convert_and_clamp( 38162d591a8SYue Hin Lau watermarks->c.cstate_pstate.cstate_exit_ns, 38262d591a8SYue Hin Lau refclk_mhz, 0x1fffff); 38362d591a8SYue Hin Lau REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C, prog_wm_value); 3841296423bSBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_C calculated =%d\n" 38562d591a8SYue Hin Lau "HW register value = 0x%x\n", 38662d591a8SYue Hin Lau watermarks->c.cstate_pstate.cstate_exit_ns, prog_wm_value); 38762d591a8SYue Hin Lau } 388d7b539d3SDmytro Laktyushkin } 38962d591a8SYue Hin Lau 390d7b539d3SDmytro Laktyushkin if (safe_to_lower || watermarks->c.cstate_pstate.pstate_change_ns 391d7b539d3SDmytro Laktyushkin > hubbub->watermarks.c.cstate_pstate.pstate_change_ns) { 392d7b539d3SDmytro Laktyushkin hubbub->watermarks.c.cstate_pstate.pstate_change_ns = 393d7b539d3SDmytro Laktyushkin watermarks->c.cstate_pstate.pstate_change_ns; 39462d591a8SYue Hin Lau prog_wm_value = convert_and_clamp( 39562d591a8SYue Hin Lau watermarks->c.cstate_pstate.pstate_change_ns, 39662d591a8SYue Hin Lau refclk_mhz, 0x1fffff); 39762d591a8SYue Hin Lau REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C, prog_wm_value); 398d7b539d3SDmytro Laktyushkin DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_C calculated =%d\n" 399d7b539d3SDmytro Laktyushkin "HW register value = 0x%x\n\n", 40062d591a8SYue Hin Lau watermarks->c.cstate_pstate.pstate_change_ns, prog_wm_value); 401d7b539d3SDmytro Laktyushkin } 40262d591a8SYue Hin Lau 40362d591a8SYue Hin Lau /* clock state D */ 404d7b539d3SDmytro Laktyushkin if (safe_to_lower || watermarks->d.urgent_ns > hubbub->watermarks.d.urgent_ns) { 405d7b539d3SDmytro Laktyushkin hubbub->watermarks.d.urgent_ns = watermarks->d.urgent_ns; 406d7b539d3SDmytro Laktyushkin prog_wm_value = convert_and_clamp(watermarks->d.urgent_ns, 407d7b539d3SDmytro Laktyushkin refclk_mhz, 0x1fffff); 40862d591a8SYue Hin Lau REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, prog_wm_value); 409d7b539d3SDmytro Laktyushkin 4101296423bSBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_D calculated =%d\n" 41162d591a8SYue Hin Lau "HW register value = 0x%x\n", 41262d591a8SYue Hin Lau watermarks->d.urgent_ns, prog_wm_value); 413d7b539d3SDmytro Laktyushkin } 41462d591a8SYue Hin Lau 415d7b539d3SDmytro Laktyushkin if (safe_to_lower || watermarks->d.pte_meta_urgent_ns > hubbub->watermarks.d.pte_meta_urgent_ns) { 416d7b539d3SDmytro Laktyushkin hubbub->watermarks.d.pte_meta_urgent_ns = watermarks->d.pte_meta_urgent_ns; 417d7b539d3SDmytro Laktyushkin prog_wm_value = convert_and_clamp(watermarks->d.pte_meta_urgent_ns, 41862d591a8SYue Hin Lau refclk_mhz, 0x1fffff); 41962d591a8SYue Hin Lau REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_D, prog_wm_value); 4201296423bSBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("PTE_META_URGENCY_WATERMARK_D calculated =%d\n" 42162d591a8SYue Hin Lau "HW register value = 0x%x\n", 42262d591a8SYue Hin Lau watermarks->d.pte_meta_urgent_ns, prog_wm_value); 423d7b539d3SDmytro Laktyushkin } 42462d591a8SYue Hin Lau 42562d591a8SYue Hin Lau if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D)) { 426d7b539d3SDmytro Laktyushkin if (safe_to_lower || watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns 427d7b539d3SDmytro Laktyushkin > hubbub->watermarks.d.cstate_pstate.cstate_enter_plus_exit_ns) { 428d7b539d3SDmytro Laktyushkin hubbub->watermarks.d.cstate_pstate.cstate_enter_plus_exit_ns = 429d7b539d3SDmytro Laktyushkin watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns; 43062d591a8SYue Hin Lau prog_wm_value = convert_and_clamp( 43162d591a8SYue Hin Lau watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns, 43262d591a8SYue Hin Lau refclk_mhz, 0x1fffff); 43362d591a8SYue Hin Lau REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, prog_wm_value); 434d7b539d3SDmytro Laktyushkin DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_D calculated =%d\n" 43562d591a8SYue Hin Lau "HW register value = 0x%x\n", 43662d591a8SYue Hin Lau watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value); 437d7b539d3SDmytro Laktyushkin } 43862d591a8SYue Hin Lau 439d7b539d3SDmytro Laktyushkin if (safe_to_lower || watermarks->d.cstate_pstate.cstate_exit_ns 440d7b539d3SDmytro Laktyushkin > hubbub->watermarks.d.cstate_pstate.cstate_exit_ns) { 441d7b539d3SDmytro Laktyushkin hubbub->watermarks.d.cstate_pstate.cstate_exit_ns = 442d7b539d3SDmytro Laktyushkin watermarks->d.cstate_pstate.cstate_exit_ns; 44362d591a8SYue Hin Lau prog_wm_value = convert_and_clamp( 44462d591a8SYue Hin Lau watermarks->d.cstate_pstate.cstate_exit_ns, 44562d591a8SYue Hin Lau refclk_mhz, 0x1fffff); 44662d591a8SYue Hin Lau REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D, prog_wm_value); 4471296423bSBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_D calculated =%d\n" 44862d591a8SYue Hin Lau "HW register value = 0x%x\n", 44962d591a8SYue Hin Lau watermarks->d.cstate_pstate.cstate_exit_ns, prog_wm_value); 45062d591a8SYue Hin Lau } 451d7b539d3SDmytro Laktyushkin } 45262d591a8SYue Hin Lau 453d7b539d3SDmytro Laktyushkin if (safe_to_lower || watermarks->d.cstate_pstate.pstate_change_ns 454d7b539d3SDmytro Laktyushkin > hubbub->watermarks.d.cstate_pstate.pstate_change_ns) { 455d7b539d3SDmytro Laktyushkin hubbub->watermarks.d.cstate_pstate.pstate_change_ns = 456d7b539d3SDmytro Laktyushkin watermarks->d.cstate_pstate.pstate_change_ns; 45762d591a8SYue Hin Lau prog_wm_value = convert_and_clamp( 45862d591a8SYue Hin Lau watermarks->d.cstate_pstate.pstate_change_ns, 45962d591a8SYue Hin Lau refclk_mhz, 0x1fffff); 46062d591a8SYue Hin Lau REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D, prog_wm_value); 4611296423bSBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_D calculated =%d\n" 46262d591a8SYue Hin Lau "HW register value = 0x%x\n\n", 46362d591a8SYue Hin Lau watermarks->d.cstate_pstate.pstate_change_ns, prog_wm_value); 464d7b539d3SDmytro Laktyushkin } 46562d591a8SYue Hin Lau 46662d591a8SYue Hin Lau REG_UPDATE(DCHUBBUB_ARB_SAT_LEVEL, 46762d591a8SYue Hin Lau DCHUBBUB_ARB_SAT_LEVEL, 60 * refclk_mhz); 46862d591a8SYue Hin Lau REG_UPDATE(DCHUBBUB_ARB_DF_REQ_OUTSTAND, 46962d591a8SYue Hin Lau DCHUBBUB_ARB_MIN_REQ_OUTSTAND, 68); 47062d591a8SYue Hin Lau 47162d591a8SYue Hin Lau REG_UPDATE_2(DCHUBBUB_ARB_DRAM_STATE_CNTL, 47262d591a8SYue Hin Lau DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_VALUE, 0, 47362d591a8SYue Hin Lau DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_ENABLE, force_en); 47462d591a8SYue Hin Lau 47562d591a8SYue Hin Lau #if 0 47662d591a8SYue Hin Lau REG_UPDATE_2(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL, 47762d591a8SYue Hin Lau DCHUBBUB_ARB_WATERMARK_CHANGE_DONE_INTERRUPT_DISABLE, 1, 47862d591a8SYue Hin Lau DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, 1); 47962d591a8SYue Hin Lau #endif 48062d591a8SYue Hin Lau } 48162d591a8SYue Hin Lau 482c9ef081dSYue Hin Lau void hubbub1_update_dchub( 483c9ef081dSYue Hin Lau struct hubbub *hubbub, 48462d591a8SYue Hin Lau struct dchub_init_data *dh_data) 48562d591a8SYue Hin Lau { 48662d591a8SYue Hin Lau /* TODO: port code from dal2 */ 48762d591a8SYue Hin Lau switch (dh_data->fb_mode) { 48862d591a8SYue Hin Lau case FRAME_BUFFER_MODE_ZFB_ONLY: 48962d591a8SYue Hin Lau /*For ZFB case need to put DCHUB FB BASE and TOP upside down to indicate ZFB mode*/ 49062d591a8SYue Hin Lau REG_UPDATE(DCHUBBUB_SDPIF_FB_TOP, 49162d591a8SYue Hin Lau SDPIF_FB_TOP, 0); 49262d591a8SYue Hin Lau 49362d591a8SYue Hin Lau REG_UPDATE(DCHUBBUB_SDPIF_FB_BASE, 49462d591a8SYue Hin Lau SDPIF_FB_BASE, 0x0FFFF); 49562d591a8SYue Hin Lau 49662d591a8SYue Hin Lau REG_UPDATE(DCHUBBUB_SDPIF_AGP_BASE, 49762d591a8SYue Hin Lau SDPIF_AGP_BASE, dh_data->zfb_phys_addr_base >> 22); 49862d591a8SYue Hin Lau 49962d591a8SYue Hin Lau REG_UPDATE(DCHUBBUB_SDPIF_AGP_BOT, 50062d591a8SYue Hin Lau SDPIF_AGP_BOT, dh_data->zfb_mc_base_addr >> 22); 50162d591a8SYue Hin Lau 50262d591a8SYue Hin Lau REG_UPDATE(DCHUBBUB_SDPIF_AGP_TOP, 50362d591a8SYue Hin Lau SDPIF_AGP_TOP, (dh_data->zfb_mc_base_addr + 50462d591a8SYue Hin Lau dh_data->zfb_size_in_byte - 1) >> 22); 50562d591a8SYue Hin Lau break; 50662d591a8SYue Hin Lau case FRAME_BUFFER_MODE_MIXED_ZFB_AND_LOCAL: 50762d591a8SYue Hin Lau /*Should not touch FB LOCATION (done by VBIOS on AsicInit table)*/ 50862d591a8SYue Hin Lau 50962d591a8SYue Hin Lau REG_UPDATE(DCHUBBUB_SDPIF_AGP_BASE, 51062d591a8SYue Hin Lau SDPIF_AGP_BASE, dh_data->zfb_phys_addr_base >> 22); 51162d591a8SYue Hin Lau 51262d591a8SYue Hin Lau REG_UPDATE(DCHUBBUB_SDPIF_AGP_BOT, 51362d591a8SYue Hin Lau SDPIF_AGP_BOT, dh_data->zfb_mc_base_addr >> 22); 51462d591a8SYue Hin Lau 51562d591a8SYue Hin Lau REG_UPDATE(DCHUBBUB_SDPIF_AGP_TOP, 51662d591a8SYue Hin Lau SDPIF_AGP_TOP, (dh_data->zfb_mc_base_addr + 51762d591a8SYue Hin Lau dh_data->zfb_size_in_byte - 1) >> 22); 51862d591a8SYue Hin Lau break; 51962d591a8SYue Hin Lau case FRAME_BUFFER_MODE_LOCAL_ONLY: 52062d591a8SYue Hin Lau /*Should not touch FB LOCATION (done by VBIOS on AsicInit table)*/ 52162d591a8SYue Hin Lau REG_UPDATE(DCHUBBUB_SDPIF_AGP_BASE, 52262d591a8SYue Hin Lau SDPIF_AGP_BASE, 0); 52362d591a8SYue Hin Lau 52462d591a8SYue Hin Lau REG_UPDATE(DCHUBBUB_SDPIF_AGP_BOT, 52562d591a8SYue Hin Lau SDPIF_AGP_BOT, 0X03FFFF); 52662d591a8SYue Hin Lau 52762d591a8SYue Hin Lau REG_UPDATE(DCHUBBUB_SDPIF_AGP_TOP, 52862d591a8SYue Hin Lau SDPIF_AGP_TOP, 0); 52962d591a8SYue Hin Lau break; 53062d591a8SYue Hin Lau default: 53162d591a8SYue Hin Lau break; 53262d591a8SYue Hin Lau } 53362d591a8SYue Hin Lau 53462d591a8SYue Hin Lau dh_data->dchub_initialzied = true; 53562d591a8SYue Hin Lau dh_data->dchub_info_valid = false; 53662d591a8SYue Hin Lau } 53762d591a8SYue Hin Lau 538ea00f297SYue Hin Lau void hubbub1_toggle_watermark_change_req(struct hubbub *hubbub) 53962d591a8SYue Hin Lau { 54062d591a8SYue Hin Lau uint32_t watermark_change_req; 54162d591a8SYue Hin Lau 54262d591a8SYue Hin Lau REG_GET(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL, 54362d591a8SYue Hin Lau DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, &watermark_change_req); 54462d591a8SYue Hin Lau 54562d591a8SYue Hin Lau if (watermark_change_req) 54662d591a8SYue Hin Lau watermark_change_req = 0; 54762d591a8SYue Hin Lau else 54862d591a8SYue Hin Lau watermark_change_req = 1; 54962d591a8SYue Hin Lau 55062d591a8SYue Hin Lau REG_UPDATE(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL, 55162d591a8SYue Hin Lau DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, watermark_change_req); 55262d591a8SYue Hin Lau } 55362d591a8SYue Hin Lau 5543ba43a59SCharlene Liu void hubbub1_soft_reset(struct hubbub *hubbub, bool reset) 5553ba43a59SCharlene Liu { 5563ba43a59SCharlene Liu uint32_t reset_en = reset ? 1 : 0; 5573ba43a59SCharlene Liu 5583ba43a59SCharlene Liu REG_UPDATE(DCHUBBUB_SOFT_RESET, 5593ba43a59SCharlene Liu DCHUBBUB_GLOBAL_SOFT_RESET, reset_en); 5603ba43a59SCharlene Liu } 5613ba43a59SCharlene Liu 5625ebfb7a5SEric Bernstein static bool hubbub1_dcc_support_swizzle( 5635ebfb7a5SEric Bernstein enum swizzle_mode_values swizzle, 5645ebfb7a5SEric Bernstein unsigned int bytes_per_element, 5655ebfb7a5SEric Bernstein enum segment_order *segment_order_horz, 5665ebfb7a5SEric Bernstein enum segment_order *segment_order_vert) 5675ebfb7a5SEric Bernstein { 5685ebfb7a5SEric Bernstein bool standard_swizzle = false; 5695ebfb7a5SEric Bernstein bool display_swizzle = false; 5705ebfb7a5SEric Bernstein 5715ebfb7a5SEric Bernstein switch (swizzle) { 5725ebfb7a5SEric Bernstein case DC_SW_4KB_S: 5735ebfb7a5SEric Bernstein case DC_SW_64KB_S: 5745ebfb7a5SEric Bernstein case DC_SW_VAR_S: 5755ebfb7a5SEric Bernstein case DC_SW_4KB_S_X: 5765ebfb7a5SEric Bernstein case DC_SW_64KB_S_X: 5775ebfb7a5SEric Bernstein case DC_SW_VAR_S_X: 5785ebfb7a5SEric Bernstein standard_swizzle = true; 5795ebfb7a5SEric Bernstein break; 5805ebfb7a5SEric Bernstein case DC_SW_4KB_D: 5815ebfb7a5SEric Bernstein case DC_SW_64KB_D: 5825ebfb7a5SEric Bernstein case DC_SW_VAR_D: 5835ebfb7a5SEric Bernstein case DC_SW_4KB_D_X: 5845ebfb7a5SEric Bernstein case DC_SW_64KB_D_X: 5855ebfb7a5SEric Bernstein case DC_SW_VAR_D_X: 5865ebfb7a5SEric Bernstein display_swizzle = true; 5875ebfb7a5SEric Bernstein break; 5885ebfb7a5SEric Bernstein default: 5895ebfb7a5SEric Bernstein break; 5905ebfb7a5SEric Bernstein } 5915ebfb7a5SEric Bernstein 5925ebfb7a5SEric Bernstein if (bytes_per_element == 1 && standard_swizzle) { 5935ebfb7a5SEric Bernstein *segment_order_horz = segment_order__contiguous; 5945ebfb7a5SEric Bernstein *segment_order_vert = segment_order__na; 5955ebfb7a5SEric Bernstein return true; 5965ebfb7a5SEric Bernstein } 5975ebfb7a5SEric Bernstein if (bytes_per_element == 2 && standard_swizzle) { 5985ebfb7a5SEric Bernstein *segment_order_horz = segment_order__non_contiguous; 5995ebfb7a5SEric Bernstein *segment_order_vert = segment_order__contiguous; 6005ebfb7a5SEric Bernstein return true; 6015ebfb7a5SEric Bernstein } 6025ebfb7a5SEric Bernstein if (bytes_per_element == 4 && standard_swizzle) { 6035ebfb7a5SEric Bernstein *segment_order_horz = segment_order__non_contiguous; 6045ebfb7a5SEric Bernstein *segment_order_vert = segment_order__contiguous; 6055ebfb7a5SEric Bernstein return true; 6065ebfb7a5SEric Bernstein } 6075ebfb7a5SEric Bernstein if (bytes_per_element == 8 && standard_swizzle) { 6085ebfb7a5SEric Bernstein *segment_order_horz = segment_order__na; 6095ebfb7a5SEric Bernstein *segment_order_vert = segment_order__contiguous; 6105ebfb7a5SEric Bernstein return true; 6115ebfb7a5SEric Bernstein } 6125ebfb7a5SEric Bernstein if (bytes_per_element == 8 && display_swizzle) { 6135ebfb7a5SEric Bernstein *segment_order_horz = segment_order__contiguous; 6145ebfb7a5SEric Bernstein *segment_order_vert = segment_order__non_contiguous; 6155ebfb7a5SEric Bernstein return true; 6165ebfb7a5SEric Bernstein } 6175ebfb7a5SEric Bernstein 6185ebfb7a5SEric Bernstein return false; 6195ebfb7a5SEric Bernstein } 6205ebfb7a5SEric Bernstein 6215ebfb7a5SEric Bernstein static bool hubbub1_dcc_support_pixel_format( 6225ebfb7a5SEric Bernstein enum surface_pixel_format format, 6235ebfb7a5SEric Bernstein unsigned int *bytes_per_element) 6245ebfb7a5SEric Bernstein { 6255ebfb7a5SEric Bernstein /* DML: get_bytes_per_element */ 6265ebfb7a5SEric Bernstein switch (format) { 6275ebfb7a5SEric Bernstein case SURFACE_PIXEL_FORMAT_GRPH_ARGB1555: 6285ebfb7a5SEric Bernstein case SURFACE_PIXEL_FORMAT_GRPH_RGB565: 6295ebfb7a5SEric Bernstein *bytes_per_element = 2; 6305ebfb7a5SEric Bernstein return true; 6315ebfb7a5SEric Bernstein case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888: 6325ebfb7a5SEric Bernstein case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888: 6335ebfb7a5SEric Bernstein case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010: 6345ebfb7a5SEric Bernstein case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010: 6355ebfb7a5SEric Bernstein *bytes_per_element = 4; 6365ebfb7a5SEric Bernstein return true; 6375ebfb7a5SEric Bernstein case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616: 6385ebfb7a5SEric Bernstein case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F: 6395ebfb7a5SEric Bernstein case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F: 6405ebfb7a5SEric Bernstein *bytes_per_element = 8; 6415ebfb7a5SEric Bernstein return true; 6425ebfb7a5SEric Bernstein default: 6435ebfb7a5SEric Bernstein return false; 6445ebfb7a5SEric Bernstein } 6455ebfb7a5SEric Bernstein } 6465ebfb7a5SEric Bernstein 6475ebfb7a5SEric Bernstein static void hubbub1_get_blk256_size(unsigned int *blk256_width, unsigned int *blk256_height, 6485ebfb7a5SEric Bernstein unsigned int bytes_per_element) 6495ebfb7a5SEric Bernstein { 6505ebfb7a5SEric Bernstein /* copied from DML. might want to refactor DML to leverage from DML */ 6515ebfb7a5SEric Bernstein /* DML : get_blk256_size */ 6525ebfb7a5SEric Bernstein if (bytes_per_element == 1) { 6535ebfb7a5SEric Bernstein *blk256_width = 16; 6545ebfb7a5SEric Bernstein *blk256_height = 16; 6555ebfb7a5SEric Bernstein } else if (bytes_per_element == 2) { 6565ebfb7a5SEric Bernstein *blk256_width = 16; 6575ebfb7a5SEric Bernstein *blk256_height = 8; 6585ebfb7a5SEric Bernstein } else if (bytes_per_element == 4) { 6595ebfb7a5SEric Bernstein *blk256_width = 8; 6605ebfb7a5SEric Bernstein *blk256_height = 8; 6615ebfb7a5SEric Bernstein } else if (bytes_per_element == 8) { 6625ebfb7a5SEric Bernstein *blk256_width = 8; 6635ebfb7a5SEric Bernstein *blk256_height = 4; 6645ebfb7a5SEric Bernstein } 6655ebfb7a5SEric Bernstein } 6665ebfb7a5SEric Bernstein 6675ebfb7a5SEric Bernstein static void hubbub1_det_request_size( 6685ebfb7a5SEric Bernstein unsigned int height, 6695ebfb7a5SEric Bernstein unsigned int width, 6705ebfb7a5SEric Bernstein unsigned int bpe, 6715ebfb7a5SEric Bernstein bool *req128_horz_wc, 6725ebfb7a5SEric Bernstein bool *req128_vert_wc) 6735ebfb7a5SEric Bernstein { 6745ebfb7a5SEric Bernstein unsigned int detile_buf_size = 164 * 1024; /* 164KB for DCN1.0 */ 6755ebfb7a5SEric Bernstein 6765ebfb7a5SEric Bernstein unsigned int blk256_height = 0; 6775ebfb7a5SEric Bernstein unsigned int blk256_width = 0; 6785ebfb7a5SEric Bernstein unsigned int swath_bytes_horz_wc, swath_bytes_vert_wc; 6795ebfb7a5SEric Bernstein 6805ebfb7a5SEric Bernstein hubbub1_get_blk256_size(&blk256_width, &blk256_height, bpe); 6815ebfb7a5SEric Bernstein 6825ebfb7a5SEric Bernstein swath_bytes_horz_wc = height * blk256_height * bpe; 6835ebfb7a5SEric Bernstein swath_bytes_vert_wc = width * blk256_width * bpe; 6845ebfb7a5SEric Bernstein 6855ebfb7a5SEric Bernstein *req128_horz_wc = (2 * swath_bytes_horz_wc <= detile_buf_size) ? 6865ebfb7a5SEric Bernstein false : /* full 256B request */ 6875ebfb7a5SEric Bernstein true; /* half 128b request */ 6885ebfb7a5SEric Bernstein 6895ebfb7a5SEric Bernstein *req128_vert_wc = (2 * swath_bytes_vert_wc <= detile_buf_size) ? 6905ebfb7a5SEric Bernstein false : /* full 256B request */ 6915ebfb7a5SEric Bernstein true; /* half 128b request */ 6925ebfb7a5SEric Bernstein } 6935ebfb7a5SEric Bernstein 6945ebfb7a5SEric Bernstein static bool hubbub1_get_dcc_compression_cap(struct hubbub *hubbub, 6955ebfb7a5SEric Bernstein const struct dc_dcc_surface_param *input, 6965ebfb7a5SEric Bernstein struct dc_surface_dcc_cap *output) 6975ebfb7a5SEric Bernstein { 6985ebfb7a5SEric Bernstein struct dc *dc = hubbub->ctx->dc; 6995ebfb7a5SEric Bernstein /* implement section 1.6.2.1 of DCN1_Programming_Guide.docx */ 7005ebfb7a5SEric Bernstein enum dcc_control dcc_control; 7015ebfb7a5SEric Bernstein unsigned int bpe; 7025ebfb7a5SEric Bernstein enum segment_order segment_order_horz, segment_order_vert; 7035ebfb7a5SEric Bernstein bool req128_horz_wc, req128_vert_wc; 7045ebfb7a5SEric Bernstein 7055ebfb7a5SEric Bernstein memset(output, 0, sizeof(*output)); 7065ebfb7a5SEric Bernstein 7075ebfb7a5SEric Bernstein if (dc->debug.disable_dcc == DCC_DISABLE) 7085ebfb7a5SEric Bernstein return false; 7095ebfb7a5SEric Bernstein 7105ebfb7a5SEric Bernstein if (!hubbub->funcs->dcc_support_pixel_format(input->format, &bpe)) 7115ebfb7a5SEric Bernstein return false; 7125ebfb7a5SEric Bernstein 7135ebfb7a5SEric Bernstein if (!hubbub->funcs->dcc_support_swizzle(input->swizzle_mode, bpe, 7145ebfb7a5SEric Bernstein &segment_order_horz, &segment_order_vert)) 7155ebfb7a5SEric Bernstein return false; 7165ebfb7a5SEric Bernstein 7175ebfb7a5SEric Bernstein hubbub1_det_request_size(input->surface_size.height, input->surface_size.width, 7185ebfb7a5SEric Bernstein bpe, &req128_horz_wc, &req128_vert_wc); 7195ebfb7a5SEric Bernstein 7205ebfb7a5SEric Bernstein if (!req128_horz_wc && !req128_vert_wc) { 7215ebfb7a5SEric Bernstein dcc_control = dcc_control__256_256_xxx; 7225ebfb7a5SEric Bernstein } else if (input->scan == SCAN_DIRECTION_HORIZONTAL) { 7235ebfb7a5SEric Bernstein if (!req128_horz_wc) 7245ebfb7a5SEric Bernstein dcc_control = dcc_control__256_256_xxx; 7255ebfb7a5SEric Bernstein else if (segment_order_horz == segment_order__contiguous) 7265ebfb7a5SEric Bernstein dcc_control = dcc_control__128_128_xxx; 7275ebfb7a5SEric Bernstein else 7285ebfb7a5SEric Bernstein dcc_control = dcc_control__256_64_64; 7295ebfb7a5SEric Bernstein } else if (input->scan == SCAN_DIRECTION_VERTICAL) { 7305ebfb7a5SEric Bernstein if (!req128_vert_wc) 7315ebfb7a5SEric Bernstein dcc_control = dcc_control__256_256_xxx; 7325ebfb7a5SEric Bernstein else if (segment_order_vert == segment_order__contiguous) 7335ebfb7a5SEric Bernstein dcc_control = dcc_control__128_128_xxx; 7345ebfb7a5SEric Bernstein else 7355ebfb7a5SEric Bernstein dcc_control = dcc_control__256_64_64; 7365ebfb7a5SEric Bernstein } else { 7375ebfb7a5SEric Bernstein if ((req128_horz_wc && 7385ebfb7a5SEric Bernstein segment_order_horz == segment_order__non_contiguous) || 7395ebfb7a5SEric Bernstein (req128_vert_wc && 7405ebfb7a5SEric Bernstein segment_order_vert == segment_order__non_contiguous)) 7415ebfb7a5SEric Bernstein /* access_dir not known, must use most constraining */ 7425ebfb7a5SEric Bernstein dcc_control = dcc_control__256_64_64; 7435ebfb7a5SEric Bernstein else 7445ebfb7a5SEric Bernstein /* reg128 is true for either horz and vert 7455ebfb7a5SEric Bernstein * but segment_order is contiguous 7465ebfb7a5SEric Bernstein */ 7475ebfb7a5SEric Bernstein dcc_control = dcc_control__128_128_xxx; 7485ebfb7a5SEric Bernstein } 7495ebfb7a5SEric Bernstein 7505ebfb7a5SEric Bernstein if (dc->debug.disable_dcc == DCC_HALF_REQ_DISALBE && 7515ebfb7a5SEric Bernstein dcc_control != dcc_control__256_256_xxx) 7525ebfb7a5SEric Bernstein return false; 7535ebfb7a5SEric Bernstein 7545ebfb7a5SEric Bernstein switch (dcc_control) { 7555ebfb7a5SEric Bernstein case dcc_control__256_256_xxx: 7565ebfb7a5SEric Bernstein output->grph.rgb.max_uncompressed_blk_size = 256; 7575ebfb7a5SEric Bernstein output->grph.rgb.max_compressed_blk_size = 256; 7585ebfb7a5SEric Bernstein output->grph.rgb.independent_64b_blks = false; 7595ebfb7a5SEric Bernstein break; 7605ebfb7a5SEric Bernstein case dcc_control__128_128_xxx: 7615ebfb7a5SEric Bernstein output->grph.rgb.max_uncompressed_blk_size = 128; 7625ebfb7a5SEric Bernstein output->grph.rgb.max_compressed_blk_size = 128; 7635ebfb7a5SEric Bernstein output->grph.rgb.independent_64b_blks = false; 7645ebfb7a5SEric Bernstein break; 7655ebfb7a5SEric Bernstein case dcc_control__256_64_64: 7665ebfb7a5SEric Bernstein output->grph.rgb.max_uncompressed_blk_size = 256; 7675ebfb7a5SEric Bernstein output->grph.rgb.max_compressed_blk_size = 64; 7685ebfb7a5SEric Bernstein output->grph.rgb.independent_64b_blks = true; 7695ebfb7a5SEric Bernstein break; 7705ebfb7a5SEric Bernstein } 7715ebfb7a5SEric Bernstein 7725ebfb7a5SEric Bernstein output->capable = true; 7735ebfb7a5SEric Bernstein output->const_color_support = false; 7745ebfb7a5SEric Bernstein 7755ebfb7a5SEric Bernstein return true; 7765ebfb7a5SEric Bernstein } 7775ebfb7a5SEric Bernstein 778c9ef081dSYue Hin Lau static const struct hubbub_funcs hubbub1_funcs = { 7795ebfb7a5SEric Bernstein .update_dchub = hubbub1_update_dchub, 7805ebfb7a5SEric Bernstein .dcc_support_swizzle = hubbub1_dcc_support_swizzle, 7815ebfb7a5SEric Bernstein .dcc_support_pixel_format = hubbub1_dcc_support_pixel_format, 7825ebfb7a5SEric Bernstein .get_dcc_compression_cap = hubbub1_get_dcc_compression_cap, 783c9ef081dSYue Hin Lau }; 784c9ef081dSYue Hin Lau 785c9ef081dSYue Hin Lau void hubbub1_construct(struct hubbub *hubbub, 786c9ef081dSYue Hin Lau struct dc_context *ctx, 787c9ef081dSYue Hin Lau const struct dcn_hubbub_registers *hubbub_regs, 788c9ef081dSYue Hin Lau const struct dcn_hubbub_shift *hubbub_shift, 789c9ef081dSYue Hin Lau const struct dcn_hubbub_mask *hubbub_mask) 790c9ef081dSYue Hin Lau { 791c9ef081dSYue Hin Lau hubbub->ctx = ctx; 792c9ef081dSYue Hin Lau 793c9ef081dSYue Hin Lau hubbub->funcs = &hubbub1_funcs; 794c9ef081dSYue Hin Lau 795c9ef081dSYue Hin Lau hubbub->regs = hubbub_regs; 796c9ef081dSYue Hin Lau hubbub->shifts = hubbub_shift; 797c9ef081dSYue Hin Lau hubbub->masks = hubbub_mask; 798c9ef081dSYue Hin Lau 799cf1df90fSHersen Wu hubbub->debug_test_index_pstate = 0x7; 800c9ef081dSYue Hin Lau } 80162d591a8SYue Hin Lau 802