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 */ 34 enum 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 43 enum 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 52 static 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 67 struct out_csc_color_matrix_type { 68 enum dc_color_space_type color_space_type; 69 uint16_t regval[12]; 70 }; 71 72 static 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 93 static 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 109 static 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 120 static 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 131 static 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 141 static 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 152 static 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 } 161 162 static 163 enum dc_color_space_type get_color_space_type(enum dc_color_space color_space) 164 { 165 enum dc_color_space_type type = COLOR_SPACE_RGB_TYPE; 166 167 if (is_rgb_type(color_space)) 168 type = COLOR_SPACE_RGB_TYPE; 169 else if (is_rgb_limited_type(color_space)) 170 type = COLOR_SPACE_RGB_LIMITED_TYPE; 171 else if (is_ycbcr601_type(color_space)) 172 type = COLOR_SPACE_YCBCR601_TYPE; 173 else if (is_ycbcr709_type(color_space)) 174 type = COLOR_SPACE_YCBCR709_TYPE; 175 else if (is_ycbcr601_limited_type(color_space)) 176 type = COLOR_SPACE_YCBCR601_LIMITED_TYPE; 177 else if (is_ycbcr709_limited_type(color_space)) 178 type = COLOR_SPACE_YCBCR709_LIMITED_TYPE; 179 180 return type; 181 } 182 183 const uint16_t *find_color_matrix(enum dc_color_space color_space, 184 uint32_t *array_size) 185 { 186 int i; 187 enum dc_color_space_type type; 188 const uint16_t *val = NULL; 189 int arr_size = NUM_ELEMENTS(output_csc_matrix); 190 191 type = get_color_space_type(color_space); 192 for (i = 0; i < arr_size; i++) 193 if (output_csc_matrix[i].color_space_type == type) { 194 val = output_csc_matrix[i].regval; 195 *array_size = 12; 196 break; 197 } 198 199 return val; 200 } 201 202 203 void color_space_to_black_color( 204 const struct dc *dc, 205 enum dc_color_space colorspace, 206 struct tg_color *black_color) 207 { 208 switch (colorspace) { 209 case COLOR_SPACE_YCBCR601: 210 case COLOR_SPACE_YCBCR709: 211 case COLOR_SPACE_YCBCR601_LIMITED: 212 case COLOR_SPACE_YCBCR709_LIMITED: 213 case COLOR_SPACE_2020_YCBCR: 214 *black_color = black_color_format[BLACK_COLOR_FORMAT_YUV_CV]; 215 break; 216 217 case COLOR_SPACE_SRGB_LIMITED: 218 *black_color = 219 black_color_format[BLACK_COLOR_FORMAT_RGB_LIMITED]; 220 break; 221 222 /** 223 * Remove default and add case for all color space 224 * so when we forget to add new color space 225 * compiler will give a warning 226 */ 227 case COLOR_SPACE_UNKNOWN: 228 case COLOR_SPACE_SRGB: 229 case COLOR_SPACE_XR_RGB: 230 case COLOR_SPACE_MSREF_SCRGB: 231 case COLOR_SPACE_XV_YCC_709: 232 case COLOR_SPACE_XV_YCC_601: 233 case COLOR_SPACE_2020_RGB_FULLRANGE: 234 case COLOR_SPACE_2020_RGB_LIMITEDRANGE: 235 case COLOR_SPACE_ADOBERGB: 236 case COLOR_SPACE_DCIP3: 237 case COLOR_SPACE_DISPLAYNATIVE: 238 case COLOR_SPACE_DOLBYVISION: 239 case COLOR_SPACE_APPCTRL: 240 case COLOR_SPACE_CUSTOMPOINTS: 241 /* fefault is sRGB black (full range). */ 242 *black_color = 243 black_color_format[BLACK_COLOR_FORMAT_RGB_FULLRANGE]; 244 /* default is sRGB black 0. */ 245 break; 246 } 247 } 248 249 bool hwss_wait_for_blank_complete( 250 struct timing_generator *tg) 251 { 252 int counter; 253 254 /* Not applicable if the pipe is not primary, save 300ms of boot time */ 255 if (!tg->funcs->is_blanked) 256 return true; 257 for (counter = 0; counter < 100; counter++) { 258 if (tg->funcs->is_blanked(tg)) 259 break; 260 261 msleep(1); 262 } 263 264 if (counter == 100) { 265 dm_error("DC: failed to blank crtc!\n"); 266 return false; 267 } 268 269 return true; 270 } 271