File Index
Files and directories
Sign in
FILE

dcn35_dccg.c

File preview with syntax highlighting.

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