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 enum 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 181 const 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 201 void 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 *black_color = black_color_format[BLACK_COLOR_FORMAT_YUV_CV]; 212 break; 213 214 case COLOR_SPACE_SRGB_LIMITED: 215 *black_color = 216 black_color_format[BLACK_COLOR_FORMAT_RGB_LIMITED]; 217 break; 218 219 default: 220 /* fefault is sRGB black (full range). */ 221 *black_color = 222 black_color_format[BLACK_COLOR_FORMAT_RGB_FULLRANGE]; 223 /* default is sRGB black 0. */ 224 break; 225 } 226 } 227 228 bool hwss_wait_for_blank_complete( 229 struct timing_generator *tg) 230 { 231 int counter; 232 233 for (counter = 0; counter < 100; counter++) { 234 if (tg->funcs->is_blanked(tg)) 235 break; 236 237 msleep(1); 238 } 239 240 if (counter == 100) { 241 dm_error("DC: failed to blank crtc!\n"); 242 return false; 243 } 244 245 return true; 246 } 247