Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright 2012-15 Advanced Micro Devices, Inc.
0003  *
0004  * Permission is hereby granted, free of charge, to any person obtaining a
0005  * copy of this software and associated documentation files (the "Software"),
0006  * to deal in the Software without restriction, including without limitation
0007  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
0008  * and/or sell copies of the Software, and to permit persons to whom the
0009  * Software is furnished to do so, subject to the following conditions:
0010  *
0011  * The above copyright notice and this permission notice shall be included in
0012  * all copies or substantial portions of the Software.
0013  *
0014  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0015  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0016  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
0017  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
0018  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
0019  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
0020  * OTHER DEALINGS IN THE SOFTWARE.
0021  *
0022  * Authors: AMD
0023  *
0024  */
0025 
0026 #include "dm_services.h"
0027 #include "dcn20_opp.h"
0028 #include "reg_helper.h"
0029 
0030 #define REG(reg) \
0031     (oppn20->regs->reg)
0032 
0033 #undef FN
0034 #define FN(reg_name, field_name) \
0035     oppn20->opp_shift->field_name, oppn20->opp_mask->field_name
0036 
0037 #define CTX \
0038     oppn20->base.ctx
0039 
0040 
0041 void opp2_set_disp_pattern_generator(
0042         struct output_pixel_processor *opp,
0043         enum controller_dp_test_pattern test_pattern,
0044         enum controller_dp_color_space color_space,
0045         enum dc_color_depth color_depth,
0046         const struct tg_color *solid_color,
0047         int width,
0048         int height,
0049         int offset)
0050 {
0051     struct dcn20_opp *oppn20 = TO_DCN20_OPP(opp);
0052     enum test_pattern_color_format bit_depth;
0053     enum test_pattern_dyn_range dyn_range;
0054     enum test_pattern_mode mode;
0055 
0056     /* color ramp generator mixes 16-bits color */
0057     uint32_t src_bpc = 16;
0058     /* requested bpc */
0059     uint32_t dst_bpc;
0060     uint32_t index;
0061     /* RGB values of the color bars.
0062      * Produce two RGB colors: RGB0 - white (all Fs)
0063      * and RGB1 - black (all 0s)
0064      * (three RGB components for two colors)
0065      */
0066     uint16_t src_color[6] = {0xFFFF, 0xFFFF, 0xFFFF, 0x0000,
0067                         0x0000, 0x0000};
0068     /* dest color (converted to the specified color format) */
0069     uint16_t dst_color[6];
0070     uint32_t inc_base;
0071 
0072     /* translate to bit depth */
0073     switch (color_depth) {
0074     case COLOR_DEPTH_666:
0075         bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_6;
0076     break;
0077     case COLOR_DEPTH_888:
0078         bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_8;
0079     break;
0080     case COLOR_DEPTH_101010:
0081         bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_10;
0082     break;
0083     case COLOR_DEPTH_121212:
0084         bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_12;
0085     break;
0086     default:
0087         bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_8;
0088     break;
0089     }
0090 
0091     /* set DPG dimentions */
0092     REG_SET_2(DPG_DIMENSIONS, 0,
0093         DPG_ACTIVE_WIDTH, width,
0094         DPG_ACTIVE_HEIGHT, height);
0095 
0096     /* set DPG offset */
0097     REG_SET_2(DPG_OFFSET_SEGMENT, 0,
0098         DPG_X_OFFSET, offset,
0099         DPG_SEGMENT_WIDTH, 0);
0100 
0101     switch (test_pattern) {
0102     case CONTROLLER_DP_TEST_PATTERN_COLORSQUARES:
0103     case CONTROLLER_DP_TEST_PATTERN_COLORSQUARES_CEA:
0104     {
0105         dyn_range = (test_pattern ==
0106                 CONTROLLER_DP_TEST_PATTERN_COLORSQUARES_CEA ?
0107                 TEST_PATTERN_DYN_RANGE_CEA :
0108                 TEST_PATTERN_DYN_RANGE_VESA);
0109 
0110         switch (color_space) {
0111         case CONTROLLER_DP_COLOR_SPACE_YCBCR601:
0112             mode = TEST_PATTERN_MODE_COLORSQUARES_YCBCR601;
0113         break;
0114         case CONTROLLER_DP_COLOR_SPACE_YCBCR709:
0115             mode = TEST_PATTERN_MODE_COLORSQUARES_YCBCR709;
0116         break;
0117         case CONTROLLER_DP_COLOR_SPACE_RGB:
0118         default:
0119             mode = TEST_PATTERN_MODE_COLORSQUARES_RGB;
0120         break;
0121         }
0122 
0123         REG_UPDATE_6(DPG_CONTROL,
0124             DPG_EN, 1,
0125             DPG_MODE, mode,
0126             DPG_DYNAMIC_RANGE, dyn_range,
0127             DPG_BIT_DEPTH, bit_depth,
0128             DPG_VRES, 6,
0129             DPG_HRES, 6);
0130     }
0131     break;
0132 
0133     case CONTROLLER_DP_TEST_PATTERN_VERTICALBARS:
0134     case CONTROLLER_DP_TEST_PATTERN_HORIZONTALBARS:
0135     {
0136         mode = (test_pattern ==
0137             CONTROLLER_DP_TEST_PATTERN_VERTICALBARS ?
0138             TEST_PATTERN_MODE_VERTICALBARS :
0139             TEST_PATTERN_MODE_HORIZONTALBARS);
0140 
0141         switch (bit_depth) {
0142         case TEST_PATTERN_COLOR_FORMAT_BPC_6:
0143             dst_bpc = 6;
0144         break;
0145         case TEST_PATTERN_COLOR_FORMAT_BPC_8:
0146             dst_bpc = 8;
0147         break;
0148         case TEST_PATTERN_COLOR_FORMAT_BPC_10:
0149             dst_bpc = 10;
0150         break;
0151         default:
0152             dst_bpc = 8;
0153         break;
0154         }
0155 
0156         /* adjust color to the required colorFormat */
0157         for (index = 0; index < 6; index++) {
0158             /* dst = 2^dstBpc * src / 2^srcBpc = src >>
0159              * (srcBpc - dstBpc);
0160              */
0161             dst_color[index] =
0162                 src_color[index] >> (src_bpc - dst_bpc);
0163         /* DPG_COLOUR registers are 16-bit MSB aligned value with bits 3:0 hardwired to ZERO.
0164          * XXXXXXXXXX000000 for 10 bit,
0165          * XXXXXXXX00000000 for 8 bit,
0166          * XXXXXX0000000000 for 6 bits
0167          */
0168             dst_color[index] <<= (16 - dst_bpc);
0169         }
0170 
0171         REG_SET_2(DPG_COLOUR_R_CR, 0,
0172                 DPG_COLOUR1_R_CR, dst_color[0],
0173                 DPG_COLOUR0_R_CR, dst_color[3]);
0174         REG_SET_2(DPG_COLOUR_G_Y, 0,
0175                 DPG_COLOUR1_G_Y, dst_color[1],
0176                 DPG_COLOUR0_G_Y, dst_color[4]);
0177         REG_SET_2(DPG_COLOUR_B_CB, 0,
0178                 DPG_COLOUR1_B_CB, dst_color[2],
0179                 DPG_COLOUR0_B_CB, dst_color[5]);
0180 
0181         /* enable test pattern */
0182         REG_UPDATE_6(DPG_CONTROL,
0183             DPG_EN, 1,
0184             DPG_MODE, mode,
0185             DPG_DYNAMIC_RANGE, 0,
0186             DPG_BIT_DEPTH, bit_depth,
0187             DPG_VRES, 0,
0188             DPG_HRES, 0);
0189     }
0190     break;
0191 
0192     case CONTROLLER_DP_TEST_PATTERN_COLORRAMP:
0193     {
0194         mode = (bit_depth ==
0195             TEST_PATTERN_COLOR_FORMAT_BPC_10 ?
0196             TEST_PATTERN_MODE_DUALRAMP_RGB :
0197             TEST_PATTERN_MODE_SINGLERAMP_RGB);
0198 
0199         switch (bit_depth) {
0200         case TEST_PATTERN_COLOR_FORMAT_BPC_6:
0201             dst_bpc = 6;
0202         break;
0203         case TEST_PATTERN_COLOR_FORMAT_BPC_8:
0204             dst_bpc = 8;
0205         break;
0206         case TEST_PATTERN_COLOR_FORMAT_BPC_10:
0207             dst_bpc = 10;
0208         break;
0209         default:
0210             dst_bpc = 8;
0211         break;
0212         }
0213 
0214         /* increment for the first ramp for one color gradation
0215          * 1 gradation for 6-bit color is 2^10
0216          * gradations in 16-bit color
0217          */
0218         inc_base = (src_bpc - dst_bpc);
0219 
0220         switch (bit_depth) {
0221         case TEST_PATTERN_COLOR_FORMAT_BPC_6:
0222         {
0223             REG_SET_3(DPG_RAMP_CONTROL, 0,
0224                 DPG_RAMP0_OFFSET, 0,
0225                 DPG_INC0, inc_base,
0226                 DPG_INC1, 0);
0227             REG_UPDATE_2(DPG_CONTROL,
0228                 DPG_VRES, 6,
0229                 DPG_HRES, 6);
0230         }
0231         break;
0232         case TEST_PATTERN_COLOR_FORMAT_BPC_8:
0233         {
0234             REG_SET_3(DPG_RAMP_CONTROL, 0,
0235                 DPG_RAMP0_OFFSET, 0,
0236                 DPG_INC0, inc_base,
0237                 DPG_INC1, 0);
0238             REG_UPDATE_2(DPG_CONTROL,
0239                 DPG_VRES, 6,
0240                 DPG_HRES, 8);
0241         }
0242         break;
0243         case TEST_PATTERN_COLOR_FORMAT_BPC_10:
0244         {
0245             REG_SET_3(DPG_RAMP_CONTROL, 0,
0246                 DPG_RAMP0_OFFSET, 384 << 6,
0247                 DPG_INC0, inc_base,
0248                 DPG_INC1, inc_base + 2);
0249             REG_UPDATE_2(DPG_CONTROL,
0250                 DPG_VRES, 5,
0251                 DPG_HRES, 8);
0252         }
0253         break;
0254         default:
0255         break;
0256         }
0257 
0258         /* enable test pattern */
0259         REG_UPDATE_4(DPG_CONTROL,
0260             DPG_EN, 1,
0261             DPG_MODE, mode,
0262             DPG_DYNAMIC_RANGE, 0,
0263             DPG_BIT_DEPTH, bit_depth);
0264     }
0265     break;
0266     case CONTROLLER_DP_TEST_PATTERN_VIDEOMODE:
0267     {
0268         REG_WRITE(DPG_CONTROL, 0);
0269         REG_WRITE(DPG_COLOUR_R_CR, 0);
0270         REG_WRITE(DPG_COLOUR_G_Y, 0);
0271         REG_WRITE(DPG_COLOUR_B_CB, 0);
0272         REG_WRITE(DPG_RAMP_CONTROL, 0);
0273     }
0274     break;
0275     case CONTROLLER_DP_TEST_PATTERN_SOLID_COLOR:
0276     {
0277         opp2_dpg_set_blank_color(opp, solid_color);
0278         REG_UPDATE_2(DPG_CONTROL,
0279                 DPG_EN, 1,
0280                 DPG_MODE, TEST_PATTERN_MODE_HORIZONTALBARS);
0281 
0282         REG_SET_2(DPG_DIMENSIONS, 0,
0283                 DPG_ACTIVE_WIDTH, width,
0284                 DPG_ACTIVE_HEIGHT, height);
0285     }
0286     break;
0287     default:
0288         break;
0289 
0290     }
0291 }
0292 
0293 void opp2_program_dpg_dimensions(
0294         struct output_pixel_processor *opp,
0295         int width, int height)
0296 {
0297     struct dcn20_opp *oppn20 = TO_DCN20_OPP(opp);
0298 
0299     REG_SET_2(DPG_DIMENSIONS, 0,
0300         DPG_ACTIVE_WIDTH, width,
0301         DPG_ACTIVE_HEIGHT, height);
0302 }
0303 
0304 void opp2_dpg_set_blank_color(
0305         struct output_pixel_processor *opp,
0306         const struct tg_color *color)
0307 {
0308     struct dcn20_opp *oppn20 = TO_DCN20_OPP(opp);
0309 
0310     /* 16-bit MSB aligned value. Bits 3:0 of this field are hardwired to ZERO */
0311     ASSERT(color);
0312     REG_SET_2(DPG_COLOUR_B_CB, 0,
0313             DPG_COLOUR1_B_CB, color->color_b_cb << 6,
0314             DPG_COLOUR0_B_CB, color->color_b_cb << 6);
0315     REG_SET_2(DPG_COLOUR_G_Y, 0,
0316             DPG_COLOUR1_G_Y, color->color_g_y << 6,
0317             DPG_COLOUR0_G_Y, color->color_g_y << 6);
0318     REG_SET_2(DPG_COLOUR_R_CR, 0,
0319             DPG_COLOUR1_R_CR, color->color_r_cr << 6,
0320             DPG_COLOUR0_R_CR, color->color_r_cr << 6);
0321 }
0322 
0323 bool opp2_dpg_is_blanked(struct output_pixel_processor *opp)
0324 {
0325     struct dcn20_opp *oppn20 = TO_DCN20_OPP(opp);
0326     uint32_t dpg_en, dpg_mode;
0327     uint32_t double_buffer_pending;
0328 
0329     REG_GET_2(DPG_CONTROL,
0330             DPG_EN, &dpg_en,
0331             DPG_MODE, &dpg_mode);
0332 
0333     REG_GET(DPG_STATUS,
0334             DPG_DOUBLE_BUFFER_PENDING, &double_buffer_pending);
0335 
0336     return (dpg_en == 1) &&
0337         (double_buffer_pending == 0);
0338 }
0339 
0340 void opp2_program_left_edge_extra_pixel (
0341         struct output_pixel_processor *opp,
0342         bool count)
0343 {
0344     struct dcn20_opp *oppn20 = TO_DCN20_OPP(opp);
0345 
0346     /* Specifies the number of extra left edge pixels that are supplied to
0347      * the 422 horizontal chroma sub-sample filter.
0348      * Note that when left edge pixel is not "0", fmt pixel encoding can be in either 420 or 422 mode
0349      * */
0350     REG_UPDATE(FMT_422_CONTROL, FMT_LEFT_EDGE_EXTRA_PIXEL_COUNT, count);
0351 }
0352 
0353 /*****************************************/
0354 /* Constructor, Destructor               */
0355 /*****************************************/
0356 
0357 static struct opp_funcs dcn20_opp_funcs = {
0358         .opp_set_dyn_expansion = opp1_set_dyn_expansion,
0359         .opp_program_fmt = opp1_program_fmt,
0360         .opp_program_bit_depth_reduction = opp1_program_bit_depth_reduction,
0361         .opp_program_stereo = opp1_program_stereo,
0362         .opp_pipe_clock_control = opp1_pipe_clock_control,
0363         .opp_set_disp_pattern_generator = opp2_set_disp_pattern_generator,
0364         .opp_program_dpg_dimensions = opp2_program_dpg_dimensions,
0365         .dpg_is_blanked = opp2_dpg_is_blanked,
0366         .opp_dpg_set_blank_color = opp2_dpg_set_blank_color,
0367         .opp_destroy = opp1_destroy,
0368         .opp_program_left_edge_extra_pixel = opp2_program_left_edge_extra_pixel,
0369 };
0370 
0371 void dcn20_opp_construct(struct dcn20_opp *oppn20,
0372     struct dc_context *ctx,
0373     uint32_t inst,
0374     const struct dcn20_opp_registers *regs,
0375     const struct dcn20_opp_shift *opp_shift,
0376     const struct dcn20_opp_mask *opp_mask)
0377 {
0378     oppn20->base.ctx = ctx;
0379     oppn20->base.inst = inst;
0380     oppn20->base.funcs = &dcn20_opp_funcs;
0381 
0382     oppn20->regs = regs;
0383     oppn20->opp_shift = opp_shift;
0384     oppn20->opp_mask = opp_mask;
0385 }
0386