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 dc_color_depth color_depth,
  45                const struct tg_color *solid_color,
  46                int width,
  47                int height)
  48{
  49        struct dcn20_opp *oppn20 = TO_DCN20_OPP(opp);
  50        enum test_pattern_color_format bit_depth;
  51        enum test_pattern_dyn_range dyn_range;
  52        enum test_pattern_mode mode;
  53
  54        /* color ramp generator mixes 16-bits color */
  55        uint32_t src_bpc = 16;
  56        /* requested bpc */
  57        uint32_t dst_bpc;
  58        uint32_t index;
  59        /* RGB values of the color bars.
  60         * Produce two RGB colors: RGB0 - white (all Fs)
  61         * and RGB1 - black (all 0s)
  62         * (three RGB components for two colors)
  63         */
  64        uint16_t src_color[6] = {0xFFFF, 0xFFFF, 0xFFFF, 0x0000,
  65                                                0x0000, 0x0000};
  66        /* dest color (converted to the specified color format) */
  67        uint16_t dst_color[6];
  68        uint32_t inc_base;
  69
  70        /* translate to bit depth */
  71        switch (color_depth) {
  72        case COLOR_DEPTH_666:
  73                bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_6;
  74        break;
  75        case COLOR_DEPTH_888:
  76                bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_8;
  77        break;
  78        case COLOR_DEPTH_101010:
  79                bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_10;
  80        break;
  81        case COLOR_DEPTH_121212:
  82                bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_12;
  83        break;
  84        default:
  85                bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_8;
  86        break;
  87        }
  88
  89        /* set DPG dimentions */
  90        REG_SET_2(DPG_DIMENSIONS, 0,
  91                DPG_ACTIVE_WIDTH, width,
  92                DPG_ACTIVE_HEIGHT, height);
  93
  94        switch (test_pattern) {
  95        case CONTROLLER_DP_TEST_PATTERN_COLORSQUARES:
  96        case CONTROLLER_DP_TEST_PATTERN_COLORSQUARES_CEA:
  97        {
  98                dyn_range = (test_pattern ==
  99                                CONTROLLER_DP_TEST_PATTERN_COLORSQUARES_CEA ?
 100                                TEST_PATTERN_DYN_RANGE_CEA :
 101                                TEST_PATTERN_DYN_RANGE_VESA);
 102
 103                REG_UPDATE_6(DPG_CONTROL,
 104                        DPG_EN, 1,
 105                        DPG_MODE, TEST_PATTERN_MODE_COLORSQUARES_RGB,
 106                        DPG_DYNAMIC_RANGE, dyn_range,
 107                        DPG_BIT_DEPTH, bit_depth,
 108                        DPG_VRES, 6,
 109                        DPG_HRES, 6);
 110        }
 111        break;
 112
 113        case CONTROLLER_DP_TEST_PATTERN_VERTICALBARS:
 114        case CONTROLLER_DP_TEST_PATTERN_HORIZONTALBARS:
 115        {
 116                mode = (test_pattern ==
 117                        CONTROLLER_DP_TEST_PATTERN_VERTICALBARS ?
 118                        TEST_PATTERN_MODE_VERTICALBARS :
 119                        TEST_PATTERN_MODE_HORIZONTALBARS);
 120
 121                switch (bit_depth) {
 122                case TEST_PATTERN_COLOR_FORMAT_BPC_6:
 123                        dst_bpc = 6;
 124                break;
 125                case TEST_PATTERN_COLOR_FORMAT_BPC_8:
 126                        dst_bpc = 8;
 127                break;
 128                case TEST_PATTERN_COLOR_FORMAT_BPC_10:
 129                        dst_bpc = 10;
 130                break;
 131                default:
 132                        dst_bpc = 8;
 133                break;
 134                }
 135
 136                /* adjust color to the required colorFormat */
 137                for (index = 0; index < 6; index++) {
 138                        /* dst = 2^dstBpc * src / 2^srcBpc = src >>
 139                         * (srcBpc - dstBpc);
 140                         */
 141                        dst_color[index] =
 142                                src_color[index] >> (src_bpc - dst_bpc);
 143                /* DPG_COLOUR registers are 16-bit MSB aligned value with bits 3:0 hardwired to ZERO.
 144                 * XXXXXXXXXX000000 for 10 bit,
 145                 * XXXXXXXX00000000 for 8 bit,
 146                 * XXXXXX0000000000 for 6 bits
 147                 */
 148                        dst_color[index] <<= (16 - dst_bpc);
 149                }
 150
 151                REG_SET_2(DPG_COLOUR_R_CR, 0,
 152                                DPG_COLOUR1_R_CR, dst_color[0],
 153                                DPG_COLOUR0_R_CR, dst_color[3]);
 154                REG_SET_2(DPG_COLOUR_G_Y, 0,
 155                                DPG_COLOUR1_G_Y, dst_color[1],
 156                                DPG_COLOUR0_G_Y, dst_color[4]);
 157                REG_SET_2(DPG_COLOUR_B_CB, 0,
 158                                DPG_COLOUR1_B_CB, dst_color[2],
 159                                DPG_COLOUR0_B_CB, dst_color[5]);
 160
 161                /* enable test pattern */
 162                REG_UPDATE_6(DPG_CONTROL,
 163                        DPG_EN, 1,
 164                        DPG_MODE, mode,
 165                        DPG_DYNAMIC_RANGE, 0,
 166                        DPG_BIT_DEPTH, bit_depth,
 167                        DPG_VRES, 0,
 168                        DPG_HRES, 0);
 169        }
 170        break;
 171
 172        case CONTROLLER_DP_TEST_PATTERN_COLORRAMP:
 173        {
 174                mode = (bit_depth ==
 175                        TEST_PATTERN_COLOR_FORMAT_BPC_10 ?
 176                        TEST_PATTERN_MODE_DUALRAMP_RGB :
 177                        TEST_PATTERN_MODE_SINGLERAMP_RGB);
 178
 179                switch (bit_depth) {
 180                case TEST_PATTERN_COLOR_FORMAT_BPC_6:
 181                        dst_bpc = 6;
 182                break;
 183                case TEST_PATTERN_COLOR_FORMAT_BPC_8:
 184                        dst_bpc = 8;
 185                break;
 186                case TEST_PATTERN_COLOR_FORMAT_BPC_10:
 187                        dst_bpc = 10;
 188                break;
 189                default:
 190                        dst_bpc = 8;
 191                break;
 192                }
 193
 194                /* increment for the first ramp for one color gradation
 195                 * 1 gradation for 6-bit color is 2^10
 196                 * gradations in 16-bit color
 197                 */
 198                inc_base = (src_bpc - dst_bpc);
 199
 200                switch (bit_depth) {
 201                case TEST_PATTERN_COLOR_FORMAT_BPC_6:
 202                {
 203                        REG_SET_3(DPG_RAMP_CONTROL, 0,
 204                                DPG_RAMP0_OFFSET, 0,
 205                                DPG_INC0, inc_base,
 206                                DPG_INC1, 0);
 207                        REG_UPDATE_2(DPG_CONTROL,
 208                                DPG_VRES, 6,
 209                                DPG_HRES, 6);
 210                }
 211                break;
 212                case TEST_PATTERN_COLOR_FORMAT_BPC_8:
 213                {
 214                        REG_SET_3(DPG_RAMP_CONTROL, 0,
 215                                DPG_RAMP0_OFFSET, 0,
 216                                DPG_INC0, inc_base,
 217                                DPG_INC1, 0);
 218                        REG_UPDATE_2(DPG_CONTROL,
 219                                DPG_VRES, 6,
 220                                DPG_HRES, 8);
 221                }
 222                break;
 223                case TEST_PATTERN_COLOR_FORMAT_BPC_10:
 224                {
 225                        REG_SET_3(DPG_RAMP_CONTROL, 0,
 226                                DPG_RAMP0_OFFSET, 384 << 6,
 227                                DPG_INC0, inc_base,
 228                                DPG_INC1, inc_base + 2);
 229                        REG_UPDATE_2(DPG_CONTROL,
 230                                DPG_VRES, 5,
 231                                DPG_HRES, 8);
 232                }
 233                break;
 234                default:
 235                break;
 236                }
 237
 238                /* enable test pattern */
 239                REG_UPDATE_4(DPG_CONTROL,
 240                        DPG_EN, 1,
 241                        DPG_MODE, mode,
 242                        DPG_DYNAMIC_RANGE, 0,
 243                        DPG_BIT_DEPTH, bit_depth);
 244        }
 245        break;
 246        case CONTROLLER_DP_TEST_PATTERN_VIDEOMODE:
 247        {
 248                REG_WRITE(DPG_CONTROL, 0);
 249                REG_WRITE(DPG_COLOUR_R_CR, 0);
 250                REG_WRITE(DPG_COLOUR_G_Y, 0);
 251                REG_WRITE(DPG_COLOUR_B_CB, 0);
 252                REG_WRITE(DPG_RAMP_CONTROL, 0);
 253        }
 254        break;
 255        case CONTROLLER_DP_TEST_PATTERN_SOLID_COLOR:
 256        {
 257                opp2_dpg_set_blank_color(opp, solid_color);
 258                REG_UPDATE_2(DPG_CONTROL,
 259                                DPG_EN, 1,
 260                                DPG_MODE, TEST_PATTERN_MODE_HORIZONTALBARS);
 261
 262                REG_SET_2(DPG_DIMENSIONS, 0,
 263                                DPG_ACTIVE_WIDTH, width,
 264                                DPG_ACTIVE_HEIGHT, height);
 265        }
 266        break;
 267        default:
 268                break;
 269
 270        }
 271}
 272
 273void opp2_dpg_set_blank_color(
 274                struct output_pixel_processor *opp,
 275                const struct tg_color *color)
 276{
 277        struct dcn20_opp *oppn20 = TO_DCN20_OPP(opp);
 278
 279        /* 16-bit MSB aligned value. Bits 3:0 of this field are hardwired to ZERO */
 280        ASSERT(color);
 281        REG_SET_2(DPG_COLOUR_B_CB, 0,
 282                        DPG_COLOUR1_B_CB, color->color_b_cb << 6,
 283                        DPG_COLOUR0_B_CB, color->color_b_cb << 6);
 284        REG_SET_2(DPG_COLOUR_G_Y, 0,
 285                        DPG_COLOUR1_G_Y, color->color_g_y << 6,
 286                        DPG_COLOUR0_G_Y, color->color_g_y << 6);
 287        REG_SET_2(DPG_COLOUR_R_CR, 0,
 288                        DPG_COLOUR1_R_CR, color->color_r_cr << 6,
 289                        DPG_COLOUR0_R_CR, color->color_r_cr << 6);
 290}
 291
 292bool opp2_dpg_is_blanked(struct output_pixel_processor *opp)
 293{
 294        struct dcn20_opp *oppn20 = TO_DCN20_OPP(opp);
 295        uint32_t dpg_en, dpg_mode;
 296        uint32_t double_buffer_pending;
 297
 298        REG_GET_2(DPG_CONTROL,
 299                        DPG_EN, &dpg_en,
 300                        DPG_MODE, &dpg_mode);
 301
 302        REG_GET(DPG_STATUS,
 303                        DPG_DOUBLE_BUFFER_PENDING, &double_buffer_pending);
 304
 305        return (dpg_en == 1) &&
 306                (double_buffer_pending == 0);
 307}
 308
 309void opp2_program_left_edge_extra_pixel (
 310                struct output_pixel_processor *opp,
 311                bool count)
 312{
 313        struct dcn20_opp *oppn20 = TO_DCN20_OPP(opp);
 314
 315        /* Specifies the number of extra left edge pixels that are supplied to
 316         * the 422 horizontal chroma sub-sample filter.
 317         * Note that when left edge pixel is not "0", fmt pixel encoding can be in either 420 or 422 mode
 318         * */
 319        REG_UPDATE(FMT_422_CONTROL, FMT_LEFT_EDGE_EXTRA_PIXEL_COUNT, count);
 320}
 321
 322/*****************************************/
 323/* Constructor, Destructor               */
 324/*****************************************/
 325
 326static struct opp_funcs dcn20_opp_funcs = {
 327                .opp_set_dyn_expansion = opp1_set_dyn_expansion,
 328                .opp_program_fmt = opp1_program_fmt,
 329                .opp_program_bit_depth_reduction = opp1_program_bit_depth_reduction,
 330                .opp_program_stereo = opp1_program_stereo,
 331                .opp_pipe_clock_control = opp1_pipe_clock_control,
 332                .opp_set_disp_pattern_generator = opp2_set_disp_pattern_generator,
 333                .dpg_is_blanked = opp2_dpg_is_blanked,
 334                .opp_dpg_set_blank_color = opp2_dpg_set_blank_color,
 335                .opp_convert_pti = NULL,
 336                .opp_destroy = opp1_destroy,
 337                .opp_program_left_edge_extra_pixel = opp2_program_left_edge_extra_pixel,
 338};
 339
 340void dcn20_opp_construct(struct dcn20_opp *oppn20,
 341        struct dc_context *ctx,
 342        uint32_t inst,
 343        const struct dcn20_opp_registers *regs,
 344        const struct dcn20_opp_shift *opp_shift,
 345        const struct dcn20_opp_mask *opp_mask)
 346{
 347        oppn20->base.ctx = ctx;
 348        oppn20->base.inst = inst;
 349        oppn20->base.funcs = &dcn20_opp_funcs;
 350
 351        oppn20->regs = regs;
 352        oppn20->opp_shift = opp_shift;
 353        oppn20->opp_mask = opp_mask;
 354}
 355
 356