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