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