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 "dce_ipp.h"
0027 #include "reg_helper.h"
0028 #include "dm_services.h"
0029
0030 #define REG(reg) \
0031 (ipp_dce->regs->reg)
0032
0033 #undef FN
0034 #define FN(reg_name, field_name) \
0035 ipp_dce->ipp_shift->field_name, ipp_dce->ipp_mask->field_name
0036
0037 #define CTX \
0038 ipp_dce->base.ctx
0039
0040
0041 static void dce_ipp_cursor_set_position(
0042 struct input_pixel_processor *ipp,
0043 const struct dc_cursor_position *position,
0044 const struct dc_cursor_mi_param *param)
0045 {
0046 struct dce_ipp *ipp_dce = TO_DCE_IPP(ipp);
0047
0048
0049 REG_UPDATE(CUR_UPDATE, CURSOR_UPDATE_LOCK, true);
0050
0051
0052
0053 REG_UPDATE(CUR_CONTROL, CURSOR_EN, position->enable);
0054
0055 REG_SET_2(CUR_POSITION, 0,
0056 CURSOR_X_POSITION, position->x,
0057 CURSOR_Y_POSITION, position->y);
0058
0059 REG_SET_2(CUR_HOT_SPOT, 0,
0060 CURSOR_HOT_SPOT_X, position->x_hotspot,
0061 CURSOR_HOT_SPOT_Y, position->y_hotspot);
0062
0063
0064 REG_UPDATE(CUR_UPDATE, CURSOR_UPDATE_LOCK, false);
0065 }
0066
0067 static void dce_ipp_cursor_set_attributes(
0068 struct input_pixel_processor *ipp,
0069 const struct dc_cursor_attributes *attributes)
0070 {
0071 struct dce_ipp *ipp_dce = TO_DCE_IPP(ipp);
0072 int mode;
0073
0074
0075 REG_UPDATE(CUR_UPDATE, CURSOR_UPDATE_LOCK, true);
0076
0077
0078 switch (attributes->color_format) {
0079 case CURSOR_MODE_MONO:
0080 mode = 0;
0081 break;
0082 case CURSOR_MODE_COLOR_1BIT_AND:
0083 mode = 1;
0084 break;
0085 case CURSOR_MODE_COLOR_PRE_MULTIPLIED_ALPHA:
0086 mode = 2;
0087 break;
0088 case CURSOR_MODE_COLOR_UN_PRE_MULTIPLIED_ALPHA:
0089 mode = 3;
0090 break;
0091 default:
0092 BREAK_TO_DEBUGGER();
0093 mode = 0;
0094 }
0095
0096 REG_UPDATE_3(CUR_CONTROL,
0097 CURSOR_MODE, mode,
0098 CURSOR_2X_MAGNIFY, attributes->attribute_flags.bits.ENABLE_MAGNIFICATION,
0099 CUR_INV_TRANS_CLAMP, attributes->attribute_flags.bits.INVERSE_TRANSPARENT_CLAMPING);
0100
0101 if (attributes->color_format == CURSOR_MODE_MONO) {
0102 REG_SET_3(CUR_COLOR1, 0,
0103 CUR_COLOR1_BLUE, 0,
0104 CUR_COLOR1_GREEN, 0,
0105 CUR_COLOR1_RED, 0);
0106
0107 REG_SET_3(CUR_COLOR2, 0,
0108 CUR_COLOR2_BLUE, 0xff,
0109 CUR_COLOR2_GREEN, 0xff,
0110 CUR_COLOR2_RED, 0xff);
0111 }
0112
0113
0114
0115
0116
0117 REG_SET_2(CUR_SIZE, 0,
0118 CURSOR_WIDTH, attributes->width-1,
0119 CURSOR_HEIGHT, attributes->height-1);
0120
0121
0122
0123
0124
0125
0126
0127 REG_SET(CUR_SURFACE_ADDRESS_HIGH, 0,
0128 CURSOR_SURFACE_ADDRESS_HIGH, attributes->address.high_part);
0129
0130 REG_SET(CUR_SURFACE_ADDRESS, 0,
0131 CURSOR_SURFACE_ADDRESS, attributes->address.low_part);
0132
0133
0134 REG_UPDATE(CUR_UPDATE, CURSOR_UPDATE_LOCK, false);
0135 }
0136
0137
0138 static void dce_ipp_program_prescale(struct input_pixel_processor *ipp,
0139 struct ipp_prescale_params *params)
0140 {
0141 struct dce_ipp *ipp_dce = TO_DCE_IPP(ipp);
0142
0143
0144 REG_UPDATE(PRESCALE_GRPH_CONTROL,
0145 GRPH_PRESCALE_BYPASS, 1);
0146
0147 REG_SET_2(PRESCALE_VALUES_GRPH_R, 0,
0148 GRPH_PRESCALE_SCALE_R, params->scale,
0149 GRPH_PRESCALE_BIAS_R, params->bias);
0150
0151 REG_SET_2(PRESCALE_VALUES_GRPH_G, 0,
0152 GRPH_PRESCALE_SCALE_G, params->scale,
0153 GRPH_PRESCALE_BIAS_G, params->bias);
0154
0155 REG_SET_2(PRESCALE_VALUES_GRPH_B, 0,
0156 GRPH_PRESCALE_SCALE_B, params->scale,
0157 GRPH_PRESCALE_BIAS_B, params->bias);
0158
0159 if (params->mode != IPP_PRESCALE_MODE_BYPASS) {
0160 REG_UPDATE(PRESCALE_GRPH_CONTROL,
0161 GRPH_PRESCALE_BYPASS, 0);
0162
0163
0164 REG_UPDATE(INPUT_GAMMA_CONTROL,
0165 GRPH_INPUT_GAMMA_MODE, 1);
0166 }
0167 }
0168
0169 static void dce_ipp_program_input_lut(
0170 struct input_pixel_processor *ipp,
0171 const struct dc_gamma *gamma)
0172 {
0173 int i;
0174 struct dce_ipp *ipp_dce = TO_DCE_IPP(ipp);
0175
0176
0177 if (REG(DCFE_MEM_PWR_CTRL))
0178 REG_SET(DCFE_MEM_PWR_CTRL, 0, DCP_LUT_MEM_PWR_DIS, 1);
0179
0180
0181 REG_SET(DC_LUT_WRITE_EN_MASK, 0, DC_LUT_WRITE_EN_MASK, 0x7);
0182
0183
0184 REG_UPDATE(DC_LUT_RW_MODE, DC_LUT_RW_MODE, 0);
0185
0186
0187 REG_SET_3(DC_LUT_CONTROL, 0,
0188 DC_LUT_DATA_R_FORMAT, 3,
0189 DC_LUT_DATA_G_FORMAT, 3,
0190 DC_LUT_DATA_B_FORMAT, 3);
0191
0192
0193 REG_SET(DC_LUT_RW_INDEX, 0,
0194 DC_LUT_RW_INDEX, 0);
0195
0196 for (i = 0; i < gamma->num_entries; i++) {
0197 REG_SET(DC_LUT_SEQ_COLOR, 0, DC_LUT_SEQ_COLOR,
0198 dc_fixpt_round(
0199 gamma->entries.red[i]));
0200 REG_SET(DC_LUT_SEQ_COLOR, 0, DC_LUT_SEQ_COLOR,
0201 dc_fixpt_round(
0202 gamma->entries.green[i]));
0203 REG_SET(DC_LUT_SEQ_COLOR, 0, DC_LUT_SEQ_COLOR,
0204 dc_fixpt_round(
0205 gamma->entries.blue[i]));
0206 }
0207
0208
0209 if (REG(DCFE_MEM_PWR_CTRL))
0210 REG_SET(DCFE_MEM_PWR_CTRL, 0, DCP_LUT_MEM_PWR_DIS, 0);
0211
0212
0213 REG_UPDATE(PRESCALE_GRPH_CONTROL, GRPH_PRESCALE_BYPASS, 1);
0214 REG_UPDATE(INPUT_GAMMA_CONTROL, GRPH_INPUT_GAMMA_MODE, 0);
0215 }
0216
0217 static void dce_ipp_set_degamma(
0218 struct input_pixel_processor *ipp,
0219 enum ipp_degamma_mode mode)
0220 {
0221 struct dce_ipp *ipp_dce = TO_DCE_IPP(ipp);
0222 uint32_t degamma_type = (mode == IPP_DEGAMMA_MODE_HW_sRGB) ? 1 : 0;
0223
0224 ASSERT(mode == IPP_DEGAMMA_MODE_BYPASS || mode == IPP_DEGAMMA_MODE_HW_sRGB);
0225
0226 REG_SET_3(DEGAMMA_CONTROL, 0,
0227 GRPH_DEGAMMA_MODE, degamma_type,
0228 CURSOR_DEGAMMA_MODE, degamma_type,
0229 CURSOR2_DEGAMMA_MODE, degamma_type);
0230 }
0231
0232 #if defined(CONFIG_DRM_AMD_DC_SI)
0233 static void dce60_ipp_set_degamma(
0234 struct input_pixel_processor *ipp,
0235 enum ipp_degamma_mode mode)
0236 {
0237 struct dce_ipp *ipp_dce = TO_DCE_IPP(ipp);
0238 uint32_t degamma_type = (mode == IPP_DEGAMMA_MODE_HW_sRGB) ? 1 : 0;
0239
0240 ASSERT(mode == IPP_DEGAMMA_MODE_BYPASS || mode == IPP_DEGAMMA_MODE_HW_sRGB);
0241
0242 REG_SET_2(DEGAMMA_CONTROL, 0,
0243 GRPH_DEGAMMA_MODE, degamma_type,
0244 CURSOR_DEGAMMA_MODE, degamma_type);
0245 }
0246 #endif
0247
0248 static const struct ipp_funcs dce_ipp_funcs = {
0249 .ipp_cursor_set_attributes = dce_ipp_cursor_set_attributes,
0250 .ipp_cursor_set_position = dce_ipp_cursor_set_position,
0251 .ipp_program_prescale = dce_ipp_program_prescale,
0252 .ipp_program_input_lut = dce_ipp_program_input_lut,
0253 .ipp_set_degamma = dce_ipp_set_degamma
0254 };
0255
0256 #if defined(CONFIG_DRM_AMD_DC_SI)
0257 static const struct ipp_funcs dce60_ipp_funcs = {
0258 .ipp_cursor_set_attributes = dce_ipp_cursor_set_attributes,
0259 .ipp_cursor_set_position = dce_ipp_cursor_set_position,
0260 .ipp_program_prescale = dce_ipp_program_prescale,
0261 .ipp_program_input_lut = dce_ipp_program_input_lut,
0262 .ipp_set_degamma = dce60_ipp_set_degamma
0263 };
0264 #endif
0265
0266
0267
0268
0269
0270
0271 void dce_ipp_construct(
0272 struct dce_ipp *ipp_dce,
0273 struct dc_context *ctx,
0274 int inst,
0275 const struct dce_ipp_registers *regs,
0276 const struct dce_ipp_shift *ipp_shift,
0277 const struct dce_ipp_mask *ipp_mask)
0278 {
0279 ipp_dce->base.ctx = ctx;
0280 ipp_dce->base.inst = inst;
0281 ipp_dce->base.funcs = &dce_ipp_funcs;
0282
0283 ipp_dce->regs = regs;
0284 ipp_dce->ipp_shift = ipp_shift;
0285 ipp_dce->ipp_mask = ipp_mask;
0286 }
0287
0288 #if defined(CONFIG_DRM_AMD_DC_SI)
0289 void dce60_ipp_construct(
0290 struct dce_ipp *ipp_dce,
0291 struct dc_context *ctx,
0292 int inst,
0293 const struct dce_ipp_registers *regs,
0294 const struct dce_ipp_shift *ipp_shift,
0295 const struct dce_ipp_mask *ipp_mask)
0296 {
0297 ipp_dce->base.ctx = ctx;
0298 ipp_dce->base.inst = inst;
0299 ipp_dce->base.funcs = &dce60_ipp_funcs;
0300
0301 ipp_dce->regs = regs;
0302 ipp_dce->ipp_shift = ipp_shift;
0303 ipp_dce->ipp_mask = ipp_mask;
0304 }
0305 #endif
0306
0307 void dce_ipp_destroy(struct input_pixel_processor **ipp)
0308 {
0309 kfree(TO_DCE_IPP(*ipp));
0310 *ipp = NULL;
0311 }