brintos

brintos / linux-shallow public Read only

0
0
Text · 66.7 KiB · 838d72e Raw
2434 lines · c
1/* SPDX-License-Identifier: MIT */2/*3 * Copyright 2023 Advanced Micro Devices, Inc.4 *5 * Permission is hereby granted, free of charge, to any person obtaining a6 * copy of this software and associated documentation files (the "Software"),7 * to deal in the Software without restriction, including without limitation8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,9 * and/or sell copies of the Software, and to permit persons to whom the10 * Software is furnished to do so, subject to the following conditions:11 *12 * The above copyright notice and this permission notice shall be included in13 * all copies or substantial portions of the Software.14 *15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL18 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR19 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,20 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR21 * OTHER DEALINGS IN THE SOFTWARE.22 *23 */24 25#include "reg_helper.h"26#include "core_types.h"27#include "resource.h"28#include "dcn35_dccg.h"29 30#define TO_DCN_DCCG(dccg)\31	container_of(dccg, struct dcn_dccg, base)32 33#define REG(reg) \34	(dccg_dcn->regs->reg)35 36#undef FN37#define FN(reg_name, field_name) \38	dccg_dcn->dccg_shift->field_name, dccg_dcn->dccg_mask->field_name39 40#define CTX \41	dccg_dcn->base.ctx42#define DC_LOGGER \43	dccg->ctx->logger44 45enum symclk_fe_source {46	SYMCLK_FE_SYMCLK_A = 0,	// Select functional clock from backend symclk A47	SYMCLK_FE_SYMCLK_B,48	SYMCLK_FE_SYMCLK_C,49	SYMCLK_FE_SYMCLK_D,50	SYMCLK_FE_SYMCLK_E,51	SYMCLK_FE_REFCLK = 0xFF,	// Arbitrary value to pass refclk selection in software52};53 54enum symclk_be_source {55	SYMCLK_BE_PHYCLK = 0,	// Select phy clk when sym_clk_enable = 156	SYMCLK_BE_DPIACLK_810 = 4,57	SYMCLK_BE_DPIACLK_162 = 5,58	SYMCLK_BE_DPIACLK_540 = 6,59	SYMCLK_BE_DPIACLK_270 = 7,60	SYMCLK_BE_REFCLK = 0xFF,	// Arbitrary value to pass refclk selection in software61};62 63enum physymclk_source {64	PHYSYMCLK_PHYCLK = 0,		// Select symclk as source of clock which is output to PHY through DCIO.65	PHYSYMCLK_PHYD18CLK,		// Select phyd18clk as the source of clock which is output to PHY through DCIO.66	PHYSYMCLK_PHYD32CLK,		// Select phyd32clk as the source of clock which is output to PHY through DCIO.67	PHYSYMCLK_REFCLK = 0xFF,	// Arbitrary value to pass refclk selection in software68};69 70enum dtbclk_source {71	DTBCLK_DPREFCLK = 0,		// Selects source for DTBCLK_P# as DPREFCLK (src sel 0 and 1 are same)72	DTBCLK_DPREFCLK_0,			// Selects source for DTBCLK_P# as DPREFCLK (src sel 0 and 1 are same)73	DTBCLK_DTBCLK0,				// Selects source for DTBCLK_P# as DTBCLK074	DTBCLK_DTBCLK1,				// Selects source for DTBCLK_P# as DTBCLK075	DTBCLK_REFCLK = 0xFF,		// Arbitrary value to pass refclk selection in software76};77 78enum dppclk_clock_source {79	DPP_REFCLK = 0,				// refclk is selected80	DPP_DCCG_DTO,				// Functional clock selected is DTO tuned DPPCLK81};82 83enum dp_stream_clk_source {84	DP_STREAM_DTBCLK_P0 = 0,	// Selects functional for DP_STREAM_CLK as DTBCLK_P#85	DP_STREAM_DTBCLK_P1,86	DP_STREAM_DTBCLK_P2,87	DP_STREAM_DTBCLK_P3,88	DP_STREAM_DTBCLK_P4,89	DP_STREAM_DTBCLK_P5,90	DP_STREAM_REFCLK = 0xFF,	// Arbitrary value to pass refclk selection in software91};92 93enum hdmi_char_clk {94	HDMI_CHAR_PHYAD18CLK = 0,	// Selects functional for hdmi_char_clk as UNIPHYA PHYD18CLK95	HDMI_CHAR_PHYBD18CLK,96	HDMI_CHAR_PHYCD18CLK,97	HDMI_CHAR_PHYDD18CLK,98	HDMI_CHAR_PHYED18CLK,99	HDMI_CHAR_REFCLK = 0xFF,	// Arbitrary value to pass refclk selection in software100};101 102enum hdmi_stream_clk_source {103	HDMI_STREAM_DTBCLK_P0 = 0,	// Selects functional for HDMI_STREAM_CLK as DTBCLK_P#104	HDMI_STREAM_DTBCLK_P1,105	HDMI_STREAM_DTBCLK_P2,106	HDMI_STREAM_DTBCLK_P3,107	HDMI_STREAM_DTBCLK_P4,108	HDMI_STREAM_DTBCLK_P5,109	HDMI_STREAM_REFCLK = 0xFF,	// Arbitrary value to pass refclk selection in software110};111 112enum symclk32_se_clk_source {113	SYMCLK32_SE_PHYAD32CLK = 0,	// Selects functional for SYMCLK32 as UNIPHYA PHYD32CLK114	SYMCLK32_SE_PHYBD32CLK,115	SYMCLK32_SE_PHYCD32CLK,116	SYMCLK32_SE_PHYDD32CLK,117	SYMCLK32_SE_PHYED32CLK,118	SYMCLK32_SE_REFCLK = 0xFF,	// Arbitrary value to pass refclk selection in software119};120 121enum symclk32_le_clk_source {122	SYMCLK32_LE_PHYAD32CLK = 0,	// Selects functional for SYMCLK32 as UNIPHYA PHYD32CLK123	SYMCLK32_LE_PHYBD32CLK,124	SYMCLK32_LE_PHYCD32CLK,125	SYMCLK32_LE_PHYDD32CLK,126	SYMCLK32_LE_PHYED32CLK,127	SYMCLK32_LE_REFCLK = 0xFF,	// Arbitrary value to pass refclk selection in software128};129 130enum dsc_clk_source {131	DSC_CLK_REF_CLK = 0,			// Ref clock selected for DSC_CLK132	DSC_DTO_TUNED_CK_GPU_DISCLK_3,	// DTO divided clock selected as functional clock133};134 135 136static void dccg35_set_dsc_clk_rcg(struct dccg *dccg, int inst, bool enable)137{138	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);139 140	if (!dccg->ctx->dc->debug.root_clock_optimization.bits.dsc && enable)141		return;142 143	switch (inst) {144	case 0:145		REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DSCCLK0_ROOT_GATE_DISABLE, enable ? 0 : 1);146		break;147	case 1:148		REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DSCCLK1_ROOT_GATE_DISABLE, enable ? 0 : 1);149		break;150	case 2:151		REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DSCCLK2_ROOT_GATE_DISABLE, enable ? 0 : 1);152		break;153	case 3:154		REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DSCCLK3_ROOT_GATE_DISABLE, enable ? 0 : 1);155		break;156	default:157		BREAK_TO_DEBUGGER();158		return;159	}160}161 162static void dccg35_set_symclk32_se_rcg(163	struct dccg *dccg,164	int inst,165	bool enable)166{167	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);168 169	if (!dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se && enable)170		return;171 172	/* SYMCLK32_ROOT_SE#_GATE_DISABLE will clock gate in DCCG */173	/* SYMCLK32_SE#_GATE_DISABLE will clock gate in HPO only */174	switch (inst) {175	case 0:176		REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,177				   SYMCLK32_SE0_GATE_DISABLE, enable ? 0 : 1,178				   SYMCLK32_ROOT_SE0_GATE_DISABLE, enable ? 0 : 1);179		break;180	case 1:181		REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,182				   SYMCLK32_SE1_GATE_DISABLE, enable ? 0 : 1,183				   SYMCLK32_ROOT_SE1_GATE_DISABLE, enable ? 0 : 1);184		break;185	case 2:186		REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,187				   SYMCLK32_SE2_GATE_DISABLE, enable ? 0 : 1,188				   SYMCLK32_ROOT_SE2_GATE_DISABLE, enable ? 0 : 1);189		break;190	case 3:191		REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,192				   SYMCLK32_SE3_GATE_DISABLE, enable ? 0 : 1,193				   SYMCLK32_ROOT_SE3_GATE_DISABLE, enable ? 0 : 1);194		break;195	default:196		BREAK_TO_DEBUGGER();197		return;198	}199}200 201static void dccg35_set_symclk32_le_rcg(202	struct dccg *dccg,203	int inst,204	bool enable)205{206	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);207 208	if (!dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le && enable)209		return;210 211	switch (inst) {212	case 0:213		REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,214				   SYMCLK32_LE0_GATE_DISABLE, enable ? 0 : 1,215				   SYMCLK32_ROOT_LE0_GATE_DISABLE, enable ? 0 : 1);216		break;217	case 1:218		REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,219				   SYMCLK32_LE1_GATE_DISABLE, enable ? 0 : 1,220				   SYMCLK32_ROOT_LE1_GATE_DISABLE, enable ? 0 : 1);221		break;222	default:223		BREAK_TO_DEBUGGER();224		return;225	}226}227 228static void dccg35_set_physymclk_rcg(229	struct dccg *dccg,230	int inst,231	bool enable)232{233	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);234 235	if (!dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk && enable)236		return;237 238	switch (inst) {239	case 0:240		REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,241				PHYASYMCLK_ROOT_GATE_DISABLE, enable ? 0 : 1);242		break;243	case 1:244		REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,245				PHYBSYMCLK_ROOT_GATE_DISABLE, enable ? 0 : 1);246		break;247	case 2:248		REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,249				PHYCSYMCLK_ROOT_GATE_DISABLE, enable ? 0 : 1);250		break;251	case 3:252		REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,253				PHYDSYMCLK_ROOT_GATE_DISABLE, enable ? 0 : 1);254		break;255	case 4:256		REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,257				PHYESYMCLK_ROOT_GATE_DISABLE, enable ? 0 : 1);258		break;259	default:260		BREAK_TO_DEBUGGER();261		return;262	}263}264 265static void dccg35_set_symclk_fe_rcg(266	struct dccg *dccg,267	int inst,268	bool enable)269{270	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);271 272	if (!dccg->ctx->dc->debug.root_clock_optimization.bits.symclk_fe && enable)273		return;274 275	switch (inst) {276	case 0:277		REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,278				   SYMCLKA_FE_GATE_DISABLE, enable ? 0 : 1);279		REG_UPDATE(DCCG_GATE_DISABLE_CNTL5,280				   SYMCLKA_FE_ROOT_GATE_DISABLE, enable ? 0 : 1);281		break;282	case 1:283		REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,284				   SYMCLKB_FE_GATE_DISABLE, enable ? 0 : 1);285		REG_UPDATE(DCCG_GATE_DISABLE_CNTL5,286				   SYMCLKB_FE_ROOT_GATE_DISABLE, enable ? 0 : 1);287		break;288	case 2:289		REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,290				   SYMCLKC_FE_GATE_DISABLE, enable ? 0 : 1);291		REG_UPDATE(DCCG_GATE_DISABLE_CNTL5,292				   SYMCLKC_FE_ROOT_GATE_DISABLE, enable ? 0 : 1);293		break;294	case 3:295		REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,296				   SYMCLKD_FE_GATE_DISABLE, enable ? 0 : 1);297		REG_UPDATE(DCCG_GATE_DISABLE_CNTL5,298				   SYMCLKD_FE_ROOT_GATE_DISABLE, enable ? 0 : 1);299		break;300	case 4:301		REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,302				   SYMCLKE_FE_GATE_DISABLE, enable ? 0 : 1);303		REG_UPDATE(DCCG_GATE_DISABLE_CNTL5,304				   SYMCLKE_FE_ROOT_GATE_DISABLE, enable ? 0 : 1);305		break;306	default:307		BREAK_TO_DEBUGGER();308		return;309	}310}311 312static void dccg35_set_symclk_be_rcg(313	struct dccg *dccg,314	int inst,315	bool enable)316{317 318	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);319 320	/* TBD add symclk_be in rcg control bits */321	if (!dccg->ctx->dc->debug.root_clock_optimization.bits.symclk_fe && enable)322		return;323 324	switch (inst) {325	case 0:326		REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,327				   SYMCLKA_GATE_DISABLE, enable ? 0 : 1);328		REG_UPDATE(DCCG_GATE_DISABLE_CNTL5,329				   SYMCLKA_ROOT_GATE_DISABLE, enable ? 0 : 1);330		break;331	case 1:332		REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,333				   SYMCLKB_GATE_DISABLE, enable ? 0 : 1);334		REG_UPDATE(DCCG_GATE_DISABLE_CNTL5,335				   SYMCLKB_ROOT_GATE_DISABLE, enable ? 0 : 1);336		break;337	case 2:338		REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,339				   SYMCLKC_GATE_DISABLE, enable ? 0 : 1);340		REG_UPDATE(DCCG_GATE_DISABLE_CNTL5,341				   SYMCLKC_ROOT_GATE_DISABLE, enable ? 0 : 1);342		break;343	case 3:344		REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,345				   SYMCLKD_GATE_DISABLE, enable ? 0 : 1);346		REG_UPDATE(DCCG_GATE_DISABLE_CNTL5,347				   SYMCLKD_ROOT_GATE_DISABLE, enable ? 0 : 1);348		break;349	case 4:350		REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,351				   SYMCLKE_GATE_DISABLE, enable ? 0 : 1);352		REG_UPDATE(DCCG_GATE_DISABLE_CNTL5,353				   SYMCLKE_ROOT_GATE_DISABLE, enable ? 0 : 1);354		break;355	default:356		BREAK_TO_DEBUGGER();357		return;358	}359}360 361static void dccg35_set_dtbclk_p_rcg(struct dccg *dccg, int inst, bool enable)362{363 364	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);365 366	if (!dccg->ctx->dc->debug.root_clock_optimization.bits.dpp && enable)367		return;368 369	switch (inst) {370	case 0:371		REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, DTBCLK_P0_GATE_DISABLE, enable ? 0 : 1);372		break;373	case 1:374		REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, DTBCLK_P1_GATE_DISABLE, enable ? 0 : 1);375		break;376	case 2:377		REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, DTBCLK_P2_GATE_DISABLE, enable ? 0 : 1);378		break;379	case 3:380		REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, DTBCLK_P3_GATE_DISABLE, enable ? 0 : 1);381		break;382	default:383		BREAK_TO_DEBUGGER();384		break;385	}386}387 388static void dccg35_set_dppclk_rcg(struct dccg *dccg,389												int inst, bool enable)390{391 392	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);393 394	if (!dccg->ctx->dc->debug.root_clock_optimization.bits.dpp && enable)395		return;396 397	switch (inst) {398	case 0:399		REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DPPCLK0_ROOT_GATE_DISABLE, enable ? 0 : 1);400		break;401	case 1:402		REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DPPCLK1_ROOT_GATE_DISABLE, enable ? 0 : 1);403		break;404	case 2:405		REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DPPCLK2_ROOT_GATE_DISABLE, enable ? 0 : 1);406		break;407	case 3:408		REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DPPCLK3_ROOT_GATE_DISABLE, enable ? 0 : 1);409		break;410	default:411	BREAK_TO_DEBUGGER();412		break;413	}414}415 416static void dccg35_set_dpstreamclk_rcg(417	struct dccg *dccg,418	int inst,419	bool enable)420{421	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);422 423	if (!dccg->ctx->dc->debug.root_clock_optimization.bits.dpstream && enable)424		return;425 426	switch (inst) {427	case 0:428		REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL5,429					 DPSTREAMCLK0_GATE_DISABLE, enable ? 0 : 1,430					 DPSTREAMCLK0_ROOT_GATE_DISABLE, enable ? 0 : 1);431		break;432	case 1:433		REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL5,434					 DPSTREAMCLK1_GATE_DISABLE, enable ? 0 : 1,435					 DPSTREAMCLK1_ROOT_GATE_DISABLE, enable ? 0 : 1);436		break;437	case 2:438		REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL5,439				   DPSTREAMCLK2_GATE_DISABLE, enable ? 0 : 1,440				   DPSTREAMCLK2_ROOT_GATE_DISABLE, enable ? 0 : 1);441		break;442	case 3:443		REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL5,444				   DPSTREAMCLK3_GATE_DISABLE, enable ? 0 : 1,445				   DPSTREAMCLK3_ROOT_GATE_DISABLE, enable ? 0 : 1);446		break;447	default:448		BREAK_TO_DEBUGGER();449		return;450	}451}452 453static void dccg35_set_smclk32_se_rcg(454		struct dccg *dccg,455		int inst,456		bool enable)457{458	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);459 460	if (!dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se && enable)461		return;462 463	switch (inst) {464	case 0:465		REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,466					 SYMCLK32_SE0_GATE_DISABLE, enable ? 0 : 1,467					 SYMCLK32_ROOT_SE0_GATE_DISABLE, enable ? 0 : 1);468		break;469	case 1:470		REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,471					 SYMCLK32_SE1_GATE_DISABLE, enable ? 0 : 1,472					 SYMCLK32_ROOT_SE1_GATE_DISABLE, enable ? 0 : 1);473		break;474	case 2:475		REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,476					 SYMCLK32_SE2_GATE_DISABLE, enable ? 0 : 1,477					 SYMCLK32_ROOT_SE2_GATE_DISABLE, enable ? 0 : 1);478		break;479	case 3:480		REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,481					 SYMCLK32_SE3_GATE_DISABLE, enable ? 0 : 1,482					 SYMCLK32_ROOT_SE3_GATE_DISABLE, enable ? 0 : 1);483		break;484	default:485		BREAK_TO_DEBUGGER();486		return;487	}488}489 490static void dccg35_set_dsc_clk_src_new(struct dccg *dccg, int inst, enum dsc_clk_source src)491{492	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);493 494	/* DSCCLK#_EN=0 switches to refclock from functional clock */495 496	switch (inst) {497	case 0:498		REG_UPDATE(DSCCLK_DTO_CTRL, DSCCLK0_EN, src);499		break;500	case 1:501		REG_UPDATE(DSCCLK_DTO_CTRL, DSCCLK1_EN, src);502		break;503	case 2:504		REG_UPDATE(DSCCLK_DTO_CTRL, DSCCLK2_EN, src);505		break;506	case 3:507		REG_UPDATE(DSCCLK_DTO_CTRL, DSCCLK3_EN, src);508		break;509	default:510		BREAK_TO_DEBUGGER();511		return;512	}513}514 515static void dccg35_set_symclk32_se_src_new(516	struct dccg *dccg,517	int inst,518	enum symclk32_se_clk_source src519	)520{521	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);522 523	switch (inst) {524	case 0:525		REG_UPDATE_2(SYMCLK32_SE_CNTL,526					 SYMCLK32_SE0_SRC_SEL, (src == SYMCLK32_SE_REFCLK) ? 0 : src,527					 SYMCLK32_SE0_EN,  (src == SYMCLK32_SE_REFCLK) ? 0 : 1);528		break;529	case 1:530		REG_UPDATE_2(SYMCLK32_SE_CNTL,531					 SYMCLK32_SE1_SRC_SEL, (src == SYMCLK32_SE_REFCLK) ? 0 : src,532					 SYMCLK32_SE1_EN, (src == SYMCLK32_SE_REFCLK) ? 0 : 1);533		break;534	case 2:535		REG_UPDATE_2(SYMCLK32_SE_CNTL,536					 SYMCLK32_SE2_SRC_SEL, (src == SYMCLK32_SE_REFCLK) ? 0 : src,537					 SYMCLK32_SE2_EN, (src == SYMCLK32_SE_REFCLK) ? 0 : 1);538		break;539	case 3:540		REG_UPDATE_2(SYMCLK32_SE_CNTL,541					 SYMCLK32_SE3_SRC_SEL, (src == SYMCLK32_SE_REFCLK) ? 0 : src,542					 SYMCLK32_SE3_EN, (src == SYMCLK32_SE_REFCLK) ? 0 : 1);543		break;544	default:545		BREAK_TO_DEBUGGER();546		return;547	}548}549 550static int551dccg35_is_symclk32_se_src_functional_le_new(struct dccg *dccg, int symclk_32_se_inst, int symclk_32_le_inst)552{553	uint32_t en;554	uint32_t src_sel;555 556	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);557 558	REG_GET_2(SYMCLK32_SE_CNTL, SYMCLK32_SE3_SRC_SEL, &src_sel, SYMCLK32_SE3_EN, &en);559 560	if (en == 1 && src_sel == symclk_32_le_inst)561		return 1;562 563	return 0;564}565 566 567static void dccg35_set_symclk32_le_src_new(568	struct dccg *dccg,569	int inst,570	enum symclk32_le_clk_source src)571{572	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);573 574	switch (inst) {575	case 0:576		REG_UPDATE_2(SYMCLK32_LE_CNTL,577					 SYMCLK32_LE0_SRC_SEL, (src == SYMCLK32_LE_REFCLK) ? 0 : src,578					 SYMCLK32_LE0_EN, (src == SYMCLK32_LE_REFCLK) ? 0 : 1);579		break;580	case 1:581		REG_UPDATE_2(SYMCLK32_LE_CNTL,582					 SYMCLK32_LE1_SRC_SEL, (src == SYMCLK32_LE_REFCLK) ? 0 : src,583					 SYMCLK32_LE1_EN, (src == SYMCLK32_LE_REFCLK) ? 0 : 1);584		break;585	default:586		BREAK_TO_DEBUGGER();587		return;588	}589}590 591static void dcn35_set_dppclk_src_new(struct dccg *dccg,592				 int inst, enum dppclk_clock_source src)593{594	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);595 596	switch (inst) {597	case 0:598		REG_UPDATE(DPPCLK_CTRL, DPPCLK0_EN, src);599		break;600	case 1:601		REG_UPDATE(DPPCLK_CTRL, DPPCLK1_EN, src);602		break;603	case 2:604		REG_UPDATE(DPPCLK_CTRL, DPPCLK2_EN, src);605		break;606	case 3:607		REG_UPDATE(DPPCLK_CTRL, DPPCLK3_EN, src);608		break;609	default:610	BREAK_TO_DEBUGGER();611		break;612	}613}614 615static void dccg35_set_dtbclk_p_src_new(616	struct dccg *dccg,617	enum dtbclk_source src,618	int inst)619{620	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);621 622	/* If DTBCLK_P#_EN is 0 refclock is selected as functional clock623	 * If DTBCLK_P#_EN is 1 functional clock is selected as DTBCLK_P#_SRC_SEL624	 */625 626	switch (inst) {627	case 0:628		REG_UPDATE_2(DTBCLK_P_CNTL,629					 DTBCLK_P0_SRC_SEL, (src == DTBCLK_REFCLK) ? 0 : src,630					 DTBCLK_P0_EN, (src == DTBCLK_REFCLK) ? 0 : 1);631		break;632	case 1:633		REG_UPDATE_2(DTBCLK_P_CNTL,634					 DTBCLK_P1_SRC_SEL, (src == DTBCLK_REFCLK) ? 0 : src,635					 DTBCLK_P1_EN, (src == DTBCLK_REFCLK) ? 0 : 1);636		break;637	case 2:638		REG_UPDATE_2(DTBCLK_P_CNTL,639					 DTBCLK_P2_SRC_SEL, (src == DTBCLK_REFCLK) ? 0 : src,640					 DTBCLK_P2_EN, (src == DTBCLK_REFCLK) ? 0 : 1);641		break;642	case 3:643		REG_UPDATE_2(DTBCLK_P_CNTL,644					 DTBCLK_P3_SRC_SEL, (src == DTBCLK_REFCLK) ? 0 : src,645					 DTBCLK_P3_EN, (src == DTBCLK_REFCLK) ? 0 : 1);646		break;647	default:648		BREAK_TO_DEBUGGER();649		return;650	}651}652 653static void dccg35_set_dpstreamclk_src_new(654	struct dccg *dccg,655	enum dp_stream_clk_source src,656	int inst)657{658	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);659 660	switch (inst) {661	case 0:662		REG_UPDATE_2(DPSTREAMCLK_CNTL, DPSTREAMCLK0_EN,663					 (src == DP_STREAM_REFCLK) ? 0 : 1,664					 DPSTREAMCLK0_SRC_SEL,665					 (src == DP_STREAM_REFCLK) ? 0 : src);666		break;667	case 1:668		REG_UPDATE_2(DPSTREAMCLK_CNTL, DPSTREAMCLK1_EN,669					 (src == DP_STREAM_REFCLK) ? 0 : 1,670					 DPSTREAMCLK1_SRC_SEL,671					 (src == DP_STREAM_REFCLK) ? 0 : src);672 673		break;674	case 2:675		REG_UPDATE_2(DPSTREAMCLK_CNTL, DPSTREAMCLK2_EN,676					 (src == DP_STREAM_REFCLK) ? 0 : 1,677					 DPSTREAMCLK2_SRC_SEL,678					 (src == DP_STREAM_REFCLK) ? 0 : src);679 680		break;681	case 3:682		REG_UPDATE_2(DPSTREAMCLK_CNTL, DPSTREAMCLK3_EN,683					 (src == DP_STREAM_REFCLK) ? 0 : 1,684					 DPSTREAMCLK3_SRC_SEL,685					 (src == DP_STREAM_REFCLK) ? 0 : src);686		break;687	default:688		BREAK_TO_DEBUGGER();689		return;690	}691}692 693static void dccg35_set_physymclk_src_new(694	struct dccg *dccg,695	enum physymclk_source src,696	int inst)697{698	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);699 700	switch (inst) {701	case 0:702		REG_UPDATE_2(PHYASYMCLK_CLOCK_CNTL, PHYASYMCLK_EN,703					 (src == PHYSYMCLK_REFCLK) ? 0 : 1,704					 PHYASYMCLK_SRC_SEL,705					 (src == PHYSYMCLK_REFCLK) ? 0 : src);706		break;707	case 1:708		REG_UPDATE_2(PHYBSYMCLK_CLOCK_CNTL, PHYBSYMCLK_EN,709					 (src == PHYSYMCLK_REFCLK) ? 0 : 1,710					 PHYBSYMCLK_SRC_SEL,711					 (src == PHYSYMCLK_REFCLK) ? 0 : src);712		break;713	case 2:714		REG_UPDATE_2(PHYCSYMCLK_CLOCK_CNTL, PHYCSYMCLK_EN,715					 (src == PHYSYMCLK_REFCLK) ? 0 : 1,716					 PHYCSYMCLK_SRC_SEL,717					 (src == PHYSYMCLK_REFCLK) ? 0 : src);718		break;719	case 3:720		REG_UPDATE_2(PHYDSYMCLK_CLOCK_CNTL, PHYDSYMCLK_EN,721					 (src == PHYSYMCLK_REFCLK) ? 0 : 1,722					 PHYDSYMCLK_SRC_SEL,723					 (src == PHYSYMCLK_REFCLK) ? 0 : src);724		break;725	case 4:726		REG_UPDATE_2(PHYESYMCLK_CLOCK_CNTL, PHYESYMCLK_EN,727					 (src == PHYSYMCLK_REFCLK) ? 0 : 1,728					 PHYESYMCLK_SRC_SEL,729					 (src == PHYSYMCLK_REFCLK) ? 0 : src);730		break;731	default:732		BREAK_TO_DEBUGGER();733		return;734	}735}736 737static void dccg35_set_symclk_be_src_new(738	struct dccg *dccg,739	enum symclk_be_source src,740	int inst)741{742	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);743 744	switch (inst) {745	case 0:746		REG_UPDATE_2(SYMCLKA_CLOCK_ENABLE,747					 SYMCLKA_CLOCK_ENABLE, (src == SYMCLK_BE_REFCLK) ? 0 : 1,748					 SYMCLKA_SRC_SEL, (src == SYMCLK_BE_REFCLK) ? 0 : src);749		break;750	case 1:751		REG_UPDATE_2(SYMCLKB_CLOCK_ENABLE,752					 SYMCLKB_CLOCK_ENABLE, (src == SYMCLK_BE_REFCLK) ? 0 : 1,753					 SYMCLKB_SRC_SEL, (src == SYMCLK_BE_REFCLK) ? 0 : src);754		break;755	case 2:756		REG_UPDATE_2(SYMCLKC_CLOCK_ENABLE,757					 SYMCLKC_CLOCK_ENABLE, (src == SYMCLK_BE_REFCLK) ? 0 : 1,758					 SYMCLKC_SRC_SEL, (src == SYMCLK_BE_REFCLK) ? 0 : src);759		break;760	case 3:761		REG_UPDATE_2(SYMCLKD_CLOCK_ENABLE,762					 SYMCLKD_CLOCK_ENABLE, (src == SYMCLK_BE_REFCLK) ? 0 : 1,763					 SYMCLKD_SRC_SEL, (src == SYMCLK_BE_REFCLK) ? 0 : src);764		break;765	case 4:766		REG_UPDATE_2(SYMCLKE_CLOCK_ENABLE,767					 SYMCLKE_CLOCK_ENABLE, (src == SYMCLK_BE_REFCLK) ? 0 : 1,768					 SYMCLKE_SRC_SEL, (src == SYMCLK_BE_REFCLK) ? 0 : src);769		break;770	}771}772 773static int dccg35_is_symclk_fe_src_functional_be(struct dccg *dccg,774												 int symclk_fe_inst,775												 int symclk_be_inst)776{777 778	uint32_t en = 0;779	uint32_t src_sel = 0;780 781	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);782 783	switch (symclk_fe_inst) {784	case 0:785		REG_GET_2(SYMCLKA_CLOCK_ENABLE, SYMCLKA_FE_SRC_SEL, &src_sel, SYMCLKA_FE_EN, &en);786		break;787	case 1:788		REG_GET_2(SYMCLKB_CLOCK_ENABLE, SYMCLKB_FE_SRC_SEL, &src_sel, SYMCLKB_FE_EN, &en);789		break;790	case 2:791		REG_GET_2(SYMCLKC_CLOCK_ENABLE, SYMCLKC_FE_SRC_SEL, &src_sel, SYMCLKC_FE_EN, &en);792		break;793	case 3:794		REG_GET_2(SYMCLKD_CLOCK_ENABLE, SYMCLKD_FE_SRC_SEL, &src_sel, SYMCLKD_FE_EN, &en);795		break;796	case 4:797		REG_GET_2(SYMCLKE_CLOCK_ENABLE, SYMCLKE_FE_SRC_SEL, &src_sel, SYMCLKE_FE_EN, &en);798		break;799	}800 801	if (en == 1 && src_sel == symclk_be_inst)802		return 1;803 804	return 0;805}806 807static void dccg35_set_symclk_fe_src_new(struct dccg *dccg, enum symclk_fe_source src, int inst)808{809	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);810 811	switch (inst) {812	case 0:813		REG_UPDATE_2(SYMCLKA_CLOCK_ENABLE,814					 SYMCLKA_FE_EN, (src == SYMCLK_FE_REFCLK) ? 0 : 1,815					 SYMCLKA_FE_SRC_SEL, (src == SYMCLK_FE_REFCLK) ? 0 : src);816		break;817	case 1:818		REG_UPDATE_2(SYMCLKB_CLOCK_ENABLE,819					 SYMCLKB_FE_EN, (src == SYMCLK_FE_REFCLK) ? 0 : 1,820					 SYMCLKB_FE_SRC_SEL, (src == SYMCLK_FE_REFCLK) ? 0 : src);821		break;822	case 2:823		REG_UPDATE_2(SYMCLKC_CLOCK_ENABLE,824					 SYMCLKC_FE_EN, (src == SYMCLK_FE_REFCLK) ? 0 : 1,825					 SYMCLKC_FE_SRC_SEL, (src == SYMCLK_FE_REFCLK) ? 0 : src);826		break;827	case 3:828		REG_UPDATE_2(SYMCLKD_CLOCK_ENABLE,829					 SYMCLKD_FE_EN, (src == SYMCLK_FE_REFCLK) ? 0 : 1,830					 SYMCLKD_FE_SRC_SEL, (src == SYMCLK_FE_REFCLK) ? 0 : src);831		break;832	case 4:833		REG_UPDATE_2(SYMCLKE_CLOCK_ENABLE,834					 SYMCLKE_FE_EN, (src == SYMCLK_FE_REFCLK) ? 0 : 1,835					 SYMCLKE_FE_SRC_SEL, (src == SYMCLK_FE_REFCLK) ? 0 : src);836		break;837	}838}839 840static uint32_t dccg35_is_fe_rcg(struct dccg *dccg, int inst)841{842	uint32_t enable = 0;843	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);844 845	switch (inst) {846	case 0:847		REG_GET(DCCG_GATE_DISABLE_CNTL5,848				SYMCLKA_FE_ROOT_GATE_DISABLE, &enable);849		break;850	case 1:851		REG_GET(DCCG_GATE_DISABLE_CNTL5,852				SYMCLKB_FE_ROOT_GATE_DISABLE, &enable);853		break;854	case 2:855		REG_GET(DCCG_GATE_DISABLE_CNTL5,856				SYMCLKC_FE_ROOT_GATE_DISABLE, &enable);857		break;858	case 3:859		REG_GET(DCCG_GATE_DISABLE_CNTL5,860				SYMCLKD_FE_ROOT_GATE_DISABLE, &enable);861		break;862	case 4:863		REG_GET(DCCG_GATE_DISABLE_CNTL5,864				SYMCLKE_FE_ROOT_GATE_DISABLE, &enable);865		break;866	default:867		BREAK_TO_DEBUGGER();868		break;869	}870	return enable;871}872 873static uint32_t dccg35_is_symclk32_se_rcg(struct dccg *dccg, int inst)874{875	uint32_t disable_l1 = 0;876	uint32_t disable_l2 = 0;877	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);878 879	switch (inst) {880	case 0:881		REG_GET_2(DCCG_GATE_DISABLE_CNTL3,882				  SYMCLK32_SE0_GATE_DISABLE, &disable_l1,883				  SYMCLK32_ROOT_SE0_GATE_DISABLE, &disable_l2);884		break;885	case 1:886		REG_GET_2(DCCG_GATE_DISABLE_CNTL3,887				  SYMCLK32_SE1_GATE_DISABLE, &disable_l1,888				  SYMCLK32_ROOT_SE1_GATE_DISABLE, &disable_l2);889		break;890	case 2:891		REG_GET_2(DCCG_GATE_DISABLE_CNTL3,892				  SYMCLK32_SE2_GATE_DISABLE, &disable_l1,893				  SYMCLK32_ROOT_SE2_GATE_DISABLE, &disable_l2);894		break;895	case 3:896		REG_GET_2(DCCG_GATE_DISABLE_CNTL3,897				  SYMCLK32_SE3_GATE_DISABLE, &disable_l1,898				  SYMCLK32_ROOT_SE3_GATE_DISABLE, &disable_l2);899		break;900	default:901		BREAK_TO_DEBUGGER();902		return 0;903	}904 905	/* return true if either block level or DCCG level gating is active */906	return (disable_l1 | disable_l2);907}908 909static void dccg35_enable_symclk_fe_new(910	struct dccg *dccg,911	int inst,912	enum symclk_fe_source src)913{914	dccg35_set_symclk_fe_rcg(dccg, inst, false);915	dccg35_set_symclk_fe_src_new(dccg, src, inst);916}917 918static void dccg35_disable_symclk_fe_new(919	struct dccg *dccg,920	int inst)921{922	dccg35_set_symclk_fe_src_new(dccg, SYMCLK_FE_REFCLK, inst);923	dccg35_set_symclk_fe_rcg(dccg, inst, true);924}925 926static void dccg35_enable_symclk_be_new(927	struct dccg *dccg,928	int inst,929	enum symclk_be_source src)930{931	dccg35_set_symclk_be_rcg(dccg, inst, false);932	dccg35_set_symclk_be_src_new(dccg, inst, src);933}934 935static void dccg35_disable_symclk_be_new(936	struct dccg *dccg,937	int inst)938{939	int i;940 941	/* Switch from functional clock to refclock */942	dccg35_set_symclk_be_src_new(dccg, inst, SYMCLK_BE_REFCLK);943 944	/* Check if any other SE connected LE and disable them */945	for (i = 0; i < 4; i++) {946		/* Make sure FE is not already in RCG */947		if (dccg35_is_fe_rcg(dccg, i) == 0) {948			if (dccg35_is_symclk_fe_src_functional_be(dccg, i, inst))949				dccg35_disable_symclk_fe_new(dccg, i);950		}951	}952	/* Safe to RCG SYMCLK*/953	dccg35_set_symclk_be_rcg(dccg, inst, true);954}955 956static void dccg35_enable_symclk32_se_new(957	struct dccg *dccg,958	int inst,959	enum symclk32_se_clk_source src)960{961	dccg35_set_symclk32_se_rcg(dccg, inst, false);962	dccg35_set_symclk32_se_src_new(dccg, inst, src);963}964 965static void dccg35_disable_symclk32_se_new(966	struct dccg *dccg,967	int inst)968{969	dccg35_set_symclk32_se_src_new(dccg, SYMCLK32_SE_REFCLK, inst);970	dccg35_set_symclk32_se_rcg(dccg, inst, true);971}972 973static void dccg35_enable_symclk32_le_new(974	struct dccg *dccg,975	int inst,976	enum symclk32_le_clk_source src)977{978	dccg35_set_symclk32_le_rcg(dccg, inst, false);979	dccg35_set_symclk32_le_src_new(dccg, inst, src);980}981 982static void dccg35_disable_symclk32_le_new(983	struct dccg *dccg,984	int inst)985{986	int i;987 988	/* Switch from functional clock to refclock */989	dccg35_set_symclk32_le_src_new(dccg, inst, SYMCLK32_LE_REFCLK);990 991	/* Check if any SE are connected and disable SE as well */992	for (i = 0; i < 4; i++) {993		/* Make sure FE is not already in RCG */994		if (dccg35_is_symclk32_se_rcg(dccg, i) == 0) {995			/* Disable and SE connected to this LE before RCG */996			if (dccg35_is_symclk32_se_src_functional_le_new(dccg, i, inst))997				dccg35_disable_symclk32_se_new(dccg, i);998		}999	}1000	/* Safe to RCG SYM32_LE*/1001	dccg35_set_symclk32_le_rcg(dccg, inst, true);1002}1003 1004static void dccg35_enable_physymclk_new(struct dccg *dccg,1005					int inst,1006					enum physymclk_source src)1007{1008	dccg35_set_physymclk_rcg(dccg, inst, false);1009	dccg35_set_physymclk_src_new(dccg, src, inst);1010}1011 1012static void dccg35_disable_physymclk_new(struct dccg *dccg,1013										 int inst)1014{1015	dccg35_set_physymclk_src_new(dccg, PHYSYMCLK_REFCLK, inst);1016	dccg35_set_physymclk_rcg(dccg, inst, true);1017}1018 1019static void dccg35_enable_dpp_clk_new(1020	struct dccg *dccg,1021	int inst,1022	enum dppclk_clock_source src)1023{1024	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);1025	/* Sanitize inst before use in array de-ref */1026	if (inst < 0) {1027		BREAK_TO_DEBUGGER();1028		return;1029	}1030	dccg35_set_dppclk_rcg(dccg, inst, false);1031	dcn35_set_dppclk_src_new(dccg, inst, src);1032	/* Switch DPP clock to DTO */1033	REG_SET_2(DPPCLK_DTO_PARAM[inst], 0,1034			  DPPCLK0_DTO_PHASE, 0xFF,1035			  DPPCLK0_DTO_MODULO, 0xFF);1036}1037 1038static void dccg35_disable_dpp_clk_new(1039	struct dccg *dccg,1040	int inst)1041{1042	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);1043	/* Sanitize inst before use in array de-ref */1044	if (inst < 0) {1045		BREAK_TO_DEBUGGER();1046		return;1047	}1048	dcn35_set_dppclk_src_new(dccg, inst, DPP_REFCLK);1049	REG_SET_2(DPPCLK_DTO_PARAM[inst], 0,1050			  DPPCLK0_DTO_PHASE, 0,1051			  DPPCLK0_DTO_MODULO, 1);1052	dccg35_set_dppclk_rcg(dccg, inst, true);1053}1054 1055static void dccg35_disable_dscclk_new(struct dccg *dccg,1056									  int inst)1057{1058	dccg35_set_dsc_clk_src_new(dccg, inst, DSC_CLK_REF_CLK);1059	dccg35_set_dsc_clk_rcg(dccg, inst, true);1060}1061 1062static void dccg35_enable_dscclk_new(struct dccg *dccg,1063									 int inst,1064									 enum dsc_clk_source src)1065{1066	dccg35_set_dsc_clk_rcg(dccg, inst, false);1067	dccg35_set_dsc_clk_src_new(dccg, inst, src);1068}1069 1070static void dccg35_enable_dtbclk_p_new(struct dccg *dccg,1071									   enum dtbclk_source src,1072									   int inst)1073{1074	dccg35_set_dtbclk_p_rcg(dccg, inst, false);1075	dccg35_set_dtbclk_p_src_new(dccg, src, inst);1076}1077 1078static void dccg35_disable_dtbclk_p_new(struct dccg *dccg,1079										int inst)1080{1081	dccg35_set_dtbclk_p_src_new(dccg, DTBCLK_REFCLK, inst);1082	dccg35_set_dtbclk_p_rcg(dccg, inst, true);1083}1084 1085static void dccg35_disable_dpstreamclk_new(struct dccg *dccg,1086										  int inst)1087{1088	dccg35_set_dpstreamclk_src_new(dccg, DP_STREAM_REFCLK, inst);1089	dccg35_set_dpstreamclk_rcg(dccg, inst, true);1090}1091 1092static void dccg35_enable_dpstreamclk_new(struct dccg *dccg,1093										   enum dp_stream_clk_source src,1094										   int inst)1095{1096	dccg35_set_dpstreamclk_rcg(dccg, inst, false);1097	dccg35_set_dpstreamclk_src_new(dccg, src, inst);1098}1099 1100static void dccg35_trigger_dio_fifo_resync(struct dccg *dccg)1101{1102	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);1103	uint32_t dispclk_rdivider_value = 0;1104 1105	REG_GET(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_RDIVIDER, &dispclk_rdivider_value);1106	if (dispclk_rdivider_value != 0)1107		REG_UPDATE(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_WDIVIDER, dispclk_rdivider_value);1108}1109 1110static void dcn35_set_dppclk_enable(struct dccg *dccg,1111				 uint32_t dpp_inst, uint32_t enable)1112{1113	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);1114 1115	switch (dpp_inst) {1116	case 0:1117		REG_UPDATE(DPPCLK_CTRL, DPPCLK0_EN, enable);1118		if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpp)1119			REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DPPCLK0_ROOT_GATE_DISABLE, enable);1120		break;1121	case 1:1122		REG_UPDATE(DPPCLK_CTRL, DPPCLK1_EN, enable);1123		if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpp)1124			REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DPPCLK1_ROOT_GATE_DISABLE, enable);1125		break;1126	case 2:1127		REG_UPDATE(DPPCLK_CTRL, DPPCLK2_EN, enable);1128		if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpp)1129			REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DPPCLK2_ROOT_GATE_DISABLE, enable);1130		break;1131	case 3:1132		REG_UPDATE(DPPCLK_CTRL, DPPCLK3_EN, enable);1133		if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpp)1134			REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DPPCLK3_ROOT_GATE_DISABLE, enable);1135		break;1136	default:1137		break;1138	}1139 1140}1141 1142static void dccg35_update_dpp_dto(struct dccg *dccg, int dpp_inst,1143				  int req_dppclk)1144{1145	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);1146 1147	if (dccg->dpp_clock_gated[dpp_inst]) {1148		/*1149		 * Do not update the DPPCLK DTO if the clock is stopped.1150		 */1151		return;1152	}1153 1154	if (dccg->ref_dppclk && req_dppclk) {1155		int ref_dppclk = dccg->ref_dppclk;1156		int modulo, phase;1157 1158		// phase / modulo = dpp pipe clk / dpp global clk1159		modulo = 0xff;   // use FF at the end1160		phase = ((modulo * req_dppclk) + ref_dppclk - 1) / ref_dppclk;1161 1162		if (phase > 0xff) {1163			ASSERT(false);1164			phase = 0xff;1165		}1166 1167		REG_SET_2(DPPCLK_DTO_PARAM[dpp_inst], 0,1168				DPPCLK0_DTO_PHASE, phase,1169				DPPCLK0_DTO_MODULO, modulo);1170 1171		dcn35_set_dppclk_enable(dccg, dpp_inst, true);1172	} else1173		dcn35_set_dppclk_enable(dccg, dpp_inst, false);1174	dccg->pipe_dppclk_khz[dpp_inst] = req_dppclk;1175}1176 1177static void dccg35_set_dppclk_root_clock_gating(struct dccg *dccg,1178		 uint32_t dpp_inst, uint32_t enable)1179{1180	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);1181 1182	if (!dccg->ctx->dc->debug.root_clock_optimization.bits.dpp)1183		return;1184 1185	switch (dpp_inst) {1186	case 0:1187		REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DPPCLK0_ROOT_GATE_DISABLE, enable);1188		break;1189	case 1:1190		REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DPPCLK1_ROOT_GATE_DISABLE, enable);1191		break;1192	case 2:1193		REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DPPCLK2_ROOT_GATE_DISABLE, enable);1194		break;1195	case 3:1196		REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DPPCLK3_ROOT_GATE_DISABLE, enable);1197		break;1198	default:1199		break;1200	}1201}1202 1203static void dccg35_get_pixel_rate_div(1204		struct dccg *dccg,1205		uint32_t otg_inst,1206		uint32_t *k1,1207		uint32_t *k2)1208{1209	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);1210	uint32_t val_k1 = PIXEL_RATE_DIV_NA, val_k2 = PIXEL_RATE_DIV_NA;1211 1212	*k1 = PIXEL_RATE_DIV_NA;1213	*k2 = PIXEL_RATE_DIV_NA;1214 1215	switch (otg_inst) {1216	case 0:1217		REG_GET_2(OTG_PIXEL_RATE_DIV,1218			OTG0_PIXEL_RATE_DIVK1, &val_k1,1219			OTG0_PIXEL_RATE_DIVK2, &val_k2);1220		break;1221	case 1:1222		REG_GET_2(OTG_PIXEL_RATE_DIV,1223			OTG1_PIXEL_RATE_DIVK1, &val_k1,1224			OTG1_PIXEL_RATE_DIVK2, &val_k2);1225		break;1226	case 2:1227		REG_GET_2(OTG_PIXEL_RATE_DIV,1228			OTG2_PIXEL_RATE_DIVK1, &val_k1,1229			OTG2_PIXEL_RATE_DIVK2, &val_k2);1230		break;1231	case 3:1232		REG_GET_2(OTG_PIXEL_RATE_DIV,1233			OTG3_PIXEL_RATE_DIVK1, &val_k1,1234			OTG3_PIXEL_RATE_DIVK2, &val_k2);1235		break;1236	default:1237		BREAK_TO_DEBUGGER();1238		return;1239	}1240 1241	*k1 = val_k1;1242	*k2 = val_k2;1243}1244 1245static void dccg35_set_pixel_rate_div(1246		struct dccg *dccg,1247		uint32_t otg_inst,1248		enum pixel_rate_div k1,1249		enum pixel_rate_div k2)1250{1251	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);1252	uint32_t cur_k1 = PIXEL_RATE_DIV_NA;1253	uint32_t cur_k2 = PIXEL_RATE_DIV_NA;1254 1255 1256	// Don't program 0xF into the register field. Not valid since1257	// K1 / K2 field is only 1 / 2 bits wide1258	if (k1 == PIXEL_RATE_DIV_NA || k2 == PIXEL_RATE_DIV_NA) {1259		BREAK_TO_DEBUGGER();1260		return;1261	}1262 1263	dccg35_get_pixel_rate_div(dccg, otg_inst, &cur_k1, &cur_k2);1264	if (k1 == cur_k1 && k2 == cur_k2)1265		return;1266 1267	switch (otg_inst) {1268	case 0:1269		REG_UPDATE_2(OTG_PIXEL_RATE_DIV,1270				OTG0_PIXEL_RATE_DIVK1, k1,1271				OTG0_PIXEL_RATE_DIVK2, k2);1272		break;1273	case 1:1274		REG_UPDATE_2(OTG_PIXEL_RATE_DIV,1275				OTG1_PIXEL_RATE_DIVK1, k1,1276				OTG1_PIXEL_RATE_DIVK2, k2);1277		break;1278	case 2:1279		REG_UPDATE_2(OTG_PIXEL_RATE_DIV,1280				OTG2_PIXEL_RATE_DIVK1, k1,1281				OTG2_PIXEL_RATE_DIVK2, k2);1282		break;1283	case 3:1284		REG_UPDATE_2(OTG_PIXEL_RATE_DIV,1285				OTG3_PIXEL_RATE_DIVK1, k1,1286				OTG3_PIXEL_RATE_DIVK2, k2);1287		break;1288	default:1289		BREAK_TO_DEBUGGER();1290		return;1291	}1292}1293 1294static void dccg35_set_dtbclk_p_src(1295		struct dccg *dccg,1296		enum streamclk_source src,1297		uint32_t otg_inst)1298{1299	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);1300 1301	uint32_t p_src_sel = 0; /* selects dprefclk */1302	if (src == DTBCLK0)1303		p_src_sel = 2;  /* selects dtbclk0 */1304 1305	switch (otg_inst) {1306	case 0:1307		if (src == REFCLK)1308			REG_UPDATE(DTBCLK_P_CNTL,1309					DTBCLK_P0_EN, 0);1310		else1311			REG_UPDATE_2(DTBCLK_P_CNTL,1312					DTBCLK_P0_SRC_SEL, p_src_sel,1313					DTBCLK_P0_EN, 1);1314		break;1315	case 1:1316		if (src == REFCLK)1317			REG_UPDATE(DTBCLK_P_CNTL,1318					DTBCLK_P1_EN, 0);1319		else1320			REG_UPDATE_2(DTBCLK_P_CNTL,1321					DTBCLK_P1_SRC_SEL, p_src_sel,1322					DTBCLK_P1_EN, 1);1323		break;1324	case 2:1325		if (src == REFCLK)1326			REG_UPDATE(DTBCLK_P_CNTL,1327					DTBCLK_P2_EN, 0);1328		else1329			REG_UPDATE_2(DTBCLK_P_CNTL,1330					DTBCLK_P2_SRC_SEL, p_src_sel,1331					DTBCLK_P2_EN, 1);1332		break;1333	case 3:1334		if (src == REFCLK)1335			REG_UPDATE(DTBCLK_P_CNTL,1336					DTBCLK_P3_EN, 0);1337		else1338			REG_UPDATE_2(DTBCLK_P_CNTL,1339					DTBCLK_P3_SRC_SEL, p_src_sel,1340					DTBCLK_P3_EN, 1);1341		break;1342	default:1343		BREAK_TO_DEBUGGER();1344		return;1345	}1346 1347}1348 1349/* Controls the generation of pixel valid for OTG in (OTG -> HPO case) */1350static void dccg35_set_dtbclk_dto(1351		struct dccg *dccg,1352		const struct dtbclk_dto_params *params)1353{1354	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);1355	/* DTO Output Rate / Pixel Rate = 1/4 */1356	int req_dtbclk_khz = params->pixclk_khz / 4;1357 1358	if (params->ref_dtbclk_khz && req_dtbclk_khz) {1359		uint32_t modulo, phase;1360 1361		switch (params->otg_inst) {1362		case 0:1363			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, DTBCLK_P0_GATE_DISABLE, 1);1364			break;1365		case 1:1366			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, DTBCLK_P1_GATE_DISABLE, 1);1367			break;1368		case 2:1369			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, DTBCLK_P2_GATE_DISABLE, 1);1370			break;1371		case 3:1372			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, DTBCLK_P3_GATE_DISABLE, 1);1373			break;1374		}1375 1376		// phase / modulo = dtbclk / dtbclk ref1377		modulo = params->ref_dtbclk_khz * 1000;1378		phase = req_dtbclk_khz * 1000;1379 1380		REG_WRITE(DTBCLK_DTO_MODULO[params->otg_inst], modulo);1381		REG_WRITE(DTBCLK_DTO_PHASE[params->otg_inst], phase);1382 1383		REG_UPDATE(OTG_PIXEL_RATE_CNTL[params->otg_inst],1384				DTBCLK_DTO_ENABLE[params->otg_inst], 1);1385 1386		REG_WAIT(OTG_PIXEL_RATE_CNTL[params->otg_inst],1387				DTBCLKDTO_ENABLE_STATUS[params->otg_inst], 1,1388				1, 100);1389 1390		/* program OTG_PIXEL_RATE_DIV for DIVK1 and DIVK2 fields */1391		dccg35_set_pixel_rate_div(dccg, params->otg_inst, PIXEL_RATE_DIV_BY_1, PIXEL_RATE_DIV_BY_1);1392 1393		/* The recommended programming sequence to enable DTBCLK DTO to generate1394		 * valid pixel HPO DPSTREAM ENCODER, specifies that DTO source select should1395		 * be set only after DTO is enabled1396		 */1397		REG_UPDATE(OTG_PIXEL_RATE_CNTL[params->otg_inst],1398				PIPE_DTO_SRC_SEL[params->otg_inst], 2);1399	} else {1400		switch (params->otg_inst) {1401		case 0:1402			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, DTBCLK_P0_GATE_DISABLE, 0);1403			break;1404		case 1:1405			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, DTBCLK_P1_GATE_DISABLE, 0);1406			break;1407		case 2:1408			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, DTBCLK_P2_GATE_DISABLE, 0);1409			break;1410		case 3:1411			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, DTBCLK_P3_GATE_DISABLE, 0);1412			break;1413		}1414 1415		REG_UPDATE_2(OTG_PIXEL_RATE_CNTL[params->otg_inst],1416				DTBCLK_DTO_ENABLE[params->otg_inst], 0,1417				PIPE_DTO_SRC_SEL[params->otg_inst], params->is_hdmi ? 0 : 1);1418 1419		REG_WRITE(DTBCLK_DTO_MODULO[params->otg_inst], 0);1420		REG_WRITE(DTBCLK_DTO_PHASE[params->otg_inst], 0);1421	}1422}1423 1424static void dccg35_set_dpstreamclk(1425		struct dccg *dccg,1426		enum streamclk_source src,1427		int otg_inst,1428		int dp_hpo_inst)1429{1430	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);1431 1432	/* set the dtbclk_p source */1433	dccg35_set_dtbclk_p_src(dccg, src, otg_inst);1434 1435	/* enabled to select one of the DTBCLKs for pipe */1436	switch (dp_hpo_inst) {1437	case 0:1438		REG_UPDATE_2(DPSTREAMCLK_CNTL, DPSTREAMCLK0_EN,1439				(src == REFCLK) ? 0 : 1, DPSTREAMCLK0_SRC_SEL, otg_inst);1440		if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpstream)1441			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, DPSTREAMCLK0_ROOT_GATE_DISABLE, (src == REFCLK) ? 0 : 1);1442		break;1443	case 1:1444		REG_UPDATE_2(DPSTREAMCLK_CNTL, DPSTREAMCLK1_EN,1445				(src == REFCLK) ? 0 : 1, DPSTREAMCLK1_SRC_SEL, otg_inst);1446		if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpstream)1447			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, DPSTREAMCLK1_ROOT_GATE_DISABLE, (src == REFCLK) ? 0 : 1);1448		break;1449	case 2:1450		REG_UPDATE_2(DPSTREAMCLK_CNTL, DPSTREAMCLK2_EN,1451				(src == REFCLK) ? 0 : 1, DPSTREAMCLK2_SRC_SEL, otg_inst);1452		if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpstream)1453			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, DPSTREAMCLK2_ROOT_GATE_DISABLE, (src == REFCLK) ? 0 : 1);1454		break;1455	case 3:1456		REG_UPDATE_2(DPSTREAMCLK_CNTL, DPSTREAMCLK3_EN,1457				(src == REFCLK) ? 0 : 1, DPSTREAMCLK3_SRC_SEL, otg_inst);1458		if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpstream)1459			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, DPSTREAMCLK3_ROOT_GATE_DISABLE, (src == REFCLK) ? 0 : 1);1460		break;1461	default:1462		BREAK_TO_DEBUGGER();1463		return;1464	}1465}1466 1467 1468static void dccg35_set_dpstreamclk_root_clock_gating(1469		struct dccg *dccg,1470		int dp_hpo_inst,1471		bool enable)1472{1473	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);1474 1475	switch (dp_hpo_inst) {1476	case 0:1477		if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpstream) {1478			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, DPSTREAMCLK0_ROOT_GATE_DISABLE, enable ? 1 : 0);1479			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, DPSTREAMCLK0_GATE_DISABLE, enable ? 1 : 0);1480		}1481		break;1482	case 1:1483		if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpstream) {1484			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, DPSTREAMCLK1_ROOT_GATE_DISABLE, enable ? 1 : 0);1485			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, DPSTREAMCLK1_GATE_DISABLE, enable ? 1 : 0);1486		}1487		break;1488	case 2:1489		if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpstream) {1490			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, DPSTREAMCLK2_ROOT_GATE_DISABLE, enable ? 1 : 0);1491			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, DPSTREAMCLK2_GATE_DISABLE, enable ? 1 : 0);1492		}1493		break;1494	case 3:1495		if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpstream) {1496			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, DPSTREAMCLK3_ROOT_GATE_DISABLE, enable ? 1 : 0);1497			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, DPSTREAMCLK3_GATE_DISABLE, enable ? 1 : 0);1498		}1499		break;1500	default:1501		BREAK_TO_DEBUGGER();1502		return;1503	}1504}1505 1506 1507 1508static void dccg35_set_physymclk_root_clock_gating(1509		struct dccg *dccg,1510		int phy_inst,1511		bool enable)1512{1513	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);1514 1515	if (!dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)1516		return;1517 1518	switch (phy_inst) {1519	case 0:1520		REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,1521				PHYASYMCLK_ROOT_GATE_DISABLE, enable ? 1 : 0);1522		break;1523	case 1:1524		REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,1525				PHYBSYMCLK_ROOT_GATE_DISABLE, enable ? 1 : 0);1526		break;1527	case 2:1528		REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,1529				PHYCSYMCLK_ROOT_GATE_DISABLE, enable ? 1 : 0);1530		break;1531	case 3:1532		REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,1533				PHYDSYMCLK_ROOT_GATE_DISABLE, enable ? 1 : 0);1534		break;1535	case 4:1536		REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,1537				PHYESYMCLK_ROOT_GATE_DISABLE, enable ? 1 : 0);1538		break;1539	default:1540		BREAK_TO_DEBUGGER();1541		return;1542	}1543}1544 1545static void dccg35_set_physymclk(1546		struct dccg *dccg,1547		int phy_inst,1548		enum physymclk_clock_source clk_src,1549		bool force_enable)1550{1551	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);1552 1553	/* Force PHYSYMCLK on and Select phyd32clk as the source of clock which is output to PHY through DCIO */1554	switch (phy_inst) {1555	case 0:1556		if (force_enable) {1557			REG_UPDATE_2(PHYASYMCLK_CLOCK_CNTL,1558					PHYASYMCLK_EN, 1,1559					PHYASYMCLK_SRC_SEL, clk_src);1560		} else {1561			REG_UPDATE_2(PHYASYMCLK_CLOCK_CNTL,1562					PHYASYMCLK_EN, 0,1563					PHYASYMCLK_SRC_SEL, 0);1564		}1565		break;1566	case 1:1567		if (force_enable) {1568			REG_UPDATE_2(PHYBSYMCLK_CLOCK_CNTL,1569					PHYBSYMCLK_EN, 1,1570					PHYBSYMCLK_SRC_SEL, clk_src);1571		} else {1572			REG_UPDATE_2(PHYBSYMCLK_CLOCK_CNTL,1573					PHYBSYMCLK_EN, 0,1574					PHYBSYMCLK_SRC_SEL, 0);1575		}1576		break;1577	case 2:1578		if (force_enable) {1579			REG_UPDATE_2(PHYCSYMCLK_CLOCK_CNTL,1580					PHYCSYMCLK_EN, 1,1581					PHYCSYMCLK_SRC_SEL, clk_src);1582		} else {1583			REG_UPDATE_2(PHYCSYMCLK_CLOCK_CNTL,1584					PHYCSYMCLK_EN, 0,1585					PHYCSYMCLK_SRC_SEL, 0);1586		}1587		break;1588	case 3:1589		if (force_enable) {1590			REG_UPDATE_2(PHYDSYMCLK_CLOCK_CNTL,1591					PHYDSYMCLK_EN, 1,1592					PHYDSYMCLK_SRC_SEL, clk_src);1593		} else {1594			REG_UPDATE_2(PHYDSYMCLK_CLOCK_CNTL,1595					PHYDSYMCLK_EN, 0,1596					PHYDSYMCLK_SRC_SEL, 0);1597		}1598		break;1599	case 4:1600		if (force_enable) {1601			REG_UPDATE_2(PHYESYMCLK_CLOCK_CNTL,1602					PHYESYMCLK_EN, 1,1603					PHYESYMCLK_SRC_SEL, clk_src);1604		} else {1605			REG_UPDATE_2(PHYESYMCLK_CLOCK_CNTL,1606					PHYESYMCLK_EN, 0,1607					PHYESYMCLK_SRC_SEL, 0);1608		}1609		break;1610	default:1611		BREAK_TO_DEBUGGER();1612		return;1613	}1614}1615 1616static void dccg35_set_valid_pixel_rate(1617		struct dccg *dccg,1618		int ref_dtbclk_khz,1619		int otg_inst,1620		int pixclk_khz)1621{1622	struct dtbclk_dto_params dto_params = {0};1623 1624	dto_params.ref_dtbclk_khz = ref_dtbclk_khz;1625	dto_params.otg_inst = otg_inst;1626	dto_params.pixclk_khz = pixclk_khz;1627	dto_params.is_hdmi = true;1628 1629	dccg35_set_dtbclk_dto(dccg, &dto_params);1630}1631 1632static void dccg35_dpp_root_clock_control(1633		struct dccg *dccg,1634		unsigned int dpp_inst,1635		bool clock_on)1636{1637	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);1638 1639	if (dccg->dpp_clock_gated[dpp_inst] == clock_on)1640		return;1641 1642	if (clock_on) {1643		/* turn off the DTO and leave phase/modulo at max */1644		dcn35_set_dppclk_enable(dccg, dpp_inst, 1);1645		REG_SET_2(DPPCLK_DTO_PARAM[dpp_inst], 0,1646			  DPPCLK0_DTO_PHASE, 0xFF,1647			  DPPCLK0_DTO_MODULO, 0xFF);1648	} else {1649		dcn35_set_dppclk_enable(dccg, dpp_inst, 0);1650		/* turn on the DTO to generate a 0hz clock */1651		REG_SET_2(DPPCLK_DTO_PARAM[dpp_inst], 0,1652			  DPPCLK0_DTO_PHASE, 0,1653			  DPPCLK0_DTO_MODULO, 1);1654	}1655 1656	dccg->dpp_clock_gated[dpp_inst] = !clock_on;1657}1658 1659static void dccg35_disable_symclk32_se(1660		struct dccg *dccg,1661		int hpo_se_inst)1662{1663	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);1664 1665	/* set refclk as the source for symclk32_se */1666	switch (hpo_se_inst) {1667	case 0:1668		REG_UPDATE_2(SYMCLK32_SE_CNTL,1669				SYMCLK32_SE0_SRC_SEL, 0,1670				SYMCLK32_SE0_EN, 0);1671		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se) {1672			REG_UPDATE(DCCG_GATE_DISABLE_CNTL3,1673					SYMCLK32_SE0_GATE_DISABLE, 0);1674//			REG_UPDATE(DCCG_GATE_DISABLE_CNTL3,1675//					SYMCLK32_ROOT_SE0_GATE_DISABLE, 0);1676		}1677		break;1678	case 1:1679		REG_UPDATE_2(SYMCLK32_SE_CNTL,1680				SYMCLK32_SE1_SRC_SEL, 0,1681				SYMCLK32_SE1_EN, 0);1682		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se) {1683			REG_UPDATE(DCCG_GATE_DISABLE_CNTL3,1684					SYMCLK32_SE1_GATE_DISABLE, 0);1685//			REG_UPDATE(DCCG_GATE_DISABLE_CNTL3,1686//					SYMCLK32_ROOT_SE1_GATE_DISABLE, 0);1687		}1688		break;1689	case 2:1690		REG_UPDATE_2(SYMCLK32_SE_CNTL,1691				SYMCLK32_SE2_SRC_SEL, 0,1692				SYMCLK32_SE2_EN, 0);1693		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se) {1694			REG_UPDATE(DCCG_GATE_DISABLE_CNTL3,1695					SYMCLK32_SE2_GATE_DISABLE, 0);1696//			REG_UPDATE(DCCG_GATE_DISABLE_CNTL3,1697//					SYMCLK32_ROOT_SE2_GATE_DISABLE, 0);1698		}1699		break;1700	case 3:1701		REG_UPDATE_2(SYMCLK32_SE_CNTL,1702				SYMCLK32_SE3_SRC_SEL, 0,1703				SYMCLK32_SE3_EN, 0);1704		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se) {1705			REG_UPDATE(DCCG_GATE_DISABLE_CNTL3,1706					SYMCLK32_SE3_GATE_DISABLE, 0);1707//			REG_UPDATE(DCCG_GATE_DISABLE_CNTL3,1708//					SYMCLK32_ROOT_SE3_GATE_DISABLE, 0);1709		}1710		break;1711	default:1712		BREAK_TO_DEBUGGER();1713		return;1714	}1715}1716 1717static void dccg35_init_cb(struct dccg *dccg)1718{1719	(void)dccg;1720	/* Any RCG should be done when driver enter low power mode*/1721}1722 1723void dccg35_init(struct dccg *dccg)1724{1725	int otg_inst;1726	/* Set HPO stream encoder to use refclk to avoid case where PHY is1727	 * disabled and SYMCLK32 for HPO SE is sourced from PHYD32CLK which1728	 * will cause DCN to hang.1729	 */1730	for (otg_inst = 0; otg_inst < 4; otg_inst++)1731		dccg35_disable_symclk32_se(dccg, otg_inst);1732 1733	if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le)1734		for (otg_inst = 0; otg_inst < 2; otg_inst++) {1735			dccg31_disable_symclk32_le(dccg, otg_inst);1736			dccg31_set_symclk32_le_root_clock_gating(dccg, otg_inst, false);1737		}1738 1739//	if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)1740//		for (otg_inst = 0; otg_inst < 4; otg_inst++)1741//			dccg35_disable_symclk_se(dccg, otg_inst, otg_inst);1742 1743 1744	if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpstream)1745		for (otg_inst = 0; otg_inst < 4; otg_inst++) {1746			dccg35_set_dpstreamclk(dccg, REFCLK, otg_inst,1747						otg_inst);1748			dccg35_set_dpstreamclk_root_clock_gating(dccg, otg_inst, false);1749		}1750 1751/*1752	dccg35_enable_global_fgcg_rep(1753		dccg, dccg->ctx->dc->debug.enable_fine_grain_clock_gating.bits1754			      .dccg_global_fgcg_rep);*/1755}1756 1757void dccg35_enable_global_fgcg_rep(struct dccg *dccg, bool value)1758{1759	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);1760 1761	REG_UPDATE(DCCG_GLOBAL_FGCG_REP_CNTL, DCCG_GLOBAL_FGCG_REP_DIS, !value);1762}1763 1764static void dccg35_enable_dscclk(struct dccg *dccg, int inst)1765{1766	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);1767 1768	//Disable DTO1769	switch (inst) {1770	case 0:1771		REG_UPDATE_2(DSCCLK0_DTO_PARAM,1772				DSCCLK0_DTO_PHASE, 0,1773				DSCCLK0_DTO_MODULO, 0);1774		REG_UPDATE(DSCCLK_DTO_CTRL,	DSCCLK0_EN, 1);1775		if (dccg->ctx->dc->debug.root_clock_optimization.bits.dsc)1776			REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DSCCLK0_ROOT_GATE_DISABLE, 1);1777		break;1778	case 1:1779		REG_UPDATE_2(DSCCLK1_DTO_PARAM,1780				DSCCLK1_DTO_PHASE, 0,1781				DSCCLK1_DTO_MODULO, 0);1782		REG_UPDATE(DSCCLK_DTO_CTRL, DSCCLK1_EN, 1);1783		if (dccg->ctx->dc->debug.root_clock_optimization.bits.dsc)1784			REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DSCCLK1_ROOT_GATE_DISABLE, 1);1785		break;1786	case 2:1787		REG_UPDATE_2(DSCCLK2_DTO_PARAM,1788				DSCCLK2_DTO_PHASE, 0,1789				DSCCLK2_DTO_MODULO, 0);1790		REG_UPDATE(DSCCLK_DTO_CTRL, DSCCLK2_EN, 1);1791		if (dccg->ctx->dc->debug.root_clock_optimization.bits.dsc)1792			REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DSCCLK2_ROOT_GATE_DISABLE, 1);1793		break;1794	case 3:1795		REG_UPDATE_2(DSCCLK3_DTO_PARAM,1796				DSCCLK3_DTO_PHASE, 0,1797				DSCCLK3_DTO_MODULO, 0);1798		REG_UPDATE(DSCCLK_DTO_CTRL, DSCCLK3_EN, 1);1799		if (dccg->ctx->dc->debug.root_clock_optimization.bits.dsc)1800			REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DSCCLK3_ROOT_GATE_DISABLE, 1);1801		break;1802	default:1803		BREAK_TO_DEBUGGER();1804		return;1805	}1806}1807 1808static void dccg35_disable_dscclk(struct dccg *dccg,1809				int inst)1810{1811	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);1812 1813	if (!dccg->ctx->dc->debug.root_clock_optimization.bits.dsc)1814		return;1815 1816	switch (inst) {1817	case 0:1818		REG_UPDATE(DSCCLK_DTO_CTRL, DSCCLK0_EN, 0);1819		REG_UPDATE_2(DSCCLK0_DTO_PARAM,1820				DSCCLK0_DTO_PHASE, 0,1821				DSCCLK0_DTO_MODULO, 1);1822		if (dccg->ctx->dc->debug.root_clock_optimization.bits.dsc)1823			REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DSCCLK0_ROOT_GATE_DISABLE, 0);1824		break;1825	case 1:1826		REG_UPDATE(DSCCLK_DTO_CTRL, DSCCLK1_EN, 0);1827		REG_UPDATE_2(DSCCLK1_DTO_PARAM,1828				DSCCLK1_DTO_PHASE, 0,1829				DSCCLK1_DTO_MODULO, 1);1830		if (dccg->ctx->dc->debug.root_clock_optimization.bits.dsc)1831			REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DSCCLK1_ROOT_GATE_DISABLE, 0);1832		break;1833	case 2:1834		REG_UPDATE(DSCCLK_DTO_CTRL, DSCCLK2_EN, 0);1835		REG_UPDATE_2(DSCCLK2_DTO_PARAM,1836				DSCCLK2_DTO_PHASE, 0,1837				DSCCLK2_DTO_MODULO, 1);1838		if (dccg->ctx->dc->debug.root_clock_optimization.bits.dsc)1839			REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DSCCLK2_ROOT_GATE_DISABLE, 0);1840		break;1841	case 3:1842		REG_UPDATE(DSCCLK_DTO_CTRL, DSCCLK3_EN, 0);1843		REG_UPDATE_2(DSCCLK3_DTO_PARAM,1844				DSCCLK3_DTO_PHASE, 0,1845				DSCCLK3_DTO_MODULO, 1);1846		if (dccg->ctx->dc->debug.root_clock_optimization.bits.dsc)1847			REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DSCCLK3_ROOT_GATE_DISABLE, 0);1848		break;1849	default:1850		return;1851	}1852}1853 1854static void dccg35_enable_symclk_se(struct dccg *dccg, uint32_t stream_enc_inst, uint32_t link_enc_inst)1855{1856	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);1857 1858	switch (link_enc_inst) {1859	case 0:1860		REG_UPDATE(SYMCLKA_CLOCK_ENABLE,1861				SYMCLKA_CLOCK_ENABLE, 1);1862		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)1863			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKA_ROOT_GATE_DISABLE, 1);1864		break;1865	case 1:1866		REG_UPDATE(SYMCLKB_CLOCK_ENABLE,1867				SYMCLKB_CLOCK_ENABLE, 1);1868		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)1869			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKB_ROOT_GATE_DISABLE, 1);1870		break;1871	case 2:1872		REG_UPDATE(SYMCLKC_CLOCK_ENABLE,1873				SYMCLKC_CLOCK_ENABLE, 1);1874		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)1875			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKC_ROOT_GATE_DISABLE, 1);1876		break;1877	case 3:1878		REG_UPDATE(SYMCLKD_CLOCK_ENABLE,1879				SYMCLKD_CLOCK_ENABLE, 1);1880		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)1881			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKD_ROOT_GATE_DISABLE, 1);1882		break;1883	case 4:1884		REG_UPDATE(SYMCLKE_CLOCK_ENABLE,1885				SYMCLKE_CLOCK_ENABLE, 1);1886		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)1887			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKE_ROOT_GATE_DISABLE, 1);1888		break;1889	}1890 1891	switch (stream_enc_inst) {1892	case 0:1893		REG_UPDATE_2(SYMCLKA_CLOCK_ENABLE,1894				SYMCLKA_FE_EN, 1,1895				SYMCLKA_FE_SRC_SEL, link_enc_inst);1896		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)1897			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKA_FE_ROOT_GATE_DISABLE, 1);1898		break;1899	case 1:1900		REG_UPDATE_2(SYMCLKB_CLOCK_ENABLE,1901				SYMCLKB_FE_EN, 1,1902				SYMCLKB_FE_SRC_SEL, link_enc_inst);1903		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)1904			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKB_FE_ROOT_GATE_DISABLE, 1);1905		break;1906	case 2:1907		REG_UPDATE_2(SYMCLKC_CLOCK_ENABLE,1908				SYMCLKC_FE_EN, 1,1909				SYMCLKC_FE_SRC_SEL, link_enc_inst);1910		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)1911			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKC_FE_ROOT_GATE_DISABLE, 1);1912		break;1913	case 3:1914		REG_UPDATE_2(SYMCLKD_CLOCK_ENABLE,1915				SYMCLKD_FE_EN, 1,1916				SYMCLKD_FE_SRC_SEL, link_enc_inst);1917		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)1918			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKD_FE_ROOT_GATE_DISABLE, 1);1919		break;1920	case 4:1921		REG_UPDATE_2(SYMCLKE_CLOCK_ENABLE,1922				SYMCLKE_FE_EN, 1,1923				SYMCLKE_FE_SRC_SEL, link_enc_inst);1924		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)1925			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKE_FE_ROOT_GATE_DISABLE, 1);1926		break;1927	}1928}1929 1930/*get other front end connected to this backend*/1931static uint8_t dccg35_get_number_enabled_symclk_fe_connected_to_be(struct dccg *dccg, uint32_t link_enc_inst)1932{1933	uint8_t num_enabled_symclk_fe = 0;1934	uint32_t fe_clk_en[5] = {0}, be_clk_sel[5] = {0};1935	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);1936 1937	REG_GET_2(SYMCLKA_CLOCK_ENABLE, SYMCLKA_FE_EN, &fe_clk_en[0],1938		SYMCLKA_FE_SRC_SEL, &be_clk_sel[0]);1939 1940	REG_GET_2(SYMCLKB_CLOCK_ENABLE, SYMCLKB_FE_EN, &fe_clk_en[1],1941		SYMCLKB_FE_SRC_SEL, &be_clk_sel[1]);1942 1943	REG_GET_2(SYMCLKC_CLOCK_ENABLE, SYMCLKC_FE_EN, &fe_clk_en[2],1944		SYMCLKC_FE_SRC_SEL, &be_clk_sel[2]);1945 1946	REG_GET_2(SYMCLKD_CLOCK_ENABLE,	SYMCLKD_FE_EN, &fe_clk_en[3],1947		SYMCLKD_FE_SRC_SEL, &be_clk_sel[3]);1948 1949	REG_GET_2(SYMCLKE_CLOCK_ENABLE,	SYMCLKE_FE_EN, &fe_clk_en[4],1950		SYMCLKE_FE_SRC_SEL, &be_clk_sel[4]);1951 1952	uint8_t i;1953 1954	for (i = 0; i < ARRAY_SIZE(fe_clk_en); i++) {1955		if (fe_clk_en[i] && be_clk_sel[i] == link_enc_inst)1956			num_enabled_symclk_fe++;1957	}1958	return num_enabled_symclk_fe;1959}1960 1961static void dccg35_disable_symclk_se(struct dccg *dccg, uint32_t stream_enc_inst, uint32_t link_enc_inst)1962{1963	uint8_t num_enabled_symclk_fe = 0;1964	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);1965 1966	switch (stream_enc_inst) {1967	case 0:1968		REG_UPDATE_2(SYMCLKA_CLOCK_ENABLE,1969				SYMCLKA_FE_EN, 0,1970				SYMCLKA_FE_SRC_SEL, 0);1971//		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)1972//			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKA_FE_ROOT_GATE_DISABLE, 0);1973		break;1974	case 1:1975		REG_UPDATE_2(SYMCLKB_CLOCK_ENABLE,1976				SYMCLKB_FE_EN, 0,1977				SYMCLKB_FE_SRC_SEL, 0);1978//		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)1979//			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKB_FE_ROOT_GATE_DISABLE, 0);1980		break;1981	case 2:1982		REG_UPDATE_2(SYMCLKC_CLOCK_ENABLE,1983				SYMCLKC_FE_EN, 0,1984				SYMCLKC_FE_SRC_SEL, 0);1985//		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)1986//			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKC_FE_ROOT_GATE_DISABLE, 0);1987		break;1988	case 3:1989		REG_UPDATE_2(SYMCLKD_CLOCK_ENABLE,1990				SYMCLKD_FE_EN, 0,1991				SYMCLKD_FE_SRC_SEL, 0);1992//		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)1993//			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKD_FE_ROOT_GATE_DISABLE, 0);1994		break;1995	case 4:1996		REG_UPDATE_2(SYMCLKE_CLOCK_ENABLE,1997				SYMCLKE_FE_EN, 0,1998				SYMCLKE_FE_SRC_SEL, 0);1999//		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)2000//			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKE_FE_ROOT_GATE_DISABLE, 0);2001		break;2002	}2003 2004	/*check other enabled symclk fe connected to this be */2005	num_enabled_symclk_fe = dccg35_get_number_enabled_symclk_fe_connected_to_be(dccg, link_enc_inst);2006	/*only turn off backend clk if other front end attached to this backend are all off,2007	 for mst, only turn off the backend if this is the last front end*/2008	if (num_enabled_symclk_fe == 0) {2009		switch (link_enc_inst) {2010		case 0:2011			REG_UPDATE(SYMCLKA_CLOCK_ENABLE,2012					SYMCLKA_CLOCK_ENABLE, 0);2013//			if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le)2014//				REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKA_ROOT_GATE_DISABLE, 0);2015			break;2016		case 1:2017			REG_UPDATE(SYMCLKB_CLOCK_ENABLE,2018					SYMCLKB_CLOCK_ENABLE, 0);2019//			if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le)2020//				REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKB_ROOT_GATE_DISABLE, 0);2021			break;2022		case 2:2023			REG_UPDATE(SYMCLKC_CLOCK_ENABLE,2024					SYMCLKC_CLOCK_ENABLE, 0);2025//			if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le)2026//				REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKC_ROOT_GATE_DISABLE, 0);2027			break;2028		case 3:2029			REG_UPDATE(SYMCLKD_CLOCK_ENABLE,2030					SYMCLKD_CLOCK_ENABLE, 0);2031//			if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le)2032//				REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKD_ROOT_GATE_DISABLE, 0);2033			break;2034		case 4:2035			REG_UPDATE(SYMCLKE_CLOCK_ENABLE,2036					SYMCLKE_CLOCK_ENABLE, 0);2037//			if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le)2038//				REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKE_ROOT_GATE_DISABLE, 0);2039			break;2040		}2041	}2042}2043 2044static void dccg35_set_dpstreamclk_cb(2045		struct dccg *dccg,2046		enum streamclk_source src,2047		int otg_inst,2048		int dp_hpo_inst)2049{2050 2051	enum dtbclk_source dtb_clk_src;2052	enum dp_stream_clk_source dp_stream_clk_src;2053 2054	switch (src) {2055	case REFCLK:2056		dtb_clk_src = DTBCLK_REFCLK;2057		dp_stream_clk_src = DP_STREAM_REFCLK;2058		break;2059	case DPREFCLK:2060		dtb_clk_src = DTBCLK_DPREFCLK;2061		dp_stream_clk_src = (enum dp_stream_clk_source)otg_inst;2062		break;2063	case DTBCLK0:2064		dtb_clk_src = DTBCLK_DTBCLK0;2065		dp_stream_clk_src = (enum dp_stream_clk_source)otg_inst;2066		break;2067	default:2068		BREAK_TO_DEBUGGER();2069		return;2070	}2071 2072	if (dtb_clk_src == DTBCLK_REFCLK &&2073		dp_stream_clk_src == DP_STREAM_REFCLK) {2074		dccg35_disable_dtbclk_p_new(dccg, otg_inst);2075		dccg35_disable_dpstreamclk_new(dccg, dp_hpo_inst);2076	} else {2077		dccg35_enable_dtbclk_p_new(dccg, dtb_clk_src, otg_inst);2078		dccg35_enable_dpstreamclk_new(dccg,2079										dp_stream_clk_src,2080										dp_hpo_inst);2081	}2082}2083 2084static void dccg35_set_dpstreamclk_root_clock_gating_cb(2085	struct dccg *dccg,2086	int dp_hpo_inst,2087	bool power_on)2088{2089	/* power_on set indicates we need to ungate2090	 * Currently called from optimize_bandwidth and prepare_bandwidth calls2091	 * Since clock source is not passed restore to refclock on ungate2092	 * Instance 0 is implied here since only one streamclock resource2093	 * Redundant as gating when enabled is acheived through set_dpstreamclk2094	 */2095	if (power_on)2096		dccg35_enable_dpstreamclk_new(dccg,2097										DP_STREAM_REFCLK,2098										dp_hpo_inst);2099	else2100		dccg35_disable_dpstreamclk_new(dccg, dp_hpo_inst);2101}2102 2103static void dccg35_update_dpp_dto_cb(struct dccg *dccg, int dpp_inst,2104				  int req_dppclk)2105{2106	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);2107 2108	if (dccg->dpp_clock_gated[dpp_inst]) {2109		/*2110		 * Do not update the DPPCLK DTO if the clock is stopped.2111		 */2112		return;2113	}2114 2115	if (dccg->ref_dppclk && req_dppclk) {2116		int ref_dppclk = dccg->ref_dppclk;2117		int modulo, phase;2118 2119		// phase / modulo = dpp pipe clk / dpp global clk2120		modulo = 0xff;   // use FF at the end2121		phase = ((modulo * req_dppclk) + ref_dppclk - 1) / ref_dppclk;2122 2123		if (phase > 0xff) {2124			ASSERT(false);2125			phase = 0xff;2126		}2127 2128		/* Enable DPP CLK DTO output */2129		dccg35_enable_dpp_clk_new(dccg, dpp_inst, DPP_DCCG_DTO);2130 2131		/* Program DTO */2132		REG_SET_2(DPPCLK_DTO_PARAM[dpp_inst], 0,2133				DPPCLK0_DTO_PHASE, phase,2134				DPPCLK0_DTO_MODULO, modulo);2135	} else2136		dccg35_disable_dpp_clk_new(dccg, dpp_inst);2137 2138	dccg->pipe_dppclk_khz[dpp_inst] = req_dppclk;2139}2140 2141static void dccg35_dpp_root_clock_control_cb(2142	struct dccg *dccg,2143	unsigned int dpp_inst,2144	bool power_on)2145{2146	if (dccg->dpp_clock_gated[dpp_inst] == power_on)2147		return;2148	/* power_on set indicates we need to ungate2149	 * Currently called from optimize_bandwidth and prepare_bandwidth calls2150	 * Since clock source is not passed restore to refclock on ungate2151	 * Redundant as gating when enabled is acheived through update_dpp_dto2152	 */2153	dccg35_set_dppclk_rcg(dccg, dpp_inst, !power_on);2154 2155	dccg->dpp_clock_gated[dpp_inst] = !power_on;2156}2157 2158static void dccg35_enable_symclk32_se_cb(2159	struct dccg *dccg,2160	int inst,2161	enum phyd32clk_clock_source phyd32clk)2162{2163	dccg35_enable_symclk32_se_new(dccg, inst, (enum symclk32_se_clk_source)phyd32clk);2164}2165 2166static void dccg35_disable_symclk32_se_cb(struct dccg *dccg, int inst)2167{2168	dccg35_disable_symclk32_se_new(dccg, inst);2169}2170 2171static void dccg35_enable_symclk32_le_cb(2172			struct dccg *dccg,2173			int inst,2174			enum phyd32clk_clock_source src)2175{2176	dccg35_enable_symclk32_le_new(dccg, inst, (enum symclk32_le_clk_source) src);2177}2178 2179static void dccg35_disable_symclk32_le_cb(struct dccg *dccg, int inst)2180{2181	dccg35_disable_symclk32_le_new(dccg, inst);2182}2183 2184static void dccg35_set_symclk32_le_root_clock_gating_cb(2185	struct dccg *dccg,2186	int inst,2187	bool power_on)2188{2189	/* power_on set indicates we need to ungate2190	 * Currently called from optimize_bandwidth and prepare_bandwidth calls2191	 * Since clock source is not passed restore to refclock on ungate2192	 * Redundant as gating when enabled is acheived through disable_symclk32_le2193	 */2194	if (power_on)2195		dccg35_enable_symclk32_le_new(dccg, inst, SYMCLK32_LE_REFCLK);2196	else2197		dccg35_disable_symclk32_le_new(dccg, inst);2198}2199 2200static void dccg35_set_physymclk_cb(2201	struct dccg *dccg,2202	int inst,2203	enum physymclk_clock_source clk_src,2204	bool force_enable)2205{2206	/* force_enable = 0 indicates we can switch to ref clock */2207	if (force_enable)2208		dccg35_enable_physymclk_new(dccg, inst, (enum physymclk_source)clk_src);2209	else2210		dccg35_disable_physymclk_new(dccg, inst);2211}2212 2213static void dccg35_set_physymclk_root_clock_gating_cb(2214	struct dccg *dccg,2215	int inst,2216	bool power_on)2217{2218	/* Redundant RCG already done in disable_physymclk2219	 * power_on = 1 indicates we need to ungate2220	 */2221	if (power_on)2222		dccg35_enable_physymclk_new(dccg, inst, PHYSYMCLK_REFCLK);2223	else2224		dccg35_disable_physymclk_new(dccg, inst);2225}2226 2227static void dccg35_set_symclk32_le_root_clock_gating(2228	struct dccg *dccg,2229	int inst,2230	bool power_on)2231{2232	/* power_on set indicates we need to ungate2233	 * Currently called from optimize_bandwidth and prepare_bandwidth calls2234	 * Since clock source is not passed restore to refclock on ungate2235	 * Redundant as gating when enabled is acheived through disable_symclk32_le2236	 */2237	if (power_on)2238		dccg35_enable_symclk32_le_new(dccg, inst, SYMCLK32_LE_REFCLK);2239	else2240		dccg35_disable_symclk32_le_new(dccg, inst);2241}2242 2243static void dccg35_set_dtbclk_p_src_cb(2244		struct dccg *dccg,2245		enum streamclk_source src,2246		uint32_t inst)2247{2248	if (src == DTBCLK0)2249		dccg35_enable_dtbclk_p_new(dccg, DTBCLK_DTBCLK0, inst);2250	else2251		dccg35_disable_dtbclk_p_new(dccg, inst);2252}2253 2254static void dccg35_set_dtbclk_dto_cb(2255		struct dccg *dccg,2256		const struct dtbclk_dto_params *params)2257{2258	/* set_dtbclk_p_src typ called earlier to switch to DTBCLK2259	 * if params->ref_dtbclk_khz and req_dtbclk_khz are 0 switch to ref-clock2260	 */2261	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);2262	/* DTO Output Rate / Pixel Rate = 1/4 */2263	int req_dtbclk_khz = params->pixclk_khz / 4;2264 2265	if (params->ref_dtbclk_khz && req_dtbclk_khz) {2266		uint32_t modulo, phase;2267 2268		dccg35_enable_dtbclk_p_new(dccg, DTBCLK_DTBCLK0, params->otg_inst);2269 2270		// phase / modulo = dtbclk / dtbclk ref2271		modulo = params->ref_dtbclk_khz * 1000;2272		phase = req_dtbclk_khz * 1000;2273 2274		REG_WRITE(DTBCLK_DTO_MODULO[params->otg_inst], modulo);2275		REG_WRITE(DTBCLK_DTO_PHASE[params->otg_inst], phase);2276 2277		REG_UPDATE(OTG_PIXEL_RATE_CNTL[params->otg_inst],2278				DTBCLK_DTO_ENABLE[params->otg_inst], 1);2279 2280		REG_WAIT(OTG_PIXEL_RATE_CNTL[params->otg_inst],2281				DTBCLKDTO_ENABLE_STATUS[params->otg_inst], 1,2282				1, 100);2283 2284		/* program OTG_PIXEL_RATE_DIV for DIVK1 and DIVK2 fields */2285		dccg35_set_pixel_rate_div(dccg, params->otg_inst, PIXEL_RATE_DIV_BY_1, PIXEL_RATE_DIV_BY_1);2286 2287		/* The recommended programming sequence to enable DTBCLK DTO to generate2288		 * valid pixel HPO DPSTREAM ENCODER, specifies that DTO source select should2289		 * be set only after DTO is enabled2290		 */2291		REG_UPDATE(OTG_PIXEL_RATE_CNTL[params->otg_inst],2292				PIPE_DTO_SRC_SEL[params->otg_inst], 2);2293	} else {2294		dccg35_disable_dtbclk_p_new(dccg, params->otg_inst);2295 2296		REG_UPDATE_2(OTG_PIXEL_RATE_CNTL[params->otg_inst],2297					 DTBCLK_DTO_ENABLE[params->otg_inst], 0,2298					 PIPE_DTO_SRC_SEL[params->otg_inst], params->is_hdmi ? 0 : 1);2299 2300		REG_WRITE(DTBCLK_DTO_MODULO[params->otg_inst], 0);2301		REG_WRITE(DTBCLK_DTO_PHASE[params->otg_inst], 0);2302	}2303}2304 2305static void dccg35_disable_dscclk_cb(struct dccg *dccg,2306									 int inst)2307{2308	dccg35_disable_dscclk_new(dccg, inst);2309}2310 2311static void dccg35_enable_dscclk_cb(struct dccg *dccg, int inst)2312{2313	dccg35_enable_dscclk_new(dccg, inst, DSC_DTO_TUNED_CK_GPU_DISCLK_3);2314}2315 2316static void dccg35_enable_symclk_se_cb(struct dccg *dccg, uint32_t stream_enc_inst, uint32_t link_enc_inst)2317{2318	/* Switch to functional clock if already not selected */2319	dccg35_enable_symclk_be_new(dccg, SYMCLK_BE_PHYCLK, link_enc_inst);2320 2321	dccg35_enable_symclk_fe_new(dccg, stream_enc_inst, (enum symclk_fe_source) link_enc_inst);2322 2323}2324 2325static void dccg35_disable_symclk_se_cb(2326			struct dccg *dccg,2327			uint32_t stream_enc_inst,2328			uint32_t link_enc_inst)2329{2330	dccg35_disable_symclk_fe_new(dccg, stream_enc_inst);2331 2332	/* DMU PHY sequence switches SYMCLK_BE (link_enc_inst) to ref clock once PHY is turned off */2333}2334 2335void dccg35_root_gate_disable_control(struct dccg *dccg, uint32_t pipe_idx, uint32_t disable_clock_gating)2336{2337 2338	if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpp) {2339		dccg35_set_dppclk_root_clock_gating(dccg, pipe_idx, disable_clock_gating);2340	}2341}2342 2343static const struct dccg_funcs dccg35_funcs_new = {2344	.update_dpp_dto = dccg35_update_dpp_dto_cb,2345	.dpp_root_clock_control = dccg35_dpp_root_clock_control_cb,2346	.get_dccg_ref_freq = dccg31_get_dccg_ref_freq,2347	.dccg_init = dccg35_init_cb,2348	.set_dpstreamclk = dccg35_set_dpstreamclk_cb,2349	.set_dpstreamclk_root_clock_gating = dccg35_set_dpstreamclk_root_clock_gating_cb,2350	.enable_symclk32_se = dccg35_enable_symclk32_se_cb,2351	.disable_symclk32_se = dccg35_disable_symclk32_se_cb,2352	.enable_symclk32_le = dccg35_enable_symclk32_le_cb,2353	.disable_symclk32_le = dccg35_disable_symclk32_le_cb,2354	.set_symclk32_le_root_clock_gating = dccg35_set_symclk32_le_root_clock_gating_cb,2355	.set_physymclk = dccg35_set_physymclk_cb,2356	.set_physymclk_root_clock_gating = dccg35_set_physymclk_root_clock_gating_cb,2357	.set_dtbclk_dto = dccg35_set_dtbclk_dto_cb,2358	.set_audio_dtbclk_dto = dccg31_set_audio_dtbclk_dto,2359	.set_fifo_errdet_ovr_en = dccg2_set_fifo_errdet_ovr_en,2360	.otg_add_pixel = dccg31_otg_add_pixel,2361	.otg_drop_pixel = dccg31_otg_drop_pixel,2362	.set_dispclk_change_mode = dccg31_set_dispclk_change_mode,2363	.disable_dsc = dccg35_disable_dscclk_cb,2364	.enable_dsc = dccg35_enable_dscclk_cb,2365	.set_pixel_rate_div = dccg35_set_pixel_rate_div,2366	.get_pixel_rate_div = dccg35_get_pixel_rate_div,2367	.trigger_dio_fifo_resync = dccg35_trigger_dio_fifo_resync,2368	.set_valid_pixel_rate = dccg35_set_valid_pixel_rate,2369	.enable_symclk_se = dccg35_enable_symclk_se_cb,2370	.disable_symclk_se = dccg35_disable_symclk_se_cb,2371	.set_dtbclk_p_src = dccg35_set_dtbclk_p_src_cb,2372};2373 2374static const struct dccg_funcs dccg35_funcs = {2375	.update_dpp_dto = dccg35_update_dpp_dto,2376	.dpp_root_clock_control = dccg35_dpp_root_clock_control,2377	.get_dccg_ref_freq = dccg31_get_dccg_ref_freq,2378	.dccg_init = dccg35_init,2379	.set_dpstreamclk = dccg35_set_dpstreamclk,2380	.set_dpstreamclk_root_clock_gating = dccg35_set_dpstreamclk_root_clock_gating,2381	.enable_symclk32_se = dccg31_enable_symclk32_se,2382	.disable_symclk32_se = dccg35_disable_symclk32_se,2383	.enable_symclk32_le = dccg31_enable_symclk32_le,2384	.disable_symclk32_le = dccg31_disable_symclk32_le,2385	.set_symclk32_le_root_clock_gating = dccg31_set_symclk32_le_root_clock_gating,2386	.set_physymclk = dccg35_set_physymclk,2387	.set_physymclk_root_clock_gating = dccg35_set_physymclk_root_clock_gating,2388	.set_dtbclk_dto = dccg35_set_dtbclk_dto,2389	.set_audio_dtbclk_dto = dccg31_set_audio_dtbclk_dto,2390	.set_fifo_errdet_ovr_en = dccg2_set_fifo_errdet_ovr_en,2391	.otg_add_pixel = dccg31_otg_add_pixel,2392	.otg_drop_pixel = dccg31_otg_drop_pixel,2393	.set_dispclk_change_mode = dccg31_set_dispclk_change_mode,2394	.disable_dsc = dccg35_disable_dscclk,2395	.enable_dsc = dccg35_enable_dscclk,2396	.set_pixel_rate_div = dccg35_set_pixel_rate_div,2397	.get_pixel_rate_div = dccg35_get_pixel_rate_div,2398	.trigger_dio_fifo_resync = dccg35_trigger_dio_fifo_resync,2399	.set_valid_pixel_rate = dccg35_set_valid_pixel_rate,2400	.enable_symclk_se = dccg35_enable_symclk_se,2401	.disable_symclk_se = dccg35_disable_symclk_se,2402	.set_dtbclk_p_src = dccg35_set_dtbclk_p_src,2403	.dccg_root_gate_disable_control = dccg35_root_gate_disable_control,2404};2405 2406struct dccg *dccg35_create(2407	struct dc_context *ctx,2408	const struct dccg_registers *regs,2409	const struct dccg_shift *dccg_shift,2410	const struct dccg_mask *dccg_mask)2411{2412	struct dcn_dccg *dccg_dcn = kzalloc(sizeof(*dccg_dcn), GFP_KERNEL);2413	struct dccg *base;2414 2415	if (dccg_dcn == NULL) {2416		BREAK_TO_DEBUGGER();2417		return NULL;2418	}2419	(void)&dccg35_disable_symclk_be_new;2420	(void)&dccg35_set_symclk32_le_root_clock_gating;2421	(void)&dccg35_set_smclk32_se_rcg;2422	(void)&dccg35_funcs_new;2423 2424	base = &dccg_dcn->base;2425	base->ctx = ctx;2426	base->funcs = &dccg35_funcs;2427 2428	dccg_dcn->regs = regs;2429	dccg_dcn->dccg_shift = dccg_shift;2430	dccg_dcn->dccg_mask = dccg_mask;2431 2432	return &dccg_dcn->base;2433}2434