Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: MIT
0002 /*
0003  * Copyright 2022 Advanced Micro Devices, Inc.
0004  *
0005  * Permission is hereby granted, free of charge, to any person obtaining a
0006  * copy of this software and associated documentation files (the "Software"),
0007  * to deal in the Software without restriction, including without limitation
0008  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
0009  * and/or sell copies of the Software, and to permit persons to whom the
0010  * Software is furnished to do so, subject to the following conditions:
0011  *
0012  * The above copyright notice and this permission notice shall be included in
0013  * all copies or substantial portions of the Software.
0014  *
0015  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0016  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0017  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
0018  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
0019  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
0020  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
0021  * OTHER DEALINGS IN THE SOFTWARE.
0022  *
0023  * Authors: AMD
0024  *
0025  */
0026 
0027 #include "reg_helper.h"
0028 #include "core_types.h"
0029 
0030 #include "dcn31/dcn31_dccg.h"
0031 #include "dcn314_dccg.h"
0032 
0033 #define TO_DCN_DCCG(dccg)\
0034     container_of(dccg, struct dcn_dccg, base)
0035 
0036 #define REG(reg) \
0037     (dccg_dcn->regs->reg)
0038 
0039 #undef FN
0040 #define FN(reg_name, field_name) \
0041     dccg_dcn->dccg_shift->field_name, dccg_dcn->dccg_mask->field_name
0042 
0043 #define CTX \
0044     dccg_dcn->base.ctx
0045 #define DC_LOGGER \
0046     dccg->ctx->logger
0047 
0048 static void dccg314_get_pixel_rate_div(
0049         struct dccg *dccg,
0050         uint32_t otg_inst,
0051         enum pixel_rate_div *k1,
0052         enum pixel_rate_div *k2)
0053 {
0054     struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
0055     uint32_t val_k1 = PIXEL_RATE_DIV_NA, val_k2 = PIXEL_RATE_DIV_NA;
0056 
0057     *k1 = PIXEL_RATE_DIV_NA;
0058     *k2 = PIXEL_RATE_DIV_NA;
0059 
0060     switch (otg_inst) {
0061     case 0:
0062         REG_GET_2(OTG_PIXEL_RATE_DIV,
0063             OTG0_PIXEL_RATE_DIVK1, &val_k1,
0064             OTG0_PIXEL_RATE_DIVK2, &val_k2);
0065         break;
0066     case 1:
0067         REG_GET_2(OTG_PIXEL_RATE_DIV,
0068             OTG1_PIXEL_RATE_DIVK1, &val_k1,
0069             OTG1_PIXEL_RATE_DIVK2, &val_k2);
0070         break;
0071     case 2:
0072         REG_GET_2(OTG_PIXEL_RATE_DIV,
0073             OTG2_PIXEL_RATE_DIVK1, &val_k1,
0074             OTG2_PIXEL_RATE_DIVK2, &val_k2);
0075         break;
0076     case 3:
0077         REG_GET_2(OTG_PIXEL_RATE_DIV,
0078             OTG3_PIXEL_RATE_DIVK1, &val_k1,
0079             OTG3_PIXEL_RATE_DIVK2, &val_k2);
0080         break;
0081     default:
0082         BREAK_TO_DEBUGGER();
0083         return;
0084     }
0085 
0086     *k1 = (enum pixel_rate_div)val_k1;
0087     *k2 = (enum pixel_rate_div)val_k2;
0088 }
0089 
0090 static void dccg314_set_pixel_rate_div(
0091         struct dccg *dccg,
0092         uint32_t otg_inst,
0093         enum pixel_rate_div k1,
0094         enum pixel_rate_div k2)
0095 {
0096     struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
0097     enum pixel_rate_div cur_k1 = PIXEL_RATE_DIV_NA, cur_k2 = PIXEL_RATE_DIV_NA;
0098 
0099     dccg314_get_pixel_rate_div(dccg, otg_inst, &cur_k1, &cur_k2);
0100     if (k1 == PIXEL_RATE_DIV_NA || k2 == PIXEL_RATE_DIV_NA || (k1 == cur_k1 && k2 == cur_k2))
0101         return;
0102 
0103     switch (otg_inst) {
0104     case 0:
0105         REG_UPDATE_2(OTG_PIXEL_RATE_DIV,
0106                 OTG0_PIXEL_RATE_DIVK1, k1,
0107                 OTG0_PIXEL_RATE_DIVK2, k2);
0108         break;
0109     case 1:
0110         REG_UPDATE_2(OTG_PIXEL_RATE_DIV,
0111                 OTG1_PIXEL_RATE_DIVK1, k1,
0112                 OTG1_PIXEL_RATE_DIVK2, k2);
0113         break;
0114     case 2:
0115         REG_UPDATE_2(OTG_PIXEL_RATE_DIV,
0116                 OTG2_PIXEL_RATE_DIVK1, k1,
0117                 OTG2_PIXEL_RATE_DIVK2, k2);
0118         break;
0119     case 3:
0120         REG_UPDATE_2(OTG_PIXEL_RATE_DIV,
0121                 OTG3_PIXEL_RATE_DIVK1, k1,
0122                 OTG3_PIXEL_RATE_DIVK2, k2);
0123         break;
0124     default:
0125         BREAK_TO_DEBUGGER();
0126         return;
0127     }
0128 }
0129 
0130 static void dccg314_set_dtbclk_p_src(
0131         struct dccg *dccg,
0132         enum streamclk_source src,
0133         uint32_t otg_inst)
0134 {
0135     struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
0136 
0137     uint32_t p_src_sel = 0; /* selects dprefclk */
0138 
0139     if (src == DTBCLK0)
0140         p_src_sel = 2;  /* selects dtbclk0 */
0141 
0142     switch (otg_inst) {
0143     case 0:
0144         if (src == REFCLK)
0145             REG_UPDATE(DTBCLK_P_CNTL,
0146                     DTBCLK_P0_EN, 0);
0147         else
0148             REG_UPDATE_2(DTBCLK_P_CNTL,
0149                     DTBCLK_P0_SRC_SEL, p_src_sel,
0150                     DTBCLK_P0_EN, 1);
0151         break;
0152     case 1:
0153         if (src == REFCLK)
0154             REG_UPDATE(DTBCLK_P_CNTL,
0155                     DTBCLK_P1_EN, 0);
0156         else
0157             REG_UPDATE_2(DTBCLK_P_CNTL,
0158                     DTBCLK_P1_SRC_SEL, p_src_sel,
0159                     DTBCLK_P1_EN, 1);
0160         break;
0161     case 2:
0162         if (src == REFCLK)
0163             REG_UPDATE(DTBCLK_P_CNTL,
0164                     DTBCLK_P2_EN, 0);
0165         else
0166             REG_UPDATE_2(DTBCLK_P_CNTL,
0167                     DTBCLK_P2_SRC_SEL, p_src_sel,
0168                     DTBCLK_P2_EN, 1);
0169         break;
0170     case 3:
0171         if (src == REFCLK)
0172             REG_UPDATE(DTBCLK_P_CNTL,
0173                     DTBCLK_P3_EN, 0);
0174         else
0175             REG_UPDATE_2(DTBCLK_P_CNTL,
0176                     DTBCLK_P3_SRC_SEL, p_src_sel,
0177                     DTBCLK_P3_EN, 1);
0178         break;
0179     default:
0180         BREAK_TO_DEBUGGER();
0181         return;
0182     }
0183 
0184 }
0185 
0186 /* Controls the generation of pixel valid for OTG in (OTG -> HPO case) */
0187 void dccg314_set_dtbclk_dto(
0188         struct dccg *dccg,
0189         const struct dtbclk_dto_params *params)
0190 {
0191     struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
0192     /* DTO Output Rate / Pixel Rate = 1/4 */
0193     int req_dtbclk_khz = params->pixclk_khz / 4;
0194 
0195     if (params->ref_dtbclk_khz && req_dtbclk_khz) {
0196         uint32_t modulo, phase;
0197 
0198         // phase / modulo = dtbclk / dtbclk ref
0199         modulo = params->ref_dtbclk_khz * 1000;
0200         phase = req_dtbclk_khz * 1000;
0201 
0202         REG_WRITE(DTBCLK_DTO_MODULO[params->otg_inst], modulo);
0203         REG_WRITE(DTBCLK_DTO_PHASE[params->otg_inst], phase);
0204 
0205         REG_UPDATE(OTG_PIXEL_RATE_CNTL[params->otg_inst],
0206                 DTBCLK_DTO_ENABLE[params->otg_inst], 1);
0207 
0208         REG_WAIT(OTG_PIXEL_RATE_CNTL[params->otg_inst],
0209                 DTBCLKDTO_ENABLE_STATUS[params->otg_inst], 1,
0210                 1, 100);
0211 
0212         /* program OTG_PIXEL_RATE_DIV for DIVK1 and DIVK2 fields */
0213         dccg314_set_pixel_rate_div(dccg, params->otg_inst, PIXEL_RATE_DIV_BY_1, PIXEL_RATE_DIV_BY_1);
0214 
0215         /* The recommended programming sequence to enable DTBCLK DTO to generate
0216          * valid pixel HPO DPSTREAM ENCODER, specifies that DTO source select should
0217          * be set only after DTO is enabled
0218          */
0219         REG_UPDATE(OTG_PIXEL_RATE_CNTL[params->otg_inst],
0220                 PIPE_DTO_SRC_SEL[params->otg_inst], 2);
0221     } else {
0222         REG_UPDATE_2(OTG_PIXEL_RATE_CNTL[params->otg_inst],
0223                 DTBCLK_DTO_ENABLE[params->otg_inst], 0,
0224                 PIPE_DTO_SRC_SEL[params->otg_inst], 1);
0225 
0226         REG_WRITE(DTBCLK_DTO_MODULO[params->otg_inst], 0);
0227         REG_WRITE(DTBCLK_DTO_PHASE[params->otg_inst], 0);
0228     }
0229 }
0230 
0231 void dccg314_set_dpstreamclk(
0232         struct dccg *dccg,
0233         enum streamclk_source src,
0234         int otg_inst,
0235         int dp_hpo_inst)
0236 {
0237     struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
0238 
0239     /* set the dtbclk_p source */
0240     dccg314_set_dtbclk_p_src(dccg, src, otg_inst);
0241 
0242     /* enabled to select one of the DTBCLKs for pipe */
0243     switch (dp_hpo_inst) {
0244     case 0:
0245         REG_UPDATE_2(DPSTREAMCLK_CNTL,
0246                     DPSTREAMCLK0_EN, (src == REFCLK) ? 0 : 1,
0247                     DPSTREAMCLK0_SRC_SEL, otg_inst);
0248         break;
0249     case 1:
0250         REG_UPDATE_2(DPSTREAMCLK_CNTL,
0251                     DPSTREAMCLK1_EN, (src == REFCLK) ? 0 : 1,
0252                     DPSTREAMCLK1_SRC_SEL, otg_inst);
0253         break;
0254     case 2:
0255         REG_UPDATE_2(DPSTREAMCLK_CNTL,
0256                     DPSTREAMCLK2_EN, (src == REFCLK) ? 0 : 1,
0257                     DPSTREAMCLK2_SRC_SEL, otg_inst);
0258         break;
0259     case 3:
0260         REG_UPDATE_2(DPSTREAMCLK_CNTL,
0261                     DPSTREAMCLK3_EN, (src == REFCLK) ? 0 : 1,
0262                     DPSTREAMCLK3_SRC_SEL, otg_inst);
0263         break;
0264     default:
0265         BREAK_TO_DEBUGGER();
0266         return;
0267     }
0268 }
0269 
0270 void dccg314_set_valid_pixel_rate(
0271         struct dccg *dccg,
0272         int ref_dtbclk_khz,
0273         int otg_inst,
0274         int pixclk_khz)
0275 {
0276     struct dtbclk_dto_params dto_params = {0};
0277 
0278     dto_params.ref_dtbclk_khz = ref_dtbclk_khz;
0279     dto_params.otg_inst = otg_inst;
0280     dto_params.pixclk_khz = pixclk_khz;
0281 
0282     dccg314_set_dtbclk_dto(dccg, &dto_params);
0283 }
0284 
0285 static const struct dccg_funcs dccg314_funcs = {
0286     .update_dpp_dto = dccg31_update_dpp_dto,
0287     .get_dccg_ref_freq = dccg31_get_dccg_ref_freq,
0288     .dccg_init = dccg31_init,
0289     .set_dpstreamclk = dccg314_set_dpstreamclk,
0290     .enable_symclk32_se = dccg31_enable_symclk32_se,
0291     .disable_symclk32_se = dccg31_disable_symclk32_se,
0292     .enable_symclk32_le = dccg31_enable_symclk32_le,
0293     .disable_symclk32_le = dccg31_disable_symclk32_le,
0294     .set_physymclk = dccg31_set_physymclk,
0295     .set_dtbclk_dto = dccg314_set_dtbclk_dto,
0296     .set_audio_dtbclk_dto = dccg31_set_audio_dtbclk_dto,
0297     .set_fifo_errdet_ovr_en = dccg2_set_fifo_errdet_ovr_en,
0298     .otg_add_pixel = dccg31_otg_add_pixel,
0299     .otg_drop_pixel = dccg31_otg_drop_pixel,
0300     .set_dispclk_change_mode = dccg31_set_dispclk_change_mode,
0301     .disable_dsc = dccg31_disable_dscclk,
0302     .enable_dsc = dccg31_enable_dscclk,
0303     .set_pixel_rate_div = dccg314_set_pixel_rate_div,
0304     .set_valid_pixel_rate = dccg314_set_valid_pixel_rate,
0305 };
0306 
0307 struct dccg *dccg314_create(
0308     struct dc_context *ctx,
0309     const struct dccg_registers *regs,
0310     const struct dccg_shift *dccg_shift,
0311     const struct dccg_mask *dccg_mask)
0312 {
0313     struct dcn_dccg *dccg_dcn = kzalloc(sizeof(*dccg_dcn), GFP_KERNEL);
0314     struct dccg *base;
0315 
0316     if (dccg_dcn == NULL) {
0317         BREAK_TO_DEBUGGER();
0318         return NULL;
0319     }
0320 
0321     base = &dccg_dcn->base;
0322     base->ctx = ctx;
0323     base->funcs = &dccg314_funcs;
0324 
0325     dccg_dcn->regs = regs;
0326     dccg_dcn->dccg_shift = dccg_shift;
0327     dccg_dcn->dccg_mask = dccg_mask;
0328 
0329     return &dccg_dcn->base;
0330 }