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
3362d591a8SYue Hin Lau #define REG(reg)\
34c9ef081dSYue Hin Lau 	hubbub->regs->reg
3562d591a8SYue Hin Lau 
3662d591a8SYue Hin Lau #undef FN
3762d591a8SYue Hin Lau #define FN(reg_name, field_name) \
38c9ef081dSYue Hin Lau 	hubbub->shifts->field_name, hubbub->masks->field_name
3962d591a8SYue Hin Lau 
40c9ef081dSYue Hin Lau void hubbub1_wm_read_state(struct hubbub *hubbub,
4162d591a8SYue Hin Lau 		struct dcn_hubbub_wm *wm)
4262d591a8SYue Hin Lau {
4362d591a8SYue Hin Lau 	struct dcn_hubbub_wm_set *s;
4462d591a8SYue Hin Lau 
4562d591a8SYue Hin Lau 	s = &wm->sets[0];
4662d591a8SYue Hin Lau 	s->wm_set = 0;
4762d591a8SYue Hin Lau 	s->data_urgent = REG_READ(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A);
4862d591a8SYue Hin Lau 	s->pte_meta_urgent = REG_READ(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_A);
4962d591a8SYue Hin Lau 	s->sr_enter = REG_READ(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A);
5062d591a8SYue Hin Lau 	s->sr_exit = REG_READ(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A);
5162d591a8SYue Hin Lau 	s->dram_clk_chanage = REG_READ(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A);
5262d591a8SYue Hin Lau 
5362d591a8SYue Hin Lau 	s = &wm->sets[1];
5462d591a8SYue Hin Lau 	s->wm_set = 1;
5562d591a8SYue Hin Lau 	s->data_urgent = REG_READ(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B);
5662d591a8SYue Hin Lau 	s->pte_meta_urgent = REG_READ(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_B);
5762d591a8SYue Hin Lau 	s->sr_enter = REG_READ(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B);
5862d591a8SYue Hin Lau 	s->sr_exit = REG_READ(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B);
5962d591a8SYue Hin Lau 	s->dram_clk_chanage = REG_READ(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B);
6062d591a8SYue Hin Lau 
6162d591a8SYue Hin Lau 	s = &wm->sets[2];
6262d591a8SYue Hin Lau 	s->wm_set = 2;
6362d591a8SYue Hin Lau 	s->data_urgent = REG_READ(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C);
6462d591a8SYue Hin Lau 	s->pte_meta_urgent = REG_READ(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_C);
6562d591a8SYue Hin Lau 	s->sr_enter = REG_READ(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C);
6662d591a8SYue Hin Lau 	s->sr_exit = REG_READ(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C);
6762d591a8SYue Hin Lau 	s->dram_clk_chanage = REG_READ(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C);
6862d591a8SYue Hin Lau 
6962d591a8SYue Hin Lau 	s = &wm->sets[3];
7062d591a8SYue Hin Lau 	s->wm_set = 3;
7162d591a8SYue Hin Lau 	s->data_urgent = REG_READ(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D);
7262d591a8SYue Hin Lau 	s->pte_meta_urgent = REG_READ(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_D);
7362d591a8SYue Hin Lau 	s->sr_enter = REG_READ(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D);
7462d591a8SYue Hin Lau 	s->sr_exit = REG_READ(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D);
7562d591a8SYue Hin Lau 	s->dram_clk_chanage = REG_READ(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D);
7662d591a8SYue Hin Lau }
7762d591a8SYue Hin Lau 
78ea00f297SYue Hin Lau bool hubbub1_verify_allow_pstate_change_high(
79c9ef081dSYue Hin Lau 	struct hubbub *hubbub)
8062d591a8SYue Hin Lau {
8162d591a8SYue Hin Lau 	/* pstate latency is ~20us so if we wait over 40us and pstate allow
8262d591a8SYue Hin Lau 	 * still not asserted, we are probably stuck and going to hang
8362d591a8SYue Hin Lau 	 *
8462d591a8SYue Hin Lau 	 * TODO: Figure out why it takes ~100us on linux
8562d591a8SYue Hin Lau 	 * pstate takes around ~100us on linux. Unknown currently as to
8662d591a8SYue Hin Lau 	 * why it takes that long on linux
8762d591a8SYue Hin Lau 	 */
8862d591a8SYue Hin Lau 	static unsigned int pstate_wait_timeout_us = 200;
8962d591a8SYue Hin Lau 	static unsigned int pstate_wait_expected_timeout_us = 40;
9062d591a8SYue Hin Lau 	static unsigned int max_sampled_pstate_wait_us; /* data collection */
9162d591a8SYue Hin Lau 	static bool forced_pstate_allow; /* help with revert wa */
9262d591a8SYue Hin Lau 
9362d591a8SYue Hin Lau 	unsigned int debug_index = 0x7;
9462d591a8SYue Hin Lau 	unsigned int debug_data;
9562d591a8SYue Hin Lau 	unsigned int i;
9662d591a8SYue Hin Lau 
9762d591a8SYue Hin Lau 	if (forced_pstate_allow) {
9862d591a8SYue Hin Lau 		/* we hacked to force pstate allow to prevent hang last time
9962d591a8SYue Hin Lau 		 * we verify_allow_pstate_change_high.  so disable force
10062d591a8SYue Hin Lau 		 * here so we can check status
10162d591a8SYue Hin Lau 		 */
10262d591a8SYue Hin Lau 		REG_UPDATE_2(DCHUBBUB_ARB_DRAM_STATE_CNTL,
10362d591a8SYue Hin Lau 			     DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_VALUE, 0,
10462d591a8SYue Hin Lau 			     DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_ENABLE, 0);
10562d591a8SYue Hin Lau 		forced_pstate_allow = false;
10662d591a8SYue Hin Lau 	}
10762d591a8SYue Hin Lau 
10862d591a8SYue Hin Lau 	/* description "3-0:   Pipe0 cursor0 QOS
10962d591a8SYue Hin Lau 	 * 7-4:   Pipe1 cursor0 QOS
11062d591a8SYue Hin Lau 	 * 11-8:  Pipe2 cursor0 QOS
11162d591a8SYue Hin Lau 	 * 15-12: Pipe3 cursor0 QOS
11262d591a8SYue Hin Lau 	 * 16:    Pipe0 Plane0 Allow Pstate Change
11362d591a8SYue Hin Lau 	 * 17:    Pipe1 Plane0 Allow Pstate Change
11462d591a8SYue Hin Lau 	 * 18:    Pipe2 Plane0 Allow Pstate Change
11562d591a8SYue Hin Lau 	 * 19:    Pipe3 Plane0 Allow Pstate Change
11662d591a8SYue Hin Lau 	 * 20:    Pipe0 Plane1 Allow Pstate Change
11762d591a8SYue Hin Lau 	 * 21:    Pipe1 Plane1 Allow Pstate Change
11862d591a8SYue Hin Lau 	 * 22:    Pipe2 Plane1 Allow Pstate Change
11962d591a8SYue Hin Lau 	 * 23:    Pipe3 Plane1 Allow Pstate Change
12062d591a8SYue Hin Lau 	 * 24:    Pipe0 cursor0 Allow Pstate Change
12162d591a8SYue Hin Lau 	 * 25:    Pipe1 cursor0 Allow Pstate Change
12262d591a8SYue Hin Lau 	 * 26:    Pipe2 cursor0 Allow Pstate Change
12362d591a8SYue Hin Lau 	 * 27:    Pipe3 cursor0 Allow Pstate Change
12462d591a8SYue Hin Lau 	 * 28:    WB0 Allow Pstate Change
12562d591a8SYue Hin Lau 	 * 29:    WB1 Allow Pstate Change
12662d591a8SYue Hin Lau 	 * 30:    Arbiter's allow_pstate_change
12762d591a8SYue Hin Lau 	 * 31:    SOC pstate change request
12862d591a8SYue Hin Lau 	 */
12962d591a8SYue Hin Lau 
13062d591a8SYue Hin Lau 	REG_WRITE(DCHUBBUB_TEST_DEBUG_INDEX, debug_index);
13162d591a8SYue Hin Lau 
13262d591a8SYue Hin Lau 	for (i = 0; i < pstate_wait_timeout_us; i++) {
13362d591a8SYue Hin Lau 		debug_data = REG_READ(DCHUBBUB_TEST_DEBUG_DATA);
13462d591a8SYue Hin Lau 
13562d591a8SYue Hin Lau 		if (debug_data & (1 << 30)) {
13662d591a8SYue Hin Lau 
13762d591a8SYue Hin Lau 			if (i > pstate_wait_expected_timeout_us)
138c9ef081dSYue Hin Lau 				dm_logger_write(hubbub->ctx->logger, LOG_WARNING,
13962d591a8SYue Hin Lau 						"pstate took longer than expected ~%dus\n",
14062d591a8SYue Hin Lau 						i);
14162d591a8SYue Hin Lau 
142ea00f297SYue Hin Lau 			return false;
14362d591a8SYue Hin Lau 		}
14462d591a8SYue Hin Lau 		if (max_sampled_pstate_wait_us < i)
14562d591a8SYue Hin Lau 			max_sampled_pstate_wait_us = i;
14662d591a8SYue Hin Lau 
14762d591a8SYue Hin Lau 		udelay(1);
14862d591a8SYue Hin Lau 	}
14962d591a8SYue Hin Lau 
15062d591a8SYue Hin Lau 	/* force pstate allow to prevent system hang
15162d591a8SYue Hin Lau 	 * and break to debugger to investigate
15262d591a8SYue Hin Lau 	 */
15362d591a8SYue Hin Lau 	REG_UPDATE_2(DCHUBBUB_ARB_DRAM_STATE_CNTL,
15462d591a8SYue Hin Lau 		     DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_VALUE, 1,
15562d591a8SYue Hin Lau 		     DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_ENABLE, 1);
15662d591a8SYue Hin Lau 	forced_pstate_allow = true;
15762d591a8SYue Hin Lau 
158c9ef081dSYue Hin Lau 	dm_logger_write(hubbub->ctx->logger, LOG_WARNING,
15962d591a8SYue Hin Lau 			"pstate TEST_DEBUG_DATA: 0x%X\n",
16062d591a8SYue Hin Lau 			debug_data);
161ea00f297SYue Hin Lau 
162ea00f297SYue Hin Lau 	return true;
16362d591a8SYue Hin Lau }
16462d591a8SYue Hin Lau 
16562d591a8SYue Hin Lau static uint32_t convert_and_clamp(
16662d591a8SYue Hin Lau 	uint32_t wm_ns,
16762d591a8SYue Hin Lau 	uint32_t refclk_mhz,
16862d591a8SYue Hin Lau 	uint32_t clamp_value)
16962d591a8SYue Hin Lau {
17062d591a8SYue Hin Lau 	uint32_t ret_val = 0;
17162d591a8SYue Hin Lau 	ret_val = wm_ns * refclk_mhz;
17262d591a8SYue Hin Lau 	ret_val /= 1000;
17362d591a8SYue Hin Lau 
17462d591a8SYue Hin Lau 	if (ret_val > clamp_value)
17562d591a8SYue Hin Lau 		ret_val = clamp_value;
17662d591a8SYue Hin Lau 
17762d591a8SYue Hin Lau 	return ret_val;
17862d591a8SYue Hin Lau }
17962d591a8SYue Hin Lau 
18062d591a8SYue Hin Lau 
181ea00f297SYue Hin Lau void hubbub1_program_watermarks(
182c9ef081dSYue Hin Lau 		struct hubbub *hubbub,
18362d591a8SYue Hin Lau 		struct dcn_watermark_set *watermarks,
18462d591a8SYue Hin Lau 		unsigned int refclk_mhz)
18562d591a8SYue Hin Lau {
186c9ef081dSYue Hin Lau 	uint32_t force_en = hubbub->ctx->dc->debug.disable_stutter ? 1 : 0;
18762d591a8SYue Hin Lau 	/*
18862d591a8SYue Hin Lau 	 * Need to clamp to max of the register values (i.e. no wrap)
18962d591a8SYue Hin Lau 	 * for dcn1, all wm registers are 21-bit wide
19062d591a8SYue Hin Lau 	 */
19162d591a8SYue Hin Lau 	uint32_t prog_wm_value;
19262d591a8SYue Hin Lau 
19362d591a8SYue Hin Lau 	REG_UPDATE(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL,
19462d591a8SYue Hin Lau 			DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, 0);
19562d591a8SYue Hin Lau 
19662d591a8SYue Hin Lau 	/* Repeat for water mark set A, B, C and D. */
19762d591a8SYue Hin Lau 	/* clock state A */
19862d591a8SYue Hin Lau 	prog_wm_value = convert_and_clamp(watermarks->a.urgent_ns,
19962d591a8SYue Hin Lau 			refclk_mhz, 0x1fffff);
20062d591a8SYue Hin Lau 	REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, prog_wm_value);
20162d591a8SYue Hin Lau 
202c9ef081dSYue Hin Lau 	dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS,
20362d591a8SYue Hin Lau 		"URGENCY_WATERMARK_A calculated =%d\n"
20462d591a8SYue Hin Lau 		"HW register value = 0x%x\n",
20562d591a8SYue Hin Lau 		watermarks->a.urgent_ns, prog_wm_value);
20662d591a8SYue Hin Lau 
20762d591a8SYue Hin Lau 	prog_wm_value = convert_and_clamp(watermarks->a.pte_meta_urgent_ns,
20862d591a8SYue Hin Lau 			refclk_mhz, 0x1fffff);
20962d591a8SYue Hin Lau 	REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_A, prog_wm_value);
210c9ef081dSYue Hin Lau 	dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS,
21162d591a8SYue Hin Lau 		"PTE_META_URGENCY_WATERMARK_A calculated =%d\n"
21262d591a8SYue Hin Lau 		"HW register value = 0x%x\n",
21362d591a8SYue Hin Lau 		watermarks->a.pte_meta_urgent_ns, prog_wm_value);
21462d591a8SYue Hin Lau 
21562d591a8SYue Hin Lau 	if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A)) {
21662d591a8SYue Hin Lau 		prog_wm_value = convert_and_clamp(
21762d591a8SYue Hin Lau 				watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns,
21862d591a8SYue Hin Lau 				refclk_mhz, 0x1fffff);
21962d591a8SYue Hin Lau 		REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A, prog_wm_value);
220c9ef081dSYue Hin Lau 		dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS,
22162d591a8SYue Hin Lau 			"SR_ENTER_EXIT_WATERMARK_A calculated =%d\n"
22262d591a8SYue Hin Lau 			"HW register value = 0x%x\n",
22362d591a8SYue Hin Lau 			watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
22462d591a8SYue Hin Lau 
22562d591a8SYue Hin Lau 
22662d591a8SYue Hin Lau 		prog_wm_value = convert_and_clamp(
22762d591a8SYue Hin Lau 				watermarks->a.cstate_pstate.cstate_exit_ns,
22862d591a8SYue Hin Lau 				refclk_mhz, 0x1fffff);
22962d591a8SYue Hin Lau 		REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A, prog_wm_value);
230c9ef081dSYue Hin Lau 		dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS,
23162d591a8SYue Hin Lau 			"SR_EXIT_WATERMARK_A calculated =%d\n"
23262d591a8SYue Hin Lau 			"HW register value = 0x%x\n",
23362d591a8SYue Hin Lau 			watermarks->a.cstate_pstate.cstate_exit_ns, prog_wm_value);
23462d591a8SYue Hin Lau 	}
23562d591a8SYue Hin Lau 
23662d591a8SYue Hin Lau 	prog_wm_value = convert_and_clamp(
23762d591a8SYue Hin Lau 			watermarks->a.cstate_pstate.pstate_change_ns,
23862d591a8SYue Hin Lau 			refclk_mhz, 0x1fffff);
23962d591a8SYue Hin Lau 	REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A, prog_wm_value);
240c9ef081dSYue Hin Lau 	dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS,
24162d591a8SYue Hin Lau 		"DRAM_CLK_CHANGE_WATERMARK_A calculated =%d\n"
24262d591a8SYue Hin Lau 		"HW register value = 0x%x\n\n",
24362d591a8SYue Hin Lau 		watermarks->a.cstate_pstate.pstate_change_ns, prog_wm_value);
24462d591a8SYue Hin Lau 
24562d591a8SYue Hin Lau 
24662d591a8SYue Hin Lau 	/* clock state B */
24762d591a8SYue Hin Lau 	prog_wm_value = convert_and_clamp(
24862d591a8SYue Hin Lau 			watermarks->b.urgent_ns, refclk_mhz, 0x1fffff);
24962d591a8SYue Hin Lau 	REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, prog_wm_value);
250c9ef081dSYue Hin Lau 	dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS,
25162d591a8SYue Hin Lau 		"URGENCY_WATERMARK_B calculated =%d\n"
25262d591a8SYue Hin Lau 		"HW register value = 0x%x\n",
25362d591a8SYue Hin Lau 		watermarks->b.urgent_ns, prog_wm_value);
25462d591a8SYue Hin Lau 
25562d591a8SYue Hin Lau 
25662d591a8SYue Hin Lau 	prog_wm_value = convert_and_clamp(
25762d591a8SYue Hin Lau 			watermarks->b.pte_meta_urgent_ns,
25862d591a8SYue Hin Lau 			refclk_mhz, 0x1fffff);
25962d591a8SYue Hin Lau 	REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_B, prog_wm_value);
260c9ef081dSYue Hin Lau 	dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS,
26162d591a8SYue Hin Lau 		"PTE_META_URGENCY_WATERMARK_B calculated =%d\n"
26262d591a8SYue Hin Lau 		"HW register value = 0x%x\n",
26362d591a8SYue Hin Lau 		watermarks->b.pte_meta_urgent_ns, prog_wm_value);
26462d591a8SYue Hin Lau 
26562d591a8SYue Hin Lau 
26662d591a8SYue Hin Lau 	if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B)) {
26762d591a8SYue Hin Lau 		prog_wm_value = convert_and_clamp(
26862d591a8SYue Hin Lau 				watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns,
26962d591a8SYue Hin Lau 				refclk_mhz, 0x1fffff);
27062d591a8SYue Hin Lau 		REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, prog_wm_value);
271c9ef081dSYue Hin Lau 		dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS,
27262d591a8SYue Hin Lau 			"SR_ENTER_WATERMARK_B calculated =%d\n"
27362d591a8SYue Hin Lau 			"HW register value = 0x%x\n",
27462d591a8SYue Hin Lau 			watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
27562d591a8SYue Hin Lau 
27662d591a8SYue Hin Lau 
27762d591a8SYue Hin Lau 		prog_wm_value = convert_and_clamp(
27862d591a8SYue Hin Lau 				watermarks->b.cstate_pstate.cstate_exit_ns,
27962d591a8SYue Hin Lau 				refclk_mhz, 0x1fffff);
28062d591a8SYue Hin Lau 		REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, prog_wm_value);
281c9ef081dSYue Hin Lau 		dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS,
28262d591a8SYue Hin Lau 			"SR_EXIT_WATERMARK_B calculated =%d\n"
28362d591a8SYue Hin Lau 			"HW register value = 0x%x\n",
28462d591a8SYue Hin Lau 			watermarks->b.cstate_pstate.cstate_exit_ns, prog_wm_value);
28562d591a8SYue Hin Lau 	}
28662d591a8SYue Hin Lau 
28762d591a8SYue Hin Lau 	prog_wm_value = convert_and_clamp(
28862d591a8SYue Hin Lau 			watermarks->b.cstate_pstate.pstate_change_ns,
28962d591a8SYue Hin Lau 			refclk_mhz, 0x1fffff);
29062d591a8SYue Hin Lau 	REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B, prog_wm_value);
291c9ef081dSYue Hin Lau 	dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS,
29262d591a8SYue Hin Lau 		"DRAM_CLK_CHANGE_WATERMARK_B calculated =%d\n\n"
29362d591a8SYue Hin Lau 		"HW register value = 0x%x\n",
29462d591a8SYue Hin Lau 		watermarks->b.cstate_pstate.pstate_change_ns, prog_wm_value);
29562d591a8SYue Hin Lau 
29662d591a8SYue Hin Lau 	/* clock state C */
29762d591a8SYue Hin Lau 	prog_wm_value = convert_and_clamp(
29862d591a8SYue Hin Lau 			watermarks->c.urgent_ns, refclk_mhz, 0x1fffff);
29962d591a8SYue Hin Lau 	REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, prog_wm_value);
300c9ef081dSYue Hin Lau 	dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS,
30162d591a8SYue Hin Lau 		"URGENCY_WATERMARK_C calculated =%d\n"
30262d591a8SYue Hin Lau 		"HW register value = 0x%x\n",
30362d591a8SYue Hin Lau 		watermarks->c.urgent_ns, prog_wm_value);
30462d591a8SYue Hin Lau 
30562d591a8SYue Hin Lau 
30662d591a8SYue Hin Lau 	prog_wm_value = convert_and_clamp(
30762d591a8SYue Hin Lau 			watermarks->c.pte_meta_urgent_ns,
30862d591a8SYue Hin Lau 			refclk_mhz, 0x1fffff);
30962d591a8SYue Hin Lau 	REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_C, prog_wm_value);
310c9ef081dSYue Hin Lau 	dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS,
31162d591a8SYue Hin Lau 		"PTE_META_URGENCY_WATERMARK_C calculated =%d\n"
31262d591a8SYue Hin Lau 		"HW register value = 0x%x\n",
31362d591a8SYue Hin Lau 		watermarks->c.pte_meta_urgent_ns, prog_wm_value);
31462d591a8SYue Hin Lau 
31562d591a8SYue Hin Lau 
31662d591a8SYue Hin Lau 	if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C)) {
31762d591a8SYue Hin Lau 		prog_wm_value = convert_and_clamp(
31862d591a8SYue Hin Lau 				watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns,
31962d591a8SYue Hin Lau 				refclk_mhz, 0x1fffff);
32062d591a8SYue Hin Lau 		REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, prog_wm_value);
321c9ef081dSYue Hin Lau 		dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS,
32262d591a8SYue Hin Lau 			"SR_ENTER_WATERMARK_C calculated =%d\n"
32362d591a8SYue Hin Lau 			"HW register value = 0x%x\n",
32462d591a8SYue Hin Lau 			watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
32562d591a8SYue Hin Lau 
32662d591a8SYue Hin Lau 
32762d591a8SYue Hin Lau 		prog_wm_value = convert_and_clamp(
32862d591a8SYue Hin Lau 				watermarks->c.cstate_pstate.cstate_exit_ns,
32962d591a8SYue Hin Lau 				refclk_mhz, 0x1fffff);
33062d591a8SYue Hin Lau 		REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C, prog_wm_value);
331c9ef081dSYue Hin Lau 		dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS,
33262d591a8SYue Hin Lau 			"SR_EXIT_WATERMARK_C calculated =%d\n"
33362d591a8SYue Hin Lau 			"HW register value = 0x%x\n",
33462d591a8SYue Hin Lau 			watermarks->c.cstate_pstate.cstate_exit_ns, prog_wm_value);
33562d591a8SYue Hin Lau 	}
33662d591a8SYue Hin Lau 
33762d591a8SYue Hin Lau 	prog_wm_value = convert_and_clamp(
33862d591a8SYue Hin Lau 			watermarks->c.cstate_pstate.pstate_change_ns,
33962d591a8SYue Hin Lau 			refclk_mhz, 0x1fffff);
34062d591a8SYue Hin Lau 	REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C, prog_wm_value);
341c9ef081dSYue Hin Lau 	dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS,
34262d591a8SYue Hin Lau 		"DRAM_CLK_CHANGE_WATERMARK_C calculated =%d\n\n"
34362d591a8SYue Hin Lau 		"HW register value = 0x%x\n",
34462d591a8SYue Hin Lau 		watermarks->c.cstate_pstate.pstate_change_ns, prog_wm_value);
34562d591a8SYue Hin Lau 
34662d591a8SYue Hin Lau 	/* clock state D */
34762d591a8SYue Hin Lau 	prog_wm_value = convert_and_clamp(
34862d591a8SYue Hin Lau 			watermarks->d.urgent_ns, refclk_mhz, 0x1fffff);
34962d591a8SYue Hin Lau 	REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, prog_wm_value);
350c9ef081dSYue Hin Lau 	dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS,
35162d591a8SYue Hin Lau 		"URGENCY_WATERMARK_D calculated =%d\n"
35262d591a8SYue Hin Lau 		"HW register value = 0x%x\n",
35362d591a8SYue Hin Lau 		watermarks->d.urgent_ns, prog_wm_value);
35462d591a8SYue Hin Lau 
35562d591a8SYue Hin Lau 	prog_wm_value = convert_and_clamp(
35662d591a8SYue Hin Lau 			watermarks->d.pte_meta_urgent_ns,
35762d591a8SYue Hin Lau 			refclk_mhz, 0x1fffff);
35862d591a8SYue Hin Lau 	REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_D, prog_wm_value);
359c9ef081dSYue Hin Lau 	dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS,
36062d591a8SYue Hin Lau 		"PTE_META_URGENCY_WATERMARK_D calculated =%d\n"
36162d591a8SYue Hin Lau 		"HW register value = 0x%x\n",
36262d591a8SYue Hin Lau 		watermarks->d.pte_meta_urgent_ns, prog_wm_value);
36362d591a8SYue Hin Lau 
36462d591a8SYue Hin Lau 
36562d591a8SYue Hin Lau 	if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D)) {
36662d591a8SYue Hin Lau 		prog_wm_value = convert_and_clamp(
36762d591a8SYue Hin Lau 				watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns,
36862d591a8SYue Hin Lau 				refclk_mhz, 0x1fffff);
36962d591a8SYue Hin Lau 		REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, prog_wm_value);
370c9ef081dSYue Hin Lau 		dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS,
37162d591a8SYue Hin Lau 			"SR_ENTER_WATERMARK_D calculated =%d\n"
37262d591a8SYue Hin Lau 			"HW register value = 0x%x\n",
37362d591a8SYue Hin Lau 			watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
37462d591a8SYue Hin Lau 
37562d591a8SYue Hin Lau 
37662d591a8SYue Hin Lau 		prog_wm_value = convert_and_clamp(
37762d591a8SYue Hin Lau 				watermarks->d.cstate_pstate.cstate_exit_ns,
37862d591a8SYue Hin Lau 				refclk_mhz, 0x1fffff);
37962d591a8SYue Hin Lau 		REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D, prog_wm_value);
380c9ef081dSYue Hin Lau 		dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS,
38162d591a8SYue Hin Lau 			"SR_EXIT_WATERMARK_D calculated =%d\n"
38262d591a8SYue Hin Lau 			"HW register value = 0x%x\n",
38362d591a8SYue Hin Lau 			watermarks->d.cstate_pstate.cstate_exit_ns, prog_wm_value);
38462d591a8SYue Hin Lau 	}
38562d591a8SYue Hin Lau 
38662d591a8SYue Hin Lau 
38762d591a8SYue Hin Lau 	prog_wm_value = convert_and_clamp(
38862d591a8SYue Hin Lau 			watermarks->d.cstate_pstate.pstate_change_ns,
38962d591a8SYue Hin Lau 			refclk_mhz, 0x1fffff);
39062d591a8SYue Hin Lau 	REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D, prog_wm_value);
391c9ef081dSYue Hin Lau 	dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS,
39262d591a8SYue Hin Lau 		"DRAM_CLK_CHANGE_WATERMARK_D calculated =%d\n"
39362d591a8SYue Hin Lau 		"HW register value = 0x%x\n\n",
39462d591a8SYue Hin Lau 		watermarks->d.cstate_pstate.pstate_change_ns, prog_wm_value);
39562d591a8SYue Hin Lau 
39662d591a8SYue Hin Lau 	REG_UPDATE(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL,
39762d591a8SYue Hin Lau 			DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, 1);
39862d591a8SYue Hin Lau 
39962d591a8SYue Hin Lau 	REG_UPDATE(DCHUBBUB_ARB_SAT_LEVEL,
40062d591a8SYue Hin Lau 			DCHUBBUB_ARB_SAT_LEVEL, 60 * refclk_mhz);
40162d591a8SYue Hin Lau 	REG_UPDATE(DCHUBBUB_ARB_DF_REQ_OUTSTAND,
40262d591a8SYue Hin Lau 			DCHUBBUB_ARB_MIN_REQ_OUTSTAND, 68);
40362d591a8SYue Hin Lau 
40462d591a8SYue Hin Lau 	REG_UPDATE_2(DCHUBBUB_ARB_DRAM_STATE_CNTL,
40562d591a8SYue Hin Lau 			DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_VALUE, 0,
40662d591a8SYue Hin Lau 			DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_ENABLE, force_en);
40762d591a8SYue Hin Lau 
40862d591a8SYue Hin Lau #if 0
40962d591a8SYue Hin Lau 	REG_UPDATE_2(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL,
41062d591a8SYue Hin Lau 			DCHUBBUB_ARB_WATERMARK_CHANGE_DONE_INTERRUPT_DISABLE, 1,
41162d591a8SYue Hin Lau 			DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, 1);
41262d591a8SYue Hin Lau #endif
41362d591a8SYue Hin Lau }
41462d591a8SYue Hin Lau 
415c9ef081dSYue Hin Lau void hubbub1_update_dchub(
416c9ef081dSYue Hin Lau 	struct hubbub *hubbub,
41762d591a8SYue Hin Lau 	struct dchub_init_data *dh_data)
41862d591a8SYue Hin Lau {
41962d591a8SYue Hin Lau 	/* TODO: port code from dal2 */
42062d591a8SYue Hin Lau 	switch (dh_data->fb_mode) {
42162d591a8SYue Hin Lau 	case FRAME_BUFFER_MODE_ZFB_ONLY:
42262d591a8SYue Hin Lau 		/*For ZFB case need to put DCHUB FB BASE and TOP upside down to indicate ZFB mode*/
42362d591a8SYue Hin Lau 		REG_UPDATE(DCHUBBUB_SDPIF_FB_TOP,
42462d591a8SYue Hin Lau 				SDPIF_FB_TOP, 0);
42562d591a8SYue Hin Lau 
42662d591a8SYue Hin Lau 		REG_UPDATE(DCHUBBUB_SDPIF_FB_BASE,
42762d591a8SYue Hin Lau 				SDPIF_FB_BASE, 0x0FFFF);
42862d591a8SYue Hin Lau 
42962d591a8SYue Hin Lau 		REG_UPDATE(DCHUBBUB_SDPIF_AGP_BASE,
43062d591a8SYue Hin Lau 				SDPIF_AGP_BASE, dh_data->zfb_phys_addr_base >> 22);
43162d591a8SYue Hin Lau 
43262d591a8SYue Hin Lau 		REG_UPDATE(DCHUBBUB_SDPIF_AGP_BOT,
43362d591a8SYue Hin Lau 				SDPIF_AGP_BOT, dh_data->zfb_mc_base_addr >> 22);
43462d591a8SYue Hin Lau 
43562d591a8SYue Hin Lau 		REG_UPDATE(DCHUBBUB_SDPIF_AGP_TOP,
43662d591a8SYue Hin Lau 				SDPIF_AGP_TOP, (dh_data->zfb_mc_base_addr +
43762d591a8SYue Hin Lau 						dh_data->zfb_size_in_byte - 1) >> 22);
43862d591a8SYue Hin Lau 		break;
43962d591a8SYue Hin Lau 	case FRAME_BUFFER_MODE_MIXED_ZFB_AND_LOCAL:
44062d591a8SYue Hin Lau 		/*Should not touch FB LOCATION (done by VBIOS on AsicInit table)*/
44162d591a8SYue Hin Lau 
44262d591a8SYue Hin Lau 		REG_UPDATE(DCHUBBUB_SDPIF_AGP_BASE,
44362d591a8SYue Hin Lau 				SDPIF_AGP_BASE, dh_data->zfb_phys_addr_base >> 22);
44462d591a8SYue Hin Lau 
44562d591a8SYue Hin Lau 		REG_UPDATE(DCHUBBUB_SDPIF_AGP_BOT,
44662d591a8SYue Hin Lau 				SDPIF_AGP_BOT, dh_data->zfb_mc_base_addr >> 22);
44762d591a8SYue Hin Lau 
44862d591a8SYue Hin Lau 		REG_UPDATE(DCHUBBUB_SDPIF_AGP_TOP,
44962d591a8SYue Hin Lau 				SDPIF_AGP_TOP, (dh_data->zfb_mc_base_addr +
45062d591a8SYue Hin Lau 						dh_data->zfb_size_in_byte - 1) >> 22);
45162d591a8SYue Hin Lau 		break;
45262d591a8SYue Hin Lau 	case FRAME_BUFFER_MODE_LOCAL_ONLY:
45362d591a8SYue Hin Lau 		/*Should not touch FB LOCATION (done by VBIOS on AsicInit table)*/
45462d591a8SYue Hin Lau 		REG_UPDATE(DCHUBBUB_SDPIF_AGP_BASE,
45562d591a8SYue Hin Lau 				SDPIF_AGP_BASE, 0);
45662d591a8SYue Hin Lau 
45762d591a8SYue Hin Lau 		REG_UPDATE(DCHUBBUB_SDPIF_AGP_BOT,
45862d591a8SYue Hin Lau 				SDPIF_AGP_BOT, 0X03FFFF);
45962d591a8SYue Hin Lau 
46062d591a8SYue Hin Lau 		REG_UPDATE(DCHUBBUB_SDPIF_AGP_TOP,
46162d591a8SYue Hin Lau 				SDPIF_AGP_TOP, 0);
46262d591a8SYue Hin Lau 		break;
46362d591a8SYue Hin Lau 	default:
46462d591a8SYue Hin Lau 		break;
46562d591a8SYue Hin Lau 	}
46662d591a8SYue Hin Lau 
46762d591a8SYue Hin Lau 	dh_data->dchub_initialzied = true;
46862d591a8SYue Hin Lau 	dh_data->dchub_info_valid = false;
46962d591a8SYue Hin Lau }
47062d591a8SYue Hin Lau 
471ea00f297SYue Hin Lau void hubbub1_toggle_watermark_change_req(struct hubbub *hubbub)
47262d591a8SYue Hin Lau {
47362d591a8SYue Hin Lau 	uint32_t watermark_change_req;
47462d591a8SYue Hin Lau 
47562d591a8SYue Hin Lau 	REG_GET(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL,
47662d591a8SYue Hin Lau 			DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, &watermark_change_req);
47762d591a8SYue Hin Lau 
47862d591a8SYue Hin Lau 	if (watermark_change_req)
47962d591a8SYue Hin Lau 		watermark_change_req = 0;
48062d591a8SYue Hin Lau 	else
48162d591a8SYue Hin Lau 		watermark_change_req = 1;
48262d591a8SYue Hin Lau 
48362d591a8SYue Hin Lau 	REG_UPDATE(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL,
48462d591a8SYue Hin Lau 			DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, watermark_change_req);
48562d591a8SYue Hin Lau }
48662d591a8SYue Hin Lau 
487c9ef081dSYue Hin Lau static const struct hubbub_funcs hubbub1_funcs = {
488c9ef081dSYue Hin Lau 	.update_dchub = hubbub1_update_dchub
489c9ef081dSYue Hin Lau };
490c9ef081dSYue Hin Lau 
491c9ef081dSYue Hin Lau void hubbub1_construct(struct hubbub *hubbub,
492c9ef081dSYue Hin Lau 	struct dc_context *ctx,
493c9ef081dSYue Hin Lau 	const struct dcn_hubbub_registers *hubbub_regs,
494c9ef081dSYue Hin Lau 	const struct dcn_hubbub_shift *hubbub_shift,
495c9ef081dSYue Hin Lau 	const struct dcn_hubbub_mask *hubbub_mask)
496c9ef081dSYue Hin Lau {
497c9ef081dSYue Hin Lau 	hubbub->ctx = ctx;
498c9ef081dSYue Hin Lau 
499c9ef081dSYue Hin Lau 	hubbub->funcs = &hubbub1_funcs;
500c9ef081dSYue Hin Lau 
501c9ef081dSYue Hin Lau 	hubbub->regs = hubbub_regs;
502c9ef081dSYue Hin Lau 	hubbub->shifts = hubbub_shift;
503c9ef081dSYue Hin Lau 	hubbub->masks = hubbub_mask;
504c9ef081dSYue Hin Lau 
505c9ef081dSYue Hin Lau }
50662d591a8SYue Hin Lau 
507