Lines Matching +full:no +full:- +full:wp

1 // SPDX-License-Identifier: MIT
80 struct intel_display *display = &i915->display;
82 return HAS_SAGV(display) && display->sagv.status != I915_SAGV_NOT_CONTROLLED;
88 struct intel_display *display = &i915->display;
100 ret = snb_pcode_read(&i915->uncore,
104 drm_dbg_kms(display->drm, "Couldn't read SAGV block time!\n");
120 struct intel_display *display = &i915->display;
123 display->sagv.status = I915_SAGV_NOT_CONTROLLED;
132 drm_WARN_ON(display->drm, display->sagv.status == I915_SAGV_UNKNOWN);
134 display->sagv.block_time_us = intel_sagv_block_time(i915);
136 drm_dbg_kms(display->drm, "SAGV supported: %s, original SAGV block time: %u us\n",
137 str_yes_no(intel_has_sagv(i915)), display->sagv.block_time_us);
140 if (drm_WARN(display->drm, display->sagv.block_time_us > U16_MAX,
142 display->sagv.block_time_us))
143 display->sagv.block_time_us = 0;
146 display->sagv.block_time_us = 0;
156 * - <= 1 pipe enabled
157 * - All planes can enable watermarks for latencies >= SAGV engine block time
158 * - We're not using an interlaced display configuration
167 if (i915->display.sagv.status == I915_SAGV_ENABLED)
170 drm_dbg_kms(&i915->drm, "Enabling SAGV\n");
171 ret = snb_pcode_write(&i915->uncore, GEN9_PCODE_SAGV_CONTROL,
177 * Some skl systems, pre-release machines in particular,
180 if (IS_SKYLAKE(i915) && ret == -ENXIO) {
181 drm_dbg(&i915->drm, "No SAGV found on system, ignoring\n");
182 i915->display.sagv.status = I915_SAGV_NOT_CONTROLLED;
185 drm_err(&i915->drm, "Failed to enable SAGV\n");
189 i915->display.sagv.status = I915_SAGV_ENABLED;
199 if (i915->display.sagv.status == I915_SAGV_DISABLED)
202 drm_dbg_kms(&i915->drm, "Disabling SAGV\n");
204 ret = skl_pcode_request(&i915->uncore, GEN9_PCODE_SAGV_CONTROL,
209 * Some skl systems, pre-release machines in particular,
212 if (IS_SKYLAKE(i915) && ret == -ENXIO) {
213 drm_dbg(&i915->drm, "No SAGV found on system, ignoring\n");
214 i915->display.sagv.status = I915_SAGV_NOT_CONTROLLED;
217 drm_err(&i915->drm, "Failed to disable SAGV (%d)\n", ret);
221 i915->display.sagv.status = I915_SAGV_DISABLED;
226 struct drm_i915_private *i915 = to_i915(state->base.dev);
239 struct drm_i915_private *i915 = to_i915(state->base.dev);
252 struct drm_i915_private *i915 = to_i915(state->base.dev);
262 old_mask = old_bw_state->qgv_points_mask;
263 new_mask = old_bw_state->qgv_points_mask | new_bw_state->qgv_points_mask;
268 WARN_ON(!new_bw_state->base.changed);
270 drm_dbg_kms(&i915->drm, "Restricting QGV points: 0x%x -> 0x%x\n",
284 struct drm_i915_private *i915 = to_i915(state->base.dev);
294 old_mask = old_bw_state->qgv_points_mask | new_bw_state->qgv_points_mask;
295 new_mask = new_bw_state->qgv_points_mask;
300 WARN_ON(!new_bw_state->base.changed);
302 drm_dbg_kms(&i915->drm, "Relaxing QGV points: 0x%x -> 0x%x\n",
316 struct drm_i915_private *i915 = to_i915(state->base.dev);
321 * afford it due to DBuf limitation - in case if SAGV is completely
336 struct drm_i915_private *i915 = to_i915(state->base.dev);
341 * afford it due to DBuf limitation - in case if SAGV is completely
356 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
357 struct drm_i915_private *i915 = to_i915(crtc->base.dev);
364 if (!crtc_state->hw.active)
367 if (crtc_state->hw.pipe_mode.flags & DRM_MODE_FLAG_INTERLACE)
372 &crtc_state->wm.skl.optimal.planes[plane_id];
376 if (!wm->wm[0].enable)
380 for (level = i915->display.wm.num_levels - 1;
381 !wm->wm[level].enable; --level)
388 /* No enabled planes? */
394 &crtc_state->wm.skl.optimal.planes[plane_id];
400 if (wm->wm[0].enable && !wm->wm[max_level].can_sagv)
409 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
412 if (!crtc_state->hw.active)
417 &crtc_state->wm.skl.optimal.planes[plane_id];
419 if (wm->wm[0].enable && !wm->sagv.wm0.enable)
428 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
429 struct drm_i915_private *i915 = to_i915(crtc->base.dev);
431 if (!i915->display.params.enable_sagv)
444 bw_state->active_pipes && !is_power_of_2(bw_state->active_pipes))
447 return bw_state->pipe_sagv_reject == 0;
453 struct drm_i915_private *i915 = to_i915(state->base.dev);
463 struct skl_pipe_wm *pipe_wm = &new_crtc_state->wm.skl.optimal;
473 * that bw state since we have no convenient way to get at the
486 * normal (ie. non-SAGV) watermarks.
488 pipe_wm->use_sagv_wm = !HAS_HW_SAGV_WM(display) &&
493 new_bw_state->pipe_sagv_reject &= ~BIT(crtc->pipe);
495 new_bw_state->pipe_sagv_reject |= BIT(crtc->pipe);
501 new_bw_state->active_pipes =
502 intel_calc_active_pipes(state, old_bw_state->active_pipes);
504 if (new_bw_state->active_pipes != old_bw_state->active_pipes) {
505 ret = intel_atomic_lock_global_state(&new_bw_state->base);
512 ret = intel_atomic_serialize_global_state(&new_bw_state->base);
515 } else if (new_bw_state->pipe_sagv_reject != old_bw_state->pipe_sagv_reject) {
516 ret = intel_atomic_lock_global_state(&new_bw_state->base);
527 entry->start = start;
528 entry->end = end;
535 return DISPLAY_INFO(i915)->dbuf.size /
536 hweight8(DISPLAY_INFO(i915)->dbuf.slice_mask);
546 ddb->start = 0;
547 ddb->end = 0;
551 ddb->start = (ffs(slice_mask) - 1) * slice_size;
552 ddb->end = fls(slice_mask) * slice_size;
554 WARN_ON(ddb->start >= ddb->end);
555 WARN_ON(ddb->end > DISPLAY_INFO(i915)->dbuf.size);
582 start_slice = entry->start / slice_size;
583 end_slice = (entry->end - 1) / slice_size;
599 const struct drm_display_mode *pipe_mode = &crtc_state->hw.pipe_mode;
602 if (!crtc_state->hw.active)
622 to_i915(dbuf_state->base.state->base.dev);
630 int weight = dbuf_state->weight[pipe];
636 * i.e no partial intersection), so it is enough to check for
639 if (dbuf_state->slices[pipe] != dbuf_state->slices[for_pipe])
655 struct drm_i915_private *i915 = to_i915(crtc->base.dev);
663 enum pipe pipe = crtc->pipe;
670 if (new_dbuf_state->weight[pipe] == 0) {
671 skl_ddb_entry_init(&new_dbuf_state->ddb[pipe], 0, 0);
675 dbuf_slice_mask = new_dbuf_state->slices[pipe];
687 skl_ddb_entry_init(&new_dbuf_state->ddb[pipe],
688 ddb_slices.start - mbus_offset + start,
689 ddb_slices.start - mbus_offset + end);
692 if (old_dbuf_state->slices[pipe] == new_dbuf_state->slices[pipe] &&
693 skl_ddb_entry_equal(&old_dbuf_state->ddb[pipe],
694 &new_dbuf_state->ddb[pipe]))
697 ret = intel_atomic_lock_global_state(&new_dbuf_state->base);
701 crtc_state = intel_atomic_get_crtc_state(&state->base, crtc);
709 crtc_state->wm.skl.ddb.start = mbus_offset + new_dbuf_state->ddb[pipe].start;
710 crtc_state->wm.skl.ddb.end = mbus_offset + new_dbuf_state->ddb[pipe].end;
712 drm_dbg_kms(&i915->drm,
713 "[CRTC:%d:%s] dbuf slices 0x%x -> 0x%x, ddb (%d - %d) -> (%d - %d), active pipes 0x%x -> 0x%x\n",
714 crtc->base.base.id, crtc->base.name,
715 old_dbuf_state->slices[pipe], new_dbuf_state->slices[pipe],
716 old_dbuf_state->ddb[pipe].start, old_dbuf_state->ddb[pipe].end,
717 new_dbuf_state->ddb[pipe].start, new_dbuf_state->ddb[pipe].end,
718 old_dbuf_state->active_pipes, new_dbuf_state->active_pipes);
726 u32 plane_pixel_rate, struct skl_wm_params *wp,
733 const struct skl_wm_params *wp,
738 const struct skl_wm_params *wp)
740 unsigned int latency = i915->display.wm.skl_latency[level];
753 if (skl_needs_memory_bw_wa(i915) && wp && wp->x_tiled)
763 struct intel_plane *plane = to_intel_plane(crtc_state->uapi.crtc->cursor);
764 struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
767 struct skl_wm_params wp;
774 crtc_state->pixel_rate, &wp, 0, 0);
775 drm_WARN_ON(&i915->drm, ret);
777 for (level = 0; level < i915->display.wm.num_levels; level++) {
778 unsigned int latency = skl_wm_latency(i915, level, &wp);
780 skl_compute_plane_wm(crtc_state, plane, level, latency, &wp, &wm, &wm);
795 if (entry->end)
796 entry->end++;
807 struct intel_display *display = &i915->display;
810 /* Cursor doesn't support NV12/planar, so no extra calculation needed */
840 struct drm_i915_private *i915 = to_i915(crtc->base.dev);
842 enum pipe pipe = crtc->pipe;
875 * as is from BSpec itself - that way it is at least easier
938 * as is from BSpec itself - that way it is at least easier
1343 * still here - we will need it once those additional constraints
1370 struct drm_i915_private *i915 = to_i915(crtc->base.dev);
1371 enum pipe pipe = crtc->pipe;
1396 crtc_state->uapi.async_flip &&
1397 plane->async_flip;
1419 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1420 struct drm_i915_private *i915 = to_i915(crtc->base.dev);
1428 data_rate += crtc_state->rel_data_rate[plane_id];
1431 data_rate += crtc_state->rel_data_rate_y[plane_id];
1442 const struct skl_plane_wm *wm = &pipe_wm->planes[plane_id];
1444 if (level == 0 && pipe_wm->use_sagv_wm)
1445 return &wm->sagv.wm0;
1447 return &wm->wm[level];
1454 const struct skl_plane_wm *wm = &pipe_wm->planes[plane_id];
1456 if (pipe_wm->use_sagv_wm)
1457 return &wm->sagv.trans_wm;
1459 return &wm->trans_wm;
1477 if (wm->min_ddb_alloc > skl_ddb_entry_size(ddb))
1485 if (wm->min_ddb_alloc > skl_ddb_entry_size(ddb_y) ||
1486 uv_wm->min_ddb_alloc > skl_ddb_entry_size(ddb)) {
1507 return level > 0 && !wm->wm[level].enable;
1524 extra = min_t(u16, iter->size,
1525 DIV64_U64_ROUND_UP(iter->size * data_rate,
1526 iter->data_rate));
1527 iter->size -= extra;
1528 iter->data_rate -= data_rate;
1536 size = wm->min_ddb_alloc + extra;
1538 iter->start = skl_ddb_entry_init(ddb, iter->start,
1539 iter->start + size);
1546 struct drm_i915_private *i915 = to_i915(crtc->base.dev);
1551 const struct skl_ddb_entry *alloc = &dbuf_state->ddb[crtc->pipe];
1553 int num_active = hweight8(dbuf_state->active_pipes);
1561 memset(crtc_state->wm.skl.plane_ddb, 0, sizeof(crtc_state->wm.skl.plane_ddb));
1562 memset(crtc_state->wm.skl.plane_ddb_y, 0, sizeof(crtc_state->wm.skl.plane_ddb_y));
1563 memset(crtc_state->wm.skl.plane_min_ddb, 0,
1564 sizeof(crtc_state->wm.skl.plane_min_ddb));
1565 memset(crtc_state->wm.skl.plane_interim_ddb, 0,
1566 sizeof(crtc_state->wm.skl.plane_interim_ddb));
1568 if (!crtc_state->hw.active)
1571 iter.start = alloc->start;
1578 iter.size -= cursor_size;
1579 skl_ddb_entry_init(&crtc_state->wm.skl.plane_ddb[PLANE_CURSOR],
1580 alloc->end - cursor_size, alloc->end);
1588 for (level = i915->display.wm.num_levels - 1; level >= 0; level--) {
1592 &crtc_state->wm.skl.optimal.planes[plane_id];
1596 &crtc_state->wm.skl.plane_ddb[plane_id];
1598 if (wm->wm[level].min_ddb_alloc > skl_ddb_entry_size(ddb)) {
1599 drm_WARN_ON(&i915->drm,
1600 wm->wm[level].min_ddb_alloc != U16_MAX);
1607 blocks += wm->wm[level].min_ddb_alloc;
1608 blocks += wm->uv_wm[level].min_ddb_alloc;
1612 iter.size -= blocks;
1618 drm_dbg_kms(&i915->drm,
1620 drm_dbg_kms(&i915->drm, "minimum required %d/%d\n",
1622 return -EINVAL;
1636 &crtc_state->wm.skl.plane_ddb[plane_id];
1638 &crtc_state->wm.skl.plane_ddb_y[plane_id];
1639 u16 *min_ddb = &crtc_state->wm.skl.plane_min_ddb[plane_id];
1641 &crtc_state->wm.skl.plane_interim_ddb[plane_id];
1643 &crtc_state->wm.skl.optimal.planes[plane_id];
1649 crtc_state->nv12_planes & BIT(plane_id)) {
1650 skl_allocate_plane_ddb(&iter, ddb_y, &wm->wm[level],
1651 crtc_state->rel_data_rate_y[plane_id]);
1652 skl_allocate_plane_ddb(&iter, ddb, &wm->uv_wm[level],
1653 crtc_state->rel_data_rate[plane_id]);
1655 skl_allocate_plane_ddb(&iter, ddb, &wm->wm[level],
1656 crtc_state->rel_data_rate[plane_id]);
1660 *min_ddb = wm->wm[0].min_ddb_alloc;
1661 *interim_ddb = wm->sagv.wm0.min_ddb_alloc;
1664 drm_WARN_ON(&i915->drm, iter.size != 0 || iter.data_rate != 0);
1672 for (level++; level < i915->display.wm.num_levels; level++) {
1675 &crtc_state->wm.skl.plane_ddb[plane_id];
1677 &crtc_state->wm.skl.plane_ddb_y[plane_id];
1679 &crtc_state->wm.skl.optimal.planes[plane_id];
1682 crtc_state->nv12_planes & BIT(plane_id))
1683 skl_check_nv12_wm_level(&wm->wm[level],
1684 &wm->uv_wm[level],
1687 skl_check_wm_level(&wm->wm[level], ddb);
1690 wm->wm[level].blocks = wm->wm[level - 1].blocks;
1691 wm->wm[level].lines = wm->wm[level - 1].lines;
1692 wm->wm[level].ignore_lines = wm->wm[level - 1].ignore_lines;
1703 &crtc_state->wm.skl.plane_ddb[plane_id];
1705 &crtc_state->wm.skl.plane_ddb_y[plane_id];
1707 &crtc_state->wm.skl.plane_interim_ddb[plane_id];
1709 &crtc_state->wm.skl.optimal.planes[plane_id];
1712 crtc_state->nv12_planes & BIT(plane_id)) {
1713 skl_check_wm_level(&wm->trans_wm, ddb_y);
1717 skl_check_wm_level(&wm->trans_wm, ddb);
1720 skl_check_wm_level(&wm->sagv.wm0, ddb);
1722 *interim_ddb = wm->sagv.wm0.min_ddb_alloc;
1724 skl_check_wm_level(&wm->sagv.trans_wm, ddb);
1775 struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
1780 if (!crtc_state->hw.active)
1783 pixel_rate = crtc_state->pixel_rate;
1785 if (drm_WARN_ON(&i915->drm, pixel_rate == 0))
1788 crtc_htotal = crtc_state->hw.pipe_mode.crtc_htotal;
1798 u32 plane_pixel_rate, struct skl_wm_params *wp,
1801 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1803 struct drm_i915_private *i915 = to_i915(crtc->base.dev);
1809 drm_dbg_kms(&i915->drm,
1811 return -EINVAL;
1814 wp->x_tiled = modifier == I915_FORMAT_MOD_X_TILED;
1815 wp->y_tiled = modifier != I915_FORMAT_MOD_X_TILED &&
1817 wp->rc_surface = intel_fb_is_ccs_modifier(modifier);
1818 wp->is_planar = intel_format_info_is_yuv_semiplanar(format, modifier);
1820 wp->width = width;
1821 if (color_plane == 1 && wp->is_planar)
1822 wp->width /= 2;
1824 wp->cpp = format->cpp[color_plane];
1825 wp->plane_pixel_rate = plane_pixel_rate;
1828 modifier == I915_FORMAT_MOD_Yf_TILED && wp->cpp == 1)
1829 wp->dbuf_block_size = 256;
1831 wp->dbuf_block_size = 512;
1834 switch (wp->cpp) {
1836 wp->y_min_scanlines = 16;
1839 wp->y_min_scanlines = 8;
1842 wp->y_min_scanlines = 4;
1845 MISSING_CASE(wp->cpp);
1846 return -EINVAL;
1849 wp->y_min_scanlines = 4;
1853 wp->y_min_scanlines *= 2;
1855 wp->plane_bytes_per_line = wp->width * wp->cpp;
1856 if (wp->y_tiled) {
1857 interm_pbpl = DIV_ROUND_UP(wp->plane_bytes_per_line *
1858 wp->y_min_scanlines,
1859 wp->dbuf_block_size);
1866 wp->plane_blocks_per_line = div_fixed16(interm_pbpl,
1867 wp->y_min_scanlines);
1869 interm_pbpl = DIV_ROUND_UP(wp->plane_bytes_per_line,
1870 wp->dbuf_block_size);
1872 if (!wp->x_tiled || DISPLAY_VER(i915) >= 10)
1875 wp->plane_blocks_per_line = u32_to_fixed16(interm_pbpl);
1878 wp->y_tile_minimum = mul_u32_fixed16(wp->y_min_scanlines,
1879 wp->plane_blocks_per_line);
1881 wp->linetime_us = fixed16_to_u32_round_up(intel_get_linetime_us(crtc_state));
1889 struct skl_wm_params *wp, int color_plane)
1891 const struct drm_framebuffer *fb = plane_state->hw.fb;
1897 * GTT mapping), hence no need to account for rotation here.
1899 width = drm_rect_width(&plane_state->uapi.src) >> 16;
1902 fb->format, fb->modifier,
1903 plane_state->hw.rotation,
1905 wp, color_plane,
1906 plane_state->uapi.src.x1);
1930 return DISPLAY_VER(display) >= 30 && level == 0 && plane->id != PLANE_CURSOR;
1937 const struct skl_wm_params *wp,
1941 struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
1949 result->min_ddb_alloc = U16_MAX;
1953 method1 = skl_wm_method1(i915, wp->plane_pixel_rate,
1954 wp->cpp, latency, wp->dbuf_block_size);
1955 method2 = skl_wm_method2(wp->plane_pixel_rate,
1956 crtc_state->hw.pipe_mode.crtc_htotal,
1958 wp->plane_blocks_per_line);
1960 if (wp->y_tiled) {
1961 selected_result = max_fixed16(method2, wp->y_tile_minimum);
1963 if ((wp->cpp * crtc_state->hw.pipe_mode.crtc_htotal /
1964 wp->dbuf_block_size < 1) &&
1965 (wp->plane_bytes_per_line / wp->dbuf_block_size < 1)) {
1967 } else if (latency >= wp->linetime_us) {
1999 fixed16_to_u32_round_up(wp->plane_blocks_per_line));
2001 wp->plane_blocks_per_line);
2005 if (level == 0 && wp->rc_surface)
2006 blocks += fixed16_to_u32_round_up(wp->y_tile_minimum);
2010 if (wp->y_tiled) {
2011 blocks += fixed16_to_u32_round_up(wp->y_tile_minimum);
2012 lines += wp->y_min_scanlines;
2023 if (result_prev->blocks > blocks)
2024 blocks = result_prev->blocks;
2029 if (wp->y_tiled) {
2032 if (lines % wp->y_min_scanlines == 0)
2033 extra_lines = wp->y_min_scanlines;
2035 extra_lines = wp->y_min_scanlines * 2 -
2036 lines % wp->y_min_scanlines;
2039 wp->plane_blocks_per_line);
2050 result->min_ddb_alloc = U16_MAX;
2060 result->blocks = blocks;
2061 result->lines = lines;
2062 /* Bspec says: value >= plane ddb allocation -> invalid, hence the +1 here */
2063 result->min_ddb_alloc = max(min_ddb_alloc, blocks) + 1;
2064 result->enable = true;
2065 result->auto_min_alloc_wm_enable = xe3_auto_min_alloc_capable(plane, level);
2067 if (DISPLAY_VER(i915) < 12 && i915->display.sagv.block_time_us)
2068 result->can_sagv = latency >= i915->display.sagv.block_time_us;
2077 struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
2081 for (level = 0; level < i915->display.wm.num_levels; level++) {
2097 struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
2098 struct skl_wm_level *sagv_wm = &plane_wm->sagv.wm0;
2099 struct skl_wm_level *levels = plane_wm->wm;
2102 if (i915->display.sagv.block_time_us)
2103 latency = i915->display.sagv.block_time_us +
2114 const struct skl_wm_params *wp)
2146 * letters. The value wm_l0->blocks is actually Result Blocks, but
2153 wm0_blocks = wm0->blocks - 1;
2155 if (wp->y_tiled) {
2157 (u16)mul_round_up_u32_fixed16(2, wp->y_tile_minimum);
2169 trans_wm->blocks = blocks;
2170 trans_wm->min_ddb_alloc = max_t(u16, wm0->min_ddb_alloc, blocks + 1);
2171 trans_wm->enable = true;
2178 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
2179 struct drm_i915_private *i915 = to_i915(crtc->base.dev);
2180 struct skl_plane_wm *wm = &crtc_state->wm.skl.raw.planes[plane->id];
2189 skl_compute_wm_levels(crtc_state, plane, &wm_params, wm->wm);
2191 skl_compute_transition_wm(i915, &wm->trans_wm,
2192 &wm->wm[0], &wm_params);
2197 skl_compute_transition_wm(i915, &wm->sagv.trans_wm,
2198 &wm->sagv.wm0, &wm_params);
2208 struct skl_plane_wm *wm = &crtc_state->wm.skl.raw.planes[plane->id];
2212 wm->is_planar = true;
2220 skl_compute_wm_levels(crtc_state, plane, &wm_params, wm->uv_wm);
2228 struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
2229 enum plane_id plane_id = plane->id;
2230 struct skl_plane_wm *wm = &crtc_state->wm.skl.raw.planes[plane_id];
2231 const struct drm_framebuffer *fb = plane_state->hw.fb;
2244 if (fb->format->is_yuv && fb->format->num_planes > 1) {
2257 struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
2258 struct drm_i915_private *i915 = to_i915(plane->base.dev);
2259 enum plane_id plane_id = plane->id;
2260 struct skl_plane_wm *wm = &crtc_state->wm.skl.raw.planes[plane_id];
2264 if (plane_state->is_y_plane)
2269 if (plane_state->planar_linked_plane) {
2270 const struct drm_framebuffer *fb = plane_state->hw.fb;
2272 drm_WARN_ON(&i915->drm,
2274 drm_WARN_ON(&i915->drm, !fb->format->is_yuv ||
2275 fb->format->num_planes == 1);
2278 plane_state->planar_linked_plane, 0);
2301 to_intel_atomic_state(crtc_state->uapi.state);
2306 drm_WARN_ON(display->drm, PTR_ERR(cdclk_state));
2310 return min(1, DIV_ROUND_UP(crtc_state->pixel_rate,
2311 2 * cdclk_state->logical.cdclk));
2317 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
2319 &crtc_state->scaler_state;
2320 int linetime = DIV_ROUND_UP(1000 * crtc_state->hw.adjusted_mode.htotal,
2321 crtc_state->hw.adjusted_mode.clock);
2322 int num_scaler_users = hweight32(scaler_state->scaler_users);
2324 crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420 ? 2 : 1;
2327 if (!crtc_state->dsc.compression_enable ||
2329 num_scaler_users > crtc->num_scalers)
2337 hscale_k = max(1000, mul_u32_u32(scaler_state->scalers[i].hscale, 1000) >> 16);
2338 vscale_k = max(1000, mul_u32_u32(scaler_state->scalers[i].vscale, 1000) >> 16);
2345 return intel_usecs_to_scanlines(&crtc_state->hw.adjusted_mode, dsc_prefill_latency);
2352 &crtc_state->scaler_state;
2353 int num_scaler_users = hweight32(scaler_state->scaler_users);
2355 int linetime = DIV_ROUND_UP(1000 * crtc_state->hw.adjusted_mode.htotal,
2356 crtc_state->hw.adjusted_mode.clock);
2364 u64 hscale_k = max(1000, mul_u32_u32(scaler_state->scalers[0].hscale, 1000) >> 16);
2365 u64 vscale_k = max(1000, mul_u32_u32(scaler_state->scalers[0].vscale, 1000) >> 16);
2367 crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420 ? 2 : 1;
2377 return intel_usecs_to_scanlines(&crtc_state->hw.adjusted_mode, scaler_prefill_latency);
2385 &crtc_state->hw.adjusted_mode;
2387 return crtc_state->framestart_delay +
2392 adjusted_mode->crtc_vtotal - adjusted_mode->crtc_vblank_start;
2397 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
2402 const struct skl_plane_wm *wm = &crtc_state->wm.skl.optimal.planes[plane_id];
2405 wm0_lines = max_t(int, wm0_lines, wm->wm[0].lines);
2414 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
2415 struct drm_i915_private *i915 = to_i915(crtc->base.dev);
2418 for (level = i915->display.wm.num_levels - 1; level >= 0; level--) {
2434 return -EINVAL;
2439 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
2440 struct drm_i915_private *i915 = to_i915(crtc->base.dev);
2443 if (!crtc_state->hw.active)
2456 crtc_state->wm_level_disabled = level < i915->display.wm.num_levels - 1;
2458 for (level++; level < i915->display.wm.num_levels; level++) {
2463 &crtc_state->wm.skl.optimal.planes[plane_id];
2469 wm->wm[level].enable = false;
2470 wm->uv_wm[level].enable = false;
2475 i915->display.sagv.block_time_us &&
2477 i915->display.sagv.block_time_us)) {
2482 &crtc_state->wm.skl.optimal.planes[plane_id];
2484 wm->sagv.wm0.enable = false;
2485 wm->sagv.trans_wm.enable = false;
2495 struct drm_i915_private *i915 = to_i915(crtc->base.dev);
2504 * FIXME should perhaps check {old,new}_plane_crtc->hw.crtc
2508 if (plane->pipe != crtc->pipe)
2519 crtc_state->wm.skl.optimal = crtc_state->wm.skl.raw;
2527 return l1->enable == l2->enable &&
2528 l1->ignore_lines == l2->ignore_lines &&
2529 l1->lines == l2->lines &&
2530 l1->blocks == l2->blocks &&
2531 l1->auto_min_alloc_wm_enable == l2->auto_min_alloc_wm_enable;
2538 struct intel_display *display = &i915->display;
2541 for (level = 0; level < display->wm.num_levels; level++) {
2547 if (!skl_wm_level_equals(&wm1->wm[level], &wm2->wm[level]))
2551 return skl_wm_level_equals(&wm1->trans_wm, &wm2->trans_wm) &&
2552 skl_wm_level_equals(&wm1->sagv.wm0, &wm2->sagv.wm0) &&
2553 skl_wm_level_equals(&wm1->sagv.trans_wm, &wm2->sagv.trans_wm);
2559 return a->start < b->end && b->start < a->end;
2565 if (a->end && b->end) {
2566 a->start = min(a->start, b->start);
2567 a->end = max(a->end, b->end);
2568 } else if (b->end) {
2569 a->start = b->start;
2570 a->end = b->end;
2593 struct drm_i915_private *i915 = to_i915(state->base.dev);
2600 for_each_intel_plane_on_crtc(&i915->drm, crtc, plane) {
2602 enum plane_id plane_id = plane->id;
2604 if (skl_ddb_entry_equal(&old_crtc_state->wm.skl.plane_ddb[plane_id],
2605 &new_crtc_state->wm.skl.plane_ddb[plane_id]) &&
2606 skl_ddb_entry_equal(&old_crtc_state->wm.skl.plane_ddb_y[plane_id],
2607 &new_crtc_state->wm.skl.plane_ddb_y[plane_id]))
2610 if (new_crtc_state->do_async_flip) {
2611 drm_dbg_kms(&i915->drm, "[PLANE:%d:%s] Can't change DDB during async flip\n",
2612 plane->base.base.id, plane->base.name);
2613 return -EINVAL;
2620 new_crtc_state->update_planes |= BIT(plane_id);
2621 new_crtc_state->async_flip_planes = 0;
2622 new_crtc_state->do_async_flip = false;
2630 struct drm_i915_private *i915 = to_i915(dbuf_state->base.state->base.dev);
2641 enabled_slices |= dbuf_state->slices[pipe];
2650 struct drm_i915_private *i915 = to_i915(state->base.dev);
2669 new_dbuf_state->active_pipes =
2670 intel_calc_active_pipes(state, old_dbuf_state->active_pipes);
2672 if (old_dbuf_state->active_pipes != new_dbuf_state->active_pipes) {
2673 ret = intel_atomic_lock_global_state(&new_dbuf_state->base);
2679 new_dbuf_state->joined_mbus =
2680 adlp_check_mbus_joined(new_dbuf_state->active_pipes);
2682 if (old_dbuf_state->joined_mbus != new_dbuf_state->joined_mbus) {
2683 ret = intel_cdclk_state_set_joined_mbus(state, new_dbuf_state->joined_mbus);
2689 for_each_intel_crtc(&i915->drm, crtc) {
2690 enum pipe pipe = crtc->pipe;
2692 new_dbuf_state->slices[pipe] =
2693 skl_compute_dbuf_slices(crtc, new_dbuf_state->active_pipes,
2694 new_dbuf_state->joined_mbus);
2696 if (old_dbuf_state->slices[pipe] == new_dbuf_state->slices[pipe])
2699 ret = intel_atomic_lock_global_state(&new_dbuf_state->base);
2704 new_dbuf_state->enabled_slices = intel_dbuf_enabled_slices(new_dbuf_state);
2706 if (old_dbuf_state->enabled_slices != new_dbuf_state->enabled_slices ||
2707 old_dbuf_state->joined_mbus != new_dbuf_state->joined_mbus) {
2708 ret = intel_atomic_serialize_global_state(&new_dbuf_state->base);
2712 drm_dbg_kms(&i915->drm,
2713 "Enabled dbuf slices 0x%x -> 0x%x (total dbuf slices 0x%x), mbus joined? %s->%s\n",
2714 old_dbuf_state->enabled_slices,
2715 new_dbuf_state->enabled_slices,
2716 DISPLAY_INFO(i915)->dbuf.slice_mask,
2717 str_yes_no(old_dbuf_state->joined_mbus),
2718 str_yes_no(new_dbuf_state->joined_mbus));
2722 enum pipe pipe = crtc->pipe;
2724 new_dbuf_state->weight[pipe] = intel_crtc_ddb_weight(new_crtc_state);
2726 if (old_dbuf_state->weight[pipe] == new_dbuf_state->weight[pipe])
2729 ret = intel_atomic_lock_global_state(&new_dbuf_state->base);
2734 for_each_intel_crtc(&i915->drm, crtc) {
2761 struct drm_i915_private *i915 = to_i915(state->base.dev);
2775 old_pipe_wm = &old_crtc_state->wm.skl.optimal;
2776 new_pipe_wm = &new_crtc_state->wm.skl.optimal;
2778 for_each_intel_plane_on_crtc(&i915->drm, crtc, plane) {
2779 enum plane_id plane_id = plane->id;
2782 old = &old_crtc_state->wm.skl.plane_ddb[plane_id];
2783 new = &new_crtc_state->wm.skl.plane_ddb[plane_id];
2788 drm_dbg_kms(&i915->drm,
2789 "[PLANE:%d:%s] ddb (%4d - %4d) -> (%4d - %4d), size %4d -> %4d\n",
2790 plane->base.base.id, plane->base.name,
2791 old->start, old->end, new->start, new->end,
2795 for_each_intel_plane_on_crtc(&i915->drm, crtc, plane) {
2796 enum plane_id plane_id = plane->id;
2799 old_wm = &old_pipe_wm->planes[plane_id];
2800 new_wm = &new_pipe_wm->planes[plane_id];
2805 drm_dbg_kms(&i915->drm,
2807 " -> %cwm0,%cwm1,%cwm2,%cwm3,%cwm4,%cwm5,%cwm6,%cwm7,%ctwm,%cswm,%cstwm\n",
2808 plane->base.base.id, plane->base.name,
2809 enast(old_wm->wm[0].enable), enast(old_wm->wm[1].enable),
2810 enast(old_wm->wm[2].enable), enast(old_wm->wm[3].enable),
2811 enast(old_wm->wm[4].enable), enast(old_wm->wm[5].enable),
2812 enast(old_wm->wm[6].enable), enast(old_wm->wm[7].enable),
2813 enast(old_wm->trans_wm.enable),
2814 enast(old_wm->sagv.wm0.enable),
2815 enast(old_wm->sagv.trans_wm.enable),
2816 enast(new_wm->wm[0].enable), enast(new_wm->wm[1].enable),
2817 enast(new_wm->wm[2].enable), enast(new_wm->wm[3].enable),
2818 enast(new_wm->wm[4].enable), enast(new_wm->wm[5].enable),
2819 enast(new_wm->wm[6].enable), enast(new_wm->wm[7].enable),
2820 enast(new_wm->trans_wm.enable),
2821 enast(new_wm->sagv.wm0.enable),
2822 enast(new_wm->sagv.trans_wm.enable));
2824 drm_dbg_kms(&i915->drm,
2826 " -> %c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%4d\n",
2827 plane->base.base.id, plane->base.name,
2828 enast(old_wm->wm[0].ignore_lines), old_wm->wm[0].lines,
2829 enast(old_wm->wm[1].ignore_lines), old_wm->wm[1].lines,
2830 enast(old_wm->wm[2].ignore_lines), old_wm->wm[2].lines,
2831 enast(old_wm->wm[3].ignore_lines), old_wm->wm[3].lines,
2832 enast(old_wm->wm[4].ignore_lines), old_wm->wm[4].lines,
2833 enast(old_wm->wm[5].ignore_lines), old_wm->wm[5].lines,
2834 enast(old_wm->wm[6].ignore_lines), old_wm->wm[6].lines,
2835 enast(old_wm->wm[7].ignore_lines), old_wm->wm[7].lines,
2836 enast(old_wm->trans_wm.ignore_lines), old_wm->trans_wm.lines,
2837 enast(old_wm->sagv.wm0.ignore_lines), old_wm->sagv.wm0.lines,
2838 enast(old_wm->sagv.trans_wm.ignore_lines), old_wm->sagv.trans_wm.lines,
2839 enast(new_wm->wm[0].ignore_lines), new_wm->wm[0].lines,
2840 enast(new_wm->wm[1].ignore_lines), new_wm->wm[1].lines,
2841 enast(new_wm->wm[2].ignore_lines), new_wm->wm[2].lines,
2842 enast(new_wm->wm[3].ignore_lines), new_wm->wm[3].lines,
2843 enast(new_wm->wm[4].ignore_lines), new_wm->wm[4].lines,
2844 enast(new_wm->wm[5].ignore_lines), new_wm->wm[5].lines,
2845 enast(new_wm->wm[6].ignore_lines), new_wm->wm[6].lines,
2846 enast(new_wm->wm[7].ignore_lines), new_wm->wm[7].lines,
2847 enast(new_wm->trans_wm.ignore_lines), new_wm->trans_wm.lines,
2848 enast(new_wm->sagv.wm0.ignore_lines), new_wm->sagv.wm0.lines,
2849 enast(new_wm->sagv.trans_wm.ignore_lines), new_wm->sagv.trans_wm.lines);
2851 drm_dbg_kms(&i915->drm,
2853 " -> %4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%5d\n",
2854 plane->base.base.id, plane->base.name,
2855 old_wm->wm[0].blocks, old_wm->wm[1].blocks,
2856 old_wm->wm[2].blocks, old_wm->wm[3].blocks,
2857 old_wm->wm[4].blocks, old_wm->wm[5].blocks,
2858 old_wm->wm[6].blocks, old_wm->wm[7].blocks,
2859 old_wm->trans_wm.blocks,
2860 old_wm->sagv.wm0.blocks,
2861 old_wm->sagv.trans_wm.blocks,
2862 new_wm->wm[0].blocks, new_wm->wm[1].blocks,
2863 new_wm->wm[2].blocks, new_wm->wm[3].blocks,
2864 new_wm->wm[4].blocks, new_wm->wm[5].blocks,
2865 new_wm->wm[6].blocks, new_wm->wm[7].blocks,
2866 new_wm->trans_wm.blocks,
2867 new_wm->sagv.wm0.blocks,
2868 new_wm->sagv.trans_wm.blocks);
2870 drm_dbg_kms(&i915->drm,
2872 " -> %4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%5d\n",
2873 plane->base.base.id, plane->base.name,
2874 old_wm->wm[0].min_ddb_alloc, old_wm->wm[1].min_ddb_alloc,
2875 old_wm->wm[2].min_ddb_alloc, old_wm->wm[3].min_ddb_alloc,
2876 old_wm->wm[4].min_ddb_alloc, old_wm->wm[5].min_ddb_alloc,
2877 old_wm->wm[6].min_ddb_alloc, old_wm->wm[7].min_ddb_alloc,
2878 old_wm->trans_wm.min_ddb_alloc,
2879 old_wm->sagv.wm0.min_ddb_alloc,
2880 old_wm->sagv.trans_wm.min_ddb_alloc,
2881 new_wm->wm[0].min_ddb_alloc, new_wm->wm[1].min_ddb_alloc,
2882 new_wm->wm[2].min_ddb_alloc, new_wm->wm[3].min_ddb_alloc,
2883 new_wm->wm[4].min_ddb_alloc, new_wm->wm[5].min_ddb_alloc,
2884 new_wm->wm[6].min_ddb_alloc, new_wm->wm[7].min_ddb_alloc,
2885 new_wm->trans_wm.min_ddb_alloc,
2886 new_wm->sagv.wm0.min_ddb_alloc,
2887 new_wm->sagv.trans_wm.min_ddb_alloc);
2899 for (level = 0; level < display->wm.num_levels; level++) {
2905 if (!skl_wm_level_equals(skl_plane_wm_level(old_pipe_wm, plane->id, level),
2906 skl_plane_wm_level(new_pipe_wm, plane->id, level)))
2911 const struct skl_plane_wm *old_wm = &old_pipe_wm->planes[plane->id];
2912 const struct skl_plane_wm *new_wm = &new_pipe_wm->planes[plane->id];
2914 if (!skl_wm_level_equals(&old_wm->sagv.wm0, &new_wm->sagv.wm0) ||
2915 !skl_wm_level_equals(&old_wm->sagv.trans_wm, &new_wm->sagv.trans_wm))
2919 return skl_wm_level_equals(skl_plane_trans_wm(old_pipe_wm, plane->id),
2920 skl_plane_trans_wm(new_pipe_wm, plane->id));
2948 struct drm_i915_private *i915 = to_i915(crtc->base.dev);
2955 for_each_intel_plane_on_crtc(&i915->drm, crtc, plane) {
2957 enum plane_id plane_id = plane->id;
2962 * is non-zero, whereas we want all disabled planes to
2969 &old_crtc_state->wm.skl.optimal,
2970 &new_crtc_state->wm.skl.optimal))
2973 if (new_crtc_state->do_async_flip) {
2974 drm_dbg_kms(&i915->drm, "[PLANE:%d:%s] Can't change watermarks during async flip\n",
2975 plane->base.base.id, plane->base.name);
2976 return -EINVAL;
2983 new_crtc_state->update_planes |= BIT(plane_id);
2984 new_crtc_state->async_flip_planes = 0;
2985 new_crtc_state->do_async_flip = false;
3005 struct drm_i915_private *i915 = to_i915(display->drm);
3019 if (!new_crtc_state->vrr.enable ||
3020 (new_crtc_state->vrr.vmin == new_crtc_state->vrr.vmax &&
3021 new_crtc_state->vrr.vmin == new_crtc_state->vrr.flipline))
3024 max_linetime = max(new_crtc_state->linetime, max_linetime);
3029 display->sagv.block_time_us;
3095 level->enable = val & PLANE_WM_EN;
3096 level->ignore_lines = val & PLANE_WM_IGNORE_LINES;
3097 level->blocks = REG_FIELD_GET(PLANE_WM_BLOCKS_MASK, val);
3098 level->lines = REG_FIELD_GET(PLANE_WM_LINES_MASK, val);
3099 level->auto_min_alloc_wm_enable = DISPLAY_VER(display) >= 30 ?
3107 enum pipe pipe = crtc->pipe;
3113 struct skl_plane_wm *wm = &out->planes[plane_id];
3115 for (level = 0; level < display->wm.num_levels; level++) {
3121 skl_wm_level_from_reg_val(display, val, &wm->wm[level]);
3129 skl_wm_level_from_reg_val(display, val, &wm->trans_wm);
3137 skl_wm_level_from_reg_val(display, val, &wm->sagv.wm0);
3144 skl_wm_level_from_reg_val(display, val, &wm->sagv.trans_wm);
3146 wm->sagv.wm0 = wm->wm[0];
3147 wm->sagv.trans_wm = wm->trans_wm;
3154 struct intel_display *display = &i915->display;
3156 to_intel_dbuf_state(i915->display.dbuf.obj.state);
3160 dbuf_state->joined_mbus = intel_de_read(display, MBUS_CTL) & MBUS_JOIN;
3162 dbuf_state->mdclk_cdclk_ratio = intel_mdclk_cdclk_ratio(display, &display->cdclk.hw);
3163 dbuf_state->active_pipes = 0;
3165 for_each_intel_crtc(display->drm, crtc) {
3167 to_intel_crtc_state(crtc->base.state);
3168 enum pipe pipe = crtc->pipe;
3173 memset(&crtc_state->wm.skl.optimal, 0,
3174 sizeof(crtc_state->wm.skl.optimal));
3175 if (crtc_state->hw.active) {
3176 skl_pipe_wm_get_hw_state(crtc, &crtc_state->wm.skl.optimal);
3177 dbuf_state->active_pipes |= BIT(pipe);
3179 crtc_state->wm.skl.raw = crtc_state->wm.skl.optimal;
3181 memset(&dbuf_state->ddb[pipe], 0, sizeof(dbuf_state->ddb[pipe]));
3185 &crtc_state->wm.skl.plane_ddb[plane_id];
3187 &crtc_state->wm.skl.plane_ddb_y[plane_id];
3189 &crtc_state->wm.skl.plane_min_ddb[plane_id];
3191 &crtc_state->wm.skl.plane_interim_ddb[plane_id];
3193 if (!crtc_state->hw.active)
3196 skl_ddb_get_hw_plane_state(i915, crtc->pipe,
3200 skl_ddb_entry_union(&dbuf_state->ddb[pipe], ddb);
3201 skl_ddb_entry_union(&dbuf_state->ddb[pipe], ddb_y);
3204 dbuf_state->weight[pipe] = intel_crtc_ddb_weight(crtc_state);
3210 slices = skl_compute_dbuf_slices(crtc, dbuf_state->active_pipes,
3211 dbuf_state->joined_mbus);
3213 crtc_state->wm.skl.ddb.start = mbus_offset + dbuf_state->ddb[pipe].start;
3214 crtc_state->wm.skl.ddb.end = mbus_offset + dbuf_state->ddb[pipe].end;
3217 dbuf_state->slices[pipe] =
3218 skl_ddb_dbuf_slice_mask(i915, &crtc_state->wm.skl.ddb);
3220 drm_dbg_kms(display->drm,
3221 "[CRTC:%d:%s] dbuf slices 0x%x, ddb (%d - %d), active pipes 0x%x, mbus joined: %s\n",
3222 crtc->base.base.id, crtc->base.name,
3223 dbuf_state->slices[pipe], dbuf_state->ddb[pipe].start,
3224 dbuf_state->ddb[pipe].end, dbuf_state->active_pipes,
3225 str_yes_no(dbuf_state->joined_mbus));
3228 dbuf_state->enabled_slices = display->dbuf.enabled_slices;
3233 return i915->display.wm.ipc_enabled;
3255 return i915->dram_info.symmetric_memory;
3265 i915->display.wm.ipc_enabled = skl_watermark_ipc_can_enable(i915);
3274 bool wm_lv_0_adjust_needed = i915->dram_info.wm_lv_0_adjust_needed;
3305 * WA Level-0 adjustment for 16GB DIMMs: SKL+
3316 int num_levels = i915->display.wm.num_levels;
3336 int num_levels = i915->display.wm.num_levels;
3344 ret = snb_pcode_read(&i915->uncore, GEN9_PCODE_READ_MEM_LATENCY, &val, NULL);
3346 drm_err(&i915->drm, "SKL Mailbox read error = %d\n", ret);
3357 ret = snb_pcode_read(&i915->uncore, GEN9_PCODE_READ_MEM_LATENCY, &val, NULL);
3359 drm_err(&i915->drm, "SKL Mailbox read error = %d\n", ret);
3373 struct intel_display *display = &i915->display;
3376 display->wm.num_levels = 6;
3378 display->wm.num_levels = 8;
3381 mtl_read_wm_latency(i915, display->wm.skl_latency);
3383 skl_read_wm_latency(i915, display->wm.skl_latency);
3385 intel_print_wm_latency(i915, "Gen9 Plane", display->wm.skl_latency);
3392 dbuf_state = kmemdup(obj->state, sizeof(*dbuf_state), GFP_KERNEL);
3396 return &dbuf_state->base;
3413 struct drm_i915_private *i915 = to_i915(state->base.dev);
3416 dbuf_state = intel_atomic_get_global_obj_state(state, &i915->display.dbuf.obj);
3425 struct intel_display *display = &i915->display;
3430 return -ENOMEM;
3432 intel_atomic_global_obj_init(display, &display->dbuf.obj,
3433 &dbuf_state->base, &intel_dbuf_funcs);
3460 struct drm_i915_private *i915 = to_i915(crtc->base.dev);
3473 val |= dbuf_state->joined_mbus ?
3476 /* Wa_22010947358:adl-p */
3477 val |= dbuf_state->joined_mbus ?
3496 if (xelpdp_is_only_pipe_per_dbuf_bank(crtc->pipe, dbuf_state->active_pipes))
3510 for_each_intel_crtc_in_pipe_mask(&i915->drm, crtc, dbuf_state->active_pipes)
3511 intel_de_write(i915, PIPE_MBUS_DBOX_CTL(crtc->pipe),
3517 struct drm_i915_private *i915 = to_i915(state->base.dev);
3526 (new_dbuf_state->joined_mbus == old_dbuf_state->joined_mbus &&
3527 new_dbuf_state->active_pipes == old_dbuf_state->active_pipes))
3542 dbuf_state->mdclk_cdclk_ratio = ratio;
3544 return intel_atomic_lock_global_state(&dbuf_state->base);
3550 struct intel_display *display = &i915->display;
3558 MBUS_TRANSLATION_THROTTLE_MIN(ratio - 1));
3563 drm_dbg_kms(display->drm, "Updating dbuf ratio to %d (mbus joined: %s)\n",
3569 DBUF_MIN_TRACKER_STATE_SERVICE(ratio - 1));
3574 struct drm_i915_private *i915 = to_i915(state->base.dev);
3583 mdclk_cdclk_ratio = old_dbuf_state->mdclk_cdclk_ratio;
3586 mdclk_cdclk_ratio = new_dbuf_state->mdclk_cdclk_ratio;
3590 new_dbuf_state->joined_mbus);
3597 struct drm_i915_private *i915 = to_i915(state->base.dev);
3598 enum pipe pipe = ffs(dbuf_state->active_pipes) - 1;
3602 drm_WARN_ON(&i915->drm, !dbuf_state->joined_mbus);
3603 drm_WARN_ON(&i915->drm, !is_power_of_2(dbuf_state->active_pipes));
3620 if (dbuf_state->joined_mbus)
3638 struct drm_i915_private *i915 = to_i915(state->base.dev);
3644 drm_dbg_kms(&i915->drm, "Changing mbus joined: %s -> %s (pipe: %c)\n",
3645 str_yes_no(old_dbuf_state->joined_mbus),
3646 str_yes_no(new_dbuf_state->joined_mbus),
3662 if (!old_dbuf_state->joined_mbus && new_dbuf_state->joined_mbus) {
3665 WARN_ON(!new_dbuf_state->base.changed);
3684 if (old_dbuf_state->joined_mbus && !new_dbuf_state->joined_mbus) {
3687 WARN_ON(!new_dbuf_state->base.changed);
3698 } else if (old_dbuf_state->joined_mbus == new_dbuf_state->joined_mbus &&
3699 old_dbuf_state->active_pipes != new_dbuf_state->active_pipes) {
3700 WARN_ON(!new_dbuf_state->base.changed);
3720 old_slices = old_dbuf_state->enabled_slices;
3721 new_slices = old_dbuf_state->enabled_slices | new_dbuf_state->enabled_slices;
3726 WARN_ON(!new_dbuf_state->base.changed);
3743 old_slices = old_dbuf_state->enabled_slices | new_dbuf_state->enabled_slices;
3744 new_slices = new_dbuf_state->enabled_slices;
3749 WARN_ON(!new_dbuf_state->base.changed);
3756 struct intel_display *display = &i915->display;
3758 to_intel_dbuf_state(display->dbuf.obj.state);
3763 if (!dbuf_state->joined_mbus ||
3764 adlp_check_mbus_joined(dbuf_state->active_pipes))
3767 drm_dbg_kms(display->drm, "Disabling redundant MBUS joining (active pipes 0x%x)\n",
3768 dbuf_state->active_pipes);
3770 dbuf_state->joined_mbus = false;
3772 dbuf_state->mdclk_cdclk_ratio,
3773 dbuf_state->joined_mbus);
3781 to_intel_dbuf_state(i915->display.dbuf.obj.state);
3785 for_each_intel_crtc(&i915->drm, crtc) {
3787 to_intel_crtc_state(crtc->base.state);
3789 entries[crtc->pipe] = crtc_state->wm.skl.ddb;
3792 for_each_intel_crtc(&i915->drm, crtc) {
3794 to_intel_crtc_state(crtc->base.state);
3797 slices = skl_compute_dbuf_slices(crtc, dbuf_state->active_pipes,
3798 dbuf_state->joined_mbus);
3799 if (dbuf_state->slices[crtc->pipe] & ~slices)
3802 if (skl_ddb_allocation_overlaps(&crtc_state->wm.skl.ddb, entries,
3803 I915_MAX_PIPES, crtc->pipe))
3828 drm_dbg_kms(&i915->drm, "BIOS has misprogrammed the DBUF, disabling all planes\n");
3830 for_each_intel_crtc(&i915->drm, crtc) {
3831 struct intel_plane *plane = to_intel_plane(crtc->base.primary);
3833 to_intel_plane_state(plane->base.state);
3835 to_intel_crtc_state(crtc->base.state);
3837 if (plane_state->uapi.visible)
3840 drm_WARN_ON(&i915->drm, crtc_state->active_planes != 0);
3842 memset(&crtc_state->wm.skl.ddb, 0, sizeof(crtc_state->wm.skl.ddb));
3856 to_intel_crtc_state(crtc->base.state);
3858 to_intel_dbuf_state(display->dbuf.obj.state);
3859 enum pipe pipe = crtc->pipe;
3864 dbuf_state->active_pipes &= ~BIT(pipe);
3866 dbuf_state->weight[pipe] = 0;
3867 dbuf_state->slices[pipe] = 0;
3869 memset(&dbuf_state->ddb[pipe], 0, sizeof(dbuf_state->ddb[pipe]));
3871 memset(&crtc_state->wm.skl.ddb, 0, sizeof(crtc_state->wm.skl.ddb));
3879 to_intel_crtc_state(crtc->base.state);
3884 skl_ddb_entry_init(&crtc_state->wm.skl.plane_ddb[plane->id], 0, 0);
3885 skl_ddb_entry_init(&crtc_state->wm.skl.plane_ddb[plane->id], 0, 0);
3887 crtc_state->wm.skl.plane_min_ddb[plane->id] = 0;
3888 crtc_state->wm.skl.plane_interim_ddb[plane->id] = 0;
3890 memset(&crtc_state->wm.skl.raw.planes[plane->id], 0,
3891 sizeof(crtc_state->wm.skl.raw.planes[plane->id]));
3892 memset(&crtc_state->wm.skl.optimal.planes[plane->id], 0,
3893 sizeof(crtc_state->wm.skl.optimal.planes[plane->id]));
3900 struct drm_i915_private *i915 = to_i915(state->base.dev);
3910 const struct skl_pipe_wm *sw_wm = &new_crtc_state->wm.skl.optimal;
3915 if (DISPLAY_VER(i915) < 9 || !new_crtc_state->hw.active)
3922 skl_pipe_wm_get_hw_state(crtc, &hw->wm);
3924 skl_pipe_ddb_get_hw_state(crtc, hw->ddb, hw->ddb_y, hw->min_ddb, hw->interim_ddb);
3929 hw_enabled_slices != i915->display.dbuf.enabled_slices)
3930 drm_err(&i915->drm,
3932 i915->display.dbuf.enabled_slices,
3935 for_each_intel_plane_on_crtc(&i915->drm, crtc, plane) {
3940 for (level = 0; level < i915->display.wm.num_levels; level++) {
3941 hw_wm_level = &hw->wm.planes[plane->id].wm[level];
3942 sw_wm_level = skl_plane_wm_level(sw_wm, plane->id, level);
3947 drm_err(&i915->drm,
3949 plane->base.base.id, plane->base.name, level,
3950 sw_wm_level->enable,
3951 sw_wm_level->blocks,
3952 sw_wm_level->lines,
3953 hw_wm_level->enable,
3954 hw_wm_level->blocks,
3955 hw_wm_level->lines);
3958 hw_wm_level = &hw->wm.planes[plane->id].trans_wm;
3959 sw_wm_level = skl_plane_trans_wm(sw_wm, plane->id);
3962 drm_err(&i915->drm,
3964 plane->base.base.id, plane->base.name,
3965 sw_wm_level->enable,
3966 sw_wm_level->blocks,
3967 sw_wm_level->lines,
3968 hw_wm_level->enable,
3969 hw_wm_level->blocks,
3970 hw_wm_level->lines);
3973 hw_wm_level = &hw->wm.planes[plane->id].sagv.wm0;
3974 sw_wm_level = &sw_wm->planes[plane->id].sagv.wm0;
3978 drm_err(&i915->drm,
3980 plane->base.base.id, plane->base.name,
3981 sw_wm_level->enable,
3982 sw_wm_level->blocks,
3983 sw_wm_level->lines,
3984 hw_wm_level->enable,
3985 hw_wm_level->blocks,
3986 hw_wm_level->lines);
3989 hw_wm_level = &hw->wm.planes[plane->id].sagv.trans_wm;
3990 sw_wm_level = &sw_wm->planes[plane->id].sagv.trans_wm;
3994 drm_err(&i915->drm,
3996 plane->base.base.id, plane->base.name,
3997 sw_wm_level->enable,
3998 sw_wm_level->blocks,
3999 sw_wm_level->lines,
4000 hw_wm_level->enable,
4001 hw_wm_level->blocks,
4002 hw_wm_level->lines);
4006 hw_ddb_entry = &hw->ddb[PLANE_CURSOR];
4007 sw_ddb_entry = &new_crtc_state->wm.skl.plane_ddb[PLANE_CURSOR];
4010 drm_err(&i915->drm,
4012 plane->base.base.id, plane->base.name,
4013 sw_ddb_entry->start, sw_ddb_entry->end,
4014 hw_ddb_entry->start, hw_ddb_entry->end);
4033 i915->display.funcs.wm = &skl_wm_funcs;
4038 struct drm_i915_private *i915 = m->private;
4047 struct drm_i915_private *i915 = inode->i_private;
4056 struct seq_file *m = file->private_data;
4057 struct drm_i915_private *i915 = m->private;
4066 with_intel_runtime_pm(&i915->runtime_pm, wakeref) {
4068 drm_info(&i915->drm,
4070 i915->display.wm.ipc_enabled = enable;
4088 struct drm_i915_private *i915 = m->private;
4098 str_enabled_disabled(i915->display.params.enable_sagv));
4099 seq_printf(m, "SAGV status: %s\n", sagv_status[i915->display.sagv.status]);
4100 seq_printf(m, "SAGV block time: %d usec\n", i915->display.sagv.block_time_us);
4109 struct intel_display *display = &i915->display;
4110 struct drm_minor *minor = display->drm->primary;
4113 debugfs_create_file("i915_ipc_status", 0644, minor->debugfs_root, i915,
4117 debugfs_create_file("i915_sagv_status", 0444, minor->debugfs_root, i915,
4125 for (level = i915->display.wm.num_levels - 1; level >= initial_wm_level; level--) {