0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026 #include "reg_helper.h"
0027 #include "core_types.h"
0028 #include "dcn32_dccg.h"
0029
0030 #define TO_DCN_DCCG(dccg)\
0031 container_of(dccg, struct dcn_dccg, base)
0032
0033 #define REG(reg) \
0034 (dccg_dcn->regs->reg)
0035
0036 #undef FN
0037 #define FN(reg_name, field_name) \
0038 dccg_dcn->dccg_shift->field_name, dccg_dcn->dccg_mask->field_name
0039
0040 #define CTX \
0041 dccg_dcn->base.ctx
0042 #define DC_LOGGER \
0043 dccg->ctx->logger
0044
0045 static void dccg32_get_pixel_rate_div(
0046 struct dccg *dccg,
0047 uint32_t otg_inst,
0048 enum pixel_rate_div *k1,
0049 enum pixel_rate_div *k2)
0050 {
0051 struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
0052 uint32_t val_k1 = PIXEL_RATE_DIV_NA, val_k2 = PIXEL_RATE_DIV_NA;
0053
0054 *k1 = PIXEL_RATE_DIV_NA;
0055 *k2 = PIXEL_RATE_DIV_NA;
0056
0057 switch (otg_inst) {
0058 case 0:
0059 REG_GET_2(OTG_PIXEL_RATE_DIV,
0060 OTG0_PIXEL_RATE_DIVK1, &val_k1,
0061 OTG0_PIXEL_RATE_DIVK2, &val_k2);
0062 break;
0063 case 1:
0064 REG_GET_2(OTG_PIXEL_RATE_DIV,
0065 OTG1_PIXEL_RATE_DIVK1, &val_k1,
0066 OTG1_PIXEL_RATE_DIVK2, &val_k2);
0067 break;
0068 case 2:
0069 REG_GET_2(OTG_PIXEL_RATE_DIV,
0070 OTG2_PIXEL_RATE_DIVK1, &val_k1,
0071 OTG2_PIXEL_RATE_DIVK2, &val_k2);
0072 break;
0073 case 3:
0074 REG_GET_2(OTG_PIXEL_RATE_DIV,
0075 OTG3_PIXEL_RATE_DIVK1, &val_k1,
0076 OTG3_PIXEL_RATE_DIVK2, &val_k2);
0077 break;
0078 default:
0079 BREAK_TO_DEBUGGER();
0080 return;
0081 }
0082
0083 *k1 = (enum pixel_rate_div)val_k1;
0084 *k2 = (enum pixel_rate_div)val_k2;
0085 }
0086
0087 static void dccg32_set_pixel_rate_div(
0088 struct dccg *dccg,
0089 uint32_t otg_inst,
0090 enum pixel_rate_div k1,
0091 enum pixel_rate_div k2)
0092 {
0093 struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
0094
0095 enum pixel_rate_div cur_k1 = PIXEL_RATE_DIV_NA, cur_k2 = PIXEL_RATE_DIV_NA;
0096
0097
0098
0099 if (k1 == PIXEL_RATE_DIV_NA || k2 == PIXEL_RATE_DIV_NA)
0100 return;
0101
0102 dccg32_get_pixel_rate_div(dccg, otg_inst, &cur_k1, &cur_k2);
0103 if (k1 == cur_k1 && k2 == cur_k2)
0104 return;
0105
0106 switch (otg_inst) {
0107 case 0:
0108 REG_UPDATE_2(OTG_PIXEL_RATE_DIV,
0109 OTG0_PIXEL_RATE_DIVK1, k1,
0110 OTG0_PIXEL_RATE_DIVK2, k2);
0111 break;
0112 case 1:
0113 REG_UPDATE_2(OTG_PIXEL_RATE_DIV,
0114 OTG1_PIXEL_RATE_DIVK1, k1,
0115 OTG1_PIXEL_RATE_DIVK2, k2);
0116 break;
0117 case 2:
0118 REG_UPDATE_2(OTG_PIXEL_RATE_DIV,
0119 OTG2_PIXEL_RATE_DIVK1, k1,
0120 OTG2_PIXEL_RATE_DIVK2, k2);
0121 break;
0122 case 3:
0123 REG_UPDATE_2(OTG_PIXEL_RATE_DIV,
0124 OTG3_PIXEL_RATE_DIVK1, k1,
0125 OTG3_PIXEL_RATE_DIVK2, k2);
0126 break;
0127 default:
0128 BREAK_TO_DEBUGGER();
0129 return;
0130 }
0131 }
0132
0133 static void dccg32_set_dtbclk_p_src(
0134 struct dccg *dccg,
0135 enum streamclk_source src,
0136 uint32_t otg_inst)
0137 {
0138 struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
0139
0140 uint32_t p_src_sel = 0;
0141 if (src == DTBCLK0)
0142 p_src_sel = 2;
0143
0144 switch (otg_inst) {
0145 case 0:
0146 if (src == REFCLK)
0147 REG_UPDATE(DTBCLK_P_CNTL,
0148 DTBCLK_P0_EN, 0);
0149 else
0150 REG_UPDATE_2(DTBCLK_P_CNTL,
0151 DTBCLK_P0_SRC_SEL, p_src_sel,
0152 DTBCLK_P0_EN, 1);
0153 break;
0154 case 1:
0155 if (src == REFCLK)
0156 REG_UPDATE(DTBCLK_P_CNTL,
0157 DTBCLK_P1_EN, 0);
0158 else
0159 REG_UPDATE_2(DTBCLK_P_CNTL,
0160 DTBCLK_P1_SRC_SEL, p_src_sel,
0161 DTBCLK_P1_EN, 1);
0162 break;
0163 case 2:
0164 if (src == REFCLK)
0165 REG_UPDATE(DTBCLK_P_CNTL,
0166 DTBCLK_P2_EN, 0);
0167 else
0168 REG_UPDATE_2(DTBCLK_P_CNTL,
0169 DTBCLK_P2_SRC_SEL, p_src_sel,
0170 DTBCLK_P2_EN, 1);
0171 break;
0172 case 3:
0173 if (src == REFCLK)
0174 REG_UPDATE(DTBCLK_P_CNTL,
0175 DTBCLK_P3_EN, 0);
0176 else
0177 REG_UPDATE_2(DTBCLK_P_CNTL,
0178 DTBCLK_P3_SRC_SEL, p_src_sel,
0179 DTBCLK_P3_EN, 1);
0180 break;
0181 default:
0182 BREAK_TO_DEBUGGER();
0183 return;
0184 }
0185
0186 }
0187
0188
0189 void dccg32_set_dtbclk_dto(
0190 struct dccg *dccg,
0191 const struct dtbclk_dto_params *params)
0192 {
0193 struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
0194
0195 int req_dtbclk_khz = params->pixclk_khz / 4;
0196
0197 if (params->ref_dtbclk_khz && req_dtbclk_khz) {
0198 uint32_t modulo, phase;
0199
0200
0201 modulo = params->ref_dtbclk_khz * 1000;
0202 phase = req_dtbclk_khz * 1000;
0203
0204 REG_WRITE(DTBCLK_DTO_MODULO[params->otg_inst], modulo);
0205 REG_WRITE(DTBCLK_DTO_PHASE[params->otg_inst], phase);
0206
0207 REG_UPDATE(OTG_PIXEL_RATE_CNTL[params->otg_inst],
0208 DTBCLK_DTO_ENABLE[params->otg_inst], 1);
0209
0210 REG_WAIT(OTG_PIXEL_RATE_CNTL[params->otg_inst],
0211 DTBCLKDTO_ENABLE_STATUS[params->otg_inst], 1,
0212 1, 100);
0213
0214
0215 dccg32_set_pixel_rate_div(dccg, params->otg_inst, PIXEL_RATE_DIV_BY_1, PIXEL_RATE_DIV_BY_1);
0216
0217
0218
0219
0220
0221 REG_UPDATE(OTG_PIXEL_RATE_CNTL[params->otg_inst],
0222 PIPE_DTO_SRC_SEL[params->otg_inst], 2);
0223 } else {
0224 REG_UPDATE_2(OTG_PIXEL_RATE_CNTL[params->otg_inst],
0225 DTBCLK_DTO_ENABLE[params->otg_inst], 0,
0226 PIPE_DTO_SRC_SEL[params->otg_inst], 1);
0227 if (params->is_hdmi)
0228 REG_UPDATE(OTG_PIXEL_RATE_CNTL[params->otg_inst],
0229 PIPE_DTO_SRC_SEL[params->otg_inst], 0);
0230
0231 REG_WRITE(DTBCLK_DTO_MODULO[params->otg_inst], 0);
0232 REG_WRITE(DTBCLK_DTO_PHASE[params->otg_inst], 0);
0233 }
0234 }
0235
0236 static void dccg32_set_valid_pixel_rate(
0237 struct dccg *dccg,
0238 int ref_dtbclk_khz,
0239 int otg_inst,
0240 int pixclk_khz)
0241 {
0242 struct dtbclk_dto_params dto_params = {0};
0243
0244 dto_params.ref_dtbclk_khz = ref_dtbclk_khz;
0245 dto_params.otg_inst = otg_inst;
0246 dto_params.pixclk_khz = pixclk_khz;
0247 dto_params.is_hdmi = true;
0248
0249 dccg32_set_dtbclk_dto(dccg, &dto_params);
0250 }
0251
0252 static void dccg32_get_dccg_ref_freq(struct dccg *dccg,
0253 unsigned int xtalin_freq_inKhz,
0254 unsigned int *dccg_ref_freq_inKhz)
0255 {
0256
0257
0258
0259
0260 *dccg_ref_freq_inKhz = xtalin_freq_inKhz;
0261 return;
0262 }
0263
0264 void dccg32_set_dpstreamclk(
0265 struct dccg *dccg,
0266 enum streamclk_source src,
0267 int otg_inst,
0268 int dp_hpo_inst)
0269 {
0270 struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
0271
0272
0273 dccg32_set_dtbclk_p_src(dccg, src, otg_inst);
0274
0275
0276 switch (otg_inst)
0277 {
0278 case 0:
0279 REG_UPDATE_2(DPSTREAMCLK_CNTL,
0280 DPSTREAMCLK0_EN,
0281 (src == REFCLK) ? 0 : 1, DPSTREAMCLK0_SRC_SEL, otg_inst);
0282 break;
0283 case 1:
0284 REG_UPDATE_2(DPSTREAMCLK_CNTL, DPSTREAMCLK1_EN,
0285 (src == REFCLK) ? 0 : 1, DPSTREAMCLK1_SRC_SEL, otg_inst);
0286 break;
0287 case 2:
0288 REG_UPDATE_2(DPSTREAMCLK_CNTL, DPSTREAMCLK2_EN,
0289 (src == REFCLK) ? 0 : 1, DPSTREAMCLK2_SRC_SEL, otg_inst);
0290 break;
0291 case 3:
0292 REG_UPDATE_2(DPSTREAMCLK_CNTL, DPSTREAMCLK3_EN,
0293 (src == REFCLK) ? 0 : 1, DPSTREAMCLK3_SRC_SEL, otg_inst);
0294 break;
0295 default:
0296 BREAK_TO_DEBUGGER();
0297 return;
0298 }
0299 }
0300
0301 void dccg32_otg_add_pixel(struct dccg *dccg,
0302 uint32_t otg_inst)
0303 {
0304 struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
0305
0306 REG_UPDATE(OTG_PIXEL_RATE_CNTL[otg_inst],
0307 OTG_ADD_PIXEL[otg_inst], 1);
0308 }
0309
0310 void dccg32_otg_drop_pixel(struct dccg *dccg,
0311 uint32_t otg_inst)
0312 {
0313 struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
0314
0315 REG_UPDATE(OTG_PIXEL_RATE_CNTL[otg_inst],
0316 OTG_DROP_PIXEL[otg_inst], 1);
0317 }
0318
0319 static const struct dccg_funcs dccg32_funcs = {
0320 .update_dpp_dto = dccg2_update_dpp_dto,
0321 .get_dccg_ref_freq = dccg32_get_dccg_ref_freq,
0322 .dccg_init = dccg31_init,
0323 .set_dpstreamclk = dccg32_set_dpstreamclk,
0324 .enable_symclk32_se = dccg31_enable_symclk32_se,
0325 .disable_symclk32_se = dccg31_disable_symclk32_se,
0326 .enable_symclk32_le = dccg31_enable_symclk32_le,
0327 .disable_symclk32_le = dccg31_disable_symclk32_le,
0328 .set_physymclk = dccg31_set_physymclk,
0329 .set_dtbclk_dto = dccg32_set_dtbclk_dto,
0330 .set_valid_pixel_rate = dccg32_set_valid_pixel_rate,
0331 .set_fifo_errdet_ovr_en = dccg2_set_fifo_errdet_ovr_en,
0332 .set_audio_dtbclk_dto = dccg31_set_audio_dtbclk_dto,
0333 .otg_add_pixel = dccg32_otg_add_pixel,
0334 .otg_drop_pixel = dccg32_otg_drop_pixel,
0335 .set_pixel_rate_div = dccg32_set_pixel_rate_div,
0336 };
0337
0338 struct dccg *dccg32_create(
0339 struct dc_context *ctx,
0340 const struct dccg_registers *regs,
0341 const struct dccg_shift *dccg_shift,
0342 const struct dccg_mask *dccg_mask)
0343 {
0344 struct dcn_dccg *dccg_dcn = kzalloc(sizeof(*dccg_dcn), GFP_KERNEL);
0345 struct dccg *base;
0346
0347 if (dccg_dcn == NULL) {
0348 BREAK_TO_DEBUGGER();
0349 return NULL;
0350 }
0351
0352 base = &dccg_dcn->base;
0353 base->ctx = ctx;
0354 base->funcs = &dccg32_funcs;
0355
0356 dccg_dcn->regs = regs;
0357 dccg_dcn->dccg_shift = dccg_shift;
0358 dccg_dcn->dccg_mask = dccg_mask;
0359
0360 return &dccg_dcn->base;
0361 }