[PATCH v3] drm/i915/display: update handling of FBC when VT-d active workaround
Move the handling of the disabling FBC when VT-d is active wa as part of the intel_fbc_check_plane(). As the hw is still there, intel_fbc_sanitize should be able to handle the state properly. v2: update the patch description (Jani Nikula) v3: fix the return value in wa handling (Jani Nikula) Bspec: 21664 Suggested-by: Ville Syrjälä Signed-off-by: Vinod Govindapillai --- drivers/gpu/drm/i915/display/intel_fbc.c | 22 ++ 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c index e9189a864f69..b546ebc6823d 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.c +++ b/drivers/gpu/drm/i915/display/intel_fbc.c @@ -1235,6 +1235,12 @@ static int intel_fbc_check_plane(struct intel_atomic_state *state, return 0; } + /* WaFbcTurnOffFbcWhenHyperVisorIsUsed:skl,bxt */ + if (i915_vtd_active(i915) && (IS_SKYLAKE(i915) || IS_BROXTON(i915))) { + plane_state->no_fbc_reason = "VT-d enabled"; + return 0; + } + crtc_state = intel_atomic_get_new_crtc_state(state, crtc); if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE) { @@ -1820,19 +1826,6 @@ static int intel_sanitize_fbc_option(struct drm_i915_private *i915) return 0; } -static bool need_fbc_vtd_wa(struct drm_i915_private *i915) -{ - /* WaFbcTurnOffFbcWhenHyperVisorIsUsed:skl,bxt */ - if (i915_vtd_active(i915) && - (IS_SKYLAKE(i915) || IS_BROXTON(i915))) { - drm_info(>drm, -"Disabling framebuffer compression (FBC) to prevent screen flicker with VT-d enabled\n"); - return true; - } - - return false; -} - void intel_fbc_add_plane(struct intel_fbc *fbc, struct intel_plane *plane) { plane->fbc = fbc; @@ -1878,9 +1871,6 @@ void intel_fbc_init(struct drm_i915_private *i915) { enum intel_fbc_id fbc_id; - if (need_fbc_vtd_wa(i915)) - DISPLAY_RUNTIME_INFO(i915)->fbc_mask = 0; - i915->display.params.enable_fbc = intel_sanitize_fbc_option(i915); drm_dbg_kms(>drm, "Sanitized enable_fbc value: %d\n", i915->display.params.enable_fbc); -- 2.34.1
[PATCH v2] drm/i915/display: update handling of FBC when VT-d active workaround
Move the handling of the disabling FBC when VT-d is active wa as part of the intel_fbc_check_plane(). As the hw is still there, intel_fbc_sanitize should be able to handle the state properly. v2: update the patch description (Jani Nikula) Bspec: 21664 Suggested-by: Ville Syrjälä Signed-off-by: Vinod Govindapillai --- drivers/gpu/drm/i915/display/intel_fbc.c | 22 ++ 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c index e9189a864f69..492dc26ecfa2 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.c +++ b/drivers/gpu/drm/i915/display/intel_fbc.c @@ -1235,6 +1235,12 @@ static int intel_fbc_check_plane(struct intel_atomic_state *state, return 0; } + /* WaFbcTurnOffFbcWhenHyperVisorIsUsed:skl,bxt */ + if (i915_vtd_active(i915) && (IS_SKYLAKE(i915) || IS_BROXTON(i915))) { + plane_state->no_fbc_reason = "VT-d enabled"; + return true; + } + crtc_state = intel_atomic_get_new_crtc_state(state, crtc); if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE) { @@ -1820,19 +1826,6 @@ static int intel_sanitize_fbc_option(struct drm_i915_private *i915) return 0; } -static bool need_fbc_vtd_wa(struct drm_i915_private *i915) -{ - /* WaFbcTurnOffFbcWhenHyperVisorIsUsed:skl,bxt */ - if (i915_vtd_active(i915) && - (IS_SKYLAKE(i915) || IS_BROXTON(i915))) { - drm_info(>drm, -"Disabling framebuffer compression (FBC) to prevent screen flicker with VT-d enabled\n"); - return true; - } - - return false; -} - void intel_fbc_add_plane(struct intel_fbc *fbc, struct intel_plane *plane) { plane->fbc = fbc; @@ -1878,9 +1871,6 @@ void intel_fbc_init(struct drm_i915_private *i915) { enum intel_fbc_id fbc_id; - if (need_fbc_vtd_wa(i915)) - DISPLAY_RUNTIME_INFO(i915)->fbc_mask = 0; - i915->display.params.enable_fbc = intel_sanitize_fbc_option(i915); drm_dbg_kms(>drm, "Sanitized enable_fbc value: %d\n", i915->display.params.enable_fbc); -- 2.34.1
[PATCH] drm/i915/display: update handling of FBC when VT-d active workaround
Move the handling of the disabling FBC when VT-d is active wa as part of the intel_fbc_check_plane() Bspec: 21664 Signed-off-by: Vinod Govindapillai --- drivers/gpu/drm/i915/display/intel_fbc.c | 22 ++ 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c index e9189a864f69..492dc26ecfa2 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.c +++ b/drivers/gpu/drm/i915/display/intel_fbc.c @@ -1235,6 +1235,12 @@ static int intel_fbc_check_plane(struct intel_atomic_state *state, return 0; } + /* WaFbcTurnOffFbcWhenHyperVisorIsUsed:skl,bxt */ + if (i915_vtd_active(i915) && (IS_SKYLAKE(i915) || IS_BROXTON(i915))) { + plane_state->no_fbc_reason = "VT-d enabled"; + return true; + } + crtc_state = intel_atomic_get_new_crtc_state(state, crtc); if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE) { @@ -1820,19 +1826,6 @@ static int intel_sanitize_fbc_option(struct drm_i915_private *i915) return 0; } -static bool need_fbc_vtd_wa(struct drm_i915_private *i915) -{ - /* WaFbcTurnOffFbcWhenHyperVisorIsUsed:skl,bxt */ - if (i915_vtd_active(i915) && - (IS_SKYLAKE(i915) || IS_BROXTON(i915))) { - drm_info(>drm, -"Disabling framebuffer compression (FBC) to prevent screen flicker with VT-d enabled\n"); - return true; - } - - return false; -} - void intel_fbc_add_plane(struct intel_fbc *fbc, struct intel_plane *plane) { plane->fbc = fbc; @@ -1878,9 +1871,6 @@ void intel_fbc_init(struct drm_i915_private *i915) { enum intel_fbc_id fbc_id; - if (need_fbc_vtd_wa(i915)) - DISPLAY_RUNTIME_INFO(i915)->fbc_mask = 0; - i915->display.params.enable_fbc = intel_sanitize_fbc_option(i915); drm_dbg_kms(>drm, "Sanitized enable_fbc value: %d\n", i915->display.params.enable_fbc); -- 2.34.1
[PATCH v1] drm/xe: avoid the async_flip update in the initial plane config
Async flip call is not needed. The updated fb mapping is updated as part of the fixup_initial_plane_config() call. Otherwise we end up updating the PLAN_SURF register twice with the same info. v2: avoid async_flip instead of removing fixup call (Ville) Signed-off-by: Vinod Govindapillai --- drivers/gpu/drm/xe/display/xe_plane_initial.c | 10 -- 1 file changed, 10 deletions(-) diff --git a/drivers/gpu/drm/xe/display/xe_plane_initial.c b/drivers/gpu/drm/xe/display/xe_plane_initial.c index 9693c56d386b..b5f8381b593d 100644 --- a/drivers/gpu/drm/xe/display/xe_plane_initial.c +++ b/drivers/gpu/drm/xe/display/xe_plane_initial.c @@ -189,8 +189,6 @@ intel_find_initial_plane_obj(struct intel_crtc *crtc, to_intel_plane(crtc->base.primary); struct intel_plane_state *plane_state = to_intel_plane_state(plane->base.state); - struct intel_crtc_state *crtc_state = - to_intel_crtc_state(crtc->base.state); struct drm_framebuffer *fb; struct i915_vma *vma; @@ -236,14 +234,6 @@ intel_find_initial_plane_obj(struct intel_crtc *crtc, atomic_or(plane->frontbuffer_bit, _intel_frontbuffer(fb)->bits); plane_config->vma = vma; - - /* -* Flip to the newly created mapping ASAP, so we can re-use the -* first part of GGTT for WOPCM, prevent flickering, and prevent -* the lookup of sysmem scratch pages. -*/ - plane->check_plane(crtc_state, plane_state); - plane->async_flip(plane, crtc_state, plane_state, true); return; nofb: -- 2.34.1
[PATCH v1] drm/xe: no need to call fixup_initial_plane_config in XE
In XE, the updated fb mapping is already done and updated as part of intel_find_initial_plane_obj(). So no need to invoke fixup_initial_plane_config() again as it would basically write the same data to "PLAN_SURF" again. Signed-off-by: Vinod Govindapillai --- drivers/gpu/drm/xe/display/xe_plane_initial.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/gpu/drm/xe/display/xe_plane_initial.c b/drivers/gpu/drm/xe/display/xe_plane_initial.c index 9693c56d386b..51eb80729cfb 100644 --- a/drivers/gpu/drm/xe/display/xe_plane_initial.c +++ b/drivers/gpu/drm/xe/display/xe_plane_initial.c @@ -297,9 +297,6 @@ void intel_initial_plane_config(struct drm_i915_private *i915) */ intel_find_initial_plane_obj(crtc, plane_configs); - if (i915->display.funcs.display->fixup_initial_plane_config(crtc, plane_config)) - intel_crtc_wait_for_next_vblank(crtc); - plane_config_fini(plane_config); } } -- 2.34.1
[PATCH v1 1/1] iommu/vt-d: Fix WARN_ON in iommu probe path
From: Lu Baolu Commit 1a75cc710b95 ("iommu/vt-d: Use rbtree to track iommu probed devices") adds all devices probed by the iommu driver in a rbtree indexed by the source ID of each device. It assumes that each device has a unique source ID. This assumption is incorrect and the VT-d spec doesn't state this requirement either. The reason for using a rbtree to track devices is to look up the device with PCI bus and devfunc in the paths of handling ATS invalidation time out error and the PRI I/O page faults. Both are PCI ATS feature related. Only track the devices that have PCI ATS capabilities in the rbtree to avoid unnecessary WARN_ON in the iommu probe path. Otherwise, on some platforms below kernel splat will be displayed and the iommu probe results in failure. WARNING: CPU: 3 PID: 166 at drivers/iommu/intel/iommu.c:158 intel_iommu_probe_device+0x319/0xd90 Call Trace: ? __warn+0x7e/0x180 ? intel_iommu_probe_device+0x319/0xd90 ? report_bug+0x1f8/0x200 ? handle_bug+0x3c/0x70 ? exc_invalid_op+0x18/0x70 ? asm_exc_invalid_op+0x1a/0x20 ? intel_iommu_probe_device+0x319/0xd90 ? debug_mutex_init+0x37/0x50 __iommu_probe_device+0xf2/0x4f0 iommu_probe_device+0x22/0x70 iommu_bus_notifier+0x1e/0x40 notifier_call_chain+0x46/0x150 blocking_notifier_call_chain+0x42/0x60 bus_notify+0x2f/0x50 device_add+0x5ed/0x7e0 platform_device_add+0xf5/0x240 mfd_add_devices+0x3f9/0x500 ? preempt_count_add+0x4c/0xa0 ? up_write+0xa2/0x1b0 ? __debugfs_create_file+0xe3/0x150 intel_lpss_probe+0x49f/0x5b0 ? pci_conf1_write+0xa3/0xf0 intel_lpss_pci_probe+0xcf/0x110 [intel_lpss_pci] pci_device_probe+0x95/0x120 really_probe+0xd9/0x370 ? __pfx___driver_attach+0x10/0x10 __driver_probe_device+0x73/0x150 driver_probe_device+0x19/0xa0 __driver_attach+0xb6/0x180 ? __pfx___driver_attach+0x10/0x10 bus_for_each_dev+0x77/0xd0 bus_add_driver+0x114/0x210 driver_register+0x5b/0x110 ? __pfx_intel_lpss_pci_driver_init+0x10/0x10 [intel_lpss_pci] do_one_initcall+0x57/0x2b0 ? kmalloc_trace+0x21e/0x280 ? do_init_module+0x1e/0x210 do_init_module+0x5f/0x210 load_module+0x1d37/0x1fc0 ? init_module_from_file+0x86/0xd0 init_module_from_file+0x86/0xd0 idempotent_init_module+0x17c/0x230 __x64_sys_finit_module+0x56/0xb0 do_syscall_64+0x6e/0x140 entry_SYSCALL_64_after_hwframe+0x71/0x79 Fixes: 1a75cc710b95 ("iommu/vt-d: Use rbtree to track iommu probed devices") Signed-off-by: Lu Baolu Signed-off-by: Vinod Govindapillai --- drivers/iommu/intel/iommu.c | 11 +++ 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c index 50eb9aed47cc..a7ecd90303dc 100644 --- a/drivers/iommu/intel/iommu.c +++ b/drivers/iommu/intel/iommu.c @@ -4299,9 +4299,11 @@ static struct iommu_device *intel_iommu_probe_device(struct device *dev) } dev_iommu_priv_set(dev, info); - ret = device_rbtree_insert(iommu, info); - if (ret) - goto free; + if (pdev && pci_ats_supported(pdev)) { + ret = device_rbtree_insert(iommu, info); + if (ret) + goto free; + } if (sm_supported(iommu) && !dev_is_real_dma_subdevice(dev)) { ret = intel_pasid_alloc_table(dev); @@ -4336,7 +4338,8 @@ static void intel_iommu_release_device(struct device *dev) struct intel_iommu *iommu = info->iommu; mutex_lock(>iopf_lock); - device_rbtree_remove(info); + if (dev_is_pci(dev) && pci_ats_supported(to_pci_dev(dev))) + device_rbtree_remove(info); mutex_unlock(>iopf_lock); if (sm_supported(iommu) && !dev_is_real_dma_subdevice(dev) && -- 2.34.1
[PATCH v1 0/1] iommu/vt-d: Fix WARN_ON in iommu probe path
This has already been sent to try bot https://patchwork.freedesktop.org/series/132132/ Lu Baolu (1): iommu/vt-d: Fix WARN_ON in iommu probe path drivers/iommu/intel/iommu.c | 11 +++ 1 file changed, 7 insertions(+), 4 deletions(-) -- 2.34.1
[PATCH v10 6/6] drm/i915/display: force qgv check after the hw state readout
The current intel_bw_atomic_check do not check the possbility of a sagv configuration change after the hw state readout. Hence cannot update the sagv configuration until some other relevant changes like data rates, number of planes etc. happen. Introduce a flag to force qgv check in such cases. Signed-off-by: Vinod Govindapillai --- drivers/gpu/drm/i915/display/intel_bw.c | 8 ++-- drivers/gpu/drm/i915/display/intel_bw.h | 6 ++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c index 6fb228a1a28f..1b190be745a0 100644 --- a/drivers/gpu/drm/i915/display/intel_bw.c +++ b/drivers/gpu/drm/i915/display/intel_bw.c @@ -755,6 +755,7 @@ void intel_bw_crtc_update(struct intel_bw_state *bw_state, intel_bw_crtc_data_rate(crtc_state); bw_state->num_active_planes[crtc->pipe] = intel_bw_crtc_num_active_planes(crtc_state); + bw_state->force_check_qgv = true; drm_dbg_kms(>drm, "pipe %c data rate %u num active planes %u\n", pipe_name(crtc->pipe), @@ -1339,8 +1340,9 @@ int intel_bw_atomic_check(struct intel_atomic_state *state) new_bw_state = intel_atomic_get_new_bw_state(state); if (new_bw_state && - intel_can_enable_sagv(i915, old_bw_state) != - intel_can_enable_sagv(i915, new_bw_state)) + (intel_can_enable_sagv(i915, old_bw_state) != +intel_can_enable_sagv(i915, new_bw_state) || +new_bw_state->force_check_qgv)) changed = true; /* @@ -1354,6 +1356,8 @@ int intel_bw_atomic_check(struct intel_atomic_state *state) if (ret) return ret; + new_bw_state->force_check_qgv = false; + return 0; } diff --git a/drivers/gpu/drm/i915/display/intel_bw.h b/drivers/gpu/drm/i915/display/intel_bw.h index fa1e924ec961..161813cca473 100644 --- a/drivers/gpu/drm/i915/display/intel_bw.h +++ b/drivers/gpu/drm/i915/display/intel_bw.h @@ -47,6 +47,12 @@ struct intel_bw_state { */ u16 qgv_points_mask; + /* +* Flag to force the QGV comparison in atomic check right after the +* hw state readout +*/ + bool force_check_qgv; + int min_cdclk[I915_MAX_PIPES]; unsigned int data_rate[I915_MAX_PIPES]; u8 num_active_planes[I915_MAX_PIPES]; -- 2.34.1
[PATCH v10 5/6] drm/i915/display: handle systems with duplicate psf gv points
From: Stanislav Lisovskiy There could be multiple qgv and psf gv points with similar values. Apparently pcode's handling og psf and qgv points are different. For qgv case, pcode sets whatever is asked by the driver. But in case of psf gv points, it compares the bw from points before setting the mask. This can cause problems in scenarios where we have to disable sagv by setting the highest bw point and there could be multiple points with highest bw. So to set the maximum psf gv point, find out all the points with the highest bw and set all together. v1: - use the same treatment to qgv points as well (Vinod) v2: - pcode confirms that for qgv points, it sets whatever the driver sets (Vinod) Signed-off-by: Stanislav Lisovskiy Signed-off-by: Vinod Govindapillai --- drivers/gpu/drm/i915/display/intel_bw.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c index 5f4f93524bef..6fb228a1a28f 100644 --- a/drivers/gpu/drm/i915/display/intel_bw.c +++ b/drivers/gpu/drm/i915/display/intel_bw.c @@ -874,6 +874,8 @@ static unsigned int icl_max_bw_psf_gv_point_mask(struct drm_i915_private *i915) if (max_data_rate > max_bw) { max_bw_point_mask = BIT(i); max_bw = max_data_rate; + } else if (max_data_rate == max_bw) { + max_bw_point_mask |= BIT(i); } } -- 2.34.1
[PATCH v10 4/6] drm/i915/display: Disable SAGV on bw init, to force QGV point recalculation
From: Stanislav Lisovskiy Problem is that on some platforms, we do get QGV point mask in wrong state on boot. However driver assumes it is set to 0 (i.e all points allowed), however in reality we might get them all restricted, causing issues. Lets disable SAGV initially to force proper QGV point state. If more QGV points are available, driver will recalculate and update those then after next commit. v2: - Added trace to see which QGV/PSF GV point is used when SAGV is disabled. v3: - Move force disable function to intel_bw_init in order to initialize bw state as well, so that hw/sw are immediately in sync after init. v4: - Don't try sending PCode request, seems like it is not possible at intel_bw_init, however assigning bw->state to be restricted as if SAGV is off, still forces driveer to send PCode request anyway on next modeset, so the solution still works. However we still need to address the case, when no display is connected, which anyway requires much more changes. v5: - Put PCode request back and apply temporary hack to make the request succeed(in case if there 2 PSF GV points with same BW, PCode accepts only if both points are restricted/unrestricted same time) - Fix argument sequence for adl_qgv_bw(Ville Syrjälä) v6: - Fix wrong platform checks, not to break everything else. v7: - Split the handling of quplicate QGV/PSF GV points (Vinod) Restrict force disable to display version below 14 (Vinod) v8: - Simplify icl_force_disable_sagv (Vinod) Signed-off-by: Stanislav Lisovskiy Signed-off-by: Vinod Govindapillai --- drivers/gpu/drm/i915/display/intel_bw.c | 50 ++-- drivers/gpu/drm/i915/display/skl_watermark.c | 2 +- drivers/gpu/drm/i915/display/skl_watermark.h | 1 + 3 files changed, 49 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c index 4fed84869e09..5f4f93524bef 100644 --- a/drivers/gpu/drm/i915/display/intel_bw.c +++ b/drivers/gpu/drm/i915/display/intel_bw.c @@ -162,7 +162,9 @@ int icl_pcode_restrict_qgv_points(struct drm_i915_private *dev_priv, 1); if (ret < 0) { - drm_err(_priv->drm, "Failed to disable qgv points (%d) points: 0x%x\n", ret, points_mask); + drm_err(_priv->drm, + "Failed to disable qgv points (0x%x) points: 0x%x\n", + ret, points_mask); return ret; } @@ -859,6 +861,41 @@ static u16 icl_prepare_qgv_points_mask(struct drm_i915_private *i915, ADLS_PCODE_REQ_PSF_PT(psf_points)) & icl_qgv_points_mask(i915); } +static unsigned int icl_max_bw_psf_gv_point_mask(struct drm_i915_private *i915) +{ + unsigned int num_psf_gv_points = i915->display.bw.max[0].num_psf_gv_points; + unsigned int max_bw_point_mask = 0; + unsigned int max_bw = 0; + int i; + + for (i = 0; i < num_psf_gv_points; i++) { + unsigned int max_data_rate = adl_psf_bw(i915, i); + + if (max_data_rate > max_bw) { + max_bw_point_mask = BIT(i); + max_bw = max_data_rate; + } + } + + return max_bw_point_mask; +} + +static void icl_force_disable_sagv(struct drm_i915_private *i915, + struct intel_bw_state *bw_state) +{ + unsigned int qgv_points = icl_max_bw_qgv_point_mask(i915, 0); + unsigned int psf_points = icl_max_bw_psf_gv_point_mask(i915); + + bw_state->qgv_points_mask = icl_prepare_qgv_points_mask(i915, + qgv_points, + psf_points); + + drm_dbg_kms(>drm, "Forcing SAGV disable: mask 0x%x\n", + bw_state->qgv_points_mask); + + icl_pcode_restrict_qgv_points(i915, bw_state->qgv_points_mask); +} + static int mtl_find_qgv_points(struct drm_i915_private *i915, unsigned int data_rate, unsigned int num_active_planes, @@ -1341,7 +1378,7 @@ static const struct intel_global_state_funcs intel_bw_funcs = { .atomic_destroy_state = intel_bw_destroy_state, }; -int intel_bw_init(struct drm_i915_private *dev_priv) +int intel_bw_init(struct drm_i915_private *i915) { struct intel_bw_state *state; @@ -1349,8 +1386,15 @@ int intel_bw_init(struct drm_i915_private *dev_priv) if (!state) return -ENOMEM; - intel_atomic_global_obj_init(dev_priv, _priv->display.bw.obj, + intel_atomic_global_obj_init(i915, >display.bw.obj, >base, _bw_funcs); + /* +* Limit this only if we have SAGV. And for Display version 14 onwards +* sagv is
[PATCH v10 3/6] drm/i915/display: extract code to prepare qgv points mask
Extract the code to prepare the QGV points mask as per the format expected by the pcode as this could be utlized from multiple points. Signed-off-by: Vinod Govindapillai --- drivers/gpu/drm/i915/display/intel_bw.c | 16 +++- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c index c00094e5f11c..4fed84869e09 100644 --- a/drivers/gpu/drm/i915/display/intel_bw.c +++ b/drivers/gpu/drm/i915/display/intel_bw.c @@ -851,6 +851,14 @@ static unsigned int icl_max_bw_qgv_point_mask(struct drm_i915_private *i915, return max_bw_point_mask; } +static u16 icl_prepare_qgv_points_mask(struct drm_i915_private *i915, + unsigned int qgv_points, + unsigned int psf_points) +{ + return ~(ICL_PCODE_REQ_QGV_PT(qgv_points) | +ADLS_PCODE_REQ_PSF_PT(psf_points)) & icl_qgv_points_mask(i915); +} + static int mtl_find_qgv_points(struct drm_i915_private *i915, unsigned int data_rate, unsigned int num_active_planes, @@ -994,11 +1002,9 @@ static int icl_find_qgv_points(struct drm_i915_private *i915, * We store the ones which need to be masked as that is what PCode * actually accepts as a parameter. */ - new_bw_state->qgv_points_mask = - ~(ICL_PCODE_REQ_QGV_PT(qgv_points) | - ADLS_PCODE_REQ_PSF_PT(psf_points)) & - icl_qgv_points_mask(i915); - + new_bw_state->qgv_points_mask = icl_prepare_qgv_points_mask(i915, + qgv_points, + psf_points); /* * If the actual mask had changed we need to make sure that * the commits are serialized(in case this is a nomodeset, nonblocking) -- 2.34.1
[PATCH v10 1/6] drm/i915/display: Add meaningful traces for QGV point info error handling
From: Stanislav Lisovskiy For debug purposes we need those - error path won't flood the log, however there has been already numerous cases, when due to lack of debugs, we couldn't immediately tell what was the problem on customer machine, which slowed down the investigation, requiring to get access to target device and adding those traces manually. v2: - Make the debug more generic and move it to intel_dram_detect (Gustavo Sousa) v3: - Use %u for unsigned variable in debug prints (Gustavo) Reviewed-by: Gustavo Sousa Signed-off-by: Stanislav Lisovskiy Signed-off-by: Vinod Govindapillai --- drivers/gpu/drm/i915/display/intel_bw.c | 4 +++- drivers/gpu/drm/i915/soc/intel_dram.c | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c index 7f2a50b4f494..77886cc21211 100644 --- a/drivers/gpu/drm/i915/display/intel_bw.c +++ b/drivers/gpu/drm/i915/display/intel_bw.c @@ -290,8 +290,10 @@ static int icl_get_qgv_points(struct drm_i915_private *dev_priv, struct intel_qgv_point *sp = >points[i]; ret = intel_read_qgv_point_info(dev_priv, sp, i); - if (ret) + if (ret) { + drm_dbg_kms(_priv->drm, "Could not read QGV %d info\n", i); return ret; + } drm_dbg_kms(_priv->drm, "QGV %d: DCLK=%d tRP=%d tRDPRE=%d tRAS=%d tRCD=%d tRC=%d\n", diff --git a/drivers/gpu/drm/i915/soc/intel_dram.c b/drivers/gpu/drm/i915/soc/intel_dram.c index 15492b69f698..e3287f1de774 100644 --- a/drivers/gpu/drm/i915/soc/intel_dram.c +++ b/drivers/gpu/drm/i915/soc/intel_dram.c @@ -681,6 +681,8 @@ void intel_dram_detect(struct drm_i915_private *i915) if (ret) return; + drm_dbg_kms(>drm, "Num qgv points %u\n", dram_info->num_qgv_points); + drm_dbg_kms(>drm, "DRAM channels: %u\n", dram_info->num_channels); drm_dbg_kms(>drm, "Watermark level 0 adjustment needed: %s\n", -- 2.34.1
[PATCH v10 2/6] drm/i915/display: Extract code required to calculate max qgv/psf gv point
From: Stanislav Lisovskiy We need that in order to force disable SAGV in next patch. Also it is beneficial to separate that code, as in majority cases, when SAGV is enabled, we don't even need those calculations. Also we probably need to determine max PSF GV point as well, however currently we don't do that when we disable SAGV, which might be actually causing some issues in that case. v2: - Introduce helper adl_qgv_bw(counterpart to adl_psf_bw) (Ville Syrjälä) - Don't restrict psf gv points for SAGV disable case (Ville Syrjälä) v3: - Update icl_max_bw_qgv_point_mask to return max qgv point mask (Vinod) v4: - Minor changes in icl_find_qgv_points (Vinod) Signed-off-by: Stanislav Lisovskiy Signed-off-by: Vinod Govindapillai --- drivers/gpu/drm/i915/display/intel_bw.c | 80 +++-- 1 file changed, 50 insertions(+), 30 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c index 77886cc21211..c00094e5f11c 100644 --- a/drivers/gpu/drm/i915/display/intel_bw.c +++ b/drivers/gpu/drm/i915/display/intel_bw.c @@ -661,6 +661,22 @@ static unsigned int adl_psf_bw(struct drm_i915_private *dev_priv, return bi->psf_bw[psf_gv_point]; } +static unsigned int icl_qgv_bw(struct drm_i915_private *i915, + int num_active_planes, int qgv_point) +{ + unsigned int idx; + + if (DISPLAY_VER(i915) >= 12) + idx = tgl_max_bw_index(i915, num_active_planes, qgv_point); + else + idx = icl_max_bw_index(i915, num_active_planes, qgv_point); + + if (idx >= ARRAY_SIZE(i915->display.bw.max)) + return 0; + + return i915->display.bw.max[idx].deratedbw[qgv_point]; +} + void intel_bw_init_hw(struct drm_i915_private *dev_priv) { if (!HAS_DISPLAY(dev_priv)) @@ -806,6 +822,35 @@ intel_atomic_get_bw_state(struct intel_atomic_state *state) return to_intel_bw_state(bw_state); } +static unsigned int icl_max_bw_qgv_point_mask(struct drm_i915_private *i915, + int num_active_planes) +{ + unsigned int num_qgv_points = i915->display.bw.max[0].num_qgv_points; + unsigned int max_bw_point_mask = 0; + unsigned int max_bw = 0; + int i; + + for (i = 0; i < num_qgv_points; i++) { + unsigned int max_data_rate = + icl_qgv_bw(i915, num_active_planes, i); + + /* +* We need to know which qgv point gives us +* maximum bandwidth in order to disable SAGV +* if we find that we exceed SAGV block time +* with watermarks. By that moment we already +* have those, as it is calculated earlier in +* intel_atomic_check, +*/ + if (max_data_rate > max_bw) { + max_bw_point_mask = BIT(i); + max_bw = max_data_rate; + } + } + + return max_bw_point_mask; +} + static int mtl_find_qgv_points(struct drm_i915_private *i915, unsigned int data_rate, unsigned int num_active_planes, @@ -883,8 +928,6 @@ static int icl_find_qgv_points(struct drm_i915_private *i915, const struct intel_bw_state *old_bw_state, struct intel_bw_state *new_bw_state) { - unsigned int max_bw_point = 0; - unsigned int max_bw = 0; unsigned int num_psf_gv_points = i915->display.bw.max[0].num_psf_gv_points; unsigned int num_qgv_points = i915->display.bw.max[0].num_qgv_points; u16 psf_points = 0; @@ -897,31 +940,8 @@ static int icl_find_qgv_points(struct drm_i915_private *i915, return ret; for (i = 0; i < num_qgv_points; i++) { - unsigned int idx; - unsigned int max_data_rate; - - if (DISPLAY_VER(i915) >= 12) - idx = tgl_max_bw_index(i915, num_active_planes, i); - else - idx = icl_max_bw_index(i915, num_active_planes, i); - - if (idx >= ARRAY_SIZE(i915->display.bw.max)) - continue; - - max_data_rate = i915->display.bw.max[idx].deratedbw[i]; - - /* -* We need to know which qgv point gives us -* maximum bandwidth in order to disable SAGV -* if we find that we exceed SAGV block time -* with watermarks. By that moment we already -* have those, as it is calculated earlier in -* intel_atomic_check, -*/ - if (max_data_rate > max_bw) { - max_bw_point = i; - max_bw = max_data_rate; - } +
[PATCH v10 0/6] QGV/SAGV related fixes
We have couple of customer issues, related to SAGV/QGV point calculation. Those patches contain fixes plus some additional debugs for those issues. Stanislav Lisovskiy (4): drm/i915/display: Add meaningful traces for QGV point info error handling drm/i915/display: Extract code required to calculate max qgv/psf gv point drm/i915/display: Disable SAGV on bw init, to force QGV point recalculation drm/i915/display: handle systems with duplicate psf gv points Vinod Govindapillai (2): drm/i915/display: extract code to prepare qgv points mask drm/i915/display: force qgv check after the hw state readout drivers/gpu/drm/i915/display/intel_bw.c | 160 ++- drivers/gpu/drm/i915/display/intel_bw.h | 6 + drivers/gpu/drm/i915/display/skl_watermark.c | 2 +- drivers/gpu/drm/i915/display/skl_watermark.h | 1 + drivers/gpu/drm/i915/soc/intel_dram.c| 2 + 5 files changed, 129 insertions(+), 42 deletions(-) -- 2.34.1
[PATCH v9 6/6] drm/i915/display: force qgv check after the hw state readout
The current intel_bw_atomic_check do not check the possbility of a sagv configuration change after the hw state readout. Hence cannot update the sagv configuration until some other relevant changes like data rates, number of planes etc. happen. Introduce a flag to force qgv check in such cases. Signed-off-by: Vinod Govindapillai --- drivers/gpu/drm/i915/display/intel_bw.c | 8 ++-- drivers/gpu/drm/i915/display/intel_bw.h | 6 ++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c index f6690d545d95..ecb9600cb69a 100644 --- a/drivers/gpu/drm/i915/display/intel_bw.c +++ b/drivers/gpu/drm/i915/display/intel_bw.c @@ -755,6 +755,7 @@ void intel_bw_crtc_update(struct intel_bw_state *bw_state, intel_bw_crtc_data_rate(crtc_state); bw_state->num_active_planes[crtc->pipe] = intel_bw_crtc_num_active_planes(crtc_state); + bw_state->force_check_qgv = true; drm_dbg_kms(>drm, "pipe %c data rate %u num active planes %u\n", pipe_name(crtc->pipe), @@ -1341,8 +1342,9 @@ int intel_bw_atomic_check(struct intel_atomic_state *state) new_bw_state = intel_atomic_get_new_bw_state(state); if (new_bw_state && - intel_can_enable_sagv(i915, old_bw_state) != - intel_can_enable_sagv(i915, new_bw_state)) + (intel_can_enable_sagv(i915, old_bw_state) != +intel_can_enable_sagv(i915, new_bw_state) || +new_bw_state->force_check_qgv)) changed = true; /* @@ -1356,6 +1358,8 @@ int intel_bw_atomic_check(struct intel_atomic_state *state) if (ret) return ret; + new_bw_state->force_check_qgv = false; + return 0; } diff --git a/drivers/gpu/drm/i915/display/intel_bw.h b/drivers/gpu/drm/i915/display/intel_bw.h index fa1e924ec961..161813cca473 100644 --- a/drivers/gpu/drm/i915/display/intel_bw.h +++ b/drivers/gpu/drm/i915/display/intel_bw.h @@ -47,6 +47,12 @@ struct intel_bw_state { */ u16 qgv_points_mask; + /* +* Flag to force the QGV comparison in atomic check right after the +* hw state readout +*/ + bool force_check_qgv; + int min_cdclk[I915_MAX_PIPES]; unsigned int data_rate[I915_MAX_PIPES]; u8 num_active_planes[I915_MAX_PIPES]; -- 2.34.1
[PATCH v9 4/6] drm/i915/display: Disable SAGV on bw init, to force QGV point recalculation
From: Stanislav Lisovskiy Problem is that on some platforms, we do get QGV point mask in wrong state on boot. However driver assumes it is set to 0 (i.e all points allowed), however in reality we might get them all restricted, causing issues. Lets disable SAGV initially to force proper QGV point state. If more QGV points are available, driver will recalculate and update those then after next commit. v2: - Added trace to see which QGV/PSF GV point is used when SAGV is disabled. v3: - Move force disable function to intel_bw_init in order to initialize bw state as well, so that hw/sw are immediately in sync after init. v4: - Don't try sending PCode request, seems like it is not possible at intel_bw_init, however assigning bw->state to be restricted as if SAGV is off, still forces driveer to send PCode request anyway on next modeset, so the solution still works. However we still need to address the case, when no display is connected, which anyway requires much more changes. v5: - Put PCode request back and apply temporary hack to make the request succeed(in case if there 2 PSF GV points with same BW, PCode accepts only if both points are restricted/unrestricted same time) - Fix argument sequence for adl_qgv_bw(Ville Syrjälä) v6: - Fix wrong platform checks, not to break everything else. v7: - Split the handling of quplicate QGV/PSF GV points (Vinod) Restrict force disable to display version below 14 (Vinod) v8: - Simplify icl_force_disable_sagv (Vinod) Signed-off-by: Stanislav Lisovskiy Signed-off-by: Vinod Govindapillai --- drivers/gpu/drm/i915/display/intel_bw.c | 50 ++-- drivers/gpu/drm/i915/display/skl_watermark.c | 2 +- drivers/gpu/drm/i915/display/skl_watermark.h | 1 + 3 files changed, 49 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c index 4fed84869e09..5f4f93524bef 100644 --- a/drivers/gpu/drm/i915/display/intel_bw.c +++ b/drivers/gpu/drm/i915/display/intel_bw.c @@ -162,7 +162,9 @@ int icl_pcode_restrict_qgv_points(struct drm_i915_private *dev_priv, 1); if (ret < 0) { - drm_err(_priv->drm, "Failed to disable qgv points (%d) points: 0x%x\n", ret, points_mask); + drm_err(_priv->drm, + "Failed to disable qgv points (0x%x) points: 0x%x\n", + ret, points_mask); return ret; } @@ -859,6 +861,41 @@ static u16 icl_prepare_qgv_points_mask(struct drm_i915_private *i915, ADLS_PCODE_REQ_PSF_PT(psf_points)) & icl_qgv_points_mask(i915); } +static unsigned int icl_max_bw_psf_gv_point_mask(struct drm_i915_private *i915) +{ + unsigned int num_psf_gv_points = i915->display.bw.max[0].num_psf_gv_points; + unsigned int max_bw_point_mask = 0; + unsigned int max_bw = 0; + int i; + + for (i = 0; i < num_psf_gv_points; i++) { + unsigned int max_data_rate = adl_psf_bw(i915, i); + + if (max_data_rate > max_bw) { + max_bw_point_mask = BIT(i); + max_bw = max_data_rate; + } + } + + return max_bw_point_mask; +} + +static void icl_force_disable_sagv(struct drm_i915_private *i915, + struct intel_bw_state *bw_state) +{ + unsigned int qgv_points = icl_max_bw_qgv_point_mask(i915, 0); + unsigned int psf_points = icl_max_bw_psf_gv_point_mask(i915); + + bw_state->qgv_points_mask = icl_prepare_qgv_points_mask(i915, + qgv_points, + psf_points); + + drm_dbg_kms(>drm, "Forcing SAGV disable: mask 0x%x\n", + bw_state->qgv_points_mask); + + icl_pcode_restrict_qgv_points(i915, bw_state->qgv_points_mask); +} + static int mtl_find_qgv_points(struct drm_i915_private *i915, unsigned int data_rate, unsigned int num_active_planes, @@ -1341,7 +1378,7 @@ static const struct intel_global_state_funcs intel_bw_funcs = { .atomic_destroy_state = intel_bw_destroy_state, }; -int intel_bw_init(struct drm_i915_private *dev_priv) +int intel_bw_init(struct drm_i915_private *i915) { struct intel_bw_state *state; @@ -1349,8 +1386,15 @@ int intel_bw_init(struct drm_i915_private *dev_priv) if (!state) return -ENOMEM; - intel_atomic_global_obj_init(dev_priv, _priv->display.bw.obj, + intel_atomic_global_obj_init(i915, >display.bw.obj, >base, _bw_funcs); + /* +* Limit this only if we have SAGV. And for Display version 14 onwards +* sagv is
[PATCH v9 5/6] drm/i915/display: handle systems with duplicate qgv/psf gv points
From: Stanislav Lisovskiy There could be multiple qgv and psf gv points with similar values In case if we need to set one such QGV or psf gv point where there could be duplicate entries, we would have to select all those points. Otherwise pcode might reject the GV configuration. We do handle this when we set appropriate qgv and psf gv as part of intel_bw_atomic_check calls. But during the bw_init force disable QGV points phase, we need to select all those points corresponding to the maximum bw as well. v1: - use the same treatment to qgv points as well (Vinod) Signed-off-by: Stanislav Lisovskiy Signed-off-by: Vinod Govindapillai --- drivers/gpu/drm/i915/display/intel_bw.c | 4 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c index 5f4f93524bef..f6690d545d95 100644 --- a/drivers/gpu/drm/i915/display/intel_bw.c +++ b/drivers/gpu/drm/i915/display/intel_bw.c @@ -847,6 +847,8 @@ static unsigned int icl_max_bw_qgv_point_mask(struct drm_i915_private *i915, if (max_data_rate > max_bw) { max_bw_point_mask = BIT(i); max_bw = max_data_rate; + } else if (max_data_rate == max_bw) { + max_bw_point_mask |= BIT(i); } } @@ -874,6 +876,8 @@ static unsigned int icl_max_bw_psf_gv_point_mask(struct drm_i915_private *i915) if (max_data_rate > max_bw) { max_bw_point_mask = BIT(i); max_bw = max_data_rate; + } else if (max_data_rate == max_bw) { + max_bw_point_mask |= BIT(i); } } -- 2.34.1
[PATCH v9 2/6] drm/i915/display: Extract code required to calculate max qgv/psf gv point
From: Stanislav Lisovskiy We need that in order to force disable SAGV in next patch. Also it is beneficial to separate that code, as in majority cases, when SAGV is enabled, we don't even need those calculations. Also we probably need to determine max PSF GV point as well, however currently we don't do that when we disable SAGV, which might be actually causing some issues in that case. v2: - Introduce helper adl_qgv_bw(counterpart to adl_psf_bw) (Ville Syrjälä) - Don't restrict psf gv points for SAGV disable case (Ville Syrjälä) v3: - Update icl_max_bw_qgv_point_mask to return max qgv point mask (Vinod) v4: - Minor changes in icl_find_qgv_points (Vinod) Signed-off-by: Stanislav Lisovskiy Signed-off-by: Vinod Govindapillai --- drivers/gpu/drm/i915/display/intel_bw.c | 80 +++-- 1 file changed, 50 insertions(+), 30 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c index 77886cc21211..c00094e5f11c 100644 --- a/drivers/gpu/drm/i915/display/intel_bw.c +++ b/drivers/gpu/drm/i915/display/intel_bw.c @@ -661,6 +661,22 @@ static unsigned int adl_psf_bw(struct drm_i915_private *dev_priv, return bi->psf_bw[psf_gv_point]; } +static unsigned int icl_qgv_bw(struct drm_i915_private *i915, + int num_active_planes, int qgv_point) +{ + unsigned int idx; + + if (DISPLAY_VER(i915) >= 12) + idx = tgl_max_bw_index(i915, num_active_planes, qgv_point); + else + idx = icl_max_bw_index(i915, num_active_planes, qgv_point); + + if (idx >= ARRAY_SIZE(i915->display.bw.max)) + return 0; + + return i915->display.bw.max[idx].deratedbw[qgv_point]; +} + void intel_bw_init_hw(struct drm_i915_private *dev_priv) { if (!HAS_DISPLAY(dev_priv)) @@ -806,6 +822,35 @@ intel_atomic_get_bw_state(struct intel_atomic_state *state) return to_intel_bw_state(bw_state); } +static unsigned int icl_max_bw_qgv_point_mask(struct drm_i915_private *i915, + int num_active_planes) +{ + unsigned int num_qgv_points = i915->display.bw.max[0].num_qgv_points; + unsigned int max_bw_point_mask = 0; + unsigned int max_bw = 0; + int i; + + for (i = 0; i < num_qgv_points; i++) { + unsigned int max_data_rate = + icl_qgv_bw(i915, num_active_planes, i); + + /* +* We need to know which qgv point gives us +* maximum bandwidth in order to disable SAGV +* if we find that we exceed SAGV block time +* with watermarks. By that moment we already +* have those, as it is calculated earlier in +* intel_atomic_check, +*/ + if (max_data_rate > max_bw) { + max_bw_point_mask = BIT(i); + max_bw = max_data_rate; + } + } + + return max_bw_point_mask; +} + static int mtl_find_qgv_points(struct drm_i915_private *i915, unsigned int data_rate, unsigned int num_active_planes, @@ -883,8 +928,6 @@ static int icl_find_qgv_points(struct drm_i915_private *i915, const struct intel_bw_state *old_bw_state, struct intel_bw_state *new_bw_state) { - unsigned int max_bw_point = 0; - unsigned int max_bw = 0; unsigned int num_psf_gv_points = i915->display.bw.max[0].num_psf_gv_points; unsigned int num_qgv_points = i915->display.bw.max[0].num_qgv_points; u16 psf_points = 0; @@ -897,31 +940,8 @@ static int icl_find_qgv_points(struct drm_i915_private *i915, return ret; for (i = 0; i < num_qgv_points; i++) { - unsigned int idx; - unsigned int max_data_rate; - - if (DISPLAY_VER(i915) >= 12) - idx = tgl_max_bw_index(i915, num_active_planes, i); - else - idx = icl_max_bw_index(i915, num_active_planes, i); - - if (idx >= ARRAY_SIZE(i915->display.bw.max)) - continue; - - max_data_rate = i915->display.bw.max[idx].deratedbw[i]; - - /* -* We need to know which qgv point gives us -* maximum bandwidth in order to disable SAGV -* if we find that we exceed SAGV block time -* with watermarks. By that moment we already -* have those, as it is calculated earlier in -* intel_atomic_check, -*/ - if (max_data_rate > max_bw) { - max_bw_point = i; - max_bw = max_data_rate; - } +
[PATCH v9 3/6] drm/i915/display: extract code to prepare qgv points mask
Extract the code to prepare the QGV points mask as per the format expected by the pcode as this could be utlized from multiple points. Signed-off-by: Vinod Govindapillai --- drivers/gpu/drm/i915/display/intel_bw.c | 16 +++- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c index c00094e5f11c..4fed84869e09 100644 --- a/drivers/gpu/drm/i915/display/intel_bw.c +++ b/drivers/gpu/drm/i915/display/intel_bw.c @@ -851,6 +851,14 @@ static unsigned int icl_max_bw_qgv_point_mask(struct drm_i915_private *i915, return max_bw_point_mask; } +static u16 icl_prepare_qgv_points_mask(struct drm_i915_private *i915, + unsigned int qgv_points, + unsigned int psf_points) +{ + return ~(ICL_PCODE_REQ_QGV_PT(qgv_points) | +ADLS_PCODE_REQ_PSF_PT(psf_points)) & icl_qgv_points_mask(i915); +} + static int mtl_find_qgv_points(struct drm_i915_private *i915, unsigned int data_rate, unsigned int num_active_planes, @@ -994,11 +1002,9 @@ static int icl_find_qgv_points(struct drm_i915_private *i915, * We store the ones which need to be masked as that is what PCode * actually accepts as a parameter. */ - new_bw_state->qgv_points_mask = - ~(ICL_PCODE_REQ_QGV_PT(qgv_points) | - ADLS_PCODE_REQ_PSF_PT(psf_points)) & - icl_qgv_points_mask(i915); - + new_bw_state->qgv_points_mask = icl_prepare_qgv_points_mask(i915, + qgv_points, + psf_points); /* * If the actual mask had changed we need to make sure that * the commits are serialized(in case this is a nomodeset, nonblocking) -- 2.34.1
[PATCH v9 1/6] drm/i915/display: Add meaningful traces for QGV point info error handling
From: Stanislav Lisovskiy For debug purposes we need those - error path won't flood the log, however there has been already numerous cases, when due to lack of debugs, we couldn't immediately tell what was the problem on customer machine, which slowed down the investigation, requiring to get access to target device and adding those traces manually. v2: - Make the debug more generic and move it to intel_dram_detect (Gustavo Sousa) v3: - Use %u for unsigned variable in debug prints (Gustavo) Reviewed-by: Gustavo Sousa Signed-off-by: Stanislav Lisovskiy Signed-off-by: Vinod Govindapillai --- drivers/gpu/drm/i915/display/intel_bw.c | 4 +++- drivers/gpu/drm/i915/soc/intel_dram.c | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c index 7f2a50b4f494..77886cc21211 100644 --- a/drivers/gpu/drm/i915/display/intel_bw.c +++ b/drivers/gpu/drm/i915/display/intel_bw.c @@ -290,8 +290,10 @@ static int icl_get_qgv_points(struct drm_i915_private *dev_priv, struct intel_qgv_point *sp = >points[i]; ret = intel_read_qgv_point_info(dev_priv, sp, i); - if (ret) + if (ret) { + drm_dbg_kms(_priv->drm, "Could not read QGV %d info\n", i); return ret; + } drm_dbg_kms(_priv->drm, "QGV %d: DCLK=%d tRP=%d tRDPRE=%d tRAS=%d tRCD=%d tRC=%d\n", diff --git a/drivers/gpu/drm/i915/soc/intel_dram.c b/drivers/gpu/drm/i915/soc/intel_dram.c index 15492b69f698..e3287f1de774 100644 --- a/drivers/gpu/drm/i915/soc/intel_dram.c +++ b/drivers/gpu/drm/i915/soc/intel_dram.c @@ -681,6 +681,8 @@ void intel_dram_detect(struct drm_i915_private *i915) if (ret) return; + drm_dbg_kms(>drm, "Num qgv points %u\n", dram_info->num_qgv_points); + drm_dbg_kms(>drm, "DRAM channels: %u\n", dram_info->num_channels); drm_dbg_kms(>drm, "Watermark level 0 adjustment needed: %s\n", -- 2.34.1
[PATCH v9 0/6] QGV/SAGV related fixes
We have couple of customer issues, related to SAGV/QGV point calculation. Those patches contain fixes plus some additional debugs for those issues. Stanislav Lisovskiy (4): drm/i915/display: Add meaningful traces for QGV point info error handling drm/i915/display: Extract code required to calculate max qgv/psf gv point drm/i915/display: Disable SAGV on bw init, to force QGV point recalculation drm/i915/display: handle systems with duplicate qgv/psf gv points Vinod Govindapillai (2): drm/i915/display: extract code to prepare qgv points mask drm/i915/display: force qgv check after the hw state readout drivers/gpu/drm/i915/display/intel_bw.c | 162 ++- drivers/gpu/drm/i915/display/intel_bw.h | 6 + drivers/gpu/drm/i915/display/skl_watermark.c | 2 +- drivers/gpu/drm/i915/display/skl_watermark.h | 1 + drivers/gpu/drm/i915/soc/intel_dram.c| 2 + 5 files changed, 131 insertions(+), 42 deletions(-) -- 2.34.1
[PATCH v8 4/4] drm/i915/display: handle systems with duplicate qgv/psf gv points
From: Stanislav Lisovskiy There could be multiple qgv and psf gv points with similar values In case if we need to set one such QGV or psf gv point where there could be duplicate entries, we would have to select all those points. Otherwise pcode might reject the GV configuration. We do handle this when we set appropriate qgv and psf gv as part of intel_bw_atomic_check calls. But during the bw_init force disable QGV points phase, we need to select all those points corresponding to the maximum bw as well. v1: - use the same treatment to qgv points as well (Vinod) Signed-off-by: Stanislav Lisovskiy Signed-off-by: Vinod Govindapillai --- drivers/gpu/drm/i915/display/intel_bw.c | 4 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c index 844d2d9efeb4..20c67474154e 100644 --- a/drivers/gpu/drm/i915/display/intel_bw.c +++ b/drivers/gpu/drm/i915/display/intel_bw.c @@ -847,6 +847,8 @@ static unsigned int icl_max_bw_qgv_point_mask(struct drm_i915_private *i915, if (max_data_rate > max_bw) { max_bw_point_mask = BIT(i); max_bw = max_data_rate; + } else if (max_data_rate == max_bw) { + max_bw_point_mask |= BIT(i); } } @@ -866,6 +868,8 @@ static unsigned int icl_max_bw_psf_gv_point_mask(struct drm_i915_private *i915) if (max_data_rate > max_bw) { max_bw_point_mask = BIT(i); max_bw = max_data_rate; + } else if (max_data_rate == max_bw) { + max_bw_point_mask |= BIT(i); } } -- 2.34.1
[PATCH v8 3/4] drm/i915: Disable SAGV on bw init, to force QGV point recalculation
From: Stanislav Lisovskiy Problem is that on some platforms, we do get QGV point mask in wrong state on boot. However driver assumes it is set to 0 (i.e all points allowed), however in reality we might get them all restricted, causing issues. Lets disable SAGV initially to force proper QGV point state. If more QGV points are available, driver will recalculate and update those then after next commit. v2: - Added trace to see which QGV/PSF GV point is used when SAGV is disabled. v3: - Move force disable function to intel_bw_init in order to initialize bw state as well, so that hw/sw are immediately in sync after init. v4: - Don't try sending PCode request, seems like it is not possible at intel_bw_init, however assigning bw->state to be restricted as if SAGV is off, still forces driveer to send PCode request anyway on next modeset, so the solution still works. However we still need to address the case, when no display is connected, which anyway requires much more changes. v5: - Put PCode request back and apply temporary hack to make the request succeed(in case if there 2 PSF GV points with same BW, PCode accepts only if both points are restricted/unrestricted same time) - Fix argument sequence for adl_qgv_bw(Ville Syrjälä) v6: - Fix wrong platform checks, not to break everything else. v7: - Split the handling of quplicate QGV/PSF GV points (Vinod) Restrict force disable to display version below 14 (Vinod) Signed-off-by: Stanislav Lisovskiy Signed-off-by: Vinod Govindapillai --- drivers/gpu/drm/i915/display/intel_bw.c | 55 ++-- drivers/gpu/drm/i915/display/skl_watermark.c | 2 +- drivers/gpu/drm/i915/display/skl_watermark.h | 1 + 3 files changed, 54 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c index b3d7893f2cd7..844d2d9efeb4 100644 --- a/drivers/gpu/drm/i915/display/intel_bw.c +++ b/drivers/gpu/drm/i915/display/intel_bw.c @@ -162,7 +162,9 @@ int icl_pcode_restrict_qgv_points(struct drm_i915_private *dev_priv, 1); if (ret < 0) { - drm_err(_priv->drm, "Failed to disable qgv points (%d) points: 0x%x\n", ret, points_mask); + drm_err(_priv->drm, + "Failed to disable qgv points (0x%x) points: 0x%x\n", + ret, points_mask); return ret; } @@ -851,6 +853,46 @@ static unsigned int icl_max_bw_qgv_point_mask(struct drm_i915_private *i915, return max_bw_point_mask; } +static unsigned int icl_max_bw_psf_gv_point_mask(struct drm_i915_private *i915) +{ + unsigned int num_psf_gv_points = i915->display.bw.max[0].num_psf_gv_points; + unsigned int max_bw_point_mask = 0; + unsigned int max_bw = 0; + int i; + + for (i = 0; i < num_psf_gv_points; i++) { + unsigned int max_data_rate = adl_psf_bw(i915, i); + + if (max_data_rate > max_bw) { + max_bw_point_mask = BIT(i); + max_bw = max_data_rate; + } + } + + return max_bw_point_mask; +} + +static void icl_force_disable_sagv(struct drm_i915_private *i915, + struct intel_bw_state *bw_state) +{ + unsigned int qgv_points = icl_max_bw_qgv_point_mask(i915, 0); + unsigned int psf_points = icl_max_bw_psf_gv_point_mask(i915); + int ret; + + bw_state->qgv_points_mask = ~(ICL_PCODE_REQ_QGV_PT(qgv_points)| + ADLS_PCODE_REQ_PSF_PT(psf_points)) & + icl_qgv_points_mask(i915); + + drm_dbg_kms(>drm, "Forcing SAGV disable: mask %x\n", bw_state->qgv_points_mask); + + ret = icl_pcode_restrict_qgv_points(i915, bw_state->qgv_points_mask); + if (ret) + drm_dbg_kms(>drm, "Restricting GV points failed: %x\n", ret); + else + drm_dbg_kms(>drm, "Restricting GV points succeeded\n"); + +} + static int mtl_find_qgv_points(struct drm_i915_private *i915, unsigned int data_rate, unsigned int num_active_planes, @@ -1337,7 +1379,7 @@ static const struct intel_global_state_funcs intel_bw_funcs = { .atomic_destroy_state = intel_bw_destroy_state, }; -int intel_bw_init(struct drm_i915_private *dev_priv) +int intel_bw_init(struct drm_i915_private *i915) { struct intel_bw_state *state; @@ -1345,8 +1387,15 @@ int intel_bw_init(struct drm_i915_private *dev_priv) if (!state) return -ENOMEM; - intel_atomic_global_obj_init(dev_priv, _priv->display.bw.obj, + intel_atomic_global_obj_init(i915, >display.bw.obj, >base, _bw_funcs); +
[PATCH v8 2/4] drm/i915: Extract code required to calculate max qgv/psf gv point
From: Stanislav Lisovskiy We need that in order to force disable SAGV in next patch. Also it is beneficial to separate that code, as in majority cases, when SAGV is enabled, we don't even need those calculations. Also we probably need to determine max PSF GV point as well, however currently we don't do that when we disable SAGV, which might be actually causing some issues in that case. v2: - Introduce helper adl_qgv_bw(counterpart to adl_psf_bw) (Ville Syrjälä) - Don't restrict psf gv points for SAGV disable case (Ville Syrjälä) v3: - Update icl_max_bw_qgv_point_mask to return max qgv point mask (Vinod) Signed-off-by: Stanislav Lisovskiy Signed-off-by: Vinod Govindapillai --- drivers/gpu/drm/i915/display/intel_bw.c | 76 - 1 file changed, 49 insertions(+), 27 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c index 77886cc21211..b3d7893f2cd7 100644 --- a/drivers/gpu/drm/i915/display/intel_bw.c +++ b/drivers/gpu/drm/i915/display/intel_bw.c @@ -661,6 +661,22 @@ static unsigned int adl_psf_bw(struct drm_i915_private *dev_priv, return bi->psf_bw[psf_gv_point]; } +static unsigned int icl_qgv_bw(struct drm_i915_private *i915, + int num_active_planes, int qgv_point) +{ + unsigned int idx; + + if (DISPLAY_VER(i915) >= 12) + idx = tgl_max_bw_index(i915, num_active_planes, qgv_point); + else + idx = icl_max_bw_index(i915, num_active_planes, qgv_point); + + if (idx >= ARRAY_SIZE(i915->display.bw.max)) + return 0; + + return i915->display.bw.max[idx].deratedbw[qgv_point]; +} + void intel_bw_init_hw(struct drm_i915_private *dev_priv) { if (!HAS_DISPLAY(dev_priv)) @@ -806,6 +822,35 @@ intel_atomic_get_bw_state(struct intel_atomic_state *state) return to_intel_bw_state(bw_state); } +static unsigned int icl_max_bw_qgv_point_mask(struct drm_i915_private *i915, + int num_active_planes) +{ + unsigned int num_qgv_points = i915->display.bw.max[0].num_qgv_points; + unsigned int max_bw_point_mask = 0; + unsigned int max_bw = 0; + int i; + + for (i = 0; i < num_qgv_points; i++) { + unsigned int max_data_rate = + icl_qgv_bw(i915, num_active_planes, i); + + /* +* We need to know which qgv point gives us +* maximum bandwidth in order to disable SAGV +* if we find that we exceed SAGV block time +* with watermarks. By that moment we already +* have those, as it is calculated earlier in +* intel_atomic_check, +*/ + if (max_data_rate > max_bw) { + max_bw_point_mask = BIT(i); + max_bw = max_data_rate; + } + } + + return max_bw_point_mask; +} + static int mtl_find_qgv_points(struct drm_i915_private *i915, unsigned int data_rate, unsigned int num_active_planes, @@ -883,8 +928,6 @@ static int icl_find_qgv_points(struct drm_i915_private *i915, const struct intel_bw_state *old_bw_state, struct intel_bw_state *new_bw_state) { - unsigned int max_bw_point = 0; - unsigned int max_bw = 0; unsigned int num_psf_gv_points = i915->display.bw.max[0].num_psf_gv_points; unsigned int num_qgv_points = i915->display.bw.max[0].num_qgv_points; u16 psf_points = 0; @@ -897,31 +940,10 @@ static int icl_find_qgv_points(struct drm_i915_private *i915, return ret; for (i = 0; i < num_qgv_points; i++) { - unsigned int idx; unsigned int max_data_rate; - if (DISPLAY_VER(i915) >= 12) - idx = tgl_max_bw_index(i915, num_active_planes, i); - else - idx = icl_max_bw_index(i915, num_active_planes, i); - - if (idx >= ARRAY_SIZE(i915->display.bw.max)) - continue; - - max_data_rate = i915->display.bw.max[idx].deratedbw[i]; + max_data_rate = icl_qgv_bw(i915, num_active_planes, i); - /* -* We need to know which qgv point gives us -* maximum bandwidth in order to disable SAGV -* if we find that we exceed SAGV block time -* with watermarks. By that moment we already -* have those, as it is calculated earlier in -* intel_atomic_check, -*/ - if (max_data_rate > max_bw) { - max_bw_point = i; - max_bw = max_data_rate; -
[PATCH v8 1/4] drm/i915: Add meaningful traces for QGV point info error handling
From: Stanislav Lisovskiy For debug purposes we need those - error path won't flood the log, however there has been already numerous cases, when due to lack of debugs, we couldn't immediately tell what was the problem on customer machine, which slowed down the investigation, requiring to get access to target device and adding those traces manually. v2: - Make the debug more generic and move it to intel_dram_detect (Gustavo Sousa) v3: - Use %u for unsigned variable in debug prints (Gustavo) Reviewed-by: Gustavo Sousa Signed-off-by: Stanislav Lisovskiy Signed-off-by: Vinod Govindapillai --- drivers/gpu/drm/i915/display/intel_bw.c | 4 +++- drivers/gpu/drm/i915/soc/intel_dram.c | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c index 7f2a50b4f494..77886cc21211 100644 --- a/drivers/gpu/drm/i915/display/intel_bw.c +++ b/drivers/gpu/drm/i915/display/intel_bw.c @@ -290,8 +290,10 @@ static int icl_get_qgv_points(struct drm_i915_private *dev_priv, struct intel_qgv_point *sp = >points[i]; ret = intel_read_qgv_point_info(dev_priv, sp, i); - if (ret) + if (ret) { + drm_dbg_kms(_priv->drm, "Could not read QGV %d info\n", i); return ret; + } drm_dbg_kms(_priv->drm, "QGV %d: DCLK=%d tRP=%d tRDPRE=%d tRAS=%d tRCD=%d tRC=%d\n", diff --git a/drivers/gpu/drm/i915/soc/intel_dram.c b/drivers/gpu/drm/i915/soc/intel_dram.c index 15492b69f698..e3287f1de774 100644 --- a/drivers/gpu/drm/i915/soc/intel_dram.c +++ b/drivers/gpu/drm/i915/soc/intel_dram.c @@ -681,6 +681,8 @@ void intel_dram_detect(struct drm_i915_private *i915) if (ret) return; + drm_dbg_kms(>drm, "Num qgv points %u\n", dram_info->num_qgv_points); + drm_dbg_kms(>drm, "DRAM channels: %u\n", dram_info->num_channels); drm_dbg_kms(>drm, "Watermark level 0 adjustment needed: %s\n", -- 2.34.1
[PATCH v8 0/4] QGV/SAGV related fixes
We have couple of customer issues, related to SAGV/QGV point calculation. Those patches contain fixes plus some additional debugs for those issues. Stanislav Lisovskiy (4): drm/i915: Add meaningful traces for QGV point info error handling drm/i915: Extract code required to calculate max qgv/psf gv point drm/i915: Disable SAGV on bw init, to force QGV point recalculation drm/i915/display: handle systems with duplicate qgv/psf gv points drivers/gpu/drm/i915/display/intel_bw.c | 139 ++- drivers/gpu/drm/i915/display/skl_watermark.c | 2 +- drivers/gpu/drm/i915/display/skl_watermark.h | 1 + drivers/gpu/drm/i915/soc/intel_dram.c| 2 + 4 files changed, 112 insertions(+), 32 deletions(-) -- 2.34.1
[PATCH v1 6/6] drm/xe/lnl: Enable the display support
From: Balasubramani Vivekanandan Enable the display support for LUNARLAKE Signed-off-by: Balasubramani Vivekanandan Signed-off-by: Lucas De Marchi Reviewed-by: Matt Roper --- drivers/gpu/drm/xe/xe_pci.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/xe/xe_pci.c b/drivers/gpu/drm/xe/xe_pci.c index 5b5c29761c5d..42ba2ea62c1e 100644 --- a/drivers/gpu/drm/xe/xe_pci.c +++ b/drivers/gpu/drm/xe/xe_pci.c @@ -333,6 +333,7 @@ static const struct xe_device_desc mtl_desc = { static const struct xe_device_desc lnl_desc = { PLATFORM(XE_LUNARLAKE), + .has_display = true, .require_force_probe = true, }; -- 2.34.1
[PATCH v1 5/6] drm/i915/xe2lpd: Load DMC
From: Balasubramani Vivekanandan Load DMC for XE2LPD. The value 0x8000 is the maximum payload size for any xe2lpd dmc firmware. Signed-off-by: Balasubramani Vivekanandan Signed-off-by: Dnyaneshwar Bhadane --- drivers/gpu/drm/i915/display/intel_dmc.c | 9 - 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_dmc.c b/drivers/gpu/drm/i915/display/intel_dmc.c index 835781624482..54c5909de293 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc.c +++ b/drivers/gpu/drm/i915/display/intel_dmc.c @@ -89,10 +89,14 @@ static struct intel_dmc *i915_to_dmc(struct drm_i915_private *i915) __stringify(major) "_" \ __stringify(minor) ".bin" +#define XE2LPD_MAX_FW_SIZE 0x8000 #define XELPDP_DMC_MAX_FW_SIZE 0x7000 #define DISPLAY_VER13_DMC_MAX_FW_SIZE 0x2 #define DISPLAY_VER12_DMC_MAX_FW_SIZE ICL_DMC_MAX_FW_SIZE +#define XE2LPD_DMC_PATHDMC_PATH(xe2lpd) +MODULE_FIRMWARE(XE2LPD_DMC_PATH); + #define MTL_DMC_PATH DMC_PATH(mtl) MODULE_FIRMWARE(MTL_DMC_PATH); @@ -987,7 +991,10 @@ void intel_dmc_init(struct drm_i915_private *i915) INIT_WORK(>work, dmc_load_work_fn); - if (DISPLAY_VER_FULL(i915) == IP_VER(14, 0)) { + if (DISPLAY_VER_FULL(i915) == IP_VER(20, 0)) { + dmc->fw_path = XE2LPD_DMC_PATH; + dmc->max_fw_size = XE2LPD_MAX_FW_SIZE; + } else if (DISPLAY_VER_FULL(i915) == IP_VER(14, 0)) { dmc->fw_path = MTL_DMC_PATH; dmc->max_fw_size = XELPDP_DMC_MAX_FW_SIZE; } else if (IS_DG2(i915)) { -- 2.34.1
[PATCH v1 4/6] drm/i915/xe2lpd: Update mbus on post plane updates
From: Stanislav Lisovskiy According to BSpec we need to write the MBUS CTL and DBUF CTL both for increasing CDCLK case (pre plane) and for decreasing CDCLK case (post plane). Make sure those updates are in place for Xe2-LPD. Since the mbus update is not only on pre-enable anymore, also rename the function accordingly. Cc: Mika Kahola Signed-off-by: Stanislav Lisovskiy Signed-off-by: Lucas De Marchi Reviewed-by: Mika Kahola --- drivers/gpu/drm/i915/display/skl_watermark.c | 7 +-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c b/drivers/gpu/drm/i915/display/skl_watermark.c index ad76db6c6ab7..1042f1c7b410 100644 --- a/drivers/gpu/drm/i915/display/skl_watermark.c +++ b/drivers/gpu/drm/i915/display/skl_watermark.c @@ -3494,7 +3494,7 @@ static int get_mbus_mdclk_cdclk_ratio(struct drm_i915_private *i915, * Configure MBUS_CTL and all DBUF_CTL_S of each slice to join_mbus state before * update the request state of all DBUS slices. */ -static void update_mbus_pre_enable(struct intel_atomic_state *state) +static void update_mbus(struct intel_atomic_state *state) { struct drm_i915_private *i915 = to_i915(state->base.dev); u32 mbus_ctl, dbuf_min_tracker_val; @@ -3553,7 +3553,7 @@ void intel_dbuf_pre_plane_update(struct intel_atomic_state *state) WARN_ON(!new_dbuf_state->base.changed); - update_mbus_pre_enable(state); + update_mbus(state); gen9_dbuf_slices_update(i915, old_dbuf_state->enabled_slices | new_dbuf_state->enabled_slices); @@ -3575,6 +3575,9 @@ void intel_dbuf_post_plane_update(struct intel_atomic_state *state) WARN_ON(!new_dbuf_state->base.changed); + if (DISPLAY_VER(i915) >= 20) + update_mbus(state); + gen9_dbuf_slices_update(i915, new_dbuf_state->enabled_slices); } -- 2.34.1
[PATCH v1 2/6] drm/i915/lnl: Add programming for CDCLK change
From: Ravi Kumar Vodapalli Add programming sequence for changes on CDCLK for Lunar Lake platforms. It's mostly the same as MTL, but with some additional programming for the squash and crawling steps when a change in mdclk/cdclk ratio is observed. v2: Remove wrong changes for bxt_cdclk_cd2x_pipe() (Matt Roper) v3: Reword commit message and flatten if/else ladder (Matt Roper) BSpec: 68864 Signed-off-by: Ravi Kumar Vodapalli Signed-off-by: Lucas De Marchi Reviewed-by: Matt Roper --- drivers/gpu/drm/i915/display/intel_cdclk.c | 46 +- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index 4d7244284efc..36fba017110d 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -40,6 +40,7 @@ #include "intel_psr.h" #include "intel_vdsc.h" #include "skl_watermark.h" +#include "skl_watermark_regs.h" #include "vlv_sideband.h" /** @@ -1860,6 +1861,47 @@ static int get_mdclk_cdclk_ratio(struct drm_i915_private *i915, return 1; } +static void lnl_prog_mbus_dbuf_ctrl(struct drm_i915_private *i915, + const struct intel_cdclk_config *cdclk_config) +{ + int min_throttle_val; + int min_tracker_state; + enum dbuf_slice slice; + int mdclk_cdclk_div_ratio; + int mbus_join = intel_de_read(i915, MBUS_CTL) & MBUS_JOIN; + + mdclk_cdclk_div_ratio = get_mdclk_cdclk_ratio(i915, cdclk_config); + + min_throttle_val = MBUS_TRANS_THROTTLE_MIN_SELECT(mdclk_cdclk_div_ratio); + + intel_de_rmw(i915, MBUS_CTL, MBUS_TRANS_THROTTLE_MIN_MASK, min_throttle_val); + + if (mbus_join) + mdclk_cdclk_div_ratio = (mdclk_cdclk_div_ratio << 1) + 1; + + min_tracker_state = DBUF_MIN_TRACKER_STATE_SERVICE(mdclk_cdclk_div_ratio); + + for_each_dbuf_slice(i915, slice) + intel_de_rmw(i915, DBUF_CTL_S(slice), +DBUF_MIN_TRACKER_STATE_SERVICE_MASK, +min_tracker_state); +} + +static void lnl_cdclk_squash_program(struct drm_i915_private *i915, +const struct intel_cdclk_config *cdclk_config, +u16 waveform) +{ + if (cdclk_config->cdclk < i915->display.cdclk.hw.cdclk) + /* Program mbus_ctrl and dbuf_ctrl registers as Pre hook */ + lnl_prog_mbus_dbuf_ctrl(i915, cdclk_config); + + dg2_cdclk_squash_program(i915, waveform); + + if (cdclk_config->cdclk > i915->display.cdclk.hw.cdclk) + /* Program mbus_ctrl and dbuf_ctrl registers as Post hook */ + lnl_prog_mbus_dbuf_ctrl(i915, cdclk_config); +} + static bool cdclk_compute_crawl_and_squash_midpoint(struct drm_i915_private *i915, const struct intel_cdclk_config *old_cdclk_config, const struct intel_cdclk_config *new_cdclk_config, @@ -1994,7 +2036,9 @@ static void _bxt_set_cdclk(struct drm_i915_private *dev_priv, waveform = cdclk_squash_waveform(dev_priv, cdclk); - if (HAS_CDCLK_SQUASH(dev_priv)) + if (DISPLAY_VER(dev_priv) >= 20) + lnl_cdclk_squash_program(dev_priv, cdclk_config, waveform); + else if (HAS_CDCLK_SQUASH(dev_priv)) dg2_cdclk_squash_program(dev_priv, waveform); intel_de_write(dev_priv, CDCLK_CTL, bxt_cdclk_ctl(dev_priv, cdclk_config, pipe)); -- 2.34.1
[PATCH v1 3/6] drm/i915/xe2lpd: Write DBuf after CDCLK change in post plane
From: Stanislav Lisovskiy Previously we always updated DBuf MBUS CTL and DBUF CTL regs after CDCLK has been changed(CDCLK_CTL), however for Xe2-LPD we can't do like that anymore. According to BSpec, we have to first update DBuf regs and then write CDCLK regs, when CDCLK is decreased, which we do in post plane. So now we do CDCLK post plane update only after DBuf regs are written (CDCLK/MDCLK separation requires MDCLK/CDCLK ratio to be written to DBuf regs). Cc: Mika Kahola Signed-off-by: Stanislav Lisovskiy Signed-off-by: Lucas De Marchi Reviewed-by: Mika Kahola --- drivers/gpu/drm/i915/display/intel_display.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 00ac65a14029..4d8d32741a4f 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -7160,7 +7160,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state) /* Now enable the clocks, plane, pipe, and connectors that we set up. */ dev_priv->display.funcs.display->commit_modeset_enables(state); - if (state->modeset) + if (state->modeset && DISPLAY_VER(dev_priv) < 20) intel_set_cdclk_post_plane_update(state); intel_wait_for_vblank_workers(state); @@ -7208,6 +7208,9 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state) intel_dbuf_post_plane_update(state); + if (state->modeset && DISPLAY_VER(dev_priv) >= 20) + intel_set_cdclk_post_plane_update(state); + for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { intel_post_plane_update(state, crtc); -- 2.34.1
[PATCH v1 1/6] drm/i915/lnl: Introduce MDCLK_CDCLK ratio to DBuf
From: Stanislav Lisovskiy When we change MDCLK/CDCLK the BSpec now instructs us to write a ratio between MDCLK/CDCLK to MBUS CTL and DBUF CTL registers during that change. Previsouly DBuf state and CDCLK were not anyhow coupled together. Now at compute stage when we know which CDCLK/MDCLK we are going to use, we need to update the DBuf state with that ratio, being properly encoded, so that it gets written to those registers, once DBuf state is being update. The criteria for updating DBuf state is also a CDCLK/MDCLK ratio change now. v2: - Remove condition check for display version 20 since it's compatible with previous versions (Matt Roper) - Squash the serialization of global state when mdclk_cdclk_ratio changes Bspec: 68864, 69482, 69445 Cc: Mika Kahola Signed-off-by: Stanislav Lisovskiy Signed-off-by: Lucas De Marchi Signed-off-by: Vinod Govindapillai --- drivers/gpu/drm/i915/display/intel_cdclk.c| 28 +++ drivers/gpu/drm/i915/display/skl_watermark.c | 28 --- drivers/gpu/drm/i915/display/skl_watermark.h | 1 + .../gpu/drm/i915/display/skl_watermark_regs.h | 2 ++ 4 files changed, 55 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index 30dae4fef6cb..4d7244284efc 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -39,6 +39,7 @@ #include "intel_pcode.h" #include "intel_psr.h" #include "intel_vdsc.h" +#include "skl_watermark.h" #include "vlv_sideband.h" /** @@ -1849,6 +1850,16 @@ static bool cdclk_pll_is_unknown(unsigned int vco) return vco == ~0; } +/* Return the MBUS_CTL's encoding of the mdclk/cdclk ratio */ +static int get_mdclk_cdclk_ratio(struct drm_i915_private *i915, +const struct intel_cdclk_config *cdclk_config) +{ + if (DISPLAY_VER(i915) >= 20) + return DIV_ROUND_UP(cdclk_config->vco, cdclk_config->cdclk) - 1; + + return 1; +} + static bool cdclk_compute_crawl_and_squash_midpoint(struct drm_i915_private *i915, const struct intel_cdclk_config *old_cdclk_config, const struct intel_cdclk_config *new_cdclk_config, @@ -2761,6 +2772,8 @@ static int intel_compute_min_cdclk(struct intel_cdclk_state *cdclk_state) struct intel_crtc_state *crtc_state; int min_cdclk, i; enum pipe pipe; + struct intel_dbuf_state *new_dbuf_state; + struct intel_dbuf_state *old_dbuf_state; for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) { int ret; @@ -2794,6 +2807,21 @@ static int intel_compute_min_cdclk(struct intel_cdclk_state *cdclk_state) } } + new_dbuf_state = intel_atomic_get_new_dbuf_state(state); + old_dbuf_state = intel_atomic_get_old_dbuf_state(state); + if (new_dbuf_state && old_dbuf_state) { + new_dbuf_state->mdclk_cdclk_ratio = + get_mdclk_cdclk_ratio(dev_priv, _state->actual); + + if (new_dbuf_state->mdclk_cdclk_ratio != old_dbuf_state->mdclk_cdclk_ratio) { + int ret; + + ret = intel_atomic_serialize_global_state(_dbuf_state->base); + if (ret) + return ret; + } + } + min_cdclk = max(cdclk_state->force_min_cdclk, cdclk_state->bw_min_cdclk); for_each_pipe(dev_priv, pipe) diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c b/drivers/gpu/drm/i915/display/skl_watermark.c index 614f319d754e..ad76db6c6ab7 100644 --- a/drivers/gpu/drm/i915/display/skl_watermark.c +++ b/drivers/gpu/drm/i915/display/skl_watermark.c @@ -3480,6 +3480,16 @@ int intel_dbuf_init(struct drm_i915_private *i915) return 0; } +static int get_mbus_mdclk_cdclk_ratio(struct drm_i915_private *i915, + int mdclk_cdclk_ratio, + int mbus_joined) +{ + if (mbus_joined) + return (mdclk_cdclk_ratio << 1) + 1; + + return mdclk_cdclk_ratio; +} + /* * Configure MBUS_CTL and all DBUF_CTL_S of each slice to join_mbus state before * update the request state of all DBUS slices. @@ -3491,10 +3501,16 @@ static void update_mbus_pre_enable(struct intel_atomic_state *state) enum dbuf_slice slice; const struct intel_dbuf_state *dbuf_state = intel_atomic_get_new_dbuf_state(state); + int tracker_state_service; if (!HAS_MBUS_JOINING(i915)) return; + tracker_state_service = + get_mbus_mdclk_cdclk_ratio(i915, + dbu
[PATCH v1 0/6] LNL display
Rest of the cdclk patches as well as the patches to enable the display in LNL Balasubramani Vivekanandan (2): drm/i915/xe2lpd: Load DMC drm/xe/lnl: Enable the display support Ravi Kumar Vodapalli (1): drm/i915/lnl: Add programming for CDCLK change Stanislav Lisovskiy (3): drm/i915/lnl: Introduce MDCLK_CDCLK ratio to DBuf drm/i915/xe2lpd: Write DBuf after CDCLK change in post plane drm/i915/xe2lpd: Update mbus on post plane updates drivers/gpu/drm/i915/display/intel_cdclk.c| 74 ++- drivers/gpu/drm/i915/display/intel_display.c | 5 +- drivers/gpu/drm/i915/display/intel_dmc.c | 9 ++- drivers/gpu/drm/i915/display/skl_watermark.c | 35 +++-- drivers/gpu/drm/i915/display/skl_watermark.h | 1 + .../gpu/drm/i915/display/skl_watermark_regs.h | 2 + drivers/gpu/drm/xe/xe_pci.c | 1 + 7 files changed, 118 insertions(+), 9 deletions(-) -- 2.34.1
[PATCH v1 2/2] drm/xe: Modify the cfb size to be page size aligned for FBC
drm_gem_private_object_init expect the object size be page size aligned. The xe_bo create functions do not update the size for any alignment requirements. So align cfb size to be page size aligned in xe stolen memory handling. Signed-off-by: Vinod Govindapillai --- drivers/gpu/drm/xe/compat-i915-headers/i915_gem_stolen.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/xe/compat-i915-headers/i915_gem_stolen.h b/drivers/gpu/drm/xe/compat-i915-headers/i915_gem_stolen.h index 888e7a87a925..bd233007c1b7 100644 --- a/drivers/gpu/drm/xe/compat-i915-headers/i915_gem_stolen.h +++ b/drivers/gpu/drm/xe/compat-i915-headers/i915_gem_stolen.h @@ -19,6 +19,9 @@ static inline int i915_gem_stolen_insert_node_in_range(struct xe_device *xe, int err; u32 flags = XE_BO_CREATE_PINNED_BIT | XE_BO_CREATE_STOLEN_BIT; + if (align) + size = ALIGN(size, align); + bo = xe_bo_create_locked_range(xe, xe_device_get_root_tile(xe), NULL, size, start, end, ttm_bo_type_kernel, flags); -- 2.34.1
[PATCH v1 1/2] drm/i915/display: use PAGE_SIZE macro for FBC cfb alloc
FBC compressed frame buffer size need to be PAGE_SIZE aligned and the corresponding the drm_gem functions check the object size alignment using PAGE_SIZE macro. Use the PAGE_SIZE macro in the cfb alloc as well instead of the magic number. Signed-off-by: Vinod Govindapillai --- drivers/gpu/drm/i915/display/intel_fbc.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c index f17a1afb4929..9b9c8715d664 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.c +++ b/drivers/gpu/drm/i915/display/intel_fbc.c @@ -764,13 +764,15 @@ static int find_compression_limit(struct intel_fbc *fbc, /* Try to over-allocate to reduce reallocations and fragmentation. */ ret = i915_gem_stolen_insert_node_in_range(i915, >compressed_fb, - size <<= 1, 4096, 0, end); + size <<= 1, PAGE_SIZE, 0, + end); if (ret == 0) return limit; for (; limit <= intel_fbc_max_limit(i915); limit <<= 1) { ret = i915_gem_stolen_insert_node_in_range(i915, >compressed_fb, - size >>= 1, 4096, 0, end); + size >>= 1, PAGE_SIZE, 0, + end); if (ret == 0) return limit; } -- 2.34.1
[PATCH v1 0/2] drm/xe: ensure fbc cfb size to be page size aligned
DRM gem object handling expet the object size to be page size aligned. Neither the driver or xe stolen memory handlers do that causing BUG_ON being triggered in some cases. Vinod Govindapillai (2): drm/i915/display: use PAGE_SIZE macro for FBC cfb alloc drm/xe: Modify the cfb size to be page size aligned for FBC drivers/gpu/drm/i915/display/intel_fbc.c | 6 -- drivers/gpu/drm/xe/compat-i915-headers/i915_gem_stolen.h | 3 +++ 2 files changed, 7 insertions(+), 2 deletions(-) -- 2.34.1
[Intel-gfx] [PATCH v4 1/1] drm/i915/xe2lpd: implement WA for underruns while enabling FBC
FIFO underruns are observed when FBC is enabled on plane 2 or plane 3. Recommended WA is to update the FBC enabling sequence. The plane binding register bits need to be updated separately before programming the FBC enable bit. Bspec: 74151 Reviewed-by: Mika Kahola #v3 Signed-off-by: Vinod Govindapillai --- drivers/gpu/drm/i915/display/intel_fbc.c | 8 +++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c index bde12fe62275..b73cf1c5ba33 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.c +++ b/drivers/gpu/drm/i915/display/intel_fbc.c @@ -608,6 +608,7 @@ static u32 ivb_dpfc_ctl(struct intel_fbc *fbc) static void ivb_fbc_activate(struct intel_fbc *fbc) { struct drm_i915_private *i915 = fbc->i915; + u32 dpfc_ctl; if (DISPLAY_VER(i915) >= 10) glk_fbc_program_cfb_stride(fbc); @@ -617,8 +618,13 @@ static void ivb_fbc_activate(struct intel_fbc *fbc) if (intel_gt_support_legacy_fencing(to_gt(i915))) snb_fbc_program_fence(fbc); + /* wa_14019417088 Alternative WA*/ + dpfc_ctl = ivb_dpfc_ctl(fbc); + if (DISPLAY_VER(i915) >= 20) + intel_de_write(i915, ILK_DPFC_CONTROL(fbc->id), dpfc_ctl); + intel_de_write(i915, ILK_DPFC_CONTROL(fbc->id), - DPFC_CTL_EN | ivb_dpfc_ctl(fbc)); + DPFC_CTL_EN | dpfc_ctl); } static bool ivb_fbc_is_compressing(struct intel_fbc *fbc) -- 2.34.1
[Intel-gfx] [PATCH v4 0/1] drm/i915/xe2lpd: WA for underruns during FBC enable
Update the FBC enabling sequence. The plane binding register bits need to programmed before fbc enable bit. v2: update the patch subject and description as this underrun is not tied to PSR. FIFO underruns are observed when FBC is enabled on planes 2 or 3. v3: Updated the comments and removed reference to PSR from the comments Added reference to HSD v4: updated the comments to include wa number Vinod Govindapillai (1): drm/i915/xe2lpd: implement WA for underruns while enabling FBC drivers/gpu/drm/i915/display/intel_fbc.c | 8 +++- 1 file changed, 7 insertions(+), 1 deletion(-) -- 2.34.1
[Intel-gfx] [PATCH v1 1/1] drm/i915/xe2lpd: remove the FBC restriction if PSR2 is enabled
In earlier versions, FBC was restricted if PSR2 is enabled. From xe2lpd onwards no such restrictions are needed anymore. HSD: 14014305387 Signed-off-by: Vinod Govindapillai --- drivers/gpu/drm/i915/display/intel_fbc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c index bde12fe62275..f3d572d54e82 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.c +++ b/drivers/gpu/drm/i915/display/intel_fbc.c @@ -1201,7 +1201,7 @@ static int intel_fbc_check_plane(struct intel_atomic_state *state, * Recommendation is to keep this combination disabled * Bspec: 50422 HSD: 14010260002 */ - if (DISPLAY_VER(i915) >= 12 && crtc_state->has_psr2) { + if (IS_DISPLAY_VER(i915, 12, 14) && crtc_state->has_psr2) { plane_state->no_fbc_reason = "PSR2 enabled"; return 0; } -- 2.34.1
[Intel-gfx] [PATCH v1 0/1] drm/i915/xe2lpd: remove FBC restriction if PSR2 is enabled
FBC restriction when PSR2 is enabled can be removed in xe2lpd Vinod Govindapillai (1): drm/i915/xe2lpd: remove the FBC restriction if PSR2 is enabled drivers/gpu/drm/i915/display/intel_fbc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) -- 2.34.1
[Intel-gfx] [PATCH v3 1/1] drm/i915/xe2lpd: implement WA for underruns while enabling FBC
FIFO underruns are observed when FBC is enabled on plane 2 or 3. This is root caused to a HW bug and the recommended WA is to update the FBC enabling sequence. The plane binding register bits need to be updated separately before programming the FBC enable bit. HSD: 16021232047 Signed-off-by: Vinod Govindapillai --- drivers/gpu/drm/i915/display/intel_fbc.c | 13 - 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c index bde12fe62275..8a3594e4d992 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.c +++ b/drivers/gpu/drm/i915/display/intel_fbc.c @@ -608,6 +608,7 @@ static u32 ivb_dpfc_ctl(struct intel_fbc *fbc) static void ivb_fbc_activate(struct intel_fbc *fbc) { struct drm_i915_private *i915 = fbc->i915; + u32 dpfc_ctl; if (DISPLAY_VER(i915) >= 10) glk_fbc_program_cfb_stride(fbc); @@ -617,8 +618,18 @@ static void ivb_fbc_activate(struct intel_fbc *fbc) if (intel_gt_support_legacy_fencing(to_gt(i915))) snb_fbc_program_fence(fbc); + /* +* xe2lpd: WA for FIFO underruns while enabling FBC on planes 2 or 3 +* 1.Write FBC_CTL with Plane binding set correctly with FBC enable = 0 +* 2.Write FBC_CTL with Plane binding set correctly with FBC enable = 1 +* HSD: 16021232047 +*/ + dpfc_ctl = ivb_dpfc_ctl(fbc); + if (DISPLAY_VER(i915) >= 20) + intel_de_write(i915, ILK_DPFC_CONTROL(fbc->id), dpfc_ctl); + intel_de_write(i915, ILK_DPFC_CONTROL(fbc->id), - DPFC_CTL_EN | ivb_dpfc_ctl(fbc)); + DPFC_CTL_EN | dpfc_ctl); } static bool ivb_fbc_is_compressing(struct intel_fbc *fbc) -- 2.34.1
[Intel-gfx] [PATCH v3 0/1] drm/i915/xe2lpd: WA for underruns during FBC enable
Update the FBC enabling sequence. The plane binding register bits need to programmed before fbe enable bit. v2: update the patch subject and description as this underrun is not tied to PSR. FIFO underruns are observed when FBC is enabled on planes 2 or 3. v2: Updated the comments and removed reference to PSR from the comments Added reference to HSD Vinod Govindapillai (1): drm/i915/xe2lpd: implement WA for underruns while enabling FBC drivers/gpu/drm/i915/display/intel_fbc.c | 13 - 1 file changed, 12 insertions(+), 1 deletion(-) -- 2.34.1
[Intel-gfx] [PATCH v2 1/1] drm/i915/xe2lpd: implement WA for underruns while enabling FBC
Because of HW bug, the FBC enabling sequence need to be updated. The plane binding registrer need to be updated before programming the FBC enable bit. Signed-off-by: Vinod Govindapillai --- drivers/gpu/drm/i915/display/intel_fbc.c | 12 +++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c index bde12fe62275..b9cd92a997cd 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.c +++ b/drivers/gpu/drm/i915/display/intel_fbc.c @@ -608,6 +608,7 @@ static u32 ivb_dpfc_ctl(struct intel_fbc *fbc) static void ivb_fbc_activate(struct intel_fbc *fbc) { struct drm_i915_private *i915 = fbc->i915; + u32 dpfc_ctl; if (DISPLAY_VER(i915) >= 10) glk_fbc_program_cfb_stride(fbc); @@ -617,8 +618,17 @@ static void ivb_fbc_activate(struct intel_fbc *fbc) if (intel_gt_support_legacy_fencing(to_gt(i915))) snb_fbc_program_fence(fbc); + /* +* Alternate WA for HW bug with PSR2 + FBC. +* 1.Write FBC_CTL with Plane binding set correctly with FBC enable = 0 +* 2.Write FBC_CTL with Plane binding set correctly with FBC enable = 1 +*/ + dpfc_ctl = ivb_dpfc_ctl(fbc); + if (DISPLAY_VER(i915) >= 20) + intel_de_write(i915, ILK_DPFC_CONTROL(fbc->id), dpfc_ctl); + intel_de_write(i915, ILK_DPFC_CONTROL(fbc->id), - DPFC_CTL_EN | ivb_dpfc_ctl(fbc)); + DPFC_CTL_EN | dpfc_ctl); } static bool ivb_fbc_is_compressing(struct intel_fbc *fbc) -- 2.34.1
[Intel-gfx] [PATCH v2 0/1] drm/i915/xe2lpd: WA for underruns during FBC enable
Update the FBC enabling sequence. The plane binding register bits need to programmed before fbe enable bit. v2: update the patch subject and description as this underrun is not tied to PSR. FIFO underruns are observed when FBC is enabled on plane other than the primary. Vinod Govindapillai (1): drm/i915/xe2lpd: implement WA for underruns while enabling FBC drivers/gpu/drm/i915/display/intel_fbc.c | 12 +++- 1 file changed, 11 insertions(+), 1 deletion(-) -- 2.34.1
[Intel-gfx] [PATCH v1 1/1] drm/i915/xe2lpd: alternate WA for underruns with PSR2 and FBC
Implement the alternate WA for the underruns when both PSR2 and FBC is enabled. Signed-off-by: Vinod Govindapillai --- drivers/gpu/drm/i915/display/intel_fbc.c | 12 +++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c index bde12fe62275..b9cd92a997cd 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.c +++ b/drivers/gpu/drm/i915/display/intel_fbc.c @@ -608,6 +608,7 @@ static u32 ivb_dpfc_ctl(struct intel_fbc *fbc) static void ivb_fbc_activate(struct intel_fbc *fbc) { struct drm_i915_private *i915 = fbc->i915; + u32 dpfc_ctl; if (DISPLAY_VER(i915) >= 10) glk_fbc_program_cfb_stride(fbc); @@ -617,8 +618,17 @@ static void ivb_fbc_activate(struct intel_fbc *fbc) if (intel_gt_support_legacy_fencing(to_gt(i915))) snb_fbc_program_fence(fbc); + /* +* Alternate WA for HW bug with PSR2 + FBC. +* 1.Write FBC_CTL with Plane binding set correctly with FBC enable = 0 +* 2.Write FBC_CTL with Plane binding set correctly with FBC enable = 1 +*/ + dpfc_ctl = ivb_dpfc_ctl(fbc); + if (DISPLAY_VER(i915) >= 20) + intel_de_write(i915, ILK_DPFC_CONTROL(fbc->id), dpfc_ctl); + intel_de_write(i915, ILK_DPFC_CONTROL(fbc->id), - DPFC_CTL_EN | ivb_dpfc_ctl(fbc)); + DPFC_CTL_EN | dpfc_ctl); } static bool ivb_fbc_is_compressing(struct intel_fbc *fbc) -- 2.34.1
[Intel-gfx] [PATCH v1 0/1] drm/i915/xe2lpd: alternate WA for underruns with PSR2 and FBC
Implement the alternate WA for the underruns when both PSR2 and FBC is enabled. Vinod Govindapillai (1): drm/i915/xe2lpd: alternate WA for underruns with PSR2 and FBC drivers/gpu/drm/i915/display/intel_fbc.c | 12 +++- 1 file changed, 11 insertions(+), 1 deletion(-) -- 2.34.1
[Intel-gfx] [PATCH v1 0/2] drm/i915/xe2lpd: choose between PSR2 and FBC
In devices with PSR2 + FBC support, choose between PSR2 selective fetch and FBC based on the better power saving efficiency Vinod Govindapillai (2): drm/i915/xe2lpd: check selective fetch is optimal in some cases drm/i915/xe2lpd: prefer FBC for full frame fetch in PSR2 .../drm/i915/display/intel_display_types.h| 1 + drivers/gpu/drm/i915/display/intel_fbc.c | 11 - drivers/gpu/drm/i915/display/intel_psr.c | 42 --- 3 files changed, 47 insertions(+), 7 deletions(-) -- 2.34.1
[Intel-gfx] [PATCH v1 2/2] drm/i915/xe2lpd: prefer FBC for full frame fetch in PSR2
If the selective fetch is not optimal, use FBC Bspec: 68881 Signed-off-by: Vinod Govindapillai --- drivers/gpu/drm/i915/display/intel_fbc.c | 11 +-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c index bde12fe62275..1c32d85dc688 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.c +++ b/drivers/gpu/drm/i915/display/intel_fbc.c @@ -1202,8 +1202,15 @@ static int intel_fbc_check_plane(struct intel_atomic_state *state, * Bspec: 50422 HSD: 14010260002 */ if (DISPLAY_VER(i915) >= 12 && crtc_state->has_psr2) { - plane_state->no_fbc_reason = "PSR2 enabled"; - return 0; + if (DISPLAY_VER(i915) >= 20) + plane_state->no_fbc_reason = + crtc_state->full_frame_fetch ? NULL : + "PSR2 selective fetch enabled"; + else + plane_state->no_fbc_reason = "PSR2 enabled"; + + if (plane_state->no_fbc_reason) + return 0; } /* Wa_14016291713 */ -- 2.34.1
[Intel-gfx] [PATCH v1 1/2] drm/i915/xe2lpd: check selective fetch is optimal in some cases
If both PSR2 + FBC is supported, in cases where the selective fetch area is greater than 25% of the screen area, FBC might be more efficient. So have a possibility to check this and add provision to enable FBC in such cases. Bspec: 68881 Signed-off-by: Vinod Govindapillai --- .../drm/i915/display/intel_display_types.h| 1 + drivers/gpu/drm/i915/display/intel_psr.c | 42 --- 2 files changed, 38 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 047fe3f8905a..bcc5fd8d8a00 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -1207,6 +1207,7 @@ struct intel_crtc_state { bool has_psr; bool has_psr2; bool enable_psr2_sel_fetch; + bool full_frame_fetch; bool req_psr2_sdp_prior_scanline; bool wm_level_disabled; u32 dc3co_exitline; diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index ecd24a0b86cb..6cb32fd29d10 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -1987,10 +1987,35 @@ static bool psr2_sel_fetch_pipe_state_supported(const struct intel_crtc_state *c return true; } +/* + * Check selective fetch is optimum + * + * Compare selective fetch area w.r.t screen size in case both FBC and PSR2 + * is supported. If the selective fetch area is more than 25% of screen + * size, FBC is might be more efficient than PSR2. So force full frame + * update. + */ +static bool psr2_sel_fetch_not_optimal(struct drm_i915_private *i915, + struct drm_rect *sel_fetch, + struct drm_rect *src) +{ + int screen_area, selfetch_area; + + /* This is needed where FBC + PSR can be supported */ + if (DISPLAY_VER(i915) < 20 || !i915->display.params.enable_fbc || + !HAS_FBC(i915)) + return false; + + selfetch_area = drm_rect_height(sel_fetch) * drm_rect_width(sel_fetch); + screen_area = drm_rect_height(src) * drm_rect_width(src); + + return DIV_ROUND_CLOSEST(screen_area, selfetch_area) <= 4; +} + int intel_psr2_sel_fetch_update(struct intel_atomic_state *state, struct intel_crtc *crtc) { - struct drm_i915_private *dev_priv = to_i915(state->base.dev); + struct drm_i915_private *i915 = to_i915(state->base.dev); struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc); struct drm_rect pipe_clip = { .x1 = 0, .y1 = -1, .x2 = INT_MAX, .y2 = -1 }; struct intel_plane_state *new_plane_state, *old_plane_state; @@ -2082,7 +2107,7 @@ int intel_psr2_sel_fetch_update(struct intel_atomic_state *state, * calculation for those. */ if (pipe_clip.y1 == -1) { - drm_info_once(_priv->drm, + drm_info_once(>drm, "Selective fetch area calculation failed in pipe %c\n", pipe_name(crtc->pipe)); full_update = true; @@ -2092,9 +2117,9 @@ int intel_psr2_sel_fetch_update(struct intel_atomic_state *state, goto skip_sel_fetch_set_loop; /* Wa_14014971492 */ - if ((IS_DISPLAY_IP_STEP(dev_priv, IP_VER(14, 0), STEP_A0, STEP_B0) || -IS_ALDERLAKE_P(dev_priv) || IS_TIGERLAKE(dev_priv)) && - crtc_state->splitter.enable) + if ((IS_DISPLAY_IP_STEP(i915, IP_VER(14, 0), STEP_A0, STEP_B0) || +IS_ALDERLAKE_P(i915) || IS_TIGERLAKE(i915)) && +crtc_state->splitter.enable) pipe_clip.y1 = 0; ret = drm_atomic_add_affected_planes(>base, >base); @@ -2149,7 +2174,14 @@ int intel_psr2_sel_fetch_update(struct intel_atomic_state *state, } } + if (full_update) + goto skip_sel_fetch_set_loop; + + full_update = psr2_sel_fetch_not_optimal(i915, _clip, +_state->pipe_src); + skip_sel_fetch_set_loop: + crtc_state->full_frame_fetch = full_update; psr2_man_trk_ctl_calc(crtc_state, _clip, full_update); return 0; } -- 2.34.1
[Intel-gfx] [PATCH v4 0/2] display device info as a separate debugfs entry
Expose the display device info as a separate debugfs entry to list out display device info and remove the same from i915_capabilities v2: rename the debugs entry to i915_display_capabilities and patch description changes v3: Exclude the patch to remove display device and runtime info from i915_capabilities from this patch series. Remove this only after IGT starts using the i915_display_capabilities v4: Add back the patch to remove the display info from i915_capabilities and use test with tag to combine the IGT and kernel changes Test-with: 20231018063537.140125-1-swati2.sha...@intel.com Vinod Govindapillai (2): drm/i915/display: debugfs entry to list display capabilities drm/i915: remove display device info from i915 capabilities drivers/gpu/drm/i915/display/intel_display_debugfs.c | 12 drivers/gpu/drm/i915/i915_debugfs.c | 1 - 2 files changed, 12 insertions(+), 1 deletion(-) -- 2.34.1
[Intel-gfx] [PATCH v4 1/2] drm/i915/display: debugfs entry to list display capabilities
Create a separate debugfs entry to list the display capabilities IGT can rely on this debugfs entry for tests that depend on display device and display runtime info for both xe and i915 drivers. v2: rename the entry to i915_display_capabilities (Chaitanya) Signed-off-by: Vinod Govindapillai --- drivers/gpu/drm/i915/display/intel_display_debugfs.c | 12 1 file changed, 12 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c index fbe75d47a165..b0248dfa8dea 100644 --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c @@ -641,6 +641,17 @@ static int i915_display_info(struct seq_file *m, void *unused) return 0; } +static int i915_display_capabilities(struct seq_file *m, void *unused) +{ + struct drm_i915_private *i915 = node_to_i915(m->private); + struct drm_printer p = drm_seq_file_printer(m); + + intel_display_device_info_print(DISPLAY_INFO(i915), + DISPLAY_RUNTIME_INFO(i915), ); + + return 0; +} + static int i915_shared_dplls_info(struct seq_file *m, void *unused) { struct drm_i915_private *dev_priv = node_to_i915(m->private); @@ -1059,6 +1070,7 @@ static const struct drm_info_list intel_display_debugfs_list[] = { {"i915_gem_framebuffer", i915_gem_framebuffer_info, 0}, {"i915_power_domain_info", i915_power_domain_info, 0}, {"i915_display_info", i915_display_info, 0}, + {"i915_display_capabilities", i915_display_capabilities, 0}, {"i915_shared_dplls_info", i915_shared_dplls_info, 0}, {"i915_dp_mst_info", i915_dp_mst_info, 0}, {"i915_ddb_info", i915_ddb_info, 0}, -- 2.34.1
[Intel-gfx] [PATCH v4 2/2] drm/i915: remove display device info from i915 capabilities
Display device and display runtime info is exposed as part of i915_display_capabilities debugfs entry. Remove this information from i915_ capabilities as it is now reduntant. Signed-off-by: Vinod Govindapillai --- drivers/gpu/drm/i915/i915_debugfs.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index e9b79c2c37d8..bb48feb3b12e 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -67,7 +67,6 @@ static int i915_capabilities(struct seq_file *m, void *data) seq_printf(m, "pch: %d\n", INTEL_PCH_TYPE(i915)); intel_device_info_print(INTEL_INFO(i915), RUNTIME_INFO(i915), ); - intel_display_device_info_print(DISPLAY_INFO(i915), DISPLAY_RUNTIME_INFO(i915), ); i915_print_iommu_status(i915, ); intel_gt_info_print(_gt(i915)->info, ); intel_driver_caps_print(>caps, ); -- 2.34.1
[Intel-gfx] [PATCH v3 1/1] drm/i915/display: debugfs entry to list display capabilities
Create a separate debugfs entry to list the display capabilities IGT can rely on this debugfs entry for tests that depend on display device and display runtime info for both xe and i915 drivers. v2: rename the entry to i915_display_capabilities (Chaitanya) Signed-off-by: Vinod Govindapillai --- drivers/gpu/drm/i915/display/intel_display_debugfs.c | 12 1 file changed, 12 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c index fbe75d47a165..b0248dfa8dea 100644 --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c @@ -641,6 +641,17 @@ static int i915_display_info(struct seq_file *m, void *unused) return 0; } +static int i915_display_capabilities(struct seq_file *m, void *unused) +{ + struct drm_i915_private *i915 = node_to_i915(m->private); + struct drm_printer p = drm_seq_file_printer(m); + + intel_display_device_info_print(DISPLAY_INFO(i915), + DISPLAY_RUNTIME_INFO(i915), ); + + return 0; +} + static int i915_shared_dplls_info(struct seq_file *m, void *unused) { struct drm_i915_private *dev_priv = node_to_i915(m->private); @@ -1059,6 +1070,7 @@ static const struct drm_info_list intel_display_debugfs_list[] = { {"i915_gem_framebuffer", i915_gem_framebuffer_info, 0}, {"i915_power_domain_info", i915_power_domain_info, 0}, {"i915_display_info", i915_display_info, 0}, + {"i915_display_capabilities", i915_display_capabilities, 0}, {"i915_shared_dplls_info", i915_shared_dplls_info, 0}, {"i915_dp_mst_info", i915_dp_mst_info, 0}, {"i915_ddb_info", i915_ddb_info, 0}, -- 2.34.1
[Intel-gfx] [PATCH v3 0/1] display device info as a separate debugfs entry
Expose the display device info as a separate debugfs entry to list out display device info and remove the same from i915_capabilities v2: rename the debugs entry to i915_display_capabilities and patch description changes v3: Exclude the patch to remove display device and runtime info from i915_capabilities from this patch series. Remove this only after IGT starts using the i915_display_capabilities Vinod Govindapillai (1): drm/i915/display: debugfs entry to list display capabilities drivers/gpu/drm/i915/display/intel_display_debugfs.c | 12 1 file changed, 12 insertions(+) -- 2.34.1
[Intel-gfx] [PATCH v2 1/2] drm/i915/display: debugfs entry to list display capabilities
Create a separate debugfs entry to list the display capabilities IGT can rely on this debugfs entry for tests that depend on display device and display runtime info for both xe and i915 drivers. v2: rename the entry to i915_display_capabilities (Chaitanya) Signed-off-by: Vinod Govindapillai --- drivers/gpu/drm/i915/display/intel_display_debugfs.c | 12 1 file changed, 12 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c index fbe75d47a165..b0248dfa8dea 100644 --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c @@ -641,6 +641,17 @@ static int i915_display_info(struct seq_file *m, void *unused) return 0; } +static int i915_display_capabilities(struct seq_file *m, void *unused) +{ + struct drm_i915_private *i915 = node_to_i915(m->private); + struct drm_printer p = drm_seq_file_printer(m); + + intel_display_device_info_print(DISPLAY_INFO(i915), + DISPLAY_RUNTIME_INFO(i915), ); + + return 0; +} + static int i915_shared_dplls_info(struct seq_file *m, void *unused) { struct drm_i915_private *dev_priv = node_to_i915(m->private); @@ -1059,6 +1070,7 @@ static const struct drm_info_list intel_display_debugfs_list[] = { {"i915_gem_framebuffer", i915_gem_framebuffer_info, 0}, {"i915_power_domain_info", i915_power_domain_info, 0}, {"i915_display_info", i915_display_info, 0}, + {"i915_display_capabilities", i915_display_capabilities, 0}, {"i915_shared_dplls_info", i915_shared_dplls_info, 0}, {"i915_dp_mst_info", i915_dp_mst_info, 0}, {"i915_ddb_info", i915_ddb_info, 0}, -- 2.34.1
[Intel-gfx] [PATCH v2 2/2] drm/i915: remove display device info from i915 capabilities
Display device and display runtime info is exposed as part of i915_display_capabilities debugfs entry. Remove this information from i915_ capabilities as it is now reduntant. Signed-off-by: Vinod Govindapillai --- drivers/gpu/drm/i915/i915_debugfs.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index e9b79c2c37d8..bb48feb3b12e 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -67,7 +67,6 @@ static int i915_capabilities(struct seq_file *m, void *data) seq_printf(m, "pch: %d\n", INTEL_PCH_TYPE(i915)); intel_device_info_print(INTEL_INFO(i915), RUNTIME_INFO(i915), ); - intel_display_device_info_print(DISPLAY_INFO(i915), DISPLAY_RUNTIME_INFO(i915), ); i915_print_iommu_status(i915, ); intel_gt_info_print(_gt(i915)->info, ); intel_driver_caps_print(>caps, ); -- 2.34.1
[Intel-gfx] [PATCH v2 0/2] display device info as a separate debugfs entry
Expose the display device info as a separate debugfs entry to list out display device info and remove the same from i915_capabilities v2: rename the debugs entry to i915_display_capabilities and patch description changes Vinod Govindapillai (2): drm/i915/display: debugfs entry to list display capabilities drm/i915: remove display device info from i915 capabilities drivers/gpu/drm/i915/display/intel_display_debugfs.c | 12 drivers/gpu/drm/i915/i915_debugfs.c | 1 - 2 files changed, 12 insertions(+), 1 deletion(-) -- 2.34.1
[Intel-gfx] [PATCH v1 2/2] drm/i915: remove display device info from i915 capabilities
Display device info is exposed as a separate debugfs entry. So remove the duplicate entries from i915_capabilities debugfs Signed-off-by: Vinod Govindapillai --- drivers/gpu/drm/i915/i915_debugfs.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index e9b79c2c37d8..bb48feb3b12e 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -67,7 +67,6 @@ static int i915_capabilities(struct seq_file *m, void *data) seq_printf(m, "pch: %d\n", INTEL_PCH_TYPE(i915)); intel_device_info_print(INTEL_INFO(i915), RUNTIME_INFO(i915), ); - intel_display_device_info_print(DISPLAY_INFO(i915), DISPLAY_RUNTIME_INFO(i915), ); i915_print_iommu_status(i915, ); intel_gt_info_print(_gt(i915)->info, ); intel_driver_caps_print(>caps, ); -- 2.34.1
[Intel-gfx] [PATCH v1 1/2] drm/i915/display: display device info debugfs entry
Have a common debugfs entry to get the display device info for both xe and i915 drivers. Signed-off-by: Vinod Govindapillai --- drivers/gpu/drm/i915/display/intel_display_debugfs.c | 11 +++ 1 file changed, 11 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c index fbe75d47a165..ed83339f50f0 100644 --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c @@ -641,6 +641,16 @@ static int i915_display_info(struct seq_file *m, void *unused) return 0; } +static int i915_display_device_info(struct seq_file *m, void *unused) +{ + struct drm_i915_private *i915 = node_to_i915(m->private); + struct drm_printer p = drm_seq_file_printer(m); + + intel_display_device_info_print(DISPLAY_INFO(i915), DISPLAY_RUNTIME_INFO(i915), ); + + return 0; +} + static int i915_shared_dplls_info(struct seq_file *m, void *unused) { struct drm_i915_private *dev_priv = node_to_i915(m->private); @@ -1059,6 +1069,7 @@ static const struct drm_info_list intel_display_debugfs_list[] = { {"i915_gem_framebuffer", i915_gem_framebuffer_info, 0}, {"i915_power_domain_info", i915_power_domain_info, 0}, {"i915_display_info", i915_display_info, 0}, + {"i915_display_device_info", i915_display_device_info, 0}, {"i915_shared_dplls_info", i915_shared_dplls_info, 0}, {"i915_dp_mst_info", i915_dp_mst_info, 0}, {"i915_ddb_info", i915_ddb_info, 0}, -- 2.34.1
[Intel-gfx] [PATCH v1 0/2] display device info as a separate debugfs entry
Expose the display device info as a separate debugfs entry to list out display device info and remove the same from i915_capabilities Vinod Govindapillai (2): drm/i915/display: display device info debugfs entry drm/i915: remove display device info from i915 capabilities drivers/gpu/drm/i915/display/intel_display_debugfs.c | 11 +++ drivers/gpu/drm/i915/i915_debugfs.c | 1 - 2 files changed, 11 insertions(+), 1 deletion(-) -- 2.34.1
[Intel-gfx] [PATCH v1 3/3] drm/i915/xe2lpd: update the scaler feature capability
Update the number of scalers per pipe based on the display capabilities reported. v1: define the field values instead of the magic number (JaniN) Bspec: 71161 Signed-off-by: Vinod Govindapillai --- drivers/gpu/drm/i915/display/intel_display_device.c | 7 +++ 1 file changed, 7 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_display_device.c b/drivers/gpu/drm/i915/display/intel_display_device.c index 2c891fe4d74b..bb4fdfba138c 100644 --- a/drivers/gpu/drm/i915/display/intel_display_device.c +++ b/drivers/gpu/drm/i915/display/intel_display_device.c @@ -1071,6 +1071,13 @@ void intel_display_device_info_runtime_init(struct drm_i915_private *i915) if (REG_FIELD_GET(XE2LPD_DE_CAP_DSC_MASK, cap) == XE2LPD_DE_CAP_DSC_REMOVED) display_runtime->has_dsc = 0; + + if (REG_FIELD_GET(XE2LPD_DE_CAP_SCALER_MASK, cap) == + XE2LPD_DE_CAP_SCALER_SINGLE) { + for_each_pipe(i915, pipe) + if (display_runtime->num_scalers[pipe]) + display_runtime->num_scalers[pipe] = 1; + } } return; -- 2.34.1
[Intel-gfx] [PATCH v1 0/3] scalable display feature configurations
Get the reported device capabilities and update DSC and scaler feature support v1: use defined field values instead of magic numbers (Jani Nikula) Vinod Govindapillai (3): drm/i915/xe2lpd: display capability register definitions drm/i915/xe2lpd: update the dsc feature capability drm/i915/xe2lpd: update the scaler feature capability .../gpu/drm/i915/display/intel_display_device.c | 15 +++ drivers/gpu/drm/i915/i915_reg.h | 7 +++ 2 files changed, 22 insertions(+) -- 2.34.1
[Intel-gfx] [PATCH v1 2/3] drm/i915/xe2lpd: update the dsc feature capability
Update the global dsc flag based on the display capabilities reported. v1: define the field values instead of the magic number (JaniN) Bspec: 71161 Signed-off-by: Vinod Govindapillai --- drivers/gpu/drm/i915/display/intel_display_device.c | 8 1 file changed, 8 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_display_device.c b/drivers/gpu/drm/i915/display/intel_display_device.c index a6a18eae7ae8..2c891fe4d74b 100644 --- a/drivers/gpu/drm/i915/display/intel_display_device.c +++ b/drivers/gpu/drm/i915/display/intel_display_device.c @@ -1065,6 +1065,14 @@ void intel_display_device_info_runtime_init(struct drm_i915_private *i915) display_runtime->has_dsc = 0; } + if (DISPLAY_VER(i915) >= 20) { + u32 cap = intel_de_read(i915, XE2LPD_DE_CAP); + + if (REG_FIELD_GET(XE2LPD_DE_CAP_DSC_MASK, cap) == + XE2LPD_DE_CAP_DSC_REMOVED) + display_runtime->has_dsc = 0; + } + return; display_fused_off: -- 2.34.1
[Intel-gfx] [PATCH v1 1/3] drm/i915/xe2lpd: display capability register definitions
Register definitions to track the reported scalable display feature configurations Bspec: 71161 Signed-off-by: Vinod Govindapillai --- drivers/gpu/drm/i915/i915_reg.h | 7 +++ 1 file changed, 7 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index e0ea2dc13556..dc70c1777345 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -4678,6 +4678,13 @@ #define TGL_DFSM_PIPE_D_DISABLE (1 << 22) #define GLK_DFSM_DISPLAY_DSC_DISABLE (1 << 7) +#define XE2LPD_DE_CAP _MMIO(0x41100) +#define XE2LPD_DE_CAP_3DLUT_MASK REG_GENMASK(31, 30) +#define XE2LPD_DE_CAP_DSC_MASK REG_GENMASK(29, 28) +#define XE2LPD_DE_CAP_DSC_REMOVED1 +#define XE2LPD_DE_CAP_SCALER_MASKREG_GENMASK(27, 26) +#define XE2LPD_DE_CAP_SCALER_SINGLE 1 + #define SKL_DSSM _MMIO(0x51004) #define ICL_DSSM_CDCLK_PLL_REFCLK_MASK (7 << 29) #define ICL_DSSM_CDCLK_PLL_REFCLK_24MHz(0 << 29) -- 2.34.1
[Intel-gfx] [PATCH 3/3] drm/i915/xe2lpd: update the scaler feature capability
Update the number of scalers per pipe based on the display capabilities reported. Bspec: 71161 Signed-off-by: Vinod Govindapillai --- drivers/gpu/drm/i915/display/intel_display_device.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_display_device.c b/drivers/gpu/drm/i915/display/intel_display_device.c index e51506e37384..dea9b6ab069e 100644 --- a/drivers/gpu/drm/i915/display/intel_display_device.c +++ b/drivers/gpu/drm/i915/display/intel_display_device.c @@ -1070,6 +1070,12 @@ void intel_display_device_info_runtime_init(struct drm_i915_private *i915) if (REG_FIELD_GET(XE2LPD_DE_CAP_DSC_MASK, cap) == 1) display_runtime->has_dsc = 0; + + if (REG_FIELD_GET(XE2LPD_DE_CAP_SCALER_MASK, cap) == 1) { + for_each_pipe(i915, pipe) + if (display_runtime->num_scalers[pipe]) + display_runtime->num_scalers[pipe] = 1; + } } return; -- 2.34.1
[Intel-gfx] [PATCH 2/3] drm/i915/xe2lpd: update the dsc feature capability
Update the global dsc flag based on the display capabilities reported. Bspec: 71161 Signed-off-by: Vinod Govindapillai --- drivers/gpu/drm/i915/display/intel_display_device.c | 7 +++ 1 file changed, 7 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_display_device.c b/drivers/gpu/drm/i915/display/intel_display_device.c index a6a18eae7ae8..e51506e37384 100644 --- a/drivers/gpu/drm/i915/display/intel_display_device.c +++ b/drivers/gpu/drm/i915/display/intel_display_device.c @@ -1065,6 +1065,13 @@ void intel_display_device_info_runtime_init(struct drm_i915_private *i915) display_runtime->has_dsc = 0; } + if (DISPLAY_VER(i915) >= 20) { + u32 cap = intel_de_read(i915, XE2LPD_DE_CAP); + + if (REG_FIELD_GET(XE2LPD_DE_CAP_DSC_MASK, cap) == 1) + display_runtime->has_dsc = 0; + } + return; display_fused_off: -- 2.34.1
[Intel-gfx] [PATCH 1/3] drm/i915/xe2lpd: display capability register definitions
Register definitions to track the reported scalable display feature configurations Bspec: 71161 Signed-off-by: Vinod Govindapillai --- drivers/gpu/drm/i915/i915_reg.h | 5 + 1 file changed, 5 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index e0ea2dc13556..afb0697eafa5 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -4678,6 +4678,11 @@ #define TGL_DFSM_PIPE_D_DISABLE (1 << 22) #define GLK_DFSM_DISPLAY_DSC_DISABLE (1 << 7) +#define XE2LPD_DE_CAP _MMIO(0x41100) +#define XE2LPD_DE_CAP_3DLUT_MASK REG_GENMASK(31, 30) +#define XE2LPD_DE_CAP_DSC_MASK REG_GENMASK(29, 28) +#define XE2LPD_DE_CAP_SCALER_MASKREG_GENMASK(27, 26) + #define SKL_DSSM _MMIO(0x51004) #define ICL_DSSM_CDCLK_PLL_REFCLK_MASK (7 << 29) #define ICL_DSSM_CDCLK_PLL_REFCLK_24MHz(0 << 29) -- 2.34.1
[Intel-gfx] [PATCH 0/3] scalable display feature configurations
Get the reported device capabilities and update DSC and scaler feature support Vinod Govindapillai (3): drm/i915/xe2lpd: display capability register definitions drm/i915/xe2lpd: update the dsc feature capability drm/i915/xe2lpd: update the scaler feature capability drivers/gpu/drm/i915/display/intel_display_device.c | 13 + drivers/gpu/drm/i915/i915_reg.h | 5 + 2 files changed, 18 insertions(+) -- 2.34.1
[Intel-gfx] [PATCH v5 2/2] drm/i915/lnl: update the supported plane formats with FBC
FBC is supported with RGB32 8:8:8:8 with or without alpha Bspec: 68904, 69560 Signed-off-by: Vinod Govindapillai --- drivers/gpu/drm/i915/display/intel_fbc.c | 8 +++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c index aef5a4f6ad09..9b19fe018bce 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.c +++ b/drivers/gpu/drm/i915/display/intel_fbc.c @@ -903,6 +903,11 @@ static bool pixel_format_is_valid(const struct intel_plane_state *plane_state) if (IS_G4X(i915)) return false; return true; + case DRM_FORMAT_ARGB: + case DRM_FORMAT_ABGR: + if (DISPLAY_VER(i915) >= 20) + return true; + fallthrough; default: return false; } @@ -1132,7 +1137,8 @@ static int intel_fbc_check_plane(struct intel_atomic_state *state, return 0; } - if (plane_state->hw.pixel_blend_mode != DRM_MODE_BLEND_PIXEL_NONE && + if (DISPLAY_VER(i915) < 20 && + plane_state->hw.pixel_blend_mode != DRM_MODE_BLEND_PIXEL_NONE && fb->format->has_alpha) { plane_state->no_fbc_reason = "per-pixel alpha not supported"; return 0; -- 2.34.1
[Intel-gfx] [PATCH v5 0/2] fbc on any planes
FBC can be supported in first three planes in lnl Vinod Govindapillai (2): drm/i915/lnl: possibility to enable FBC on first three planes drm/i915/lnl: update the supported plane formats with FBC drivers/gpu/drm/i915/display/intel_fbc.c | 11 ++- drivers/gpu/drm/i915/display/skl_universal_plane.c | 9 ++--- drivers/gpu/drm/i915/i915_reg.h| 2 ++ 3 files changed, 18 insertions(+), 4 deletions(-) -- 2.34.1
[Intel-gfx] [PATCH v5 1/2] drm/i915/lnl: possibility to enable FBC on first three planes
In LNL onwards, FBC can be associated to the first three planes. FBC will be enabled on planes first come first served basis until the userspace can select one of these FBC capable planes explicitly. v2: - avoid fbc->state.plane check in intel_fbc_check_plane (Ville) - simplify plane binding register writes (Matt) - Update the subject to reflect that fbc can be enabled only in the first three planes (Matt) v3: - use icl_is_hdr_plane(), use wrapper macro for plane binding register access, comments update and patch split (Ville) v4: - update to the plane binding register access macro Bspec: 69560 Signed-off-by: Vinod Govindapillai --- drivers/gpu/drm/i915/display/intel_fbc.c | 3 +++ drivers/gpu/drm/i915/display/skl_universal_plane.c | 9 ++--- drivers/gpu/drm/i915/i915_reg.h| 2 ++ 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c index 7f70166f7035..aef5a4f6ad09 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.c +++ b/drivers/gpu/drm/i915/display/intel_fbc.c @@ -592,6 +592,9 @@ static u32 ivb_dpfc_ctl(struct intel_fbc *fbc) if (IS_IVYBRIDGE(i915)) dpfc_ctl |= DPFC_CTL_PLANE_IVB(fbc_state->plane->i9xx_plane); + if (DISPLAY_VER(i915) >= 20) + dpfc_ctl |= DPFC_CTL_PLANE_BINDING(fbc_state->plane->id); + if (fbc_state->fence_id >= 0) dpfc_ctl |= DPFC_CTL_FENCE_EN_IVB; diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c index 4d01c7ae4485..8f946c5a2fd8 100644 --- a/drivers/gpu/drm/i915/display/skl_universal_plane.c +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c @@ -1956,13 +1956,16 @@ static enum intel_fbc_id skl_fbc_id_for_pipe(enum pipe pipe) return pipe - PIPE_A + INTEL_FBC_A; } -static bool skl_plane_has_fbc(struct drm_i915_private *dev_priv, +static bool skl_plane_has_fbc(struct drm_i915_private *i915, enum intel_fbc_id fbc_id, enum plane_id plane_id) { - if ((DISPLAY_RUNTIME_INFO(dev_priv)->fbc_mask & BIT(fbc_id)) == 0) + if ((DISPLAY_RUNTIME_INFO(i915)->fbc_mask & BIT(fbc_id)) == 0) return false; - return plane_id == PLANE_PRIMARY; + if (DISPLAY_VER(i915) >= 20) + return icl_is_hdr_plane(i915, plane_id); + else + return plane_id == PLANE_PRIMARY; } static struct intel_fbc *skl_plane_fbc(struct drm_i915_private *dev_priv, diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index aefad14ab27a..d44ac6f1c052 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -1327,6 +1327,8 @@ #define DPFC_CTL_PLANE_IVB(i9xx_plane) REG_FIELD_PREP(DPFC_CTL_PLANE_MASK_IVB, (i9xx_plane)) #define DPFC_CTL_FENCE_EN_IVBREG_BIT(28) /* ivb+ */ #define DPFC_CTL_PERSISTENT_MODE REG_BIT(25) /* g4x-snb */ +#define DPFC_CTL_PLANE_BINDING_MASK REG_GENMASK(12, 11) /* lnl+ */ +#define DPFC_CTL_PLANE_BINDING(plane_id) REG_FIELD_PREP(DPFC_CTL_PLANE_BINDING_MASK, (plane_id)) #define DPFC_CTL_FALSE_COLOR REG_BIT(10) /* ivb+ */ #define DPFC_CTL_SR_EN REG_BIT(10) /* g4x only */ #define DPFC_CTL_SR_EXIT_DIS REG_BIT(9) /* g4x only */ -- 2.34.1
[Intel-gfx] [PATCH v4 1/2] drm/i915/lnl: possibility to enable FBC on first three planes
In LNL onwards, FBC can be associated to the first three planes. FBC will be enabled on planes first come first served basis until the userspace can select one of these FBC capable planes explicitly. v2: - avoid fbc->state.plane check in intel_fbc_check_plane (Ville) - simplify plane binding register writes (Matt) - Update the subject to reflect that fbc can be enabled only in the first three planes (Matt) v3: - use icl_is_hdr_plane(), use wrapper macro for plane binding register access, comments update and patch split (Ville) v4: - update to the plane binding register access macro Bspec: 69560 Signed-off-by: Vinod Govindapillai --- drivers/gpu/drm/i915/display/intel_fbc.c | 3 +++ drivers/gpu/drm/i915/display/skl_universal_plane.c | 9 ++--- drivers/gpu/drm/i915/i915_reg.h| 2 ++ 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c index 66c8aed07bbc..a3999ad95a19 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.c +++ b/drivers/gpu/drm/i915/display/intel_fbc.c @@ -660,6 +660,9 @@ static u32 ivb_dpfc_ctl(struct intel_fbc *fbc) if (IS_IVYBRIDGE(i915)) dpfc_ctl |= DPFC_CTL_PLANE_IVB(fbc_state->plane->i9xx_plane); + if (DISPLAY_VER(i915) >= 20) + dpfc_ctl |= DPFC_CTL_PLANE_BINDING(fbc_state->plane->id); + if (fbc_state->fence_id >= 0) dpfc_ctl |= DPFC_CTL_FENCE_EN_IVB; diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c index 4d01c7ae4485..8f946c5a2fd8 100644 --- a/drivers/gpu/drm/i915/display/skl_universal_plane.c +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c @@ -1956,13 +1956,16 @@ static enum intel_fbc_id skl_fbc_id_for_pipe(enum pipe pipe) return pipe - PIPE_A + INTEL_FBC_A; } -static bool skl_plane_has_fbc(struct drm_i915_private *dev_priv, +static bool skl_plane_has_fbc(struct drm_i915_private *i915, enum intel_fbc_id fbc_id, enum plane_id plane_id) { - if ((DISPLAY_RUNTIME_INFO(dev_priv)->fbc_mask & BIT(fbc_id)) == 0) + if ((DISPLAY_RUNTIME_INFO(i915)->fbc_mask & BIT(fbc_id)) == 0) return false; - return plane_id == PLANE_PRIMARY; + if (DISPLAY_VER(i915) >= 20) + return icl_is_hdr_plane(i915, plane_id); + else + return plane_id == PLANE_PRIMARY; } static struct intel_fbc *skl_plane_fbc(struct drm_i915_private *dev_priv, diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index aefad14ab27a..d44ac6f1c052 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -1327,6 +1327,8 @@ #define DPFC_CTL_PLANE_IVB(i9xx_plane) REG_FIELD_PREP(DPFC_CTL_PLANE_MASK_IVB, (i9xx_plane)) #define DPFC_CTL_FENCE_EN_IVBREG_BIT(28) /* ivb+ */ #define DPFC_CTL_PERSISTENT_MODE REG_BIT(25) /* g4x-snb */ +#define DPFC_CTL_PLANE_BINDING_MASK REG_GENMASK(12, 11) /* lnl+ */ +#define DPFC_CTL_PLANE_BINDING(plane_id) REG_FIELD_PREP(DPFC_CTL_PLANE_BINDING_MASK, (plane_id)) #define DPFC_CTL_FALSE_COLOR REG_BIT(10) /* ivb+ */ #define DPFC_CTL_SR_EN REG_BIT(10) /* g4x only */ #define DPFC_CTL_SR_EXIT_DIS REG_BIT(9) /* g4x only */ -- 2.34.1
[Intel-gfx] [PATCH v4 2/2] drm/i915/lnl: FBC is supported with per pixel alpha
For LNL onwards, FBC can be supported on planes with per pixel alpha Bspec: 69560 Signed-off-by: Vinod Govindapillai --- drivers/gpu/drm/i915/display/intel_fbc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c index a3999ad95a19..c0e4caec03ea 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.c +++ b/drivers/gpu/drm/i915/display/intel_fbc.c @@ -1209,7 +1209,8 @@ static int intel_fbc_check_plane(struct intel_atomic_state *state, return 0; } - if (plane_state->hw.pixel_blend_mode != DRM_MODE_BLEND_PIXEL_NONE && + if (DISPLAY_VER(i915) < 20 && + plane_state->hw.pixel_blend_mode != DRM_MODE_BLEND_PIXEL_NONE && fb->format->has_alpha) { plane_state->no_fbc_reason = "per-pixel alpha not supported"; return 0; -- 2.34.1
[Intel-gfx] [PATCH v4 0/2] fbc on any planes
FBC can be supported in first three planes in lnl Vinod Govindapillai (2): drm/i915/lnl: possibility to enable FBC on first three planes drm/i915/lnl: FBC is supported with per pixel alpha drivers/gpu/drm/i915/display/intel_fbc.c | 6 +- drivers/gpu/drm/i915/display/skl_universal_plane.c | 9 ++--- drivers/gpu/drm/i915/i915_reg.h| 2 ++ 3 files changed, 13 insertions(+), 4 deletions(-) -- 2.34.1
[Intel-gfx] [PATCH v3 2/2] drm/i915/lnl: FBC is supported with per pixel alpha
For LNL onwards, FBC can be supported on planes with per pixel alpha Bspec: 69560 Signed-off-by: Vinod Govindapillai --- drivers/gpu/drm/i915/display/intel_fbc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c index a3999ad95a19..c0e4caec03ea 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.c +++ b/drivers/gpu/drm/i915/display/intel_fbc.c @@ -1209,7 +1209,8 @@ static int intel_fbc_check_plane(struct intel_atomic_state *state, return 0; } - if (plane_state->hw.pixel_blend_mode != DRM_MODE_BLEND_PIXEL_NONE && + if (DISPLAY_VER(i915) < 20 && + plane_state->hw.pixel_blend_mode != DRM_MODE_BLEND_PIXEL_NONE && fb->format->has_alpha) { plane_state->no_fbc_reason = "per-pixel alpha not supported"; return 0; -- 2.34.1
[Intel-gfx] [PATCH v3 1/2] drm/i915/lnl: possibility to enable FBC on first three planes
In LNL onwards, FBC can be associated to the first three planes. FBC will be enabled on planes first come first served basis until the userspace can select one of these FBC capable planes explicitly. v2: - avoid fbc->state.plane check in intel_fbc_check_plane (Ville) - simplify plane binding register writes (Matt) - Update the subject to reflect that fbc can be enabled only in the first three planes (Matt) v3: - use icl_is_hdr_plane(), use wrapper macro for plane binding register access, comments update and patch split (Ville) Bspec: 69560 Signed-off-by: Vinod Govindapillai --- drivers/gpu/drm/i915/display/intel_fbc.c | 3 +++ drivers/gpu/drm/i915/display/skl_universal_plane.c | 9 ++--- drivers/gpu/drm/i915/i915_reg.h| 2 ++ 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c index 66c8aed07bbc..a3999ad95a19 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.c +++ b/drivers/gpu/drm/i915/display/intel_fbc.c @@ -660,6 +660,9 @@ static u32 ivb_dpfc_ctl(struct intel_fbc *fbc) if (IS_IVYBRIDGE(i915)) dpfc_ctl |= DPFC_CTL_PLANE_IVB(fbc_state->plane->i9xx_plane); + if (DISPLAY_VER(i915) >= 20) + dpfc_ctl |= DPFC_CTL_PLANE_BINDING(fbc_state->plane->id); + if (fbc_state->fence_id >= 0) dpfc_ctl |= DPFC_CTL_FENCE_EN_IVB; diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c index 4d01c7ae4485..8f946c5a2fd8 100644 --- a/drivers/gpu/drm/i915/display/skl_universal_plane.c +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c @@ -1956,13 +1956,16 @@ static enum intel_fbc_id skl_fbc_id_for_pipe(enum pipe pipe) return pipe - PIPE_A + INTEL_FBC_A; } -static bool skl_plane_has_fbc(struct drm_i915_private *dev_priv, +static bool skl_plane_has_fbc(struct drm_i915_private *i915, enum intel_fbc_id fbc_id, enum plane_id plane_id) { - if ((DISPLAY_RUNTIME_INFO(dev_priv)->fbc_mask & BIT(fbc_id)) == 0) + if ((DISPLAY_RUNTIME_INFO(i915)->fbc_mask & BIT(fbc_id)) == 0) return false; - return plane_id == PLANE_PRIMARY; + if (DISPLAY_VER(i915) >= 20) + return icl_is_hdr_plane(i915, plane_id); + else + return plane_id == PLANE_PRIMARY; } static struct intel_fbc *skl_plane_fbc(struct drm_i915_private *dev_priv, diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index aefad14ab27a..a3a3e37fb8fb 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -1327,6 +1327,8 @@ #define DPFC_CTL_PLANE_IVB(i9xx_plane) REG_FIELD_PREP(DPFC_CTL_PLANE_MASK_IVB, (i9xx_plane)) #define DPFC_CTL_FENCE_EN_IVBREG_BIT(28) /* ivb+ */ #define DPFC_CTL_PERSISTENT_MODE REG_BIT(25) /* g4x-snb */ +#define DPFC_CTL_PLANE_BINDING_MASK REG_GENMASK(12, 11) /* lnl+ */ +#define DPFC_CTL_PLANE_BINDING(i9xx_plane) REG_FIELD_PREP(DPFC_CTL_PLANE_BINDING_MASK, (i9xx_plane)) #define DPFC_CTL_FALSE_COLOR REG_BIT(10) /* ivb+ */ #define DPFC_CTL_SR_EN REG_BIT(10) /* g4x only */ #define DPFC_CTL_SR_EXIT_DIS REG_BIT(9) /* g4x only */ -- 2.34.1
[Intel-gfx] [PATCH v3 0/2] fbc on any planes
FBC can be supported in first three planes in lnl Vinod Govindapillai (2): drm/i915/lnl: possibility to enable FBC on first three planes drm/i915/lnl: FBC is supported with per pixel alpha drivers/gpu/drm/i915/display/intel_fbc.c | 6 +- drivers/gpu/drm/i915/display/skl_universal_plane.c | 9 ++--- drivers/gpu/drm/i915/i915_reg.h| 2 ++ 3 files changed, 13 insertions(+), 4 deletions(-) -- 2.34.1
[Intel-gfx] [PATCH v2 0/1] fbc on any plane
FBC can be supported in first three planes in lnl Matt pointed out that FBC + PSR2 combination require few more condition checks and also a WA also need to be impleteds. So patch to enabled FBC in case of PSR2 is removed from this version. Also per pizel alpha condition is removed for FBC in LNL. Vinod Govindapillai (1): drm/i915/lnl: possibility to enable FBC on first three planes drivers/gpu/drm/i915/display/intel_fbc.c | 7 ++- drivers/gpu/drm/i915/display/skl_universal_plane.c | 5 - drivers/gpu/drm/i915/i915_reg.h| 1 + 3 files changed, 11 insertions(+), 2 deletions(-) -- 2.34.1
[Intel-gfx] [PATCH v2 1/1] drm/i915/lnl: possibility to enable FBC on first three planes
In LNL onwards, FBC can be associated to the first three planes. FBC will be enabled on planes first come first served basis until the userspace can select one of these FBC capable plane explicitly. FBC can be supported in planes with per pixel alpha v2: - avoid fbc->state.plane check in intel_fbc_check_plane (Ville) - simplify plane binding register writes (Matt) - Update the subject to reflect that fbc can be enabled only in the first three planes (Matt) Bspec: 69560 Signed-off-by: Vinod Govindapillai --- drivers/gpu/drm/i915/display/intel_fbc.c | 7 ++- drivers/gpu/drm/i915/display/skl_universal_plane.c | 5 - drivers/gpu/drm/i915/i915_reg.h| 1 + 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c index 66c8aed07bbc..f1537bb63775 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.c +++ b/drivers/gpu/drm/i915/display/intel_fbc.c @@ -660,6 +660,10 @@ static u32 ivb_dpfc_ctl(struct intel_fbc *fbc) if (IS_IVYBRIDGE(i915)) dpfc_ctl |= DPFC_CTL_PLANE_IVB(fbc_state->plane->i9xx_plane); + if (DISPLAY_VER(i915) >= 20) + dpfc_ctl |= REG_FIELD_PREP(DPFC_CTL_PLANE_BINDING_MASK, + fbc_state->plane->id); + if (fbc_state->fence_id >= 0) dpfc_ctl |= DPFC_CTL_FENCE_EN_IVB; @@ -1206,7 +1210,8 @@ static int intel_fbc_check_plane(struct intel_atomic_state *state, return 0; } - if (plane_state->hw.pixel_blend_mode != DRM_MODE_BLEND_PIXEL_NONE && + if (DISPLAY_VER(i915) < 20 && + plane_state->hw.pixel_blend_mode != DRM_MODE_BLEND_PIXEL_NONE && fb->format->has_alpha) { plane_state->no_fbc_reason = "per-pixel alpha not supported"; return 0; diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c index 4d01c7ae4485..1291351c9941 100644 --- a/drivers/gpu/drm/i915/display/skl_universal_plane.c +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c @@ -1962,7 +1962,10 @@ static bool skl_plane_has_fbc(struct drm_i915_private *dev_priv, if ((DISPLAY_RUNTIME_INFO(dev_priv)->fbc_mask & BIT(fbc_id)) == 0) return false; - return plane_id == PLANE_PRIMARY; + if (DISPLAY_VER(dev_priv) >= 20) + return plane_id <= PLANE_SPRITE1; + else + return plane_id == PLANE_PRIMARY; } static struct intel_fbc *skl_plane_fbc(struct drm_i915_private *dev_priv, diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index aefad14ab27a..aadcc630cb52 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -1327,6 +1327,7 @@ #define DPFC_CTL_PLANE_IVB(i9xx_plane) REG_FIELD_PREP(DPFC_CTL_PLANE_MASK_IVB, (i9xx_plane)) #define DPFC_CTL_FENCE_EN_IVBREG_BIT(28) /* ivb+ */ #define DPFC_CTL_PERSISTENT_MODE REG_BIT(25) /* g4x-snb */ +#define DPFC_CTL_PLANE_BINDING_MASK REG_GENMASK(12, 11) /* lnl */ #define DPFC_CTL_FALSE_COLOR REG_BIT(10) /* ivb+ */ #define DPFC_CTL_SR_EN REG_BIT(10) /* g4x only */ #define DPFC_CTL_SR_EXIT_DIS REG_BIT(9) /* g4x only */ -- 2.34.1
[Intel-gfx] [PATCH v2 1/1] drm/i915/lnl: possibility to enable FBC on first three planes
In LNL onwards, FBC can be associated to the first three planes. FBC will be enabled on planes first come first served basis until the userspace can select one of these FBC capable plane explicitly. FBC can be supported in planes with per pixel alpha v2: - avoid fbc->state.plane check in intel_fbc_check_plane (Ville) - simplify plane binding register writes (Matt) - Update the subject to reflect that fbc can be enabled only in the first three planes (Matt) Bspec: 69560 Signed-off-by: Vinod Govindapillai --- drivers/gpu/drm/i915/display/intel_fbc.c | 7 ++- drivers/gpu/drm/i915/display/skl_universal_plane.c | 5 - drivers/gpu/drm/i915/i915_reg.h| 1 + 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c index 66c8aed07bbc..f1537bb63775 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.c +++ b/drivers/gpu/drm/i915/display/intel_fbc.c @@ -660,6 +660,10 @@ static u32 ivb_dpfc_ctl(struct intel_fbc *fbc) if (IS_IVYBRIDGE(i915)) dpfc_ctl |= DPFC_CTL_PLANE_IVB(fbc_state->plane->i9xx_plane); + if (DISPLAY_VER(i915) >= 20) + dpfc_ctl |= REG_FIELD_PREP(DPFC_CTL_PLANE_BINDING_MASK, + fbc_state->plane->id); + if (fbc_state->fence_id >= 0) dpfc_ctl |= DPFC_CTL_FENCE_EN_IVB; @@ -1206,7 +1210,8 @@ static int intel_fbc_check_plane(struct intel_atomic_state *state, return 0; } - if (plane_state->hw.pixel_blend_mode != DRM_MODE_BLEND_PIXEL_NONE && + if (DISPLAY_VER(i915) < 20 && + plane_state->hw.pixel_blend_mode != DRM_MODE_BLEND_PIXEL_NONE && fb->format->has_alpha) { plane_state->no_fbc_reason = "per-pixel alpha not supported"; return 0; diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c index 4d01c7ae4485..1291351c9941 100644 --- a/drivers/gpu/drm/i915/display/skl_universal_plane.c +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c @@ -1962,7 +1962,10 @@ static bool skl_plane_has_fbc(struct drm_i915_private *dev_priv, if ((DISPLAY_RUNTIME_INFO(dev_priv)->fbc_mask & BIT(fbc_id)) == 0) return false; - return plane_id == PLANE_PRIMARY; + if (DISPLAY_VER(dev_priv) >= 20) + return plane_id <= PLANE_SPRITE1; + else + return plane_id == PLANE_PRIMARY; } static struct intel_fbc *skl_plane_fbc(struct drm_i915_private *dev_priv, diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index aefad14ab27a..aadcc630cb52 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -1327,6 +1327,7 @@ #define DPFC_CTL_PLANE_IVB(i9xx_plane) REG_FIELD_PREP(DPFC_CTL_PLANE_MASK_IVB, (i9xx_plane)) #define DPFC_CTL_FENCE_EN_IVBREG_BIT(28) /* ivb+ */ #define DPFC_CTL_PERSISTENT_MODE REG_BIT(25) /* g4x-snb */ +#define DPFC_CTL_PLANE_BINDING_MASK REG_GENMASK(12, 11) /* lnl */ #define DPFC_CTL_FALSE_COLOR REG_BIT(10) /* ivb+ */ #define DPFC_CTL_SR_EN REG_BIT(10) /* g4x only */ #define DPFC_CTL_SR_EXIT_DIS REG_BIT(9) /* g4x only */ -- 2.34.1
[Intel-gfx] [PATCH v2 0/1] fbc on any plane
FBC can be supported in first three planes in lnl Matt pointed out that FBC + PSR2 combination require few more condition checks and also a WA also need to be impleteds. So patch to enabled FBC in case of PSR2 is removed from this version. Also per pizel alpha condition is removed for FBC in LNL. Vinod Govindapillai (1): drm/i915/lnl: possibility to enable FBC on first three planes drivers/gpu/drm/i915/display/intel_fbc.c | 7 ++- drivers/gpu/drm/i915/display/skl_universal_plane.c | 5 - drivers/gpu/drm/i915/i915_reg.h| 1 + 3 files changed, 11 insertions(+), 2 deletions(-) -- 2.34.1
[Intel-gfx] [PATCH 4/4] drm/i915/lnl: FBC is supported with per pixel alpha
For LNL onwards, FBC can be supported on planes with per pixel alpha Bspec: 69560 Signed-off-by: Vinod Govindapillai --- drivers/gpu/drm/i915/display/intel_fbc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c index 62f59630d410..f36eb8652d3c 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.c +++ b/drivers/gpu/drm/i915/display/intel_fbc.c @@ -1224,7 +1224,8 @@ static int intel_fbc_check_plane(struct intel_atomic_state *state, return 0; } - if (plane_state->hw.pixel_blend_mode != DRM_MODE_BLEND_PIXEL_NONE && + if (DISPLAY_VER(i915) < 20 && + plane_state->hw.pixel_blend_mode != DRM_MODE_BLEND_PIXEL_NONE && fb->format->has_alpha) { plane_state->no_fbc_reason = "per-pixel alpha not supported"; return 0; -- 2.34.1
[Intel-gfx] [PATCH 3/4] drm/i915/lnl: support FBC on any plane
In LNL onwards, FBC can be associated to the first three planes. The FBC will be enabled for first FBC capable visible plane until the userspace can select one of these FBC capable plane explicitly Bspec: 69560 Signed-off-by: Vinod Govindapillai --- drivers/gpu/drm/i915/display/intel_fbc.c | 29 +++ .../drm/i915/display/skl_universal_plane.c| 5 +++- drivers/gpu/drm/i915/i915_reg.h | 4 +++ 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c index 45e205a0f740..62f59630d410 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.c +++ b/drivers/gpu/drm/i915/display/intel_fbc.c @@ -649,6 +649,21 @@ static void skl_fbc_program_cfb_stride(struct intel_fbc *fbc) CHICKEN_FBC_STRIDE_MASK, val); } +static u32 lnl_plane_binding(struct intel_fbc *fbc) +{ + switch (fbc->state.plane->id) { + default: + MISSING_CASE(fbc->state.plane->id); + fallthrough; + case 0: + return DPFC_CTL_PLANE_BINDING_1; + case 1: + return DPFC_CTL_PLANE_BINDING_2; + case 2: + return DPFC_CTL_PLANE_BINDING_3; + } +} + static u32 ivb_dpfc_ctl(struct intel_fbc *fbc) { const struct intel_fbc_state *fbc_state = >state; @@ -660,6 +675,9 @@ static u32 ivb_dpfc_ctl(struct intel_fbc *fbc) if (IS_IVYBRIDGE(i915)) dpfc_ctl |= DPFC_CTL_PLANE_IVB(fbc_state->plane->i9xx_plane); + if (DISPLAY_VER(i915) >= 20) + dpfc_ctl |= lnl_plane_binding(fbc); + if (fbc_state->fence_id >= 0) dpfc_ctl |= DPFC_CTL_FENCE_EN_IVB; @@ -1250,6 +1268,17 @@ static int intel_fbc_check_plane(struct intel_atomic_state *state, } } + /* +* From LNL, FBC can be assigned on any plane. Until a provision is +* provided for the userspace to select a plane for FBC, lets select +* the first visible plane that is FBC capable. +*/ + if (DISPLAY_VER(i915) >= 20 && fbc->state.plane && + fbc->state.plane != plane) { + plane_state->no_fbc_reason = "fbc enabled on another plane"; + return 0; + } + plane_state->no_fbc_reason = NULL; return 0; diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c index 4d01c7ae4485..1291351c9941 100644 --- a/drivers/gpu/drm/i915/display/skl_universal_plane.c +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c @@ -1962,7 +1962,10 @@ static bool skl_plane_has_fbc(struct drm_i915_private *dev_priv, if ((DISPLAY_RUNTIME_INFO(dev_priv)->fbc_mask & BIT(fbc_id)) == 0) return false; - return plane_id == PLANE_PRIMARY; + if (DISPLAY_VER(dev_priv) >= 20) + return plane_id <= PLANE_SPRITE1; + else + return plane_id == PLANE_PRIMARY; } static struct intel_fbc *skl_plane_fbc(struct drm_i915_private *dev_priv, diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index aefad14ab27a..b207774f3c33 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -1327,6 +1327,10 @@ #define DPFC_CTL_PLANE_IVB(i9xx_plane) REG_FIELD_PREP(DPFC_CTL_PLANE_MASK_IVB, (i9xx_plane)) #define DPFC_CTL_FENCE_EN_IVBREG_BIT(28) /* ivb+ */ #define DPFC_CTL_PERSISTENT_MODE REG_BIT(25) /* g4x-snb */ +#define DPFC_CTL_PLANE_BINDING_MASK REG_GENMASK(12, 11) /* XE */ +#define DPFC_CTL_PLANE_BINDING_1 REG_FIELD_PREP(DPFC_CTL_PLANE_BINDING_MASK, 0) /* XE */ +#define DPFC_CTL_PLANE_BINDING_2 REG_FIELD_PREP(DPFC_CTL_PLANE_BINDING_MASK, 1) /* XE */ +#define DPFC_CTL_PLANE_BINDING_3 REG_FIELD_PREP(DPFC_CTL_PLANE_BINDING_MASK, 2) /* XE */ #define DPFC_CTL_FALSE_COLOR REG_BIT(10) /* ivb+ */ #define DPFC_CTL_SR_EN REG_BIT(10) /* g4x only */ #define DPFC_CTL_SR_EXIT_DIS REG_BIT(9) /* g4x only */ -- 2.34.1
[Intel-gfx] [PATCH 2/4] drm/i915/lnl: update FBC debugfs to include plane information
In future platforms, FBC can be supported on planes other than the primary plane. So update the debugfs entry for FBC status to have the plane ID included. Signed-off-by: Vinod Govindapillai --- drivers/gpu/drm/i915/display/intel_fbc.c | 14 +++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c index d36499d7e0be..45e205a0f740 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.c +++ b/drivers/gpu/drm/i915/display/intel_fbc.c @@ -1837,7 +1837,9 @@ static int intel_fbc_debugfs_status_show(struct seq_file *m, void *unused) mutex_lock(>lock); if (fbc->active) { - seq_puts(m, "FBC enabled\n"); + seq_printf(m, "FBC enabled: [PLANE:%d:%s]\n", + fbc->state.plane->base.base.id, + fbc->state.plane->base.name); seq_printf(m, "Compressing: %s\n", str_yes_no(intel_fbc_is_compressing(fbc))); } else { @@ -1910,10 +1912,16 @@ static void intel_fbc_debugfs_add(struct intel_fbc *fbc, void intel_fbc_crtc_debugfs_add(struct intel_crtc *crtc) { - struct intel_plane *plane = to_intel_plane(crtc->base.primary); + struct drm_i915_private *i915 = to_i915(crtc->base.dev); + struct intel_plane *plane; + + for_each_intel_plane(>drm, plane) { + if (!plane->fbc || plane->pipe != crtc->pipe) + continue; - if (plane->fbc) intel_fbc_debugfs_add(plane->fbc, crtc->base.debugfs_entry); + break; + } } /* FIXME: remove this once igt is on board with per-crtc stuff */ -- 2.34.1
[Intel-gfx] [PATCH 1/4] drm/i915/lnl: FBC can be enabled with PSR2
FBC restriction with PSR2 can be removed from LNL onwards Signed-off-by: Vinod Govindapillai --- drivers/gpu/drm/i915/display/intel_fbc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c index 66c8aed07bbc..d36499d7e0be 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.c +++ b/drivers/gpu/drm/i915/display/intel_fbc.c @@ -1169,11 +1169,11 @@ static int intel_fbc_check_plane(struct intel_atomic_state *state, } /* -* Display 12+ is not supporting FBC with PSR2. +* Display 12 to 14 is not supporting FBC with PSR2. * Recommendation is to keep this combination disabled * Bspec: 50422 HSD: 14010260002 */ - if (DISPLAY_VER(i915) >= 12 && crtc_state->has_psr2) { + if (IS_DISPLAY_VER(i915, 12, 14) && crtc_state->has_psr2) { plane_state->no_fbc_reason = "PSR2 enabled"; return 0; } -- 2.34.1
[Intel-gfx] [PATCH 0/4] fbc on any plane
In LNL, FBC can be supported in planes other than the primary planes. Vinod Govindapillai (4): drm/i915/lnl: FBC can be enabled with PSR2 drm/i915/lnl: update FBC debugfs to include plane information drm/i915/lnl: support FBC on any plane drm/i915/lnl: FBC is supported with per pixel alpha drivers/gpu/drm/i915/display/intel_fbc.c | 50 --- .../drm/i915/display/skl_universal_plane.c| 5 +- drivers/gpu/drm/i915/i915_reg.h | 4 ++ 3 files changed, 52 insertions(+), 7 deletions(-) -- 2.34.1
[Intel-gfx] [PATCH v1 2/2] drm/i915/display: configure SDP split for DP-MST
Extend the SDP split audio config for DP-MST Signed-off-by: Vinod Govindapillai --- drivers/gpu/drm/i915/display/intel_dp.c | 2 +- drivers/gpu/drm/i915/display/intel_dp.h | 3 +++ drivers/gpu/drm/i915/display/intel_dp_mst.c | 21 - 3 files changed, 8 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 6ec5f2dbb6db..05694e0b6143 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -2625,7 +2625,7 @@ intel_dp_compute_output_format(struct intel_encoder *encoder, return ret; } -static void +void intel_dp_audio_compute_config(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config, struct drm_connector_state *conn_state) diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h index 788a577ebe16..b34ddc9c352a 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.h +++ b/drivers/gpu/drm/i915/display/intel_dp.h @@ -65,6 +65,9 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp, struct link_config_limits *limits, int timeslots, bool recompute_pipe_bpp); +void intel_dp_audio_compute_config(struct intel_encoder *encoder, + struct intel_crtc_state *pipe_config, + struct drm_connector_state *conn_state); bool intel_dp_has_hdmi_sink(struct intel_dp *intel_dp); bool intel_dp_is_edp(struct intel_dp *intel_dp); bool intel_dp_is_uhbr(const struct intel_crtc_state *crtc_state); diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index 3eb085fbc7c8..2d1c42a5e684 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -293,19 +293,6 @@ static int intel_dp_mst_update_slots(struct intel_encoder *encoder, return 0; } -static bool intel_dp_mst_has_audio(const struct drm_connector_state *conn_state) -{ - const struct intel_digital_connector_state *intel_conn_state = - to_intel_digital_connector_state(conn_state); - struct intel_connector *connector = - to_intel_connector(conn_state->connector); - - if (intel_conn_state->force_audio == HDMI_AUDIO_AUTO) - return connector->base.display_info.has_audio; - else - return intel_conn_state->force_audio == HDMI_AUDIO_ON; -} - static int intel_dp_mst_compute_config(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config, struct drm_connector_state *conn_state) @@ -325,10 +312,6 @@ static int intel_dp_mst_compute_config(struct intel_encoder *encoder, pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB; pipe_config->has_pch_encoder = false; - pipe_config->has_audio = - intel_dp_mst_has_audio(conn_state) && - intel_audio_compute_config(encoder, pipe_config, conn_state); - /* * for MST we always configure max link bw - the spec doesn't * seem to suggest we should do otherwise. @@ -396,6 +379,8 @@ static int intel_dp_mst_compute_config(struct intel_encoder *encoder, pipe_config->lane_lat_optim_mask = bxt_ddi_phy_calc_lane_lat_optim_mask(pipe_config->lane_count); + intel_dp_audio_compute_config(encoder, pipe_config, conn_state); + intel_ddi_compute_min_voltage_level(dev_priv, pipe_config); return 0; @@ -800,6 +785,8 @@ static void intel_mst_enable_dp(struct intel_atomic_state *state, intel_de_rmw(dev_priv, CHICKEN_TRANS(trans), 0, FECSTALL_DIS_DPTSTREAM_DPTTG); + intel_audio_sdp_split_update(pipe_config); + intel_enable_transcoder(pipe_config); intel_crtc_vblank_on(pipe_config); -- 2.34.1
[Intel-gfx] [PATCH v1 1/2] drm/i915/display: update intel_dp_has_audio to support MST
Modify intel_dp_has_audio to handle DP-MST as well. v1: fix the wrong port comparison (Jani Nikula) Signed-off-by: Vinod Govindapillai --- drivers/gpu/drm/i915/display/intel_dp.c | 10 ++ 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 7067ee3a4bd3..6ec5f2dbb6db 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -2562,15 +2562,17 @@ intel_dp_drrs_compute_config(struct intel_connector *connector, } static bool intel_dp_has_audio(struct intel_encoder *encoder, + struct intel_crtc_state *crtc_state, const struct drm_connector_state *conn_state) { struct drm_i915_private *i915 = to_i915(encoder->base.dev); - struct intel_dp *intel_dp = enc_to_intel_dp(encoder); - struct intel_connector *connector = intel_dp->attached_connector; const struct intel_digital_connector_state *intel_conn_state = to_intel_digital_connector_state(conn_state); + struct intel_connector *connector = + to_intel_connector(conn_state->connector); - if (!intel_dp_port_has_audio(i915, encoder->port)) + if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST) && + !intel_dp_port_has_audio(i915, encoder->port)) return false; if (intel_conn_state->force_audio == HDMI_AUDIO_AUTO) @@ -2632,7 +2634,7 @@ intel_dp_audio_compute_config(struct intel_encoder *encoder, struct drm_connector *connector = conn_state->connector; pipe_config->has_audio = - intel_dp_has_audio(encoder, conn_state) && + intel_dp_has_audio(encoder, pipe_config, conn_state) && intel_audio_compute_config(encoder, pipe_config, conn_state); pipe_config->sdp_split_enable = pipe_config->has_audio && -- 2.34.1
[Intel-gfx] [PATCH v1 0/2] SDP split for DP-MST
SDP split config for DP-MST v1: Fix wrong port comparison (Jani Nikula) Vinod Govindapillai (2): drm/i915/display: update intel_dp_has_audio to support MST drm/i915/display: configure SDP split for DP-MST drivers/gpu/drm/i915/display/intel_dp.c | 12 +++- drivers/gpu/drm/i915/display/intel_dp.h | 3 +++ drivers/gpu/drm/i915/display/intel_dp_mst.c | 21 - 3 files changed, 14 insertions(+), 22 deletions(-) -- 2.34.1
[Intel-gfx] [PATCH v4 4/4] drm/i915/display: configure SDP split for DP-MST
Extend the SDP split audio config for DP-MST Signed-off-by: Vinod Govindapillai --- drivers/gpu/drm/i915/display/intel_dp.c | 2 +- drivers/gpu/drm/i915/display/intel_dp.h | 3 +++ drivers/gpu/drm/i915/display/intel_dp_mst.c | 21 - 3 files changed, 8 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 0ee9b9e05c26..c1364b164df7 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -2234,7 +2234,7 @@ intel_dp_compute_output_format(struct intel_encoder *encoder, return ret; } -static void +void intel_dp_audio_compute_config(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config, struct drm_connector_state *conn_state) diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h index 22099de3ca45..62aacc89c45d 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.h +++ b/drivers/gpu/drm/i915/display/intel_dp.h @@ -65,6 +65,9 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp, struct link_config_limits *limits, int timeslots, bool recompute_pipe_bpp); +void intel_dp_audio_compute_config(struct intel_encoder *encoder, + struct intel_crtc_state *pipe_config, + struct drm_connector_state *conn_state); bool intel_dp_has_hdmi_sink(struct intel_dp *intel_dp); bool intel_dp_is_edp(struct intel_dp *intel_dp); bool intel_dp_is_uhbr(const struct intel_crtc_state *crtc_state); diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index e3f176a093d2..1645e9c1392e 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -290,19 +290,6 @@ static int intel_dp_mst_update_slots(struct intel_encoder *encoder, return 0; } -static bool intel_dp_mst_has_audio(const struct drm_connector_state *conn_state) -{ - const struct intel_digital_connector_state *intel_conn_state = - to_intel_digital_connector_state(conn_state); - struct intel_connector *connector = - to_intel_connector(conn_state->connector); - - if (intel_conn_state->force_audio == HDMI_AUDIO_AUTO) - return connector->base.display_info.has_audio; - else - return intel_conn_state->force_audio == HDMI_AUDIO_ON; -} - static int intel_dp_mst_compute_config(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config, struct drm_connector_state *conn_state) @@ -322,10 +309,6 @@ static int intel_dp_mst_compute_config(struct intel_encoder *encoder, pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB; pipe_config->has_pch_encoder = false; - pipe_config->has_audio = - intel_dp_mst_has_audio(conn_state) && - intel_audio_compute_config(encoder, pipe_config, conn_state); - /* * for MST we always configure max link bw - the spec doesn't * seem to suggest we should do otherwise. @@ -388,6 +371,8 @@ static int intel_dp_mst_compute_config(struct intel_encoder *encoder, pipe_config->lane_lat_optim_mask = bxt_ddi_phy_calc_lane_lat_optim_mask(pipe_config->lane_count); + intel_dp_audio_compute_config(encoder, pipe_config, conn_state); + intel_ddi_compute_min_voltage_level(dev_priv, pipe_config); return 0; @@ -792,6 +777,8 @@ static void intel_mst_enable_dp(struct intel_atomic_state *state, intel_de_rmw(dev_priv, CHICKEN_TRANS(trans), 0, FECSTALL_DIS_DPTSTREAM_DPTTG); + intel_audio_sdp_split_update(pipe_config); + intel_enable_transcoder(pipe_config); intel_crtc_vblank_on(pipe_config); -- 2.34.1
[Intel-gfx] [PATCH v4 3/4] drm/i915/display: update intel_dp_has_audio to support MST
Modify intel_dp_has_audio to handle DP-MST as well. Signed-off-by: Vinod Govindapillai --- drivers/gpu/drm/i915/display/intel_dp.c | 10 ++ 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 67c06bbc1760..0ee9b9e05c26 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -2171,15 +2171,17 @@ intel_dp_drrs_compute_config(struct intel_connector *connector, } static bool intel_dp_has_audio(struct intel_encoder *encoder, + struct intel_crtc_state *crtc_state, const struct drm_connector_state *conn_state) { struct drm_i915_private *i915 = to_i915(encoder->base.dev); - struct intel_dp *intel_dp = enc_to_intel_dp(encoder); - struct intel_connector *connector = intel_dp->attached_connector; const struct intel_digital_connector_state *intel_conn_state = to_intel_digital_connector_state(conn_state); + struct intel_connector *connector = + to_intel_connector(conn_state->connector); - if (!intel_dp_port_has_audio(i915, encoder->port)) + if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP) && + !intel_dp_port_has_audio(i915, encoder->port)) return false; if (intel_conn_state->force_audio == HDMI_AUDIO_AUTO) @@ -2241,7 +2243,7 @@ intel_dp_audio_compute_config(struct intel_encoder *encoder, struct drm_connector *connector = conn_state->connector; pipe_config->has_audio = - intel_dp_has_audio(encoder, conn_state) && + intel_dp_has_audio(encoder, pipe_config, conn_state) && intel_audio_compute_config(encoder, pipe_config, conn_state); pipe_config->sdp_split_enable = pipe_config->has_audio && -- 2.34.1
[Intel-gfx] [PATCH v4 2/4] drm/i915/display: combine DP audio compute config steps
Combine all DP audio configs into a single function Signed-off-by: Vinod Govindapillai --- drivers/gpu/drm/i915/display/intel_dp.c | 11 +-- 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 964bf0551bdc..67c06bbc1760 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -2240,9 +2240,12 @@ intel_dp_audio_compute_config(struct intel_encoder *encoder, struct drm_i915_private *i915 = to_i915(encoder->base.dev); struct drm_connector *connector = conn_state->connector; - pipe_config->sdp_split_enable = + pipe_config->has_audio = intel_dp_has_audio(encoder, conn_state) && - intel_dp_is_uhbr(pipe_config); + intel_audio_compute_config(encoder, pipe_config, conn_state); + + pipe_config->sdp_split_enable = pipe_config->has_audio && + intel_dp_is_uhbr(pipe_config); drm_dbg_kms(>drm, "[CONNECTOR:%d:%s] SDP split enable: %s\n", connector->base.id, connector->name, @@ -2264,10 +2267,6 @@ intel_dp_compute_config(struct intel_encoder *encoder, if (HAS_PCH_SPLIT(dev_priv) && !HAS_DDI(dev_priv) && encoder->port != PORT_A) pipe_config->has_pch_encoder = true; - pipe_config->has_audio = - intel_dp_has_audio(encoder, conn_state) && - intel_audio_compute_config(encoder, pipe_config, conn_state); - fixed_mode = intel_panel_fixed_mode(connector, adjusted_mode); if (intel_dp_is_edp(intel_dp) && fixed_mode) { ret = intel_panel_compute_config(connector, adjusted_mode); -- 2.34.1
[Intel-gfx] [PATCH v4 1/4] drm/i915/display: remove redundant parameter from sdp split update
The needed functionality can be performed using crtc_state here. Signed-off-by: Vinod Govindapillai Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_audio.c | 6 +++--- drivers/gpu/drm/i915/display/intel_audio.h | 3 +-- drivers/gpu/drm/i915/display/intel_ddi.c | 2 +- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_audio.c b/drivers/gpu/drm/i915/display/intel_audio.c index 3d9c9b4f27f8..19605264a35c 100644 --- a/drivers/gpu/drm/i915/display/intel_audio.c +++ b/drivers/gpu/drm/i915/display/intel_audio.c @@ -759,10 +759,10 @@ static void ibx_audio_codec_enable(struct intel_encoder *encoder, mutex_unlock(>display.audio.mutex); } -void intel_audio_sdp_split_update(struct intel_encoder *encoder, - const struct intel_crtc_state *crtc_state) +void intel_audio_sdp_split_update(const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); + struct drm_i915_private *i915 = to_i915(crtc->base.dev); enum transcoder trans = crtc_state->cpu_transcoder; if (HAS_DP20(i915)) diff --git a/drivers/gpu/drm/i915/display/intel_audio.h b/drivers/gpu/drm/i915/display/intel_audio.h index 07d034a981e9..9327954b801e 100644 --- a/drivers/gpu/drm/i915/display/intel_audio.h +++ b/drivers/gpu/drm/i915/display/intel_audio.h @@ -29,7 +29,6 @@ void intel_audio_cdclk_change_pre(struct drm_i915_private *dev_priv); void intel_audio_cdclk_change_post(struct drm_i915_private *dev_priv); void intel_audio_init(struct drm_i915_private *dev_priv); void intel_audio_deinit(struct drm_i915_private *dev_priv); -void intel_audio_sdp_split_update(struct intel_encoder *encoder, - const struct intel_crtc_state *crtc_state); +void intel_audio_sdp_split_update(const struct intel_crtc_state *crtc_state); #endif /* __INTEL_AUDIO_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index 84bbf854337a..b7f4281b8658 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -3248,7 +3248,7 @@ static void intel_enable_ddi(struct intel_atomic_state *state, intel_ddi_enable_transcoder_func(encoder, crtc_state); /* Enable/Disable DP2.0 SDP split config before transcoder */ - intel_audio_sdp_split_update(encoder, crtc_state); + intel_audio_sdp_split_update(crtc_state); intel_enable_transcoder(crtc_state); -- 2.34.1
[Intel-gfx] [PATCH v4 0/4] SDP split for DP-MST
SDP split config for DP-MST v2: Style changes and patch splits (Jani Nikula) v3: More style changes and reorder patches (Jani Nikula) v4: call sdp split register update before enable trancoder in MST Vinod Govindapillai (4): drm/i915/display: remove redundant parameter from sdp split update drm/i915/display: combine DP audio compute config steps drm/i915/display: update intel_dp_has_audio to support MST drm/i915/display: configure SDP split for DP-MST drivers/gpu/drm/i915/display/intel_audio.c | 6 +++--- drivers/gpu/drm/i915/display/intel_audio.h | 3 +-- drivers/gpu/drm/i915/display/intel_ddi.c| 2 +- drivers/gpu/drm/i915/display/intel_dp.c | 23 +++-- drivers/gpu/drm/i915/display/intel_dp.h | 3 +++ drivers/gpu/drm/i915/display/intel_dp_mst.c | 21 --- 6 files changed, 24 insertions(+), 34 deletions(-) -- 2.34.1
[Intel-gfx] [PATCH v3 4/4] drm/i915/display: configure SDP split for DP-MST
Extend the SDP split audio config for DP-MST Signed-off-by: Vinod Govindapillai --- drivers/gpu/drm/i915/display/intel_dp.c | 2 +- drivers/gpu/drm/i915/display/intel_dp.h | 3 +++ drivers/gpu/drm/i915/display/intel_dp_mst.c | 19 ++- 3 files changed, 6 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 0ee9b9e05c26..c1364b164df7 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -2234,7 +2234,7 @@ intel_dp_compute_output_format(struct intel_encoder *encoder, return ret; } -static void +void intel_dp_audio_compute_config(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config, struct drm_connector_state *conn_state) diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h index 22099de3ca45..62aacc89c45d 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.h +++ b/drivers/gpu/drm/i915/display/intel_dp.h @@ -65,6 +65,9 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp, struct link_config_limits *limits, int timeslots, bool recompute_pipe_bpp); +void intel_dp_audio_compute_config(struct intel_encoder *encoder, + struct intel_crtc_state *pipe_config, + struct drm_connector_state *conn_state); bool intel_dp_has_hdmi_sink(struct intel_dp *intel_dp); bool intel_dp_is_edp(struct intel_dp *intel_dp); bool intel_dp_is_uhbr(const struct intel_crtc_state *crtc_state); diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index e3f176a093d2..8fc7802d796b 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -290,19 +290,6 @@ static int intel_dp_mst_update_slots(struct intel_encoder *encoder, return 0; } -static bool intel_dp_mst_has_audio(const struct drm_connector_state *conn_state) -{ - const struct intel_digital_connector_state *intel_conn_state = - to_intel_digital_connector_state(conn_state); - struct intel_connector *connector = - to_intel_connector(conn_state->connector); - - if (intel_conn_state->force_audio == HDMI_AUDIO_AUTO) - return connector->base.display_info.has_audio; - else - return intel_conn_state->force_audio == HDMI_AUDIO_ON; -} - static int intel_dp_mst_compute_config(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config, struct drm_connector_state *conn_state) @@ -322,10 +309,6 @@ static int intel_dp_mst_compute_config(struct intel_encoder *encoder, pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB; pipe_config->has_pch_encoder = false; - pipe_config->has_audio = - intel_dp_mst_has_audio(conn_state) && - intel_audio_compute_config(encoder, pipe_config, conn_state); - /* * for MST we always configure max link bw - the spec doesn't * seem to suggest we should do otherwise. @@ -388,6 +371,8 @@ static int intel_dp_mst_compute_config(struct intel_encoder *encoder, pipe_config->lane_lat_optim_mask = bxt_ddi_phy_calc_lane_lat_optim_mask(pipe_config->lane_count); + intel_dp_audio_compute_config(encoder, pipe_config, conn_state); + intel_ddi_compute_min_voltage_level(dev_priv, pipe_config); return 0; -- 2.34.1
[Intel-gfx] [PATCH v3 3/4] drm/i915/display: update intel_dp_has_audio to support MST
Modify intel_dp_has_audio to handle DP-MST as well. Signed-off-by: Vinod Govindapillai --- drivers/gpu/drm/i915/display/intel_dp.c | 10 ++ 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 67c06bbc1760..0ee9b9e05c26 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -2171,15 +2171,17 @@ intel_dp_drrs_compute_config(struct intel_connector *connector, } static bool intel_dp_has_audio(struct intel_encoder *encoder, + struct intel_crtc_state *crtc_state, const struct drm_connector_state *conn_state) { struct drm_i915_private *i915 = to_i915(encoder->base.dev); - struct intel_dp *intel_dp = enc_to_intel_dp(encoder); - struct intel_connector *connector = intel_dp->attached_connector; const struct intel_digital_connector_state *intel_conn_state = to_intel_digital_connector_state(conn_state); + struct intel_connector *connector = + to_intel_connector(conn_state->connector); - if (!intel_dp_port_has_audio(i915, encoder->port)) + if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP) && + !intel_dp_port_has_audio(i915, encoder->port)) return false; if (intel_conn_state->force_audio == HDMI_AUDIO_AUTO) @@ -2241,7 +2243,7 @@ intel_dp_audio_compute_config(struct intel_encoder *encoder, struct drm_connector *connector = conn_state->connector; pipe_config->has_audio = - intel_dp_has_audio(encoder, conn_state) && + intel_dp_has_audio(encoder, pipe_config, conn_state) && intel_audio_compute_config(encoder, pipe_config, conn_state); pipe_config->sdp_split_enable = pipe_config->has_audio && -- 2.34.1
[Intel-gfx] [PATCH v3 2/4] drm/i915/display: combine DP audio compute config steps
Combine all DP audio configs into a single function Signed-off-by: Vinod Govindapillai --- drivers/gpu/drm/i915/display/intel_dp.c | 11 +-- 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 964bf0551bdc..67c06bbc1760 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -2240,9 +2240,12 @@ intel_dp_audio_compute_config(struct intel_encoder *encoder, struct drm_i915_private *i915 = to_i915(encoder->base.dev); struct drm_connector *connector = conn_state->connector; - pipe_config->sdp_split_enable = + pipe_config->has_audio = intel_dp_has_audio(encoder, conn_state) && - intel_dp_is_uhbr(pipe_config); + intel_audio_compute_config(encoder, pipe_config, conn_state); + + pipe_config->sdp_split_enable = pipe_config->has_audio && + intel_dp_is_uhbr(pipe_config); drm_dbg_kms(>drm, "[CONNECTOR:%d:%s] SDP split enable: %s\n", connector->base.id, connector->name, @@ -2264,10 +2267,6 @@ intel_dp_compute_config(struct intel_encoder *encoder, if (HAS_PCH_SPLIT(dev_priv) && !HAS_DDI(dev_priv) && encoder->port != PORT_A) pipe_config->has_pch_encoder = true; - pipe_config->has_audio = - intel_dp_has_audio(encoder, conn_state) && - intel_audio_compute_config(encoder, pipe_config, conn_state); - fixed_mode = intel_panel_fixed_mode(connector, adjusted_mode); if (intel_dp_is_edp(intel_dp) && fixed_mode) { ret = intel_panel_compute_config(connector, adjusted_mode); -- 2.34.1
[Intel-gfx] [PATCH v3 1/4] drm/i915/display: remove redundant parameter from sdp split update
The needed functionality can be performed using crtc_state here. Signed-off-by: Vinod Govindapillai Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_audio.c | 6 +++--- drivers/gpu/drm/i915/display/intel_audio.h | 3 +-- drivers/gpu/drm/i915/display/intel_ddi.c | 2 +- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_audio.c b/drivers/gpu/drm/i915/display/intel_audio.c index 3d9c9b4f27f8..19605264a35c 100644 --- a/drivers/gpu/drm/i915/display/intel_audio.c +++ b/drivers/gpu/drm/i915/display/intel_audio.c @@ -759,10 +759,10 @@ static void ibx_audio_codec_enable(struct intel_encoder *encoder, mutex_unlock(>display.audio.mutex); } -void intel_audio_sdp_split_update(struct intel_encoder *encoder, - const struct intel_crtc_state *crtc_state) +void intel_audio_sdp_split_update(const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); + struct drm_i915_private *i915 = to_i915(crtc->base.dev); enum transcoder trans = crtc_state->cpu_transcoder; if (HAS_DP20(i915)) diff --git a/drivers/gpu/drm/i915/display/intel_audio.h b/drivers/gpu/drm/i915/display/intel_audio.h index 07d034a981e9..9327954b801e 100644 --- a/drivers/gpu/drm/i915/display/intel_audio.h +++ b/drivers/gpu/drm/i915/display/intel_audio.h @@ -29,7 +29,6 @@ void intel_audio_cdclk_change_pre(struct drm_i915_private *dev_priv); void intel_audio_cdclk_change_post(struct drm_i915_private *dev_priv); void intel_audio_init(struct drm_i915_private *dev_priv); void intel_audio_deinit(struct drm_i915_private *dev_priv); -void intel_audio_sdp_split_update(struct intel_encoder *encoder, - const struct intel_crtc_state *crtc_state); +void intel_audio_sdp_split_update(const struct intel_crtc_state *crtc_state); #endif /* __INTEL_AUDIO_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index 84bbf854337a..b7f4281b8658 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -3248,7 +3248,7 @@ static void intel_enable_ddi(struct intel_atomic_state *state, intel_ddi_enable_transcoder_func(encoder, crtc_state); /* Enable/Disable DP2.0 SDP split config before transcoder */ - intel_audio_sdp_split_update(encoder, crtc_state); + intel_audio_sdp_split_update(crtc_state); intel_enable_transcoder(crtc_state); -- 2.34.1
[Intel-gfx] [PATCH v3 0/4] DP split for DP-MST
SDP split config for DP-MST v2: Style changes and patch splits (Jani Nikula) v3: More style changes and reorder patches (Jani Nikula) Vinod Govindapillai (4): drm/i915/display: remove redundant parameter from sdp split update drm/i915/display: combine DP audio compute config steps drm/i915/display: update intel_dp_has_audio to support MST drm/i915/display: configure SDP split for DP-MST drivers/gpu/drm/i915/display/intel_audio.c | 6 +++--- drivers/gpu/drm/i915/display/intel_audio.h | 3 +-- drivers/gpu/drm/i915/display/intel_ddi.c| 2 +- drivers/gpu/drm/i915/display/intel_dp.c | 23 +++-- drivers/gpu/drm/i915/display/intel_dp.h | 3 +++ drivers/gpu/drm/i915/display/intel_dp_mst.c | 19 ++--- 6 files changed, 22 insertions(+), 34 deletions(-) -- 2.34.1
[Intel-gfx] [PATCH v2 4/4] drm/915/display: configure SDP split for DP-MST
Extend the SDP split audio config for DP-MST Signed-off-by: Vinod Govindapillai --- drivers/gpu/drm/i915/display/intel_dp.c | 2 +- drivers/gpu/drm/i915/display/intel_dp.h | 4 drivers/gpu/drm/i915/display/intel_dp_mst.c | 7 +++ 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 0eb072a78d44..269828e22437 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -2233,7 +2233,7 @@ intel_dp_compute_output_format(struct intel_encoder *encoder, return ret; } -static void +void intel_dp_audio_compute_config(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config, struct drm_connector_state *conn_state, diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h index e7b515b685ac..b8516a34cfaf 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.h +++ b/drivers/gpu/drm/i915/display/intel_dp.h @@ -65,6 +65,10 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp, struct link_config_limits *limits, int timeslots, bool recompute_pipe_bpp); +void intel_dp_audio_compute_config(struct intel_encoder *encoder, + struct intel_crtc_state *pipe_config, + struct drm_connector_state *conn_state, + struct intel_dp *intel_dp); bool intel_dp_has_hdmi_sink(struct intel_dp *intel_dp); bool intel_dp_is_edp(struct intel_dp *intel_dp); bool intel_dp_is_uhbr(const struct intel_crtc_state *crtc_state); diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index 8881cfd41ee7..05228c006a1b 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -309,10 +309,6 @@ static int intel_dp_mst_compute_config(struct intel_encoder *encoder, pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB; pipe_config->has_pch_encoder = false; - pipe_config->has_audio = - intel_dp_has_audio(encoder, conn_state, intel_dp) && - intel_audio_compute_config(encoder, pipe_config, conn_state); - /* * for MST we always configure max link bw - the spec doesn't * seem to suggest we should do otherwise. @@ -375,6 +371,7 @@ static int intel_dp_mst_compute_config(struct intel_encoder *encoder, pipe_config->lane_lat_optim_mask = bxt_ddi_phy_calc_lane_lat_optim_mask(pipe_config->lane_count); + intel_dp_audio_compute_config(encoder, pipe_config, conn_state, intel_dp); intel_ddi_compute_min_voltage_level(dev_priv, pipe_config); return 0; @@ -779,6 +776,8 @@ static void intel_mst_enable_dp(struct intel_atomic_state *state, intel_de_rmw(dev_priv, CHICKEN_TRANS(trans), 0, FECSTALL_DIS_DPTSTREAM_DPTTG); + intel_audio_sdp_split_update(pipe_config); + intel_enable_transcoder(pipe_config); intel_crtc_vblank_on(pipe_config); -- 2.34.1