cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

dcn31_dccg.c (20199B)


      1/*
      2 * Copyright 2018 Advanced Micro Devices, Inc.
      3 *
      4 * Permission is hereby granted, free of charge, to any person obtaining a
      5 * copy of this software and associated documentation files (the "Software"),
      6 * to deal in the Software without restriction, including without limitation
      7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      8 * and/or sell copies of the Software, and to permit persons to whom the
      9 * Software is furnished to do so, subject to the following conditions:
     10 *
     11 * The above copyright notice and this permission notice shall be included in
     12 * all copies or substantial portions of the Software.
     13 *
     14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
     18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     20 * OTHER DEALINGS IN THE SOFTWARE.
     21 *
     22 * Authors: AMD
     23 *
     24 */
     25
     26#include "reg_helper.h"
     27#include "core_types.h"
     28#include "dcn31_dccg.h"
     29#include "dal_asic_id.h"
     30
     31#define TO_DCN_DCCG(dccg)\
     32	container_of(dccg, struct dcn_dccg, base)
     33
     34#define REG(reg) \
     35	(dccg_dcn->regs->reg)
     36
     37#undef FN
     38#define FN(reg_name, field_name) \
     39	dccg_dcn->dccg_shift->field_name, dccg_dcn->dccg_mask->field_name
     40
     41#define CTX \
     42	dccg_dcn->base.ctx
     43#define DC_LOGGER \
     44	dccg->ctx->logger
     45
     46static void dccg31_update_dpp_dto(struct dccg *dccg, int dpp_inst, int req_dppclk)
     47{
     48	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
     49
     50	if (dccg->ref_dppclk && req_dppclk) {
     51		int ref_dppclk = dccg->ref_dppclk;
     52		int modulo, phase;
     53
     54		// phase / modulo = dpp pipe clk / dpp global clk
     55		modulo = 0xff;   // use FF at the end
     56		phase = ((modulo * req_dppclk) + ref_dppclk - 1) / ref_dppclk;
     57
     58		if (phase > 0xff) {
     59			ASSERT(false);
     60			phase = 0xff;
     61		}
     62
     63		REG_SET_2(DPPCLK_DTO_PARAM[dpp_inst], 0,
     64				DPPCLK0_DTO_PHASE, phase,
     65				DPPCLK0_DTO_MODULO, modulo);
     66		REG_UPDATE(DPPCLK_DTO_CTRL,
     67				DPPCLK_DTO_ENABLE[dpp_inst], 1);
     68	} else {
     69		//DTO must be enabled to generate a 0Hz clock output
     70		if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpp) {
     71			REG_UPDATE(DPPCLK_DTO_CTRL,
     72					DPPCLK_DTO_ENABLE[dpp_inst], 1);
     73			REG_SET_2(DPPCLK_DTO_PARAM[dpp_inst], 0,
     74					DPPCLK0_DTO_PHASE, 0,
     75					DPPCLK0_DTO_MODULO, 1);
     76		} else {
     77			REG_UPDATE(DPPCLK_DTO_CTRL,
     78					DPPCLK_DTO_ENABLE[dpp_inst], 0);
     79		}
     80	}
     81	dccg->pipe_dppclk_khz[dpp_inst] = req_dppclk;
     82}
     83
     84static enum phyd32clk_clock_source get_phy_mux_symclk(
     85		struct dcn_dccg *dccg_dcn,
     86		enum phyd32clk_clock_source src)
     87{
     88	if (dccg_dcn->base.ctx->asic_id.hw_internal_rev == YELLOW_CARP_B0) {
     89		if (src == PHYD32CLKC)
     90			src = PHYD32CLKF;
     91		if (src == PHYD32CLKD)
     92			src = PHYD32CLKG;
     93	}
     94	return src;
     95}
     96
     97static void dccg31_enable_dpstreamclk(struct dccg *dccg, int otg_inst)
     98{
     99	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
    100
    101	/* enabled to select one of the DTBCLKs for pipe */
    102	switch (otg_inst) {
    103	case 0:
    104		REG_UPDATE(DPSTREAMCLK_CNTL,
    105				DPSTREAMCLK_PIPE0_EN, 1);
    106		break;
    107	case 1:
    108		REG_UPDATE(DPSTREAMCLK_CNTL,
    109				DPSTREAMCLK_PIPE1_EN, 1);
    110		break;
    111	case 2:
    112		REG_UPDATE(DPSTREAMCLK_CNTL,
    113				DPSTREAMCLK_PIPE2_EN, 1);
    114		break;
    115	case 3:
    116		REG_UPDATE(DPSTREAMCLK_CNTL,
    117				DPSTREAMCLK_PIPE3_EN, 1);
    118		break;
    119	default:
    120		BREAK_TO_DEBUGGER();
    121		return;
    122	}
    123	if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpstream)
    124		REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
    125			DPSTREAMCLK_GATE_DISABLE, 1,
    126			DPSTREAMCLK_ROOT_GATE_DISABLE, 1);
    127}
    128
    129static void dccg31_disable_dpstreamclk(struct dccg *dccg, int otg_inst)
    130{
    131	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
    132
    133	if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpstream)
    134		REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
    135				DPSTREAMCLK_ROOT_GATE_DISABLE, 0,
    136				DPSTREAMCLK_GATE_DISABLE, 0);
    137
    138	switch (otg_inst) {
    139	case 0:
    140		REG_UPDATE(DPSTREAMCLK_CNTL,
    141				DPSTREAMCLK_PIPE0_EN, 0);
    142		break;
    143	case 1:
    144		REG_UPDATE(DPSTREAMCLK_CNTL,
    145				DPSTREAMCLK_PIPE1_EN, 0);
    146		break;
    147	case 2:
    148		REG_UPDATE(DPSTREAMCLK_CNTL,
    149				DPSTREAMCLK_PIPE2_EN, 0);
    150		break;
    151	case 3:
    152		REG_UPDATE(DPSTREAMCLK_CNTL,
    153				DPSTREAMCLK_PIPE3_EN, 0);
    154		break;
    155	default:
    156		BREAK_TO_DEBUGGER();
    157		return;
    158	}
    159}
    160
    161void dccg31_set_dpstreamclk(
    162		struct dccg *dccg,
    163		enum hdmistreamclk_source src,
    164		int otg_inst)
    165{
    166	if (src == REFCLK)
    167		dccg31_disable_dpstreamclk(dccg, otg_inst);
    168	else
    169		dccg31_enable_dpstreamclk(dccg, otg_inst);
    170}
    171
    172void dccg31_enable_symclk32_se(
    173		struct dccg *dccg,
    174		int hpo_se_inst,
    175		enum phyd32clk_clock_source phyd32clk)
    176{
    177	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
    178
    179	phyd32clk = get_phy_mux_symclk(dccg_dcn, phyd32clk);
    180
    181	/* select one of the PHYD32CLKs as the source for symclk32_se */
    182	switch (hpo_se_inst) {
    183	case 0:
    184		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
    185			REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
    186					SYMCLK32_SE0_GATE_DISABLE, 1,
    187					SYMCLK32_ROOT_SE0_GATE_DISABLE, 1);
    188		REG_UPDATE_2(SYMCLK32_SE_CNTL,
    189				SYMCLK32_SE0_SRC_SEL, phyd32clk,
    190				SYMCLK32_SE0_EN, 1);
    191		break;
    192	case 1:
    193		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
    194			REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
    195					SYMCLK32_SE1_GATE_DISABLE, 1,
    196					SYMCLK32_ROOT_SE1_GATE_DISABLE, 1);
    197		REG_UPDATE_2(SYMCLK32_SE_CNTL,
    198				SYMCLK32_SE1_SRC_SEL, phyd32clk,
    199				SYMCLK32_SE1_EN, 1);
    200		break;
    201	case 2:
    202		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
    203			REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
    204					SYMCLK32_SE2_GATE_DISABLE, 1,
    205					SYMCLK32_ROOT_SE2_GATE_DISABLE, 1);
    206		REG_UPDATE_2(SYMCLK32_SE_CNTL,
    207				SYMCLK32_SE2_SRC_SEL, phyd32clk,
    208				SYMCLK32_SE2_EN, 1);
    209		break;
    210	case 3:
    211		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
    212			REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
    213					SYMCLK32_SE3_GATE_DISABLE, 1,
    214					SYMCLK32_ROOT_SE3_GATE_DISABLE, 1);
    215		REG_UPDATE_2(SYMCLK32_SE_CNTL,
    216				SYMCLK32_SE3_SRC_SEL, phyd32clk,
    217				SYMCLK32_SE3_EN, 1);
    218		break;
    219	default:
    220		BREAK_TO_DEBUGGER();
    221		return;
    222	}
    223}
    224
    225void dccg31_disable_symclk32_se(
    226		struct dccg *dccg,
    227		int hpo_se_inst)
    228{
    229	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
    230
    231	/* set refclk as the source for symclk32_se */
    232	switch (hpo_se_inst) {
    233	case 0:
    234		REG_UPDATE_2(SYMCLK32_SE_CNTL,
    235				SYMCLK32_SE0_SRC_SEL, 0,
    236				SYMCLK32_SE0_EN, 0);
    237		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
    238			REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
    239					SYMCLK32_SE0_GATE_DISABLE, 0,
    240					SYMCLK32_ROOT_SE0_GATE_DISABLE, 0);
    241		break;
    242	case 1:
    243		REG_UPDATE_2(SYMCLK32_SE_CNTL,
    244				SYMCLK32_SE1_SRC_SEL, 0,
    245				SYMCLK32_SE1_EN, 0);
    246		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
    247			REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
    248					SYMCLK32_SE1_GATE_DISABLE, 0,
    249					SYMCLK32_ROOT_SE1_GATE_DISABLE, 0);
    250		break;
    251	case 2:
    252		REG_UPDATE_2(SYMCLK32_SE_CNTL,
    253				SYMCLK32_SE2_SRC_SEL, 0,
    254				SYMCLK32_SE2_EN, 0);
    255		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
    256			REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
    257					SYMCLK32_SE2_GATE_DISABLE, 0,
    258					SYMCLK32_ROOT_SE2_GATE_DISABLE, 0);
    259		break;
    260	case 3:
    261		REG_UPDATE_2(SYMCLK32_SE_CNTL,
    262				SYMCLK32_SE3_SRC_SEL, 0,
    263				SYMCLK32_SE3_EN, 0);
    264		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
    265			REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
    266					SYMCLK32_SE3_GATE_DISABLE, 0,
    267					SYMCLK32_ROOT_SE3_GATE_DISABLE, 0);
    268		break;
    269	default:
    270		BREAK_TO_DEBUGGER();
    271		return;
    272	}
    273}
    274
    275void dccg31_enable_symclk32_le(
    276		struct dccg *dccg,
    277		int hpo_le_inst,
    278		enum phyd32clk_clock_source phyd32clk)
    279{
    280	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
    281
    282	phyd32clk = get_phy_mux_symclk(dccg_dcn, phyd32clk);
    283
    284	/* select one of the PHYD32CLKs as the source for symclk32_le */
    285	switch (hpo_le_inst) {
    286	case 0:
    287		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le)
    288			REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
    289					SYMCLK32_LE0_GATE_DISABLE, 1,
    290					SYMCLK32_ROOT_LE0_GATE_DISABLE, 1);
    291		REG_UPDATE_2(SYMCLK32_LE_CNTL,
    292				SYMCLK32_LE0_SRC_SEL, phyd32clk,
    293				SYMCLK32_LE0_EN, 1);
    294		break;
    295	case 1:
    296		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le)
    297			REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
    298					SYMCLK32_LE1_GATE_DISABLE, 1,
    299					SYMCLK32_ROOT_LE1_GATE_DISABLE, 1);
    300		REG_UPDATE_2(SYMCLK32_LE_CNTL,
    301				SYMCLK32_LE1_SRC_SEL, phyd32clk,
    302				SYMCLK32_LE1_EN, 1);
    303		break;
    304	default:
    305		BREAK_TO_DEBUGGER();
    306		return;
    307	}
    308}
    309
    310void dccg31_disable_symclk32_le(
    311		struct dccg *dccg,
    312		int hpo_le_inst)
    313{
    314	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
    315
    316	/* set refclk as the source for symclk32_le */
    317	switch (hpo_le_inst) {
    318	case 0:
    319		REG_UPDATE_2(SYMCLK32_LE_CNTL,
    320				SYMCLK32_LE0_SRC_SEL, 0,
    321				SYMCLK32_LE0_EN, 0);
    322		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le)
    323			REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
    324					SYMCLK32_LE0_GATE_DISABLE, 0,
    325					SYMCLK32_ROOT_LE0_GATE_DISABLE, 0);
    326		break;
    327	case 1:
    328		REG_UPDATE_2(SYMCLK32_LE_CNTL,
    329				SYMCLK32_LE1_SRC_SEL, 0,
    330				SYMCLK32_LE1_EN, 0);
    331		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le)
    332			REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
    333					SYMCLK32_LE1_GATE_DISABLE, 0,
    334					SYMCLK32_ROOT_LE1_GATE_DISABLE, 0);
    335		break;
    336	default:
    337		BREAK_TO_DEBUGGER();
    338		return;
    339	}
    340}
    341
    342static void dccg31_disable_dscclk(struct dccg *dccg, int inst)
    343{
    344	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
    345
    346	if (!dccg->ctx->dc->debug.root_clock_optimization.bits.dsc)
    347		return;
    348	//DTO must be enabled to generate a 0 Hz clock output
    349	switch (inst) {
    350	case 0:
    351		REG_UPDATE(DSCCLK_DTO_CTRL,
    352				DSCCLK0_DTO_ENABLE, 1);
    353		REG_UPDATE_2(DSCCLK0_DTO_PARAM,
    354				DSCCLK0_DTO_PHASE, 0,
    355				DSCCLK0_DTO_MODULO, 1);
    356		break;
    357	case 1:
    358		REG_UPDATE(DSCCLK_DTO_CTRL,
    359				DSCCLK1_DTO_ENABLE, 1);
    360		REG_UPDATE_2(DSCCLK1_DTO_PARAM,
    361				DSCCLK1_DTO_PHASE, 0,
    362				DSCCLK1_DTO_MODULO, 1);
    363		break;
    364	case 2:
    365		REG_UPDATE(DSCCLK_DTO_CTRL,
    366				DSCCLK2_DTO_ENABLE, 1);
    367		REG_UPDATE_2(DSCCLK2_DTO_PARAM,
    368				DSCCLK2_DTO_PHASE, 0,
    369				DSCCLK2_DTO_MODULO, 1);
    370		break;
    371	default:
    372		BREAK_TO_DEBUGGER();
    373		return;
    374	}
    375}
    376
    377static void dccg31_enable_dscclk(struct dccg *dccg, int inst)
    378{
    379	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
    380
    381	if (!dccg->ctx->dc->debug.root_clock_optimization.bits.dsc)
    382		return;
    383	//Disable DTO
    384	switch (inst) {
    385	case 0:
    386		REG_UPDATE_2(DSCCLK0_DTO_PARAM,
    387				DSCCLK0_DTO_PHASE, 0,
    388				DSCCLK0_DTO_MODULO, 0);
    389		REG_UPDATE(DSCCLK_DTO_CTRL,
    390				DSCCLK0_DTO_ENABLE, 0);
    391		break;
    392	case 1:
    393		REG_UPDATE_2(DSCCLK1_DTO_PARAM,
    394				DSCCLK1_DTO_PHASE, 0,
    395				DSCCLK1_DTO_MODULO, 0);
    396		REG_UPDATE(DSCCLK_DTO_CTRL,
    397				DSCCLK1_DTO_ENABLE, 0);
    398		break;
    399	case 2:
    400		REG_UPDATE_2(DSCCLK2_DTO_PARAM,
    401				DSCCLK2_DTO_PHASE, 0,
    402				DSCCLK2_DTO_MODULO, 0);
    403		REG_UPDATE(DSCCLK_DTO_CTRL,
    404				DSCCLK2_DTO_ENABLE, 0);
    405		break;
    406	default:
    407		BREAK_TO_DEBUGGER();
    408		return;
    409	}
    410}
    411
    412void dccg31_set_physymclk(
    413		struct dccg *dccg,
    414		int phy_inst,
    415		enum physymclk_clock_source clk_src,
    416		bool force_enable)
    417{
    418	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
    419
    420	/* Force PHYSYMCLK on and Select phyd32clk as the source of clock which is output to PHY through DCIO */
    421	switch (phy_inst) {
    422	case 0:
    423		if (force_enable) {
    424			REG_UPDATE_2(PHYASYMCLK_CLOCK_CNTL,
    425					PHYASYMCLK_FORCE_EN, 1,
    426					PHYASYMCLK_FORCE_SRC_SEL, clk_src);
    427			if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
    428				REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
    429					PHYASYMCLK_GATE_DISABLE, 1);
    430		} else {
    431			REG_UPDATE_2(PHYASYMCLK_CLOCK_CNTL,
    432					PHYASYMCLK_FORCE_EN, 0,
    433					PHYASYMCLK_FORCE_SRC_SEL, 0);
    434			if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
    435				REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
    436					PHYASYMCLK_GATE_DISABLE, 0);
    437		}
    438		break;
    439	case 1:
    440		if (force_enable) {
    441			REG_UPDATE_2(PHYBSYMCLK_CLOCK_CNTL,
    442					PHYBSYMCLK_FORCE_EN, 1,
    443					PHYBSYMCLK_FORCE_SRC_SEL, clk_src);
    444			if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
    445				REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
    446					PHYBSYMCLK_GATE_DISABLE, 1);
    447		} else {
    448			REG_UPDATE_2(PHYBSYMCLK_CLOCK_CNTL,
    449					PHYBSYMCLK_FORCE_EN, 0,
    450					PHYBSYMCLK_FORCE_SRC_SEL, 0);
    451			if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
    452				REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
    453					PHYBSYMCLK_GATE_DISABLE, 0);
    454		}
    455		break;
    456	case 2:
    457		if (force_enable) {
    458			REG_UPDATE_2(PHYCSYMCLK_CLOCK_CNTL,
    459					PHYCSYMCLK_FORCE_EN, 1,
    460					PHYCSYMCLK_FORCE_SRC_SEL, clk_src);
    461			if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
    462				REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
    463					PHYCSYMCLK_GATE_DISABLE, 1);
    464		} else {
    465			REG_UPDATE_2(PHYCSYMCLK_CLOCK_CNTL,
    466					PHYCSYMCLK_FORCE_EN, 0,
    467					PHYCSYMCLK_FORCE_SRC_SEL, 0);
    468			if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
    469				REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
    470					PHYCSYMCLK_GATE_DISABLE, 0);
    471		}
    472		break;
    473	case 3:
    474		if (force_enable) {
    475			REG_UPDATE_2(PHYDSYMCLK_CLOCK_CNTL,
    476					PHYDSYMCLK_FORCE_EN, 1,
    477					PHYDSYMCLK_FORCE_SRC_SEL, clk_src);
    478			if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
    479				REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
    480					PHYDSYMCLK_GATE_DISABLE, 1);
    481		} else {
    482			REG_UPDATE_2(PHYDSYMCLK_CLOCK_CNTL,
    483					PHYDSYMCLK_FORCE_EN, 0,
    484					PHYDSYMCLK_FORCE_SRC_SEL, 0);
    485			if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
    486				REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
    487					PHYDSYMCLK_GATE_DISABLE, 0);
    488		}
    489		break;
    490	case 4:
    491		if (force_enable) {
    492			REG_UPDATE_2(PHYESYMCLK_CLOCK_CNTL,
    493					PHYESYMCLK_FORCE_EN, 1,
    494					PHYESYMCLK_FORCE_SRC_SEL, clk_src);
    495			if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
    496				REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
    497					PHYESYMCLK_GATE_DISABLE, 1);
    498		} else {
    499			REG_UPDATE_2(PHYESYMCLK_CLOCK_CNTL,
    500					PHYESYMCLK_FORCE_EN, 0,
    501					PHYESYMCLK_FORCE_SRC_SEL, 0);
    502			if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
    503				REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
    504					PHYESYMCLK_GATE_DISABLE, 0);
    505		}
    506		break;
    507	default:
    508		BREAK_TO_DEBUGGER();
    509		return;
    510	}
    511}
    512
    513/* Controls the generation of pixel valid for OTG in (OTG -> HPO case) */
    514static void dccg31_set_dtbclk_dto(
    515		struct dccg *dccg,
    516		struct dtbclk_dto_params *params)
    517{
    518	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
    519	int req_dtbclk_khz = params->pixclk_khz;
    520	uint32_t dtbdto_div;
    521
    522	/* Mode	                DTBDTO Rate       DTBCLK_DTO<x>_DIV Register
    523	 * ODM 4:1 combine      pixel rate/4      2
    524	 * ODM 2:1 combine      pixel rate/2      4
    525	 * non-DSC 4:2:0 mode   pixel rate/2      4
    526	 * DSC native 4:2:0     pixel rate/2      4
    527	 * DSC native 4:2:2     pixel rate/2      4
    528	 * Other modes          pixel rate        8
    529	 */
    530	if (params->num_odm_segments == 4) {
    531		dtbdto_div = 2;
    532		req_dtbclk_khz = params->pixclk_khz / 4;
    533	} else if ((params->num_odm_segments == 2) ||
    534			(params->timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) ||
    535			(params->timing->flags.DSC && params->timing->pixel_encoding == PIXEL_ENCODING_YCBCR422
    536					&& !params->timing->dsc_cfg.ycbcr422_simple)) {
    537		dtbdto_div = 4;
    538		req_dtbclk_khz = params->pixclk_khz / 2;
    539	} else
    540		dtbdto_div = 8;
    541
    542	if (params->ref_dtbclk_khz && req_dtbclk_khz) {
    543		uint32_t modulo, phase;
    544
    545		// phase / modulo = dtbclk / dtbclk ref
    546		modulo = params->ref_dtbclk_khz * 1000;
    547		phase = div_u64((((unsigned long long)modulo * req_dtbclk_khz) + params->ref_dtbclk_khz - 1),
    548				params->ref_dtbclk_khz);
    549
    550		REG_UPDATE(OTG_PIXEL_RATE_CNTL[params->otg_inst],
    551				DTBCLK_DTO_DIV[params->otg_inst], dtbdto_div);
    552
    553		REG_WRITE(DTBCLK_DTO_MODULO[params->otg_inst], modulo);
    554		REG_WRITE(DTBCLK_DTO_PHASE[params->otg_inst], phase);
    555
    556		REG_UPDATE(OTG_PIXEL_RATE_CNTL[params->otg_inst],
    557				DTBCLK_DTO_ENABLE[params->otg_inst], 1);
    558
    559		REG_WAIT(OTG_PIXEL_RATE_CNTL[params->otg_inst],
    560				DTBCLKDTO_ENABLE_STATUS[params->otg_inst], 1,
    561				1, 100);
    562
    563		/* The recommended programming sequence to enable DTBCLK DTO to generate
    564		 * valid pixel HPO DPSTREAM ENCODER, specifies that DTO source select should
    565		 * be set only after DTO is enabled
    566		 */
    567		REG_UPDATE(OTG_PIXEL_RATE_CNTL[params->otg_inst],
    568				PIPE_DTO_SRC_SEL[params->otg_inst], 1);
    569	} else {
    570		REG_UPDATE_3(OTG_PIXEL_RATE_CNTL[params->otg_inst],
    571				DTBCLK_DTO_ENABLE[params->otg_inst], 0,
    572				PIPE_DTO_SRC_SEL[params->otg_inst], 0,
    573				DTBCLK_DTO_DIV[params->otg_inst], dtbdto_div);
    574
    575		REG_WRITE(DTBCLK_DTO_MODULO[params->otg_inst], 0);
    576		REG_WRITE(DTBCLK_DTO_PHASE[params->otg_inst], 0);
    577	}
    578}
    579
    580void dccg31_set_audio_dtbclk_dto(
    581		struct dccg *dccg,
    582		uint32_t req_audio_dtbclk_khz)
    583{
    584	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
    585
    586	if (dccg->ref_dtbclk_khz && req_audio_dtbclk_khz) {
    587		uint32_t modulo, phase;
    588
    589		// phase / modulo = dtbclk / dtbclk ref
    590		modulo = dccg->ref_dtbclk_khz * 1000;
    591		phase = div_u64((((unsigned long long)modulo * req_audio_dtbclk_khz) + dccg->ref_dtbclk_khz - 1),
    592			dccg->ref_dtbclk_khz);
    593
    594
    595		REG_WRITE(DCCG_AUDIO_DTBCLK_DTO_MODULO, modulo);
    596		REG_WRITE(DCCG_AUDIO_DTBCLK_DTO_PHASE, phase);
    597
    598		//REG_UPDATE(DCCG_AUDIO_DTO_SOURCE,
    599		//		DCCG_AUDIO_DTBCLK_DTO_USE_512FBR_DTO, 1);
    600
    601		REG_UPDATE(DCCG_AUDIO_DTO_SOURCE,
    602				DCCG_AUDIO_DTO_SEL, 4);  //  04 - DCCG_AUDIO_DTO_SEL_AUDIO_DTO_DTBCLK
    603	} else {
    604		REG_WRITE(DCCG_AUDIO_DTBCLK_DTO_PHASE, 0);
    605		REG_WRITE(DCCG_AUDIO_DTBCLK_DTO_MODULO, 0);
    606
    607		REG_UPDATE(DCCG_AUDIO_DTO_SOURCE,
    608				DCCG_AUDIO_DTO_SEL, 3);  //  03 - DCCG_AUDIO_DTO_SEL_NO_AUDIO_DTO
    609	}
    610}
    611
    612static void dccg31_get_dccg_ref_freq(struct dccg *dccg,
    613		unsigned int xtalin_freq_inKhz,
    614		unsigned int *dccg_ref_freq_inKhz)
    615{
    616	/*
    617	 * Assume refclk is sourced from xtalin
    618	 * expect 24MHz
    619	 */
    620	*dccg_ref_freq_inKhz = xtalin_freq_inKhz;
    621	return;
    622}
    623
    624static void dccg31_set_dispclk_change_mode(
    625	struct dccg *dccg,
    626	enum dentist_dispclk_change_mode change_mode)
    627{
    628	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
    629
    630	REG_UPDATE(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_CHG_MODE,
    631		   change_mode == DISPCLK_CHANGE_MODE_RAMPING ? 2 : 0);
    632}
    633
    634void dccg31_init(struct dccg *dccg)
    635{
    636	/* Set HPO stream encoder to use refclk to avoid case where PHY is
    637	 * disabled and SYMCLK32 for HPO SE is sourced from PHYD32CLK which
    638	 * will cause DCN to hang.
    639	 */
    640	dccg31_disable_symclk32_se(dccg, 0);
    641	dccg31_disable_symclk32_se(dccg, 1);
    642	dccg31_disable_symclk32_se(dccg, 2);
    643	dccg31_disable_symclk32_se(dccg, 3);
    644
    645	if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le) {
    646		dccg31_disable_symclk32_le(dccg, 0);
    647		dccg31_disable_symclk32_le(dccg, 1);
    648	}
    649
    650	if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpstream) {
    651		dccg31_disable_dpstreamclk(dccg, 0);
    652		dccg31_disable_dpstreamclk(dccg, 1);
    653		dccg31_disable_dpstreamclk(dccg, 2);
    654		dccg31_disable_dpstreamclk(dccg, 3);
    655	}
    656
    657	if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk) {
    658		dccg31_set_physymclk(dccg, 0, PHYSYMCLK_FORCE_SRC_SYMCLK, false);
    659		dccg31_set_physymclk(dccg, 1, PHYSYMCLK_FORCE_SRC_SYMCLK, false);
    660		dccg31_set_physymclk(dccg, 2, PHYSYMCLK_FORCE_SRC_SYMCLK, false);
    661		dccg31_set_physymclk(dccg, 3, PHYSYMCLK_FORCE_SRC_SYMCLK, false);
    662		dccg31_set_physymclk(dccg, 4, PHYSYMCLK_FORCE_SRC_SYMCLK, false);
    663	}
    664}
    665
    666static const struct dccg_funcs dccg31_funcs = {
    667	.update_dpp_dto = dccg31_update_dpp_dto,
    668	.get_dccg_ref_freq = dccg31_get_dccg_ref_freq,
    669	.dccg_init = dccg31_init,
    670	.set_dpstreamclk = dccg31_set_dpstreamclk,
    671	.enable_symclk32_se = dccg31_enable_symclk32_se,
    672	.disable_symclk32_se = dccg31_disable_symclk32_se,
    673	.enable_symclk32_le = dccg31_enable_symclk32_le,
    674	.disable_symclk32_le = dccg31_disable_symclk32_le,
    675	.set_physymclk = dccg31_set_physymclk,
    676	.set_dtbclk_dto = dccg31_set_dtbclk_dto,
    677	.set_audio_dtbclk_dto = dccg31_set_audio_dtbclk_dto,
    678	.set_dispclk_change_mode = dccg31_set_dispclk_change_mode,
    679	.disable_dsc = dccg31_disable_dscclk,
    680	.enable_dsc = dccg31_enable_dscclk,
    681};
    682
    683struct dccg *dccg31_create(
    684	struct dc_context *ctx,
    685	const struct dccg_registers *regs,
    686	const struct dccg_shift *dccg_shift,
    687	const struct dccg_mask *dccg_mask)
    688{
    689	struct dcn_dccg *dccg_dcn = kzalloc(sizeof(*dccg_dcn), GFP_KERNEL);
    690	struct dccg *base;
    691
    692	if (dccg_dcn == NULL) {
    693		BREAK_TO_DEBUGGER();
    694		return NULL;
    695	}
    696
    697	base = &dccg_dcn->base;
    698	base->ctx = ctx;
    699	base->funcs = &dccg31_funcs;
    700
    701	dccg_dcn->regs = regs;
    702	dccg_dcn->dccg_shift = dccg_shift;
    703	dccg_dcn->dccg_mask = dccg_mask;
    704
    705	return &dccg_dcn->base;
    706}