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