1/* $NetBSD: amdgpu_dc_hw_sequencer.c,v 1.4 2021/12/19 10:59:36 riastradh Exp $ */ 2 3/* 4 * Copyright 2015 Advanced Micro Devices, Inc. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the "Software"), 8 * to deal in the Software without restriction, including without limitation 9 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 * and/or sell copies of the Software, and to permit persons to whom the 11 * Software is furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 * OTHER DEALINGS IN THE SOFTWARE. 23 * 24 * Authors: AMD 25 * 26 */ 27 28#include <sys/cdefs.h> 29__KERNEL_RCSID(0, "$NetBSD: amdgpu_dc_hw_sequencer.c,v 1.4 2021/12/19 10:59:36 riastradh Exp $"); 30 31#include <linux/delay.h> 32 33#include "dm_services.h" 34#include "core_types.h" 35#include "timing_generator.h" 36#include "hw_sequencer.h" 37 38#define NUM_ELEMENTS(a) (sizeof(a) / sizeof((a)[0])) 39 40/* used as index in array of black_color_format */ 41enum black_color_format { 42 BLACK_COLOR_FORMAT_RGB_FULLRANGE = 0, 43 BLACK_COLOR_FORMAT_RGB_LIMITED, 44 BLACK_COLOR_FORMAT_YUV_TV, 45 BLACK_COLOR_FORMAT_YUV_CV, 46 BLACK_COLOR_FORMAT_YUV_SUPER_AA, 47 BLACK_COLOR_FORMAT_DEBUG, 48}; 49 50enum dc_color_space_type { 51 COLOR_SPACE_RGB_TYPE, 52 COLOR_SPACE_RGB_LIMITED_TYPE, 53 COLOR_SPACE_YCBCR601_TYPE, 54 COLOR_SPACE_YCBCR709_TYPE, 55 COLOR_SPACE_YCBCR2020_TYPE, 56 COLOR_SPACE_YCBCR601_LIMITED_TYPE, 57 COLOR_SPACE_YCBCR709_LIMITED_TYPE, 58 COLOR_SPACE_YCBCR709_BLACK_TYPE, 59}; 60 61static const struct tg_color black_color_format[] = { 62 /* BlackColorFormat_RGB_FullRange */ 63 {0, 0, 0}, 64 /* BlackColorFormat_RGB_Limited */ 65 {0x40, 0x40, 0x40}, 66 /* BlackColorFormat_YUV_TV */ 67 {0x200, 0x40, 0x200}, 68 /* BlackColorFormat_YUV_CV */ 69 {0x1f4, 0x40, 0x1f4}, 70 /* BlackColorFormat_YUV_SuperAA */ 71 {0x1a2, 0x20, 0x1a2}, 72 /* visual confirm debug */ 73 {0xff, 0xff, 0}, 74}; 75 76struct out_csc_color_matrix_type { 77 enum dc_color_space_type color_space_type; 78 uint16_t regval[12]; 79}; 80 81static const struct out_csc_color_matrix_type output_csc_matrix[] = { 82 { COLOR_SPACE_RGB_TYPE, 83 { 0x2000, 0, 0, 0, 0, 0x2000, 0, 0, 0, 0, 0x2000, 0} }, 84 { COLOR_SPACE_RGB_LIMITED_TYPE, 85 { 0x1B67, 0, 0, 0x201, 0, 0x1B67, 0, 0x201, 0, 0, 0x1B67, 0x201} }, 86 { COLOR_SPACE_YCBCR601_TYPE, 87 { 0xE04, 0xF444, 0xFDB9, 0x1004, 0x831, 0x1016, 0x320, 0x201, 0xFB45, 88 0xF6B7, 0xE04, 0x1004} }, 89 { COLOR_SPACE_YCBCR709_TYPE, 90 { 0xE04, 0xF345, 0xFEB7, 0x1004, 0x5D3, 0x1399, 0x1FA, 91 0x201, 0xFCCA, 0xF533, 0xE04, 0x1004} }, 92 /* TODO: correct values below */ 93 { COLOR_SPACE_YCBCR601_LIMITED_TYPE, 94 { 0xE00, 0xF447, 0xFDB9, 0x1000, 0x991, 95 0x12C9, 0x3A6, 0x200, 0xFB47, 0xF6B9, 0xE00, 0x1000} }, 96 { COLOR_SPACE_YCBCR709_LIMITED_TYPE, 97 { 0xE00, 0xF349, 0xFEB7, 0x1000, 0x6CE, 0x16E3, 98 0x24F, 0x200, 0xFCCB, 0xF535, 0xE00, 0x1000} }, 99 { COLOR_SPACE_YCBCR2020_TYPE, 100 { 0x1000, 0xF149, 0xFEB7, 0x0000, 0x0868, 0x15B2, 101 0x01E6, 0x0000, 0xFB88, 0xF478, 0x1000, 0x0000} }, 102 { COLOR_SPACE_YCBCR709_BLACK_TYPE, 103 { 0x0000, 0x0000, 0x0000, 0x1000, 0x0000, 0x0000, 104 0x0000, 0x0200, 0x0000, 0x0000, 0x0000, 0x1000} }, 105}; 106 107static bool is_rgb_type( 108 enum dc_color_space color_space) 109{ 110 bool ret = false; 111 112 if (color_space == COLOR_SPACE_SRGB || 113 color_space == COLOR_SPACE_XR_RGB || 114 color_space == COLOR_SPACE_MSREF_SCRGB || 115 color_space == COLOR_SPACE_2020_RGB_FULLRANGE || 116 color_space == COLOR_SPACE_ADOBERGB || 117 color_space == COLOR_SPACE_DCIP3 || 118 color_space == COLOR_SPACE_DOLBYVISION) 119 ret = true; 120 return ret; 121} 122 123static bool is_rgb_limited_type( 124 enum dc_color_space color_space) 125{ 126 bool ret = false; 127 128 if (color_space == COLOR_SPACE_SRGB_LIMITED || 129 color_space == COLOR_SPACE_2020_RGB_LIMITEDRANGE) 130 ret = true; 131 return ret; 132} 133 134static bool is_ycbcr601_type( 135 enum dc_color_space color_space) 136{ 137 bool ret = false; 138 139 if (color_space == COLOR_SPACE_YCBCR601 || 140 color_space == COLOR_SPACE_XV_YCC_601) 141 ret = true; 142 return ret; 143} 144 145static bool is_ycbcr601_limited_type( 146 enum dc_color_space color_space) 147{ 148 bool ret = false; 149 150 if (color_space == COLOR_SPACE_YCBCR601_LIMITED) 151 ret = true; 152 return ret; 153} 154 155static bool is_ycbcr709_type( 156 enum dc_color_space color_space) 157{ 158 bool ret = false; 159 160 if (color_space == COLOR_SPACE_YCBCR709 || 161 color_space == COLOR_SPACE_XV_YCC_709) 162 ret = true; 163 return ret; 164} 165 166static bool is_ycbcr2020_type( 167 enum dc_color_space color_space) 168{ 169 bool ret = false; 170 171 if (color_space == COLOR_SPACE_2020_YCBCR) 172 ret = true; 173 return ret; 174} 175 176static bool is_ycbcr709_limited_type( 177 enum dc_color_space color_space) 178{ 179 bool ret = false; 180 181 if (color_space == COLOR_SPACE_YCBCR709_LIMITED) 182 ret = true; 183 return ret; 184} 185enum dc_color_space_type get_color_space_type(enum dc_color_space color_space) 186{ 187 enum dc_color_space_type type = COLOR_SPACE_RGB_TYPE; 188 189 if (is_rgb_type(color_space)) 190 type = COLOR_SPACE_RGB_TYPE; 191 else if (is_rgb_limited_type(color_space)) 192 type = COLOR_SPACE_RGB_LIMITED_TYPE; 193 else if (is_ycbcr601_type(color_space)) 194 type = COLOR_SPACE_YCBCR601_TYPE; 195 else if (is_ycbcr709_type(color_space)) 196 type = COLOR_SPACE_YCBCR709_TYPE; 197 else if (is_ycbcr601_limited_type(color_space)) 198 type = COLOR_SPACE_YCBCR601_LIMITED_TYPE; 199 else if (is_ycbcr709_limited_type(color_space)) 200 type = COLOR_SPACE_YCBCR709_LIMITED_TYPE; 201 else if (is_ycbcr2020_type(color_space)) 202 type = COLOR_SPACE_YCBCR2020_TYPE; 203 else if (color_space == COLOR_SPACE_YCBCR709) 204 type = COLOR_SPACE_YCBCR709_BLACK_TYPE; 205 else if (color_space == COLOR_SPACE_YCBCR709_BLACK) 206 type = COLOR_SPACE_YCBCR709_BLACK_TYPE; 207 return type; 208} 209 210const uint16_t *find_color_matrix(enum dc_color_space color_space, 211 uint32_t *array_size) 212{ 213 int i; 214 enum dc_color_space_type type; 215 const uint16_t *val = NULL; 216 int arr_size = NUM_ELEMENTS(output_csc_matrix); 217 218 type = get_color_space_type(color_space); 219 for (i = 0; i < arr_size; i++) 220 if (output_csc_matrix[i].color_space_type == type) { 221 val = output_csc_matrix[i].regval; 222 *array_size = 12; 223 break; 224 } 225 226 return val; 227} 228 229 230void color_space_to_black_color( 231 const struct dc *dc, 232 enum dc_color_space colorspace, 233 struct tg_color *black_color) 234{ 235 switch (colorspace) { 236 case COLOR_SPACE_YCBCR601: 237 case COLOR_SPACE_YCBCR709: 238 case COLOR_SPACE_YCBCR709_BLACK: 239 case COLOR_SPACE_YCBCR601_LIMITED: 240 case COLOR_SPACE_YCBCR709_LIMITED: 241 case COLOR_SPACE_2020_YCBCR: 242 *black_color = black_color_format[BLACK_COLOR_FORMAT_YUV_CV]; 243 break; 244 245 case COLOR_SPACE_SRGB_LIMITED: 246 *black_color = 247 black_color_format[BLACK_COLOR_FORMAT_RGB_LIMITED]; 248 break; 249 250 /** 251 * Remove default and add case for all color space 252 * so when we forget to add new color space 253 * compiler will give a warning 254 */ 255 case COLOR_SPACE_UNKNOWN: 256 case COLOR_SPACE_SRGB: 257 case COLOR_SPACE_XR_RGB: 258 case COLOR_SPACE_MSREF_SCRGB: 259 case COLOR_SPACE_XV_YCC_709: 260 case COLOR_SPACE_XV_YCC_601: 261 case COLOR_SPACE_2020_RGB_FULLRANGE: 262 case COLOR_SPACE_2020_RGB_LIMITEDRANGE: 263 case COLOR_SPACE_ADOBERGB: 264 case COLOR_SPACE_DCIP3: 265 case COLOR_SPACE_DISPLAYNATIVE: 266 case COLOR_SPACE_DOLBYVISION: 267 case COLOR_SPACE_APPCTRL: 268 case COLOR_SPACE_CUSTOMPOINTS: 269 /* fefault is sRGB black (full range). */ 270 *black_color = 271 black_color_format[BLACK_COLOR_FORMAT_RGB_FULLRANGE]; 272 /* default is sRGB black 0. */ 273 break; 274 } 275} 276 277bool hwss_wait_for_blank_complete( 278 struct timing_generator *tg) 279{ 280 int counter; 281 282 /* Not applicable if the pipe is not primary, save 300ms of boot time */ 283 if (!tg->funcs->is_blanked) 284 return true; 285 for (counter = 0; counter < 100; counter++) { 286 if (tg->funcs->is_blanked(tg)) 287 break; 288 289 msleep(1); 290 } 291 292 if (counter == 100) { 293 dm_error("DC: failed to blank crtc!\n"); 294 return false; 295 } 296 297 return true; 298} 299