1d8a2b4f3SNicholas Kazlauskas /*
2d8a2b4f3SNicholas Kazlauskas * Copyright 2018 Advanced Micro Devices, Inc.
3d8a2b4f3SNicholas Kazlauskas *
4d8a2b4f3SNicholas Kazlauskas * Permission is hereby granted, free of charge, to any person obtaining a
5d8a2b4f3SNicholas Kazlauskas * copy of this software and associated documentation files (the "Software"),
6d8a2b4f3SNicholas Kazlauskas * to deal in the Software without restriction, including without limitation
7d8a2b4f3SNicholas Kazlauskas * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8d8a2b4f3SNicholas Kazlauskas * and/or sell copies of the Software, and to permit persons to whom the
9d8a2b4f3SNicholas Kazlauskas * Software is furnished to do so, subject to the following conditions:
10d8a2b4f3SNicholas Kazlauskas *
11d8a2b4f3SNicholas Kazlauskas * The above copyright notice and this permission notice shall be included in
12d8a2b4f3SNicholas Kazlauskas * all copies or substantial portions of the Software.
13d8a2b4f3SNicholas Kazlauskas *
14d8a2b4f3SNicholas Kazlauskas * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15d8a2b4f3SNicholas Kazlauskas * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16d8a2b4f3SNicholas Kazlauskas * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17d8a2b4f3SNicholas Kazlauskas * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18d8a2b4f3SNicholas Kazlauskas * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19d8a2b4f3SNicholas Kazlauskas * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20d8a2b4f3SNicholas Kazlauskas * OTHER DEALINGS IN THE SOFTWARE.
21d8a2b4f3SNicholas Kazlauskas *
22d8a2b4f3SNicholas Kazlauskas * Authors: AMD
23d8a2b4f3SNicholas Kazlauskas *
24d8a2b4f3SNicholas Kazlauskas */
25d8a2b4f3SNicholas Kazlauskas
26d8a2b4f3SNicholas Kazlauskas #include "reg_helper.h"
27d8a2b4f3SNicholas Kazlauskas #include "core_types.h"
28d8a2b4f3SNicholas Kazlauskas #include "dcn31_dccg.h"
293cf79bb7SHansen #include "dal_asic_id.h"
30d8a2b4f3SNicholas Kazlauskas
31d8a2b4f3SNicholas Kazlauskas #define TO_DCN_DCCG(dccg)\
32d8a2b4f3SNicholas Kazlauskas container_of(dccg, struct dcn_dccg, base)
33d8a2b4f3SNicholas Kazlauskas
34d8a2b4f3SNicholas Kazlauskas #define REG(reg) \
35d8a2b4f3SNicholas Kazlauskas (dccg_dcn->regs->reg)
36d8a2b4f3SNicholas Kazlauskas
37d8a2b4f3SNicholas Kazlauskas #undef FN
38d8a2b4f3SNicholas Kazlauskas #define FN(reg_name, field_name) \
39d8a2b4f3SNicholas Kazlauskas dccg_dcn->dccg_shift->field_name, dccg_dcn->dccg_mask->field_name
40d8a2b4f3SNicholas Kazlauskas
41d8a2b4f3SNicholas Kazlauskas #define CTX \
42d8a2b4f3SNicholas Kazlauskas dccg_dcn->base.ctx
43d8a2b4f3SNicholas Kazlauskas #define DC_LOGGER \
44d8a2b4f3SNicholas Kazlauskas dccg->ctx->logger
45d8a2b4f3SNicholas Kazlauskas
dccg31_update_dpp_dto(struct dccg * dccg,int dpp_inst,int req_dppclk)46ee7b62e1SRoman Li void dccg31_update_dpp_dto(struct dccg *dccg, int dpp_inst, int req_dppclk)
477a28bee0SJake Wang {
487a28bee0SJake Wang struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
497a28bee0SJake Wang
5030f90f3cSNicholas Kazlauskas if (dccg->dpp_clock_gated[dpp_inst]) {
5130f90f3cSNicholas Kazlauskas /*
5230f90f3cSNicholas Kazlauskas * Do not update the DPPCLK DTO if the clock is stopped.
5330f90f3cSNicholas Kazlauskas * It is treated the same as if the pipe itself were in PG.
5430f90f3cSNicholas Kazlauskas */
5530f90f3cSNicholas Kazlauskas return;
5630f90f3cSNicholas Kazlauskas }
5730f90f3cSNicholas Kazlauskas
587a28bee0SJake Wang if (dccg->ref_dppclk && req_dppclk) {
597a28bee0SJake Wang int ref_dppclk = dccg->ref_dppclk;
607a28bee0SJake Wang int modulo, phase;
617a28bee0SJake Wang
627a28bee0SJake Wang // phase / modulo = dpp pipe clk / dpp global clk
637a28bee0SJake Wang modulo = 0xff; // use FF at the end
647a28bee0SJake Wang phase = ((modulo * req_dppclk) + ref_dppclk - 1) / ref_dppclk;
657a28bee0SJake Wang
667a28bee0SJake Wang if (phase > 0xff) {
677a28bee0SJake Wang ASSERT(false);
687a28bee0SJake Wang phase = 0xff;
697a28bee0SJake Wang }
707a28bee0SJake Wang
717a28bee0SJake Wang REG_SET_2(DPPCLK_DTO_PARAM[dpp_inst], 0,
727a28bee0SJake Wang DPPCLK0_DTO_PHASE, phase,
737a28bee0SJake Wang DPPCLK0_DTO_MODULO, modulo);
747a28bee0SJake Wang REG_UPDATE(DPPCLK_DTO_CTRL,
757a28bee0SJake Wang DPPCLK_DTO_ENABLE[dpp_inst], 1);
767a28bee0SJake Wang } else {
777a28bee0SJake Wang REG_UPDATE(DPPCLK_DTO_CTRL,
787a28bee0SJake Wang DPPCLK_DTO_ENABLE[dpp_inst], 0);
797a28bee0SJake Wang }
807a28bee0SJake Wang dccg->pipe_dppclk_khz[dpp_inst] = req_dppclk;
817a28bee0SJake Wang }
827a28bee0SJake Wang
get_phy_mux_symclk(struct dcn_dccg * dccg_dcn,enum phyd32clk_clock_source src)833cf79bb7SHansen static enum phyd32clk_clock_source get_phy_mux_symclk(
843cf79bb7SHansen struct dcn_dccg *dccg_dcn,
853cf79bb7SHansen enum phyd32clk_clock_source src)
863cf79bb7SHansen {
87*c005a44fSGeorge Shen if (dccg_dcn->base.ctx->asic_id.chip_family == FAMILY_YELLOW_CARP &&
88*c005a44fSGeorge Shen dccg_dcn->base.ctx->asic_id.hw_internal_rev == YELLOW_CARP_B0) {
893cf79bb7SHansen if (src == PHYD32CLKC)
903cf79bb7SHansen src = PHYD32CLKF;
913cf79bb7SHansen if (src == PHYD32CLKD)
923cf79bb7SHansen src = PHYD32CLKG;
933cf79bb7SHansen }
943cf79bb7SHansen return src;
953cf79bb7SHansen }
967a28bee0SJake Wang
dccg31_enable_dpstreamclk(struct dccg * dccg,int otg_inst)97bda24462SJake Wang static void dccg31_enable_dpstreamclk(struct dccg *dccg, int otg_inst)
98d76b12daSFangzhi Zuo {
99d76b12daSFangzhi Zuo struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
100d76b12daSFangzhi Zuo
101d76b12daSFangzhi Zuo /* enabled to select one of the DTBCLKs for pipe */
102d76b12daSFangzhi Zuo switch (otg_inst) {
103d76b12daSFangzhi Zuo case 0:
104d76b12daSFangzhi Zuo REG_UPDATE(DPSTREAMCLK_CNTL,
105bda24462SJake Wang DPSTREAMCLK_PIPE0_EN, 1);
106d76b12daSFangzhi Zuo break;
107d76b12daSFangzhi Zuo case 1:
108d76b12daSFangzhi Zuo REG_UPDATE(DPSTREAMCLK_CNTL,
109bda24462SJake Wang DPSTREAMCLK_PIPE1_EN, 1);
110d76b12daSFangzhi Zuo break;
111d76b12daSFangzhi Zuo case 2:
112d76b12daSFangzhi Zuo REG_UPDATE(DPSTREAMCLK_CNTL,
113bda24462SJake Wang DPSTREAMCLK_PIPE2_EN, 1);
114d76b12daSFangzhi Zuo break;
115d76b12daSFangzhi Zuo case 3:
116d76b12daSFangzhi Zuo REG_UPDATE(DPSTREAMCLK_CNTL,
117bda24462SJake Wang DPSTREAMCLK_PIPE3_EN, 1);
118d76b12daSFangzhi Zuo break;
119d76b12daSFangzhi Zuo default:
120d76b12daSFangzhi Zuo BREAK_TO_DEBUGGER();
121d76b12daSFangzhi Zuo return;
122d76b12daSFangzhi Zuo }
123bda24462SJake Wang if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpstream)
1240015cce5SDavid Galiffi REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
1250015cce5SDavid Galiffi DPSTREAMCLK_GATE_DISABLE, 1,
126bda24462SJake Wang DPSTREAMCLK_ROOT_GATE_DISABLE, 1);
127bda24462SJake Wang }
128bda24462SJake Wang
dccg31_disable_dpstreamclk(struct dccg * dccg,int otg_inst)129bda24462SJake Wang static void dccg31_disable_dpstreamclk(struct dccg *dccg, int otg_inst)
130bda24462SJake Wang {
131bda24462SJake Wang struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
132bda24462SJake Wang
133bda24462SJake Wang if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpstream)
1340015cce5SDavid Galiffi REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
1350015cce5SDavid Galiffi DPSTREAMCLK_ROOT_GATE_DISABLE, 0,
1360015cce5SDavid Galiffi DPSTREAMCLK_GATE_DISABLE, 0);
137bda24462SJake Wang
138bda24462SJake Wang switch (otg_inst) {
139bda24462SJake Wang case 0:
140bda24462SJake Wang REG_UPDATE(DPSTREAMCLK_CNTL,
141bda24462SJake Wang DPSTREAMCLK_PIPE0_EN, 0);
142bda24462SJake Wang break;
143bda24462SJake Wang case 1:
144bda24462SJake Wang REG_UPDATE(DPSTREAMCLK_CNTL,
145bda24462SJake Wang DPSTREAMCLK_PIPE1_EN, 0);
146bda24462SJake Wang break;
147bda24462SJake Wang case 2:
148bda24462SJake Wang REG_UPDATE(DPSTREAMCLK_CNTL,
149bda24462SJake Wang DPSTREAMCLK_PIPE2_EN, 0);
150bda24462SJake Wang break;
151bda24462SJake Wang case 3:
152bda24462SJake Wang REG_UPDATE(DPSTREAMCLK_CNTL,
153bda24462SJake Wang DPSTREAMCLK_PIPE3_EN, 0);
154bda24462SJake Wang break;
155bda24462SJake Wang default:
156bda24462SJake Wang BREAK_TO_DEBUGGER();
157bda24462SJake Wang return;
158bda24462SJake Wang }
159bda24462SJake Wang }
160bda24462SJake Wang
dccg31_set_dpstreamclk(struct dccg * dccg,enum streamclk_source src,int otg_inst,int dp_hpo_inst)1611f5dcb73SMichael Strauss void dccg31_set_dpstreamclk(
1621f5dcb73SMichael Strauss struct dccg *dccg,
163d3dfceb5SAurabindo Pillai enum streamclk_source src,
1641f5dcb73SMichael Strauss int otg_inst,
1651f5dcb73SMichael Strauss int dp_hpo_inst)
166bda24462SJake Wang {
167bda24462SJake Wang if (src == REFCLK)
168bda24462SJake Wang dccg31_disable_dpstreamclk(dccg, otg_inst);
169bda24462SJake Wang else
170bda24462SJake Wang dccg31_enable_dpstreamclk(dccg, otg_inst);
171d76b12daSFangzhi Zuo }
172d76b12daSFangzhi Zuo
dccg31_enable_symclk32_se(struct dccg * dccg,int hpo_se_inst,enum phyd32clk_clock_source phyd32clk)173d76b12daSFangzhi Zuo void dccg31_enable_symclk32_se(
174d76b12daSFangzhi Zuo struct dccg *dccg,
175d76b12daSFangzhi Zuo int hpo_se_inst,
176d76b12daSFangzhi Zuo enum phyd32clk_clock_source phyd32clk)
177d76b12daSFangzhi Zuo {
178d76b12daSFangzhi Zuo struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
179d76b12daSFangzhi Zuo
1803cf79bb7SHansen phyd32clk = get_phy_mux_symclk(dccg_dcn, phyd32clk);
1813cf79bb7SHansen
182d76b12daSFangzhi Zuo /* select one of the PHYD32CLKs as the source for symclk32_se */
183d76b12daSFangzhi Zuo switch (hpo_se_inst) {
184d76b12daSFangzhi Zuo case 0:
185bda24462SJake Wang if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
1860015cce5SDavid Galiffi REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
1870015cce5SDavid Galiffi SYMCLK32_SE0_GATE_DISABLE, 1,
188bda24462SJake Wang SYMCLK32_ROOT_SE0_GATE_DISABLE, 1);
189d76b12daSFangzhi Zuo REG_UPDATE_2(SYMCLK32_SE_CNTL,
190d76b12daSFangzhi Zuo SYMCLK32_SE0_SRC_SEL, phyd32clk,
191d76b12daSFangzhi Zuo SYMCLK32_SE0_EN, 1);
192d76b12daSFangzhi Zuo break;
193d76b12daSFangzhi Zuo case 1:
194bda24462SJake Wang if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
1950015cce5SDavid Galiffi REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
1960015cce5SDavid Galiffi SYMCLK32_SE1_GATE_DISABLE, 1,
197bda24462SJake Wang SYMCLK32_ROOT_SE1_GATE_DISABLE, 1);
198d76b12daSFangzhi Zuo REG_UPDATE_2(SYMCLK32_SE_CNTL,
199d76b12daSFangzhi Zuo SYMCLK32_SE1_SRC_SEL, phyd32clk,
200d76b12daSFangzhi Zuo SYMCLK32_SE1_EN, 1);
201d76b12daSFangzhi Zuo break;
202d76b12daSFangzhi Zuo case 2:
203bda24462SJake Wang if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
2040015cce5SDavid Galiffi REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
2050015cce5SDavid Galiffi SYMCLK32_SE2_GATE_DISABLE, 1,
206bda24462SJake Wang SYMCLK32_ROOT_SE2_GATE_DISABLE, 1);
207d76b12daSFangzhi Zuo REG_UPDATE_2(SYMCLK32_SE_CNTL,
208d76b12daSFangzhi Zuo SYMCLK32_SE2_SRC_SEL, phyd32clk,
209d76b12daSFangzhi Zuo SYMCLK32_SE2_EN, 1);
210d76b12daSFangzhi Zuo break;
211d76b12daSFangzhi Zuo case 3:
212bda24462SJake Wang if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
2130015cce5SDavid Galiffi REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
2140015cce5SDavid Galiffi SYMCLK32_SE3_GATE_DISABLE, 1,
215bda24462SJake Wang SYMCLK32_ROOT_SE3_GATE_DISABLE, 1);
216d76b12daSFangzhi Zuo REG_UPDATE_2(SYMCLK32_SE_CNTL,
217d76b12daSFangzhi Zuo SYMCLK32_SE3_SRC_SEL, phyd32clk,
218d76b12daSFangzhi Zuo SYMCLK32_SE3_EN, 1);
219d76b12daSFangzhi Zuo break;
220d76b12daSFangzhi Zuo default:
221d76b12daSFangzhi Zuo BREAK_TO_DEBUGGER();
222d76b12daSFangzhi Zuo return;
223d76b12daSFangzhi Zuo }
224d76b12daSFangzhi Zuo }
225d76b12daSFangzhi Zuo
dccg31_disable_symclk32_se(struct dccg * dccg,int hpo_se_inst)226d76b12daSFangzhi Zuo void dccg31_disable_symclk32_se(
227d76b12daSFangzhi Zuo struct dccg *dccg,
228d76b12daSFangzhi Zuo int hpo_se_inst)
229d76b12daSFangzhi Zuo {
230d76b12daSFangzhi Zuo struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
231d76b12daSFangzhi Zuo
232d76b12daSFangzhi Zuo /* set refclk as the source for symclk32_se */
233d76b12daSFangzhi Zuo switch (hpo_se_inst) {
234d76b12daSFangzhi Zuo case 0:
235d76b12daSFangzhi Zuo REG_UPDATE_2(SYMCLK32_SE_CNTL,
236d76b12daSFangzhi Zuo SYMCLK32_SE0_SRC_SEL, 0,
237d76b12daSFangzhi Zuo SYMCLK32_SE0_EN, 0);
238bda24462SJake Wang if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
2390015cce5SDavid Galiffi REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
2400015cce5SDavid Galiffi SYMCLK32_SE0_GATE_DISABLE, 0,
241bda24462SJake Wang SYMCLK32_ROOT_SE0_GATE_DISABLE, 0);
242d76b12daSFangzhi Zuo break;
243d76b12daSFangzhi Zuo case 1:
244d76b12daSFangzhi Zuo REG_UPDATE_2(SYMCLK32_SE_CNTL,
245d76b12daSFangzhi Zuo SYMCLK32_SE1_SRC_SEL, 0,
246d76b12daSFangzhi Zuo SYMCLK32_SE1_EN, 0);
247bda24462SJake Wang if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
2480015cce5SDavid Galiffi REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
2490015cce5SDavid Galiffi SYMCLK32_SE1_GATE_DISABLE, 0,
250bda24462SJake Wang SYMCLK32_ROOT_SE1_GATE_DISABLE, 0);
251d76b12daSFangzhi Zuo break;
252d76b12daSFangzhi Zuo case 2:
253d76b12daSFangzhi Zuo REG_UPDATE_2(SYMCLK32_SE_CNTL,
254d76b12daSFangzhi Zuo SYMCLK32_SE2_SRC_SEL, 0,
255d76b12daSFangzhi Zuo SYMCLK32_SE2_EN, 0);
256bda24462SJake Wang if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
2570015cce5SDavid Galiffi REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
2580015cce5SDavid Galiffi SYMCLK32_SE2_GATE_DISABLE, 0,
259bda24462SJake Wang SYMCLK32_ROOT_SE2_GATE_DISABLE, 0);
260d76b12daSFangzhi Zuo break;
261d76b12daSFangzhi Zuo case 3:
262d76b12daSFangzhi Zuo REG_UPDATE_2(SYMCLK32_SE_CNTL,
263d76b12daSFangzhi Zuo SYMCLK32_SE3_SRC_SEL, 0,
264d76b12daSFangzhi Zuo SYMCLK32_SE3_EN, 0);
265bda24462SJake Wang if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
2660015cce5SDavid Galiffi REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
2670015cce5SDavid Galiffi SYMCLK32_SE3_GATE_DISABLE, 0,
268bda24462SJake Wang SYMCLK32_ROOT_SE3_GATE_DISABLE, 0);
269d76b12daSFangzhi Zuo break;
270d76b12daSFangzhi Zuo default:
271d76b12daSFangzhi Zuo BREAK_TO_DEBUGGER();
272d76b12daSFangzhi Zuo return;
273d76b12daSFangzhi Zuo }
274d76b12daSFangzhi Zuo }
275d76b12daSFangzhi Zuo
dccg31_enable_symclk32_le(struct dccg * dccg,int hpo_le_inst,enum phyd32clk_clock_source phyd32clk)276d76b12daSFangzhi Zuo void dccg31_enable_symclk32_le(
277d76b12daSFangzhi Zuo struct dccg *dccg,
278d76b12daSFangzhi Zuo int hpo_le_inst,
279d76b12daSFangzhi Zuo enum phyd32clk_clock_source phyd32clk)
280d76b12daSFangzhi Zuo {
281d76b12daSFangzhi Zuo struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
282d76b12daSFangzhi Zuo
2833cf79bb7SHansen phyd32clk = get_phy_mux_symclk(dccg_dcn, phyd32clk);
2843cf79bb7SHansen
285d76b12daSFangzhi Zuo /* select one of the PHYD32CLKs as the source for symclk32_le */
286d76b12daSFangzhi Zuo switch (hpo_le_inst) {
287d76b12daSFangzhi Zuo case 0:
288d76b12daSFangzhi Zuo REG_UPDATE_2(SYMCLK32_LE_CNTL,
289d76b12daSFangzhi Zuo SYMCLK32_LE0_SRC_SEL, phyd32clk,
290d76b12daSFangzhi Zuo SYMCLK32_LE0_EN, 1);
291d76b12daSFangzhi Zuo break;
292d76b12daSFangzhi Zuo case 1:
293d76b12daSFangzhi Zuo REG_UPDATE_2(SYMCLK32_LE_CNTL,
294d76b12daSFangzhi Zuo SYMCLK32_LE1_SRC_SEL, phyd32clk,
295d76b12daSFangzhi Zuo SYMCLK32_LE1_EN, 1);
296d76b12daSFangzhi Zuo break;
297d76b12daSFangzhi Zuo default:
298d76b12daSFangzhi Zuo BREAK_TO_DEBUGGER();
299d76b12daSFangzhi Zuo return;
300d76b12daSFangzhi Zuo }
301d76b12daSFangzhi Zuo }
302d76b12daSFangzhi Zuo
dccg31_disable_symclk32_le(struct dccg * dccg,int hpo_le_inst)303d76b12daSFangzhi Zuo void dccg31_disable_symclk32_le(
304d76b12daSFangzhi Zuo struct dccg *dccg,
305d76b12daSFangzhi Zuo int hpo_le_inst)
306d76b12daSFangzhi Zuo {
307d76b12daSFangzhi Zuo struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
308d76b12daSFangzhi Zuo
309d76b12daSFangzhi Zuo /* set refclk as the source for symclk32_le */
310d76b12daSFangzhi Zuo switch (hpo_le_inst) {
311d76b12daSFangzhi Zuo case 0:
312d76b12daSFangzhi Zuo REG_UPDATE_2(SYMCLK32_LE_CNTL,
313d76b12daSFangzhi Zuo SYMCLK32_LE0_SRC_SEL, 0,
314d76b12daSFangzhi Zuo SYMCLK32_LE0_EN, 0);
315d76b12daSFangzhi Zuo break;
316d76b12daSFangzhi Zuo case 1:
317d76b12daSFangzhi Zuo REG_UPDATE_2(SYMCLK32_LE_CNTL,
318d76b12daSFangzhi Zuo SYMCLK32_LE1_SRC_SEL, 0,
319d76b12daSFangzhi Zuo SYMCLK32_LE1_EN, 0);
3203a87e25aSDaniel Miess break;
3213a87e25aSDaniel Miess default:
3223a87e25aSDaniel Miess BREAK_TO_DEBUGGER();
3233a87e25aSDaniel Miess return;
3243a87e25aSDaniel Miess }
3253a87e25aSDaniel Miess }
3263a87e25aSDaniel Miess
dccg31_set_symclk32_le_root_clock_gating(struct dccg * dccg,int hpo_le_inst,bool enable)3273a87e25aSDaniel Miess void dccg31_set_symclk32_le_root_clock_gating(
3283a87e25aSDaniel Miess struct dccg *dccg,
3293a87e25aSDaniel Miess int hpo_le_inst,
3303a87e25aSDaniel Miess bool enable)
3313a87e25aSDaniel Miess {
3323a87e25aSDaniel Miess struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
3333a87e25aSDaniel Miess
3343a87e25aSDaniel Miess if (!dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le)
3353a87e25aSDaniel Miess return;
3363a87e25aSDaniel Miess
3373a87e25aSDaniel Miess switch (hpo_le_inst) {
3383a87e25aSDaniel Miess case 0:
3390015cce5SDavid Galiffi REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
3403a87e25aSDaniel Miess SYMCLK32_LE0_GATE_DISABLE, enable ? 1 : 0,
3413a87e25aSDaniel Miess SYMCLK32_ROOT_LE0_GATE_DISABLE, enable ? 1 : 0);
3423a87e25aSDaniel Miess break;
3433a87e25aSDaniel Miess case 1:
3443a87e25aSDaniel Miess REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
3453a87e25aSDaniel Miess SYMCLK32_LE1_GATE_DISABLE, enable ? 1 : 0,
3463a87e25aSDaniel Miess SYMCLK32_ROOT_LE1_GATE_DISABLE, enable ? 1 : 0);
347d76b12daSFangzhi Zuo break;
348d76b12daSFangzhi Zuo default:
349d76b12daSFangzhi Zuo BREAK_TO_DEBUGGER();
350d76b12daSFangzhi Zuo return;
351d76b12daSFangzhi Zuo }
352d76b12daSFangzhi Zuo }
353d76b12daSFangzhi Zuo
dccg31_disable_dscclk(struct dccg * dccg,int inst)354ee7b62e1SRoman Li void dccg31_disable_dscclk(struct dccg *dccg, int inst)
355e22ad7e3SJake Wang {
356e22ad7e3SJake Wang struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
357e22ad7e3SJake Wang
358e22ad7e3SJake Wang if (!dccg->ctx->dc->debug.root_clock_optimization.bits.dsc)
359e22ad7e3SJake Wang return;
360e22ad7e3SJake Wang //DTO must be enabled to generate a 0 Hz clock output
361e22ad7e3SJake Wang switch (inst) {
362e22ad7e3SJake Wang case 0:
363e22ad7e3SJake Wang REG_UPDATE(DSCCLK_DTO_CTRL,
364e22ad7e3SJake Wang DSCCLK0_DTO_ENABLE, 1);
365e22ad7e3SJake Wang REG_UPDATE_2(DSCCLK0_DTO_PARAM,
366e22ad7e3SJake Wang DSCCLK0_DTO_PHASE, 0,
367e22ad7e3SJake Wang DSCCLK0_DTO_MODULO, 1);
368e22ad7e3SJake Wang break;
369e22ad7e3SJake Wang case 1:
370e22ad7e3SJake Wang REG_UPDATE(DSCCLK_DTO_CTRL,
371e22ad7e3SJake Wang DSCCLK1_DTO_ENABLE, 1);
372e22ad7e3SJake Wang REG_UPDATE_2(DSCCLK1_DTO_PARAM,
373e22ad7e3SJake Wang DSCCLK1_DTO_PHASE, 0,
374e22ad7e3SJake Wang DSCCLK1_DTO_MODULO, 1);
375e22ad7e3SJake Wang break;
376e22ad7e3SJake Wang case 2:
377e22ad7e3SJake Wang REG_UPDATE(DSCCLK_DTO_CTRL,
378e22ad7e3SJake Wang DSCCLK2_DTO_ENABLE, 1);
379e22ad7e3SJake Wang REG_UPDATE_2(DSCCLK2_DTO_PARAM,
380e22ad7e3SJake Wang DSCCLK2_DTO_PHASE, 0,
381e22ad7e3SJake Wang DSCCLK2_DTO_MODULO, 1);
382e22ad7e3SJake Wang break;
383a2a0bdf1SCharlene Liu case 3:
384a2a0bdf1SCharlene Liu if (REG(DSCCLK3_DTO_PARAM)) {
385a2a0bdf1SCharlene Liu REG_UPDATE(DSCCLK_DTO_CTRL,
386a2a0bdf1SCharlene Liu DSCCLK3_DTO_ENABLE, 1);
387a2a0bdf1SCharlene Liu REG_UPDATE_2(DSCCLK3_DTO_PARAM,
388a2a0bdf1SCharlene Liu DSCCLK3_DTO_PHASE, 0,
389a2a0bdf1SCharlene Liu DSCCLK3_DTO_MODULO, 1);
390a2a0bdf1SCharlene Liu }
391a2a0bdf1SCharlene Liu break;
392e22ad7e3SJake Wang default:
393e22ad7e3SJake Wang BREAK_TO_DEBUGGER();
394e22ad7e3SJake Wang return;
395e22ad7e3SJake Wang }
396e22ad7e3SJake Wang }
397e22ad7e3SJake Wang
dccg31_enable_dscclk(struct dccg * dccg,int inst)398ee7b62e1SRoman Li void dccg31_enable_dscclk(struct dccg *dccg, int inst)
399e22ad7e3SJake Wang {
400e22ad7e3SJake Wang struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
401e22ad7e3SJake Wang
402e22ad7e3SJake Wang if (!dccg->ctx->dc->debug.root_clock_optimization.bits.dsc)
403e22ad7e3SJake Wang return;
404e22ad7e3SJake Wang //Disable DTO
405e22ad7e3SJake Wang switch (inst) {
406e22ad7e3SJake Wang case 0:
407e22ad7e3SJake Wang REG_UPDATE_2(DSCCLK0_DTO_PARAM,
408e22ad7e3SJake Wang DSCCLK0_DTO_PHASE, 0,
409e22ad7e3SJake Wang DSCCLK0_DTO_MODULO, 0);
410e22ad7e3SJake Wang REG_UPDATE(DSCCLK_DTO_CTRL,
411e22ad7e3SJake Wang DSCCLK0_DTO_ENABLE, 0);
412e22ad7e3SJake Wang break;
413e22ad7e3SJake Wang case 1:
414e22ad7e3SJake Wang REG_UPDATE_2(DSCCLK1_DTO_PARAM,
415e22ad7e3SJake Wang DSCCLK1_DTO_PHASE, 0,
416e22ad7e3SJake Wang DSCCLK1_DTO_MODULO, 0);
417e22ad7e3SJake Wang REG_UPDATE(DSCCLK_DTO_CTRL,
418e22ad7e3SJake Wang DSCCLK1_DTO_ENABLE, 0);
419e22ad7e3SJake Wang break;
420e22ad7e3SJake Wang case 2:
421e22ad7e3SJake Wang REG_UPDATE_2(DSCCLK2_DTO_PARAM,
422e22ad7e3SJake Wang DSCCLK2_DTO_PHASE, 0,
423e22ad7e3SJake Wang DSCCLK2_DTO_MODULO, 0);
424e22ad7e3SJake Wang REG_UPDATE(DSCCLK_DTO_CTRL,
425e22ad7e3SJake Wang DSCCLK2_DTO_ENABLE, 0);
426e22ad7e3SJake Wang break;
427a2a0bdf1SCharlene Liu case 3:
428a2a0bdf1SCharlene Liu if (REG(DSCCLK3_DTO_PARAM)) {
429a2a0bdf1SCharlene Liu REG_UPDATE(DSCCLK_DTO_CTRL,
430a2a0bdf1SCharlene Liu DSCCLK3_DTO_ENABLE, 0);
431a2a0bdf1SCharlene Liu REG_UPDATE_2(DSCCLK3_DTO_PARAM,
432a2a0bdf1SCharlene Liu DSCCLK3_DTO_PHASE, 0,
433a2a0bdf1SCharlene Liu DSCCLK3_DTO_MODULO, 0);
434a2a0bdf1SCharlene Liu }
435a2a0bdf1SCharlene Liu break;
436e22ad7e3SJake Wang default:
437e22ad7e3SJake Wang BREAK_TO_DEBUGGER();
438e22ad7e3SJake Wang return;
439e22ad7e3SJake Wang }
440e22ad7e3SJake Wang }
441e22ad7e3SJake Wang
dccg31_set_physymclk(struct dccg * dccg,int phy_inst,enum physymclk_clock_source clk_src,bool force_enable)442d8a2b4f3SNicholas Kazlauskas void dccg31_set_physymclk(
443d8a2b4f3SNicholas Kazlauskas struct dccg *dccg,
444d8a2b4f3SNicholas Kazlauskas int phy_inst,
445d8a2b4f3SNicholas Kazlauskas enum physymclk_clock_source clk_src,
446d8a2b4f3SNicholas Kazlauskas bool force_enable)
447d8a2b4f3SNicholas Kazlauskas {
448d8a2b4f3SNicholas Kazlauskas struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
449d8a2b4f3SNicholas Kazlauskas
450d8a2b4f3SNicholas Kazlauskas /* Force PHYSYMCLK on and Select phyd32clk as the source of clock which is output to PHY through DCIO */
451d8a2b4f3SNicholas Kazlauskas switch (phy_inst) {
452d8a2b4f3SNicholas Kazlauskas case 0:
45305d6aea3SDavid Galiffi if (force_enable) {
454d8a2b4f3SNicholas Kazlauskas REG_UPDATE_2(PHYASYMCLK_CLOCK_CNTL,
455d8a2b4f3SNicholas Kazlauskas PHYASYMCLK_FORCE_EN, 1,
456d8a2b4f3SNicholas Kazlauskas PHYASYMCLK_FORCE_SRC_SEL, clk_src);
45705d6aea3SDavid Galiffi if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
45805d6aea3SDavid Galiffi REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
45905d6aea3SDavid Galiffi PHYASYMCLK_GATE_DISABLE, 1);
46005d6aea3SDavid Galiffi } else {
461d8a2b4f3SNicholas Kazlauskas REG_UPDATE_2(PHYASYMCLK_CLOCK_CNTL,
462d8a2b4f3SNicholas Kazlauskas PHYASYMCLK_FORCE_EN, 0,
463d8a2b4f3SNicholas Kazlauskas PHYASYMCLK_FORCE_SRC_SEL, 0);
46405d6aea3SDavid Galiffi if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
46505d6aea3SDavid Galiffi REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
46605d6aea3SDavid Galiffi PHYASYMCLK_GATE_DISABLE, 0);
46705d6aea3SDavid Galiffi }
468d8a2b4f3SNicholas Kazlauskas break;
469d8a2b4f3SNicholas Kazlauskas case 1:
47005d6aea3SDavid Galiffi if (force_enable) {
471d8a2b4f3SNicholas Kazlauskas REG_UPDATE_2(PHYBSYMCLK_CLOCK_CNTL,
472d8a2b4f3SNicholas Kazlauskas PHYBSYMCLK_FORCE_EN, 1,
473d8a2b4f3SNicholas Kazlauskas PHYBSYMCLK_FORCE_SRC_SEL, clk_src);
47405d6aea3SDavid Galiffi if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
47505d6aea3SDavid Galiffi REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
47605d6aea3SDavid Galiffi PHYBSYMCLK_GATE_DISABLE, 1);
47705d6aea3SDavid Galiffi } else {
478d8a2b4f3SNicholas Kazlauskas REG_UPDATE_2(PHYBSYMCLK_CLOCK_CNTL,
479d8a2b4f3SNicholas Kazlauskas PHYBSYMCLK_FORCE_EN, 0,
480d8a2b4f3SNicholas Kazlauskas PHYBSYMCLK_FORCE_SRC_SEL, 0);
48105d6aea3SDavid Galiffi if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
48205d6aea3SDavid Galiffi REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
48305d6aea3SDavid Galiffi PHYBSYMCLK_GATE_DISABLE, 0);
48405d6aea3SDavid Galiffi }
485d8a2b4f3SNicholas Kazlauskas break;
486d8a2b4f3SNicholas Kazlauskas case 2:
48705d6aea3SDavid Galiffi if (force_enable) {
488d8a2b4f3SNicholas Kazlauskas REG_UPDATE_2(PHYCSYMCLK_CLOCK_CNTL,
489d8a2b4f3SNicholas Kazlauskas PHYCSYMCLK_FORCE_EN, 1,
490d8a2b4f3SNicholas Kazlauskas PHYCSYMCLK_FORCE_SRC_SEL, clk_src);
49105d6aea3SDavid Galiffi if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
49205d6aea3SDavid Galiffi REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
49305d6aea3SDavid Galiffi PHYCSYMCLK_GATE_DISABLE, 1);
49405d6aea3SDavid Galiffi } else {
495d8a2b4f3SNicholas Kazlauskas REG_UPDATE_2(PHYCSYMCLK_CLOCK_CNTL,
496d8a2b4f3SNicholas Kazlauskas PHYCSYMCLK_FORCE_EN, 0,
497d8a2b4f3SNicholas Kazlauskas PHYCSYMCLK_FORCE_SRC_SEL, 0);
49805d6aea3SDavid Galiffi if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
49905d6aea3SDavid Galiffi REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
50005d6aea3SDavid Galiffi PHYCSYMCLK_GATE_DISABLE, 0);
50105d6aea3SDavid Galiffi }
502d8a2b4f3SNicholas Kazlauskas break;
503d8a2b4f3SNicholas Kazlauskas case 3:
50405d6aea3SDavid Galiffi if (force_enable) {
505d8a2b4f3SNicholas Kazlauskas REG_UPDATE_2(PHYDSYMCLK_CLOCK_CNTL,
506d8a2b4f3SNicholas Kazlauskas PHYDSYMCLK_FORCE_EN, 1,
507d8a2b4f3SNicholas Kazlauskas PHYDSYMCLK_FORCE_SRC_SEL, clk_src);
50805d6aea3SDavid Galiffi if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
50905d6aea3SDavid Galiffi REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
51005d6aea3SDavid Galiffi PHYDSYMCLK_GATE_DISABLE, 1);
51105d6aea3SDavid Galiffi } else {
512d8a2b4f3SNicholas Kazlauskas REG_UPDATE_2(PHYDSYMCLK_CLOCK_CNTL,
513d8a2b4f3SNicholas Kazlauskas PHYDSYMCLK_FORCE_EN, 0,
514d8a2b4f3SNicholas Kazlauskas PHYDSYMCLK_FORCE_SRC_SEL, 0);
51505d6aea3SDavid Galiffi if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
51605d6aea3SDavid Galiffi REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
51705d6aea3SDavid Galiffi PHYDSYMCLK_GATE_DISABLE, 0);
51805d6aea3SDavid Galiffi }
519d8a2b4f3SNicholas Kazlauskas break;
520d8a2b4f3SNicholas Kazlauskas case 4:
52105d6aea3SDavid Galiffi if (force_enable) {
522d8a2b4f3SNicholas Kazlauskas REG_UPDATE_2(PHYESYMCLK_CLOCK_CNTL,
523d8a2b4f3SNicholas Kazlauskas PHYESYMCLK_FORCE_EN, 1,
524d8a2b4f3SNicholas Kazlauskas PHYESYMCLK_FORCE_SRC_SEL, clk_src);
52505d6aea3SDavid Galiffi if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
52605d6aea3SDavid Galiffi REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
52705d6aea3SDavid Galiffi PHYESYMCLK_GATE_DISABLE, 1);
52805d6aea3SDavid Galiffi } else {
529d8a2b4f3SNicholas Kazlauskas REG_UPDATE_2(PHYESYMCLK_CLOCK_CNTL,
530d8a2b4f3SNicholas Kazlauskas PHYESYMCLK_FORCE_EN, 0,
531d8a2b4f3SNicholas Kazlauskas PHYESYMCLK_FORCE_SRC_SEL, 0);
53205d6aea3SDavid Galiffi if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
53305d6aea3SDavid Galiffi REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
53405d6aea3SDavid Galiffi PHYESYMCLK_GATE_DISABLE, 0);
53505d6aea3SDavid Galiffi }
536d8a2b4f3SNicholas Kazlauskas break;
537d8a2b4f3SNicholas Kazlauskas default:
538d8a2b4f3SNicholas Kazlauskas BREAK_TO_DEBUGGER();
539d8a2b4f3SNicholas Kazlauskas return;
540d8a2b4f3SNicholas Kazlauskas }
541d8a2b4f3SNicholas Kazlauskas }
542d8a2b4f3SNicholas Kazlauskas
543d8a2b4f3SNicholas Kazlauskas /* Controls the generation of pixel valid for OTG in (OTG -> HPO case) */
dccg31_set_dtbclk_dto(struct dccg * dccg,const struct dtbclk_dto_params * params)544ee7b62e1SRoman Li void dccg31_set_dtbclk_dto(
545d8a2b4f3SNicholas Kazlauskas struct dccg *dccg,
546a8201902SLeung, Martin const struct dtbclk_dto_params *params)
547d8a2b4f3SNicholas Kazlauskas {
548d8a2b4f3SNicholas Kazlauskas struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
5496ecf9773SHung, Cruise int req_dtbclk_khz = params->pixclk_khz;
550d8a2b4f3SNicholas Kazlauskas uint32_t dtbdto_div;
551d8a2b4f3SNicholas Kazlauskas
552d8a2b4f3SNicholas Kazlauskas /* Mode DTBDTO Rate DTBCLK_DTO<x>_DIV Register
553d8a2b4f3SNicholas Kazlauskas * ODM 4:1 combine pixel rate/4 2
554d8a2b4f3SNicholas Kazlauskas * ODM 2:1 combine pixel rate/2 4
555d8a2b4f3SNicholas Kazlauskas * non-DSC 4:2:0 mode pixel rate/2 4
556d8a2b4f3SNicholas Kazlauskas * DSC native 4:2:0 pixel rate/2 4
557d8a2b4f3SNicholas Kazlauskas * DSC native 4:2:2 pixel rate/2 4
558d8a2b4f3SNicholas Kazlauskas * Other modes pixel rate 8
559d8a2b4f3SNicholas Kazlauskas */
5606ecf9773SHung, Cruise if (params->num_odm_segments == 4) {
561d8a2b4f3SNicholas Kazlauskas dtbdto_div = 2;
5626ecf9773SHung, Cruise req_dtbclk_khz = params->pixclk_khz / 4;
5636ecf9773SHung, Cruise } else if ((params->num_odm_segments == 2) ||
5646ecf9773SHung, Cruise (params->timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) ||
5656ecf9773SHung, Cruise (params->timing->flags.DSC && params->timing->pixel_encoding == PIXEL_ENCODING_YCBCR422
5666ecf9773SHung, Cruise && !params->timing->dsc_cfg.ycbcr422_simple)) {
567d8a2b4f3SNicholas Kazlauskas dtbdto_div = 4;
5686ecf9773SHung, Cruise req_dtbclk_khz = params->pixclk_khz / 2;
569d8a2b4f3SNicholas Kazlauskas } else
570d8a2b4f3SNicholas Kazlauskas dtbdto_div = 8;
571d8a2b4f3SNicholas Kazlauskas
5726ecf9773SHung, Cruise if (params->ref_dtbclk_khz && req_dtbclk_khz) {
573d8a2b4f3SNicholas Kazlauskas uint32_t modulo, phase;
574d8a2b4f3SNicholas Kazlauskas
575d8a2b4f3SNicholas Kazlauskas // phase / modulo = dtbclk / dtbclk ref
5766ecf9773SHung, Cruise modulo = params->ref_dtbclk_khz * 1000;
5776ecf9773SHung, Cruise phase = div_u64((((unsigned long long)modulo * req_dtbclk_khz) + params->ref_dtbclk_khz - 1),
5786ecf9773SHung, Cruise params->ref_dtbclk_khz);
579d8a2b4f3SNicholas Kazlauskas
5806ecf9773SHung, Cruise REG_UPDATE(OTG_PIXEL_RATE_CNTL[params->otg_inst],
5816ecf9773SHung, Cruise DTBCLK_DTO_DIV[params->otg_inst], dtbdto_div);
582d8a2b4f3SNicholas Kazlauskas
5836ecf9773SHung, Cruise REG_WRITE(DTBCLK_DTO_MODULO[params->otg_inst], modulo);
5846ecf9773SHung, Cruise REG_WRITE(DTBCLK_DTO_PHASE[params->otg_inst], phase);
585d8a2b4f3SNicholas Kazlauskas
5866ecf9773SHung, Cruise REG_UPDATE(OTG_PIXEL_RATE_CNTL[params->otg_inst],
5876ecf9773SHung, Cruise DTBCLK_DTO_ENABLE[params->otg_inst], 1);
588d8a2b4f3SNicholas Kazlauskas
5896ecf9773SHung, Cruise REG_WAIT(OTG_PIXEL_RATE_CNTL[params->otg_inst],
5906ecf9773SHung, Cruise DTBCLKDTO_ENABLE_STATUS[params->otg_inst], 1,
591d8a2b4f3SNicholas Kazlauskas 1, 100);
592d8a2b4f3SNicholas Kazlauskas
593d8a2b4f3SNicholas Kazlauskas /* The recommended programming sequence to enable DTBCLK DTO to generate
594d8a2b4f3SNicholas Kazlauskas * valid pixel HPO DPSTREAM ENCODER, specifies that DTO source select should
595d8a2b4f3SNicholas Kazlauskas * be set only after DTO is enabled
596d8a2b4f3SNicholas Kazlauskas */
5976ecf9773SHung, Cruise REG_UPDATE(OTG_PIXEL_RATE_CNTL[params->otg_inst],
5986ecf9773SHung, Cruise PIPE_DTO_SRC_SEL[params->otg_inst], 1);
599d8a2b4f3SNicholas Kazlauskas } else {
6006ecf9773SHung, Cruise REG_UPDATE_3(OTG_PIXEL_RATE_CNTL[params->otg_inst],
6016ecf9773SHung, Cruise DTBCLK_DTO_ENABLE[params->otg_inst], 0,
6026ecf9773SHung, Cruise PIPE_DTO_SRC_SEL[params->otg_inst], 0,
6036ecf9773SHung, Cruise DTBCLK_DTO_DIV[params->otg_inst], dtbdto_div);
604d8a2b4f3SNicholas Kazlauskas
6056ecf9773SHung, Cruise REG_WRITE(DTBCLK_DTO_MODULO[params->otg_inst], 0);
6066ecf9773SHung, Cruise REG_WRITE(DTBCLK_DTO_PHASE[params->otg_inst], 0);
607d8a2b4f3SNicholas Kazlauskas }
608d8a2b4f3SNicholas Kazlauskas }
609d8a2b4f3SNicholas Kazlauskas
dccg31_set_audio_dtbclk_dto(struct dccg * dccg,const struct dtbclk_dto_params * params)610d8a2b4f3SNicholas Kazlauskas void dccg31_set_audio_dtbclk_dto(
611d8a2b4f3SNicholas Kazlauskas struct dccg *dccg,
612a8201902SLeung, Martin const struct dtbclk_dto_params *params)
613d8a2b4f3SNicholas Kazlauskas {
614d8a2b4f3SNicholas Kazlauskas struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
615d8a2b4f3SNicholas Kazlauskas
616a8201902SLeung, Martin if (params->ref_dtbclk_khz && params->req_audio_dtbclk_khz) {
617d8a2b4f3SNicholas Kazlauskas uint32_t modulo, phase;
618d8a2b4f3SNicholas Kazlauskas
619d8a2b4f3SNicholas Kazlauskas // phase / modulo = dtbclk / dtbclk ref
620a8201902SLeung, Martin modulo = params->ref_dtbclk_khz * 1000;
621a8201902SLeung, Martin phase = div_u64((((unsigned long long)modulo * params->req_audio_dtbclk_khz) + params->ref_dtbclk_khz - 1),
622a8201902SLeung, Martin params->ref_dtbclk_khz);
623d8a2b4f3SNicholas Kazlauskas
624405bb9eeSAlvin Lee
625d8a2b4f3SNicholas Kazlauskas REG_WRITE(DCCG_AUDIO_DTBCLK_DTO_MODULO, modulo);
626d8a2b4f3SNicholas Kazlauskas REG_WRITE(DCCG_AUDIO_DTBCLK_DTO_PHASE, phase);
627d8a2b4f3SNicholas Kazlauskas
628d8a2b4f3SNicholas Kazlauskas //REG_UPDATE(DCCG_AUDIO_DTO_SOURCE,
629d8a2b4f3SNicholas Kazlauskas // DCCG_AUDIO_DTBCLK_DTO_USE_512FBR_DTO, 1);
630d8a2b4f3SNicholas Kazlauskas
631d8a2b4f3SNicholas Kazlauskas REG_UPDATE(DCCG_AUDIO_DTO_SOURCE,
632d8a2b4f3SNicholas Kazlauskas DCCG_AUDIO_DTO_SEL, 4); // 04 - DCCG_AUDIO_DTO_SEL_AUDIO_DTO_DTBCLK
633d8a2b4f3SNicholas Kazlauskas } else {
634d8a2b4f3SNicholas Kazlauskas REG_WRITE(DCCG_AUDIO_DTBCLK_DTO_PHASE, 0);
635d8a2b4f3SNicholas Kazlauskas REG_WRITE(DCCG_AUDIO_DTBCLK_DTO_MODULO, 0);
636d8a2b4f3SNicholas Kazlauskas
637d8a2b4f3SNicholas Kazlauskas REG_UPDATE(DCCG_AUDIO_DTO_SOURCE,
638d8a2b4f3SNicholas Kazlauskas DCCG_AUDIO_DTO_SEL, 3); // 03 - DCCG_AUDIO_DTO_SEL_NO_AUDIO_DTO
639d8a2b4f3SNicholas Kazlauskas }
640d8a2b4f3SNicholas Kazlauskas }
641d8a2b4f3SNicholas Kazlauskas
dccg31_get_dccg_ref_freq(struct dccg * dccg,unsigned int xtalin_freq_inKhz,unsigned int * dccg_ref_freq_inKhz)642ee7b62e1SRoman Li void dccg31_get_dccg_ref_freq(struct dccg *dccg,
643d8a2b4f3SNicholas Kazlauskas unsigned int xtalin_freq_inKhz,
644d8a2b4f3SNicholas Kazlauskas unsigned int *dccg_ref_freq_inKhz)
645d8a2b4f3SNicholas Kazlauskas {
646d8a2b4f3SNicholas Kazlauskas /*
647d8a2b4f3SNicholas Kazlauskas * Assume refclk is sourced from xtalin
648d8a2b4f3SNicholas Kazlauskas * expect 24MHz
649d8a2b4f3SNicholas Kazlauskas */
650d8a2b4f3SNicholas Kazlauskas *dccg_ref_freq_inKhz = xtalin_freq_inKhz;
651d8a2b4f3SNicholas Kazlauskas return;
652d8a2b4f3SNicholas Kazlauskas }
653d8a2b4f3SNicholas Kazlauskas
dccg31_set_dispclk_change_mode(struct dccg * dccg,enum dentist_dispclk_change_mode change_mode)654ee7b62e1SRoman Li void dccg31_set_dispclk_change_mode(
655d8a2b4f3SNicholas Kazlauskas struct dccg *dccg,
656d8a2b4f3SNicholas Kazlauskas enum dentist_dispclk_change_mode change_mode)
657d8a2b4f3SNicholas Kazlauskas {
658d8a2b4f3SNicholas Kazlauskas struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
659d8a2b4f3SNicholas Kazlauskas
660d8a2b4f3SNicholas Kazlauskas REG_UPDATE(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_CHG_MODE,
661d8a2b4f3SNicholas Kazlauskas change_mode == DISPCLK_CHANGE_MODE_RAMPING ? 2 : 0);
662d8a2b4f3SNicholas Kazlauskas }
663d8a2b4f3SNicholas Kazlauskas
dccg31_init(struct dccg * dccg)664d8a2b4f3SNicholas Kazlauskas void dccg31_init(struct dccg *dccg)
665d8a2b4f3SNicholas Kazlauskas {
666d76b12daSFangzhi Zuo /* Set HPO stream encoder to use refclk to avoid case where PHY is
667d76b12daSFangzhi Zuo * disabled and SYMCLK32 for HPO SE is sourced from PHYD32CLK which
668d76b12daSFangzhi Zuo * will cause DCN to hang.
669d76b12daSFangzhi Zuo */
670d76b12daSFangzhi Zuo dccg31_disable_symclk32_se(dccg, 0);
671d76b12daSFangzhi Zuo dccg31_disable_symclk32_se(dccg, 1);
672d76b12daSFangzhi Zuo dccg31_disable_symclk32_se(dccg, 2);
673d76b12daSFangzhi Zuo dccg31_disable_symclk32_se(dccg, 3);
674bda24462SJake Wang
6753a87e25aSDaniel Miess dccg31_set_symclk32_le_root_clock_gating(dccg, 0, false);
6763a87e25aSDaniel Miess dccg31_set_symclk32_le_root_clock_gating(dccg, 1, false);
677bda24462SJake Wang
678bda24462SJake Wang if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpstream) {
679bda24462SJake Wang dccg31_disable_dpstreamclk(dccg, 0);
680bda24462SJake Wang dccg31_disable_dpstreamclk(dccg, 1);
681bda24462SJake Wang dccg31_disable_dpstreamclk(dccg, 2);
682bda24462SJake Wang dccg31_disable_dpstreamclk(dccg, 3);
683bda24462SJake Wang }
684bda24462SJake Wang
68505d6aea3SDavid Galiffi if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk) {
68605d6aea3SDavid Galiffi dccg31_set_physymclk(dccg, 0, PHYSYMCLK_FORCE_SRC_SYMCLK, false);
68705d6aea3SDavid Galiffi dccg31_set_physymclk(dccg, 1, PHYSYMCLK_FORCE_SRC_SYMCLK, false);
68805d6aea3SDavid Galiffi dccg31_set_physymclk(dccg, 2, PHYSYMCLK_FORCE_SRC_SYMCLK, false);
68905d6aea3SDavid Galiffi dccg31_set_physymclk(dccg, 3, PHYSYMCLK_FORCE_SRC_SYMCLK, false);
69005d6aea3SDavid Galiffi dccg31_set_physymclk(dccg, 4, PHYSYMCLK_FORCE_SRC_SYMCLK, false);
69105d6aea3SDavid Galiffi }
692d8a2b4f3SNicholas Kazlauskas }
693d8a2b4f3SNicholas Kazlauskas
dccg31_otg_add_pixel(struct dccg * dccg,uint32_t otg_inst)694ee7b62e1SRoman Li void dccg31_otg_add_pixel(struct dccg *dccg,
695d3dfceb5SAurabindo Pillai uint32_t otg_inst)
696d3dfceb5SAurabindo Pillai {
697d3dfceb5SAurabindo Pillai struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
698d3dfceb5SAurabindo Pillai
699d3dfceb5SAurabindo Pillai REG_UPDATE(OTG_PIXEL_RATE_CNTL[otg_inst],
700d3dfceb5SAurabindo Pillai OTG_ADD_PIXEL[otg_inst], 1);
701d3dfceb5SAurabindo Pillai }
702d3dfceb5SAurabindo Pillai
dccg31_otg_drop_pixel(struct dccg * dccg,uint32_t otg_inst)703ee7b62e1SRoman Li void dccg31_otg_drop_pixel(struct dccg *dccg,
704d3dfceb5SAurabindo Pillai uint32_t otg_inst)
705d3dfceb5SAurabindo Pillai {
706d3dfceb5SAurabindo Pillai struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
707d3dfceb5SAurabindo Pillai
708d3dfceb5SAurabindo Pillai REG_UPDATE(OTG_PIXEL_RATE_CNTL[otg_inst],
709d3dfceb5SAurabindo Pillai OTG_DROP_PIXEL[otg_inst], 1);
710d3dfceb5SAurabindo Pillai }
711d3dfceb5SAurabindo Pillai
712d8a2b4f3SNicholas Kazlauskas static const struct dccg_funcs dccg31_funcs = {
7137a28bee0SJake Wang .update_dpp_dto = dccg31_update_dpp_dto,
714d8a2b4f3SNicholas Kazlauskas .get_dccg_ref_freq = dccg31_get_dccg_ref_freq,
715d8a2b4f3SNicholas Kazlauskas .dccg_init = dccg31_init,
716d76b12daSFangzhi Zuo .set_dpstreamclk = dccg31_set_dpstreamclk,
717d76b12daSFangzhi Zuo .enable_symclk32_se = dccg31_enable_symclk32_se,
718d76b12daSFangzhi Zuo .disable_symclk32_se = dccg31_disable_symclk32_se,
719d76b12daSFangzhi Zuo .enable_symclk32_le = dccg31_enable_symclk32_le,
720d76b12daSFangzhi Zuo .disable_symclk32_le = dccg31_disable_symclk32_le,
721d8a2b4f3SNicholas Kazlauskas .set_physymclk = dccg31_set_physymclk,
722d8a2b4f3SNicholas Kazlauskas .set_dtbclk_dto = dccg31_set_dtbclk_dto,
723d8a2b4f3SNicholas Kazlauskas .set_audio_dtbclk_dto = dccg31_set_audio_dtbclk_dto,
724d3dfceb5SAurabindo Pillai .set_fifo_errdet_ovr_en = dccg2_set_fifo_errdet_ovr_en,
725d3dfceb5SAurabindo Pillai .otg_add_pixel = dccg31_otg_add_pixel,
726d3dfceb5SAurabindo Pillai .otg_drop_pixel = dccg31_otg_drop_pixel,
727d8a2b4f3SNicholas Kazlauskas .set_dispclk_change_mode = dccg31_set_dispclk_change_mode,
728e22ad7e3SJake Wang .disable_dsc = dccg31_disable_dscclk,
729e22ad7e3SJake Wang .enable_dsc = dccg31_enable_dscclk,
730d8a2b4f3SNicholas Kazlauskas };
731d8a2b4f3SNicholas Kazlauskas
dccg31_create(struct dc_context * ctx,const struct dccg_registers * regs,const struct dccg_shift * dccg_shift,const struct dccg_mask * dccg_mask)732d8a2b4f3SNicholas Kazlauskas struct dccg *dccg31_create(
733d8a2b4f3SNicholas Kazlauskas struct dc_context *ctx,
734d8a2b4f3SNicholas Kazlauskas const struct dccg_registers *regs,
735d8a2b4f3SNicholas Kazlauskas const struct dccg_shift *dccg_shift,
736d8a2b4f3SNicholas Kazlauskas const struct dccg_mask *dccg_mask)
737d8a2b4f3SNicholas Kazlauskas {
738d8a2b4f3SNicholas Kazlauskas struct dcn_dccg *dccg_dcn = kzalloc(sizeof(*dccg_dcn), GFP_KERNEL);
739d8a2b4f3SNicholas Kazlauskas struct dccg *base;
740d8a2b4f3SNicholas Kazlauskas
741d8a2b4f3SNicholas Kazlauskas if (dccg_dcn == NULL) {
742d8a2b4f3SNicholas Kazlauskas BREAK_TO_DEBUGGER();
743d8a2b4f3SNicholas Kazlauskas return NULL;
744d8a2b4f3SNicholas Kazlauskas }
745d8a2b4f3SNicholas Kazlauskas
746d8a2b4f3SNicholas Kazlauskas base = &dccg_dcn->base;
747d8a2b4f3SNicholas Kazlauskas base->ctx = ctx;
748d8a2b4f3SNicholas Kazlauskas base->funcs = &dccg31_funcs;
749d8a2b4f3SNicholas Kazlauskas
750d8a2b4f3SNicholas Kazlauskas dccg_dcn->regs = regs;
751d8a2b4f3SNicholas Kazlauskas dccg_dcn->dccg_shift = dccg_shift;
752d8a2b4f3SNicholas Kazlauskas dccg_dcn->dccg_mask = dccg_mask;
753d8a2b4f3SNicholas Kazlauskas
754d8a2b4f3SNicholas Kazlauskas return &dccg_dcn->base;
755d8a2b4f3SNicholas Kazlauskas }
756