162d591a8SYue Hin Lau /*
262d591a8SYue Hin Lau  * Copyright 2016 Advanced Micro Devices, Inc.
362d591a8SYue Hin Lau  *
462d591a8SYue Hin Lau  * Permission is hereby granted, free of charge, to any person obtaining a
562d591a8SYue Hin Lau  * copy of this software and associated documentation files (the "Software"),
662d591a8SYue Hin Lau  * to deal in the Software without restriction, including without limitation
762d591a8SYue Hin Lau  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
862d591a8SYue Hin Lau  * and/or sell copies of the Software, and to permit persons to whom the
962d591a8SYue Hin Lau  * Software is furnished to do so, subject to the following conditions:
1062d591a8SYue Hin Lau  *
1162d591a8SYue Hin Lau  * The above copyright notice and this permission notice shall be included in
1262d591a8SYue Hin Lau  * all copies or substantial portions of the Software.
1362d591a8SYue Hin Lau  *
1462d591a8SYue Hin Lau  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1562d591a8SYue Hin Lau  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1662d591a8SYue Hin Lau  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
1762d591a8SYue Hin Lau  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
1862d591a8SYue Hin Lau  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
1962d591a8SYue Hin Lau  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
2062d591a8SYue Hin Lau  * OTHER DEALINGS IN THE SOFTWARE.
2162d591a8SYue Hin Lau  *
2262d591a8SYue Hin Lau  * Authors: AMD
2362d591a8SYue Hin Lau  *
2462d591a8SYue Hin Lau  */
2562d591a8SYue Hin Lau 
2662d591a8SYue Hin Lau #include "dm_services.h"
2762d591a8SYue Hin Lau #include "dcn10_hubp.h"
2862d591a8SYue Hin Lau #include "dcn10_hubbub.h"
2962d591a8SYue Hin Lau #include "reg_helper.h"
3062d591a8SYue Hin Lau 
3162d591a8SYue Hin Lau #define CTX \
32c9ef081dSYue Hin Lau 	hubbub->ctx
331296423bSBhawanpreet Lakha #define DC_LOGGER \
341296423bSBhawanpreet Lakha 	hubbub->ctx->logger
3562d591a8SYue Hin Lau #define REG(reg)\
36c9ef081dSYue Hin Lau 	hubbub->regs->reg
3762d591a8SYue Hin Lau 
3862d591a8SYue Hin Lau #undef FN
3962d591a8SYue Hin Lau #define FN(reg_name, field_name) \
40c9ef081dSYue Hin Lau 	hubbub->shifts->field_name, hubbub->masks->field_name
4162d591a8SYue Hin Lau 
42c9ef081dSYue Hin Lau void hubbub1_wm_read_state(struct hubbub *hubbub,
4362d591a8SYue Hin Lau 		struct dcn_hubbub_wm *wm)
4462d591a8SYue Hin Lau {
4562d591a8SYue Hin Lau 	struct dcn_hubbub_wm_set *s;
4662d591a8SYue Hin Lau 
47d39b3acbSKen Chalmers 	memset(wm, 0, sizeof(struct dcn_hubbub_wm));
48d39b3acbSKen Chalmers 
4962d591a8SYue Hin Lau 	s = &wm->sets[0];
5062d591a8SYue Hin Lau 	s->wm_set = 0;
5162d591a8SYue Hin Lau 	s->data_urgent = REG_READ(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A);
5262d591a8SYue Hin Lau 	s->pte_meta_urgent = REG_READ(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_A);
53d39b3acbSKen Chalmers 	if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A)) {
5462d591a8SYue Hin Lau 		s->sr_enter = REG_READ(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A);
5562d591a8SYue Hin Lau 		s->sr_exit = REG_READ(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A);
56d39b3acbSKen Chalmers 	}
5762d591a8SYue Hin Lau 	s->dram_clk_chanage = REG_READ(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A);
5862d591a8SYue Hin Lau 
5962d591a8SYue Hin Lau 	s = &wm->sets[1];
6062d591a8SYue Hin Lau 	s->wm_set = 1;
6162d591a8SYue Hin Lau 	s->data_urgent = REG_READ(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B);
6262d591a8SYue Hin Lau 	s->pte_meta_urgent = REG_READ(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_B);
63d39b3acbSKen Chalmers 	if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B)) {
6462d591a8SYue Hin Lau 		s->sr_enter = REG_READ(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B);
6562d591a8SYue Hin Lau 		s->sr_exit = REG_READ(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B);
66d39b3acbSKen Chalmers 	}
6762d591a8SYue Hin Lau 	s->dram_clk_chanage = REG_READ(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B);
6862d591a8SYue Hin Lau 
6962d591a8SYue Hin Lau 	s = &wm->sets[2];
7062d591a8SYue Hin Lau 	s->wm_set = 2;
7162d591a8SYue Hin Lau 	s->data_urgent = REG_READ(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C);
7262d591a8SYue Hin Lau 	s->pte_meta_urgent = REG_READ(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_C);
73d39b3acbSKen Chalmers 	if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C)) {
7462d591a8SYue Hin Lau 		s->sr_enter = REG_READ(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C);
7562d591a8SYue Hin Lau 		s->sr_exit = REG_READ(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C);
76d39b3acbSKen Chalmers 	}
7762d591a8SYue Hin Lau 	s->dram_clk_chanage = REG_READ(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C);
7862d591a8SYue Hin Lau 
7962d591a8SYue Hin Lau 	s = &wm->sets[3];
8062d591a8SYue Hin Lau 	s->wm_set = 3;
8162d591a8SYue Hin Lau 	s->data_urgent = REG_READ(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D);
8262d591a8SYue Hin Lau 	s->pte_meta_urgent = REG_READ(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_D);
83d39b3acbSKen Chalmers 	if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D)) {
8462d591a8SYue Hin Lau 		s->sr_enter = REG_READ(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D);
8562d591a8SYue Hin Lau 		s->sr_exit = REG_READ(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D);
86d39b3acbSKen Chalmers 	}
8762d591a8SYue Hin Lau 	s->dram_clk_chanage = REG_READ(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D);
8862d591a8SYue Hin Lau }
8962d591a8SYue Hin Lau 
90ea00f297SYue Hin Lau bool hubbub1_verify_allow_pstate_change_high(
91c9ef081dSYue Hin Lau 	struct hubbub *hubbub)
9262d591a8SYue Hin Lau {
9362d591a8SYue Hin Lau 	/* pstate latency is ~20us so if we wait over 40us and pstate allow
9462d591a8SYue Hin Lau 	 * still not asserted, we are probably stuck and going to hang
9562d591a8SYue Hin Lau 	 *
9662d591a8SYue Hin Lau 	 * TODO: Figure out why it takes ~100us on linux
9762d591a8SYue Hin Lau 	 * pstate takes around ~100us on linux. Unknown currently as to
9862d591a8SYue Hin Lau 	 * why it takes that long on linux
9962d591a8SYue Hin Lau 	 */
10062d591a8SYue Hin Lau 	static unsigned int pstate_wait_timeout_us = 200;
10162d591a8SYue Hin Lau 	static unsigned int pstate_wait_expected_timeout_us = 40;
10262d591a8SYue Hin Lau 	static unsigned int max_sampled_pstate_wait_us; /* data collection */
10362d591a8SYue Hin Lau 	static bool forced_pstate_allow; /* help with revert wa */
10462d591a8SYue Hin Lau 
10562d591a8SYue Hin Lau 	unsigned int debug_data;
10662d591a8SYue Hin Lau 	unsigned int i;
10762d591a8SYue Hin Lau 
10862d591a8SYue Hin Lau 	if (forced_pstate_allow) {
10962d591a8SYue Hin Lau 		/* we hacked to force pstate allow to prevent hang last time
11062d591a8SYue Hin Lau 		 * we verify_allow_pstate_change_high.  so disable force
11162d591a8SYue Hin Lau 		 * here so we can check status
11262d591a8SYue Hin Lau 		 */
11362d591a8SYue Hin Lau 		REG_UPDATE_2(DCHUBBUB_ARB_DRAM_STATE_CNTL,
11462d591a8SYue Hin Lau 			     DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_VALUE, 0,
11562d591a8SYue Hin Lau 			     DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_ENABLE, 0);
11662d591a8SYue Hin Lau 		forced_pstate_allow = false;
11762d591a8SYue Hin Lau 	}
11862d591a8SYue Hin Lau 
119cf1df90fSHersen Wu 	/* RV1:
120cf1df90fSHersen Wu 	 * dchubbubdebugind, at: 0x7
121cf1df90fSHersen Wu 	 * description "3-0:   Pipe0 cursor0 QOS
12262d591a8SYue Hin Lau 	 * 7-4:   Pipe1 cursor0 QOS
12362d591a8SYue Hin Lau 	 * 11-8:  Pipe2 cursor0 QOS
12462d591a8SYue Hin Lau 	 * 15-12: Pipe3 cursor0 QOS
12562d591a8SYue Hin Lau 	 * 16:    Pipe0 Plane0 Allow Pstate Change
12662d591a8SYue Hin Lau 	 * 17:    Pipe1 Plane0 Allow Pstate Change
12762d591a8SYue Hin Lau 	 * 18:    Pipe2 Plane0 Allow Pstate Change
12862d591a8SYue Hin Lau 	 * 19:    Pipe3 Plane0 Allow Pstate Change
12962d591a8SYue Hin Lau 	 * 20:    Pipe0 Plane1 Allow Pstate Change
13062d591a8SYue Hin Lau 	 * 21:    Pipe1 Plane1 Allow Pstate Change
13162d591a8SYue Hin Lau 	 * 22:    Pipe2 Plane1 Allow Pstate Change
13262d591a8SYue Hin Lau 	 * 23:    Pipe3 Plane1 Allow Pstate Change
13362d591a8SYue Hin Lau 	 * 24:    Pipe0 cursor0 Allow Pstate Change
13462d591a8SYue Hin Lau 	 * 25:    Pipe1 cursor0 Allow Pstate Change
13562d591a8SYue Hin Lau 	 * 26:    Pipe2 cursor0 Allow Pstate Change
13662d591a8SYue Hin Lau 	 * 27:    Pipe3 cursor0 Allow Pstate Change
13762d591a8SYue Hin Lau 	 * 28:    WB0 Allow Pstate Change
13862d591a8SYue Hin Lau 	 * 29:    WB1 Allow Pstate Change
13962d591a8SYue Hin Lau 	 * 30:    Arbiter's allow_pstate_change
14062d591a8SYue Hin Lau 	 * 31:    SOC pstate change request
14162d591a8SYue Hin Lau 	 */
14262d591a8SYue Hin Lau 
143cf1df90fSHersen Wu 
144cf1df90fSHersen Wu 	REG_WRITE(DCHUBBUB_TEST_DEBUG_INDEX, hubbub->debug_test_index_pstate);
14562d591a8SYue Hin Lau 
14662d591a8SYue Hin Lau 	for (i = 0; i < pstate_wait_timeout_us; i++) {
14762d591a8SYue Hin Lau 		debug_data = REG_READ(DCHUBBUB_TEST_DEBUG_DATA);
14862d591a8SYue Hin Lau 
14962d591a8SYue Hin Lau 		if (debug_data & (1 << 30)) {
15062d591a8SYue Hin Lau 
15162d591a8SYue Hin Lau 			if (i > pstate_wait_expected_timeout_us)
1521296423bSBhawanpreet Lakha 				DC_LOG_WARNING("pstate took longer than expected ~%dus\n",
15362d591a8SYue Hin Lau 						i);
15462d591a8SYue Hin Lau 
155e70fe3b1SYue Hin Lau 			return true;
15662d591a8SYue Hin Lau 		}
15762d591a8SYue Hin Lau 		if (max_sampled_pstate_wait_us < i)
15862d591a8SYue Hin Lau 			max_sampled_pstate_wait_us = i;
15962d591a8SYue Hin Lau 
16062d591a8SYue Hin Lau 		udelay(1);
16162d591a8SYue Hin Lau 	}
16262d591a8SYue Hin Lau 
16362d591a8SYue Hin Lau 	/* force pstate allow to prevent system hang
16462d591a8SYue Hin Lau 	 * and break to debugger to investigate
16562d591a8SYue Hin Lau 	 */
16662d591a8SYue Hin Lau 	REG_UPDATE_2(DCHUBBUB_ARB_DRAM_STATE_CNTL,
16762d591a8SYue Hin Lau 		     DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_VALUE, 1,
16862d591a8SYue Hin Lau 		     DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_ENABLE, 1);
16962d591a8SYue Hin Lau 	forced_pstate_allow = true;
17062d591a8SYue Hin Lau 
1711296423bSBhawanpreet Lakha 	DC_LOG_WARNING("pstate TEST_DEBUG_DATA: 0x%X\n",
17262d591a8SYue Hin Lau 			debug_data);
173ea00f297SYue Hin Lau 
174e70fe3b1SYue Hin Lau 	return false;
17562d591a8SYue Hin Lau }
17662d591a8SYue Hin Lau 
17762d591a8SYue Hin Lau static uint32_t convert_and_clamp(
17862d591a8SYue Hin Lau 	uint32_t wm_ns,
17962d591a8SYue Hin Lau 	uint32_t refclk_mhz,
18062d591a8SYue Hin Lau 	uint32_t clamp_value)
18162d591a8SYue Hin Lau {
18262d591a8SYue Hin Lau 	uint32_t ret_val = 0;
18362d591a8SYue Hin Lau 	ret_val = wm_ns * refclk_mhz;
18462d591a8SYue Hin Lau 	ret_val /= 1000;
18562d591a8SYue Hin Lau 
18662d591a8SYue Hin Lau 	if (ret_val > clamp_value)
18762d591a8SYue Hin Lau 		ret_val = clamp_value;
18862d591a8SYue Hin Lau 
18962d591a8SYue Hin Lau 	return ret_val;
19062d591a8SYue Hin Lau }
19162d591a8SYue Hin Lau 
19262d591a8SYue Hin Lau 
1937144d3cfSDmytro Laktyushkin void hubbub1_wm_change_req_wa(struct hubbub *hubbub)
1947144d3cfSDmytro Laktyushkin {
1957144d3cfSDmytro Laktyushkin 	REG_UPDATE_SEQ(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL,
1967144d3cfSDmytro Laktyushkin 			DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, 0, 1);
1977144d3cfSDmytro Laktyushkin }
1987144d3cfSDmytro Laktyushkin 
199ea00f297SYue Hin Lau void hubbub1_program_watermarks(
200c9ef081dSYue Hin Lau 		struct hubbub *hubbub,
20162d591a8SYue Hin Lau 		struct dcn_watermark_set *watermarks,
202d7b539d3SDmytro Laktyushkin 		unsigned int refclk_mhz,
203d7b539d3SDmytro Laktyushkin 		bool safe_to_lower)
20462d591a8SYue Hin Lau {
205c9ef081dSYue Hin Lau 	uint32_t force_en = hubbub->ctx->dc->debug.disable_stutter ? 1 : 0;
20662d591a8SYue Hin Lau 	/*
20762d591a8SYue Hin Lau 	 * Need to clamp to max of the register values (i.e. no wrap)
20862d591a8SYue Hin Lau 	 * for dcn1, all wm registers are 21-bit wide
20962d591a8SYue Hin Lau 	 */
21062d591a8SYue Hin Lau 	uint32_t prog_wm_value;
21162d591a8SYue Hin Lau 
21262d591a8SYue Hin Lau 
21362d591a8SYue Hin Lau 	/* Repeat for water mark set A, B, C and D. */
21462d591a8SYue Hin Lau 	/* clock state A */
215d7b539d3SDmytro Laktyushkin 	if (safe_to_lower || watermarks->a.urgent_ns > hubbub->watermarks.a.urgent_ns) {
216d7b539d3SDmytro Laktyushkin 		hubbub->watermarks.a.urgent_ns = watermarks->a.urgent_ns;
21762d591a8SYue Hin Lau 		prog_wm_value = convert_and_clamp(watermarks->a.urgent_ns,
21862d591a8SYue Hin Lau 				refclk_mhz, 0x1fffff);
21962d591a8SYue Hin Lau 		REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, prog_wm_value);
22062d591a8SYue Hin Lau 
2211296423bSBhawanpreet Lakha 		DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_A calculated =%d\n"
22262d591a8SYue Hin Lau 			"HW register value = 0x%x\n",
22362d591a8SYue Hin Lau 			watermarks->a.urgent_ns, prog_wm_value);
224d7b539d3SDmytro Laktyushkin 	}
22562d591a8SYue Hin Lau 
226d7b539d3SDmytro Laktyushkin 	if (safe_to_lower || watermarks->a.pte_meta_urgent_ns > hubbub->watermarks.a.pte_meta_urgent_ns) {
227d7b539d3SDmytro Laktyushkin 		hubbub->watermarks.a.pte_meta_urgent_ns = watermarks->a.pte_meta_urgent_ns;
22862d591a8SYue Hin Lau 		prog_wm_value = convert_and_clamp(watermarks->a.pte_meta_urgent_ns,
22962d591a8SYue Hin Lau 				refclk_mhz, 0x1fffff);
23062d591a8SYue Hin Lau 		REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_A, prog_wm_value);
2311296423bSBhawanpreet Lakha 		DC_LOG_BANDWIDTH_CALCS("PTE_META_URGENCY_WATERMARK_A calculated =%d\n"
23262d591a8SYue Hin Lau 			"HW register value = 0x%x\n",
23362d591a8SYue Hin Lau 			watermarks->a.pte_meta_urgent_ns, prog_wm_value);
234d7b539d3SDmytro Laktyushkin 	}
23562d591a8SYue Hin Lau 
23662d591a8SYue Hin Lau 	if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A)) {
237d7b539d3SDmytro Laktyushkin 		if (safe_to_lower || watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns
238d7b539d3SDmytro Laktyushkin 				> hubbub->watermarks.a.cstate_pstate.cstate_enter_plus_exit_ns) {
239d7b539d3SDmytro Laktyushkin 			hubbub->watermarks.a.cstate_pstate.cstate_enter_plus_exit_ns =
240d7b539d3SDmytro Laktyushkin 					watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns;
24162d591a8SYue Hin Lau 			prog_wm_value = convert_and_clamp(
24262d591a8SYue Hin Lau 					watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns,
24362d591a8SYue Hin Lau 					refclk_mhz, 0x1fffff);
24462d591a8SYue Hin Lau 			REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A, prog_wm_value);
2451296423bSBhawanpreet Lakha 			DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_A calculated =%d\n"
24662d591a8SYue Hin Lau 				"HW register value = 0x%x\n",
24762d591a8SYue Hin Lau 				watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
248d7b539d3SDmytro Laktyushkin 		}
24962d591a8SYue Hin Lau 
250d7b539d3SDmytro Laktyushkin 		if (safe_to_lower || watermarks->a.cstate_pstate.cstate_exit_ns
251d7b539d3SDmytro Laktyushkin 				> hubbub->watermarks.a.cstate_pstate.cstate_exit_ns) {
252d7b539d3SDmytro Laktyushkin 			hubbub->watermarks.a.cstate_pstate.cstate_exit_ns =
253d7b539d3SDmytro Laktyushkin 					watermarks->a.cstate_pstate.cstate_exit_ns;
25462d591a8SYue Hin Lau 			prog_wm_value = convert_and_clamp(
25562d591a8SYue Hin Lau 					watermarks->a.cstate_pstate.cstate_exit_ns,
25662d591a8SYue Hin Lau 					refclk_mhz, 0x1fffff);
25762d591a8SYue Hin Lau 			REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A, prog_wm_value);
2581296423bSBhawanpreet Lakha 			DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_A calculated =%d\n"
25962d591a8SYue Hin Lau 				"HW register value = 0x%x\n",
26062d591a8SYue Hin Lau 				watermarks->a.cstate_pstate.cstate_exit_ns, prog_wm_value);
26162d591a8SYue Hin Lau 		}
262d7b539d3SDmytro Laktyushkin 	}
26362d591a8SYue Hin Lau 
264d7b539d3SDmytro Laktyushkin 	if (safe_to_lower || watermarks->a.cstate_pstate.pstate_change_ns
265d7b539d3SDmytro Laktyushkin 			> hubbub->watermarks.a.cstate_pstate.pstate_change_ns) {
266d7b539d3SDmytro Laktyushkin 		hubbub->watermarks.a.cstate_pstate.pstate_change_ns =
267d7b539d3SDmytro Laktyushkin 				watermarks->a.cstate_pstate.pstate_change_ns;
26862d591a8SYue Hin Lau 		prog_wm_value = convert_and_clamp(
26962d591a8SYue Hin Lau 				watermarks->a.cstate_pstate.pstate_change_ns,
27062d591a8SYue Hin Lau 				refclk_mhz, 0x1fffff);
27162d591a8SYue Hin Lau 		REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A, prog_wm_value);
2721296423bSBhawanpreet Lakha 		DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_A calculated =%d\n"
27362d591a8SYue Hin Lau 			"HW register value = 0x%x\n\n",
27462d591a8SYue Hin Lau 			watermarks->a.cstate_pstate.pstate_change_ns, prog_wm_value);
275d7b539d3SDmytro Laktyushkin 	}
27662d591a8SYue Hin Lau 
27762d591a8SYue Hin Lau 	/* clock state B */
278d7b539d3SDmytro Laktyushkin 	if (safe_to_lower || watermarks->b.urgent_ns > hubbub->watermarks.b.urgent_ns) {
279d7b539d3SDmytro Laktyushkin 		hubbub->watermarks.b.urgent_ns = watermarks->b.urgent_ns;
280d7b539d3SDmytro Laktyushkin 		prog_wm_value = convert_and_clamp(watermarks->b.urgent_ns,
281d7b539d3SDmytro Laktyushkin 				refclk_mhz, 0x1fffff);
28262d591a8SYue Hin Lau 		REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, prog_wm_value);
283d7b539d3SDmytro Laktyushkin 
2841296423bSBhawanpreet Lakha 		DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_B calculated =%d\n"
28562d591a8SYue Hin Lau 			"HW register value = 0x%x\n",
28662d591a8SYue Hin Lau 			watermarks->b.urgent_ns, prog_wm_value);
287d7b539d3SDmytro Laktyushkin 	}
28862d591a8SYue Hin Lau 
289d7b539d3SDmytro Laktyushkin 	if (safe_to_lower || watermarks->b.pte_meta_urgent_ns > hubbub->watermarks.b.pte_meta_urgent_ns) {
290d7b539d3SDmytro Laktyushkin 		hubbub->watermarks.b.pte_meta_urgent_ns = watermarks->b.pte_meta_urgent_ns;
291d7b539d3SDmytro Laktyushkin 		prog_wm_value = convert_and_clamp(watermarks->b.pte_meta_urgent_ns,
29262d591a8SYue Hin Lau 				refclk_mhz, 0x1fffff);
29362d591a8SYue Hin Lau 		REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_B, prog_wm_value);
2941296423bSBhawanpreet Lakha 		DC_LOG_BANDWIDTH_CALCS("PTE_META_URGENCY_WATERMARK_B calculated =%d\n"
29562d591a8SYue Hin Lau 			"HW register value = 0x%x\n",
29662d591a8SYue Hin Lau 			watermarks->b.pte_meta_urgent_ns, prog_wm_value);
297d7b539d3SDmytro Laktyushkin 	}
29862d591a8SYue Hin Lau 
29962d591a8SYue Hin Lau 	if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B)) {
300d7b539d3SDmytro Laktyushkin 		if (safe_to_lower || watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns
301d7b539d3SDmytro Laktyushkin 				> hubbub->watermarks.b.cstate_pstate.cstate_enter_plus_exit_ns) {
302d7b539d3SDmytro Laktyushkin 			hubbub->watermarks.b.cstate_pstate.cstate_enter_plus_exit_ns =
303d7b539d3SDmytro Laktyushkin 					watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns;
30462d591a8SYue Hin Lau 			prog_wm_value = convert_and_clamp(
30562d591a8SYue Hin Lau 					watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns,
30662d591a8SYue Hin Lau 					refclk_mhz, 0x1fffff);
30762d591a8SYue Hin Lau 			REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, prog_wm_value);
308d7b539d3SDmytro Laktyushkin 			DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_B calculated =%d\n"
30962d591a8SYue Hin Lau 				"HW register value = 0x%x\n",
31062d591a8SYue Hin Lau 				watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
311d7b539d3SDmytro Laktyushkin 		}
31262d591a8SYue Hin Lau 
313d7b539d3SDmytro Laktyushkin 		if (safe_to_lower || watermarks->b.cstate_pstate.cstate_exit_ns
314d7b539d3SDmytro Laktyushkin 				> hubbub->watermarks.b.cstate_pstate.cstate_exit_ns) {
315d7b539d3SDmytro Laktyushkin 			hubbub->watermarks.b.cstate_pstate.cstate_exit_ns =
316d7b539d3SDmytro Laktyushkin 					watermarks->b.cstate_pstate.cstate_exit_ns;
31762d591a8SYue Hin Lau 			prog_wm_value = convert_and_clamp(
31862d591a8SYue Hin Lau 					watermarks->b.cstate_pstate.cstate_exit_ns,
31962d591a8SYue Hin Lau 					refclk_mhz, 0x1fffff);
32062d591a8SYue Hin Lau 			REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, prog_wm_value);
3211296423bSBhawanpreet Lakha 			DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_B calculated =%d\n"
32262d591a8SYue Hin Lau 				"HW register value = 0x%x\n",
32362d591a8SYue Hin Lau 				watermarks->b.cstate_pstate.cstate_exit_ns, prog_wm_value);
32462d591a8SYue Hin Lau 		}
325d7b539d3SDmytro Laktyushkin 	}
32662d591a8SYue Hin Lau 
327d7b539d3SDmytro Laktyushkin 	if (safe_to_lower || watermarks->b.cstate_pstate.pstate_change_ns
328d7b539d3SDmytro Laktyushkin 			> hubbub->watermarks.b.cstate_pstate.pstate_change_ns) {
329d7b539d3SDmytro Laktyushkin 		hubbub->watermarks.b.cstate_pstate.pstate_change_ns =
330d7b539d3SDmytro Laktyushkin 				watermarks->b.cstate_pstate.pstate_change_ns;
33162d591a8SYue Hin Lau 		prog_wm_value = convert_and_clamp(
33262d591a8SYue Hin Lau 				watermarks->b.cstate_pstate.pstate_change_ns,
33362d591a8SYue Hin Lau 				refclk_mhz, 0x1fffff);
33462d591a8SYue Hin Lau 		REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B, prog_wm_value);
335d7b539d3SDmytro Laktyushkin 		DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_B calculated =%d\n"
336d7b539d3SDmytro Laktyushkin 			"HW register value = 0x%x\n\n",
33762d591a8SYue Hin Lau 			watermarks->b.cstate_pstate.pstate_change_ns, prog_wm_value);
338d7b539d3SDmytro Laktyushkin 	}
33962d591a8SYue Hin Lau 
34062d591a8SYue Hin Lau 	/* clock state C */
341d7b539d3SDmytro Laktyushkin 	if (safe_to_lower || watermarks->c.urgent_ns > hubbub->watermarks.c.urgent_ns) {
342d7b539d3SDmytro Laktyushkin 		hubbub->watermarks.c.urgent_ns = watermarks->c.urgent_ns;
343d7b539d3SDmytro Laktyushkin 		prog_wm_value = convert_and_clamp(watermarks->c.urgent_ns,
344d7b539d3SDmytro Laktyushkin 				refclk_mhz, 0x1fffff);
34562d591a8SYue Hin Lau 		REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, prog_wm_value);
346d7b539d3SDmytro Laktyushkin 
3471296423bSBhawanpreet Lakha 		DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_C calculated =%d\n"
34862d591a8SYue Hin Lau 			"HW register value = 0x%x\n",
34962d591a8SYue Hin Lau 			watermarks->c.urgent_ns, prog_wm_value);
350d7b539d3SDmytro Laktyushkin 	}
35162d591a8SYue Hin Lau 
352d7b539d3SDmytro Laktyushkin 	if (safe_to_lower || watermarks->c.pte_meta_urgent_ns > hubbub->watermarks.c.pte_meta_urgent_ns) {
353d7b539d3SDmytro Laktyushkin 		hubbub->watermarks.c.pte_meta_urgent_ns = watermarks->c.pte_meta_urgent_ns;
354d7b539d3SDmytro Laktyushkin 		prog_wm_value = convert_and_clamp(watermarks->c.pte_meta_urgent_ns,
35562d591a8SYue Hin Lau 				refclk_mhz, 0x1fffff);
35662d591a8SYue Hin Lau 		REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_C, prog_wm_value);
3571296423bSBhawanpreet Lakha 		DC_LOG_BANDWIDTH_CALCS("PTE_META_URGENCY_WATERMARK_C calculated =%d\n"
35862d591a8SYue Hin Lau 			"HW register value = 0x%x\n",
35962d591a8SYue Hin Lau 			watermarks->c.pte_meta_urgent_ns, prog_wm_value);
360d7b539d3SDmytro Laktyushkin 	}
36162d591a8SYue Hin Lau 
36262d591a8SYue Hin Lau 	if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C)) {
363d7b539d3SDmytro Laktyushkin 		if (safe_to_lower || watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns
364d7b539d3SDmytro Laktyushkin 				> hubbub->watermarks.c.cstate_pstate.cstate_enter_plus_exit_ns) {
365d7b539d3SDmytro Laktyushkin 			hubbub->watermarks.c.cstate_pstate.cstate_enter_plus_exit_ns =
366d7b539d3SDmytro Laktyushkin 					watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns;
36762d591a8SYue Hin Lau 			prog_wm_value = convert_and_clamp(
36862d591a8SYue Hin Lau 					watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns,
36962d591a8SYue Hin Lau 					refclk_mhz, 0x1fffff);
37062d591a8SYue Hin Lau 			REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, prog_wm_value);
371d7b539d3SDmytro Laktyushkin 			DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_C calculated =%d\n"
37262d591a8SYue Hin Lau 				"HW register value = 0x%x\n",
37362d591a8SYue Hin Lau 				watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
374d7b539d3SDmytro Laktyushkin 		}
37562d591a8SYue Hin Lau 
376d7b539d3SDmytro Laktyushkin 		if (safe_to_lower || watermarks->c.cstate_pstate.cstate_exit_ns
377d7b539d3SDmytro Laktyushkin 				> hubbub->watermarks.c.cstate_pstate.cstate_exit_ns) {
378d7b539d3SDmytro Laktyushkin 			hubbub->watermarks.c.cstate_pstate.cstate_exit_ns =
379d7b539d3SDmytro Laktyushkin 					watermarks->c.cstate_pstate.cstate_exit_ns;
38062d591a8SYue Hin Lau 			prog_wm_value = convert_and_clamp(
38162d591a8SYue Hin Lau 					watermarks->c.cstate_pstate.cstate_exit_ns,
38262d591a8SYue Hin Lau 					refclk_mhz, 0x1fffff);
38362d591a8SYue Hin Lau 			REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C, prog_wm_value);
3841296423bSBhawanpreet Lakha 			DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_C calculated =%d\n"
38562d591a8SYue Hin Lau 				"HW register value = 0x%x\n",
38662d591a8SYue Hin Lau 				watermarks->c.cstate_pstate.cstate_exit_ns, prog_wm_value);
38762d591a8SYue Hin Lau 		}
388d7b539d3SDmytro Laktyushkin 	}
38962d591a8SYue Hin Lau 
390d7b539d3SDmytro Laktyushkin 	if (safe_to_lower || watermarks->c.cstate_pstate.pstate_change_ns
391d7b539d3SDmytro Laktyushkin 			> hubbub->watermarks.c.cstate_pstate.pstate_change_ns) {
392d7b539d3SDmytro Laktyushkin 		hubbub->watermarks.c.cstate_pstate.pstate_change_ns =
393d7b539d3SDmytro Laktyushkin 				watermarks->c.cstate_pstate.pstate_change_ns;
39462d591a8SYue Hin Lau 		prog_wm_value = convert_and_clamp(
39562d591a8SYue Hin Lau 				watermarks->c.cstate_pstate.pstate_change_ns,
39662d591a8SYue Hin Lau 				refclk_mhz, 0x1fffff);
39762d591a8SYue Hin Lau 		REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C, prog_wm_value);
398d7b539d3SDmytro Laktyushkin 		DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_C calculated =%d\n"
399d7b539d3SDmytro Laktyushkin 			"HW register value = 0x%x\n\n",
40062d591a8SYue Hin Lau 			watermarks->c.cstate_pstate.pstate_change_ns, prog_wm_value);
401d7b539d3SDmytro Laktyushkin 	}
40262d591a8SYue Hin Lau 
40362d591a8SYue Hin Lau 	/* clock state D */
404d7b539d3SDmytro Laktyushkin 	if (safe_to_lower || watermarks->d.urgent_ns > hubbub->watermarks.d.urgent_ns) {
405d7b539d3SDmytro Laktyushkin 		hubbub->watermarks.d.urgent_ns = watermarks->d.urgent_ns;
406d7b539d3SDmytro Laktyushkin 		prog_wm_value = convert_and_clamp(watermarks->d.urgent_ns,
407d7b539d3SDmytro Laktyushkin 				refclk_mhz, 0x1fffff);
40862d591a8SYue Hin Lau 		REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, prog_wm_value);
409d7b539d3SDmytro Laktyushkin 
4101296423bSBhawanpreet Lakha 		DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_D calculated =%d\n"
41162d591a8SYue Hin Lau 			"HW register value = 0x%x\n",
41262d591a8SYue Hin Lau 			watermarks->d.urgent_ns, prog_wm_value);
413d7b539d3SDmytro Laktyushkin 	}
41462d591a8SYue Hin Lau 
415d7b539d3SDmytro Laktyushkin 	if (safe_to_lower || watermarks->d.pte_meta_urgent_ns > hubbub->watermarks.d.pte_meta_urgent_ns) {
416d7b539d3SDmytro Laktyushkin 		hubbub->watermarks.d.pte_meta_urgent_ns = watermarks->d.pte_meta_urgent_ns;
417d7b539d3SDmytro Laktyushkin 		prog_wm_value = convert_and_clamp(watermarks->d.pte_meta_urgent_ns,
41862d591a8SYue Hin Lau 				refclk_mhz, 0x1fffff);
41962d591a8SYue Hin Lau 		REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_D, prog_wm_value);
4201296423bSBhawanpreet Lakha 		DC_LOG_BANDWIDTH_CALCS("PTE_META_URGENCY_WATERMARK_D calculated =%d\n"
42162d591a8SYue Hin Lau 			"HW register value = 0x%x\n",
42262d591a8SYue Hin Lau 			watermarks->d.pte_meta_urgent_ns, prog_wm_value);
423d7b539d3SDmytro Laktyushkin 	}
42462d591a8SYue Hin Lau 
42562d591a8SYue Hin Lau 	if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D)) {
426d7b539d3SDmytro Laktyushkin 		if (safe_to_lower || watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns
427d7b539d3SDmytro Laktyushkin 				> hubbub->watermarks.d.cstate_pstate.cstate_enter_plus_exit_ns) {
428d7b539d3SDmytro Laktyushkin 			hubbub->watermarks.d.cstate_pstate.cstate_enter_plus_exit_ns =
429d7b539d3SDmytro Laktyushkin 					watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns;
43062d591a8SYue Hin Lau 			prog_wm_value = convert_and_clamp(
43162d591a8SYue Hin Lau 					watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns,
43262d591a8SYue Hin Lau 					refclk_mhz, 0x1fffff);
43362d591a8SYue Hin Lau 			REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, prog_wm_value);
434d7b539d3SDmytro Laktyushkin 			DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_D calculated =%d\n"
43562d591a8SYue Hin Lau 				"HW register value = 0x%x\n",
43662d591a8SYue Hin Lau 				watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
437d7b539d3SDmytro Laktyushkin 		}
43862d591a8SYue Hin Lau 
439d7b539d3SDmytro Laktyushkin 		if (safe_to_lower || watermarks->d.cstate_pstate.cstate_exit_ns
440d7b539d3SDmytro Laktyushkin 				> hubbub->watermarks.d.cstate_pstate.cstate_exit_ns) {
441d7b539d3SDmytro Laktyushkin 			hubbub->watermarks.d.cstate_pstate.cstate_exit_ns =
442d7b539d3SDmytro Laktyushkin 					watermarks->d.cstate_pstate.cstate_exit_ns;
44362d591a8SYue Hin Lau 			prog_wm_value = convert_and_clamp(
44462d591a8SYue Hin Lau 					watermarks->d.cstate_pstate.cstate_exit_ns,
44562d591a8SYue Hin Lau 					refclk_mhz, 0x1fffff);
44662d591a8SYue Hin Lau 			REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D, prog_wm_value);
4471296423bSBhawanpreet Lakha 			DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_D calculated =%d\n"
44862d591a8SYue Hin Lau 				"HW register value = 0x%x\n",
44962d591a8SYue Hin Lau 				watermarks->d.cstate_pstate.cstate_exit_ns, prog_wm_value);
45062d591a8SYue Hin Lau 		}
451d7b539d3SDmytro Laktyushkin 	}
45262d591a8SYue Hin Lau 
453d7b539d3SDmytro Laktyushkin 	if (safe_to_lower || watermarks->d.cstate_pstate.pstate_change_ns
454d7b539d3SDmytro Laktyushkin 			> hubbub->watermarks.d.cstate_pstate.pstate_change_ns) {
455d7b539d3SDmytro Laktyushkin 		hubbub->watermarks.d.cstate_pstate.pstate_change_ns =
456d7b539d3SDmytro Laktyushkin 				watermarks->d.cstate_pstate.pstate_change_ns;
45762d591a8SYue Hin Lau 		prog_wm_value = convert_and_clamp(
45862d591a8SYue Hin Lau 				watermarks->d.cstate_pstate.pstate_change_ns,
45962d591a8SYue Hin Lau 				refclk_mhz, 0x1fffff);
46062d591a8SYue Hin Lau 		REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D, prog_wm_value);
4611296423bSBhawanpreet Lakha 		DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_D calculated =%d\n"
46262d591a8SYue Hin Lau 			"HW register value = 0x%x\n\n",
46362d591a8SYue Hin Lau 			watermarks->d.cstate_pstate.pstate_change_ns, prog_wm_value);
464d7b539d3SDmytro Laktyushkin 	}
46562d591a8SYue Hin Lau 
46662d591a8SYue Hin Lau 	REG_UPDATE(DCHUBBUB_ARB_SAT_LEVEL,
46762d591a8SYue Hin Lau 			DCHUBBUB_ARB_SAT_LEVEL, 60 * refclk_mhz);
46862d591a8SYue Hin Lau 	REG_UPDATE(DCHUBBUB_ARB_DF_REQ_OUTSTAND,
46962d591a8SYue Hin Lau 			DCHUBBUB_ARB_MIN_REQ_OUTSTAND, 68);
47062d591a8SYue Hin Lau 
47162d591a8SYue Hin Lau 	REG_UPDATE_2(DCHUBBUB_ARB_DRAM_STATE_CNTL,
47262d591a8SYue Hin Lau 			DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_VALUE, 0,
47362d591a8SYue Hin Lau 			DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_ENABLE, force_en);
47462d591a8SYue Hin Lau 
47562d591a8SYue Hin Lau #if 0
47662d591a8SYue Hin Lau 	REG_UPDATE_2(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL,
47762d591a8SYue Hin Lau 			DCHUBBUB_ARB_WATERMARK_CHANGE_DONE_INTERRUPT_DISABLE, 1,
47862d591a8SYue Hin Lau 			DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, 1);
47962d591a8SYue Hin Lau #endif
48062d591a8SYue Hin Lau }
48162d591a8SYue Hin Lau 
482c9ef081dSYue Hin Lau void hubbub1_update_dchub(
483c9ef081dSYue Hin Lau 	struct hubbub *hubbub,
48462d591a8SYue Hin Lau 	struct dchub_init_data *dh_data)
48562d591a8SYue Hin Lau {
48662d591a8SYue Hin Lau 	/* TODO: port code from dal2 */
48762d591a8SYue Hin Lau 	switch (dh_data->fb_mode) {
48862d591a8SYue Hin Lau 	case FRAME_BUFFER_MODE_ZFB_ONLY:
48962d591a8SYue Hin Lau 		/*For ZFB case need to put DCHUB FB BASE and TOP upside down to indicate ZFB mode*/
49062d591a8SYue Hin Lau 		REG_UPDATE(DCHUBBUB_SDPIF_FB_TOP,
49162d591a8SYue Hin Lau 				SDPIF_FB_TOP, 0);
49262d591a8SYue Hin Lau 
49362d591a8SYue Hin Lau 		REG_UPDATE(DCHUBBUB_SDPIF_FB_BASE,
49462d591a8SYue Hin Lau 				SDPIF_FB_BASE, 0x0FFFF);
49562d591a8SYue Hin Lau 
49662d591a8SYue Hin Lau 		REG_UPDATE(DCHUBBUB_SDPIF_AGP_BASE,
49762d591a8SYue Hin Lau 				SDPIF_AGP_BASE, dh_data->zfb_phys_addr_base >> 22);
49862d591a8SYue Hin Lau 
49962d591a8SYue Hin Lau 		REG_UPDATE(DCHUBBUB_SDPIF_AGP_BOT,
50062d591a8SYue Hin Lau 				SDPIF_AGP_BOT, dh_data->zfb_mc_base_addr >> 22);
50162d591a8SYue Hin Lau 
50262d591a8SYue Hin Lau 		REG_UPDATE(DCHUBBUB_SDPIF_AGP_TOP,
50362d591a8SYue Hin Lau 				SDPIF_AGP_TOP, (dh_data->zfb_mc_base_addr +
50462d591a8SYue Hin Lau 						dh_data->zfb_size_in_byte - 1) >> 22);
50562d591a8SYue Hin Lau 		break;
50662d591a8SYue Hin Lau 	case FRAME_BUFFER_MODE_MIXED_ZFB_AND_LOCAL:
50762d591a8SYue Hin Lau 		/*Should not touch FB LOCATION (done by VBIOS on AsicInit table)*/
50862d591a8SYue Hin Lau 
50962d591a8SYue Hin Lau 		REG_UPDATE(DCHUBBUB_SDPIF_AGP_BASE,
51062d591a8SYue Hin Lau 				SDPIF_AGP_BASE, dh_data->zfb_phys_addr_base >> 22);
51162d591a8SYue Hin Lau 
51262d591a8SYue Hin Lau 		REG_UPDATE(DCHUBBUB_SDPIF_AGP_BOT,
51362d591a8SYue Hin Lau 				SDPIF_AGP_BOT, dh_data->zfb_mc_base_addr >> 22);
51462d591a8SYue Hin Lau 
51562d591a8SYue Hin Lau 		REG_UPDATE(DCHUBBUB_SDPIF_AGP_TOP,
51662d591a8SYue Hin Lau 				SDPIF_AGP_TOP, (dh_data->zfb_mc_base_addr +
51762d591a8SYue Hin Lau 						dh_data->zfb_size_in_byte - 1) >> 22);
51862d591a8SYue Hin Lau 		break;
51962d591a8SYue Hin Lau 	case FRAME_BUFFER_MODE_LOCAL_ONLY:
52062d591a8SYue Hin Lau 		/*Should not touch FB LOCATION (done by VBIOS on AsicInit table)*/
52162d591a8SYue Hin Lau 		REG_UPDATE(DCHUBBUB_SDPIF_AGP_BASE,
52262d591a8SYue Hin Lau 				SDPIF_AGP_BASE, 0);
52362d591a8SYue Hin Lau 
52462d591a8SYue Hin Lau 		REG_UPDATE(DCHUBBUB_SDPIF_AGP_BOT,
52562d591a8SYue Hin Lau 				SDPIF_AGP_BOT, 0X03FFFF);
52662d591a8SYue Hin Lau 
52762d591a8SYue Hin Lau 		REG_UPDATE(DCHUBBUB_SDPIF_AGP_TOP,
52862d591a8SYue Hin Lau 				SDPIF_AGP_TOP, 0);
52962d591a8SYue Hin Lau 		break;
53062d591a8SYue Hin Lau 	default:
53162d591a8SYue Hin Lau 		break;
53262d591a8SYue Hin Lau 	}
53362d591a8SYue Hin Lau 
53462d591a8SYue Hin Lau 	dh_data->dchub_initialzied = true;
53562d591a8SYue Hin Lau 	dh_data->dchub_info_valid = false;
53662d591a8SYue Hin Lau }
53762d591a8SYue Hin Lau 
538ea00f297SYue Hin Lau void hubbub1_toggle_watermark_change_req(struct hubbub *hubbub)
53962d591a8SYue Hin Lau {
54062d591a8SYue Hin Lau 	uint32_t watermark_change_req;
54162d591a8SYue Hin Lau 
54262d591a8SYue Hin Lau 	REG_GET(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL,
54362d591a8SYue Hin Lau 			DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, &watermark_change_req);
54462d591a8SYue Hin Lau 
54562d591a8SYue Hin Lau 	if (watermark_change_req)
54662d591a8SYue Hin Lau 		watermark_change_req = 0;
54762d591a8SYue Hin Lau 	else
54862d591a8SYue Hin Lau 		watermark_change_req = 1;
54962d591a8SYue Hin Lau 
55062d591a8SYue Hin Lau 	REG_UPDATE(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL,
55162d591a8SYue Hin Lau 			DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, watermark_change_req);
55262d591a8SYue Hin Lau }
55362d591a8SYue Hin Lau 
5543ba43a59SCharlene Liu void hubbub1_soft_reset(struct hubbub *hubbub, bool reset)
5553ba43a59SCharlene Liu {
5563ba43a59SCharlene Liu 	uint32_t reset_en = reset ? 1 : 0;
5573ba43a59SCharlene Liu 
5583ba43a59SCharlene Liu 	REG_UPDATE(DCHUBBUB_SOFT_RESET,
5593ba43a59SCharlene Liu 			DCHUBBUB_GLOBAL_SOFT_RESET, reset_en);
5603ba43a59SCharlene Liu }
5613ba43a59SCharlene Liu 
5625ebfb7a5SEric Bernstein static bool hubbub1_dcc_support_swizzle(
5635ebfb7a5SEric Bernstein 		enum swizzle_mode_values swizzle,
5645ebfb7a5SEric Bernstein 		unsigned int bytes_per_element,
5655ebfb7a5SEric Bernstein 		enum segment_order *segment_order_horz,
5665ebfb7a5SEric Bernstein 		enum segment_order *segment_order_vert)
5675ebfb7a5SEric Bernstein {
5685ebfb7a5SEric Bernstein 	bool standard_swizzle = false;
5695ebfb7a5SEric Bernstein 	bool display_swizzle = false;
5705ebfb7a5SEric Bernstein 
5715ebfb7a5SEric Bernstein 	switch (swizzle) {
5725ebfb7a5SEric Bernstein 	case DC_SW_4KB_S:
5735ebfb7a5SEric Bernstein 	case DC_SW_64KB_S:
5745ebfb7a5SEric Bernstein 	case DC_SW_VAR_S:
5755ebfb7a5SEric Bernstein 	case DC_SW_4KB_S_X:
5765ebfb7a5SEric Bernstein 	case DC_SW_64KB_S_X:
5775ebfb7a5SEric Bernstein 	case DC_SW_VAR_S_X:
5785ebfb7a5SEric Bernstein 		standard_swizzle = true;
5795ebfb7a5SEric Bernstein 		break;
5805ebfb7a5SEric Bernstein 	case DC_SW_4KB_D:
5815ebfb7a5SEric Bernstein 	case DC_SW_64KB_D:
5825ebfb7a5SEric Bernstein 	case DC_SW_VAR_D:
5835ebfb7a5SEric Bernstein 	case DC_SW_4KB_D_X:
5845ebfb7a5SEric Bernstein 	case DC_SW_64KB_D_X:
5855ebfb7a5SEric Bernstein 	case DC_SW_VAR_D_X:
5865ebfb7a5SEric Bernstein 		display_swizzle = true;
5875ebfb7a5SEric Bernstein 		break;
5885ebfb7a5SEric Bernstein 	default:
5895ebfb7a5SEric Bernstein 		break;
5905ebfb7a5SEric Bernstein 	}
5915ebfb7a5SEric Bernstein 
5925ebfb7a5SEric Bernstein 	if (bytes_per_element == 1 && standard_swizzle) {
5935ebfb7a5SEric Bernstein 		*segment_order_horz = segment_order__contiguous;
5945ebfb7a5SEric Bernstein 		*segment_order_vert = segment_order__na;
5955ebfb7a5SEric Bernstein 		return true;
5965ebfb7a5SEric Bernstein 	}
5975ebfb7a5SEric Bernstein 	if (bytes_per_element == 2 && standard_swizzle) {
5985ebfb7a5SEric Bernstein 		*segment_order_horz = segment_order__non_contiguous;
5995ebfb7a5SEric Bernstein 		*segment_order_vert = segment_order__contiguous;
6005ebfb7a5SEric Bernstein 		return true;
6015ebfb7a5SEric Bernstein 	}
6025ebfb7a5SEric Bernstein 	if (bytes_per_element == 4 && standard_swizzle) {
6035ebfb7a5SEric Bernstein 		*segment_order_horz = segment_order__non_contiguous;
6045ebfb7a5SEric Bernstein 		*segment_order_vert = segment_order__contiguous;
6055ebfb7a5SEric Bernstein 		return true;
6065ebfb7a5SEric Bernstein 	}
6075ebfb7a5SEric Bernstein 	if (bytes_per_element == 8 && standard_swizzle) {
6085ebfb7a5SEric Bernstein 		*segment_order_horz = segment_order__na;
6095ebfb7a5SEric Bernstein 		*segment_order_vert = segment_order__contiguous;
6105ebfb7a5SEric Bernstein 		return true;
6115ebfb7a5SEric Bernstein 	}
6125ebfb7a5SEric Bernstein 	if (bytes_per_element == 8 && display_swizzle) {
6135ebfb7a5SEric Bernstein 		*segment_order_horz = segment_order__contiguous;
6145ebfb7a5SEric Bernstein 		*segment_order_vert = segment_order__non_contiguous;
6155ebfb7a5SEric Bernstein 		return true;
6165ebfb7a5SEric Bernstein 	}
6175ebfb7a5SEric Bernstein 
6185ebfb7a5SEric Bernstein 	return false;
6195ebfb7a5SEric Bernstein }
6205ebfb7a5SEric Bernstein 
6215ebfb7a5SEric Bernstein static bool hubbub1_dcc_support_pixel_format(
6225ebfb7a5SEric Bernstein 		enum surface_pixel_format format,
6235ebfb7a5SEric Bernstein 		unsigned int *bytes_per_element)
6245ebfb7a5SEric Bernstein {
6255ebfb7a5SEric Bernstein 	/* DML: get_bytes_per_element */
6265ebfb7a5SEric Bernstein 	switch (format) {
6275ebfb7a5SEric Bernstein 	case SURFACE_PIXEL_FORMAT_GRPH_ARGB1555:
6285ebfb7a5SEric Bernstein 	case SURFACE_PIXEL_FORMAT_GRPH_RGB565:
6295ebfb7a5SEric Bernstein 		*bytes_per_element = 2;
6305ebfb7a5SEric Bernstein 		return true;
6315ebfb7a5SEric Bernstein 	case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888:
6325ebfb7a5SEric Bernstein 	case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888:
6335ebfb7a5SEric Bernstein 	case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010:
6345ebfb7a5SEric Bernstein 	case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010:
6355ebfb7a5SEric Bernstein 		*bytes_per_element = 4;
6365ebfb7a5SEric Bernstein 		return true;
6375ebfb7a5SEric Bernstein 	case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
6385ebfb7a5SEric Bernstein 	case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
6395ebfb7a5SEric Bernstein 	case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
6405ebfb7a5SEric Bernstein 		*bytes_per_element = 8;
6415ebfb7a5SEric Bernstein 		return true;
6425ebfb7a5SEric Bernstein 	default:
6435ebfb7a5SEric Bernstein 		return false;
6445ebfb7a5SEric Bernstein 	}
6455ebfb7a5SEric Bernstein }
6465ebfb7a5SEric Bernstein 
6475ebfb7a5SEric Bernstein static void hubbub1_get_blk256_size(unsigned int *blk256_width, unsigned int *blk256_height,
6485ebfb7a5SEric Bernstein 		unsigned int bytes_per_element)
6495ebfb7a5SEric Bernstein {
6505ebfb7a5SEric Bernstein 	/* copied from DML.  might want to refactor DML to leverage from DML */
6515ebfb7a5SEric Bernstein 	/* DML : get_blk256_size */
6525ebfb7a5SEric Bernstein 	if (bytes_per_element == 1) {
6535ebfb7a5SEric Bernstein 		*blk256_width = 16;
6545ebfb7a5SEric Bernstein 		*blk256_height = 16;
6555ebfb7a5SEric Bernstein 	} else if (bytes_per_element == 2) {
6565ebfb7a5SEric Bernstein 		*blk256_width = 16;
6575ebfb7a5SEric Bernstein 		*blk256_height = 8;
6585ebfb7a5SEric Bernstein 	} else if (bytes_per_element == 4) {
6595ebfb7a5SEric Bernstein 		*blk256_width = 8;
6605ebfb7a5SEric Bernstein 		*blk256_height = 8;
6615ebfb7a5SEric Bernstein 	} else if (bytes_per_element == 8) {
6625ebfb7a5SEric Bernstein 		*blk256_width = 8;
6635ebfb7a5SEric Bernstein 		*blk256_height = 4;
6645ebfb7a5SEric Bernstein 	}
6655ebfb7a5SEric Bernstein }
6665ebfb7a5SEric Bernstein 
6675ebfb7a5SEric Bernstein static void hubbub1_det_request_size(
6685ebfb7a5SEric Bernstein 		unsigned int height,
6695ebfb7a5SEric Bernstein 		unsigned int width,
6705ebfb7a5SEric Bernstein 		unsigned int bpe,
6715ebfb7a5SEric Bernstein 		bool *req128_horz_wc,
6725ebfb7a5SEric Bernstein 		bool *req128_vert_wc)
6735ebfb7a5SEric Bernstein {
6745ebfb7a5SEric Bernstein 	unsigned int detile_buf_size = 164 * 1024;  /* 164KB for DCN1.0 */
6755ebfb7a5SEric Bernstein 
6765ebfb7a5SEric Bernstein 	unsigned int blk256_height = 0;
6775ebfb7a5SEric Bernstein 	unsigned int blk256_width = 0;
6785ebfb7a5SEric Bernstein 	unsigned int swath_bytes_horz_wc, swath_bytes_vert_wc;
6795ebfb7a5SEric Bernstein 
6805ebfb7a5SEric Bernstein 	hubbub1_get_blk256_size(&blk256_width, &blk256_height, bpe);
6815ebfb7a5SEric Bernstein 
6825ebfb7a5SEric Bernstein 	swath_bytes_horz_wc = height * blk256_height * bpe;
6835ebfb7a5SEric Bernstein 	swath_bytes_vert_wc = width * blk256_width * bpe;
6845ebfb7a5SEric Bernstein 
6855ebfb7a5SEric Bernstein 	*req128_horz_wc = (2 * swath_bytes_horz_wc <= detile_buf_size) ?
6865ebfb7a5SEric Bernstein 			false : /* full 256B request */
6875ebfb7a5SEric Bernstein 			true; /* half 128b request */
6885ebfb7a5SEric Bernstein 
6895ebfb7a5SEric Bernstein 	*req128_vert_wc = (2 * swath_bytes_vert_wc <= detile_buf_size) ?
6905ebfb7a5SEric Bernstein 			false : /* full 256B request */
6915ebfb7a5SEric Bernstein 			true; /* half 128b request */
6925ebfb7a5SEric Bernstein }
6935ebfb7a5SEric Bernstein 
6945ebfb7a5SEric Bernstein static bool hubbub1_get_dcc_compression_cap(struct hubbub *hubbub,
6955ebfb7a5SEric Bernstein 		const struct dc_dcc_surface_param *input,
6965ebfb7a5SEric Bernstein 		struct dc_surface_dcc_cap *output)
6975ebfb7a5SEric Bernstein {
6985ebfb7a5SEric Bernstein 	struct dc *dc = hubbub->ctx->dc;
6995ebfb7a5SEric Bernstein 	/* implement section 1.6.2.1 of DCN1_Programming_Guide.docx */
7005ebfb7a5SEric Bernstein 	enum dcc_control dcc_control;
7015ebfb7a5SEric Bernstein 	unsigned int bpe;
7025ebfb7a5SEric Bernstein 	enum segment_order segment_order_horz, segment_order_vert;
7035ebfb7a5SEric Bernstein 	bool req128_horz_wc, req128_vert_wc;
7045ebfb7a5SEric Bernstein 
7055ebfb7a5SEric Bernstein 	memset(output, 0, sizeof(*output));
7065ebfb7a5SEric Bernstein 
7075ebfb7a5SEric Bernstein 	if (dc->debug.disable_dcc == DCC_DISABLE)
7085ebfb7a5SEric Bernstein 		return false;
7095ebfb7a5SEric Bernstein 
7105ebfb7a5SEric Bernstein 	if (!hubbub->funcs->dcc_support_pixel_format(input->format, &bpe))
7115ebfb7a5SEric Bernstein 		return false;
7125ebfb7a5SEric Bernstein 
7135ebfb7a5SEric Bernstein 	if (!hubbub->funcs->dcc_support_swizzle(input->swizzle_mode, bpe,
7145ebfb7a5SEric Bernstein 			&segment_order_horz, &segment_order_vert))
7155ebfb7a5SEric Bernstein 		return false;
7165ebfb7a5SEric Bernstein 
7175ebfb7a5SEric Bernstein 	hubbub1_det_request_size(input->surface_size.height,  input->surface_size.width,
7185ebfb7a5SEric Bernstein 			bpe, &req128_horz_wc, &req128_vert_wc);
7195ebfb7a5SEric Bernstein 
7205ebfb7a5SEric Bernstein 	if (!req128_horz_wc && !req128_vert_wc) {
7215ebfb7a5SEric Bernstein 		dcc_control = dcc_control__256_256_xxx;
7225ebfb7a5SEric Bernstein 	} else if (input->scan == SCAN_DIRECTION_HORIZONTAL) {
7235ebfb7a5SEric Bernstein 		if (!req128_horz_wc)
7245ebfb7a5SEric Bernstein 			dcc_control = dcc_control__256_256_xxx;
7255ebfb7a5SEric Bernstein 		else if (segment_order_horz == segment_order__contiguous)
7265ebfb7a5SEric Bernstein 			dcc_control = dcc_control__128_128_xxx;
7275ebfb7a5SEric Bernstein 		else
7285ebfb7a5SEric Bernstein 			dcc_control = dcc_control__256_64_64;
7295ebfb7a5SEric Bernstein 	} else if (input->scan == SCAN_DIRECTION_VERTICAL) {
7305ebfb7a5SEric Bernstein 		if (!req128_vert_wc)
7315ebfb7a5SEric Bernstein 			dcc_control = dcc_control__256_256_xxx;
7325ebfb7a5SEric Bernstein 		else if (segment_order_vert == segment_order__contiguous)
7335ebfb7a5SEric Bernstein 			dcc_control = dcc_control__128_128_xxx;
7345ebfb7a5SEric Bernstein 		else
7355ebfb7a5SEric Bernstein 			dcc_control = dcc_control__256_64_64;
7365ebfb7a5SEric Bernstein 	} else {
7375ebfb7a5SEric Bernstein 		if ((req128_horz_wc &&
7385ebfb7a5SEric Bernstein 			segment_order_horz == segment_order__non_contiguous) ||
7395ebfb7a5SEric Bernstein 			(req128_vert_wc &&
7405ebfb7a5SEric Bernstein 			segment_order_vert == segment_order__non_contiguous))
7415ebfb7a5SEric Bernstein 			/* access_dir not known, must use most constraining */
7425ebfb7a5SEric Bernstein 			dcc_control = dcc_control__256_64_64;
7435ebfb7a5SEric Bernstein 		else
7445ebfb7a5SEric Bernstein 			/* reg128 is true for either horz and vert
7455ebfb7a5SEric Bernstein 			 * but segment_order is contiguous
7465ebfb7a5SEric Bernstein 			 */
7475ebfb7a5SEric Bernstein 			dcc_control = dcc_control__128_128_xxx;
7485ebfb7a5SEric Bernstein 	}
7495ebfb7a5SEric Bernstein 
7505ebfb7a5SEric Bernstein 	if (dc->debug.disable_dcc == DCC_HALF_REQ_DISALBE &&
7515ebfb7a5SEric Bernstein 		dcc_control != dcc_control__256_256_xxx)
7525ebfb7a5SEric Bernstein 		return false;
7535ebfb7a5SEric Bernstein 
7545ebfb7a5SEric Bernstein 	switch (dcc_control) {
7555ebfb7a5SEric Bernstein 	case dcc_control__256_256_xxx:
7565ebfb7a5SEric Bernstein 		output->grph.rgb.max_uncompressed_blk_size = 256;
7575ebfb7a5SEric Bernstein 		output->grph.rgb.max_compressed_blk_size = 256;
7585ebfb7a5SEric Bernstein 		output->grph.rgb.independent_64b_blks = false;
7595ebfb7a5SEric Bernstein 		break;
7605ebfb7a5SEric Bernstein 	case dcc_control__128_128_xxx:
7615ebfb7a5SEric Bernstein 		output->grph.rgb.max_uncompressed_blk_size = 128;
7625ebfb7a5SEric Bernstein 		output->grph.rgb.max_compressed_blk_size = 128;
7635ebfb7a5SEric Bernstein 		output->grph.rgb.independent_64b_blks = false;
7645ebfb7a5SEric Bernstein 		break;
7655ebfb7a5SEric Bernstein 	case dcc_control__256_64_64:
7665ebfb7a5SEric Bernstein 		output->grph.rgb.max_uncompressed_blk_size = 256;
7675ebfb7a5SEric Bernstein 		output->grph.rgb.max_compressed_blk_size = 64;
7685ebfb7a5SEric Bernstein 		output->grph.rgb.independent_64b_blks = true;
7695ebfb7a5SEric Bernstein 		break;
7705ebfb7a5SEric Bernstein 	}
7715ebfb7a5SEric Bernstein 
7725ebfb7a5SEric Bernstein 	output->capable = true;
7735ebfb7a5SEric Bernstein 	output->const_color_support = false;
7745ebfb7a5SEric Bernstein 
7755ebfb7a5SEric Bernstein 	return true;
7765ebfb7a5SEric Bernstein }
7775ebfb7a5SEric Bernstein 
778c9ef081dSYue Hin Lau static const struct hubbub_funcs hubbub1_funcs = {
7795ebfb7a5SEric Bernstein 	.update_dchub = hubbub1_update_dchub,
7805ebfb7a5SEric Bernstein 	.dcc_support_swizzle = hubbub1_dcc_support_swizzle,
7815ebfb7a5SEric Bernstein 	.dcc_support_pixel_format = hubbub1_dcc_support_pixel_format,
7825ebfb7a5SEric Bernstein 	.get_dcc_compression_cap = hubbub1_get_dcc_compression_cap,
783c9ef081dSYue Hin Lau };
784c9ef081dSYue Hin Lau 
785c9ef081dSYue Hin Lau void hubbub1_construct(struct hubbub *hubbub,
786c9ef081dSYue Hin Lau 	struct dc_context *ctx,
787c9ef081dSYue Hin Lau 	const struct dcn_hubbub_registers *hubbub_regs,
788c9ef081dSYue Hin Lau 	const struct dcn_hubbub_shift *hubbub_shift,
789c9ef081dSYue Hin Lau 	const struct dcn_hubbub_mask *hubbub_mask)
790c9ef081dSYue Hin Lau {
791c9ef081dSYue Hin Lau 	hubbub->ctx = ctx;
792c9ef081dSYue Hin Lau 
793c9ef081dSYue Hin Lau 	hubbub->funcs = &hubbub1_funcs;
794c9ef081dSYue Hin Lau 
795c9ef081dSYue Hin Lau 	hubbub->regs = hubbub_regs;
796c9ef081dSYue Hin Lau 	hubbub->shifts = hubbub_shift;
797c9ef081dSYue Hin Lau 	hubbub->masks = hubbub_mask;
798c9ef081dSYue Hin Lau 
799cf1df90fSHersen Wu 	hubbub->debug_test_index_pstate = 0x7;
800c9ef081dSYue Hin Lau }
80162d591a8SYue Hin Lau 
802