Merge tag 'drm-habanalabs-next-2023-10-10' of https://git.kernel.org/pub/scm/linux...
[sfrench/cifs-2.6.git] / drivers / gpu / drm / amd / display / dc / dcn314 / dcn314_dccg.c
1 // SPDX-License-Identifier: MIT
2 /*
3  * Copyright 2022 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  * Authors: AMD
24  *
25  */
26
27 #include "reg_helper.h"
28 #include "core_types.h"
29
30 #include "dcn31/dcn31_dccg.h"
31 #include "dcn314_dccg.h"
32
33 #define TO_DCN_DCCG(dccg)\
34         container_of(dccg, struct dcn_dccg, base)
35
36 #define REG(reg) \
37         (dccg_dcn->regs->reg)
38
39 #undef FN
40 #define FN(reg_name, field_name) \
41         dccg_dcn->dccg_shift->field_name, dccg_dcn->dccg_mask->field_name
42
43 #define CTX \
44         dccg_dcn->base.ctx
45 #define DC_LOGGER \
46         dccg->ctx->logger
47
48 static void dccg314_trigger_dio_fifo_resync(
49         struct dccg *dccg)
50 {
51         struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
52         uint32_t dispclk_rdivider_value = 0;
53
54         REG_GET(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_RDIVIDER, &dispclk_rdivider_value);
55         REG_UPDATE(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_WDIVIDER, dispclk_rdivider_value);
56 }
57
58 static void dccg314_get_pixel_rate_div(
59                 struct dccg *dccg,
60                 uint32_t otg_inst,
61                 enum pixel_rate_div *k1,
62                 enum pixel_rate_div *k2)
63 {
64         struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
65         uint32_t val_k1 = PIXEL_RATE_DIV_NA, val_k2 = PIXEL_RATE_DIV_NA;
66
67         *k1 = PIXEL_RATE_DIV_NA;
68         *k2 = PIXEL_RATE_DIV_NA;
69
70         switch (otg_inst) {
71         case 0:
72                 REG_GET_2(OTG_PIXEL_RATE_DIV,
73                         OTG0_PIXEL_RATE_DIVK1, &val_k1,
74                         OTG0_PIXEL_RATE_DIVK2, &val_k2);
75                 break;
76         case 1:
77                 REG_GET_2(OTG_PIXEL_RATE_DIV,
78                         OTG1_PIXEL_RATE_DIVK1, &val_k1,
79                         OTG1_PIXEL_RATE_DIVK2, &val_k2);
80                 break;
81         case 2:
82                 REG_GET_2(OTG_PIXEL_RATE_DIV,
83                         OTG2_PIXEL_RATE_DIVK1, &val_k1,
84                         OTG2_PIXEL_RATE_DIVK2, &val_k2);
85                 break;
86         case 3:
87                 REG_GET_2(OTG_PIXEL_RATE_DIV,
88                         OTG3_PIXEL_RATE_DIVK1, &val_k1,
89                         OTG3_PIXEL_RATE_DIVK2, &val_k2);
90                 break;
91         default:
92                 BREAK_TO_DEBUGGER();
93                 return;
94         }
95
96         *k1 = (enum pixel_rate_div)val_k1;
97         *k2 = (enum pixel_rate_div)val_k2;
98 }
99
100 static void dccg314_set_pixel_rate_div(
101                 struct dccg *dccg,
102                 uint32_t otg_inst,
103                 enum pixel_rate_div k1,
104                 enum pixel_rate_div k2)
105 {
106         struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
107         enum pixel_rate_div cur_k1 = PIXEL_RATE_DIV_NA, cur_k2 = PIXEL_RATE_DIV_NA;
108
109         // Don't program 0xF into the register field. Not valid since
110         // K1 / K2 field is only 1 / 2 bits wide
111         if (k1 == PIXEL_RATE_DIV_NA || k2 == PIXEL_RATE_DIV_NA) {
112                 BREAK_TO_DEBUGGER();
113                 return;
114         }
115
116         dccg314_get_pixel_rate_div(dccg, otg_inst, &cur_k1, &cur_k2);
117         if (k1 == cur_k1 && k2 == cur_k2)
118                 return;
119
120         switch (otg_inst) {
121         case 0:
122                 REG_UPDATE_2(OTG_PIXEL_RATE_DIV,
123                                 OTG0_PIXEL_RATE_DIVK1, k1,
124                                 OTG0_PIXEL_RATE_DIVK2, k2);
125                 break;
126         case 1:
127                 REG_UPDATE_2(OTG_PIXEL_RATE_DIV,
128                                 OTG1_PIXEL_RATE_DIVK1, k1,
129                                 OTG1_PIXEL_RATE_DIVK2, k2);
130                 break;
131         case 2:
132                 REG_UPDATE_2(OTG_PIXEL_RATE_DIV,
133                                 OTG2_PIXEL_RATE_DIVK1, k1,
134                                 OTG2_PIXEL_RATE_DIVK2, k2);
135                 break;
136         case 3:
137                 REG_UPDATE_2(OTG_PIXEL_RATE_DIV,
138                                 OTG3_PIXEL_RATE_DIVK1, k1,
139                                 OTG3_PIXEL_RATE_DIVK2, k2);
140                 break;
141         default:
142                 BREAK_TO_DEBUGGER();
143                 return;
144         }
145 }
146
147 static void dccg314_set_dtbclk_p_src(
148                 struct dccg *dccg,
149                 enum streamclk_source src,
150                 uint32_t otg_inst)
151 {
152         struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
153
154         uint32_t p_src_sel = 0; /* selects dprefclk */
155
156         if (src == DTBCLK0)
157                 p_src_sel = 2;  /* selects dtbclk0 */
158
159         switch (otg_inst) {
160         case 0:
161                 if (src == REFCLK)
162                         REG_UPDATE(DTBCLK_P_CNTL,
163                                         DTBCLK_P0_EN, 0);
164                 else
165                         REG_UPDATE_2(DTBCLK_P_CNTL,
166                                         DTBCLK_P0_SRC_SEL, p_src_sel,
167                                         DTBCLK_P0_EN, 1);
168                 break;
169         case 1:
170                 if (src == REFCLK)
171                         REG_UPDATE(DTBCLK_P_CNTL,
172                                         DTBCLK_P1_EN, 0);
173                 else
174                         REG_UPDATE_2(DTBCLK_P_CNTL,
175                                         DTBCLK_P1_SRC_SEL, p_src_sel,
176                                         DTBCLK_P1_EN, 1);
177                 break;
178         case 2:
179                 if (src == REFCLK)
180                         REG_UPDATE(DTBCLK_P_CNTL,
181                                         DTBCLK_P2_EN, 0);
182                 else
183                         REG_UPDATE_2(DTBCLK_P_CNTL,
184                                         DTBCLK_P2_SRC_SEL, p_src_sel,
185                                         DTBCLK_P2_EN, 1);
186                 break;
187         case 3:
188                 if (src == REFCLK)
189                         REG_UPDATE(DTBCLK_P_CNTL,
190                                         DTBCLK_P3_EN, 0);
191                 else
192                         REG_UPDATE_2(DTBCLK_P_CNTL,
193                                         DTBCLK_P3_SRC_SEL, p_src_sel,
194                                         DTBCLK_P3_EN, 1);
195                 break;
196         default:
197                 BREAK_TO_DEBUGGER();
198                 return;
199         }
200
201 }
202
203 /* Controls the generation of pixel valid for OTG in (OTG -> HPO case) */
204 static void dccg314_set_dtbclk_dto(
205                 struct dccg *dccg,
206                 const struct dtbclk_dto_params *params)
207 {
208         struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
209         /* DTO Output Rate / Pixel Rate = 1/4 */
210         int req_dtbclk_khz = params->pixclk_khz / 4;
211
212         if (params->ref_dtbclk_khz && req_dtbclk_khz) {
213                 uint32_t modulo, phase;
214
215                 // phase / modulo = dtbclk / dtbclk ref
216                 modulo = params->ref_dtbclk_khz * 1000;
217                 phase = req_dtbclk_khz * 1000;
218
219                 REG_WRITE(DTBCLK_DTO_MODULO[params->otg_inst], modulo);
220                 REG_WRITE(DTBCLK_DTO_PHASE[params->otg_inst], phase);
221
222                 REG_UPDATE(OTG_PIXEL_RATE_CNTL[params->otg_inst],
223                                 DTBCLK_DTO_ENABLE[params->otg_inst], 1);
224
225                 REG_WAIT(OTG_PIXEL_RATE_CNTL[params->otg_inst],
226                                 DTBCLKDTO_ENABLE_STATUS[params->otg_inst], 1,
227                                 1, 100);
228
229                 /* program OTG_PIXEL_RATE_DIV for DIVK1 and DIVK2 fields */
230                 dccg314_set_pixel_rate_div(dccg, params->otg_inst, PIXEL_RATE_DIV_BY_1, PIXEL_RATE_DIV_BY_1);
231
232                 /* The recommended programming sequence to enable DTBCLK DTO to generate
233                  * valid pixel HPO DPSTREAM ENCODER, specifies that DTO source select should
234                  * be set only after DTO is enabled
235                  */
236                 REG_UPDATE(OTG_PIXEL_RATE_CNTL[params->otg_inst],
237                                 PIPE_DTO_SRC_SEL[params->otg_inst], 2);
238         } else {
239                 REG_UPDATE_2(OTG_PIXEL_RATE_CNTL[params->otg_inst],
240                                 DTBCLK_DTO_ENABLE[params->otg_inst], 0,
241                                 PIPE_DTO_SRC_SEL[params->otg_inst], 1);
242
243                 REG_WRITE(DTBCLK_DTO_MODULO[params->otg_inst], 0);
244                 REG_WRITE(DTBCLK_DTO_PHASE[params->otg_inst], 0);
245         }
246 }
247
248 static void dccg314_set_dpstreamclk(
249                 struct dccg *dccg,
250                 enum streamclk_source src,
251                 int otg_inst,
252                 int dp_hpo_inst)
253 {
254         struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
255
256         /* set the dtbclk_p source */
257         dccg314_set_dtbclk_p_src(dccg, src, otg_inst);
258
259         /* enabled to select one of the DTBCLKs for pipe */
260         switch (dp_hpo_inst) {
261         case 0:
262                 REG_UPDATE_2(DPSTREAMCLK_CNTL,
263                                         DPSTREAMCLK0_EN, (src == REFCLK) ? 0 : 1,
264                                         DPSTREAMCLK0_SRC_SEL, otg_inst);
265                 break;
266         case 1:
267                 REG_UPDATE_2(DPSTREAMCLK_CNTL,
268                                         DPSTREAMCLK1_EN, (src == REFCLK) ? 0 : 1,
269                                         DPSTREAMCLK1_SRC_SEL, otg_inst);
270                 break;
271         case 2:
272                 REG_UPDATE_2(DPSTREAMCLK_CNTL,
273                                         DPSTREAMCLK2_EN, (src == REFCLK) ? 0 : 1,
274                                         DPSTREAMCLK2_SRC_SEL, otg_inst);
275                 break;
276         case 3:
277                 REG_UPDATE_2(DPSTREAMCLK_CNTL,
278                                         DPSTREAMCLK3_EN, (src == REFCLK) ? 0 : 1,
279                                         DPSTREAMCLK3_SRC_SEL, otg_inst);
280                 break;
281         default:
282                 BREAK_TO_DEBUGGER();
283                 return;
284         }
285 }
286
287 static void dccg314_init(struct dccg *dccg)
288 {
289         int otg_inst;
290
291         /* Set HPO stream encoder to use refclk to avoid case where PHY is
292          * disabled and SYMCLK32 for HPO SE is sourced from PHYD32CLK which
293          * will cause DCN to hang.
294          */
295         for (otg_inst = 0; otg_inst < 4; otg_inst++)
296                 dccg31_disable_symclk32_se(dccg, otg_inst);
297
298         if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le)
299                 for (otg_inst = 0; otg_inst < 2; otg_inst++)
300                         dccg31_disable_symclk32_le(dccg, otg_inst);
301
302         if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpstream)
303                 for (otg_inst = 0; otg_inst < 4; otg_inst++)
304                         dccg314_set_dpstreamclk(dccg, REFCLK, otg_inst,
305                                                 otg_inst);
306
307         if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
308                 for (otg_inst = 0; otg_inst < 5; otg_inst++)
309                         dccg31_set_physymclk(dccg, otg_inst,
310                                              PHYSYMCLK_FORCE_SRC_SYMCLK, false);
311 }
312
313 static void dccg314_set_valid_pixel_rate(
314                 struct dccg *dccg,
315                 int ref_dtbclk_khz,
316                 int otg_inst,
317                 int pixclk_khz)
318 {
319         struct dtbclk_dto_params dto_params = {0};
320
321         dto_params.ref_dtbclk_khz = ref_dtbclk_khz;
322         dto_params.otg_inst = otg_inst;
323         dto_params.pixclk_khz = pixclk_khz;
324
325         dccg314_set_dtbclk_dto(dccg, &dto_params);
326 }
327
328 static void dccg314_dpp_root_clock_control(
329                 struct dccg *dccg,
330                 unsigned int dpp_inst,
331                 bool clock_on)
332 {
333         struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
334
335         if (dccg->dpp_clock_gated[dpp_inst] != clock_on)
336                 return;
337
338         if (clock_on) {
339                 /* turn off the DTO and leave phase/modulo at max */
340                 REG_UPDATE(DPPCLK_DTO_CTRL, DPPCLK_DTO_ENABLE[dpp_inst], 0);
341                 REG_SET_2(DPPCLK_DTO_PARAM[dpp_inst], 0,
342                           DPPCLK0_DTO_PHASE, 0xFF,
343                           DPPCLK0_DTO_MODULO, 0xFF);
344         } else {
345                 /* turn on the DTO to generate a 0hz clock */
346                 REG_UPDATE(DPPCLK_DTO_CTRL, DPPCLK_DTO_ENABLE[dpp_inst], 1);
347                 REG_SET_2(DPPCLK_DTO_PARAM[dpp_inst], 0,
348                           DPPCLK0_DTO_PHASE, 0,
349                           DPPCLK0_DTO_MODULO, 1);
350         }
351
352         dccg->dpp_clock_gated[dpp_inst] = !clock_on;
353 }
354
355 static const struct dccg_funcs dccg314_funcs = {
356         .update_dpp_dto = dccg31_update_dpp_dto,
357         .dpp_root_clock_control = dccg314_dpp_root_clock_control,
358         .get_dccg_ref_freq = dccg31_get_dccg_ref_freq,
359         .dccg_init = dccg314_init,
360         .set_dpstreamclk = dccg314_set_dpstreamclk,
361         .enable_symclk32_se = dccg31_enable_symclk32_se,
362         .disable_symclk32_se = dccg31_disable_symclk32_se,
363         .enable_symclk32_le = dccg31_enable_symclk32_le,
364         .disable_symclk32_le = dccg31_disable_symclk32_le,
365         .set_symclk32_le_root_clock_gating = dccg31_set_symclk32_le_root_clock_gating,
366         .set_physymclk = dccg31_set_physymclk,
367         .set_dtbclk_dto = dccg314_set_dtbclk_dto,
368         .set_audio_dtbclk_dto = dccg31_set_audio_dtbclk_dto,
369         .set_fifo_errdet_ovr_en = dccg2_set_fifo_errdet_ovr_en,
370         .otg_add_pixel = dccg31_otg_add_pixel,
371         .otg_drop_pixel = dccg31_otg_drop_pixel,
372         .set_dispclk_change_mode = dccg31_set_dispclk_change_mode,
373         .disable_dsc = dccg31_disable_dscclk,
374         .enable_dsc = dccg31_enable_dscclk,
375         .set_pixel_rate_div = dccg314_set_pixel_rate_div,
376         .trigger_dio_fifo_resync = dccg314_trigger_dio_fifo_resync,
377         .set_valid_pixel_rate = dccg314_set_valid_pixel_rate,
378 };
379
380 struct dccg *dccg314_create(
381         struct dc_context *ctx,
382         const struct dccg_registers *regs,
383         const struct dccg_shift *dccg_shift,
384         const struct dccg_mask *dccg_mask)
385 {
386         struct dcn_dccg *dccg_dcn = kzalloc(sizeof(*dccg_dcn), GFP_KERNEL);
387         struct dccg *base;
388
389         if (dccg_dcn == NULL) {
390                 BREAK_TO_DEBUGGER();
391                 return NULL;
392         }
393
394         base = &dccg_dcn->base;
395         base->ctx = ctx;
396         base->funcs = &dccg314_funcs;
397
398         dccg_dcn->regs = regs;
399         dccg_dcn->dccg_shift = dccg_shift;
400         dccg_dcn->dccg_mask = dccg_mask;
401
402         return &dccg_dcn->base;
403 }