drm/amdgpu/display: fix DCN3.2 Makefiles for non-x86
[linux-2.6-microblaze.git] / drivers / gpu / drm / amd / display / dc / dcn32 / dcn32_dccg.c
1 /*
2  * Copyright 2021 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 "dcn32_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 #define DC_LOGGER \
43         dccg->ctx->logger
44
45 static void dccg32_set_pixel_rate_div(
46                 struct dccg *dccg,
47                 uint32_t otg_inst,
48                 enum pixel_rate_div k1,
49                 enum pixel_rate_div k2)
50 {
51         struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
52
53         switch (otg_inst) {
54         case 0:
55                 REG_UPDATE_2(OTG_PIXEL_RATE_DIV,
56                                 OTG0_PIXEL_RATE_DIVK1, k1,
57                                 OTG0_PIXEL_RATE_DIVK2, k2);
58                 break;
59         case 1:
60                 REG_UPDATE_2(OTG_PIXEL_RATE_DIV,
61                                 OTG1_PIXEL_RATE_DIVK1, k1,
62                                 OTG1_PIXEL_RATE_DIVK2, k2);
63                 break;
64         case 2:
65                 REG_UPDATE_2(OTG_PIXEL_RATE_DIV,
66                                 OTG2_PIXEL_RATE_DIVK1, k1,
67                                 OTG2_PIXEL_RATE_DIVK2, k2);
68                 break;
69         case 3:
70                 REG_UPDATE_2(OTG_PIXEL_RATE_DIV,
71                                 OTG3_PIXEL_RATE_DIVK1, k1,
72                                 OTG3_PIXEL_RATE_DIVK2, k2);
73                 break;
74         default:
75                 BREAK_TO_DEBUGGER();
76                 return;
77         }
78 }
79
80 static void dccg32_set_dtbclk_p_src(
81                 struct dccg *dccg,
82                 enum streamclk_source src,
83                 uint32_t otg_inst)
84 {
85         struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
86
87         uint32_t p_src_sel = 0; /* selects dprefclk */
88         if (src == DTBCLK0)
89                 p_src_sel = 2;  /* selects dtbclk0 */
90
91         switch (otg_inst) {
92         case 0:
93                 if (src == REFCLK)
94                         REG_UPDATE(DTBCLK_P_CNTL,
95                                         DTBCLK_P0_EN, 0);
96                 else
97                         REG_UPDATE_2(DTBCLK_P_CNTL,
98                                         DTBCLK_P0_SRC_SEL, p_src_sel,
99                                         DTBCLK_P0_EN, 1);
100                 break;
101         case 1:
102                 if (src == REFCLK)
103                         REG_UPDATE(DTBCLK_P_CNTL,
104                                         DTBCLK_P1_EN, 0);
105                 else
106                         REG_UPDATE_2(DTBCLK_P_CNTL,
107                                         DTBCLK_P1_SRC_SEL, p_src_sel,
108                                         DTBCLK_P1_EN, 1);
109                 break;
110         case 2:
111                 if (src == REFCLK)
112                         REG_UPDATE(DTBCLK_P_CNTL,
113                                         DTBCLK_P2_EN, 0);
114                 else
115                         REG_UPDATE_2(DTBCLK_P_CNTL,
116                                         DTBCLK_P2_SRC_SEL, p_src_sel,
117                                         DTBCLK_P2_EN, 1);
118                 break;
119         case 3:
120                 if (src == REFCLK)
121                         REG_UPDATE(DTBCLK_P_CNTL,
122                                         DTBCLK_P3_EN, 0);
123                 else
124                         REG_UPDATE_2(DTBCLK_P_CNTL,
125                                         DTBCLK_P3_SRC_SEL, p_src_sel,
126                                         DTBCLK_P3_EN, 1);
127                 break;
128         default:
129                 BREAK_TO_DEBUGGER();
130                 return;
131         }
132
133 }
134
135 /* Controls the generation of pixel valid for OTG in (OTG -> HPO case) */
136 void dccg32_set_dtbclk_dto(
137                 struct dccg *dccg,
138                 const struct dtbclk_dto_params *params)
139 {
140         struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
141         /* DTO Output Rate / Pixel Rate = 1/4 */
142         int req_dtbclk_khz = params->pixclk_khz / 4;
143
144         if (params->ref_dtbclk_khz && req_dtbclk_khz) {
145                 uint32_t modulo, phase;
146
147                 // phase / modulo = dtbclk / dtbclk ref
148                 modulo = params->ref_dtbclk_khz * 1000;
149                 phase = req_dtbclk_khz * 1000;
150
151                 REG_WRITE(DTBCLK_DTO_MODULO[params->otg_inst], modulo);
152                 REG_WRITE(DTBCLK_DTO_PHASE[params->otg_inst], phase);
153
154                 REG_UPDATE(OTG_PIXEL_RATE_CNTL[params->otg_inst],
155                                 DTBCLK_DTO_ENABLE[params->otg_inst], 1);
156
157                 REG_WAIT(OTG_PIXEL_RATE_CNTL[params->otg_inst],
158                                 DTBCLKDTO_ENABLE_STATUS[params->otg_inst], 1,
159                                 1, 100);
160
161                 /* program OTG_PIXEL_RATE_DIV for DIVK1 and DIVK2 fields */
162                 dccg32_set_pixel_rate_div(dccg, params->otg_inst, PIXEL_RATE_DIV_BY_1, PIXEL_RATE_DIV_BY_1);
163
164                 /* The recommended programming sequence to enable DTBCLK DTO to generate
165                  * valid pixel HPO DPSTREAM ENCODER, specifies that DTO source select should
166                  * be set only after DTO is enabled
167                  */
168                 REG_UPDATE(OTG_PIXEL_RATE_CNTL[params->otg_inst],
169                                 PIPE_DTO_SRC_SEL[params->otg_inst], 2);
170         } else {
171                 REG_UPDATE_2(OTG_PIXEL_RATE_CNTL[params->otg_inst],
172                                 DTBCLK_DTO_ENABLE[params->otg_inst], 0,
173                                 PIPE_DTO_SRC_SEL[params->otg_inst], 1);
174
175                 REG_WRITE(DTBCLK_DTO_MODULO[params->otg_inst], 0);
176                 REG_WRITE(DTBCLK_DTO_PHASE[params->otg_inst], 0);
177         }
178 }
179
180 static void dccg32_set_valid_pixel_rate(
181                 struct dccg *dccg,
182                 int ref_dtbclk_khz,
183                 int otg_inst,
184                 int pixclk_khz)
185 {
186         struct dtbclk_dto_params dto_params = {0};
187
188         dto_params.ref_dtbclk_khz = ref_dtbclk_khz;
189         dto_params.otg_inst = otg_inst;
190         dto_params.pixclk_khz = pixclk_khz;
191
192         dccg32_set_dtbclk_dto(dccg, &dto_params);
193 }
194
195 static void dccg32_get_dccg_ref_freq(struct dccg *dccg,
196                 unsigned int xtalin_freq_inKhz,
197                 unsigned int *dccg_ref_freq_inKhz)
198 {
199         /*
200          * Assume refclk is sourced from xtalin
201          * expect 100MHz
202          */
203         *dccg_ref_freq_inKhz = xtalin_freq_inKhz;
204         return;
205 }
206
207 void dccg32_set_dpstreamclk(
208                 struct dccg *dccg,
209                 enum streamclk_source src,
210                 int otg_inst)
211 {
212         struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
213
214         /* set the dtbclk_p source */
215         dccg32_set_dtbclk_p_src(dccg, src, otg_inst);
216
217         /* enabled to select one of the DTBCLKs for pipe */
218         switch (otg_inst)
219         {
220         case 0:
221                 REG_UPDATE_2(DPSTREAMCLK_CNTL,
222                              DPSTREAMCLK0_EN,
223                              (src == REFCLK) ? 0 : 1, DPSTREAMCLK0_SRC_SEL, 0);
224                 break;
225         case 1:
226                 REG_UPDATE_2(DPSTREAMCLK_CNTL, DPSTREAMCLK1_EN,
227                              (src == REFCLK) ? 0 : 1, DPSTREAMCLK1_SRC_SEL, 1);
228                 break;
229         case 2:
230                 REG_UPDATE_2(DPSTREAMCLK_CNTL, DPSTREAMCLK2_EN,
231                              (src == REFCLK) ? 0 : 1, DPSTREAMCLK2_SRC_SEL, 2);
232                 break;
233         case 3:
234                 REG_UPDATE_2(DPSTREAMCLK_CNTL, DPSTREAMCLK3_EN,
235                              (src == REFCLK) ? 0 : 1, DPSTREAMCLK3_SRC_SEL, 3);
236                 break;
237         default:
238                 BREAK_TO_DEBUGGER();
239                 return;
240         }
241 }
242
243 void dccg32_otg_add_pixel(struct dccg *dccg,
244                 uint32_t otg_inst)
245 {
246         struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
247
248         REG_UPDATE(OTG_PIXEL_RATE_CNTL[otg_inst],
249                         OTG_ADD_PIXEL[otg_inst], 1);
250 }
251
252 void dccg32_otg_drop_pixel(struct dccg *dccg,
253                 uint32_t otg_inst)
254 {
255         struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
256
257         REG_UPDATE(OTG_PIXEL_RATE_CNTL[otg_inst],
258                         OTG_DROP_PIXEL[otg_inst], 1);
259 }
260
261 static const struct dccg_funcs dccg32_funcs = {
262         .update_dpp_dto = dccg2_update_dpp_dto,
263         .get_dccg_ref_freq = dccg32_get_dccg_ref_freq,
264         .dccg_init = dccg31_init,
265         .set_dpstreamclk = dccg32_set_dpstreamclk,
266         .enable_symclk32_se = dccg31_enable_symclk32_se,
267         .disable_symclk32_se = dccg31_disable_symclk32_se,
268         .enable_symclk32_le = dccg31_enable_symclk32_le,
269         .disable_symclk32_le = dccg31_disable_symclk32_le,
270         .set_physymclk = dccg31_set_physymclk,
271         .set_dtbclk_dto = dccg32_set_dtbclk_dto,
272         .set_valid_pixel_rate = dccg32_set_valid_pixel_rate,
273         .set_fifo_errdet_ovr_en = dccg2_set_fifo_errdet_ovr_en,
274         .set_audio_dtbclk_dto = dccg31_set_audio_dtbclk_dto,
275         .otg_add_pixel = dccg32_otg_add_pixel,
276         .otg_drop_pixel = dccg32_otg_drop_pixel,
277         .set_pixel_rate_div = dccg32_set_pixel_rate_div,
278 };
279
280 struct dccg *dccg32_create(
281         struct dc_context *ctx,
282         const struct dccg_registers *regs,
283         const struct dccg_shift *dccg_shift,
284         const struct dccg_mask *dccg_mask)
285 {
286         struct dcn_dccg *dccg_dcn = kzalloc(sizeof(*dccg_dcn), GFP_KERNEL);
287         struct dccg *base;
288
289         if (dccg_dcn == NULL) {
290                 BREAK_TO_DEBUGGER();
291                 return NULL;
292         }
293
294         base = &dccg_dcn->base;
295         base->ctx = ctx;
296         base->funcs = &dccg32_funcs;
297
298         dccg_dcn->regs = regs;
299         dccg_dcn->dccg_shift = dccg_shift;
300         dccg_dcn->dccg_mask = dccg_mask;
301
302         return &dccg_dcn->base;
303 }