linux/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
<<
>>
Prefs
   1/*
   2 * Copyright 2015 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 "core_types.h"
  28#include "timing_generator.h"
  29#include "hw_sequencer.h"
  30
  31#define NUM_ELEMENTS(a) (sizeof(a) / sizeof((a)[0]))
  32
  33/* used as index in array of black_color_format */
  34enum black_color_format {
  35        BLACK_COLOR_FORMAT_RGB_FULLRANGE = 0,
  36        BLACK_COLOR_FORMAT_RGB_LIMITED,
  37        BLACK_COLOR_FORMAT_YUV_TV,
  38        BLACK_COLOR_FORMAT_YUV_CV,
  39        BLACK_COLOR_FORMAT_YUV_SUPER_AA,
  40        BLACK_COLOR_FORMAT_DEBUG,
  41};
  42
  43enum dc_color_space_type {
  44        COLOR_SPACE_RGB_TYPE,
  45        COLOR_SPACE_RGB_LIMITED_TYPE,
  46        COLOR_SPACE_YCBCR601_TYPE,
  47        COLOR_SPACE_YCBCR709_TYPE,
  48        COLOR_SPACE_YCBCR601_LIMITED_TYPE,
  49        COLOR_SPACE_YCBCR709_LIMITED_TYPE
  50};
  51
  52static const struct tg_color black_color_format[] = {
  53        /* BlackColorFormat_RGB_FullRange */
  54        {0, 0, 0},
  55        /* BlackColorFormat_RGB_Limited */
  56        {0x40, 0x40, 0x40},
  57        /* BlackColorFormat_YUV_TV */
  58        {0x200, 0x40, 0x200},
  59        /* BlackColorFormat_YUV_CV */
  60        {0x1f4, 0x40, 0x1f4},
  61        /* BlackColorFormat_YUV_SuperAA */
  62        {0x1a2, 0x20, 0x1a2},
  63        /* visual confirm debug */
  64        {0xff, 0xff, 0},
  65};
  66
  67struct out_csc_color_matrix_type {
  68        enum dc_color_space_type color_space_type;
  69        uint16_t regval[12];
  70};
  71
  72static const struct out_csc_color_matrix_type output_csc_matrix[] = {
  73        { COLOR_SPACE_RGB_TYPE,
  74                { 0x2000, 0, 0, 0, 0, 0x2000, 0, 0, 0, 0, 0x2000, 0} },
  75        { COLOR_SPACE_RGB_LIMITED_TYPE,
  76                { 0x1B67, 0, 0, 0x201, 0, 0x1B67, 0, 0x201, 0, 0, 0x1B67, 0x201} },
  77        { COLOR_SPACE_YCBCR601_TYPE,
  78                { 0xE04, 0xF444, 0xFDB9, 0x1004, 0x831, 0x1016, 0x320, 0x201, 0xFB45,
  79                                0xF6B7, 0xE04, 0x1004} },
  80        { COLOR_SPACE_YCBCR709_TYPE,
  81                { 0xE04, 0xF345, 0xFEB7, 0x1004, 0x5D3, 0x1399, 0x1FA,
  82                                0x201, 0xFCCA, 0xF533, 0xE04, 0x1004} },
  83
  84        /* TODO: correct values below */
  85        { COLOR_SPACE_YCBCR601_LIMITED_TYPE,
  86                { 0xE00, 0xF447, 0xFDB9, 0x1000, 0x991,
  87                                0x12C9, 0x3A6, 0x200, 0xFB47, 0xF6B9, 0xE00, 0x1000} },
  88        { COLOR_SPACE_YCBCR709_LIMITED_TYPE,
  89                { 0xE00, 0xF349, 0xFEB7, 0x1000, 0x6CE, 0x16E3,
  90                                0x24F, 0x200, 0xFCCB, 0xF535, 0xE00, 0x1000} },
  91};
  92
  93static bool is_rgb_type(
  94                enum dc_color_space color_space)
  95{
  96        bool ret = false;
  97
  98        if (color_space == COLOR_SPACE_SRGB                     ||
  99                color_space == COLOR_SPACE_XR_RGB               ||
 100                color_space == COLOR_SPACE_MSREF_SCRGB          ||
 101                color_space == COLOR_SPACE_2020_RGB_FULLRANGE   ||
 102                color_space == COLOR_SPACE_ADOBERGB             ||
 103                color_space == COLOR_SPACE_DCIP3        ||
 104                color_space == COLOR_SPACE_DOLBYVISION)
 105                ret = true;
 106        return ret;
 107}
 108
 109static bool is_rgb_limited_type(
 110                enum dc_color_space color_space)
 111{
 112        bool ret = false;
 113
 114        if (color_space == COLOR_SPACE_SRGB_LIMITED             ||
 115                color_space == COLOR_SPACE_2020_RGB_LIMITEDRANGE)
 116                ret = true;
 117        return ret;
 118}
 119
 120static bool is_ycbcr601_type(
 121                enum dc_color_space color_space)
 122{
 123        bool ret = false;
 124
 125        if (color_space == COLOR_SPACE_YCBCR601 ||
 126                color_space == COLOR_SPACE_XV_YCC_601)
 127                ret = true;
 128        return ret;
 129}
 130
 131static bool is_ycbcr601_limited_type(
 132                enum dc_color_space color_space)
 133{
 134        bool ret = false;
 135
 136        if (color_space == COLOR_SPACE_YCBCR601_LIMITED)
 137                ret = true;
 138        return ret;
 139}
 140
 141static bool is_ycbcr709_type(
 142                enum dc_color_space color_space)
 143{
 144        bool ret = false;
 145
 146        if (color_space == COLOR_SPACE_YCBCR709 ||
 147                color_space == COLOR_SPACE_XV_YCC_709)
 148                ret = true;
 149        return ret;
 150}
 151
 152static bool is_ycbcr709_limited_type(
 153                enum dc_color_space color_space)
 154{
 155        bool ret = false;
 156
 157        if (color_space == COLOR_SPACE_YCBCR709_LIMITED)
 158                ret = true;
 159        return ret;
 160}
 161enum dc_color_space_type get_color_space_type(enum dc_color_space color_space)
 162{
 163        enum dc_color_space_type type = COLOR_SPACE_RGB_TYPE;
 164
 165        if (is_rgb_type(color_space))
 166                type = COLOR_SPACE_RGB_TYPE;
 167        else if (is_rgb_limited_type(color_space))
 168                type = COLOR_SPACE_RGB_LIMITED_TYPE;
 169        else if (is_ycbcr601_type(color_space))
 170                type = COLOR_SPACE_YCBCR601_TYPE;
 171        else if (is_ycbcr709_type(color_space))
 172                type = COLOR_SPACE_YCBCR709_TYPE;
 173        else if (is_ycbcr601_limited_type(color_space))
 174                type = COLOR_SPACE_YCBCR601_LIMITED_TYPE;
 175        else if (is_ycbcr709_limited_type(color_space))
 176                type = COLOR_SPACE_YCBCR709_LIMITED_TYPE;
 177
 178        return type;
 179}
 180
 181const uint16_t *find_color_matrix(enum dc_color_space color_space,
 182                                                        uint32_t *array_size)
 183{
 184        int i;
 185        enum dc_color_space_type type;
 186        const uint16_t *val = NULL;
 187        int arr_size = NUM_ELEMENTS(output_csc_matrix);
 188
 189        type = get_color_space_type(color_space);
 190        for (i = 0; i < arr_size; i++)
 191                if (output_csc_matrix[i].color_space_type == type) {
 192                        val = output_csc_matrix[i].regval;
 193                        *array_size = 12;
 194                        break;
 195                }
 196
 197        return val;
 198}
 199
 200
 201void color_space_to_black_color(
 202        const struct dc *dc,
 203        enum dc_color_space colorspace,
 204        struct tg_color *black_color)
 205{
 206        switch (colorspace) {
 207        case COLOR_SPACE_YCBCR601:
 208        case COLOR_SPACE_YCBCR709:
 209        case COLOR_SPACE_YCBCR601_LIMITED:
 210        case COLOR_SPACE_YCBCR709_LIMITED:
 211        case COLOR_SPACE_2020_YCBCR:
 212                *black_color = black_color_format[BLACK_COLOR_FORMAT_YUV_CV];
 213                break;
 214
 215        case COLOR_SPACE_SRGB_LIMITED:
 216                *black_color =
 217                        black_color_format[BLACK_COLOR_FORMAT_RGB_LIMITED];
 218                break;
 219
 220        /**
 221         * Remove default and add case for all color space
 222         * so when we forget to add new color space
 223         * compiler will give a warning
 224         */
 225        case COLOR_SPACE_UNKNOWN:
 226        case COLOR_SPACE_SRGB:
 227        case COLOR_SPACE_XR_RGB:
 228        case COLOR_SPACE_MSREF_SCRGB:
 229        case COLOR_SPACE_XV_YCC_709:
 230        case COLOR_SPACE_XV_YCC_601:
 231        case COLOR_SPACE_2020_RGB_FULLRANGE:
 232        case COLOR_SPACE_2020_RGB_LIMITEDRANGE:
 233        case COLOR_SPACE_ADOBERGB:
 234        case COLOR_SPACE_DCIP3:
 235        case COLOR_SPACE_DISPLAYNATIVE:
 236        case COLOR_SPACE_DOLBYVISION:
 237        case COLOR_SPACE_APPCTRL:
 238        case COLOR_SPACE_CUSTOMPOINTS:
 239                /* fefault is sRGB black (full range). */
 240                *black_color =
 241                        black_color_format[BLACK_COLOR_FORMAT_RGB_FULLRANGE];
 242                /* default is sRGB black 0. */
 243                break;
 244        }
 245}
 246
 247bool hwss_wait_for_blank_complete(
 248                struct timing_generator *tg)
 249{
 250        int counter;
 251
 252        /* Not applicable if the pipe is not primary, save 300ms of boot time */
 253        if (!tg->funcs->is_blanked)
 254                return true;
 255        for (counter = 0; counter < 100; counter++) {
 256                if (tg->funcs->is_blanked(tg))
 257                        break;
 258
 259                msleep(1);
 260        }
 261
 262        if (counter == 100) {
 263                dm_error("DC: failed to blank crtc!\n");
 264                return false;
 265        }
 266
 267        return true;
 268}
 269