1 // SPDX-License-Identifier: MIT 2 /* 3 * Copyright © 2023 Intel Corporation 4 */ 5 6 #include <linux/ctype.h> 7 #include <linux/debugfs.h> 8 #include <linux/int_log.h> 9 #include <linux/math.h> 10 11 #include <drm/drm_fixed.h> 12 #include <drm/drm_print.h> 13 14 #include "intel_atomic.h" 15 #include "intel_crtc.h" 16 #include "intel_display_core.h" 17 #include "intel_display_types.h" 18 #include "intel_dp.h" 19 #include "intel_dp_mst.h" 20 #include "intel_dp_tunnel.h" 21 #include "intel_fdi.h" 22 #include "intel_link_bw.h" 23 #include "intel_vdsc.h" 24 25 static int get_forced_link_bpp_x16(struct intel_atomic_state *state, 26 const struct intel_crtc *crtc) 27 { 28 struct intel_digital_connector_state *conn_state; 29 struct intel_connector *connector; 30 int force_bpp_x16 = INT_MAX; 31 int i; 32 33 for_each_new_intel_connector_in_state(state, connector, conn_state, i) { 34 if (conn_state->base.crtc != &crtc->base) 35 continue; 36 37 if (!connector->link.force_bpp_x16) 38 continue; 39 40 force_bpp_x16 = min(force_bpp_x16, connector->link.force_bpp_x16); 41 } 42 43 return force_bpp_x16 < INT_MAX ? force_bpp_x16 : 0; 44 } 45 46 /** 47 * intel_link_bw_init_limits - initialize BW limits 48 * @state: Atomic state 49 * @limits: link BW limits 50 * 51 * Initialize @limits. 52 */ 53 void intel_link_bw_init_limits(struct intel_atomic_state *state, 54 struct intel_link_bw_limits *limits) 55 { 56 struct intel_display *display = to_intel_display(state); 57 enum pipe pipe; 58 59 limits->link_dsc_pipes = 0; 60 limits->bpp_limit_reached_pipes = 0; 61 for_each_pipe(display, pipe) { 62 struct intel_crtc *crtc = intel_crtc_for_pipe(display, pipe); 63 const struct intel_crtc_state *crtc_state = 64 intel_atomic_get_new_crtc_state(state, crtc); 65 int forced_bpp_x16 = get_forced_link_bpp_x16(state, crtc); 66 67 if (state->base.duplicated && crtc_state) { 68 limits->max_bpp_x16[pipe] = crtc_state->max_link_bpp_x16; 69 if (intel_dsc_enabled_on_link(crtc_state)) 70 limits->link_dsc_pipes |= BIT(pipe); 71 } else { 72 limits->max_bpp_x16[pipe] = INT_MAX; 73 } 74 75 if (forced_bpp_x16) 76 limits->max_bpp_x16[pipe] = min(limits->max_bpp_x16[pipe], forced_bpp_x16); 77 } 78 } 79 80 /** 81 * __intel_link_bw_reduce_bpp - reduce maximum link bpp for a selected pipe 82 * @state: atomic state 83 * @limits: link BW limits 84 * @pipe_mask: mask of pipes to select from 85 * @reason: explanation of why bpp reduction is needed 86 * @reduce_forced_bpp: allow reducing bpps below their forced link bpp 87 * 88 * Select the pipe from @pipe_mask with the biggest link bpp value and set the 89 * maximum of link bpp in @limits below this value. Modeset the selected pipe, 90 * so that its state will get recomputed. 91 * 92 * This function can be called to resolve a link's BW overallocation by reducing 93 * the link bpp of one pipe on the link and hence reducing the total link BW. 94 * 95 * Returns 96 * - 0 in case of success 97 * - %-ENOSPC if no pipe can further reduce its link bpp 98 * - Other negative error, if modesetting the selected pipe failed 99 */ 100 static int __intel_link_bw_reduce_bpp(struct intel_atomic_state *state, 101 struct intel_link_bw_limits *limits, 102 u8 pipe_mask, 103 const char *reason, 104 bool reduce_forced_bpp) 105 { 106 struct intel_display *display = to_intel_display(state); 107 enum pipe max_bpp_pipe = INVALID_PIPE; 108 struct intel_crtc *crtc; 109 int max_bpp_x16 = 0; 110 111 for_each_intel_crtc_in_pipe_mask(display->drm, crtc, pipe_mask) { 112 struct intel_crtc_state *crtc_state; 113 int link_bpp_x16; 114 115 if (limits->bpp_limit_reached_pipes & BIT(crtc->pipe)) 116 continue; 117 118 crtc_state = intel_atomic_get_crtc_state(&state->base, 119 crtc); 120 if (IS_ERR(crtc_state)) 121 return PTR_ERR(crtc_state); 122 123 if (crtc_state->dsc.compression_enable) 124 link_bpp_x16 = crtc_state->dsc.compressed_bpp_x16; 125 else 126 /* 127 * TODO: for YUV420 the actual link bpp is only half 128 * of the pipe bpp value. The MST encoder's BW allocation 129 * is based on the pipe bpp value, set the actual link bpp 130 * limit here once the MST BW allocation is fixed. 131 */ 132 link_bpp_x16 = fxp_q4_from_int(crtc_state->pipe_bpp); 133 134 if (!reduce_forced_bpp && 135 link_bpp_x16 <= get_forced_link_bpp_x16(state, crtc)) 136 continue; 137 138 if (link_bpp_x16 > max_bpp_x16) { 139 max_bpp_x16 = link_bpp_x16; 140 max_bpp_pipe = crtc->pipe; 141 } 142 } 143 144 if (max_bpp_pipe == INVALID_PIPE) 145 return -ENOSPC; 146 147 limits->max_bpp_x16[max_bpp_pipe] = max_bpp_x16 - 1; 148 149 return intel_modeset_pipes_in_mask_early(state, reason, 150 BIT(max_bpp_pipe)); 151 } 152 153 int intel_link_bw_reduce_bpp(struct intel_atomic_state *state, 154 struct intel_link_bw_limits *limits, 155 u8 pipe_mask, 156 const char *reason) 157 { 158 int ret; 159 160 /* Try to keep any forced link BPP. */ 161 ret = __intel_link_bw_reduce_bpp(state, limits, pipe_mask, reason, false); 162 if (ret == -ENOSPC) 163 ret = __intel_link_bw_reduce_bpp(state, limits, pipe_mask, reason, true); 164 165 return ret; 166 } 167 168 /** 169 * intel_link_bw_compute_pipe_bpp - compute pipe bpp limited by max link bpp 170 * @crtc_state: the crtc state 171 * 172 * Compute the pipe bpp limited by the CRTC's maximum link bpp. Encoders can 173 * call this function during state computation in the simple case where the 174 * link bpp will always match the pipe bpp. This is the case for all non-DP 175 * encoders, while DP encoders will use a link bpp lower than pipe bpp in case 176 * of DSC compression. 177 * 178 * Returns %true in case of success, %false if pipe bpp would need to be 179 * reduced below its valid range. 180 */ 181 bool intel_link_bw_compute_pipe_bpp(struct intel_crtc_state *crtc_state) 182 { 183 int pipe_bpp = min(crtc_state->pipe_bpp, 184 fxp_q4_to_int(crtc_state->max_link_bpp_x16)); 185 186 pipe_bpp = rounddown(pipe_bpp, 2 * 3); 187 188 if (pipe_bpp < 6 * 3) 189 return false; 190 191 crtc_state->pipe_bpp = pipe_bpp; 192 193 return true; 194 } 195 196 /** 197 * intel_link_bw_set_bpp_limit_for_pipe - set link bpp limit for a pipe to its minimum 198 * @state: atomic state 199 * @old_limits: link BW limits 200 * @new_limits: link BW limits 201 * @pipe: pipe 202 * 203 * Set the link bpp limit for @pipe in @new_limits to its value in 204 * @old_limits and mark this limit as the minimum. This function must be 205 * called after a pipe's compute config function failed, @old_limits 206 * containing the bpp limit with which compute config previously passed. 207 * 208 * The function will fail if setting a minimum is not possible, either 209 * because the old and new limits match (and so would lead to a pipe compute 210 * config failure) or the limit is already at the minimum. 211 * 212 * Returns %true in case of success. 213 */ 214 bool 215 intel_link_bw_set_bpp_limit_for_pipe(struct intel_atomic_state *state, 216 const struct intel_link_bw_limits *old_limits, 217 struct intel_link_bw_limits *new_limits, 218 enum pipe pipe) 219 { 220 struct intel_display *display = to_intel_display(state); 221 222 if (pipe == INVALID_PIPE) 223 return false; 224 225 if (new_limits->max_bpp_x16[pipe] == 226 old_limits->max_bpp_x16[pipe]) 227 return false; 228 229 if (drm_WARN_ON(display->drm, 230 new_limits->bpp_limit_reached_pipes & BIT(pipe))) 231 return false; 232 233 new_limits->max_bpp_x16[pipe] = 234 old_limits->max_bpp_x16[pipe]; 235 new_limits->bpp_limit_reached_pipes |= BIT(pipe); 236 237 return true; 238 } 239 240 static int check_all_link_config(struct intel_atomic_state *state, 241 struct intel_link_bw_limits *limits) 242 { 243 /* TODO: Check additional shared display link configurations like MST */ 244 int ret; 245 246 ret = intel_dp_mst_atomic_check_link(state, limits); 247 if (ret) 248 return ret; 249 250 ret = intel_dp_tunnel_atomic_check_link(state, limits); 251 if (ret) 252 return ret; 253 254 ret = intel_fdi_atomic_check_link(state, limits); 255 if (ret) 256 return ret; 257 258 return 0; 259 } 260 261 static bool 262 assert_link_limit_change_valid(struct intel_display *display, 263 const struct intel_link_bw_limits *old_limits, 264 const struct intel_link_bw_limits *new_limits) 265 { 266 bool bpps_changed = false; 267 enum pipe pipe; 268 269 /* DSC can't be disabled after it was enabled. */ 270 if (drm_WARN_ON(display->drm, 271 (old_limits->link_dsc_pipes & new_limits->link_dsc_pipes) != 272 old_limits->link_dsc_pipes)) 273 return false; 274 275 for_each_pipe(display, pipe) { 276 /* The bpp limit can only decrease. */ 277 if (drm_WARN_ON(display->drm, 278 new_limits->max_bpp_x16[pipe] > 279 old_limits->max_bpp_x16[pipe])) 280 return false; 281 282 if (new_limits->max_bpp_x16[pipe] < 283 old_limits->max_bpp_x16[pipe]) 284 bpps_changed = true; 285 } 286 287 /* At least one limit must change. */ 288 if (drm_WARN_ON(display->drm, 289 !bpps_changed && 290 new_limits->link_dsc_pipes == 291 old_limits->link_dsc_pipes)) 292 return false; 293 294 return true; 295 } 296 297 /** 298 * intel_link_bw_atomic_check - check display link states and set a fallback config if needed 299 * @state: atomic state 300 * @new_limits: link BW limits 301 * 302 * Check the configuration of all shared display links in @state and set new BW 303 * limits in @new_limits if there is a BW limitation. 304 * 305 * Returns: 306 * - 0 if the configuration is valid 307 * - %-EAGAIN, if the configuration is invalid and @new_limits got updated 308 * with fallback values with which the configuration of all CRTCs 309 * in @state must be recomputed 310 * - Other negative error, if the configuration is invalid without a 311 * fallback possibility, or the check failed for another reason 312 */ 313 int intel_link_bw_atomic_check(struct intel_atomic_state *state, 314 struct intel_link_bw_limits *new_limits) 315 { 316 struct intel_display *display = to_intel_display(state); 317 struct intel_link_bw_limits old_limits = *new_limits; 318 int ret; 319 320 ret = check_all_link_config(state, new_limits); 321 if (ret != -EAGAIN) 322 return ret; 323 324 if (!assert_link_limit_change_valid(display, &old_limits, new_limits)) 325 return -EINVAL; 326 327 return -EAGAIN; 328 } 329 330 static int force_link_bpp_show(struct seq_file *m, void *data) 331 { 332 struct intel_connector *connector = m->private; 333 334 seq_printf(m, FXP_Q4_FMT "\n", FXP_Q4_ARGS(connector->link.force_bpp_x16)); 335 336 return 0; 337 } 338 339 static int str_to_fxp_q4_nonneg_int(const char *str, int *val_x16) 340 { 341 unsigned int val; 342 int err; 343 344 err = kstrtouint(str, 10, &val); 345 if (err) 346 return err; 347 348 if (val > INT_MAX >> 4) 349 return -ERANGE; 350 351 *val_x16 = fxp_q4_from_int(val); 352 353 return 0; 354 } 355 356 /* modifies str */ 357 static int str_to_fxp_q4_nonneg(char *str, int *val_x16) 358 { 359 const char *int_str; 360 char *frac_str; 361 int frac_digits; 362 int frac_val; 363 int err; 364 365 int_str = strim(str); 366 frac_str = strchr(int_str, '.'); 367 368 if (frac_str) 369 *frac_str++ = '\0'; 370 371 err = str_to_fxp_q4_nonneg_int(int_str, val_x16); 372 if (err) 373 return err; 374 375 if (!frac_str) 376 return 0; 377 378 /* prevent negative number/leading +- sign mark */ 379 if (!isdigit(*frac_str)) 380 return -EINVAL; 381 382 err = str_to_fxp_q4_nonneg_int(frac_str, &frac_val); 383 if (err) 384 return err; 385 386 frac_digits = strlen(frac_str); 387 if (frac_digits > intlog10(INT_MAX) >> 24 || 388 frac_val > INT_MAX - int_pow(10, frac_digits) / 2) 389 return -ERANGE; 390 391 frac_val = DIV_ROUND_CLOSEST(frac_val, (int)int_pow(10, frac_digits)); 392 393 if (*val_x16 > INT_MAX - frac_val) 394 return -ERANGE; 395 396 *val_x16 += frac_val; 397 398 return 0; 399 } 400 401 static int user_str_to_fxp_q4_nonneg(const char __user *ubuf, size_t len, int *val_x16) 402 { 403 char *kbuf; 404 int err; 405 406 kbuf = memdup_user_nul(ubuf, len); 407 if (IS_ERR(kbuf)) 408 return PTR_ERR(kbuf); 409 410 err = str_to_fxp_q4_nonneg(kbuf, val_x16); 411 412 kfree(kbuf); 413 414 return err; 415 } 416 417 static bool connector_supports_dsc(struct intel_connector *connector) 418 { 419 struct intel_display *display = to_intel_display(connector); 420 421 switch (connector->base.connector_type) { 422 case DRM_MODE_CONNECTOR_eDP: 423 return intel_dp_has_dsc(connector); 424 case DRM_MODE_CONNECTOR_DisplayPort: 425 if (connector->mst.dp) 426 return HAS_DSC_MST(display); 427 428 return HAS_DSC(display); 429 default: 430 return false; 431 } 432 } 433 434 static ssize_t 435 force_link_bpp_write(struct file *file, const char __user *ubuf, size_t len, loff_t *offp) 436 { 437 struct seq_file *m = file->private_data; 438 struct intel_connector *connector = m->private; 439 struct intel_display *display = to_intel_display(connector); 440 int min_bpp; 441 int bpp_x16; 442 int err; 443 444 err = user_str_to_fxp_q4_nonneg(ubuf, len, &bpp_x16); 445 if (err) 446 return err; 447 448 /* TODO: Make the non-DSC min_bpp value connector specific. */ 449 if (connector_supports_dsc(connector)) 450 min_bpp = intel_dp_dsc_min_src_compressed_bpp(); 451 else 452 min_bpp = intel_display_min_pipe_bpp(); 453 454 if (bpp_x16 && 455 (bpp_x16 < fxp_q4_from_int(min_bpp) || 456 bpp_x16 > fxp_q4_from_int(intel_display_max_pipe_bpp(display)))) 457 return -EINVAL; 458 459 err = drm_modeset_lock_single_interruptible(&display->drm->mode_config.connection_mutex); 460 if (err) 461 return err; 462 463 connector->link.force_bpp_x16 = bpp_x16; 464 465 drm_modeset_unlock(&display->drm->mode_config.connection_mutex); 466 467 *offp += len; 468 469 return len; 470 } 471 DEFINE_SHOW_STORE_ATTRIBUTE(force_link_bpp); 472 473 void intel_link_bw_connector_debugfs_add(struct intel_connector *connector) 474 { 475 struct intel_display *display = to_intel_display(connector); 476 struct dentry *root = connector->base.debugfs_entry; 477 478 switch (connector->base.connector_type) { 479 case DRM_MODE_CONNECTOR_DisplayPort: 480 case DRM_MODE_CONNECTOR_eDP: 481 case DRM_MODE_CONNECTOR_HDMIA: 482 break; 483 case DRM_MODE_CONNECTOR_VGA: 484 case DRM_MODE_CONNECTOR_SVIDEO: 485 case DRM_MODE_CONNECTOR_LVDS: 486 case DRM_MODE_CONNECTOR_DVID: 487 if (HAS_FDI(display)) 488 break; 489 490 return; 491 default: 492 return; 493 } 494 495 debugfs_create_file("intel_force_link_bpp", 0644, root, 496 connector, &force_link_bpp_fops); 497 } 498