linux/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_opp.c
<<
>>
Prefs
   1/*
   2 * Copyright 2012-15 Advanced Micro Devices, Inc.
   3 *
   4 * Permission is hereby granted, free of charge, to any person obtaining a
   5 * copy of this software and associated documentation files (the "Software"),
   6 * to deal in the Software without restriction, including without limitation
   7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
   8 * and/or sell copies of the Software, and to permit persons to whom the
   9 * Software is furnished to do so, subject to the following conditions:
  10 *
  11 * The above copyright notice and this permission notice shall be included in
  12 * all copies or substantial portions of the Software.
  13 *
  14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
  18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  20 * OTHER DEALINGS IN THE SOFTWARE.
  21 *
  22 * Authors: AMD
  23 *
  24 */
  25
  26#include "dm_services.h"
  27#include "dcn20_opp.h"
  28#include "reg_helper.h"
  29
  30#define REG(reg) \
  31        (oppn20->regs->reg)
  32
  33#undef FN
  34#define FN(reg_name, field_name) \
  35        oppn20->opp_shift->field_name, oppn20->opp_mask->field_name
  36
  37#define CTX \
  38        oppn20->base.ctx
  39
  40
  41void opp2_set_disp_pattern_generator(
  42                struct output_pixel_processor *opp,
  43                enum controller_dp_test_pattern test_pattern,
  44                enum controller_dp_color_space color_space,
  45                enum dc_color_depth color_depth,
  46                const struct tg_color *solid_color,
  47                int width,
  48                int height,
  49                int offset)
  50{
  51        struct dcn20_opp *oppn20 = TO_DCN20_OPP(opp);
  52        enum test_pattern_color_format bit_depth;
  53        enum test_pattern_dyn_range dyn_range;
  54        enum test_pattern_mode mode;
  55
  56        /* color ramp generator mixes 16-bits color */
  57        uint32_t src_bpc = 16;
  58        /* requested bpc */
  59        uint32_t dst_bpc;
  60        uint32_t index;
  61        /* RGB values of the color bars.
  62         * Produce two RGB colors: RGB0 - white (all Fs)
  63         * and RGB1 - black (all 0s)
  64         * (three RGB components for two colors)
  65         */
  66        uint16_t src_color[6] = {0xFFFF, 0xFFFF, 0xFFFF, 0x0000,
  67                                                0x0000, 0x0000};
  68        /* dest color (converted to the specified color format) */
  69        uint16_t dst_color[6];
  70        uint32_t inc_base;
  71
  72        /* translate to bit depth */
  73        switch (color_depth) {
  74        case COLOR_DEPTH_666:
  75                bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_6;
  76        break;
  77        case COLOR_DEPTH_888:
  78                bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_8;
  79        break;
  80        case COLOR_DEPTH_101010:
  81                bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_10;
  82        break;
  83        case COLOR_DEPTH_121212:
  84                bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_12;
  85        break;
  86        default:
  87                bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_8;
  88        break;
  89        }
  90
  91        /* set DPG dimentions */
  92        REG_SET_2(DPG_DIMENSIONS, 0,
  93                DPG_ACTIVE_WIDTH, width,
  94                DPG_ACTIVE_HEIGHT, height);
  95
  96        /* set DPG offset */
  97        REG_SET_2(DPG_OFFSET_SEGMENT, 0,
  98                DPG_X_OFFSET, offset,
  99                DPG_SEGMENT_WIDTH, 0);
 100
 101        switch (test_pattern) {
 102        case CONTROLLER_DP_TEST_PATTERN_COLORSQUARES:
 103        case CONTROLLER_DP_TEST_PATTERN_COLORSQUARES_CEA:
 104        {
 105                dyn_range = (test_pattern ==
 106                                CONTROLLER_DP_TEST_PATTERN_COLORSQUARES_CEA ?
 107                                TEST_PATTERN_DYN_RANGE_CEA :
 108                                TEST_PATTERN_DYN_RANGE_VESA);
 109
 110                switch (color_space) {
 111                case CONTROLLER_DP_COLOR_SPACE_YCBCR601:
 112                        mode = TEST_PATTERN_MODE_COLORSQUARES_YCBCR601;
 113                break;
 114                case CONTROLLER_DP_COLOR_SPACE_YCBCR709:
 115                        mode = TEST_PATTERN_MODE_COLORSQUARES_YCBCR709;
 116                break;
 117                case CONTROLLER_DP_COLOR_SPACE_RGB:
 118                default:
 119                        mode = TEST_PATTERN_MODE_COLORSQUARES_RGB;
 120                break;
 121                }
 122
 123                REG_UPDATE_6(DPG_CONTROL,
 124                        DPG_EN, 1,
 125                        DPG_MODE, mode,
 126                        DPG_DYNAMIC_RANGE, dyn_range,
 127                        DPG_BIT_DEPTH, bit_depth,
 128                        DPG_VRES, 6,
 129                        DPG_HRES, 6);
 130        }
 131        break;
 132
 133        case CONTROLLER_DP_TEST_PATTERN_VERTICALBARS:
 134        case CONTROLLER_DP_TEST_PATTERN_HORIZONTALBARS:
 135        {
 136                mode = (test_pattern ==
 137                        CONTROLLER_DP_TEST_PATTERN_VERTICALBARS ?
 138                        TEST_PATTERN_MODE_VERTICALBARS :
 139                        TEST_PATTERN_MODE_HORIZONTALBARS);
 140
 141                switch (bit_depth) {
 142                case TEST_PATTERN_COLOR_FORMAT_BPC_6:
 143                        dst_bpc = 6;
 144                break;
 145                case TEST_PATTERN_COLOR_FORMAT_BPC_8:
 146                        dst_bpc = 8;
 147                break;
 148                case TEST_PATTERN_COLOR_FORMAT_BPC_10:
 149                        dst_bpc = 10;
 150                break;
 151                default:
 152                        dst_bpc = 8;
 153                break;
 154                }
 155
 156                /* adjust color to the required colorFormat */
 157                for (index = 0; index < 6; index++) {
 158                        /* dst = 2^dstBpc * src / 2^srcBpc = src >>
 159                         * (srcBpc - dstBpc);
 160                         */
 161                        dst_color[index] =
 162                                src_color[index] >> (src_bpc - dst_bpc);
 163                /* DPG_COLOUR registers are 16-bit MSB aligned value with bits 3:0 hardwired to ZERO.
 164                 * XXXXXXXXXX000000 for 10 bit,
 165                 * XXXXXXXX00000000 for 8 bit,
 166                 * XXXXXX0000000000 for 6 bits
 167                 */
 168                        dst_color[index] <<= (16 - dst_bpc);
 169                }
 170
 171                REG_SET_2(DPG_COLOUR_R_CR, 0,
 172                                DPG_COLOUR1_R_CR, dst_color[0],
 173                                DPG_COLOUR0_R_CR, dst_color[3]);
 174                REG_SET_2(DPG_COLOUR_G_Y, 0,
 175                                DPG_COLOUR1_G_Y, dst_color[1],
 176                                DPG_COLOUR0_G_Y, dst_color[4]);
 177                REG_SET_2(DPG_COLOUR_B_CB, 0,
 178                                DPG_COLOUR1_B_CB, dst_color[2],
 179                                DPG_COLOUR0_B_CB, dst_color[5]);
 180
 181                /* enable test pattern */
 182                REG_UPDATE_6(DPG_CONTROL,
 183                        DPG_EN, 1,
 184                        DPG_MODE, mode,
 185                        DPG_DYNAMIC_RANGE, 0,
 186                        DPG_BIT_DEPTH, bit_depth,
 187                        DPG_VRES, 0,
 188                        DPG_HRES, 0);
 189        }
 190        break;
 191
 192        case CONTROLLER_DP_TEST_PATTERN_COLORRAMP:
 193        {
 194                mode = (bit_depth ==
 195                        TEST_PATTERN_COLOR_FORMAT_BPC_10 ?
 196                        TEST_PATTERN_MODE_DUALRAMP_RGB :
 197                        TEST_PATTERN_MODE_SINGLERAMP_RGB);
 198
 199                switch (bit_depth) {
 200                case TEST_PATTERN_COLOR_FORMAT_BPC_6:
 201                        dst_bpc = 6;
 202                break;
 203                case TEST_PATTERN_COLOR_FORMAT_BPC_8:
 204                        dst_bpc = 8;
 205                break;
 206                case TEST_PATTERN_COLOR_FORMAT_BPC_10:
 207                        dst_bpc = 10;
 208                break;
 209                default:
 210                        dst_bpc = 8;
 211                break;
 212                }
 213
 214                /* increment for the first ramp for one color gradation
 215                 * 1 gradation for 6-bit color is 2^10
 216                 * gradations in 16-bit color
 217                 */
 218                inc_base = (src_bpc - dst_bpc);
 219
 220                switch (bit_depth) {
 221                case TEST_PATTERN_COLOR_FORMAT_BPC_6:
 222                {
 223                        REG_SET_3(DPG_RAMP_CONTROL, 0,
 224                                DPG_RAMP0_OFFSET, 0,
 225                                DPG_INC0, inc_base,
 226                                DPG_INC1, 0);
 227                        REG_UPDATE_2(DPG_CONTROL,
 228                                DPG_VRES, 6,
 229                                DPG_HRES, 6);
 230                }
 231                break;
 232                case TEST_PATTERN_COLOR_FORMAT_BPC_8:
 233                {
 234                        REG_SET_3(DPG_RAMP_CONTROL, 0,
 235                                DPG_RAMP0_OFFSET, 0,
 236                                DPG_INC0, inc_base,
 237                                DPG_INC1, 0);
 238                        REG_UPDATE_2(DPG_CONTROL,
 239                                DPG_VRES, 6,
 240                                DPG_HRES, 8);
 241                }
 242                break;
 243                case TEST_PATTERN_COLOR_FORMAT_BPC_10:
 244                {
 245                        REG_SET_3(DPG_RAMP_CONTROL, 0,
 246                                DPG_RAMP0_OFFSET, 384 << 6,
 247                                DPG_INC0, inc_base,
 248                                DPG_INC1, inc_base + 2);
 249                        REG_UPDATE_2(DPG_CONTROL,
 250                                DPG_VRES, 5,
 251                                DPG_HRES, 8);
 252                }
 253                break;
 254                default:
 255                break;
 256                }
 257
 258                /* enable test pattern */
 259                REG_UPDATE_4(DPG_CONTROL,
 260                        DPG_EN, 1,
 261                        DPG_MODE, mode,
 262                        DPG_DYNAMIC_RANGE, 0,
 263                        DPG_BIT_DEPTH, bit_depth);
 264        }
 265        break;
 266        case CONTROLLER_DP_TEST_PATTERN_VIDEOMODE:
 267        {
 268                REG_WRITE(DPG_CONTROL, 0);
 269                REG_WRITE(DPG_COLOUR_R_CR, 0);
 270                REG_WRITE(DPG_COLOUR_G_Y, 0);
 271                REG_WRITE(DPG_COLOUR_B_CB, 0);
 272                REG_WRITE(DPG_RAMP_CONTROL, 0);
 273        }
 274        break;
 275        case CONTROLLER_DP_TEST_PATTERN_SOLID_COLOR:
 276        {
 277                opp2_dpg_set_blank_color(opp, solid_color);
 278                REG_UPDATE_2(DPG_CONTROL,
 279                                DPG_EN, 1,
 280                                DPG_MODE, TEST_PATTERN_MODE_HORIZONTALBARS);
 281
 282                REG_SET_2(DPG_DIMENSIONS, 0,
 283                                DPG_ACTIVE_WIDTH, width,
 284                                DPG_ACTIVE_HEIGHT, height);
 285        }
 286        break;
 287        default:
 288                break;
 289
 290        }
 291}
 292
 293void opp2_program_dpg_dimensions(
 294                struct output_pixel_processor *opp,
 295                int width, int height)
 296{
 297        struct dcn20_opp *oppn20 = TO_DCN20_OPP(opp);
 298
 299        REG_SET_2(DPG_DIMENSIONS, 0,
 300                DPG_ACTIVE_WIDTH, width,
 301                DPG_ACTIVE_HEIGHT, height);
 302}
 303
 304void opp2_dpg_set_blank_color(
 305                struct output_pixel_processor *opp,
 306                const struct tg_color *color)
 307{
 308        struct dcn20_opp *oppn20 = TO_DCN20_OPP(opp);
 309
 310        /* 16-bit MSB aligned value. Bits 3:0 of this field are hardwired to ZERO */
 311        ASSERT(color);
 312        REG_SET_2(DPG_COLOUR_B_CB, 0,
 313                        DPG_COLOUR1_B_CB, color->color_b_cb << 6,
 314                        DPG_COLOUR0_B_CB, color->color_b_cb << 6);
 315        REG_SET_2(DPG_COLOUR_G_Y, 0,
 316                        DPG_COLOUR1_G_Y, color->color_g_y << 6,
 317                        DPG_COLOUR0_G_Y, color->color_g_y << 6);
 318        REG_SET_2(DPG_COLOUR_R_CR, 0,
 319                        DPG_COLOUR1_R_CR, color->color_r_cr << 6,
 320                        DPG_COLOUR0_R_CR, color->color_r_cr << 6);
 321}
 322
 323bool opp2_dpg_is_blanked(struct output_pixel_processor *opp)
 324{
 325        struct dcn20_opp *oppn20 = TO_DCN20_OPP(opp);
 326        uint32_t dpg_en, dpg_mode;
 327        uint32_t double_buffer_pending;
 328
 329        REG_GET_2(DPG_CONTROL,
 330                        DPG_EN, &dpg_en,
 331                        DPG_MODE, &dpg_mode);
 332
 333        REG_GET(DPG_STATUS,
 334                        DPG_DOUBLE_BUFFER_PENDING, &double_buffer_pending);
 335
 336        return (dpg_en == 1) &&
 337                (double_buffer_pending == 0);
 338}
 339
 340void opp2_program_left_edge_extra_pixel (
 341                struct output_pixel_processor *opp,
 342                bool count)
 343{
 344        struct dcn20_opp *oppn20 = TO_DCN20_OPP(opp);
 345
 346        /* Specifies the number of extra left edge pixels that are supplied to
 347         * the 422 horizontal chroma sub-sample filter.
 348         * Note that when left edge pixel is not "0", fmt pixel encoding can be in either 420 or 422 mode
 349         * */
 350        REG_UPDATE(FMT_422_CONTROL, FMT_LEFT_EDGE_EXTRA_PIXEL_COUNT, count);
 351}
 352
 353/*****************************************/
 354/* Constructor, Destructor               */
 355/*****************************************/
 356
 357static struct opp_funcs dcn20_opp_funcs = {
 358                .opp_set_dyn_expansion = opp1_set_dyn_expansion,
 359                .opp_program_fmt = opp1_program_fmt,
 360                .opp_program_bit_depth_reduction = opp1_program_bit_depth_reduction,
 361                .opp_program_stereo = opp1_program_stereo,
 362                .opp_pipe_clock_control = opp1_pipe_clock_control,
 363                .opp_set_disp_pattern_generator = opp2_set_disp_pattern_generator,
 364                .opp_program_dpg_dimensions = opp2_program_dpg_dimensions,
 365                .dpg_is_blanked = opp2_dpg_is_blanked,
 366                .opp_dpg_set_blank_color = opp2_dpg_set_blank_color,
 367                .opp_destroy = opp1_destroy,
 368                .opp_program_left_edge_extra_pixel = opp2_program_left_edge_extra_pixel,
 369};
 370
 371void dcn20_opp_construct(struct dcn20_opp *oppn20,
 372        struct dc_context *ctx,
 373        uint32_t inst,
 374        const struct dcn20_opp_registers *regs,
 375        const struct dcn20_opp_shift *opp_shift,
 376        const struct dcn20_opp_mask *opp_mask)
 377{
 378        oppn20->base.ctx = ctx;
 379        oppn20->base.inst = inst;
 380        oppn20->base.funcs = &dcn20_opp_funcs;
 381
 382        oppn20->regs = regs;
 383        oppn20->opp_shift = opp_shift;
 384        oppn20->opp_mask = opp_mask;
 385}
 386
 387