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 \
3289c4f84bSEryk Brol 	hubbub1->base.ctx
331296423bSBhawanpreet Lakha #define DC_LOGGER \
3489c4f84bSEryk Brol 	hubbub1->base.ctx->logger
3562d591a8SYue Hin Lau #define REG(reg)\
3689c4f84bSEryk Brol 	hubbub1->regs->reg
3762d591a8SYue Hin Lau 
3862d591a8SYue Hin Lau #undef FN
3962d591a8SYue Hin Lau #define FN(reg_name, field_name) \
4089c4f84bSEryk Brol 	hubbub1->shifts->field_name, hubbub1->masks->field_name
4162d591a8SYue Hin Lau 
hubbub1_wm_read_state(struct hubbub * hubbub,struct dcn_hubbub_wm * wm)42c9ef081dSYue Hin Lau void hubbub1_wm_read_state(struct hubbub *hubbub,
4362d591a8SYue Hin Lau 		struct dcn_hubbub_wm *wm)
4462d591a8SYue Hin Lau {
4589c4f84bSEryk Brol 	struct dcn10_hubbub *hubbub1 = TO_DCN10_HUBBUB(hubbub);
4662d591a8SYue Hin Lau 	struct dcn_hubbub_wm_set *s;
4762d591a8SYue Hin Lau 
48d39b3acbSKen Chalmers 	memset(wm, 0, sizeof(struct dcn_hubbub_wm));
49d39b3acbSKen Chalmers 
5062d591a8SYue Hin Lau 	s = &wm->sets[0];
5162d591a8SYue Hin Lau 	s->wm_set = 0;
5262d591a8SYue Hin Lau 	s->data_urgent = REG_READ(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A);
5362d591a8SYue Hin Lau 	s->pte_meta_urgent = REG_READ(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_A);
54d39b3acbSKen Chalmers 	if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A)) {
5562d591a8SYue Hin Lau 		s->sr_enter = REG_READ(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A);
5662d591a8SYue Hin Lau 		s->sr_exit = REG_READ(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A);
57d39b3acbSKen Chalmers 	}
58*2165359bSColin Ian King 	s->dram_clk_change = REG_READ(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A);
5962d591a8SYue Hin Lau 
6062d591a8SYue Hin Lau 	s = &wm->sets[1];
6162d591a8SYue Hin Lau 	s->wm_set = 1;
6262d591a8SYue Hin Lau 	s->data_urgent = REG_READ(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B);
6362d591a8SYue Hin Lau 	s->pte_meta_urgent = REG_READ(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_B);
64d39b3acbSKen Chalmers 	if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B)) {
6562d591a8SYue Hin Lau 		s->sr_enter = REG_READ(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B);
6662d591a8SYue Hin Lau 		s->sr_exit = REG_READ(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B);
67d39b3acbSKen Chalmers 	}
68*2165359bSColin Ian King 	s->dram_clk_change = REG_READ(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B);
6962d591a8SYue Hin Lau 
7062d591a8SYue Hin Lau 	s = &wm->sets[2];
7162d591a8SYue Hin Lau 	s->wm_set = 2;
7262d591a8SYue Hin Lau 	s->data_urgent = REG_READ(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C);
7362d591a8SYue Hin Lau 	s->pte_meta_urgent = REG_READ(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_C);
74d39b3acbSKen Chalmers 	if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C)) {
7562d591a8SYue Hin Lau 		s->sr_enter = REG_READ(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C);
7662d591a8SYue Hin Lau 		s->sr_exit = REG_READ(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C);
77d39b3acbSKen Chalmers 	}
78*2165359bSColin Ian King 	s->dram_clk_change = REG_READ(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C);
7962d591a8SYue Hin Lau 
8062d591a8SYue Hin Lau 	s = &wm->sets[3];
8162d591a8SYue Hin Lau 	s->wm_set = 3;
8262d591a8SYue Hin Lau 	s->data_urgent = REG_READ(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D);
8362d591a8SYue Hin Lau 	s->pte_meta_urgent = REG_READ(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_D);
84d39b3acbSKen Chalmers 	if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D)) {
8562d591a8SYue Hin Lau 		s->sr_enter = REG_READ(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D);
8662d591a8SYue Hin Lau 		s->sr_exit = REG_READ(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D);
87d39b3acbSKen Chalmers 	}
88*2165359bSColin Ian King 	s->dram_clk_change = REG_READ(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D);
8962d591a8SYue Hin Lau }
9062d591a8SYue Hin Lau 
hubbub1_allow_self_refresh_control(struct hubbub * hubbub,bool allow)91b9d4b330SWesley Chalmers void hubbub1_allow_self_refresh_control(struct hubbub *hubbub, bool allow)
92ceb9831dSYongqiang Sun {
9389c4f84bSEryk Brol 	struct dcn10_hubbub *hubbub1 = TO_DCN10_HUBBUB(hubbub);
94b9d4b330SWesley Chalmers 	/*
95b9d4b330SWesley Chalmers 	 * DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_ENABLE = 1 means do not allow stutter
96b9d4b330SWesley Chalmers 	 * DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_ENABLE = 0 means allow stutter
97b9d4b330SWesley Chalmers 	 */
98b9d4b330SWesley Chalmers 
99b9d4b330SWesley Chalmers 	REG_UPDATE_2(DCHUBBUB_ARB_DRAM_STATE_CNTL,
100b9d4b330SWesley Chalmers 			DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_VALUE, 0,
101b9d4b330SWesley Chalmers 			DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_ENABLE, !allow);
102ceb9831dSYongqiang Sun }
103ceb9831dSYongqiang Sun 
hubbub1_is_allow_self_refresh_enabled(struct hubbub * hubbub)1048a31820bSMartin Leung bool hubbub1_is_allow_self_refresh_enabled(struct hubbub *hubbub)
105ceb9831dSYongqiang Sun {
10689c4f84bSEryk Brol 	struct dcn10_hubbub *hubbub1 = TO_DCN10_HUBBUB(hubbub);
107ceb9831dSYongqiang Sun 	uint32_t enable = 0;
108ceb9831dSYongqiang Sun 
109ceb9831dSYongqiang Sun 	REG_GET(DCHUBBUB_ARB_DRAM_STATE_CNTL,
110ceb9831dSYongqiang Sun 			DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_ENABLE, &enable);
111ceb9831dSYongqiang Sun 
112010c8fe9SYongqiang Sun 	return enable ? true : false;
113ceb9831dSYongqiang Sun }
114ceb9831dSYongqiang Sun 
115ceb9831dSYongqiang Sun 
hubbub1_verify_allow_pstate_change_high(struct hubbub * hubbub)116ea00f297SYue Hin Lau bool hubbub1_verify_allow_pstate_change_high(
117c9ef081dSYue Hin Lau 	struct hubbub *hubbub)
11862d591a8SYue Hin Lau {
11989c4f84bSEryk Brol 	struct dcn10_hubbub *hubbub1 = TO_DCN10_HUBBUB(hubbub);
12089c4f84bSEryk Brol 
12162d591a8SYue Hin Lau 	/* pstate latency is ~20us so if we wait over 40us and pstate allow
12262d591a8SYue Hin Lau 	 * still not asserted, we are probably stuck and going to hang
12362d591a8SYue Hin Lau 	 *
12462d591a8SYue Hin Lau 	 * TODO: Figure out why it takes ~100us on linux
12520172ff3SVictor Lu 	 * pstate takes around ~100us (up to 200us) on linux. Unknown currently
12620172ff3SVictor Lu 	 * as to why it takes that long on linux
12762d591a8SYue Hin Lau 	 */
128fa1d7297STakashi Iwai 	const unsigned int pstate_wait_timeout_us = 200;
12920172ff3SVictor Lu 	const unsigned int pstate_wait_expected_timeout_us = 180;
13062d591a8SYue Hin Lau 	static unsigned int max_sampled_pstate_wait_us; /* data collection */
13162d591a8SYue Hin Lau 	static bool forced_pstate_allow; /* help with revert wa */
13262d591a8SYue Hin Lau 
13362d591a8SYue Hin Lau 	unsigned int debug_data;
13462d591a8SYue Hin Lau 	unsigned int i;
13562d591a8SYue Hin Lau 
13662d591a8SYue Hin Lau 	if (forced_pstate_allow) {
13762d591a8SYue Hin Lau 		/* we hacked to force pstate allow to prevent hang last time
13862d591a8SYue Hin Lau 		 * we verify_allow_pstate_change_high.  so disable force
13962d591a8SYue Hin Lau 		 * here so we can check status
14062d591a8SYue Hin Lau 		 */
14162d591a8SYue Hin Lau 		REG_UPDATE_2(DCHUBBUB_ARB_DRAM_STATE_CNTL,
14262d591a8SYue Hin Lau 			     DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_VALUE, 0,
14362d591a8SYue Hin Lau 			     DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_ENABLE, 0);
14462d591a8SYue Hin Lau 		forced_pstate_allow = false;
14562d591a8SYue Hin Lau 	}
14662d591a8SYue Hin Lau 
14776162cb7SPeikang Zhang 	/* The following table only applies to DCN1 and DCN2,
14876162cb7SPeikang Zhang 	 * for newer DCNs, need to consult with HW IP folks to read RTL
14976162cb7SPeikang Zhang 	 * HUBBUB:DCHUBBUB_TEST_ARB_DEBUG10 DCHUBBUBDEBUGIND:0xB
150d567cc55SRoman Li 	 * description
151d567cc55SRoman Li 	 * 0:     Pipe0 Plane0 Allow Pstate Change
152d567cc55SRoman Li 	 * 1:     Pipe0 Plane1 Allow Pstate Change
153d567cc55SRoman Li 	 * 2:     Pipe0 Cursor0 Allow Pstate Change
154d567cc55SRoman Li 	 * 3:     Pipe0 Cursor1 Allow Pstate Change
155d567cc55SRoman Li 	 * 4:     Pipe1 Plane0 Allow Pstate Change
156d567cc55SRoman Li 	 * 5:     Pipe1 Plane1 Allow Pstate Change
157d567cc55SRoman Li 	 * 6:     Pipe1 Cursor0 Allow Pstate Change
158d567cc55SRoman Li 	 * 7:     Pipe1 Cursor1 Allow Pstate Change
159d567cc55SRoman Li 	 * 8:     Pipe2 Plane0 Allow Pstate Change
160d567cc55SRoman Li 	 * 9:     Pipe2 Plane1 Allow Pstate Change
161d567cc55SRoman Li 	 * 10:    Pipe2 Cursor0 Allow Pstate Change
162d567cc55SRoman Li 	 * 11:    Pipe2 Cursor1 Allow Pstate Change
163d567cc55SRoman Li 	 * 12:    Pipe3 Plane0 Allow Pstate Change
164d567cc55SRoman Li 	 * 13:    Pipe3 Plane1 Allow Pstate Change
165d567cc55SRoman Li 	 * 14:    Pipe3 Cursor0 Allow Pstate Change
166d567cc55SRoman Li 	 * 15:    Pipe3 Cursor1 Allow Pstate Change
167d567cc55SRoman Li 	 * 16:    Pipe4 Plane0 Allow Pstate Change
168d567cc55SRoman Li 	 * 17:    Pipe4 Plane1 Allow Pstate Change
169d567cc55SRoman Li 	 * 18:    Pipe4 Cursor0 Allow Pstate Change
170d567cc55SRoman Li 	 * 19:    Pipe4 Cursor1 Allow Pstate Change
171d567cc55SRoman Li 	 * 20:    Pipe5 Plane0 Allow Pstate Change
172d567cc55SRoman Li 	 * 21:    Pipe5 Plane1 Allow Pstate Change
173d567cc55SRoman Li 	 * 22:    Pipe5 Cursor0 Allow Pstate Change
174d567cc55SRoman Li 	 * 23:    Pipe5 Cursor1 Allow Pstate Change
175d567cc55SRoman Li 	 * 24:    Pipe6 Plane0 Allow Pstate Change
176d567cc55SRoman Li 	 * 25:    Pipe6 Plane1 Allow Pstate Change
177d567cc55SRoman Li 	 * 26:    Pipe6 Cursor0 Allow Pstate Change
178d567cc55SRoman Li 	 * 27:    Pipe6 Cursor1 Allow Pstate Change
179d567cc55SRoman Li 	 * 28:    WB0 Allow Pstate Change
180d567cc55SRoman Li 	 * 29:    WB1 Allow Pstate Change
181d567cc55SRoman Li 	 * 30:    Arbiter's allow_pstate_change
18262d591a8SYue Hin Lau 	 * 31:    SOC pstate change request
18362d591a8SYue Hin Lau 	 */
18462d591a8SYue Hin Lau 
18589c4f84bSEryk Brol 	REG_WRITE(DCHUBBUB_TEST_DEBUG_INDEX, hubbub1->debug_test_index_pstate);
18662d591a8SYue Hin Lau 
18762d591a8SYue Hin Lau 	for (i = 0; i < pstate_wait_timeout_us; i++) {
18862d591a8SYue Hin Lau 		debug_data = REG_READ(DCHUBBUB_TEST_DEBUG_DATA);
18962d591a8SYue Hin Lau 
19062d591a8SYue Hin Lau 		if (debug_data & (1 << 30)) {
19162d591a8SYue Hin Lau 
19262d591a8SYue Hin Lau 			if (i > pstate_wait_expected_timeout_us)
1931296423bSBhawanpreet Lakha 				DC_LOG_WARNING("pstate took longer than expected ~%dus\n",
19462d591a8SYue Hin Lau 						i);
19562d591a8SYue Hin Lau 
196e70fe3b1SYue Hin Lau 			return true;
19762d591a8SYue Hin Lau 		}
19862d591a8SYue Hin Lau 		if (max_sampled_pstate_wait_us < i)
19962d591a8SYue Hin Lau 			max_sampled_pstate_wait_us = i;
20062d591a8SYue Hin Lau 
20162d591a8SYue Hin Lau 		udelay(1);
20262d591a8SYue Hin Lau 	}
20362d591a8SYue Hin Lau 
20462d591a8SYue Hin Lau 	/* force pstate allow to prevent system hang
20562d591a8SYue Hin Lau 	 * and break to debugger to investigate
20662d591a8SYue Hin Lau 	 */
20762d591a8SYue Hin Lau 	REG_UPDATE_2(DCHUBBUB_ARB_DRAM_STATE_CNTL,
20862d591a8SYue Hin Lau 		     DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_VALUE, 1,
20962d591a8SYue Hin Lau 		     DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_ENABLE, 1);
21062d591a8SYue Hin Lau 	forced_pstate_allow = true;
21162d591a8SYue Hin Lau 
2121296423bSBhawanpreet Lakha 	DC_LOG_WARNING("pstate TEST_DEBUG_DATA: 0x%X\n",
21362d591a8SYue Hin Lau 			debug_data);
214ea00f297SYue Hin Lau 
215e70fe3b1SYue Hin Lau 	return false;
21662d591a8SYue Hin Lau }
21762d591a8SYue Hin Lau 
convert_and_clamp(uint32_t wm_ns,uint32_t refclk_mhz,uint32_t clamp_value)21862d591a8SYue Hin Lau static uint32_t convert_and_clamp(
21962d591a8SYue Hin Lau 	uint32_t wm_ns,
22062d591a8SYue Hin Lau 	uint32_t refclk_mhz,
22162d591a8SYue Hin Lau 	uint32_t clamp_value)
22262d591a8SYue Hin Lau {
22362d591a8SYue Hin Lau 	uint32_t ret_val = 0;
22462d591a8SYue Hin Lau 	ret_val = wm_ns * refclk_mhz;
22562d591a8SYue Hin Lau 	ret_val /= 1000;
22662d591a8SYue Hin Lau 
22762d591a8SYue Hin Lau 	if (ret_val > clamp_value)
22862d591a8SYue Hin Lau 		ret_val = clamp_value;
22962d591a8SYue Hin Lau 
23062d591a8SYue Hin Lau 	return ret_val;
23162d591a8SYue Hin Lau }
23262d591a8SYue Hin Lau 
23362d591a8SYue Hin Lau 
hubbub1_wm_change_req_wa(struct hubbub * hubbub)2347144d3cfSDmytro Laktyushkin void hubbub1_wm_change_req_wa(struct hubbub *hubbub)
2357144d3cfSDmytro Laktyushkin {
23689c4f84bSEryk Brol 	struct dcn10_hubbub *hubbub1 = TO_DCN10_HUBBUB(hubbub);
23789c4f84bSEryk Brol 
23830eb85ffSYongqiang Sun 	REG_UPDATE_SEQ_2(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL,
23930eb85ffSYongqiang Sun 			DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, 0,
24030eb85ffSYongqiang Sun 			DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, 1);
2417144d3cfSDmytro Laktyushkin }
2427144d3cfSDmytro Laktyushkin 
hubbub1_program_urgent_watermarks(struct hubbub * hubbub,struct dcn_watermark_set * watermarks,unsigned int refclk_mhz,bool safe_to_lower)24389e94bc5SYongqiang Sun bool hubbub1_program_urgent_watermarks(
244c9ef081dSYue Hin Lau 		struct hubbub *hubbub,
24562d591a8SYue Hin Lau 		struct dcn_watermark_set *watermarks,
246d7b539d3SDmytro Laktyushkin 		unsigned int refclk_mhz,
247d7b539d3SDmytro Laktyushkin 		bool safe_to_lower)
24862d591a8SYue Hin Lau {
24989c4f84bSEryk Brol 	struct dcn10_hubbub *hubbub1 = TO_DCN10_HUBBUB(hubbub);
25062d591a8SYue Hin Lau 	uint32_t prog_wm_value;
25189e94bc5SYongqiang Sun 	bool wm_pending = false;
25262d591a8SYue Hin Lau 
25362d591a8SYue Hin Lau 	/* Repeat for water mark set A, B, C and D. */
25462d591a8SYue Hin Lau 	/* clock state A */
25589c4f84bSEryk Brol 	if (safe_to_lower || watermarks->a.urgent_ns > hubbub1->watermarks.a.urgent_ns) {
25689c4f84bSEryk Brol 		hubbub1->watermarks.a.urgent_ns = watermarks->a.urgent_ns;
25762d591a8SYue Hin Lau 		prog_wm_value = convert_and_clamp(watermarks->a.urgent_ns,
25862d591a8SYue Hin Lau 				refclk_mhz, 0x1fffff);
25991f28756SYongqiang Sun 		REG_SET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, 0,
26091f28756SYongqiang Sun 				DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, prog_wm_value);
26162d591a8SYue Hin Lau 
2621296423bSBhawanpreet Lakha 		DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_A calculated =%d\n"
26362d591a8SYue Hin Lau 			"HW register value = 0x%x\n",
26462d591a8SYue Hin Lau 			watermarks->a.urgent_ns, prog_wm_value);
26589e94bc5SYongqiang Sun 	} else if (watermarks->a.urgent_ns < hubbub1->watermarks.a.urgent_ns)
26689e94bc5SYongqiang Sun 		wm_pending = true;
26762d591a8SYue Hin Lau 
26889c4f84bSEryk Brol 	if (safe_to_lower || watermarks->a.pte_meta_urgent_ns > hubbub1->watermarks.a.pte_meta_urgent_ns) {
26989c4f84bSEryk Brol 		hubbub1->watermarks.a.pte_meta_urgent_ns = watermarks->a.pte_meta_urgent_ns;
27062d591a8SYue Hin Lau 		prog_wm_value = convert_and_clamp(watermarks->a.pte_meta_urgent_ns,
27162d591a8SYue Hin Lau 				refclk_mhz, 0x1fffff);
27262d591a8SYue Hin Lau 		REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_A, prog_wm_value);
2731296423bSBhawanpreet Lakha 		DC_LOG_BANDWIDTH_CALCS("PTE_META_URGENCY_WATERMARK_A calculated =%d\n"
27462d591a8SYue Hin Lau 			"HW register value = 0x%x\n",
27562d591a8SYue Hin Lau 			watermarks->a.pte_meta_urgent_ns, prog_wm_value);
27689e94bc5SYongqiang Sun 	} else if (watermarks->a.pte_meta_urgent_ns < hubbub1->watermarks.a.pte_meta_urgent_ns)
27789e94bc5SYongqiang Sun 		wm_pending = true;
27814ed3d00SYongqiang Sun 
27914ed3d00SYongqiang Sun 	/* clock state B */
28014ed3d00SYongqiang Sun 	if (safe_to_lower || watermarks->b.urgent_ns > hubbub1->watermarks.b.urgent_ns) {
28114ed3d00SYongqiang Sun 		hubbub1->watermarks.b.urgent_ns = watermarks->b.urgent_ns;
28214ed3d00SYongqiang Sun 		prog_wm_value = convert_and_clamp(watermarks->b.urgent_ns,
28314ed3d00SYongqiang Sun 				refclk_mhz, 0x1fffff);
28414ed3d00SYongqiang Sun 		REG_SET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, 0,
28514ed3d00SYongqiang Sun 				DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, prog_wm_value);
28614ed3d00SYongqiang Sun 
28714ed3d00SYongqiang Sun 		DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_B calculated =%d\n"
28814ed3d00SYongqiang Sun 			"HW register value = 0x%x\n",
28914ed3d00SYongqiang Sun 			watermarks->b.urgent_ns, prog_wm_value);
29089e94bc5SYongqiang Sun 	} else if (watermarks->b.urgent_ns < hubbub1->watermarks.b.urgent_ns)
29189e94bc5SYongqiang Sun 		wm_pending = true;
29262d591a8SYue Hin Lau 
29314ed3d00SYongqiang Sun 	if (safe_to_lower || watermarks->b.pte_meta_urgent_ns > hubbub1->watermarks.b.pte_meta_urgent_ns) {
29414ed3d00SYongqiang Sun 		hubbub1->watermarks.b.pte_meta_urgent_ns = watermarks->b.pte_meta_urgent_ns;
29514ed3d00SYongqiang Sun 		prog_wm_value = convert_and_clamp(watermarks->b.pte_meta_urgent_ns,
29614ed3d00SYongqiang Sun 				refclk_mhz, 0x1fffff);
29714ed3d00SYongqiang Sun 		REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_B, prog_wm_value);
29814ed3d00SYongqiang Sun 		DC_LOG_BANDWIDTH_CALCS("PTE_META_URGENCY_WATERMARK_B calculated =%d\n"
29914ed3d00SYongqiang Sun 			"HW register value = 0x%x\n",
30014ed3d00SYongqiang Sun 			watermarks->b.pte_meta_urgent_ns, prog_wm_value);
30189e94bc5SYongqiang Sun 	} else if (watermarks->b.pte_meta_urgent_ns < hubbub1->watermarks.b.pte_meta_urgent_ns)
30289e94bc5SYongqiang Sun 		wm_pending = true;
30314ed3d00SYongqiang Sun 
30414ed3d00SYongqiang Sun 	/* clock state C */
30514ed3d00SYongqiang Sun 	if (safe_to_lower || watermarks->c.urgent_ns > hubbub1->watermarks.c.urgent_ns) {
30614ed3d00SYongqiang Sun 		hubbub1->watermarks.c.urgent_ns = watermarks->c.urgent_ns;
30714ed3d00SYongqiang Sun 		prog_wm_value = convert_and_clamp(watermarks->c.urgent_ns,
30814ed3d00SYongqiang Sun 				refclk_mhz, 0x1fffff);
30914ed3d00SYongqiang Sun 		REG_SET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, 0,
31014ed3d00SYongqiang Sun 				DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, prog_wm_value);
31114ed3d00SYongqiang Sun 
31214ed3d00SYongqiang Sun 		DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_C calculated =%d\n"
31314ed3d00SYongqiang Sun 			"HW register value = 0x%x\n",
31414ed3d00SYongqiang Sun 			watermarks->c.urgent_ns, prog_wm_value);
31589e94bc5SYongqiang Sun 	} else if (watermarks->c.urgent_ns < hubbub1->watermarks.c.urgent_ns)
31689e94bc5SYongqiang Sun 		wm_pending = true;
31714ed3d00SYongqiang Sun 
31814ed3d00SYongqiang Sun 	if (safe_to_lower || watermarks->c.pte_meta_urgent_ns > hubbub1->watermarks.c.pte_meta_urgent_ns) {
31914ed3d00SYongqiang Sun 		hubbub1->watermarks.c.pte_meta_urgent_ns = watermarks->c.pte_meta_urgent_ns;
32014ed3d00SYongqiang Sun 		prog_wm_value = convert_and_clamp(watermarks->c.pte_meta_urgent_ns,
32114ed3d00SYongqiang Sun 				refclk_mhz, 0x1fffff);
32214ed3d00SYongqiang Sun 		REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_C, prog_wm_value);
32314ed3d00SYongqiang Sun 		DC_LOG_BANDWIDTH_CALCS("PTE_META_URGENCY_WATERMARK_C calculated =%d\n"
32414ed3d00SYongqiang Sun 			"HW register value = 0x%x\n",
32514ed3d00SYongqiang Sun 			watermarks->c.pte_meta_urgent_ns, prog_wm_value);
32689e94bc5SYongqiang Sun 	} else if (watermarks->c.pte_meta_urgent_ns < hubbub1->watermarks.c.pte_meta_urgent_ns)
32789e94bc5SYongqiang Sun 		wm_pending = true;
32814ed3d00SYongqiang Sun 
32914ed3d00SYongqiang Sun 	/* clock state D */
33014ed3d00SYongqiang Sun 	if (safe_to_lower || watermarks->d.urgent_ns > hubbub1->watermarks.d.urgent_ns) {
33114ed3d00SYongqiang Sun 		hubbub1->watermarks.d.urgent_ns = watermarks->d.urgent_ns;
33214ed3d00SYongqiang Sun 		prog_wm_value = convert_and_clamp(watermarks->d.urgent_ns,
33314ed3d00SYongqiang Sun 				refclk_mhz, 0x1fffff);
33414ed3d00SYongqiang Sun 		REG_SET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, 0,
33514ed3d00SYongqiang Sun 				DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, prog_wm_value);
33614ed3d00SYongqiang Sun 
33714ed3d00SYongqiang Sun 		DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_D calculated =%d\n"
33814ed3d00SYongqiang Sun 			"HW register value = 0x%x\n",
33914ed3d00SYongqiang Sun 			watermarks->d.urgent_ns, prog_wm_value);
34089e94bc5SYongqiang Sun 	} else if (watermarks->d.urgent_ns < hubbub1->watermarks.d.urgent_ns)
34189e94bc5SYongqiang Sun 		wm_pending = true;
34214ed3d00SYongqiang Sun 
34314ed3d00SYongqiang Sun 	if (safe_to_lower || watermarks->d.pte_meta_urgent_ns > hubbub1->watermarks.d.pte_meta_urgent_ns) {
34414ed3d00SYongqiang Sun 		hubbub1->watermarks.d.pte_meta_urgent_ns = watermarks->d.pte_meta_urgent_ns;
34514ed3d00SYongqiang Sun 		prog_wm_value = convert_and_clamp(watermarks->d.pte_meta_urgent_ns,
34614ed3d00SYongqiang Sun 				refclk_mhz, 0x1fffff);
34714ed3d00SYongqiang Sun 		REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_D, prog_wm_value);
34814ed3d00SYongqiang Sun 		DC_LOG_BANDWIDTH_CALCS("PTE_META_URGENCY_WATERMARK_D calculated =%d\n"
34914ed3d00SYongqiang Sun 			"HW register value = 0x%x\n",
35014ed3d00SYongqiang Sun 			watermarks->d.pte_meta_urgent_ns, prog_wm_value);
35189e94bc5SYongqiang Sun 	} else if (watermarks->d.pte_meta_urgent_ns < hubbub1->watermarks.d.pte_meta_urgent_ns)
35289e94bc5SYongqiang Sun 		wm_pending = true;
35389e94bc5SYongqiang Sun 
35489e94bc5SYongqiang Sun 	return wm_pending;
35514ed3d00SYongqiang Sun }
35614ed3d00SYongqiang Sun 
hubbub1_program_stutter_watermarks(struct hubbub * hubbub,struct dcn_watermark_set * watermarks,unsigned int refclk_mhz,bool safe_to_lower)35789e94bc5SYongqiang Sun bool hubbub1_program_stutter_watermarks(
35814ed3d00SYongqiang Sun 		struct hubbub *hubbub,
35914ed3d00SYongqiang Sun 		struct dcn_watermark_set *watermarks,
36014ed3d00SYongqiang Sun 		unsigned int refclk_mhz,
36114ed3d00SYongqiang Sun 		bool safe_to_lower)
36214ed3d00SYongqiang Sun {
36314ed3d00SYongqiang Sun 	struct dcn10_hubbub *hubbub1 = TO_DCN10_HUBBUB(hubbub);
36414ed3d00SYongqiang Sun 	uint32_t prog_wm_value;
36589e94bc5SYongqiang Sun 	bool wm_pending = false;
36614ed3d00SYongqiang Sun 
36714ed3d00SYongqiang Sun 	/* clock state A */
368d7b539d3SDmytro Laktyushkin 	if (safe_to_lower || watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns
36989c4f84bSEryk Brol 			> hubbub1->watermarks.a.cstate_pstate.cstate_enter_plus_exit_ns) {
37089c4f84bSEryk Brol 		hubbub1->watermarks.a.cstate_pstate.cstate_enter_plus_exit_ns =
371d7b539d3SDmytro Laktyushkin 				watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns;
37262d591a8SYue Hin Lau 		prog_wm_value = convert_and_clamp(
37362d591a8SYue Hin Lau 				watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns,
37462d591a8SYue Hin Lau 				refclk_mhz, 0x1fffff);
37591f28756SYongqiang Sun 		REG_SET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A, 0,
37691f28756SYongqiang Sun 				DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A, prog_wm_value);
3771296423bSBhawanpreet Lakha 		DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_A calculated =%d\n"
37862d591a8SYue Hin Lau 			"HW register value = 0x%x\n",
37962d591a8SYue Hin Lau 			watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
38089e94bc5SYongqiang Sun 	} else if (watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns
38189e94bc5SYongqiang Sun 			< hubbub1->watermarks.a.cstate_pstate.cstate_enter_plus_exit_ns)
38289e94bc5SYongqiang Sun 		wm_pending = true;
38362d591a8SYue Hin Lau 
384d7b539d3SDmytro Laktyushkin 	if (safe_to_lower || watermarks->a.cstate_pstate.cstate_exit_ns
38589c4f84bSEryk Brol 			> hubbub1->watermarks.a.cstate_pstate.cstate_exit_ns) {
38689c4f84bSEryk Brol 		hubbub1->watermarks.a.cstate_pstate.cstate_exit_ns =
387d7b539d3SDmytro Laktyushkin 				watermarks->a.cstate_pstate.cstate_exit_ns;
38862d591a8SYue Hin Lau 		prog_wm_value = convert_and_clamp(
38962d591a8SYue Hin Lau 				watermarks->a.cstate_pstate.cstate_exit_ns,
39062d591a8SYue Hin Lau 				refclk_mhz, 0x1fffff);
39191f28756SYongqiang Sun 		REG_SET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A, 0,
39291f28756SYongqiang Sun 				DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A, prog_wm_value);
3931296423bSBhawanpreet Lakha 		DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_A calculated =%d\n"
39462d591a8SYue Hin Lau 			"HW register value = 0x%x\n",
39562d591a8SYue Hin Lau 			watermarks->a.cstate_pstate.cstate_exit_ns, prog_wm_value);
39689e94bc5SYongqiang Sun 	} else if (watermarks->a.cstate_pstate.cstate_exit_ns
39789e94bc5SYongqiang Sun 			< hubbub1->watermarks.a.cstate_pstate.cstate_exit_ns)
39889e94bc5SYongqiang Sun 		wm_pending = true;
39962d591a8SYue Hin Lau 
40062d591a8SYue Hin Lau 	/* clock state B */
401d7b539d3SDmytro Laktyushkin 	if (safe_to_lower || watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns
40289c4f84bSEryk Brol 			> hubbub1->watermarks.b.cstate_pstate.cstate_enter_plus_exit_ns) {
40389c4f84bSEryk Brol 		hubbub1->watermarks.b.cstate_pstate.cstate_enter_plus_exit_ns =
404d7b539d3SDmytro Laktyushkin 				watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns;
40562d591a8SYue Hin Lau 		prog_wm_value = convert_and_clamp(
40662d591a8SYue Hin Lau 				watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns,
40762d591a8SYue Hin Lau 				refclk_mhz, 0x1fffff);
40891f28756SYongqiang Sun 		REG_SET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, 0,
40991f28756SYongqiang Sun 				DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, prog_wm_value);
410d7b539d3SDmytro Laktyushkin 		DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_B calculated =%d\n"
41162d591a8SYue Hin Lau 			"HW register value = 0x%x\n",
41262d591a8SYue Hin Lau 			watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
41389e94bc5SYongqiang Sun 	} else if (watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns
41489e94bc5SYongqiang Sun 			< hubbub1->watermarks.b.cstate_pstate.cstate_enter_plus_exit_ns)
41589e94bc5SYongqiang Sun 		wm_pending = true;
41662d591a8SYue Hin Lau 
417d7b539d3SDmytro Laktyushkin 	if (safe_to_lower || watermarks->b.cstate_pstate.cstate_exit_ns
41889c4f84bSEryk Brol 			> hubbub1->watermarks.b.cstate_pstate.cstate_exit_ns) {
41989c4f84bSEryk Brol 		hubbub1->watermarks.b.cstate_pstate.cstate_exit_ns =
420d7b539d3SDmytro Laktyushkin 				watermarks->b.cstate_pstate.cstate_exit_ns;
42162d591a8SYue Hin Lau 		prog_wm_value = convert_and_clamp(
42262d591a8SYue Hin Lau 				watermarks->b.cstate_pstate.cstate_exit_ns,
42362d591a8SYue Hin Lau 				refclk_mhz, 0x1fffff);
42491f28756SYongqiang Sun 		REG_SET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, 0,
42591f28756SYongqiang Sun 				DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, prog_wm_value);
4261296423bSBhawanpreet Lakha 		DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_B calculated =%d\n"
42762d591a8SYue Hin Lau 			"HW register value = 0x%x\n",
42862d591a8SYue Hin Lau 			watermarks->b.cstate_pstate.cstate_exit_ns, prog_wm_value);
42989e94bc5SYongqiang Sun 	} else if (watermarks->b.cstate_pstate.cstate_exit_ns
43089e94bc5SYongqiang Sun 			< hubbub1->watermarks.b.cstate_pstate.cstate_exit_ns)
43189e94bc5SYongqiang Sun 		wm_pending = true;
43262d591a8SYue Hin Lau 
43362d591a8SYue Hin Lau 	/* clock state C */
434d7b539d3SDmytro Laktyushkin 	if (safe_to_lower || watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns
43589c4f84bSEryk Brol 			> hubbub1->watermarks.c.cstate_pstate.cstate_enter_plus_exit_ns) {
43689c4f84bSEryk Brol 		hubbub1->watermarks.c.cstate_pstate.cstate_enter_plus_exit_ns =
437d7b539d3SDmytro Laktyushkin 				watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns;
43862d591a8SYue Hin Lau 		prog_wm_value = convert_and_clamp(
43962d591a8SYue Hin Lau 				watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns,
44062d591a8SYue Hin Lau 				refclk_mhz, 0x1fffff);
44191f28756SYongqiang Sun 		REG_SET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, 0,
44291f28756SYongqiang Sun 				DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, prog_wm_value);
443d7b539d3SDmytro Laktyushkin 		DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_C calculated =%d\n"
44462d591a8SYue Hin Lau 			"HW register value = 0x%x\n",
44562d591a8SYue Hin Lau 			watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
44689e94bc5SYongqiang Sun 	} else if (watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns
44789e94bc5SYongqiang Sun 			< hubbub1->watermarks.c.cstate_pstate.cstate_enter_plus_exit_ns)
44889e94bc5SYongqiang Sun 		wm_pending = true;
44962d591a8SYue Hin Lau 
450d7b539d3SDmytro Laktyushkin 	if (safe_to_lower || watermarks->c.cstate_pstate.cstate_exit_ns
45189c4f84bSEryk Brol 			> hubbub1->watermarks.c.cstate_pstate.cstate_exit_ns) {
45289c4f84bSEryk Brol 		hubbub1->watermarks.c.cstate_pstate.cstate_exit_ns =
453d7b539d3SDmytro Laktyushkin 				watermarks->c.cstate_pstate.cstate_exit_ns;
45462d591a8SYue Hin Lau 		prog_wm_value = convert_and_clamp(
45562d591a8SYue Hin Lau 				watermarks->c.cstate_pstate.cstate_exit_ns,
45662d591a8SYue Hin Lau 				refclk_mhz, 0x1fffff);
45791f28756SYongqiang Sun 		REG_SET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C, 0,
45891f28756SYongqiang Sun 				DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C, prog_wm_value);
4591296423bSBhawanpreet Lakha 		DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_C calculated =%d\n"
46062d591a8SYue Hin Lau 			"HW register value = 0x%x\n",
46162d591a8SYue Hin Lau 			watermarks->c.cstate_pstate.cstate_exit_ns, prog_wm_value);
46289e94bc5SYongqiang Sun 	} else if (watermarks->c.cstate_pstate.cstate_exit_ns
46389e94bc5SYongqiang Sun 			< hubbub1->watermarks.c.cstate_pstate.cstate_exit_ns)
46489e94bc5SYongqiang Sun 		wm_pending = true;
46562d591a8SYue Hin Lau 
46662d591a8SYue Hin Lau 	/* clock state D */
467d7b539d3SDmytro Laktyushkin 	if (safe_to_lower || watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns
46889c4f84bSEryk Brol 			> hubbub1->watermarks.d.cstate_pstate.cstate_enter_plus_exit_ns) {
46989c4f84bSEryk Brol 		hubbub1->watermarks.d.cstate_pstate.cstate_enter_plus_exit_ns =
470d7b539d3SDmytro Laktyushkin 				watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns;
47162d591a8SYue Hin Lau 		prog_wm_value = convert_and_clamp(
47262d591a8SYue Hin Lau 				watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns,
47362d591a8SYue Hin Lau 				refclk_mhz, 0x1fffff);
47491f28756SYongqiang Sun 		REG_SET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, 0,
47591f28756SYongqiang Sun 				DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, prog_wm_value);
476d7b539d3SDmytro Laktyushkin 		DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_D calculated =%d\n"
47762d591a8SYue Hin Lau 			"HW register value = 0x%x\n",
47862d591a8SYue Hin Lau 			watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
47989e94bc5SYongqiang Sun 	} else if (watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns
48089e94bc5SYongqiang Sun 			< hubbub1->watermarks.d.cstate_pstate.cstate_enter_plus_exit_ns)
48189e94bc5SYongqiang Sun 		wm_pending = true;
48262d591a8SYue Hin Lau 
483d7b539d3SDmytro Laktyushkin 	if (safe_to_lower || watermarks->d.cstate_pstate.cstate_exit_ns
48489c4f84bSEryk Brol 			> hubbub1->watermarks.d.cstate_pstate.cstate_exit_ns) {
48589c4f84bSEryk Brol 		hubbub1->watermarks.d.cstate_pstate.cstate_exit_ns =
486d7b539d3SDmytro Laktyushkin 				watermarks->d.cstate_pstate.cstate_exit_ns;
48762d591a8SYue Hin Lau 		prog_wm_value = convert_and_clamp(
48862d591a8SYue Hin Lau 				watermarks->d.cstate_pstate.cstate_exit_ns,
48962d591a8SYue Hin Lau 				refclk_mhz, 0x1fffff);
49091f28756SYongqiang Sun 		REG_SET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D, 0,
49191f28756SYongqiang Sun 				DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D, prog_wm_value);
4921296423bSBhawanpreet Lakha 		DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_D calculated =%d\n"
49362d591a8SYue Hin Lau 			"HW register value = 0x%x\n",
49462d591a8SYue Hin Lau 			watermarks->d.cstate_pstate.cstate_exit_ns, prog_wm_value);
49589e94bc5SYongqiang Sun 	} else if (watermarks->d.cstate_pstate.cstate_exit_ns
49689e94bc5SYongqiang Sun 			< hubbub1->watermarks.d.cstate_pstate.cstate_exit_ns)
49789e94bc5SYongqiang Sun 		wm_pending = true;
49889e94bc5SYongqiang Sun 
49989e94bc5SYongqiang Sun 	return wm_pending;
50062d591a8SYue Hin Lau }
50114ed3d00SYongqiang Sun 
hubbub1_program_pstate_watermarks(struct hubbub * hubbub,struct dcn_watermark_set * watermarks,unsigned int refclk_mhz,bool safe_to_lower)50289e94bc5SYongqiang Sun bool hubbub1_program_pstate_watermarks(
50314ed3d00SYongqiang Sun 		struct hubbub *hubbub,
50414ed3d00SYongqiang Sun 		struct dcn_watermark_set *watermarks,
50514ed3d00SYongqiang Sun 		unsigned int refclk_mhz,
50614ed3d00SYongqiang Sun 		bool safe_to_lower)
50714ed3d00SYongqiang Sun {
50814ed3d00SYongqiang Sun 	struct dcn10_hubbub *hubbub1 = TO_DCN10_HUBBUB(hubbub);
50914ed3d00SYongqiang Sun 	uint32_t prog_wm_value;
51089e94bc5SYongqiang Sun 	bool wm_pending = false;
51114ed3d00SYongqiang Sun 
51214ed3d00SYongqiang Sun 	/* clock state A */
51314ed3d00SYongqiang Sun 	if (safe_to_lower || watermarks->a.cstate_pstate.pstate_change_ns
51414ed3d00SYongqiang Sun 			> hubbub1->watermarks.a.cstate_pstate.pstate_change_ns) {
51514ed3d00SYongqiang Sun 		hubbub1->watermarks.a.cstate_pstate.pstate_change_ns =
51614ed3d00SYongqiang Sun 				watermarks->a.cstate_pstate.pstate_change_ns;
51714ed3d00SYongqiang Sun 		prog_wm_value = convert_and_clamp(
51814ed3d00SYongqiang Sun 				watermarks->a.cstate_pstate.pstate_change_ns,
51914ed3d00SYongqiang Sun 				refclk_mhz, 0x1fffff);
52014ed3d00SYongqiang Sun 		REG_SET(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A, 0,
52114ed3d00SYongqiang Sun 				DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A, prog_wm_value);
52214ed3d00SYongqiang Sun 		DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_A calculated =%d\n"
52314ed3d00SYongqiang Sun 			"HW register value = 0x%x\n\n",
52414ed3d00SYongqiang Sun 			watermarks->a.cstate_pstate.pstate_change_ns, prog_wm_value);
52589e94bc5SYongqiang Sun 	} else if (watermarks->a.cstate_pstate.pstate_change_ns
52689e94bc5SYongqiang Sun 			< hubbub1->watermarks.a.cstate_pstate.pstate_change_ns)
52789e94bc5SYongqiang Sun 		wm_pending = true;
52814ed3d00SYongqiang Sun 
52914ed3d00SYongqiang Sun 	/* clock state B */
53014ed3d00SYongqiang Sun 	if (safe_to_lower || watermarks->b.cstate_pstate.pstate_change_ns
53114ed3d00SYongqiang Sun 			> hubbub1->watermarks.b.cstate_pstate.pstate_change_ns) {
53214ed3d00SYongqiang Sun 		hubbub1->watermarks.b.cstate_pstate.pstate_change_ns =
53314ed3d00SYongqiang Sun 				watermarks->b.cstate_pstate.pstate_change_ns;
53414ed3d00SYongqiang Sun 		prog_wm_value = convert_and_clamp(
53514ed3d00SYongqiang Sun 				watermarks->b.cstate_pstate.pstate_change_ns,
53614ed3d00SYongqiang Sun 				refclk_mhz, 0x1fffff);
53714ed3d00SYongqiang Sun 		REG_SET(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B, 0,
53814ed3d00SYongqiang Sun 				DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B, prog_wm_value);
53914ed3d00SYongqiang Sun 		DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_B calculated =%d\n"
54014ed3d00SYongqiang Sun 			"HW register value = 0x%x\n\n",
54114ed3d00SYongqiang Sun 			watermarks->b.cstate_pstate.pstate_change_ns, prog_wm_value);
54289e94bc5SYongqiang Sun 	} else if (watermarks->b.cstate_pstate.pstate_change_ns
54389e94bc5SYongqiang Sun 			< hubbub1->watermarks.b.cstate_pstate.pstate_change_ns)
54489e94bc5SYongqiang Sun 		wm_pending = true;
54514ed3d00SYongqiang Sun 
54614ed3d00SYongqiang Sun 	/* clock state C */
54714ed3d00SYongqiang Sun 	if (safe_to_lower || watermarks->c.cstate_pstate.pstate_change_ns
54814ed3d00SYongqiang Sun 			> hubbub1->watermarks.c.cstate_pstate.pstate_change_ns) {
54914ed3d00SYongqiang Sun 		hubbub1->watermarks.c.cstate_pstate.pstate_change_ns =
55014ed3d00SYongqiang Sun 				watermarks->c.cstate_pstate.pstate_change_ns;
55114ed3d00SYongqiang Sun 		prog_wm_value = convert_and_clamp(
55214ed3d00SYongqiang Sun 				watermarks->c.cstate_pstate.pstate_change_ns,
55314ed3d00SYongqiang Sun 				refclk_mhz, 0x1fffff);
55414ed3d00SYongqiang Sun 		REG_SET(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C, 0,
55514ed3d00SYongqiang Sun 				DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C, prog_wm_value);
55614ed3d00SYongqiang Sun 		DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_C calculated =%d\n"
55714ed3d00SYongqiang Sun 			"HW register value = 0x%x\n\n",
55814ed3d00SYongqiang Sun 			watermarks->c.cstate_pstate.pstate_change_ns, prog_wm_value);
55989e94bc5SYongqiang Sun 	} else if (watermarks->c.cstate_pstate.pstate_change_ns
56089e94bc5SYongqiang Sun 			< hubbub1->watermarks.c.cstate_pstate.pstate_change_ns)
56189e94bc5SYongqiang Sun 		wm_pending = true;
56214ed3d00SYongqiang Sun 
56314ed3d00SYongqiang Sun 	/* clock state D */
564d7b539d3SDmytro Laktyushkin 	if (safe_to_lower || watermarks->d.cstate_pstate.pstate_change_ns
56589c4f84bSEryk Brol 			> hubbub1->watermarks.d.cstate_pstate.pstate_change_ns) {
56689c4f84bSEryk Brol 		hubbub1->watermarks.d.cstate_pstate.pstate_change_ns =
567d7b539d3SDmytro Laktyushkin 				watermarks->d.cstate_pstate.pstate_change_ns;
56862d591a8SYue Hin Lau 		prog_wm_value = convert_and_clamp(
56962d591a8SYue Hin Lau 				watermarks->d.cstate_pstate.pstate_change_ns,
57062d591a8SYue Hin Lau 				refclk_mhz, 0x1fffff);
57191f28756SYongqiang Sun 		REG_SET(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D, 0,
57291f28756SYongqiang Sun 				DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D, prog_wm_value);
5731296423bSBhawanpreet Lakha 		DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_D calculated =%d\n"
57462d591a8SYue Hin Lau 			"HW register value = 0x%x\n\n",
57562d591a8SYue Hin Lau 			watermarks->d.cstate_pstate.pstate_change_ns, prog_wm_value);
57689e94bc5SYongqiang Sun 	} else if (watermarks->d.cstate_pstate.pstate_change_ns
57789e94bc5SYongqiang Sun 			< hubbub1->watermarks.d.cstate_pstate.pstate_change_ns)
57889e94bc5SYongqiang Sun 		wm_pending = true;
57989e94bc5SYongqiang Sun 
58089e94bc5SYongqiang Sun 	return wm_pending;
58114ed3d00SYongqiang Sun }
58214ed3d00SYongqiang Sun 
hubbub1_program_watermarks(struct hubbub * hubbub,struct dcn_watermark_set * watermarks,unsigned int refclk_mhz,bool safe_to_lower)58389e94bc5SYongqiang Sun bool hubbub1_program_watermarks(
58414ed3d00SYongqiang Sun 		struct hubbub *hubbub,
58514ed3d00SYongqiang Sun 		struct dcn_watermark_set *watermarks,
58614ed3d00SYongqiang Sun 		unsigned int refclk_mhz,
58714ed3d00SYongqiang Sun 		bool safe_to_lower)
58814ed3d00SYongqiang Sun {
58914ed3d00SYongqiang Sun 	struct dcn10_hubbub *hubbub1 = TO_DCN10_HUBBUB(hubbub);
59089e94bc5SYongqiang Sun 	bool wm_pending = false;
59114ed3d00SYongqiang Sun 	/*
59214ed3d00SYongqiang Sun 	 * Need to clamp to max of the register values (i.e. no wrap)
59314ed3d00SYongqiang Sun 	 * for dcn1, all wm registers are 21-bit wide
59414ed3d00SYongqiang Sun 	 */
59589e94bc5SYongqiang Sun 	if (hubbub1_program_urgent_watermarks(hubbub, watermarks, refclk_mhz, safe_to_lower))
59689e94bc5SYongqiang Sun 		wm_pending = true;
59789e94bc5SYongqiang Sun 
59889e94bc5SYongqiang Sun 	if (hubbub1_program_stutter_watermarks(hubbub, watermarks, refclk_mhz, safe_to_lower))
59989e94bc5SYongqiang Sun 		wm_pending = true;
60089e94bc5SYongqiang Sun 
60189e94bc5SYongqiang Sun 	if (hubbub1_program_pstate_watermarks(hubbub, watermarks, refclk_mhz, safe_to_lower))
60289e94bc5SYongqiang Sun 		wm_pending = true;
60362d591a8SYue Hin Lau 
60462d591a8SYue Hin Lau 	REG_UPDATE(DCHUBBUB_ARB_SAT_LEVEL,
60562d591a8SYue Hin Lau 			DCHUBBUB_ARB_SAT_LEVEL, 60 * refclk_mhz);
60662d591a8SYue Hin Lau 	REG_UPDATE(DCHUBBUB_ARB_DF_REQ_OUTSTAND,
60762d591a8SYue Hin Lau 			DCHUBBUB_ARB_MIN_REQ_OUTSTAND, 68);
60862d591a8SYue Hin Lau 
609b9d4b330SWesley Chalmers 	hubbub1_allow_self_refresh_control(hubbub, !hubbub->ctx->dc->debug.disable_stutter);
61062d591a8SYue Hin Lau 
61162d591a8SYue Hin Lau #if 0
61262d591a8SYue Hin Lau 	REG_UPDATE_2(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL,
61362d591a8SYue Hin Lau 			DCHUBBUB_ARB_WATERMARK_CHANGE_DONE_INTERRUPT_DISABLE, 1,
61462d591a8SYue Hin Lau 			DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, 1);
61562d591a8SYue Hin Lau #endif
61689e94bc5SYongqiang Sun 	return wm_pending;
61762d591a8SYue Hin Lau }
61862d591a8SYue Hin Lau 
hubbub1_update_dchub(struct hubbub * hubbub,struct dchub_init_data * dh_data)619c9ef081dSYue Hin Lau void hubbub1_update_dchub(
620c9ef081dSYue Hin Lau 	struct hubbub *hubbub,
62162d591a8SYue Hin Lau 	struct dchub_init_data *dh_data)
62262d591a8SYue Hin Lau {
62389c4f84bSEryk Brol 	struct dcn10_hubbub *hubbub1 = TO_DCN10_HUBBUB(hubbub);
62489c4f84bSEryk Brol 
6257f93c1deSCharlene Liu 	if (REG(DCHUBBUB_SDPIF_FB_TOP) == 0) {
6267f93c1deSCharlene Liu 		ASSERT(false);
6277f93c1deSCharlene Liu 		/*should not come here*/
6287f93c1deSCharlene Liu 		return;
6297f93c1deSCharlene Liu 	}
63062d591a8SYue Hin Lau 	/* TODO: port code from dal2 */
63162d591a8SYue Hin Lau 	switch (dh_data->fb_mode) {
63262d591a8SYue Hin Lau 	case FRAME_BUFFER_MODE_ZFB_ONLY:
63362d591a8SYue Hin Lau 		/*For ZFB case need to put DCHUB FB BASE and TOP upside down to indicate ZFB mode*/
63462d591a8SYue Hin Lau 		REG_UPDATE(DCHUBBUB_SDPIF_FB_TOP,
63562d591a8SYue Hin Lau 				SDPIF_FB_TOP, 0);
63662d591a8SYue Hin Lau 
63762d591a8SYue Hin Lau 		REG_UPDATE(DCHUBBUB_SDPIF_FB_BASE,
63862d591a8SYue Hin Lau 				SDPIF_FB_BASE, 0x0FFFF);
63962d591a8SYue Hin Lau 
64062d591a8SYue Hin Lau 		REG_UPDATE(DCHUBBUB_SDPIF_AGP_BASE,
64162d591a8SYue Hin Lau 				SDPIF_AGP_BASE, dh_data->zfb_phys_addr_base >> 22);
64262d591a8SYue Hin Lau 
64362d591a8SYue Hin Lau 		REG_UPDATE(DCHUBBUB_SDPIF_AGP_BOT,
64462d591a8SYue Hin Lau 				SDPIF_AGP_BOT, dh_data->zfb_mc_base_addr >> 22);
64562d591a8SYue Hin Lau 
64662d591a8SYue Hin Lau 		REG_UPDATE(DCHUBBUB_SDPIF_AGP_TOP,
64762d591a8SYue Hin Lau 				SDPIF_AGP_TOP, (dh_data->zfb_mc_base_addr +
64862d591a8SYue Hin Lau 						dh_data->zfb_size_in_byte - 1) >> 22);
64962d591a8SYue Hin Lau 		break;
65062d591a8SYue Hin Lau 	case FRAME_BUFFER_MODE_MIXED_ZFB_AND_LOCAL:
65162d591a8SYue Hin Lau 		/*Should not touch FB LOCATION (done by VBIOS on AsicInit table)*/
65262d591a8SYue Hin Lau 
65362d591a8SYue Hin Lau 		REG_UPDATE(DCHUBBUB_SDPIF_AGP_BASE,
65462d591a8SYue Hin Lau 				SDPIF_AGP_BASE, dh_data->zfb_phys_addr_base >> 22);
65562d591a8SYue Hin Lau 
65662d591a8SYue Hin Lau 		REG_UPDATE(DCHUBBUB_SDPIF_AGP_BOT,
65762d591a8SYue Hin Lau 				SDPIF_AGP_BOT, dh_data->zfb_mc_base_addr >> 22);
65862d591a8SYue Hin Lau 
65962d591a8SYue Hin Lau 		REG_UPDATE(DCHUBBUB_SDPIF_AGP_TOP,
66062d591a8SYue Hin Lau 				SDPIF_AGP_TOP, (dh_data->zfb_mc_base_addr +
66162d591a8SYue Hin Lau 						dh_data->zfb_size_in_byte - 1) >> 22);
66262d591a8SYue Hin Lau 		break;
66362d591a8SYue Hin Lau 	case FRAME_BUFFER_MODE_LOCAL_ONLY:
66462d591a8SYue Hin Lau 		/*Should not touch FB LOCATION (done by VBIOS on AsicInit table)*/
66562d591a8SYue Hin Lau 		REG_UPDATE(DCHUBBUB_SDPIF_AGP_BASE,
66662d591a8SYue Hin Lau 				SDPIF_AGP_BASE, 0);
66762d591a8SYue Hin Lau 
66862d591a8SYue Hin Lau 		REG_UPDATE(DCHUBBUB_SDPIF_AGP_BOT,
66962d591a8SYue Hin Lau 				SDPIF_AGP_BOT, 0X03FFFF);
67062d591a8SYue Hin Lau 
67162d591a8SYue Hin Lau 		REG_UPDATE(DCHUBBUB_SDPIF_AGP_TOP,
67262d591a8SYue Hin Lau 				SDPIF_AGP_TOP, 0);
67362d591a8SYue Hin Lau 		break;
67462d591a8SYue Hin Lau 	default:
67562d591a8SYue Hin Lau 		break;
67662d591a8SYue Hin Lau 	}
67762d591a8SYue Hin Lau 
67862d591a8SYue Hin Lau 	dh_data->dchub_initialzied = true;
67962d591a8SYue Hin Lau 	dh_data->dchub_info_valid = false;
68062d591a8SYue Hin Lau }
68162d591a8SYue Hin Lau 
hubbub1_toggle_watermark_change_req(struct hubbub * hubbub)682ea00f297SYue Hin Lau void hubbub1_toggle_watermark_change_req(struct hubbub *hubbub)
68362d591a8SYue Hin Lau {
68489c4f84bSEryk Brol 	struct dcn10_hubbub *hubbub1 = TO_DCN10_HUBBUB(hubbub);
68589c4f84bSEryk Brol 
68662d591a8SYue Hin Lau 	uint32_t watermark_change_req;
68762d591a8SYue Hin Lau 
68862d591a8SYue Hin Lau 	REG_GET(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL,
68962d591a8SYue Hin Lau 			DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, &watermark_change_req);
69062d591a8SYue Hin Lau 
69162d591a8SYue Hin Lau 	if (watermark_change_req)
69262d591a8SYue Hin Lau 		watermark_change_req = 0;
69362d591a8SYue Hin Lau 	else
69462d591a8SYue Hin Lau 		watermark_change_req = 1;
69562d591a8SYue Hin Lau 
69662d591a8SYue Hin Lau 	REG_UPDATE(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL,
69762d591a8SYue Hin Lau 			DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, watermark_change_req);
69862d591a8SYue Hin Lau }
69962d591a8SYue Hin Lau 
hubbub1_soft_reset(struct hubbub * hubbub,bool reset)7003ba43a59SCharlene Liu void hubbub1_soft_reset(struct hubbub *hubbub, bool reset)
7013ba43a59SCharlene Liu {
70289c4f84bSEryk Brol 	struct dcn10_hubbub *hubbub1 = TO_DCN10_HUBBUB(hubbub);
70389c4f84bSEryk Brol 
7043ba43a59SCharlene Liu 	uint32_t reset_en = reset ? 1 : 0;
7053ba43a59SCharlene Liu 
7063ba43a59SCharlene Liu 	REG_UPDATE(DCHUBBUB_SOFT_RESET,
7073ba43a59SCharlene Liu 			DCHUBBUB_GLOBAL_SOFT_RESET, reset_en);
7083ba43a59SCharlene Liu }
7093ba43a59SCharlene Liu 
hubbub1_dcc_support_swizzle(enum swizzle_mode_values swizzle,unsigned int bytes_per_element,enum segment_order * segment_order_horz,enum segment_order * segment_order_vert)7105ebfb7a5SEric Bernstein static bool hubbub1_dcc_support_swizzle(
7115ebfb7a5SEric Bernstein 		enum swizzle_mode_values swizzle,
7125ebfb7a5SEric Bernstein 		unsigned int bytes_per_element,
7135ebfb7a5SEric Bernstein 		enum segment_order *segment_order_horz,
7145ebfb7a5SEric Bernstein 		enum segment_order *segment_order_vert)
7155ebfb7a5SEric Bernstein {
7165ebfb7a5SEric Bernstein 	bool standard_swizzle = false;
7175ebfb7a5SEric Bernstein 	bool display_swizzle = false;
7185ebfb7a5SEric Bernstein 
7195ebfb7a5SEric Bernstein 	switch (swizzle) {
7205ebfb7a5SEric Bernstein 	case DC_SW_4KB_S:
7215ebfb7a5SEric Bernstein 	case DC_SW_64KB_S:
7225ebfb7a5SEric Bernstein 	case DC_SW_VAR_S:
7235ebfb7a5SEric Bernstein 	case DC_SW_4KB_S_X:
7245ebfb7a5SEric Bernstein 	case DC_SW_64KB_S_X:
7255ebfb7a5SEric Bernstein 	case DC_SW_VAR_S_X:
7265ebfb7a5SEric Bernstein 		standard_swizzle = true;
7275ebfb7a5SEric Bernstein 		break;
7285ebfb7a5SEric Bernstein 	case DC_SW_4KB_D:
7295ebfb7a5SEric Bernstein 	case DC_SW_64KB_D:
7305ebfb7a5SEric Bernstein 	case DC_SW_VAR_D:
7315ebfb7a5SEric Bernstein 	case DC_SW_4KB_D_X:
7325ebfb7a5SEric Bernstein 	case DC_SW_64KB_D_X:
7335ebfb7a5SEric Bernstein 	case DC_SW_VAR_D_X:
7345ebfb7a5SEric Bernstein 		display_swizzle = true;
7355ebfb7a5SEric Bernstein 		break;
7365ebfb7a5SEric Bernstein 	default:
7375ebfb7a5SEric Bernstein 		break;
7385ebfb7a5SEric Bernstein 	}
7395ebfb7a5SEric Bernstein 
7405ebfb7a5SEric Bernstein 	if (bytes_per_element == 1 && standard_swizzle) {
7415ebfb7a5SEric Bernstein 		*segment_order_horz = segment_order__contiguous;
7425ebfb7a5SEric Bernstein 		*segment_order_vert = segment_order__na;
7435ebfb7a5SEric Bernstein 		return true;
7445ebfb7a5SEric Bernstein 	}
7455ebfb7a5SEric Bernstein 	if (bytes_per_element == 2 && standard_swizzle) {
7465ebfb7a5SEric Bernstein 		*segment_order_horz = segment_order__non_contiguous;
7475ebfb7a5SEric Bernstein 		*segment_order_vert = segment_order__contiguous;
7485ebfb7a5SEric Bernstein 		return true;
7495ebfb7a5SEric Bernstein 	}
7505ebfb7a5SEric Bernstein 	if (bytes_per_element == 4 && standard_swizzle) {
7515ebfb7a5SEric Bernstein 		*segment_order_horz = segment_order__non_contiguous;
7525ebfb7a5SEric Bernstein 		*segment_order_vert = segment_order__contiguous;
7535ebfb7a5SEric Bernstein 		return true;
7545ebfb7a5SEric Bernstein 	}
7555ebfb7a5SEric Bernstein 	if (bytes_per_element == 8 && standard_swizzle) {
7565ebfb7a5SEric Bernstein 		*segment_order_horz = segment_order__na;
7575ebfb7a5SEric Bernstein 		*segment_order_vert = segment_order__contiguous;
7585ebfb7a5SEric Bernstein 		return true;
7595ebfb7a5SEric Bernstein 	}
7605ebfb7a5SEric Bernstein 	if (bytes_per_element == 8 && display_swizzle) {
7615ebfb7a5SEric Bernstein 		*segment_order_horz = segment_order__contiguous;
7625ebfb7a5SEric Bernstein 		*segment_order_vert = segment_order__non_contiguous;
7635ebfb7a5SEric Bernstein 		return true;
7645ebfb7a5SEric Bernstein 	}
7655ebfb7a5SEric Bernstein 
7665ebfb7a5SEric Bernstein 	return false;
7675ebfb7a5SEric Bernstein }
7685ebfb7a5SEric Bernstein 
hubbub1_dcc_support_pixel_format(enum surface_pixel_format format,unsigned int * bytes_per_element)7695ebfb7a5SEric Bernstein static bool hubbub1_dcc_support_pixel_format(
7705ebfb7a5SEric Bernstein 		enum surface_pixel_format format,
7715ebfb7a5SEric Bernstein 		unsigned int *bytes_per_element)
7725ebfb7a5SEric Bernstein {
7735ebfb7a5SEric Bernstein 	/* DML: get_bytes_per_element */
7745ebfb7a5SEric Bernstein 	switch (format) {
7755ebfb7a5SEric Bernstein 	case SURFACE_PIXEL_FORMAT_GRPH_ARGB1555:
7765ebfb7a5SEric Bernstein 	case SURFACE_PIXEL_FORMAT_GRPH_RGB565:
7775ebfb7a5SEric Bernstein 		*bytes_per_element = 2;
7785ebfb7a5SEric Bernstein 		return true;
7795ebfb7a5SEric Bernstein 	case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888:
7805ebfb7a5SEric Bernstein 	case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888:
7815ebfb7a5SEric Bernstein 	case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010:
7825ebfb7a5SEric Bernstein 	case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010:
7835ebfb7a5SEric Bernstein 		*bytes_per_element = 4;
7845ebfb7a5SEric Bernstein 		return true;
7855ebfb7a5SEric Bernstein 	case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
786050cd3d6SMario Kleiner 	case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616:
7875ebfb7a5SEric Bernstein 	case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
7885ebfb7a5SEric Bernstein 	case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
7895ebfb7a5SEric Bernstein 		*bytes_per_element = 8;
7905ebfb7a5SEric Bernstein 		return true;
7915ebfb7a5SEric Bernstein 	default:
7925ebfb7a5SEric Bernstein 		return false;
7935ebfb7a5SEric Bernstein 	}
7945ebfb7a5SEric Bernstein }
7955ebfb7a5SEric Bernstein 
hubbub1_get_blk256_size(unsigned int * blk256_width,unsigned int * blk256_height,unsigned int bytes_per_element)7965ebfb7a5SEric Bernstein static void hubbub1_get_blk256_size(unsigned int *blk256_width, unsigned int *blk256_height,
7975ebfb7a5SEric Bernstein 		unsigned int bytes_per_element)
7985ebfb7a5SEric Bernstein {
7995ebfb7a5SEric Bernstein 	/* copied from DML.  might want to refactor DML to leverage from DML */
8005ebfb7a5SEric Bernstein 	/* DML : get_blk256_size */
8015ebfb7a5SEric Bernstein 	if (bytes_per_element == 1) {
8025ebfb7a5SEric Bernstein 		*blk256_width = 16;
8035ebfb7a5SEric Bernstein 		*blk256_height = 16;
8045ebfb7a5SEric Bernstein 	} else if (bytes_per_element == 2) {
8055ebfb7a5SEric Bernstein 		*blk256_width = 16;
8065ebfb7a5SEric Bernstein 		*blk256_height = 8;
8075ebfb7a5SEric Bernstein 	} else if (bytes_per_element == 4) {
8085ebfb7a5SEric Bernstein 		*blk256_width = 8;
8095ebfb7a5SEric Bernstein 		*blk256_height = 8;
8105ebfb7a5SEric Bernstein 	} else if (bytes_per_element == 8) {
8115ebfb7a5SEric Bernstein 		*blk256_width = 8;
8125ebfb7a5SEric Bernstein 		*blk256_height = 4;
8135ebfb7a5SEric Bernstein 	}
8145ebfb7a5SEric Bernstein }
8155ebfb7a5SEric Bernstein 
hubbub1_det_request_size(unsigned int height,unsigned int width,unsigned int bpe,bool * req128_horz_wc,bool * req128_vert_wc)8165ebfb7a5SEric Bernstein static void hubbub1_det_request_size(
8175ebfb7a5SEric Bernstein 		unsigned int height,
8185ebfb7a5SEric Bernstein 		unsigned int width,
8195ebfb7a5SEric Bernstein 		unsigned int bpe,
8205ebfb7a5SEric Bernstein 		bool *req128_horz_wc,
8215ebfb7a5SEric Bernstein 		bool *req128_vert_wc)
8225ebfb7a5SEric Bernstein {
8235ebfb7a5SEric Bernstein 	unsigned int detile_buf_size = 164 * 1024;  /* 164KB for DCN1.0 */
8245ebfb7a5SEric Bernstein 
8255ebfb7a5SEric Bernstein 	unsigned int blk256_height = 0;
8265ebfb7a5SEric Bernstein 	unsigned int blk256_width = 0;
8275ebfb7a5SEric Bernstein 	unsigned int swath_bytes_horz_wc, swath_bytes_vert_wc;
8285ebfb7a5SEric Bernstein 
8295ebfb7a5SEric Bernstein 	hubbub1_get_blk256_size(&blk256_width, &blk256_height, bpe);
8305ebfb7a5SEric Bernstein 
831a0275dfcSJosip Pavic 	swath_bytes_horz_wc = width * blk256_height * bpe;
832a0275dfcSJosip Pavic 	swath_bytes_vert_wc = height * blk256_width * bpe;
8335ebfb7a5SEric Bernstein 
8345ebfb7a5SEric Bernstein 	*req128_horz_wc = (2 * swath_bytes_horz_wc <= detile_buf_size) ?
8355ebfb7a5SEric Bernstein 			false : /* full 256B request */
8365ebfb7a5SEric Bernstein 			true; /* half 128b request */
8375ebfb7a5SEric Bernstein 
8385ebfb7a5SEric Bernstein 	*req128_vert_wc = (2 * swath_bytes_vert_wc <= detile_buf_size) ?
8395ebfb7a5SEric Bernstein 			false : /* full 256B request */
8405ebfb7a5SEric Bernstein 			true; /* half 128b request */
8415ebfb7a5SEric Bernstein }
8425ebfb7a5SEric Bernstein 
hubbub1_get_dcc_compression_cap(struct hubbub * hubbub,const struct dc_dcc_surface_param * input,struct dc_surface_dcc_cap * output)8435ebfb7a5SEric Bernstein static bool hubbub1_get_dcc_compression_cap(struct hubbub *hubbub,
8445ebfb7a5SEric Bernstein 		const struct dc_dcc_surface_param *input,
8455ebfb7a5SEric Bernstein 		struct dc_surface_dcc_cap *output)
8465ebfb7a5SEric Bernstein {
84789c4f84bSEryk Brol 	struct dcn10_hubbub *hubbub1 = TO_DCN10_HUBBUB(hubbub);
84889c4f84bSEryk Brol 	struct dc *dc = hubbub1->base.ctx->dc;
84989c4f84bSEryk Brol 
8505ebfb7a5SEric Bernstein 	/* implement section 1.6.2.1 of DCN1_Programming_Guide.docx */
8515ebfb7a5SEric Bernstein 	enum dcc_control dcc_control;
8525ebfb7a5SEric Bernstein 	unsigned int bpe;
8535ebfb7a5SEric Bernstein 	enum segment_order segment_order_horz, segment_order_vert;
8545ebfb7a5SEric Bernstein 	bool req128_horz_wc, req128_vert_wc;
8555ebfb7a5SEric Bernstein 
8565ebfb7a5SEric Bernstein 	memset(output, 0, sizeof(*output));
8575ebfb7a5SEric Bernstein 
8585ebfb7a5SEric Bernstein 	if (dc->debug.disable_dcc == DCC_DISABLE)
8595ebfb7a5SEric Bernstein 		return false;
8605ebfb7a5SEric Bernstein 
86189c4f84bSEryk Brol 	if (!hubbub1->base.funcs->dcc_support_pixel_format(input->format, &bpe))
8625ebfb7a5SEric Bernstein 		return false;
8635ebfb7a5SEric Bernstein 
86489c4f84bSEryk Brol 	if (!hubbub1->base.funcs->dcc_support_swizzle(input->swizzle_mode, bpe,
8655ebfb7a5SEric Bernstein 			&segment_order_horz, &segment_order_vert))
8665ebfb7a5SEric Bernstein 		return false;
8675ebfb7a5SEric Bernstein 
8685ebfb7a5SEric Bernstein 	hubbub1_det_request_size(input->surface_size.height,  input->surface_size.width,
8695ebfb7a5SEric Bernstein 			bpe, &req128_horz_wc, &req128_vert_wc);
8705ebfb7a5SEric Bernstein 
8715ebfb7a5SEric Bernstein 	if (!req128_horz_wc && !req128_vert_wc) {
8725ebfb7a5SEric Bernstein 		dcc_control = dcc_control__256_256_xxx;
8735ebfb7a5SEric Bernstein 	} else if (input->scan == SCAN_DIRECTION_HORIZONTAL) {
8745ebfb7a5SEric Bernstein 		if (!req128_horz_wc)
8755ebfb7a5SEric Bernstein 			dcc_control = dcc_control__256_256_xxx;
8765ebfb7a5SEric Bernstein 		else if (segment_order_horz == segment_order__contiguous)
8775ebfb7a5SEric Bernstein 			dcc_control = dcc_control__128_128_xxx;
8785ebfb7a5SEric Bernstein 		else
8795ebfb7a5SEric Bernstein 			dcc_control = dcc_control__256_64_64;
8805ebfb7a5SEric Bernstein 	} else if (input->scan == SCAN_DIRECTION_VERTICAL) {
8815ebfb7a5SEric Bernstein 		if (!req128_vert_wc)
8825ebfb7a5SEric Bernstein 			dcc_control = dcc_control__256_256_xxx;
8835ebfb7a5SEric Bernstein 		else if (segment_order_vert == segment_order__contiguous)
8845ebfb7a5SEric Bernstein 			dcc_control = dcc_control__128_128_xxx;
8855ebfb7a5SEric Bernstein 		else
8865ebfb7a5SEric Bernstein 			dcc_control = dcc_control__256_64_64;
8875ebfb7a5SEric Bernstein 	} else {
8885ebfb7a5SEric Bernstein 		if ((req128_horz_wc &&
8895ebfb7a5SEric Bernstein 			segment_order_horz == segment_order__non_contiguous) ||
8905ebfb7a5SEric Bernstein 			(req128_vert_wc &&
8915ebfb7a5SEric Bernstein 			segment_order_vert == segment_order__non_contiguous))
8925ebfb7a5SEric Bernstein 			/* access_dir not known, must use most constraining */
8935ebfb7a5SEric Bernstein 			dcc_control = dcc_control__256_64_64;
8945ebfb7a5SEric Bernstein 		else
8955ebfb7a5SEric Bernstein 			/* reg128 is true for either horz and vert
8965ebfb7a5SEric Bernstein 			 * but segment_order is contiguous
8975ebfb7a5SEric Bernstein 			 */
8985ebfb7a5SEric Bernstein 			dcc_control = dcc_control__128_128_xxx;
8995ebfb7a5SEric Bernstein 	}
9005ebfb7a5SEric Bernstein 
9015ebfb7a5SEric Bernstein 	if (dc->debug.disable_dcc == DCC_HALF_REQ_DISALBE &&
9025ebfb7a5SEric Bernstein 		dcc_control != dcc_control__256_256_xxx)
9035ebfb7a5SEric Bernstein 		return false;
9045ebfb7a5SEric Bernstein 
9055ebfb7a5SEric Bernstein 	switch (dcc_control) {
9065ebfb7a5SEric Bernstein 	case dcc_control__256_256_xxx:
9075ebfb7a5SEric Bernstein 		output->grph.rgb.max_uncompressed_blk_size = 256;
9085ebfb7a5SEric Bernstein 		output->grph.rgb.max_compressed_blk_size = 256;
9095ebfb7a5SEric Bernstein 		output->grph.rgb.independent_64b_blks = false;
9105ebfb7a5SEric Bernstein 		break;
9115ebfb7a5SEric Bernstein 	case dcc_control__128_128_xxx:
9125ebfb7a5SEric Bernstein 		output->grph.rgb.max_uncompressed_blk_size = 128;
9135ebfb7a5SEric Bernstein 		output->grph.rgb.max_compressed_blk_size = 128;
9145ebfb7a5SEric Bernstein 		output->grph.rgb.independent_64b_blks = false;
9155ebfb7a5SEric Bernstein 		break;
9165ebfb7a5SEric Bernstein 	case dcc_control__256_64_64:
9175ebfb7a5SEric Bernstein 		output->grph.rgb.max_uncompressed_blk_size = 256;
9185ebfb7a5SEric Bernstein 		output->grph.rgb.max_compressed_blk_size = 64;
9195ebfb7a5SEric Bernstein 		output->grph.rgb.independent_64b_blks = true;
9205ebfb7a5SEric Bernstein 		break;
921d905c33aSChris Park 	default:
922d905c33aSChris Park 		ASSERT(false);
923d905c33aSChris Park 		break;
9245ebfb7a5SEric Bernstein 	}
9255ebfb7a5SEric Bernstein 
9265ebfb7a5SEric Bernstein 	output->capable = true;
9275ebfb7a5SEric Bernstein 	output->const_color_support = false;
9285ebfb7a5SEric Bernstein 
9295ebfb7a5SEric Bernstein 	return true;
9305ebfb7a5SEric Bernstein }
9315ebfb7a5SEric Bernstein 
932c9ef081dSYue Hin Lau static const struct hubbub_funcs hubbub1_funcs = {
9335ebfb7a5SEric Bernstein 	.update_dchub = hubbub1_update_dchub,
9345ebfb7a5SEric Bernstein 	.dcc_support_swizzle = hubbub1_dcc_support_swizzle,
9355ebfb7a5SEric Bernstein 	.dcc_support_pixel_format = hubbub1_dcc_support_pixel_format,
9365ebfb7a5SEric Bernstein 	.get_dcc_compression_cap = hubbub1_get_dcc_compression_cap,
937da1043cfSEric Bernstein 	.wm_read_state = hubbub1_wm_read_state,
93891f28756SYongqiang Sun 	.program_watermarks = hubbub1_program_watermarks,
9398a31820bSMartin Leung 	.is_allow_self_refresh_enabled = hubbub1_is_allow_self_refresh_enabled,
9408a31820bSMartin Leung 	.allow_self_refresh_control = hubbub1_allow_self_refresh_control,
941e7031d82SNicholas Kazlauskas 	.verify_allow_pstate_change_high = hubbub1_verify_allow_pstate_change_high,
942c9ef081dSYue Hin Lau };
943c9ef081dSYue Hin Lau 
hubbub1_construct(struct hubbub * hubbub,struct dc_context * ctx,const struct dcn_hubbub_registers * hubbub_regs,const struct dcn_hubbub_shift * hubbub_shift,const struct dcn_hubbub_mask * hubbub_mask)944c9ef081dSYue Hin Lau void hubbub1_construct(struct hubbub *hubbub,
945c9ef081dSYue Hin Lau 	struct dc_context *ctx,
946c9ef081dSYue Hin Lau 	const struct dcn_hubbub_registers *hubbub_regs,
947c9ef081dSYue Hin Lau 	const struct dcn_hubbub_shift *hubbub_shift,
948c9ef081dSYue Hin Lau 	const struct dcn_hubbub_mask *hubbub_mask)
949c9ef081dSYue Hin Lau {
95089c4f84bSEryk Brol 	struct dcn10_hubbub *hubbub1 = TO_DCN10_HUBBUB(hubbub);
951c9ef081dSYue Hin Lau 
95289c4f84bSEryk Brol 	hubbub1->base.ctx = ctx;
953c9ef081dSYue Hin Lau 
95489c4f84bSEryk Brol 	hubbub1->base.funcs = &hubbub1_funcs;
955c9ef081dSYue Hin Lau 
95689c4f84bSEryk Brol 	hubbub1->regs = hubbub_regs;
95789c4f84bSEryk Brol 	hubbub1->shifts = hubbub_shift;
95889c4f84bSEryk Brol 	hubbub1->masks = hubbub_mask;
95989c4f84bSEryk Brol 
96089c4f84bSEryk Brol 	hubbub1->debug_test_index_pstate = 0x7;
961d567cc55SRoman Li 	if (ctx->dce_version == DCN_VERSION_1_01)
96289c4f84bSEryk Brol 		hubbub1->debug_test_index_pstate = 0xB;
963c9ef081dSYue Hin Lau }
96462d591a8SYue Hin Lau 
965