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
0027 #include "reg_helper.h"
0028 #include "resource.h"
0029 #include "dwb.h"
0030 #include "dcn20_dwb.h"
0031
0032
0033 #define REG(reg)\
0034 dwbc20->dwbc_regs->reg
0035
0036 #define CTX \
0037 dwbc20->base.ctx
0038
0039 #define DC_LOGGER \
0040 dwbc20->base.ctx->logger
0041 #undef FN
0042 #define FN(reg_name, field_name) \
0043 dwbc20->dwbc_shift->field_name, dwbc20->dwbc_mask->field_name
0044
0045 enum dwb_outside_pix_strategy {
0046 DWB_OUTSIDE_PIX_STRATEGY_BLACK = 0,
0047 DWB_OUTSIDE_PIX_STRATEGY_EDGE = 1
0048 };
0049
0050 static bool dwb2_get_caps(struct dwbc *dwbc, struct dwb_caps *caps)
0051 {
0052 struct dcn20_dwbc *dwbc20 = TO_DCN20_DWBC(dwbc);
0053 if (caps) {
0054 caps->adapter_id = 0;
0055 caps->hw_version = DCN_VERSION_2_0;
0056 caps->num_pipes = 1;
0057 memset(&caps->reserved, 0, sizeof(caps->reserved));
0058 memset(&caps->reserved2, 0, sizeof(caps->reserved2));
0059 caps->sw_version = dwb_ver_1_0;
0060 caps->caps.support_dwb = true;
0061 caps->caps.support_ogam = false;
0062 caps->caps.support_wbscl = false;
0063 caps->caps.support_ocsc = false;
0064 DC_LOG_DWB("%s SUPPORTED! inst = %d", __func__, dwbc20->base.inst);
0065 return true;
0066 } else {
0067 DC_LOG_DWB("%s NOT SUPPORTED! inst = %d", __func__, dwbc20->base.inst);
0068 return false;
0069 }
0070 }
0071
0072 void dwb2_config_dwb_cnv(struct dwbc *dwbc, struct dc_dwb_params *params)
0073 {
0074 struct dcn20_dwbc *dwbc20 = TO_DCN20_DWBC(dwbc);
0075 DC_LOG_DWB("%s inst = %d", __func__, dwbc20->base.inst);
0076
0077
0078 REG_UPDATE_2(CNV_SOURCE_SIZE, CNV_SOURCE_WIDTH, params->cnv_params.src_width,
0079 CNV_SOURCE_HEIGHT, params->cnv_params.src_height);
0080
0081
0082 if (params->cnv_params.crop_en) {
0083 REG_UPDATE(CNV_MODE, CNV_WINDOW_CROP_EN, 1);
0084 REG_UPDATE(CNV_WINDOW_START, CNV_WINDOW_START_X, params->cnv_params.crop_x);
0085 REG_UPDATE(CNV_WINDOW_START, CNV_WINDOW_START_Y, params->cnv_params.crop_y);
0086 REG_UPDATE(CNV_WINDOW_SIZE, CNV_WINDOW_WIDTH, params->cnv_params.crop_width);
0087 REG_UPDATE(CNV_WINDOW_SIZE, CNV_WINDOW_HEIGHT, params->cnv_params.crop_height);
0088 } else {
0089 REG_UPDATE(CNV_MODE, CNV_WINDOW_CROP_EN, 0);
0090 }
0091
0092
0093 REG_UPDATE(CNV_MODE, CNV_FRAME_CAPTURE_RATE, params->capture_rate);
0094
0095
0096 REG_UPDATE(CNV_MODE, CNV_OUT_BPC, params->cnv_params.cnv_out_bpc);
0097 }
0098
0099 static bool dwb2_enable(struct dwbc *dwbc, struct dc_dwb_params *params)
0100 {
0101 struct dcn20_dwbc *dwbc20 = TO_DCN20_DWBC(dwbc);
0102
0103
0104 if ((params->cnv_params.src_width != params->dest_width) ||
0105 (params->cnv_params.src_height != params->dest_height)) {
0106
0107 DC_LOG_DWB("%s inst = %d, FAILED!LUMA SCALING NOT SUPPORTED", __func__, dwbc20->base.inst);
0108 return false;
0109 }
0110 DC_LOG_DWB("%s inst = %d, ENABLED", __func__, dwbc20->base.inst);
0111
0112
0113
0114
0115
0116
0117
0118 REG_UPDATE(WB_ENABLE, WB_ENABLE, 1);
0119
0120
0121 dwb2_config_dwb_cnv(dwbc, params);
0122
0123
0124 dwb2_set_scaler(dwbc, params);
0125
0126
0127 REG_UPDATE(CNV_MODE, CNV_FRAME_CAPTURE_EN, DWB_FRAME_CAPTURE_ENABLE);
0128
0129
0130 REG_UPDATE(WB_WARM_UP_MODE_CTL1, GMC_WARM_UP_ENABLE, 0);
0131
0132 return true;
0133 }
0134
0135 bool dwb2_disable(struct dwbc *dwbc)
0136 {
0137 struct dcn20_dwbc *dwbc20 = TO_DCN20_DWBC(dwbc);
0138 DC_LOG_DWB("%s inst = %d, Disabled", __func__, dwbc20->base.inst);
0139
0140
0141 REG_UPDATE(CNV_MODE, CNV_FRAME_CAPTURE_EN, DWB_FRAME_CAPTURE_DISABLE);
0142
0143
0144 REG_UPDATE(WB_ENABLE, WB_ENABLE, 0);
0145
0146
0147 REG_UPDATE(WB_SOFT_RESET, WB_SOFT_RESET, 1);
0148 REG_UPDATE(WB_SOFT_RESET, WB_SOFT_RESET, 0);
0149
0150
0151
0152
0153
0154
0155 return true;
0156 }
0157
0158 static bool dwb2_update(struct dwbc *dwbc, struct dc_dwb_params *params)
0159 {
0160 struct dcn20_dwbc *dwbc20 = TO_DCN20_DWBC(dwbc);
0161 unsigned int pre_locked;
0162
0163
0164 if ((params->cnv_params.src_width != params->dest_width) ||
0165 (params->cnv_params.src_height != params->dest_height)) {
0166 DC_LOG_DWB("%s inst = %d, FAILED!LUMA SCALING NOT SUPPORTED", __func__, dwbc20->base.inst);
0167 return false;
0168 }
0169 DC_LOG_DWB("%s inst = %d, scaling", __func__, dwbc20->base.inst);
0170
0171
0172
0173
0174
0175
0176
0177 REG_GET(CNV_UPDATE, CNV_UPDATE_LOCK, &pre_locked);
0178
0179 if (pre_locked == 0) {
0180
0181 REG_UPDATE(CNV_UPDATE, CNV_UPDATE_LOCK, 1);
0182 }
0183
0184
0185 dwb2_config_dwb_cnv(dwbc, params);
0186
0187
0188 dwb2_set_scaler(dwbc, params);
0189
0190 if (pre_locked == 0) {
0191
0192 REG_UPDATE(CNV_UPDATE, CNV_UPDATE_LOCK, 0);
0193 }
0194
0195 return true;
0196 }
0197
0198 bool dwb2_is_enabled(struct dwbc *dwbc)
0199 {
0200 struct dcn20_dwbc *dwbc20 = TO_DCN20_DWBC(dwbc);
0201 unsigned int wb_enabled = 0;
0202 unsigned int cnv_frame_capture_en = 0;
0203
0204 REG_GET(WB_ENABLE, WB_ENABLE, &wb_enabled);
0205 REG_GET(CNV_MODE, CNV_FRAME_CAPTURE_EN, &cnv_frame_capture_en);
0206
0207 return ((wb_enabled != 0) && (cnv_frame_capture_en != 0));
0208 }
0209
0210 void dwb2_set_stereo(struct dwbc *dwbc,
0211 struct dwb_stereo_params *stereo_params)
0212 {
0213 struct dcn20_dwbc *dwbc20 = TO_DCN20_DWBC(dwbc);
0214 DC_LOG_DWB("%s inst = %d, enabled =%d", __func__,\
0215 dwbc20->base.inst, stereo_params->stereo_enabled);
0216
0217 if (stereo_params->stereo_enabled) {
0218 REG_UPDATE(CNV_MODE, CNV_STEREO_TYPE, stereo_params->stereo_type);
0219 REG_UPDATE(CNV_MODE, CNV_EYE_SELECTION, stereo_params->stereo_eye_select);
0220 REG_UPDATE(CNV_MODE, CNV_STEREO_POLARITY, stereo_params->stereo_polarity);
0221 } else {
0222 REG_UPDATE(CNV_MODE, CNV_EYE_SELECTION, 0);
0223 }
0224 }
0225
0226 void dwb2_set_new_content(struct dwbc *dwbc,
0227 bool is_new_content)
0228 {
0229 struct dcn20_dwbc *dwbc20 = TO_DCN20_DWBC(dwbc);
0230 DC_LOG_DWB("%s inst = %d", __func__, dwbc20->base.inst);
0231
0232 REG_UPDATE(CNV_MODE, CNV_NEW_CONTENT, is_new_content);
0233 }
0234
0235 static void dwb2_set_warmup(struct dwbc *dwbc,
0236 struct dwb_warmup_params *warmup_params)
0237 {
0238 struct dcn20_dwbc *dwbc20 = TO_DCN20_DWBC(dwbc);
0239 DC_LOG_DWB("%s inst = %d", __func__, dwbc20->base.inst);
0240
0241 REG_UPDATE(WB_WARM_UP_MODE_CTL1, GMC_WARM_UP_ENABLE, warmup_params->warmup_en);
0242 REG_UPDATE(WB_WARM_UP_MODE_CTL1, WIDTH_WARMUP, warmup_params->warmup_width);
0243 REG_UPDATE(WB_WARM_UP_MODE_CTL1, HEIGHT_WARMUP, warmup_params->warmup_height);
0244
0245 REG_UPDATE(WB_WARM_UP_MODE_CTL2, DATA_VALUE_WARMUP, warmup_params->warmup_data);
0246 REG_UPDATE(WB_WARM_UP_MODE_CTL2, MODE_WARMUP, warmup_params->warmup_mode);
0247 REG_UPDATE(WB_WARM_UP_MODE_CTL2, DATA_DEPTH_WARMUP, warmup_params->warmup_depth);
0248 }
0249
0250 void dwb2_set_scaler(struct dwbc *dwbc, struct dc_dwb_params *params)
0251 {
0252 struct dcn20_dwbc *dwbc20 = TO_DCN20_DWBC(dwbc);
0253 DC_LOG_DWB("%s inst = %d", __func__, dwbc20->base.inst);
0254
0255
0256 REG_UPDATE_2(WBSCL_MODE, WBSCL_MODE, params->out_format,
0257 WBSCL_OUT_BIT_DEPTH, params->output_depth);
0258
0259 if (params->out_format != dwb_scaler_mode_bypass444) {
0260
0261 REG_UPDATE(WBSCL_DEST_SIZE, WBSCL_DEST_WIDTH, params->dest_width);
0262 REG_UPDATE(WBSCL_DEST_SIZE, WBSCL_DEST_HEIGHT, params->dest_height);
0263
0264
0265 REG_UPDATE(WBSCL_ROUND_OFFSET, WBSCL_ROUND_OFFSET_Y_RGB, 0x40);
0266 REG_UPDATE(WBSCL_ROUND_OFFSET, WBSCL_ROUND_OFFSET_CBCR, 0x200);
0267
0268
0269 REG_UPDATE(WBSCL_CLAMP_Y_RGB, WBSCL_CLAMP_UPPER_Y_RGB, 0x3fe);
0270 REG_UPDATE(WBSCL_CLAMP_Y_RGB, WBSCL_CLAMP_LOWER_Y_RGB, 0x1);
0271 REG_UPDATE(WBSCL_CLAMP_CBCR, WBSCL_CLAMP_UPPER_CBCR, 0x3fe);
0272 REG_UPDATE(WBSCL_CLAMP_CBCR, WBSCL_CLAMP_LOWER_CBCR, 0x1);
0273
0274
0275 REG_UPDATE(WBSCL_OUTSIDE_PIX_STRATEGY, WBSCL_OUTSIDE_PIX_STRATEGY, DWB_OUTSIDE_PIX_STRATEGY_EDGE);
0276
0277 if (params->cnv_params.crop_en) {
0278
0279 dwb_program_horz_scalar(dwbc20, params->cnv_params.crop_width,
0280 params->dest_width,
0281 params->scaler_taps);
0282
0283
0284 dwb_program_vert_scalar(dwbc20, params->cnv_params.crop_height,
0285 params->dest_height,
0286 params->scaler_taps,
0287 params->subsample_position);
0288 } else {
0289
0290 dwb_program_horz_scalar(dwbc20, params->cnv_params.src_width,
0291 params->dest_width,
0292 params->scaler_taps);
0293
0294
0295 dwb_program_vert_scalar(dwbc20, params->cnv_params.src_height,
0296 params->dest_height,
0297 params->scaler_taps,
0298 params->subsample_position);
0299 }
0300 }
0301
0302 }
0303
0304 const struct dwbc_funcs dcn20_dwbc_funcs = {
0305 .get_caps = dwb2_get_caps,
0306 .enable = dwb2_enable,
0307 .disable = dwb2_disable,
0308 .update = dwb2_update,
0309 .is_enabled = dwb2_is_enabled,
0310 .set_stereo = dwb2_set_stereo,
0311 .set_new_content = dwb2_set_new_content,
0312 .set_warmup = dwb2_set_warmup,
0313 .dwb_set_scaler = dwb2_set_scaler,
0314 };
0315
0316 void dcn20_dwbc_construct(struct dcn20_dwbc *dwbc20,
0317 struct dc_context *ctx,
0318 const struct dcn20_dwbc_registers *dwbc_regs,
0319 const struct dcn20_dwbc_shift *dwbc_shift,
0320 const struct dcn20_dwbc_mask *dwbc_mask,
0321 int inst)
0322 {
0323 dwbc20->base.ctx = ctx;
0324
0325 dwbc20->base.inst = inst;
0326 dwbc20->base.funcs = &dcn20_dwbc_funcs;
0327
0328 dwbc20->dwbc_regs = dwbc_regs;
0329 dwbc20->dwbc_shift = dwbc_shift;
0330 dwbc20->dwbc_mask = dwbc_mask;
0331 }
0332