1 // SPDX-License-Identifier: MIT 2 /* 3 * Copyright © 2020 Intel Corporation 4 */ 5 6 #include "i915_reg.h" 7 #include "intel_de.h" 8 #include "intel_display_types.h" 9 #include "intel_fb.h" 10 #include "skl_scaler.h" 11 #include "skl_universal_plane.h" 12 13 /* 14 * The hardware phase 0.0 refers to the center of the pixel. 15 * We want to start from the top/left edge which is phase 16 * -0.5. That matches how the hardware calculates the scaling 17 * factors (from top-left of the first pixel to bottom-right 18 * of the last pixel, as opposed to the pixel centers). 19 * 20 * For 4:2:0 subsampled chroma planes we obviously have to 21 * adjust that so that the chroma sample position lands in 22 * the right spot. 23 * 24 * Note that for packed YCbCr 4:2:2 formats there is no way to 25 * control chroma siting. The hardware simply replicates the 26 * chroma samples for both of the luma samples, and thus we don't 27 * actually get the expected MPEG2 chroma siting convention :( 28 * The same behaviour is observed on pre-SKL platforms as well. 29 * 30 * Theory behind the formula (note that we ignore sub-pixel 31 * source coordinates): 32 * s = source sample position 33 * d = destination sample position 34 * 35 * Downscaling 4:1: 36 * -0.5 37 * | 0.0 38 * | | 1.5 (initial phase) 39 * | | | 40 * v v v 41 * | s | s | s | s | 42 * | d | 43 * 44 * Upscaling 1:4: 45 * -0.5 46 * | -0.375 (initial phase) 47 * | | 0.0 48 * | | | 49 * v v v 50 * | s | 51 * | d | d | d | d | 52 */ 53 static u16 skl_scaler_calc_phase(int sub, int scale, bool chroma_cosited) 54 { 55 int phase = -0x8000; 56 u16 trip = 0; 57 58 if (chroma_cosited) 59 phase += (sub - 1) * 0x8000 / sub; 60 61 phase += scale / (2 * sub); 62 63 /* 64 * Hardware initial phase limited to [-0.5:1.5]. 65 * Since the max hardware scale factor is 3.0, we 66 * should never actually excdeed 1.0 here. 67 */ 68 WARN_ON(phase < -0x8000 || phase > 0x18000); 69 70 if (phase < 0) 71 phase = 0x10000 + phase; 72 else 73 trip = PS_PHASE_TRIP; 74 75 return ((phase >> 2) & PS_PHASE_MASK) | trip; 76 } 77 78 #define SKL_MIN_SRC_W 8 79 #define SKL_MAX_SRC_W 4096 80 #define SKL_MIN_SRC_H 8 81 #define SKL_MAX_SRC_H 4096 82 #define SKL_MIN_DST_W 8 83 #define SKL_MAX_DST_W 4096 84 #define SKL_MIN_DST_H 8 85 #define SKL_MAX_DST_H 4096 86 #define ICL_MAX_SRC_W 5120 87 #define ICL_MAX_SRC_H 4096 88 #define ICL_MAX_DST_W 5120 89 #define ICL_MAX_DST_H 4096 90 #define MTL_MAX_SRC_W 4096 91 #define MTL_MAX_SRC_H 8192 92 #define MTL_MAX_DST_W 8192 93 #define MTL_MAX_DST_H 8192 94 #define SKL_MIN_YUV_420_SRC_W 16 95 #define SKL_MIN_YUV_420_SRC_H 16 96 97 static int 98 skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach, 99 unsigned int scaler_user, int *scaler_id, 100 int src_w, int src_h, int dst_w, int dst_h, 101 const struct drm_format_info *format, 102 u64 modifier, bool need_scaler) 103 { 104 struct intel_crtc_scaler_state *scaler_state = 105 &crtc_state->scaler_state; 106 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); 107 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); 108 const struct drm_display_mode *adjusted_mode = 109 &crtc_state->hw.adjusted_mode; 110 int min_src_w, min_src_h, min_dst_w, min_dst_h; 111 int max_src_w, max_src_h, max_dst_w, max_dst_h; 112 113 /* 114 * Src coordinates are already rotated by 270 degrees for 115 * the 90/270 degree plane rotation cases (to match the 116 * GTT mapping), hence no need to account for rotation here. 117 */ 118 if (src_w != dst_w || src_h != dst_h) 119 need_scaler = true; 120 121 /* 122 * Scaling/fitting not supported in IF-ID mode in GEN9+ 123 * TODO: Interlace fetch mode doesn't support YUV420 planar formats. 124 * Once NV12 is enabled, handle it here while allocating scaler 125 * for NV12. 126 */ 127 if (DISPLAY_VER(dev_priv) >= 9 && crtc_state->hw.enable && 128 need_scaler && adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) { 129 drm_dbg_kms(&dev_priv->drm, 130 "Pipe/Plane scaling not supported with IF-ID mode\n"); 131 return -EINVAL; 132 } 133 134 /* 135 * if plane is being disabled or scaler is no more required or force detach 136 * - free scaler binded to this plane/crtc 137 * - in order to do this, update crtc->scaler_usage 138 * 139 * Here scaler state in crtc_state is set free so that 140 * scaler can be assigned to other user. Actual register 141 * update to free the scaler is done in plane/panel-fit programming. 142 * For this purpose crtc/plane_state->scaler_id isn't reset here. 143 */ 144 if (force_detach || !need_scaler) { 145 if (*scaler_id >= 0) { 146 scaler_state->scaler_users &= ~(1 << scaler_user); 147 scaler_state->scalers[*scaler_id].in_use = 0; 148 149 drm_dbg_kms(&dev_priv->drm, 150 "scaler_user index %u.%u: " 151 "Staged freeing scaler id %d scaler_users = 0x%x\n", 152 crtc->pipe, scaler_user, *scaler_id, 153 scaler_state->scaler_users); 154 *scaler_id = -1; 155 } 156 return 0; 157 } 158 159 if (format && intel_format_info_is_yuv_semiplanar(format, modifier) && 160 (src_h < SKL_MIN_YUV_420_SRC_H || src_w < SKL_MIN_YUV_420_SRC_W)) { 161 drm_dbg_kms(&dev_priv->drm, 162 "Planar YUV: src dimensions not met\n"); 163 return -EINVAL; 164 } 165 166 min_src_w = SKL_MIN_SRC_W; 167 min_src_h = SKL_MIN_SRC_H; 168 min_dst_w = SKL_MIN_DST_W; 169 min_dst_h = SKL_MIN_DST_H; 170 171 if (DISPLAY_VER(dev_priv) < 11) { 172 max_src_w = SKL_MAX_SRC_W; 173 max_src_h = SKL_MAX_SRC_H; 174 max_dst_w = SKL_MAX_DST_W; 175 max_dst_h = SKL_MAX_DST_H; 176 } else if (DISPLAY_VER(dev_priv) < 14) { 177 max_src_w = ICL_MAX_SRC_W; 178 max_src_h = ICL_MAX_SRC_H; 179 max_dst_w = ICL_MAX_DST_W; 180 max_dst_h = ICL_MAX_DST_H; 181 } else { 182 max_src_w = MTL_MAX_SRC_W; 183 max_src_h = MTL_MAX_SRC_H; 184 max_dst_w = MTL_MAX_DST_W; 185 max_dst_h = MTL_MAX_DST_H; 186 } 187 188 /* range checks */ 189 if (src_w < min_src_w || src_h < min_src_h || 190 dst_w < min_dst_w || dst_h < min_dst_h || 191 src_w > max_src_w || src_h > max_src_h || 192 dst_w > max_dst_w || dst_h > max_dst_h) { 193 drm_dbg_kms(&dev_priv->drm, 194 "scaler_user index %u.%u: src %ux%u dst %ux%u " 195 "size is out of scaler range\n", 196 crtc->pipe, scaler_user, src_w, src_h, 197 dst_w, dst_h); 198 return -EINVAL; 199 } 200 201 /* mark this plane as a scaler user in crtc_state */ 202 scaler_state->scaler_users |= (1 << scaler_user); 203 drm_dbg_kms(&dev_priv->drm, "scaler_user index %u.%u: " 204 "staged scaling request for %ux%u->%ux%u scaler_users = 0x%x\n", 205 crtc->pipe, scaler_user, src_w, src_h, dst_w, dst_h, 206 scaler_state->scaler_users); 207 208 return 0; 209 } 210 211 int skl_update_scaler_crtc(struct intel_crtc_state *crtc_state) 212 { 213 const struct drm_display_mode *pipe_mode = &crtc_state->hw.pipe_mode; 214 int width, height; 215 216 if (crtc_state->pch_pfit.enabled) { 217 width = drm_rect_width(&crtc_state->pch_pfit.dst); 218 height = drm_rect_height(&crtc_state->pch_pfit.dst); 219 } else { 220 width = pipe_mode->crtc_hdisplay; 221 height = pipe_mode->crtc_vdisplay; 222 } 223 return skl_update_scaler(crtc_state, !crtc_state->hw.active, 224 SKL_CRTC_INDEX, 225 &crtc_state->scaler_state.scaler_id, 226 drm_rect_width(&crtc_state->pipe_src), 227 drm_rect_height(&crtc_state->pipe_src), 228 width, height, NULL, 0, 229 crtc_state->pch_pfit.enabled); 230 } 231 232 /** 233 * skl_update_scaler_plane - Stages update to scaler state for a given plane. 234 * @crtc_state: crtc's scaler state 235 * @plane_state: atomic plane state to update 236 * 237 * Return 238 * 0 - scaler_usage updated successfully 239 * error - requested scaling cannot be supported or other error condition 240 */ 241 int skl_update_scaler_plane(struct intel_crtc_state *crtc_state, 242 struct intel_plane_state *plane_state) 243 { 244 struct intel_plane *intel_plane = 245 to_intel_plane(plane_state->uapi.plane); 246 struct drm_i915_private *dev_priv = to_i915(intel_plane->base.dev); 247 struct drm_framebuffer *fb = plane_state->hw.fb; 248 int ret; 249 bool force_detach = !fb || !plane_state->uapi.visible; 250 bool need_scaler = false; 251 252 /* Pre-gen11 and SDR planes always need a scaler for planar formats. */ 253 if (!icl_is_hdr_plane(dev_priv, intel_plane->id) && 254 fb && intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier)) 255 need_scaler = true; 256 257 ret = skl_update_scaler(crtc_state, force_detach, 258 drm_plane_index(&intel_plane->base), 259 &plane_state->scaler_id, 260 drm_rect_width(&plane_state->uapi.src) >> 16, 261 drm_rect_height(&plane_state->uapi.src) >> 16, 262 drm_rect_width(&plane_state->uapi.dst), 263 drm_rect_height(&plane_state->uapi.dst), 264 fb ? fb->format : NULL, 265 fb ? fb->modifier : 0, 266 need_scaler); 267 268 if (ret || plane_state->scaler_id < 0) 269 return ret; 270 271 /* check colorkey */ 272 if (plane_state->ckey.flags) { 273 drm_dbg_kms(&dev_priv->drm, 274 "[PLANE:%d:%s] scaling with color key not allowed", 275 intel_plane->base.base.id, 276 intel_plane->base.name); 277 return -EINVAL; 278 } 279 280 /* Check src format */ 281 switch (fb->format->format) { 282 case DRM_FORMAT_RGB565: 283 case DRM_FORMAT_XBGR8888: 284 case DRM_FORMAT_XRGB8888: 285 case DRM_FORMAT_ABGR8888: 286 case DRM_FORMAT_ARGB8888: 287 case DRM_FORMAT_XRGB2101010: 288 case DRM_FORMAT_XBGR2101010: 289 case DRM_FORMAT_ARGB2101010: 290 case DRM_FORMAT_ABGR2101010: 291 case DRM_FORMAT_YUYV: 292 case DRM_FORMAT_YVYU: 293 case DRM_FORMAT_UYVY: 294 case DRM_FORMAT_VYUY: 295 case DRM_FORMAT_NV12: 296 case DRM_FORMAT_XYUV8888: 297 case DRM_FORMAT_P010: 298 case DRM_FORMAT_P012: 299 case DRM_FORMAT_P016: 300 case DRM_FORMAT_Y210: 301 case DRM_FORMAT_Y212: 302 case DRM_FORMAT_Y216: 303 case DRM_FORMAT_XVYU2101010: 304 case DRM_FORMAT_XVYU12_16161616: 305 case DRM_FORMAT_XVYU16161616: 306 break; 307 case DRM_FORMAT_XBGR16161616F: 308 case DRM_FORMAT_ABGR16161616F: 309 case DRM_FORMAT_XRGB16161616F: 310 case DRM_FORMAT_ARGB16161616F: 311 if (DISPLAY_VER(dev_priv) >= 11) 312 break; 313 fallthrough; 314 default: 315 drm_dbg_kms(&dev_priv->drm, 316 "[PLANE:%d:%s] FB:%d unsupported scaling format 0x%x\n", 317 intel_plane->base.base.id, intel_plane->base.name, 318 fb->base.id, fb->format->format); 319 return -EINVAL; 320 } 321 322 return 0; 323 } 324 325 static int glk_coef_tap(int i) 326 { 327 return i % 7; 328 } 329 330 static u16 glk_nearest_filter_coef(int t) 331 { 332 return t == 3 ? 0x0800 : 0x3000; 333 } 334 335 /* 336 * Theory behind setting nearest-neighbor integer scaling: 337 * 338 * 17 phase of 7 taps requires 119 coefficients in 60 dwords per set. 339 * The letter represents the filter tap (D is the center tap) and the number 340 * represents the coefficient set for a phase (0-16). 341 * 342 * +------------+------------------------+------------------------+ 343 * |Index value | Data value coeffient 1 | Data value coeffient 2 | 344 * +------------+------------------------+------------------------+ 345 * | 00h | B0 | A0 | 346 * +------------+------------------------+------------------------+ 347 * | 01h | D0 | C0 | 348 * +------------+------------------------+------------------------+ 349 * | 02h | F0 | E0 | 350 * +------------+------------------------+------------------------+ 351 * | 03h | A1 | G0 | 352 * +------------+------------------------+------------------------+ 353 * | 04h | C1 | B1 | 354 * +------------+------------------------+------------------------+ 355 * | ... | ... | ... | 356 * +------------+------------------------+------------------------+ 357 * | 38h | B16 | A16 | 358 * +------------+------------------------+------------------------+ 359 * | 39h | D16 | C16 | 360 * +------------+------------------------+------------------------+ 361 * | 3Ah | F16 | C16 | 362 * +------------+------------------------+------------------------+ 363 * | 3Bh | Reserved | G16 | 364 * +------------+------------------------+------------------------+ 365 * 366 * To enable nearest-neighbor scaling: program scaler coefficents with 367 * the center tap (Dxx) values set to 1 and all other values set to 0 as per 368 * SCALER_COEFFICIENT_FORMAT 369 * 370 */ 371 372 static void glk_program_nearest_filter_coefs(struct drm_i915_private *dev_priv, 373 enum pipe pipe, int id, int set) 374 { 375 int i; 376 377 intel_de_write_fw(dev_priv, GLK_PS_COEF_INDEX_SET(pipe, id, set), 378 PS_COEE_INDEX_AUTO_INC); 379 380 for (i = 0; i < 17 * 7; i += 2) { 381 u32 tmp; 382 int t; 383 384 t = glk_coef_tap(i); 385 tmp = glk_nearest_filter_coef(t); 386 387 t = glk_coef_tap(i + 1); 388 tmp |= glk_nearest_filter_coef(t) << 16; 389 390 intel_de_write_fw(dev_priv, GLK_PS_COEF_DATA_SET(pipe, id, set), 391 tmp); 392 } 393 394 intel_de_write_fw(dev_priv, GLK_PS_COEF_INDEX_SET(pipe, id, set), 0); 395 } 396 397 static u32 skl_scaler_get_filter_select(enum drm_scaling_filter filter, int set) 398 { 399 if (filter == DRM_SCALING_FILTER_NEAREST_NEIGHBOR) { 400 return (PS_FILTER_PROGRAMMED | 401 PS_Y_VERT_FILTER_SELECT(set) | 402 PS_Y_HORZ_FILTER_SELECT(set) | 403 PS_UV_VERT_FILTER_SELECT(set) | 404 PS_UV_HORZ_FILTER_SELECT(set)); 405 } 406 407 return PS_FILTER_MEDIUM; 408 } 409 410 static void skl_scaler_setup_filter(struct drm_i915_private *dev_priv, enum pipe pipe, 411 int id, int set, enum drm_scaling_filter filter) 412 { 413 switch (filter) { 414 case DRM_SCALING_FILTER_DEFAULT: 415 break; 416 case DRM_SCALING_FILTER_NEAREST_NEIGHBOR: 417 glk_program_nearest_filter_coefs(dev_priv, pipe, id, set); 418 break; 419 default: 420 MISSING_CASE(filter); 421 } 422 } 423 424 void skl_pfit_enable(const struct intel_crtc_state *crtc_state) 425 { 426 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); 427 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); 428 const struct intel_crtc_scaler_state *scaler_state = 429 &crtc_state->scaler_state; 430 const struct drm_rect *dst = &crtc_state->pch_pfit.dst; 431 u16 uv_rgb_hphase, uv_rgb_vphase; 432 enum pipe pipe = crtc->pipe; 433 int width = drm_rect_width(dst); 434 int height = drm_rect_height(dst); 435 int x = dst->x1; 436 int y = dst->y1; 437 int hscale, vscale; 438 struct drm_rect src; 439 int id; 440 u32 ps_ctrl; 441 442 if (!crtc_state->pch_pfit.enabled) 443 return; 444 445 if (drm_WARN_ON(&dev_priv->drm, 446 crtc_state->scaler_state.scaler_id < 0)) 447 return; 448 449 drm_rect_init(&src, 0, 0, 450 drm_rect_width(&crtc_state->pipe_src) << 16, 451 drm_rect_height(&crtc_state->pipe_src) << 16); 452 453 hscale = drm_rect_calc_hscale(&src, dst, 0, INT_MAX); 454 vscale = drm_rect_calc_vscale(&src, dst, 0, INT_MAX); 455 456 uv_rgb_hphase = skl_scaler_calc_phase(1, hscale, false); 457 uv_rgb_vphase = skl_scaler_calc_phase(1, vscale, false); 458 459 id = scaler_state->scaler_id; 460 461 ps_ctrl = skl_scaler_get_filter_select(crtc_state->hw.scaling_filter, 0); 462 ps_ctrl |= PS_SCALER_EN | scaler_state->scalers[id].mode; 463 464 skl_scaler_setup_filter(dev_priv, pipe, id, 0, 465 crtc_state->hw.scaling_filter); 466 467 intel_de_write_fw(dev_priv, SKL_PS_CTRL(pipe, id), ps_ctrl); 468 469 intel_de_write_fw(dev_priv, SKL_PS_VPHASE(pipe, id), 470 PS_Y_PHASE(0) | PS_UV_RGB_PHASE(uv_rgb_vphase)); 471 intel_de_write_fw(dev_priv, SKL_PS_HPHASE(pipe, id), 472 PS_Y_PHASE(0) | PS_UV_RGB_PHASE(uv_rgb_hphase)); 473 intel_de_write_fw(dev_priv, SKL_PS_WIN_POS(pipe, id), 474 x << 16 | y); 475 intel_de_write_fw(dev_priv, SKL_PS_WIN_SZ(pipe, id), 476 width << 16 | height); 477 } 478 479 void 480 skl_program_plane_scaler(struct intel_plane *plane, 481 const struct intel_crtc_state *crtc_state, 482 const struct intel_plane_state *plane_state) 483 { 484 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 485 const struct drm_framebuffer *fb = plane_state->hw.fb; 486 enum pipe pipe = plane->pipe; 487 int scaler_id = plane_state->scaler_id; 488 const struct intel_scaler *scaler = 489 &crtc_state->scaler_state.scalers[scaler_id]; 490 int crtc_x = plane_state->uapi.dst.x1; 491 int crtc_y = plane_state->uapi.dst.y1; 492 u32 crtc_w = drm_rect_width(&plane_state->uapi.dst); 493 u32 crtc_h = drm_rect_height(&plane_state->uapi.dst); 494 u16 y_hphase, uv_rgb_hphase; 495 u16 y_vphase, uv_rgb_vphase; 496 int hscale, vscale; 497 u32 ps_ctrl; 498 499 hscale = drm_rect_calc_hscale(&plane_state->uapi.src, 500 &plane_state->uapi.dst, 501 0, INT_MAX); 502 vscale = drm_rect_calc_vscale(&plane_state->uapi.src, 503 &plane_state->uapi.dst, 504 0, INT_MAX); 505 506 /* TODO: handle sub-pixel coordinates */ 507 if (intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier) && 508 !icl_is_hdr_plane(dev_priv, plane->id)) { 509 y_hphase = skl_scaler_calc_phase(1, hscale, false); 510 y_vphase = skl_scaler_calc_phase(1, vscale, false); 511 512 /* MPEG2 chroma siting convention */ 513 uv_rgb_hphase = skl_scaler_calc_phase(2, hscale, true); 514 uv_rgb_vphase = skl_scaler_calc_phase(2, vscale, false); 515 } else { 516 /* not used */ 517 y_hphase = 0; 518 y_vphase = 0; 519 520 uv_rgb_hphase = skl_scaler_calc_phase(1, hscale, false); 521 uv_rgb_vphase = skl_scaler_calc_phase(1, vscale, false); 522 } 523 524 ps_ctrl = skl_scaler_get_filter_select(plane_state->hw.scaling_filter, 0); 525 ps_ctrl |= PS_SCALER_EN | PS_PLANE_SEL(plane->id) | scaler->mode; 526 527 skl_scaler_setup_filter(dev_priv, pipe, scaler_id, 0, 528 plane_state->hw.scaling_filter); 529 530 intel_de_write_fw(dev_priv, SKL_PS_CTRL(pipe, scaler_id), ps_ctrl); 531 intel_de_write_fw(dev_priv, SKL_PS_VPHASE(pipe, scaler_id), 532 PS_Y_PHASE(y_vphase) | PS_UV_RGB_PHASE(uv_rgb_vphase)); 533 intel_de_write_fw(dev_priv, SKL_PS_HPHASE(pipe, scaler_id), 534 PS_Y_PHASE(y_hphase) | PS_UV_RGB_PHASE(uv_rgb_hphase)); 535 intel_de_write_fw(dev_priv, SKL_PS_WIN_POS(pipe, scaler_id), 536 (crtc_x << 16) | crtc_y); 537 intel_de_write_fw(dev_priv, SKL_PS_WIN_SZ(pipe, scaler_id), 538 (crtc_w << 16) | crtc_h); 539 } 540 541 static void skl_detach_scaler(struct intel_crtc *crtc, int id) 542 { 543 struct drm_device *dev = crtc->base.dev; 544 struct drm_i915_private *dev_priv = to_i915(dev); 545 546 intel_de_write_fw(dev_priv, SKL_PS_CTRL(crtc->pipe, id), 0); 547 intel_de_write_fw(dev_priv, SKL_PS_WIN_POS(crtc->pipe, id), 0); 548 intel_de_write_fw(dev_priv, SKL_PS_WIN_SZ(crtc->pipe, id), 0); 549 } 550 551 /* 552 * This function detaches (aka. unbinds) unused scalers in hardware 553 */ 554 void skl_detach_scalers(const struct intel_crtc_state *crtc_state) 555 { 556 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); 557 const struct intel_crtc_scaler_state *scaler_state = 558 &crtc_state->scaler_state; 559 int i; 560 561 /* loop through and disable scalers that aren't in use */ 562 for (i = 0; i < crtc->num_scalers; i++) { 563 if (!scaler_state->scalers[i].in_use) 564 skl_detach_scaler(crtc, i); 565 } 566 } 567 568 void skl_scaler_disable(const struct intel_crtc_state *old_crtc_state) 569 { 570 struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc); 571 int i; 572 573 for (i = 0; i < crtc->num_scalers; i++) 574 skl_detach_scaler(crtc, i); 575 } 576