Merge tag 'drm-intel-next-2025-03-10' of https://gitlab.freedesktop.org/drm/i915/kernel into drm-next

drm/i915 feature pull #2 for v6.15:

Features and functionality:
- FBC dirty rectangle support for display version 30+ (Vinod)
- Update plane scalers via DSB based commits (Ville)
- Move runtime power status info to display power debugfs (Jani)

Refactoring and cleanups:
- Convert i915 and xe to DRM client setup (Thomas)
- Refactor and clean up CDCLK/bw/dbuf readout/sanitation (Ville)
- Conversions from drm_i915_private to struct intel_display (Jani, Suraj)
- Refactor display reset for better separation between display and core (Jani)
- Move panel fitter code together (Jani)
- Add mst and hdcp sub-structs to display structs for clarity (Jani)
- Header refactoring to clarify separation between display and i915 core (Jani)

Fixes:
- Fix DP MST max stream count to match number of pipes (Jani)
- Fix encoder HW state readout of DP MST UHBR (Imre)
- Fix ICL+ combo PHY cursor and coeff polarity programming (Ville)
- Fix pipeDMC and ATS fault handling (Ville)
- Display workarounds (Gustavo)
- Remove duplicate forward declaration (Vinod)
- Improve POWER_DOMAIN_*() macro type safety (Gustavo)
- Move CDCLK post plane programming later (Ville)

DRM core changes:
- Add client-hotplug helper (Thomas)
- Send pending hotplug events after client resume (Thomas)
- Add fb_restore and fb_set_suspend fb helper hooks (Thomas)
- Remove struct fb_probe fb helper hook (Thomas)
- Add const qualifier to drm_atomic_helper_damage_merged() (Vinod)

Xe driver changes:
- Convert i915 and xe to DRM client setup (Thomas)
- Refactor i915 compat headers (Jani)
- Fix fbdev GGTT mapping handling (Maarten)
- Figure out pxp instance from the gem object (Jani)

Merges:
- Backmerge drm-next to fix conflicts with drm-xe-next (Jani)

Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/87o6y9gpub.fsf@intel.com
This commit is contained in:
Dave Airlie 2025-03-11 12:15:48 +10:00
commit e5dc4f665d
124 changed files with 2545 additions and 2374 deletions

View File

@ -49,6 +49,29 @@ void drm_client_dev_unregister(struct drm_device *dev)
}
EXPORT_SYMBOL(drm_client_dev_unregister);
static void drm_client_hotplug(struct drm_client_dev *client)
{
struct drm_device *dev = client->dev;
int ret;
if (!client->funcs || !client->funcs->hotplug)
return;
if (client->hotplug_failed)
return;
if (client->suspended) {
client->hotplug_pending = true;
return;
}
client->hotplug_pending = false;
ret = client->funcs->hotplug(client);
drm_dbg_kms(dev, "%s: ret=%d\n", client->name, ret);
if (ret)
client->hotplug_failed = true;
}
/**
* drm_client_dev_hotplug - Send hotplug event to clients
* @dev: DRM device
@ -61,7 +84,6 @@ EXPORT_SYMBOL(drm_client_dev_unregister);
void drm_client_dev_hotplug(struct drm_device *dev)
{
struct drm_client_dev *client;
int ret;
if (!drm_core_check_feature(dev, DRIVER_MODESET))
return;
@ -72,18 +94,8 @@ void drm_client_dev_hotplug(struct drm_device *dev)
}
mutex_lock(&dev->clientlist_mutex);
list_for_each_entry(client, &dev->clientlist, list) {
if (!client->funcs || !client->funcs->hotplug)
continue;
if (client->hotplug_failed)
continue;
ret = client->funcs->hotplug(client);
drm_dbg_kms(dev, "%s: ret=%d\n", client->name, ret);
if (ret)
client->hotplug_failed = true;
}
list_for_each_entry(client, &dev->clientlist, list)
drm_client_hotplug(client);
mutex_unlock(&dev->clientlist_mutex);
}
EXPORT_SYMBOL(drm_client_dev_hotplug);
@ -153,6 +165,9 @@ static int drm_client_resume(struct drm_client_dev *client, bool holds_console_l
client->suspended = false;
if (client->hotplug_pending)
drm_client_hotplug(client);
return ret;
}

View File

@ -308,7 +308,7 @@ EXPORT_SYMBOL(drm_atomic_helper_damage_iter_next);
* True if there is valid plane damage otherwise false.
*/
bool drm_atomic_helper_damage_merged(const struct drm_plane_state *old_state,
struct drm_plane_state *state,
const struct drm_plane_state *state,
struct drm_rect *rect)
{
struct drm_atomic_helper_damage_iter iter;

View File

@ -245,6 +245,9 @@ __drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper,
if (do_delayed)
drm_fb_helper_hotplug_event(fb_helper);
if (fb_helper->funcs->fb_restore)
fb_helper->funcs->fb_restore(fb_helper);
return ret;
}
@ -754,7 +757,12 @@ EXPORT_SYMBOL(drm_fb_helper_deferred_io);
*/
void drm_fb_helper_set_suspend(struct drm_fb_helper *fb_helper, bool suspend)
{
if (fb_helper && fb_helper->info)
if (!fb_helper || !fb_helper->info)
return;
if (fb_helper->funcs->fb_set_suspend)
fb_helper->funcs->fb_set_suspend(fb_helper, suspend);
else
fb_set_suspend(fb_helper->info, suspend);
}
EXPORT_SYMBOL(drm_fb_helper_set_suspend);
@ -800,7 +808,7 @@ void drm_fb_helper_set_suspend_unlocked(struct drm_fb_helper *fb_helper,
}
}
fb_set_suspend(fb_helper->info, suspend);
drm_fb_helper_set_suspend(fb_helper, suspend);
console_unlock();
}
EXPORT_SYMBOL(drm_fb_helper_set_suspend_unlocked);
@ -1626,6 +1634,9 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper)
struct fb_info *info;
int ret;
if (drm_WARN_ON(dev, !dev->driver->fbdev_probe))
return -EINVAL;
ret = drm_fb_helper_find_sizes(fb_helper, &sizes);
if (ret) {
/* First time: disable all crtc's.. */
@ -1635,10 +1646,7 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper)
}
/* push down into drivers */
if (dev->driver->fbdev_probe)
ret = dev->driver->fbdev_probe(fb_helper, &sizes);
else if (fb_helper->funcs)
ret = fb_helper->funcs->fb_probe(fb_helper, &sizes);
ret = dev->driver->fbdev_probe(fb_helper, &sizes);
if (ret < 0)
return ret;

View File

@ -1311,7 +1311,7 @@ bool g4x_dp_init(struct intel_display *display,
intel_encoder->devdata = devdata;
mutex_init(&dig_port->hdcp_mutex);
mutex_init(&dig_port->hdcp.mutex);
if (drm_encoder_init(display->drm, &intel_encoder->base,
&intel_dp_enc_funcs, DRM_MODE_ENCODER_TMDS,

View File

@ -715,7 +715,7 @@ bool g4x_hdmi_init(struct intel_display *display,
intel_encoder->devdata = devdata;
mutex_init(&dig_port->hdcp_mutex);
mutex_init(&dig_port->hdcp.mutex);
if (drm_encoder_init(display->drm, &intel_encoder->base,
&intel_hdmi_enc_funcs, DRM_MODE_ENCODER_TMDS,

View File

@ -3902,12 +3902,6 @@ static void g4x_wm_sanitize(struct drm_i915_private *dev_priv)
mutex_unlock(&dev_priv->display.wm.wm_mutex);
}
static void g4x_wm_get_hw_state_and_sanitize(struct drm_i915_private *i915)
{
g4x_wm_get_hw_state(i915);
g4x_wm_sanitize(i915);
}
static void vlv_wm_get_hw_state(struct drm_i915_private *dev_priv)
{
struct vlv_wm_values *wm = &dev_priv->display.wm.vlv;
@ -4055,12 +4049,6 @@ static void vlv_wm_sanitize(struct drm_i915_private *dev_priv)
mutex_unlock(&dev_priv->display.wm.wm_mutex);
}
static void vlv_wm_get_hw_state_and_sanitize(struct drm_i915_private *i915)
{
vlv_wm_get_hw_state(i915);
vlv_wm_sanitize(i915);
}
/*
* FIXME should probably kill this and improve
* the real watermark readout/sanitation instead
@ -4122,14 +4110,16 @@ static const struct intel_wm_funcs vlv_wm_funcs = {
.initial_watermarks = vlv_initial_watermarks,
.optimize_watermarks = vlv_optimize_watermarks,
.atomic_update_watermarks = vlv_atomic_update_fifo,
.get_hw_state = vlv_wm_get_hw_state_and_sanitize,
.get_hw_state = vlv_wm_get_hw_state,
.sanitize = vlv_wm_sanitize,
};
static const struct intel_wm_funcs g4x_wm_funcs = {
.compute_watermarks = g4x_compute_watermarks,
.initial_watermarks = g4x_initial_watermarks,
.optimize_watermarks = g4x_optimize_watermarks,
.get_hw_state = g4x_wm_get_hw_state_and_sanitize,
.get_hw_state = g4x_wm_get_hw_state,
.sanitize = g4x_wm_sanitize,
};
static const struct intel_wm_funcs pnv_wm_funcs = {

View File

@ -1647,7 +1647,7 @@ static int gen11_dsi_compute_config(struct intel_encoder *encoder,
if (ret)
return ret;
ret = intel_panel_fitting(pipe_config, conn_state);
ret = intel_pfit_compute_config(pipe_config, conn_state);
if (ret)
return ret;

View File

@ -9,6 +9,8 @@
#include <linux/acpi.h>
#include <acpi/video.h>
#include <drm/drm_print.h>
#include "i915_utils.h"
#include "intel_acpi.h"
#include "intel_display_core.h"

View File

@ -14,7 +14,6 @@ struct drm_connector_state;
struct drm_crtc;
struct drm_crtc_state;
struct drm_device;
struct drm_i915_private;
struct drm_property;
struct intel_atomic_state;
struct intel_connector;

View File

@ -36,12 +36,15 @@
#include <drm/drm_atomic_helper.h>
#include <drm/drm_blend.h>
#include <drm/drm_damage_helper.h>
#include <drm/drm_fourcc.h>
#include <drm/drm_gem.h>
#include <drm/drm_gem_atomic_helper.h>
#include "i915_drv.h"
#include "gem/i915_gem_object.h"
#include "i915_config.h"
#include "i915_scheduler_types.h"
#include "i915_vma.h"
#include "i9xx_plane_regs.h"
#include "intel_atomic_plane.h"
#include "intel_cdclk.h"
@ -131,6 +134,7 @@ intel_plane_duplicate_state(struct drm_plane *plane)
intel_state->ggtt_vma = NULL;
intel_state->dpt_vma = NULL;
intel_state->flags = 0;
intel_state->damage = DRM_RECT_INIT(0, 0, 0, 0);
/* add reference to fb */
if (intel_state->hw.fb)
@ -164,10 +168,10 @@ intel_plane_destroy_state(struct drm_plane *plane,
bool intel_plane_needs_physical(struct intel_plane *plane)
{
struct drm_i915_private *i915 = to_i915(plane->base.dev);
struct intel_display *display = to_intel_display(plane);
return plane->id == PLANE_CURSOR &&
DISPLAY_INFO(i915)->cursor_needs_physical;
DISPLAY_INFO(display)->cursor_needs_physical;
}
bool intel_plane_can_async_flip(struct intel_plane *plane, u64 modifier)
@ -272,7 +276,7 @@ int intel_plane_calc_min_cdclk(struct intel_atomic_state *state,
struct intel_plane *plane,
bool *need_cdclk_calc)
{
struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
struct intel_display *display = to_intel_display(plane);
const struct intel_plane_state *plane_state =
intel_atomic_get_new_plane_state(state, plane);
struct intel_crtc *crtc = to_intel_crtc(plane_state->hw.crtc);
@ -317,7 +321,7 @@ int intel_plane_calc_min_cdclk(struct intel_atomic_state *state,
cdclk_state->min_cdclk[crtc->pipe])
return 0;
drm_dbg_kms(&dev_priv->drm,
drm_dbg_kms(display->drm,
"[PLANE:%d:%s] min cdclk (%d kHz) > [CRTC:%d:%s] min cdclk (%d kHz)\n",
plane->base.base.id, plane->base.name,
new_crtc_state->min_cdclk[plane->id],
@ -336,6 +340,25 @@ static void intel_plane_clear_hw_state(struct intel_plane_state *plane_state)
memset(&plane_state->hw, 0, sizeof(plane_state->hw));
}
static void
intel_plane_copy_uapi_plane_damage(struct intel_plane_state *new_plane_state,
const struct intel_plane_state *old_uapi_plane_state,
const struct intel_plane_state *new_uapi_plane_state)
{
struct intel_display *display = to_intel_display(new_plane_state);
struct drm_rect *damage = &new_plane_state->damage;
/* damage property tracking enabled from display version 12 onwards */
if (DISPLAY_VER(display) < 12)
return;
if (!drm_atomic_helper_damage_merged(&old_uapi_plane_state->uapi,
&new_uapi_plane_state->uapi,
damage))
/* Incase helper fails, mark whole plane region as damage */
*damage = drm_plane_state_src(&new_uapi_plane_state->uapi);
}
void intel_plane_copy_uapi_to_hw_state(struct intel_plane_state *plane_state,
const struct intel_plane_state *from_plane_state,
struct intel_crtc *crtc)
@ -411,7 +434,7 @@ static bool intel_plane_do_async_flip(struct intel_plane *plane,
const struct intel_crtc_state *old_crtc_state,
const struct intel_crtc_state *new_crtc_state)
{
struct drm_i915_private *i915 = to_i915(plane->base.dev);
struct intel_display *display = to_intel_display(plane);
if (!plane->async_flip)
return false;
@ -432,7 +455,7 @@ static bool intel_plane_do_async_flip(struct intel_plane *plane,
* extend this so other scanout parameters (stride/etc) could
* be changed as well...
*/
return DISPLAY_VER(i915) < 9 || old_crtc_state->uapi.async_flip;
return DISPLAY_VER(display) < 9 || old_crtc_state->uapi.async_flip;
}
static bool i9xx_must_disable_cxsr(const struct intel_crtc_state *new_crtc_state,
@ -536,16 +559,16 @@ static int intel_plane_atomic_calc_changes(const struct intel_crtc_state *old_cr
const struct intel_plane_state *old_plane_state,
struct intel_plane_state *new_plane_state)
{
struct intel_display *display = to_intel_display(new_crtc_state);
struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
struct intel_plane *plane = to_intel_plane(new_plane_state->uapi.plane);
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
bool mode_changed = intel_crtc_needs_modeset(new_crtc_state);
bool was_crtc_enabled = old_crtc_state->hw.active;
bool is_crtc_enabled = new_crtc_state->hw.active;
bool turn_off, turn_on, visible, was_visible;
int ret;
if (DISPLAY_VER(dev_priv) >= 9 && plane->id != PLANE_CURSOR) {
if (DISPLAY_VER(display) >= 9 && plane->id != PLANE_CURSOR) {
ret = skl_update_scaler_plane(new_crtc_state, new_plane_state);
if (ret)
return ret;
@ -554,7 +577,7 @@ static int intel_plane_atomic_calc_changes(const struct intel_crtc_state *old_cr
was_visible = old_plane_state->uapi.visible;
visible = new_plane_state->uapi.visible;
if (!was_crtc_enabled && drm_WARN_ON(&dev_priv->drm, was_visible))
if (!was_crtc_enabled && drm_WARN_ON(display->drm, was_visible))
was_visible = false;
/*
@ -578,7 +601,7 @@ static int intel_plane_atomic_calc_changes(const struct intel_crtc_state *old_cr
turn_off = was_visible && (!visible || mode_changed);
turn_on = visible && (!was_visible || mode_changed);
drm_dbg_atomic(&dev_priv->drm,
drm_dbg_atomic(display->drm,
"[CRTC:%d:%s] with [PLANE:%d:%s] visible %i -> %i, off %i, on %i, ms %i\n",
crtc->base.base.id, crtc->base.name,
plane->base.base.id, plane->base.name,
@ -588,11 +611,11 @@ static int intel_plane_atomic_calc_changes(const struct intel_crtc_state *old_cr
if (visible || was_visible)
new_crtc_state->fb_bits |= plane->frontbuffer_bit;
if (HAS_GMCH(dev_priv) &&
if (HAS_GMCH(display) &&
i9xx_must_disable_cxsr(new_crtc_state, old_plane_state, new_plane_state))
new_crtc_state->disable_cxsr = true;
if ((IS_IRONLAKE(dev_priv) || IS_SANDYBRIDGE(dev_priv) || IS_IVYBRIDGE(dev_priv)) &&
if ((display->platform.ironlake || display->platform.sandybridge || display->platform.ivybridge) &&
ilk_must_disable_cxsr(new_crtc_state, old_plane_state, new_plane_state))
new_crtc_state->disable_cxsr = true;
@ -685,10 +708,10 @@ int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_
struct intel_plane *
intel_crtc_get_plane(struct intel_crtc *crtc, enum plane_id plane_id)
{
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
struct intel_display *display = to_intel_display(crtc);
struct intel_plane *plane;
for_each_intel_plane_on_crtc(&i915->drm, crtc, plane) {
for_each_intel_plane_on_crtc(display->drm, crtc, plane) {
if (plane->id == plane_id)
return plane;
}
@ -705,6 +728,7 @@ int intel_plane_atomic_check(struct intel_atomic_state *state,
const struct intel_plane_state *old_plane_state =
intel_atomic_get_old_plane_state(state, plane);
const struct intel_plane_state *new_primary_crtc_plane_state;
const struct intel_plane_state *old_primary_crtc_plane_state;
struct intel_crtc *crtc = intel_crtc_for_pipe(display, plane->pipe);
const struct intel_crtc_state *old_crtc_state =
intel_atomic_get_old_crtc_state(state, crtc);
@ -719,10 +743,17 @@ int intel_plane_atomic_check(struct intel_atomic_state *state,
new_primary_crtc_plane_state =
intel_atomic_get_new_plane_state(state, primary_crtc_plane);
old_primary_crtc_plane_state =
intel_atomic_get_old_plane_state(state, primary_crtc_plane);
} else {
new_primary_crtc_plane_state = new_plane_state;
old_primary_crtc_plane_state = old_plane_state;
}
intel_plane_copy_uapi_plane_damage(new_plane_state,
old_primary_crtc_plane_state,
new_primary_crtc_plane_state);
intel_plane_copy_uapi_to_hw_state(new_plane_state,
new_primary_crtc_plane_state,
crtc);
@ -788,6 +819,9 @@ void intel_plane_update_noarm(struct intel_dsb *dsb,
trace_intel_plane_update_noarm(plane_state, crtc);
if (plane->fbc)
intel_fbc_dirty_rect_update_noarm(dsb, plane);
if (plane->update_noarm)
plane->update_noarm(dsb, plane, crtc_state, plane_state);
}
@ -926,9 +960,9 @@ void intel_crtc_planes_update_arm(struct intel_dsb *dsb,
struct intel_atomic_state *state,
struct intel_crtc *crtc)
{
struct drm_i915_private *i915 = to_i915(state->base.dev);
struct intel_display *display = to_intel_display(state);
if (DISPLAY_VER(i915) >= 9)
if (DISPLAY_VER(display) >= 9)
skl_crtc_planes_update_arm(dsb, state, crtc);
else
i9xx_crtc_planes_update_arm(dsb, state, crtc);
@ -939,7 +973,7 @@ int intel_atomic_plane_check_clipping(struct intel_plane_state *plane_state,
int min_scale, int max_scale,
bool can_position)
{
struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev);
struct intel_display *display = to_intel_display(plane_state);
struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
struct drm_framebuffer *fb = plane_state->hw.fb;
struct drm_rect *src = &plane_state->uapi.src;
@ -959,7 +993,7 @@ int intel_atomic_plane_check_clipping(struct intel_plane_state *plane_state,
hscale = drm_rect_calc_hscale(src, dst, min_scale, max_scale);
vscale = drm_rect_calc_vscale(src, dst, min_scale, max_scale);
if (hscale < 0 || vscale < 0) {
drm_dbg_kms(&i915->drm,
drm_dbg_kms(display->drm,
"[PLANE:%d:%s] invalid scaling "DRM_RECT_FP_FMT " -> " DRM_RECT_FMT "\n",
plane->base.base.id, plane->base.name,
DRM_RECT_FP_ARG(src), DRM_RECT_ARG(dst));
@ -976,7 +1010,7 @@ int intel_atomic_plane_check_clipping(struct intel_plane_state *plane_state,
if (!can_position && plane_state->uapi.visible &&
!drm_rect_equals(dst, clip)) {
drm_dbg_kms(&i915->drm,
drm_dbg_kms(display->drm,
"[PLANE:%d:%s] plane (" DRM_RECT_FMT ") must cover entire CRTC (" DRM_RECT_FMT ")\n",
plane->base.base.id, plane->base.name,
DRM_RECT_ARG(dst), DRM_RECT_ARG(clip));
@ -991,7 +1025,7 @@ int intel_atomic_plane_check_clipping(struct intel_plane_state *plane_state,
int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state)
{
struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev);
struct intel_display *display = to_intel_display(plane_state);
struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
const struct drm_framebuffer *fb = plane_state->hw.fb;
struct drm_rect *src = &plane_state->uapi.src;
@ -1025,18 +1059,18 @@ int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state)
if (fb->format->format == DRM_FORMAT_RGB565 && rotated) {
hsub = 2;
vsub = 2;
} else if (DISPLAY_VER(i915) >= 20 &&
} else if (DISPLAY_VER(display) >= 20 &&
intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier)) {
/*
* This allows NV12 and P0xx formats to have odd size and/or odd
* source coordinates on DISPLAY_VER(i915) >= 20
* source coordinates on DISPLAY_VER(display) >= 20
*/
hsub = 1;
vsub = 1;
/* Wa_16023981245 */
if ((DISPLAY_VERx100(i915) == 2000 ||
DISPLAY_VERx100(i915) == 3000) &&
if ((DISPLAY_VERx100(display) == 2000 ||
DISPLAY_VERx100(display) == 3000) &&
src_x % 2 != 0)
hsub = 2;
} else {
@ -1048,7 +1082,7 @@ int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state)
hsub = vsub = max(hsub, vsub);
if (src_x % hsub || src_w % hsub) {
drm_dbg_kms(&i915->drm,
drm_dbg_kms(display->drm,
"[PLANE:%d:%s] src x/w (%u, %u) must be a multiple of %u (rotated: %s)\n",
plane->base.base.id, plane->base.name,
src_x, src_w, hsub, str_yes_no(rotated));
@ -1056,7 +1090,7 @@ int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state)
}
if (src_y % vsub || src_h % vsub) {
drm_dbg_kms(&i915->drm,
drm_dbg_kms(display->drm,
"[PLANE:%d:%s] src y/h (%u, %u) must be a multiple of %u (rotated: %s)\n",
plane->base.base.id, plane->base.name,
src_y, src_h, vsub, str_yes_no(rotated));
@ -1119,11 +1153,11 @@ intel_prepare_plane_fb(struct drm_plane *_plane,
{
struct i915_sched_attr attr = { .priority = I915_PRIORITY_DISPLAY };
struct intel_plane *plane = to_intel_plane(_plane);
struct intel_display *display = to_intel_display(plane);
struct intel_plane_state *new_plane_state =
to_intel_plane_state(_new_plane_state);
struct intel_atomic_state *state =
to_intel_atomic_state(new_plane_state->uapi.state);
struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
struct intel_plane_state *old_plane_state =
intel_atomic_get_old_plane_state(state, plane);
struct drm_gem_object *obj = intel_fb_bo(new_plane_state->hw.fb);
@ -1181,7 +1215,7 @@ intel_prepare_plane_fb(struct drm_plane *_plane,
* that are not quite steady state without resorting to forcing
* maximum clocks following a vblank miss (see do_rps_boost()).
*/
intel_display_rps_mark_interactive(dev_priv, state, true);
intel_display_rps_mark_interactive(display, state, true);
return 0;
@ -1202,17 +1236,17 @@ static void
intel_cleanup_plane_fb(struct drm_plane *plane,
struct drm_plane_state *_old_plane_state)
{
struct intel_display *display = to_intel_display(plane->dev);
struct intel_plane_state *old_plane_state =
to_intel_plane_state(_old_plane_state);
struct intel_atomic_state *state =
to_intel_atomic_state(old_plane_state->uapi.state);
struct drm_i915_private *dev_priv = to_i915(plane->dev);
struct drm_gem_object *obj = intel_fb_bo(old_plane_state->hw.fb);
if (!obj)
return;
intel_display_rps_mark_interactive(dev_priv, state, false);
intel_display_rps_mark_interactive(display, state, false);
intel_plane_unpin_fb(old_plane_state);
}
@ -1301,14 +1335,13 @@ static int icl_check_nv12_planes(struct intel_atomic_state *state,
struct intel_crtc *crtc)
{
struct intel_display *display = to_intel_display(state);
struct drm_i915_private *dev_priv = to_i915(state->base.dev);
struct intel_crtc_state *crtc_state =
intel_atomic_get_new_crtc_state(state, crtc);
struct intel_plane_state *plane_state;
struct intel_plane *plane;
int i;
if (DISPLAY_VER(dev_priv) < 11)
if (DISPLAY_VER(display) < 11)
return 0;
/*
@ -1336,7 +1369,7 @@ static int icl_check_nv12_planes(struct intel_atomic_state *state,
if ((crtc_state->nv12_planes & BIT(plane->id)) == 0)
continue;
for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, y_plane) {
for_each_intel_plane_on_crtc(display->drm, crtc, y_plane) {
if (!icl_is_nv12_y_plane(display, y_plane->id))
continue;
@ -1351,7 +1384,7 @@ static int icl_check_nv12_planes(struct intel_atomic_state *state,
}
if (!y_plane_state) {
drm_dbg_kms(&dev_priv->drm,
drm_dbg_kms(display->drm,
"[CRTC:%d:%s] need %d free Y planes for planar YUV\n",
crtc->base.base.id, crtc->base.name,
hweight8(crtc_state->nv12_planes));
@ -1368,10 +1401,10 @@ static int intel_crtc_add_planes_to_state(struct intel_atomic_state *state,
struct intel_crtc *crtc,
u8 plane_ids_mask)
{
struct drm_i915_private *dev_priv = to_i915(state->base.dev);
struct intel_display *display = to_intel_display(state);
struct intel_plane *plane;
for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, plane) {
for_each_intel_plane_on_crtc(display->drm, crtc, plane) {
struct intel_plane_state *plane_state;
if ((plane_ids_mask & BIT(plane->id)) == 0)
@ -1398,12 +1431,12 @@ int intel_atomic_add_affected_planes(struct intel_atomic_state *state,
new_crtc_state->enabled_planes);
}
static bool active_planes_affects_min_cdclk(struct drm_i915_private *dev_priv)
static bool active_planes_affects_min_cdclk(struct intel_display *display)
{
/* See {hsw,vlv,ivb}_plane_ratio() */
return IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv) ||
IS_CHERRYVIEW(dev_priv) || IS_VALLEYVIEW(dev_priv) ||
IS_IVYBRIDGE(dev_priv);
return display->platform.broadwell || display->platform.haswell ||
display->platform.cherryview || display->platform.valleyview ||
display->platform.ivybridge;
}
static u8 intel_joiner_affected_planes(struct intel_atomic_state *state,
@ -1482,7 +1515,7 @@ static int intel_add_affected_planes(struct intel_atomic_state *state)
int intel_atomic_check_planes(struct intel_atomic_state *state)
{
struct drm_i915_private *dev_priv = to_i915(state->base.dev);
struct intel_display *display = to_intel_display(state);
struct intel_crtc_state *old_crtc_state, *new_crtc_state;
struct intel_plane_state __maybe_unused *plane_state;
struct intel_plane *plane;
@ -1496,7 +1529,7 @@ int intel_atomic_check_planes(struct intel_atomic_state *state)
for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
ret = intel_plane_atomic_check(state, plane);
if (ret) {
drm_dbg_atomic(&dev_priv->drm,
drm_dbg_atomic(display->drm,
"[PLANE:%d:%s] atomic driver check failed\n",
plane->base.base.id, plane->base.name);
return ret;
@ -1516,7 +1549,7 @@ int intel_atomic_check_planes(struct intel_atomic_state *state)
* the planes' minimum cdclk calculation. Add such planes
* to the state before we compute the minimum cdclk.
*/
if (!active_planes_affects_min_cdclk(dev_priv))
if (!active_planes_affects_min_cdclk(display))
continue;
old_active_planes = old_crtc_state->active_planes & ~BIT(PLANE_CURSOR);
@ -1532,3 +1565,8 @@ int intel_atomic_check_planes(struct intel_atomic_state *state)
return 0;
}
u32 intel_plane_ggtt_offset(const struct intel_plane_state *plane_state)
{
return i915_ggtt_offset(plane_state->ggtt_vma);
}

View File

@ -88,4 +88,6 @@ int intel_atomic_add_affected_planes(struct intel_atomic_state *state,
struct intel_crtc *crtc);
int intel_atomic_check_planes(struct intel_atomic_state *state);
u32 intel_plane_ggtt_offset(const struct intel_plane_state *plane_state);
#endif /* __INTEL_ATOMIC_PLANE_H__ */

View File

@ -190,7 +190,9 @@ static const struct hdmi_aud_ncts hdmi_aud_ncts_36bpp[] = {
*/
static bool needs_wa_14020863754(struct intel_display *display)
{
return DISPLAY_VER(display) == 20 || display->platform.battlemage;
return DISPLAY_VERx100(display) == 3000 ||
DISPLAY_VERx100(display) == 2000 ||
DISPLAY_VERx100(display) == 1401;
}
/* get AUD_CONFIG_PIXEL_CLOCK_HDMI_* value for mode */

View File

@ -2902,7 +2902,6 @@ init_vbt_panel_defaults(struct intel_panel *panel)
static void
init_vbt_missing_defaults(struct intel_display *display)
{
struct drm_i915_private *i915 = to_i915(display->drm);
unsigned int ports = DISPLAY_RUNTIME_INFO(display)->port_mask;
enum port port;
@ -2912,13 +2911,13 @@ init_vbt_missing_defaults(struct intel_display *display)
for_each_port_masked(port, ports) {
struct intel_bios_encoder_data *devdata;
struct child_device_config *child;
enum phy phy = intel_port_to_phy(i915, port);
enum phy phy = intel_port_to_phy(display, port);
/*
* VBT has the TypeC mode (native,TBT/USB) and we don't want
* to detect it.
*/
if (intel_phy_is_tc(i915, phy))
if (intel_phy_is_tc(display, phy))
continue;
/* Create fake child device config */

View File

@ -806,24 +806,6 @@ static int intel_bw_crtc_min_cdclk(const struct intel_crtc_state *crtc_state)
return DIV_ROUND_UP_ULL(mul_u32_u32(intel_bw_crtc_data_rate(crtc_state), 10), 512);
}
void intel_bw_crtc_update(struct intel_bw_state *bw_state,
const struct intel_crtc_state *crtc_state)
{
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
bw_state->data_rate[crtc->pipe] =
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(&i915->drm, "pipe %c data rate %u num active planes %u\n",
pipe_name(crtc->pipe),
bw_state->data_rate[crtc->pipe],
bw_state->num_active_planes[crtc->pipe]);
}
static unsigned int intel_bw_num_active_planes(struct drm_i915_private *dev_priv,
const struct intel_bw_state *bw_state)
{
@ -1422,6 +1404,62 @@ int intel_bw_atomic_check(struct intel_atomic_state *state)
return 0;
}
static void intel_bw_crtc_update(struct intel_bw_state *bw_state,
const struct intel_crtc_state *crtc_state)
{
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
bw_state->data_rate[crtc->pipe] =
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(&i915->drm, "pipe %c data rate %u num active planes %u\n",
pipe_name(crtc->pipe),
bw_state->data_rate[crtc->pipe],
bw_state->num_active_planes[crtc->pipe]);
}
void intel_bw_update_hw_state(struct intel_display *display)
{
struct intel_bw_state *bw_state =
to_intel_bw_state(display->bw.obj.state);
struct intel_crtc *crtc;
if (DISPLAY_VER(display) < 9)
return;
bw_state->active_pipes = 0;
for_each_intel_crtc(display->drm, crtc) {
const struct intel_crtc_state *crtc_state =
to_intel_crtc_state(crtc->base.state);
enum pipe pipe = crtc->pipe;
if (crtc_state->hw.active)
bw_state->active_pipes |= BIT(pipe);
if (DISPLAY_VER(display) >= 11)
intel_bw_crtc_update(bw_state, crtc_state);
}
}
void intel_bw_crtc_disable_noatomic(struct intel_crtc *crtc)
{
struct intel_display *display = to_intel_display(crtc);
struct intel_bw_state *bw_state =
to_intel_bw_state(display->bw.obj.state);
enum pipe pipe = crtc->pipe;
if (DISPLAY_VER(display) < 9)
return;
bw_state->data_rate[pipe] = 0;
bw_state->num_active_planes[pipe] = 0;
}
static struct intel_global_state *
intel_bw_duplicate_state(struct intel_global_obj *obj)
{

View File

@ -14,7 +14,9 @@
struct drm_i915_private;
struct intel_atomic_state;
struct intel_crtc;
struct intel_crtc_state;
struct intel_display;
struct intel_dbuf_bw {
unsigned int max_bw[I915_MAX_DBUF_SLICES];
@ -73,13 +75,13 @@ intel_atomic_get_bw_state(struct intel_atomic_state *state);
void intel_bw_init_hw(struct drm_i915_private *dev_priv);
int intel_bw_init(struct drm_i915_private *dev_priv);
int intel_bw_atomic_check(struct intel_atomic_state *state);
void intel_bw_crtc_update(struct intel_bw_state *bw_state,
const struct intel_crtc_state *crtc_state);
int icl_pcode_restrict_qgv_points(struct drm_i915_private *dev_priv,
u32 points_mask);
int intel_bw_calc_min_cdclk(struct intel_atomic_state *state,
bool *need_cdclk_calc);
int intel_bw_min_cdclk(struct drm_i915_private *i915,
const struct intel_bw_state *bw_state);
void intel_bw_update_hw_state(struct intel_display *display);
void intel_bw_crtc_disable_noatomic(struct intel_crtc *crtc);
#endif /* __INTEL_BW_H__ */

View File

@ -2788,7 +2788,7 @@ static int intel_planes_min_cdclk(const struct intel_crtc_state *crtc_state)
return min_cdclk;
}
int intel_crtc_compute_min_cdclk(const struct intel_crtc_state *crtc_state)
static int intel_crtc_compute_min_cdclk(const struct intel_crtc_state *crtc_state)
{
int min_cdclk;
@ -3340,6 +3340,34 @@ int intel_modeset_calc_cdclk(struct intel_atomic_state *state)
return 0;
}
void intel_cdclk_update_hw_state(struct intel_display *display)
{
struct intel_cdclk_state *cdclk_state =
to_intel_cdclk_state(display->cdclk.obj.state);
struct intel_crtc *crtc;
cdclk_state->active_pipes = 0;
for_each_intel_crtc(display->drm, crtc) {
const struct intel_crtc_state *crtc_state =
to_intel_crtc_state(crtc->base.state);
enum pipe pipe = crtc->pipe;
if (crtc_state->hw.active)
cdclk_state->active_pipes |= BIT(pipe);
cdclk_state->min_cdclk[pipe] = intel_crtc_compute_min_cdclk(crtc_state);
cdclk_state->min_voltage_level[pipe] = crtc_state->min_voltage_level;
}
}
void intel_cdclk_crtc_disable_noatomic(struct intel_crtc *crtc)
{
struct intel_display *display = to_intel_display(crtc);
intel_cdclk_update_hw_state(display);
}
static int intel_compute_max_dotclk(struct intel_display *display)
{
int ppc = intel_cdclk_ppc(display, HAS_DOUBLE_WIDE(display));

View File

@ -12,6 +12,7 @@
#include "intel_global_state.h"
struct intel_atomic_state;
struct intel_crtc;
struct intel_crtc_state;
struct intel_display;
@ -58,7 +59,6 @@ struct intel_cdclk_state {
bool disable_pipes;
};
int intel_crtc_compute_min_cdclk(const struct intel_crtc_state *crtc_state);
void intel_cdclk_init_hw(struct intel_display *display);
void intel_cdclk_uninit_hw(struct intel_display *display);
void intel_init_cdclk_hooks(struct intel_display *display);
@ -83,6 +83,8 @@ int intel_cdclk_atomic_check(struct intel_atomic_state *state,
int intel_cdclk_state_set_joined_mbus(struct intel_atomic_state *state, bool joined_mbus);
struct intel_cdclk_state *
intel_atomic_get_cdclk_state(struct intel_atomic_state *state);
void intel_cdclk_update_hw_state(struct intel_display *display);
void intel_cdclk_crtc_disable_noatomic(struct intel_crtc *crtc);
#define to_intel_cdclk_state(global_state) \
container_of_const((global_state), struct intel_cdclk_state, base)

View File

@ -133,6 +133,8 @@
#define TX_TRAINING_EN REG_BIT(31)
#define TAP2_DISABLE REG_BIT(30)
#define TAP3_DISABLE REG_BIT(29)
#define CURSOR_PROGRAM REG_BIT(26)
#define COEFF_POLARITY REG_BIT(25)
#define SCALING_MODE_SEL_MASK REG_GENMASK(20, 18)
#define SCALING_MODE_SEL(x) REG_FIELD_PREP(SCALING_MODE_SEL_MASK, (x))
#define RTERM_SELECT_MASK REG_GENMASK(5, 3)

View File

@ -145,8 +145,8 @@ void intel_connector_destroy(struct drm_connector *connector)
drm_connector_cleanup(connector);
if (intel_connector->port)
drm_dp_mst_put_port_malloc(intel_connector->port);
if (intel_connector->mst.port)
drm_dp_mst_put_port_malloc(intel_connector->mst.port);
kfree(connector);
}

View File

@ -54,6 +54,7 @@
#include "intel_load_detect.h"
#include "intel_pch_display.h"
#include "intel_pch_refclk.h"
#include "intel_pfit.h"
/* Here's the desired hotplug mode */
#define ADPA_HOTPLUG_BITS (ADPA_CRT_HOTPLUG_ENABLE | \

View File

@ -70,6 +70,7 @@
#include "intel_lspcon.h"
#include "intel_mg_phy_regs.h"
#include "intel_modeset_lock.h"
#include "intel_pfit.h"
#include "intel_pps.h"
#include "intel_psr.h"
#include "intel_quirks.h"
@ -187,11 +188,8 @@ static i915_reg_t intel_ddi_buf_status_reg(struct intel_display *display, enum p
return DDI_BUF_CTL(port);
}
void intel_wait_ddi_buf_idle(struct drm_i915_private *dev_priv,
enum port port)
void intel_wait_ddi_buf_idle(struct intel_display *display, enum port port)
{
struct intel_display *display = &dev_priv->display;
/*
* Bspec's platform specific timeouts:
* MTL+ : 100 us
@ -890,7 +888,7 @@ static void intel_ddi_get_encoder_pipes(struct intel_encoder *encoder,
encoder->base.base.id, encoder->base.name);
if (!mst_pipe_mask && dp128b132b_pipe_mask) {
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
/*
* If we don't have 8b/10b MST, but have more than one
@ -902,7 +900,8 @@ static void intel_ddi_get_encoder_pipes(struct intel_encoder *encoder,
* we don't expect MST to have been enabled at that point, and
* can assume it's SST.
*/
if (hweight8(dp128b132b_pipe_mask) > 1 || intel_dp->is_mst)
if (hweight8(dp128b132b_pipe_mask) > 1 ||
intel_dp_mst_encoder_active_links(dig_port))
mst_pipe_mask = dp128b132b_pipe_mask;
}
@ -1194,7 +1193,8 @@ static void icl_ddi_combo_vswing_program(struct intel_encoder *encoder,
/* Set PORT_TX_DW5 */
val = intel_de_read(dev_priv, ICL_PORT_TX_DW5_LN(0, phy));
val &= ~(SCALING_MODE_SEL_MASK | RTERM_SELECT_MASK |
TAP2_DISABLE | TAP3_DISABLE);
COEFF_POLARITY | CURSOR_PROGRAM |
TAP2_DISABLE | TAP3_DISABLE);
val |= SCALING_MODE_SEL(0x2);
val |= RTERM_SELECT(0x6);
val |= TAP3_DISABLE;
@ -3095,7 +3095,7 @@ static void intel_ddi_buf_disable(struct intel_encoder *encoder,
intel_de_rmw(dev_priv, DDI_BUF_CTL(port), DDI_BUF_CTL_ENABLE, 0);
if (DISPLAY_VER(display) >= 14)
intel_wait_ddi_buf_idle(dev_priv, port);
intel_wait_ddi_buf_idle(display, port);
mtl_ddi_disable_d2d(encoder);
@ -3107,7 +3107,7 @@ static void intel_ddi_buf_disable(struct intel_encoder *encoder,
intel_ddi_disable_fec(encoder, crtc_state);
if (DISPLAY_VER(display) < 14)
intel_wait_ddi_buf_idle(dev_priv, port);
intel_wait_ddi_buf_idle(display, port);
intel_ddi_wait_for_fec_status(encoder, crtc_state, false);
}
@ -4131,13 +4131,13 @@ static void intel_ddi_read_func_ctl(struct intel_encoder *encoder,
} else if (ddi_mode == TRANS_DDI_MODE_SELECT_DP_MST) {
intel_ddi_read_func_ctl_dp_mst(encoder, pipe_config, ddi_func_ctl);
} else if (ddi_mode == TRANS_DDI_MODE_SELECT_FDI_OR_128B132B && HAS_DP20(display)) {
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
/*
* If this is true, we know we're being called from mst stream
* encoder's ->get_config().
*/
if (intel_dp->is_mst)
if (intel_dp_mst_encoder_active_links(dig_port))
intel_ddi_read_func_ctl_dp_mst(encoder, pipe_config, ddi_func_ctl);
else
intel_ddi_read_func_ctl_dp_sst(encoder, pipe_config, ddi_func_ctl);
@ -4583,7 +4583,7 @@ static void intel_ddi_encoder_destroy(struct drm_encoder *encoder)
intel_display_power_flush_work(display);
drm_encoder_cleanup(encoder);
kfree(dig_port->hdcp_port_data.streams);
kfree(dig_port->hdcp.port_data.streams);
kfree(dig_port);
}
@ -4661,6 +4661,7 @@ static int intel_ddi_init_dp_connector(struct intel_digital_port *dig_port)
static int intel_hdmi_reset_link(struct intel_encoder *encoder,
struct drm_modeset_acquire_ctx *ctx)
{
struct intel_display *display = to_intel_display(encoder);
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
struct intel_hdmi *hdmi = enc_to_intel_hdmi(encoder);
struct intel_connector *connector = hdmi->attached_connector;
@ -4727,7 +4728,7 @@ static int intel_hdmi_reset_link(struct intel_encoder *encoder,
* would be perfectly happy if were to just reconfigure
* the SCDC settings on the fly.
*/
return intel_modeset_commit_pipes(dev_priv, BIT(crtc->pipe), ctx);
return intel_modeset_commit_pipes(display, BIT(crtc->pipe), ctx);
}
static void intel_ddi_link_check(struct intel_encoder *encoder)
@ -5101,7 +5102,7 @@ void intel_ddi_init(struct intel_display *display,
return;
}
phy = intel_port_to_phy(dev_priv, port);
phy = intel_port_to_phy(display, port);
/*
* On platforms with HTI (aka HDPORT), if it's enabled at boot it may
@ -5138,7 +5139,7 @@ void intel_ddi_init(struct intel_display *display,
return;
}
if (intel_phy_is_snps(dev_priv, phy) &&
if (intel_phy_is_snps(display, phy) &&
dev_priv->display.snps.phy_failed_calibration & BIT(phy)) {
drm_dbg_kms(&dev_priv->drm,
"SNPS PHY %c failed to calibrate, proceeding anyway\n",
@ -5161,7 +5162,7 @@ void intel_ddi_init(struct intel_display *display,
port_name(port - PORT_D_XELPD + PORT_D),
phy_name(phy));
} else if (DISPLAY_VER(dev_priv) >= 12) {
enum tc_port tc_port = intel_port_to_tc(dev_priv, port);
enum tc_port tc_port = intel_port_to_tc(display, port);
drm_encoder_init(&dev_priv->drm, &encoder->base, &intel_ddi_funcs,
DRM_MODE_ENCODER_TMDS,
@ -5171,7 +5172,7 @@ void intel_ddi_init(struct intel_display *display,
tc_port != TC_PORT_NONE ? "TC" : "",
tc_port != TC_PORT_NONE ? tc_port_name(tc_port) : phy_name(phy));
} else if (DISPLAY_VER(dev_priv) >= 11) {
enum tc_port tc_port = intel_port_to_tc(dev_priv, port);
enum tc_port tc_port = intel_port_to_tc(display, port);
drm_encoder_init(&dev_priv->drm, &encoder->base, &intel_ddi_funcs,
DRM_MODE_ENCODER_TMDS,
@ -5188,8 +5189,8 @@ void intel_ddi_init(struct intel_display *display,
intel_encoder_link_check_init(encoder, intel_ddi_link_check);
mutex_init(&dig_port->hdcp_mutex);
dig_port->num_hdcp_streams = 0;
mutex_init(&dig_port->hdcp.mutex);
dig_port->hdcp.num_streams = 0;
encoder->hotplug = intel_ddi_hotplug;
encoder->compute_output_type = intel_ddi_compute_output_type;

View File

@ -9,7 +9,6 @@
#include "i915_reg_defs.h"
struct drm_connector_state;
struct drm_i915_private;
struct intel_atomic_state;
struct intel_bios_encoder_data;
struct intel_connector;
@ -54,8 +53,7 @@ void hsw_ddi_get_config(struct intel_encoder *encoder,
struct intel_shared_dpll *icl_ddi_combo_get_pll(struct intel_encoder *encoder);
void hsw_prepare_dp_ddi_buffers(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state);
void intel_wait_ddi_buf_idle(struct drm_i915_private *dev_priv,
enum port port);
void intel_wait_ddi_buf_idle(struct intel_display *display, enum port port);
void intel_ddi_init(struct intel_display *display,
const struct intel_bios_encoder_data *devdata);
bool intel_ddi_get_hw_state(struct intel_encoder *encoder, enum pipe *pipe);

View File

@ -8,7 +8,6 @@
#include <linux/types.h>
struct drm_i915_private;
struct intel_encoder;
struct intel_crtc_state;

File diff suppressed because it is too large Load Diff

View File

@ -426,7 +426,7 @@ intel_mode_valid_max_plane_size(struct intel_display *display,
enum drm_mode_status
intel_cpu_transcoder_mode_valid(struct intel_display *display,
const struct drm_display_mode *mode);
enum phy intel_port_to_phy(struct drm_i915_private *i915, enum port port);
enum phy intel_port_to_phy(struct intel_display *display, enum port port);
bool is_trans_port_sync_mode(const struct intel_crtc_state *state);
bool is_trans_port_sync_master(const struct intel_crtc_state *state);
u8 intel_crtc_joined_pipe_mask(const struct intel_crtc_state *crtc_state);
@ -457,18 +457,16 @@ int vlv_get_cck_clock(struct drm_i915_private *dev_priv,
const char *name, u32 reg, int ref_freq);
int vlv_get_cck_clock_hpll(struct drm_i915_private *dev_priv,
const char *name, u32 reg);
void intel_init_display_hooks(struct drm_i915_private *dev_priv);
bool intel_has_pending_fb_unpin(struct drm_i915_private *dev_priv);
bool intel_has_pending_fb_unpin(struct intel_display *display);
void intel_encoder_destroy(struct drm_encoder *encoder);
struct drm_display_mode *
intel_encoder_current_mode(struct intel_encoder *encoder);
void intel_encoder_get_config(struct intel_encoder *encoder,
struct intel_crtc_state *crtc_state);
bool intel_phy_is_combo(struct intel_display *display, enum phy phy);
bool intel_phy_is_tc(struct drm_i915_private *dev_priv, enum phy phy);
bool intel_phy_is_snps(struct drm_i915_private *dev_priv, enum phy phy);
enum tc_port intel_port_to_tc(struct drm_i915_private *dev_priv,
enum port port);
bool intel_phy_is_tc(struct intel_display *display, enum phy phy);
bool intel_phy_is_snps(struct intel_display *display, enum phy phy);
enum tc_port intel_port_to_tc(struct intel_display *display, enum port port);
enum phy intel_encoder_to_phy(struct intel_encoder *encoder);
bool intel_encoder_is_combo(struct intel_encoder *encoder);
@ -481,15 +479,15 @@ int ilk_get_lanes_required(int target_clock, int link_bw, int bpp);
bool intel_fuzzy_clock_check(int clock1, int clock2);
void intel_zero_m_n(struct intel_link_m_n *m_n);
void intel_set_m_n(struct drm_i915_private *i915,
void intel_set_m_n(struct intel_display *display,
const struct intel_link_m_n *m_n,
i915_reg_t data_m_reg, i915_reg_t data_n_reg,
i915_reg_t link_m_reg, i915_reg_t link_n_reg);
void intel_get_m_n(struct drm_i915_private *i915,
void intel_get_m_n(struct intel_display *display,
struct intel_link_m_n *m_n,
i915_reg_t data_m_reg, i915_reg_t data_n_reg,
i915_reg_t link_m_reg, i915_reg_t link_n_reg);
bool intel_cpu_transcoder_has_m2_n2(struct drm_i915_private *dev_priv,
bool intel_cpu_transcoder_has_m2_n2(struct intel_display *display,
enum transcoder transcoder);
void intel_cpu_transcoder_set_m1_n1(struct intel_crtc *crtc,
enum transcoder cpu_transcoder,
@ -510,8 +508,6 @@ enum intel_display_power_domain
intel_aux_power_domain(struct intel_digital_port *dig_port);
void intel_crtc_arm_fifo_underrun(struct intel_crtc *crtc,
struct intel_crtc_state *crtc_state);
void ilk_pfit_disable(const struct intel_crtc_state *old_crtc_state);
int bdw_get_pipe_misc_bpp(struct intel_crtc *crtc);
unsigned int intel_plane_fence_y_offset(const struct intel_plane_state *plane_state);
@ -525,8 +521,6 @@ void intel_set_plane_visible(struct intel_crtc_state *crtc_state,
bool visible);
void intel_plane_fixup_bitmasks(struct intel_crtc_state *crtc_state);
void intel_update_watermarks(struct drm_i915_private *i915);
bool intel_crtc_vrr_disabling(struct intel_atomic_state *state,
struct intel_crtc *crtc);
@ -535,7 +529,7 @@ int intel_modeset_pipes_in_mask_early(struct intel_atomic_state *state,
const char *reason, u8 pipe_mask);
int intel_modeset_all_pipes_late(struct intel_atomic_state *state,
const char *reason);
int intel_modeset_commit_pipes(struct drm_i915_private *i915,
int intel_modeset_commit_pipes(struct intel_display *display,
u8 pipe_mask,
struct drm_modeset_acquire_ctx *ctx);
void intel_modeset_get_crtc_power_domains(struct intel_crtc_state *crtc_state,
@ -544,11 +538,11 @@ void intel_modeset_put_crtc_power_domains(struct intel_crtc *crtc,
struct intel_power_domain_mask *domains);
/* interface for intel_display_driver.c */
void intel_setup_outputs(struct drm_i915_private *i915);
int intel_initial_commit(struct drm_device *dev);
void intel_panel_sanitize_ssc(struct drm_i915_private *i915);
void intel_update_czclk(struct drm_i915_private *i915);
void intel_atomic_helper_free_state_worker(struct work_struct *work);
void intel_init_display_hooks(struct intel_display *display);
void intel_setup_outputs(struct intel_display *display);
int intel_initial_commit(struct intel_display *display);
void intel_panel_sanitize_ssc(struct intel_display *display);
void intel_update_czclk(struct intel_display *display);
enum drm_mode_status intel_mode_valid(struct drm_device *dev,
const struct drm_display_mode *mode);
int intel_atomic_commit(struct drm_device *dev, struct drm_atomic_state *_state,

View File

@ -91,6 +91,7 @@ struct intel_wm_funcs {
struct intel_crtc *crtc);
int (*compute_global_watermarks)(struct intel_atomic_state *state);
void (*get_hw_state)(struct drm_i915_private *i915);
void (*sanitize)(struct drm_i915_private *i915);
};
struct intel_audio_state {
@ -386,7 +387,6 @@ struct intel_display {
struct {
/* list of fbdev register on this device */
struct intel_fbdev *fbdev;
struct work_struct suspend_work;
} fbdev;
struct {
@ -512,6 +512,8 @@ struct intel_display {
/* restore state for suspend/resume and display reset */
struct drm_atomic_state *modeset_state;
struct drm_modeset_acquire_ctx reset_ctx;
/* modeset stuck tracking for reset */
atomic_t pending_fb_pin;
u32 saveDSPARB;
u32 saveSWF0[16];
u32 saveSWF1[16];

View File

@ -49,11 +49,6 @@ static struct intel_display *node_to_intel_display(struct drm_info_node *node)
return to_intel_display(node->minor->dev);
}
static inline struct drm_i915_private *node_to_i915(struct drm_info_node *node)
{
return to_i915(node->minor->dev);
}
static int intel_display_caps(struct seq_file *m, void *data)
{
struct intel_display *display = node_to_intel_display(m->private);
@ -85,8 +80,8 @@ static int i915_frontbuffer_tracking(struct seq_file *m, void *unused)
static int i915_sr_status(struct seq_file *m, void *unused)
{
struct drm_i915_private *dev_priv = node_to_i915(m->private);
struct intel_display *display = node_to_intel_display(m->private);
struct drm_i915_private *dev_priv = to_i915(display->drm);
intel_wakeref_t wakeref;
bool sr_enabled = false;
@ -102,7 +97,7 @@ static int i915_sr_status(struct seq_file *m, void *unused)
else if (display->platform.i915gm)
sr_enabled = intel_de_read(display, INSTPM) & INSTPM_SELF_EN;
else if (display->platform.pineview)
sr_enabled = intel_de_read(display, DSPFW3(dev_priv)) & PINEVIEW_SELF_REFRESH_EN;
sr_enabled = intel_de_read(display, DSPFW3(display)) & PINEVIEW_SELF_REFRESH_EN;
else if (display->platform.valleyview || display->platform.cherryview)
sr_enabled = intel_de_read(display, FW_BLC_SELF_VLV) & FW_CSPWRDWNEN;
@ -119,7 +114,6 @@ static int i915_gem_framebuffer_info(struct seq_file *m, void *data)
struct intel_framebuffer *fbdev_fb = NULL;
struct drm_framebuffer *drm_fb;
#ifdef CONFIG_DRM_FBDEV_EMULATION
fbdev_fb = intel_fbdev_framebuffer(display->fbdev.fbdev);
if (fbdev_fb) {
seq_printf(m, "fbcon size: %d x %d, depth %d, %d bpp, modifier 0x%llx, refcount %d, obj ",
@ -132,7 +126,6 @@ static int i915_gem_framebuffer_info(struct seq_file *m, void *data)
intel_bo_describe(m, intel_fb_bo(&fbdev_fb->base));
seq_putc(m, '\n');
}
#endif
mutex_lock(&display->drm->mode_config.fb_lock);
drm_for_each_fb(drm_fb, display->drm) {
@ -157,8 +150,7 @@ static int i915_gem_framebuffer_info(struct seq_file *m, void *data)
static int i915_power_domain_info(struct seq_file *m, void *unused)
{
struct drm_i915_private *i915 = node_to_i915(m->private);
struct intel_display *display = &i915->display;
struct intel_display *display = node_to_intel_display(m->private);
intel_display_power_debug(display, m);
@ -267,7 +259,7 @@ static void intel_connector_info(struct seq_file *m,
switch (connector->connector_type) {
case DRM_MODE_CONNECTOR_DisplayPort:
case DRM_MODE_CONNECTOR_eDP:
if (intel_connector->mst_port)
if (intel_connector->mst.dp)
intel_dp_mst_info(m, intel_connector);
else
intel_dp_info(m, intel_connector);
@ -588,7 +580,7 @@ static void intel_crtc_info(struct seq_file *m, struct intel_crtc *crtc)
static int i915_display_info(struct seq_file *m, void *unused)
{
struct intel_display *display = node_to_intel_display(m->private);
struct drm_i915_private *dev_priv = node_to_i915(m->private);
struct drm_i915_private *dev_priv = to_i915(display->drm);
struct intel_crtc *crtc;
struct drm_connector *connector;
struct drm_connector_list_iter conn_iter;
@ -713,14 +705,13 @@ intel_lpsp_power_well_enabled(struct intel_display *display,
static int i915_lpsp_status(struct seq_file *m, void *unused)
{
struct intel_display *display = node_to_intel_display(m->private);
struct drm_i915_private *i915 = node_to_i915(m->private);
bool lpsp_enabled = false;
if (DISPLAY_VER(display) >= 13 || IS_DISPLAY_VER(display, 9, 10)) {
lpsp_enabled = !intel_lpsp_power_well_enabled(display, SKL_DISP_PW_2);
} else if (IS_DISPLAY_VER(display, 11, 12)) {
lpsp_enabled = !intel_lpsp_power_well_enabled(display, ICL_DISP_PW_3);
} else if (IS_HASWELL(i915) || IS_BROADWELL(i915)) {
} else if (display->platform.haswell || display->platform.broadwell) {
lpsp_enabled = !intel_lpsp_power_well_enabled(display, HSW_DISP_PW_GLOBAL);
} else {
seq_puts(m, "LPSP: not supported\n");
@ -756,7 +747,7 @@ static int i915_dp_mst_info(struct seq_file *m, void *unused)
seq_printf(m, "MST Source Port [ENCODER:%d:%s]\n",
dig_port->base.base.base.id,
dig_port->base.base.name);
drm_dp_mst_dump_topology(m, &dig_port->dp.mst_mgr);
drm_dp_mst_dump_topology(m, &dig_port->dp.mst.mgr);
}
drm_connector_list_iter_end(&conn_iter);
@ -836,10 +827,10 @@ static const struct drm_info_list intel_display_debugfs_list[] = {
{"i915_lpsp_status", i915_lpsp_status, 0},
};
void intel_display_debugfs_register(struct drm_i915_private *i915)
void intel_display_debugfs_register(struct intel_display *display)
{
struct intel_display *display = &i915->display;
struct drm_minor *minor = i915->drm.primary;
struct drm_i915_private *i915 = to_i915(display->drm);
struct drm_minor *minor = display->drm->primary;
debugfs_create_file("i915_fifo_underrun_reset", 0644, minor->debugfs_root,
display, &i915_fifo_underrun_reset_ops);
@ -865,7 +856,6 @@ static int i915_lpsp_capability_show(struct seq_file *m, void *data)
struct intel_connector *connector = m->private;
struct intel_display *display = to_intel_display(connector);
struct intel_encoder *encoder = intel_attached_encoder(connector);
struct drm_i915_private *i915 = to_i915(connector->base.dev);
int connector_type = connector->base.connector_type;
bool lpsp_capable = false;
@ -892,7 +882,7 @@ static int i915_lpsp_capability_show(struct seq_file *m, void *data)
(connector_type == DRM_MODE_CONNECTOR_DSI ||
connector_type == DRM_MODE_CONNECTOR_eDP ||
connector_type == DRM_MODE_CONNECTOR_DisplayPort));
else if (IS_HASWELL(i915) || IS_BROADWELL(i915))
else if (display->platform.haswell || display->platform.broadwell)
lpsp_capable = connector_type == DRM_MODE_CONNECTOR_eDP;
seq_printf(m, "LPSP: %s\n", lpsp_capable ? "capable" : "incapable");
@ -1349,7 +1339,7 @@ void intel_connector_debugfs_add(struct intel_connector *connector)
intel_dp_link_training_debugfs_add(connector);
if (DISPLAY_VER(display) >= 11 &&
((connector_type == DRM_MODE_CONNECTOR_DisplayPort && !connector->mst_port) ||
((connector_type == DRM_MODE_CONNECTOR_DisplayPort && !connector->mst.dp) ||
connector_type == DRM_MODE_CONNECTOR_eDP)) {
debugfs_create_file("i915_dsc_fec_support", 0644, root,
connector, &i915_dsc_fec_support_fops);

View File

@ -6,16 +6,16 @@
#ifndef __INTEL_DISPLAY_DEBUGFS_H__
#define __INTEL_DISPLAY_DEBUGFS_H__
struct drm_i915_private;
struct intel_connector;
struct intel_crtc;
struct intel_display;
#ifdef CONFIG_DEBUG_FS
void intel_display_debugfs_register(struct drm_i915_private *i915);
void intel_display_debugfs_register(struct intel_display *display);
void intel_connector_debugfs_add(struct intel_connector *connector);
void intel_crtc_debugfs_add(struct intel_crtc *crtc);
#else
static inline void intel_display_debugfs_register(struct drm_i915_private *i915) {}
static inline void intel_display_debugfs_register(struct intel_display *display) {}
static inline void intel_connector_debugfs_add(struct intel_connector *connector) {}
static inline void intel_crtc_debugfs_add(struct intel_crtc *crtc) {}
#endif

View File

@ -163,6 +163,7 @@ struct intel_display_platforms {
#define HAS_DSC(__display) (DISPLAY_RUNTIME_INFO(__display)->has_dsc)
#define HAS_DSC_MST(__display) (DISPLAY_VER(__display) >= 12 && HAS_DSC(__display))
#define HAS_FBC(__display) (DISPLAY_RUNTIME_INFO(__display)->fbc_mask != 0)
#define HAS_FBC_DIRTY_RECT(__display) (DISPLAY_VER(__display) >= 30)
#define HAS_FPGA_DBG_UNCLAIMED(__display) (DISPLAY_INFO(__display)->has_fpga_dbg)
#define HAS_FW_BLC(__display) (DISPLAY_VER(__display) >= 3)
#define HAS_GMBUS_IRQ(__display) (DISPLAY_VER(__display) >= 4)

View File

@ -194,13 +194,13 @@ void intel_display_driver_early_probe(struct intel_display *display)
mutex_init(&display->hdcp.hdcp_mutex);
intel_display_irq_init(i915);
intel_dkl_phy_init(i915);
intel_dkl_phy_init(display);
intel_color_init_hooks(display);
intel_init_cdclk_hooks(display);
intel_audio_hooks_init(display);
intel_dpll_init_clock_hook(i915);
intel_init_display_hooks(i915);
intel_fdi_init_hook(i915);
intel_init_display_hooks(display);
intel_fdi_init_hook(display);
intel_dmc_wl_init(display);
}
@ -431,7 +431,7 @@ int intel_display_driver_probe_nogem(struct intel_display *display)
intel_wm_init(i915);
intel_panel_sanitize_ssc(i915);
intel_panel_sanitize_ssc(display);
intel_pps_setup(display);
@ -449,9 +449,9 @@ int intel_display_driver_probe_nogem(struct intel_display *display)
intel_plane_possible_crtcs_init(display);
intel_shared_dpll_init(display);
intel_fdi_pll_freq_update(i915);
intel_fdi_pll_freq_update(display);
intel_update_czclk(i915);
intel_update_czclk(display);
intel_display_driver_init_hw(display);
intel_dpll_update_ref_clks(display);
@ -462,7 +462,7 @@ int intel_display_driver_probe_nogem(struct intel_display *display)
/* Just disable it once at startup */
intel_vga_disable(display);
intel_setup_outputs(i915);
intel_setup_outputs(display);
ret = intel_dp_tunnel_mgr_init(display);
if (ret)
@ -517,7 +517,7 @@ int intel_display_driver_probe(struct intel_display *display)
* are already calculated and there is no assert_plane warnings
* during bootup.
*/
ret = intel_initial_commit(display->drm);
ret = intel_initial_commit(display);
if (ret)
drm_dbg_kms(display->drm, "Initial modeset failed, %d\n", ret);
@ -550,7 +550,7 @@ void intel_display_driver_register(struct intel_display *display)
intel_audio_register(display);
intel_display_debugfs_register(i915);
intel_display_debugfs_register(display);
/*
* We need to coordinate the hotplugs with the asynchronous

View File

@ -1101,7 +1101,7 @@ static bool handle_plane_ats_fault(struct intel_crtc *crtc, enum plane_id plane_
"[CRTC:%d:%s] PLANE ATS fault\n",
crtc->base.base.id, crtc->base.name);
return false;
return true;
}
static bool handle_pipedmc_ats_fault(struct intel_crtc *crtc, enum plane_id plane_id)
@ -1112,7 +1112,7 @@ static bool handle_pipedmc_ats_fault(struct intel_crtc *crtc, enum plane_id plan
"[CRTC:%d:%s] PIPEDMC ATS fault\n",
crtc->base.base.id, crtc->base.name);
return false;
return true;
}
static bool handle_pipedmc_fault(struct intel_crtc *crtc, enum plane_id plane_id)
@ -1123,7 +1123,7 @@ static bool handle_pipedmc_fault(struct intel_crtc *crtc, enum plane_id plane_id
"[CRTC:%d:%s] PIPEDMC fault\n",
crtc->base.base.id, crtc->base.name);
return false;
return true;
}
static const struct pipe_fault_handler mtl_pipe_fault_handlers[] = {

View File

@ -1684,7 +1684,7 @@ static void icl_display_core_init(struct intel_display *display,
/* 8. Ensure PHYs have completed calibration and adaptation */
if (display->platform.dg2)
intel_snps_phy_wait_for_calibration(dev_priv);
intel_snps_phy_wait_for_calibration(display);
/* 9. XE2_HPD: Program CHICKEN_MISC_2 before any cursor or planes are enabled */
if (DISPLAY_VERx100(display) == 1401)
@ -2317,6 +2317,9 @@ void intel_display_power_debug(struct intel_display *display, struct seq_file *m
mutex_lock(&power_domains->lock);
seq_printf(m, "Runtime power status: %s\n",
str_enabled_disabled(!power_domains->init_wakeref));
seq_printf(m, "%-25s %s\n", "Power well/domain", "Use count");
for (i = 0; i < power_domains->power_well_count; i++) {
struct i915_power_well *power_well;

View File

@ -117,12 +117,13 @@ enum intel_display_power_domain {
POWER_DOMAIN_INVALID = POWER_DOMAIN_NUM,
};
#define POWER_DOMAIN_PIPE(pipe) ((pipe) + POWER_DOMAIN_PIPE_A)
#define POWER_DOMAIN_PIPE(pipe) \
((enum intel_display_power_domain)((pipe) - PIPE_A + POWER_DOMAIN_PIPE_A))
#define POWER_DOMAIN_PIPE_PANEL_FITTER(pipe) \
((pipe) + POWER_DOMAIN_PIPE_PANEL_FITTER_A)
((enum intel_display_power_domain)((pipe) - PIPE_A + POWER_DOMAIN_PIPE_PANEL_FITTER_A))
#define POWER_DOMAIN_TRANSCODER(tran) \
((tran) == TRANSCODER_EDP ? POWER_DOMAIN_TRANSCODER_EDP : \
(tran) + POWER_DOMAIN_TRANSCODER_A)
(enum intel_display_power_domain)((tran) - TRANSCODER_A + POWER_DOMAIN_TRANSCODER_A))
struct intel_power_domain_mask {
DECLARE_BITMAP(bits, POWER_DOMAIN_NUM);

View File

@ -3,6 +3,8 @@
* Copyright © 2022 Intel Corporation
*/
#include <drm/drm_print.h>
#include "i915_reg.h"
#include "intel_display_core.h"
#include "intel_display_power_map.h"

View File

@ -549,10 +549,9 @@ static void
icl_aux_power_well_enable(struct intel_display *display,
struct i915_power_well *power_well)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
enum phy phy = icl_aux_pw_to_phy(display, power_well);
if (intel_phy_is_tc(dev_priv, phy))
if (intel_phy_is_tc(display, phy))
return icl_tc_phy_aux_power_well_enable(display, power_well);
else if (display->platform.icelake)
return icl_combo_phy_aux_power_well_enable(display,
@ -565,10 +564,9 @@ static void
icl_aux_power_well_disable(struct intel_display *display,
struct i915_power_well *power_well)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
enum phy phy = icl_aux_pw_to_phy(display, power_well);
if (intel_phy_is_tc(dev_priv, phy))
if (intel_phy_is_tc(display, phy))
return hsw_power_well_disable(display, power_well);
else if (display->platform.icelake)
return icl_combo_phy_aux_power_well_disable(display,
@ -1829,11 +1827,10 @@ tgl_tc_cold_off_power_well_is_enabled(struct intel_display *display,
static void xelpdp_aux_power_well_enable(struct intel_display *display,
struct i915_power_well *power_well)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
enum aux_ch aux_ch = i915_power_well_instance(power_well)->xelpdp.aux_ch;
enum phy phy = icl_aux_pw_to_phy(display, power_well);
if (intel_phy_is_tc(dev_priv, phy))
if (intel_phy_is_tc(display, phy))
icl_tc_port_assert_ref_held(display, power_well,
aux_ch_to_digital_port(display, aux_ch));

View File

@ -14,45 +14,36 @@
#include "intel_hotplug.h"
#include "intel_pps.h"
static bool gpu_reset_clobbers_display(struct drm_i915_private *dev_priv)
bool intel_display_reset_test(struct intel_display *display)
{
return (INTEL_INFO(dev_priv)->gpu_reset_clobbers_display &&
intel_has_gpu_reset(to_gt(dev_priv)));
return display->params.force_reset_modeset_test;
}
void intel_display_reset_prepare(struct drm_i915_private *dev_priv)
/* returns true if intel_display_reset_finish() needs to be called */
bool intel_display_reset_prepare(struct intel_display *display,
modeset_stuck_fn modeset_stuck, void *context)
{
struct drm_modeset_acquire_ctx *ctx = &dev_priv->display.restore.reset_ctx;
struct drm_modeset_acquire_ctx *ctx = &display->restore.reset_ctx;
struct drm_atomic_state *state;
int ret;
if (!HAS_DISPLAY(dev_priv))
return;
if (!HAS_DISPLAY(display))
return false;
/* reset doesn't touch the display */
if (!dev_priv->display.params.force_reset_modeset_test &&
!gpu_reset_clobbers_display(dev_priv))
return;
/* We have a modeset vs reset deadlock, defensively unbreak it. */
set_bit(I915_RESET_MODESET, &to_gt(dev_priv)->reset.flags);
smp_mb__after_atomic();
wake_up_bit(&to_gt(dev_priv)->reset.flags, I915_RESET_MODESET);
if (atomic_read(&dev_priv->gpu_error.pending_fb_pin)) {
drm_dbg_kms(&dev_priv->drm,
if (atomic_read(&display->restore.pending_fb_pin)) {
drm_dbg_kms(display->drm,
"Modeset potentially stuck, unbreaking through wedging\n");
intel_gt_set_wedged(to_gt(dev_priv));
modeset_stuck(context);
}
/*
* Need mode_config.mutex so that we don't
* trample ongoing ->detect() and whatnot.
*/
mutex_lock(&dev_priv->drm.mode_config.mutex);
mutex_lock(&display->drm->mode_config.mutex);
drm_modeset_acquire_init(ctx, 0);
while (1) {
ret = drm_modeset_lock_all_ctx(&dev_priv->drm, ctx);
ret = drm_modeset_lock_all_ctx(display->drm, ctx);
if (ret != -EDEADLK)
break;
@ -62,38 +53,36 @@ void intel_display_reset_prepare(struct drm_i915_private *dev_priv)
* Disabling the crtcs gracefully seems nicer. Also the
* g33 docs say we should at least disable all the planes.
*/
state = drm_atomic_helper_duplicate_state(&dev_priv->drm, ctx);
state = drm_atomic_helper_duplicate_state(display->drm, ctx);
if (IS_ERR(state)) {
ret = PTR_ERR(state);
drm_err(&dev_priv->drm, "Duplicating state failed with %i\n",
drm_err(display->drm, "Duplicating state failed with %i\n",
ret);
return;
return true;
}
ret = drm_atomic_helper_disable_all(&dev_priv->drm, ctx);
ret = drm_atomic_helper_disable_all(display->drm, ctx);
if (ret) {
drm_err(&dev_priv->drm, "Suspending crtc's failed with %i\n",
drm_err(display->drm, "Suspending crtc's failed with %i\n",
ret);
drm_atomic_state_put(state);
return;
return true;
}
dev_priv->display.restore.modeset_state = state;
display->restore.modeset_state = state;
state->acquire_ctx = ctx;
return true;
}
void intel_display_reset_finish(struct drm_i915_private *i915)
void intel_display_reset_finish(struct intel_display *display, bool test_only)
{
struct intel_display *display = &i915->display;
struct drm_i915_private *i915 = to_i915(display->drm);
struct drm_modeset_acquire_ctx *ctx = &display->restore.reset_ctx;
struct drm_atomic_state *state;
int ret;
if (!HAS_DISPLAY(i915))
return;
/* reset doesn't touch the display */
if (!test_bit(I915_RESET_MODESET, &to_gt(i915)->reset.flags))
if (!HAS_DISPLAY(display))
return;
state = fetch_and_zero(&display->restore.modeset_state);
@ -101,12 +90,12 @@ void intel_display_reset_finish(struct drm_i915_private *i915)
goto unlock;
/* reset doesn't touch the display */
if (!gpu_reset_clobbers_display(i915)) {
if (test_only) {
/* for testing only restore the display */
ret = drm_atomic_helper_commit_duplicated_state(state, ctx);
if (ret) {
drm_WARN_ON(&i915->drm, ret == -EDEADLK);
drm_err(&i915->drm,
drm_WARN_ON(display->drm, ret == -EDEADLK);
drm_err(display->drm,
"Restoring old state failed with %i\n", ret);
}
} else {
@ -122,7 +111,7 @@ void intel_display_reset_finish(struct drm_i915_private *i915)
ret = __intel_display_driver_resume(display, state, ctx);
if (ret)
drm_err(&i915->drm,
drm_err(display->drm,
"Restoring old state failed with %i\n", ret);
intel_hpd_poll_disable(i915);
@ -132,7 +121,5 @@ void intel_display_reset_finish(struct drm_i915_private *i915)
unlock:
drm_modeset_drop_locks(ctx);
drm_modeset_acquire_fini(ctx);
mutex_unlock(&i915->drm.mode_config.mutex);
clear_bit_unlock(I915_RESET_MODESET, &to_gt(i915)->reset.flags);
mutex_unlock(&display->drm->mode_config.mutex);
}

View File

@ -6,9 +6,15 @@
#ifndef __INTEL_RESET_H__
#define __INTEL_RESET_H__
struct drm_i915_private;
#include <linux/types.h>
void intel_display_reset_prepare(struct drm_i915_private *i915);
void intel_display_reset_finish(struct drm_i915_private *i915);
struct intel_display;
typedef void modeset_stuck_fn(void *context);
bool intel_display_reset_test(struct intel_display *display);
bool intel_display_reset_prepare(struct intel_display *display,
modeset_stuck_fn modeset_stuck, void *context);
void intel_display_reset_finish(struct intel_display *display, bool test_only);
#endif /* __INTEL_RESET_H__ */

View File

@ -69,10 +69,12 @@ void intel_display_rps_boost_after_vblank(struct drm_crtc *crtc,
add_wait_queue(drm_crtc_vblank_waitqueue(crtc), &wait->wait);
}
void intel_display_rps_mark_interactive(struct drm_i915_private *i915,
void intel_display_rps_mark_interactive(struct intel_display *display,
struct intel_atomic_state *state,
bool interactive)
{
struct drm_i915_private *i915 = to_i915(display->drm);
if (state->rps_interactive == interactive)
return;

View File

@ -10,12 +10,12 @@
struct dma_fence;
struct drm_crtc;
struct drm_i915_private;
struct intel_atomic_state;
struct intel_display;
void intel_display_rps_boost_after_vblank(struct drm_crtc *crtc,
struct dma_fence *fence);
void intel_display_rps_mark_interactive(struct drm_i915_private *i915,
void intel_display_rps_mark_interactive(struct intel_display *display,
struct intel_atomic_state *state,
bool interactive);

View File

@ -40,9 +40,9 @@
#include <drm/drm_rect.h>
#include <drm/drm_vblank_work.h>
#include <drm/intel/i915_hdcp_interface.h>
#include <uapi/drm/i915_drm.h>
#include "i915_vma.h"
#include "i915_vma_types.h"
#include "i915_gtt_view_types.h"
#include "intel_bios.h"
#include "intel_display.h"
#include "intel_display_conversion.h"
@ -534,10 +534,6 @@ struct intel_connector {
state of connector->polled in case hotplug storm detection changes it */
u8 polled;
struct drm_dp_mst_port *port;
struct intel_dp *mst_port;
int force_joined_pipes;
struct {
@ -549,6 +545,11 @@ struct intel_connector {
u8 dsc_decompression_enabled:1;
} dp;
struct {
struct drm_dp_mst_port *port;
struct intel_dp *dp;
} mst;
/* Work struct to schedule a uevent on link train failure */
struct work_struct modeset_retry_work;
@ -692,6 +693,8 @@ struct intel_plane_state {
u64 ccval;
const char *no_fbc_reason;
struct drm_rect damage;
};
struct intel_initial_plane_config {
@ -1724,7 +1727,6 @@ struct intel_dp {
struct intel_pps pps;
bool is_mst;
int active_mst_links;
enum drm_dp_mst_mode mst_detect;
/* connector directly attached - won't be use for modeset in mst world */
@ -1734,9 +1736,11 @@ struct intel_dp {
struct drm_dp_tunnel *tunnel;
bool tunnel_suspended:1;
/* mst connector list */
struct intel_dp_mst_encoder *mst_encoders[I915_MAX_PIPES];
struct drm_dp_mst_topology_mgr mst_mgr;
struct {
struct intel_dp_mst_encoder *stream_encoders[I915_MAX_PIPES];
struct drm_dp_mst_topology_mgr mgr;
int active_links;
} mst;
u32 (*get_aux_clock_divider)(struct intel_dp *dp, int index);
/*
@ -1847,16 +1851,18 @@ struct intel_digital_port {
struct intel_tc_port *tc;
/* protects num_hdcp_streams reference count, hdcp_port_data and hdcp_auth_status */
struct mutex hdcp_mutex;
/* the number of pipes using HDCP signalling out of this port */
unsigned int num_hdcp_streams;
/* port HDCP auth status */
bool hdcp_auth_status;
/* HDCP port data need to pass to security f/w */
struct hdcp_port_data hdcp_port_data;
/* Whether the MST topology supports HDCP Type 1 Content */
bool hdcp_mst_type1_capable;
struct {
/* protects num_streams reference count, port_data and auth_status */
struct mutex mutex;
/* the number of pipes using HDCP signalling out of this port */
unsigned int num_streams;
/* port HDCP auth status */
bool auth_status;
/* HDCP port data need to pass to security f/w */
struct hdcp_port_data port_data;
/* Whether the MST topology supports HDCP Type 1 Content */
bool mst_type1_capable;
} hdcp;
void (*write_infoframe)(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state,
@ -1955,8 +1961,8 @@ static inline struct intel_dp *enc_to_intel_dp(struct intel_encoder *encoder)
static inline struct intel_dp *intel_attached_dp(struct intel_connector *connector)
{
if (connector->mst_port)
return connector->mst_port;
if (connector->mst.dp)
return connector->mst.dp;
else
return enc_to_intel_dp(intel_attached_encoder(connector));
}
@ -2100,11 +2106,6 @@ intel_crtc_needs_color_update(const struct intel_crtc_state *crtc_state)
intel_crtc_needs_modeset(crtc_state);
}
static inline u32 intel_plane_ggtt_offset(const struct intel_plane_state *plane_state)
{
return i915_ggtt_offset(plane_state->ggtt_vma);
}
static inline struct intel_frontbuffer *
to_intel_frontbuffer(struct drm_framebuffer *fb)
{

View File

@ -3,7 +3,7 @@
* Copyright © 2022 Intel Corporation
*/
#include "i915_drv.h"
#include <drm/drm_device.h>
#include "intel_de.h"
#include "intel_display.h"
@ -12,11 +12,11 @@
/**
* intel_dkl_phy_init - initialize Dekel PHY
* @i915: i915 device instance
* @display: display device instance
*/
void intel_dkl_phy_init(struct drm_i915_private *i915)
void intel_dkl_phy_init(struct intel_display *display)
{
spin_lock_init(&i915->display.dkl.phy_lock);
spin_lock_init(&display->dkl.phy_lock);
}
static void

View File

@ -10,10 +10,9 @@
#include "intel_dkl_phy_regs.h"
struct drm_i915_private;
struct intel_display;
void intel_dkl_phy_init(struct drm_i915_private *i915);
void intel_dkl_phy_init(struct intel_display *display);
u32
intel_dkl_phy_read(struct intel_display *display, struct intel_dkl_phy_reg reg);
void

View File

@ -1376,7 +1376,7 @@ bool intel_dp_has_dsc(const struct intel_connector *connector)
if (!HAS_DSC(display))
return false;
if (connector->mst_port && !HAS_DSC_MST(display))
if (connector->mst.dp && !HAS_DSC_MST(display))
return false;
if (connector->base.connector_type == DRM_MODE_CONNECTOR_eDP &&
@ -2912,7 +2912,7 @@ static bool can_enable_drrs(struct intel_connector *connector,
const struct intel_crtc_state *pipe_config,
const struct drm_display_mode *downclock_mode)
{
struct drm_i915_private *i915 = to_i915(connector->base.dev);
struct intel_display *display = to_intel_display(connector);
if (pipe_config->vrr.enable)
return false;
@ -2930,7 +2930,7 @@ static bool can_enable_drrs(struct intel_connector *connector,
if (pipe_config->has_pch_encoder)
return false;
if (!intel_cpu_transcoder_has_drrs(i915, pipe_config->cpu_transcoder))
if (!intel_cpu_transcoder_has_drrs(display, pipe_config->cpu_transcoder))
return false;
return downclock_mode &&
@ -2943,7 +2943,6 @@ intel_dp_drrs_compute_config(struct intel_connector *connector,
int link_bpp_x16)
{
struct intel_display *display = to_intel_display(connector);
struct drm_i915_private *i915 = to_i915(connector->base.dev);
const struct drm_display_mode *downclock_mode =
intel_panel_downclock_mode(connector, &pipe_config->hw.adjusted_mode);
int pixel_clock;
@ -2956,7 +2955,7 @@ intel_dp_drrs_compute_config(struct intel_connector *connector,
pipe_config->update_m_n = true;
if (!can_enable_drrs(connector, pipe_config, downclock_mode)) {
if (intel_cpu_transcoder_has_m2_n2(i915, pipe_config->cpu_transcoder))
if (intel_cpu_transcoder_has_m2_n2(display, pipe_config->cpu_transcoder))
intel_zero_m_n(&pipe_config->dp_m2_n2);
return;
}
@ -3081,7 +3080,7 @@ intel_dp_queue_modeset_retry_for_link(struct intel_atomic_state *state,
if (!conn_state->base.crtc)
continue;
if (connector->mst_port == intel_dp)
if (connector->mst.dp == intel_dp)
intel_connector_queue_modeset_retry_work(connector);
}
}
@ -3131,7 +3130,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
if ((intel_dp_is_edp(intel_dp) && fixed_mode) ||
pipe_config->output_format == INTEL_OUTPUT_FORMAT_YCBCR420) {
ret = intel_panel_fitting(pipe_config, conn_state);
ret = intel_pfit_compute_config(pipe_config, conn_state);
if (ret)
return ret;
}
@ -3303,8 +3302,8 @@ intel_dp_sink_set_dsc_passthrough(const struct intel_connector *connector,
bool enable)
{
struct intel_display *display = to_intel_display(connector);
struct drm_dp_aux *aux = connector->port ?
connector->port->passthrough_aux : NULL;
struct drm_dp_aux *aux = connector->mst.port ?
connector->mst.port->passthrough_aux : NULL;
if (!aux)
return;
@ -3331,7 +3330,7 @@ static int intel_dp_dsc_aux_ref_count(struct intel_atomic_state *state,
* On SST the decompression AUX device won't be shared, each connector
* uses for this its own AUX targeting the sink device.
*/
if (!connector->mst_port)
if (!connector->mst.dp)
return connector->dp.dsc_decompression_enabled ? 1 : 0;
for_each_oldnew_connector_in_state(&state->base, _connector_iter,
@ -3339,7 +3338,7 @@ static int intel_dp_dsc_aux_ref_count(struct intel_atomic_state *state,
const struct intel_connector *
connector_iter = to_intel_connector(_connector_iter);
if (connector_iter->mst_port != connector->mst_port)
if (connector_iter->mst.dp != connector->mst.dp)
continue;
if (!connector_iter->dp.dsc_decompression_enabled)
@ -4397,7 +4396,7 @@ intel_dp_mst_configure(struct intel_dp *intel_dp)
if (intel_dp->is_mst)
intel_dp_mst_prepare_probe(intel_dp);
drm_dp_mst_topology_mgr_set_mst(&intel_dp->mst_mgr, intel_dp->is_mst);
drm_dp_mst_topology_mgr_set_mst(&intel_dp->mst.mgr, intel_dp->is_mst);
/* Avoid stale info on the next detect cycle. */
intel_dp->mst_detect = DRM_DP_SST;
@ -4413,9 +4412,9 @@ intel_dp_mst_disconnect(struct intel_dp *intel_dp)
drm_dbg_kms(display->drm,
"MST device may have disappeared %d vs %d\n",
intel_dp->is_mst, intel_dp->mst_mgr.mst_state);
intel_dp->is_mst, intel_dp->mst.mgr.mst_state);
intel_dp->is_mst = false;
drm_dp_mst_topology_mgr_set_mst(&intel_dp->mst_mgr, intel_dp->is_mst);
drm_dp_mst_topology_mgr_set_mst(&intel_dp->mst.mgr, intel_dp->is_mst);
}
static bool
@ -4921,7 +4920,7 @@ intel_dp_mst_hpd_irq(struct intel_dp *intel_dp, u8 *esi, u8 *ack)
{
bool handled = false;
drm_dp_mst_hpd_irq_handle_event(&intel_dp->mst_mgr, esi, ack, &handled);
drm_dp_mst_hpd_irq_handle_event(&intel_dp->mst.mgr, esi, ack, &handled);
if (esi[1] & DP_CP_IRQ) {
intel_hdcp_handle_cp_irq(intel_dp->attached_connector);
@ -4970,7 +4969,7 @@ intel_dp_check_mst_status(struct intel_dp *intel_dp)
bool link_ok = true;
bool reprobe_needed = false;
drm_WARN_ON_ONCE(display->drm, intel_dp->active_mst_links < 0);
drm_WARN_ON_ONCE(display->drm, intel_dp->mst.active_links < 0);
for (;;) {
u8 esi[4] = {};
@ -4986,7 +4985,7 @@ intel_dp_check_mst_status(struct intel_dp *intel_dp)
drm_dbg_kms(display->drm, "DPRX ESI: %4ph\n", esi);
if (intel_dp->active_mst_links > 0 && link_ok &&
if (intel_dp->mst.active_links > 0 && link_ok &&
esi[3] & LINK_STATUS_CHANGED) {
if (!intel_dp_mst_link_status(intel_dp))
link_ok = false;
@ -5009,7 +5008,7 @@ intel_dp_check_mst_status(struct intel_dp *intel_dp)
drm_dbg_kms(display->drm, "Failed to ack ESI\n");
if (ack[1] & (DP_DOWN_REP_MSG_RDY | DP_UP_REQ_MSG_RDY))
drm_dp_mst_hpd_irq_send_new_request(&intel_dp->mst_mgr);
drm_dp_mst_hpd_irq_send_new_request(&intel_dp->mst.mgr);
}
if (!link_ok || intel_dp->link.force_retrain)
@ -5108,7 +5107,7 @@ bool intel_dp_has_connector(struct intel_dp *intel_dp,
/* MST */
for_each_pipe(display, pipe) {
encoder = &intel_dp->mst_encoders[pipe]->base;
encoder = &intel_dp->mst.stream_encoders[pipe]->base;
if (conn_state->best_encoder == &encoder->base)
return true;
}
@ -5194,7 +5193,6 @@ static int intel_dp_retrain_link(struct intel_encoder *encoder,
struct drm_modeset_acquire_ctx *ctx)
{
struct intel_display *display = to_intel_display(encoder);
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
u8 pipe_mask;
int ret;
@ -5225,7 +5223,7 @@ static int intel_dp_retrain_link(struct intel_encoder *encoder,
encoder->base.base.id, encoder->base.name,
str_yes_no(intel_dp->link.force_retrain));
ret = intel_modeset_commit_pipes(dev_priv, pipe_mask, ctx);
ret = intel_modeset_commit_pipes(display, pipe_mask, ctx);
if (ret == -EDEADLK)
return ret;
@ -6067,7 +6065,7 @@ static int intel_dp_connector_atomic_check(struct drm_connector *conn,
return ret;
if (intel_dp_mst_source_support(intel_dp)) {
ret = drm_dp_mst_root_conn_atomic_check(conn_state, &intel_dp->mst_mgr);
ret = drm_dp_mst_root_conn_atomic_check(conn_state, &intel_dp->mst.mgr);
if (ret)
return ret;
}
@ -6605,7 +6603,7 @@ void intel_dp_mst_suspend(struct intel_display *display)
continue;
if (intel_dp->is_mst)
drm_dp_mst_topology_mgr_suspend(&intel_dp->mst_mgr);
drm_dp_mst_topology_mgr_suspend(&intel_dp->mst.mgr);
}
}
@ -6628,12 +6626,10 @@ void intel_dp_mst_resume(struct intel_display *display)
if (!intel_dp_mst_source_support(intel_dp))
continue;
ret = drm_dp_mst_topology_mgr_resume(&intel_dp->mst_mgr,
true);
ret = drm_dp_mst_topology_mgr_resume(&intel_dp->mst.mgr, true);
if (ret) {
intel_dp->is_mst = false;
drm_dp_mst_topology_mgr_set_mst(&intel_dp->mst_mgr,
false);
drm_dp_mst_topology_mgr_set_mst(&intel_dp->mst.mgr, false);
}
}
}

View File

@ -34,6 +34,8 @@
* for some reason.
*/
#include <drm/drm_print.h>
#include "i915_utils.h"
#include "intel_backlight.h"
#include "intel_display_core.h"

View File

@ -705,10 +705,10 @@ int intel_dp_hdcp_get_remote_capability(struct intel_connector *connector,
*hdcp_capable = false;
*hdcp2_capable = false;
if (!connector->mst_port)
if (!connector->mst.dp)
return -EINVAL;
aux = &connector->port->aux;
aux = &connector->mst.port->aux;
ret = _intel_dp_hdcp2_get_capability(aux, hdcp2_capable);
if (ret)
drm_dbg_kms(display->drm,
@ -799,7 +799,7 @@ intel_dp_mst_hdcp2_stream_encryption(struct intel_connector *connector,
{
struct intel_display *display = to_intel_display(connector);
struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
struct hdcp_port_data *data = &dig_port->hdcp_port_data;
struct hdcp_port_data *data = &dig_port->hdcp.port_data;
struct intel_hdcp *hdcp = &connector->hdcp;
enum transcoder cpu_transcoder = hdcp->stream_transcoder;
enum pipe pipe = (enum pipe)cpu_transcoder;
@ -883,7 +883,7 @@ int intel_dp_hdcp_init(struct intel_digital_port *dig_port,
if (!is_hdcp_supported(display, port))
return 0;
if (intel_connector->mst_port)
if (intel_connector->mst.dp)
return intel_hdcp_init(intel_connector, dig_port,
&intel_dp_mst_hdcp_shim);
else if (!intel_dp_is_edp(intel_dp))

View File

@ -24,6 +24,7 @@
#include <linux/debugfs.h>
#include <drm/display/drm_dp_helper.h>
#include <drm/drm_print.h>
#include "i915_utils.h"
#include "intel_display_core.h"

View File

@ -49,6 +49,7 @@
#include "intel_hdcp.h"
#include "intel_hotplug.h"
#include "intel_link_bw.h"
#include "intel_pfit.h"
#include "intel_psr.h"
#include "intel_vdsc.h"
#include "skl_scaler.h"
@ -252,7 +253,7 @@ int intel_dp_mtp_tu_compute_config(struct intel_dp *intel_dp,
fxp_q4_to_frac(bpp_step_x16)));
if (is_mst) {
mst_state = drm_atomic_get_mst_topology_state(state, &intel_dp->mst_mgr);
mst_state = drm_atomic_get_mst_topology_state(state, &intel_dp->mst.mgr);
if (IS_ERR(mst_state))
return PTR_ERR(mst_state);
@ -354,8 +355,8 @@ int intel_dp_mtp_tu_compute_config(struct intel_dp *intel_dp,
drm_WARN_ON(display->drm, remote_tu < crtc_state->dp_m_n.tu);
crtc_state->dp_m_n.tu = remote_tu;
slots = drm_dp_atomic_find_time_slots(state, &intel_dp->mst_mgr,
connector->port,
slots = drm_dp_atomic_find_time_slots(state, &intel_dp->mst.mgr,
connector->mst.port,
dfixed_trunc(pbn));
} else {
/* Same as above for remote_tu */
@ -478,7 +479,7 @@ static int mst_stream_update_slots(struct intel_dp *intel_dp,
struct drm_connector_state *conn_state)
{
struct intel_display *display = to_intel_display(intel_dp);
struct drm_dp_mst_topology_mgr *mgr = &intel_dp->mst_mgr;
struct drm_dp_mst_topology_mgr *mgr = &intel_dp->mst.mgr;
struct drm_dp_mst_topology_state *topology_state;
u8 link_coding_cap = intel_dp_is_uhbr(crtc_state) ?
DP_CAP_ANSI_128B132B : DP_CAP_ANSI_8B10B;
@ -508,8 +509,8 @@ hblank_expansion_quirk_needs_dsc(const struct intel_connector *connector,
{
const struct drm_display_mode *adjusted_mode =
&crtc_state->hw.adjusted_mode;
bool is_uhbr_sink = connector->mst_port &&
drm_dp_128b132b_supported(connector->mst_port->dpcd);
bool is_uhbr_sink = connector->mst.dp &&
drm_dp_128b132b_supported(connector->mst.dp->dpcd);
int hblank_limit = is_uhbr_sink ? 500 : 300;
if (!connector->dp.dsc_hblank_expansion_quirk)
@ -740,7 +741,7 @@ intel_dp_mst_transcoder_mask(struct intel_atomic_state *state,
const struct intel_crtc_state *crtc_state;
struct intel_crtc *crtc;
if (connector->mst_port != mst_port || !conn_state->base.crtc)
if (connector->mst.dp != mst_port || !conn_state->base.crtc)
continue;
crtc = to_intel_crtc(conn_state->base.crtc);
@ -768,12 +769,12 @@ static u8 get_pipes_downstream_of_mst_port(struct intel_atomic_state *state,
if (!conn_state->base.crtc)
continue;
if (&connector->mst_port->mst_mgr != mst_mgr)
if (&connector->mst.dp->mst.mgr != mst_mgr)
continue;
if (connector->port != parent_port &&
if (connector->mst.port != parent_port &&
!drm_dp_mst_port_downstream_of_parent(mst_mgr,
connector->port,
connector->mst.port,
parent_port))
continue;
@ -924,7 +925,7 @@ mst_connector_atomic_topology_check(struct intel_connector *connector,
struct intel_crtc_state *crtc_state;
struct intel_crtc *crtc;
if (connector_iter->mst_port != connector->mst_port ||
if (connector_iter->mst.dp != connector->mst.dp ||
connector_iter == connector)
continue;
@ -973,15 +974,15 @@ mst_connector_atomic_check(struct drm_connector *_connector,
if (intel_connector_needs_modeset(state, &connector->base)) {
ret = intel_dp_tunnel_atomic_check_state(state,
connector->mst_port,
connector->mst.dp,
connector);
if (ret)
return ret;
}
return drm_dp_atomic_release_time_slots(&state->base,
&connector->mst_port->mst_mgr,
connector->port);
&connector->mst.dp->mst.mgr,
connector->mst.port);
}
static void mst_stream_disable(struct intel_atomic_state *state,
@ -997,9 +998,9 @@ static void mst_stream_disable(struct intel_atomic_state *state,
enum transcoder trans = old_crtc_state->cpu_transcoder;
drm_dbg_kms(display->drm, "active links %d\n",
intel_dp->active_mst_links);
intel_dp->mst.active_links);
if (intel_dp->active_mst_links == 1)
if (intel_dp->mst.active_links == 1)
intel_dp->link_trained = false;
intel_hdcp_disable(intel_mst->connector);
@ -1022,19 +1023,19 @@ static void mst_stream_post_disable(struct intel_atomic_state *state,
struct intel_connector *connector =
to_intel_connector(old_conn_state->connector);
struct drm_dp_mst_topology_state *old_mst_state =
drm_atomic_get_old_mst_topology_state(&state->base, &intel_dp->mst_mgr);
drm_atomic_get_old_mst_topology_state(&state->base, &intel_dp->mst.mgr);
struct drm_dp_mst_topology_state *new_mst_state =
drm_atomic_get_new_mst_topology_state(&state->base, &intel_dp->mst_mgr);
drm_atomic_get_new_mst_topology_state(&state->base, &intel_dp->mst.mgr);
const struct drm_dp_mst_atomic_payload *old_payload =
drm_atomic_get_mst_payload_state(old_mst_state, connector->port);
drm_atomic_get_mst_payload_state(old_mst_state, connector->mst.port);
struct drm_dp_mst_atomic_payload *new_payload =
drm_atomic_get_mst_payload_state(new_mst_state, connector->port);
drm_atomic_get_mst_payload_state(new_mst_state, connector->mst.port);
struct intel_crtc *pipe_crtc;
bool last_mst_stream;
int i;
intel_dp->active_mst_links--;
last_mst_stream = intel_dp->active_mst_links == 0;
intel_dp->mst.active_links--;
last_mst_stream = intel_dp->mst.active_links == 0;
drm_WARN_ON(display->drm, DISPLAY_VER(display) >= 12 && last_mst_stream &&
!intel_dp_mst_is_master_trans(old_crtc_state));
@ -1047,7 +1048,7 @@ static void mst_stream_post_disable(struct intel_atomic_state *state,
intel_disable_transcoder(old_crtc_state);
drm_dp_remove_payload_part1(&intel_dp->mst_mgr, new_mst_state, new_payload);
drm_dp_remove_payload_part1(&intel_dp->mst.mgr, new_mst_state, new_payload);
intel_ddi_clear_act_sent(encoder, old_crtc_state);
@ -1056,9 +1057,9 @@ static void mst_stream_post_disable(struct intel_atomic_state *state,
TRANS_DDI_DP_VC_PAYLOAD_ALLOC, 0);
intel_ddi_wait_for_act_sent(encoder, old_crtc_state);
drm_dp_check_act_status(&intel_dp->mst_mgr);
drm_dp_check_act_status(&intel_dp->mst.mgr);
drm_dp_remove_payload_part2(&intel_dp->mst_mgr, new_mst_state,
drm_dp_remove_payload_part2(&intel_dp->mst.mgr, new_mst_state,
old_payload, new_payload);
intel_ddi_disable_transcoder_func(old_crtc_state);
@ -1079,7 +1080,7 @@ static void mst_stream_post_disable(struct intel_atomic_state *state,
* Power down mst path before disabling the port, otherwise we end
* up getting interrupts from the sink upon detecting link loss.
*/
drm_dp_send_power_updown_phy(&intel_dp->mst_mgr, connector->port,
drm_dp_send_power_updown_phy(&intel_dp->mst.mgr, connector->mst.port,
false);
/*
@ -1104,7 +1105,7 @@ static void mst_stream_post_disable(struct intel_atomic_state *state,
old_crtc_state, NULL);
drm_dbg_kms(display->drm, "active links %d\n",
intel_dp->active_mst_links);
intel_dp->mst.active_links);
}
static void mst_stream_post_pll_disable(struct intel_atomic_state *state,
@ -1115,7 +1116,7 @@ static void mst_stream_post_pll_disable(struct intel_atomic_state *state,
struct intel_encoder *primary_encoder = to_primary_encoder(encoder);
struct intel_dp *intel_dp = to_primary_dp(encoder);
if (intel_dp->active_mst_links == 0 &&
if (intel_dp->mst.active_links == 0 &&
primary_encoder->post_pll_disable)
primary_encoder->post_pll_disable(state, primary_encoder, old_crtc_state, old_conn_state);
}
@ -1128,7 +1129,7 @@ static void mst_stream_pre_pll_enable(struct intel_atomic_state *state,
struct intel_encoder *primary_encoder = to_primary_encoder(encoder);
struct intel_dp *intel_dp = to_primary_dp(encoder);
if (intel_dp->active_mst_links == 0)
if (intel_dp->mst.active_links == 0)
primary_encoder->pre_pll_enable(state, primary_encoder,
pipe_config, NULL);
else
@ -1161,7 +1162,7 @@ static void intel_mst_reprobe_topology(struct intel_dp *intel_dp,
crtc_state->port_clock, crtc_state->lane_count))
return;
drm_dp_mst_topology_queue_probe(&intel_dp->mst_mgr);
drm_dp_mst_topology_queue_probe(&intel_dp->mst.mgr);
intel_mst_set_probed_link_params(intel_dp,
crtc_state->port_clock, crtc_state->lane_count);
@ -1179,7 +1180,7 @@ static void mst_stream_pre_enable(struct intel_atomic_state *state,
struct intel_connector *connector =
to_intel_connector(conn_state->connector);
struct drm_dp_mst_topology_state *mst_state =
drm_atomic_get_new_mst_topology_state(&state->base, &intel_dp->mst_mgr);
drm_atomic_get_new_mst_topology_state(&state->base, &intel_dp->mst.mgr);
int ret;
bool first_mst_stream;
@ -1188,17 +1189,17 @@ static void mst_stream_pre_enable(struct intel_atomic_state *state,
*/
connector->encoder = encoder;
intel_mst->connector = connector;
first_mst_stream = intel_dp->active_mst_links == 0;
first_mst_stream = intel_dp->mst.active_links == 0;
drm_WARN_ON(display->drm, DISPLAY_VER(display) >= 12 && first_mst_stream &&
!intel_dp_mst_is_master_trans(pipe_config));
drm_dbg_kms(display->drm, "active links %d\n",
intel_dp->active_mst_links);
intel_dp->mst.active_links);
if (first_mst_stream)
intel_dp_set_power(intel_dp, DP_SET_POWER_D0);
drm_dp_send_power_updown_phy(&intel_dp->mst_mgr, connector->port, true);
drm_dp_send_power_updown_phy(&intel_dp->mst.mgr, connector->mst.port, true);
intel_dp_sink_enable_decompression(state, connector, pipe_config);
@ -1209,10 +1210,10 @@ static void mst_stream_pre_enable(struct intel_atomic_state *state,
intel_mst_reprobe_topology(intel_dp, pipe_config);
}
intel_dp->active_mst_links++;
intel_dp->mst.active_links++;
ret = drm_dp_add_payload_part1(&intel_dp->mst_mgr, mst_state,
drm_atomic_get_mst_payload_state(mst_state, connector->port));
ret = drm_dp_add_payload_part1(&intel_dp->mst.mgr, mst_state,
drm_atomic_get_mst_payload_state(mst_state, connector->mst.port));
if (ret < 0)
intel_dp_queue_modeset_retry_for_link(state, primary_encoder, pipe_config);
@ -1276,9 +1277,9 @@ static void mst_stream_enable(struct intel_atomic_state *state,
struct intel_dp *intel_dp = to_primary_dp(encoder);
struct intel_connector *connector = to_intel_connector(conn_state->connector);
struct drm_dp_mst_topology_state *mst_state =
drm_atomic_get_new_mst_topology_state(&state->base, &intel_dp->mst_mgr);
drm_atomic_get_new_mst_topology_state(&state->base, &intel_dp->mst.mgr);
enum transcoder trans = pipe_config->cpu_transcoder;
bool first_mst_stream = intel_dp->active_mst_links == 1;
bool first_mst_stream = intel_dp->mst.active_links == 1;
struct intel_crtc *pipe_crtc;
int ret, i, min_hblank;
@ -1328,17 +1329,17 @@ static void mst_stream_enable(struct intel_atomic_state *state,
TRANS_DDI_DP_VC_PAYLOAD_ALLOC);
drm_dbg_kms(display->drm, "active links %d\n",
intel_dp->active_mst_links);
intel_dp->mst.active_links);
intel_ddi_wait_for_act_sent(encoder, pipe_config);
drm_dp_check_act_status(&intel_dp->mst_mgr);
drm_dp_check_act_status(&intel_dp->mst.mgr);
if (first_mst_stream)
intel_ddi_wait_for_fec_status(encoder, pipe_config, true);
ret = drm_dp_add_payload_part2(&intel_dp->mst_mgr,
ret = drm_dp_add_payload_part2(&intel_dp->mst.mgr,
drm_atomic_get_mst_payload_state(mst_state,
connector->port));
connector->mst.port));
if (ret < 0)
intel_dp_queue_modeset_retry_for_link(state, primary_encoder, pipe_config);
@ -1391,7 +1392,7 @@ static int mst_connector_get_ddc_modes(struct drm_connector *_connector)
{
struct intel_connector *connector = to_intel_connector(_connector);
struct intel_display *display = to_intel_display(connector);
struct intel_dp *intel_dp = connector->mst_port;
struct intel_dp *intel_dp = connector->mst.dp;
const struct drm_edid *drm_edid;
int ret;
@ -1401,7 +1402,7 @@ static int mst_connector_get_ddc_modes(struct drm_connector *_connector)
if (!intel_display_driver_check_access(display))
return drm_edid_connector_add_modes(&connector->base);
drm_edid = drm_dp_mst_edid_read(&connector->base, &intel_dp->mst_mgr, connector->port);
drm_edid = drm_dp_mst_edid_read(&connector->base, &intel_dp->mst.mgr, connector->mst.port);
ret = intel_connector_update_modes(&connector->base, drm_edid);
@ -1416,13 +1417,13 @@ mst_connector_late_register(struct drm_connector *_connector)
struct intel_connector *connector = to_intel_connector(_connector);
int ret;
ret = drm_dp_mst_connector_late_register(&connector->base, connector->port);
ret = drm_dp_mst_connector_late_register(&connector->base, connector->mst.port);
if (ret < 0)
return ret;
ret = intel_connector_register(&connector->base);
if (ret < 0)
drm_dp_mst_connector_early_unregister(&connector->base, connector->port);
drm_dp_mst_connector_early_unregister(&connector->base, connector->mst.port);
return ret;
}
@ -1433,7 +1434,7 @@ mst_connector_early_unregister(struct drm_connector *_connector)
struct intel_connector *connector = to_intel_connector(_connector);
intel_connector_unregister(&connector->base);
drm_dp_mst_connector_early_unregister(&connector->base, connector->port);
drm_dp_mst_connector_early_unregister(&connector->base, connector->mst.port);
}
static const struct drm_connector_funcs mst_connector_funcs = {
@ -1462,9 +1463,9 @@ mst_connector_mode_valid_ctx(struct drm_connector *_connector,
{
struct intel_connector *connector = to_intel_connector(_connector);
struct intel_display *display = to_intel_display(connector);
struct intel_dp *intel_dp = connector->mst_port;
struct drm_dp_mst_topology_mgr *mgr = &intel_dp->mst_mgr;
struct drm_dp_mst_port *port = connector->port;
struct intel_dp *intel_dp = connector->mst.dp;
struct drm_dp_mst_topology_mgr *mgr = &intel_dp->mst.mgr;
struct drm_dp_mst_port *port = connector->mst.port;
const int min_bpp = 18;
int max_dotclk = display->cdclk.max_dotclk_freq;
int max_rate, mode_rate, max_lanes, max_link_clock;
@ -1575,10 +1576,10 @@ mst_connector_atomic_best_encoder(struct drm_connector *_connector,
struct intel_connector *connector = to_intel_connector(_connector);
struct drm_connector_state *connector_state =
drm_atomic_get_new_connector_state(state, &connector->base);
struct intel_dp *intel_dp = connector->mst_port;
struct intel_dp *intel_dp = connector->mst.dp;
struct intel_crtc *crtc = to_intel_crtc(connector_state->crtc);
return &intel_dp->mst_encoders[crtc->pipe]->base.base;
return &intel_dp->mst.stream_encoders[crtc->pipe]->base.base;
}
static int
@ -1587,7 +1588,7 @@ mst_connector_detect_ctx(struct drm_connector *_connector,
{
struct intel_connector *connector = to_intel_connector(_connector);
struct intel_display *display = to_intel_display(connector);
struct intel_dp *intel_dp = connector->mst_port;
struct intel_dp *intel_dp = connector->mst.dp;
if (!intel_display_device_enabled(display))
return connector_status_disconnected;
@ -1600,8 +1601,8 @@ mst_connector_detect_ctx(struct drm_connector *_connector,
intel_dp_flush_connector_commits(connector);
return drm_dp_mst_detect_port(&connector->base, ctx, &intel_dp->mst_mgr,
connector->port);
return drm_dp_mst_detect_port(&connector->base, ctx, &intel_dp->mst.mgr,
connector->mst.port);
}
static const struct drm_connector_helper_funcs mst_connector_helper_funcs = {
@ -1692,10 +1693,10 @@ static bool detect_dsc_hblank_expansion_quirk(const struct intel_connector *conn
* A logical port's OUI (at least for affected sinks) is all 0, so
* instead of that the parent port's OUI is used for identification.
*/
if (drm_dp_mst_port_is_logical(connector->port)) {
aux = drm_dp_mst_aux_for_parent(connector->port);
if (drm_dp_mst_port_is_logical(connector->mst.port)) {
aux = drm_dp_mst_aux_for_parent(connector->mst.port);
if (!aux)
aux = &connector->mst_port->aux;
aux = &connector->mst.dp->aux;
}
if (drm_dp_read_dpcd_caps(aux, dpcd) < 0)
@ -1730,7 +1731,7 @@ mst_topology_add_connector(struct drm_dp_mst_topology_mgr *mgr,
struct drm_dp_mst_port *port,
const char *pathprop)
{
struct intel_dp *intel_dp = container_of(mgr, struct intel_dp, mst_mgr);
struct intel_dp *intel_dp = container_of(mgr, struct intel_dp, mst.mgr);
struct intel_display *display = to_intel_display(intel_dp);
struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
struct intel_connector *connector;
@ -1743,8 +1744,8 @@ mst_topology_add_connector(struct drm_dp_mst_topology_mgr *mgr,
connector->get_hw_state = mst_connector_get_hw_state;
connector->sync_state = intel_dp_connector_sync_state;
connector->mst_port = intel_dp;
connector->port = port;
connector->mst.dp = intel_dp;
connector->mst.port = port;
drm_dp_mst_get_port_malloc(port);
ret = drm_connector_dynamic_init(display->drm, &connector->base, &mst_connector_funcs,
@ -1761,7 +1762,7 @@ mst_topology_add_connector(struct drm_dp_mst_topology_mgr *mgr,
for_each_pipe(display, pipe) {
struct drm_encoder *enc =
&intel_dp->mst_encoders[pipe]->base.base;
&intel_dp->mst.stream_encoders[pipe]->base.base;
ret = drm_connector_attach_encoder(&connector->base, enc);
if (ret)
@ -1791,7 +1792,7 @@ mst_topology_add_connector(struct drm_dp_mst_topology_mgr *mgr,
static void
mst_topology_poll_hpd_irq(struct drm_dp_mst_topology_mgr *mgr)
{
struct intel_dp *intel_dp = container_of(mgr, struct intel_dp, mst_mgr);
struct intel_dp *intel_dp = container_of(mgr, struct intel_dp, mst.mgr);
intel_hpd_trigger_irq(dp_to_dig_port(intel_dp));
}
@ -1864,14 +1865,14 @@ mst_stream_encoders_create(struct intel_digital_port *dig_port)
enum pipe pipe;
for_each_pipe(display, pipe)
intel_dp->mst_encoders[pipe] = mst_stream_encoder_create(dig_port, pipe);
intel_dp->mst.stream_encoders[pipe] = mst_stream_encoder_create(dig_port, pipe);
return true;
}
int
intel_dp_mst_encoder_active_links(struct intel_digital_port *dig_port)
{
return dig_port->dp.active_mst_links;
return dig_port->dp.mst.active_links;
}
int
@ -1891,14 +1892,15 @@ intel_dp_mst_encoder_init(struct intel_digital_port *dig_port, int conn_base_id)
if (DISPLAY_VER(display) < 11 && port == PORT_E)
return 0;
intel_dp->mst_mgr.cbs = &mst_topology_cbs;
intel_dp->mst.mgr.cbs = &mst_topology_cbs;
/* create encoders */
mst_stream_encoders_create(dig_port);
ret = drm_dp_mst_topology_mgr_init(&intel_dp->mst_mgr, display->drm,
&intel_dp->aux, 16, 3, conn_base_id);
ret = drm_dp_mst_topology_mgr_init(&intel_dp->mst.mgr, display->drm,
&intel_dp->aux, 16,
INTEL_NUM_PIPES(display), conn_base_id);
if (ret) {
intel_dp->mst_mgr.cbs = NULL;
intel_dp->mst.mgr.cbs = NULL;
return ret;
}
@ -1907,7 +1909,7 @@ intel_dp_mst_encoder_init(struct intel_digital_port *dig_port, int conn_base_id)
bool intel_dp_mst_source_support(struct intel_dp *intel_dp)
{
return intel_dp->mst_mgr.cbs;
return intel_dp->mst.mgr.cbs;
}
void
@ -1918,10 +1920,10 @@ intel_dp_mst_encoder_cleanup(struct intel_digital_port *dig_port)
if (!intel_dp_mst_source_support(intel_dp))
return;
drm_dp_mst_topology_mgr_destroy(&intel_dp->mst_mgr);
drm_dp_mst_topology_mgr_destroy(&intel_dp->mst.mgr);
/* encoders will get killed by normal cleanup */
intel_dp->mst_mgr.cbs = NULL;
intel_dp->mst.mgr.cbs = NULL;
}
bool intel_dp_mst_is_master_trans(const struct intel_crtc_state *crtc_state)
@ -1952,11 +1954,11 @@ intel_dp_mst_add_topology_state_for_connector(struct intel_atomic_state *state,
{
struct drm_dp_mst_topology_state *mst_state;
if (!connector->mst_port)
if (!connector->mst.dp)
return 0;
mst_state = drm_atomic_get_mst_topology_state(&state->base,
&connector->mst_port->mst_mgr);
&connector->mst.dp->mst.mgr);
if (IS_ERR(mst_state))
return PTR_ERR(mst_state);
@ -2054,7 +2056,7 @@ bool intel_dp_mst_crtc_needs_modeset(struct intel_atomic_state *state,
const struct intel_crtc_state *old_crtc_state;
struct intel_crtc *crtc_iter;
if (connector->mst_port != crtc_connector->mst_port ||
if (connector->mst.dp != crtc_connector->mst.dp ||
!conn_state->crtc)
continue;
@ -2077,7 +2079,7 @@ bool intel_dp_mst_crtc_needs_modeset(struct intel_atomic_state *state,
* case.
*/
if (connector->dp.dsc_decompression_aux ==
&connector->mst_port->aux)
&connector->mst.dp->aux)
return true;
}
@ -2138,7 +2140,7 @@ bool intel_dp_mst_verify_dpcd_state(struct intel_dp *intel_dp)
if (!intel_dp->is_mst)
return true;
ret = drm_dp_dpcd_readb(intel_dp->mst_mgr.aux, DP_MSTM_CTRL, &val);
ret = drm_dp_dpcd_readb(intel_dp->mst.mgr.aux, DP_MSTM_CTRL, &val);
/* Adjust the expected register value for SST + SideBand. */
if (ret < 0 || val != (DP_MST_EN | DP_UP_REQ_EN | DP_UPSTREAM_IS_SRC)) {

View File

@ -6,6 +6,8 @@
#include <drm/display/drm_dp.h>
#include <drm/display/drm_dp_helper.h>
#include <drm/drm_edid.h>
#include <drm/drm_file.h>
#include <drm/drm_print.h>
#include <drm/drm_probe_helper.h>
#include "i915_reg.h"

View File

@ -4,6 +4,7 @@
*/
#include <drm/display/drm_dp_tunnel.h>
#include <drm/drm_print.h>
#include "intel_atomic.h"
#include "intel_display_core.h"

View File

@ -125,6 +125,7 @@ struct i915_vma *intel_dpt_pin_to_ggtt(struct i915_address_space *vm,
unsigned int alignment)
{
struct drm_i915_private *i915 = vm->i915;
struct intel_display *display = &i915->display;
struct i915_dpt *dpt = i915_vm_to_dpt(vm);
intel_wakeref_t wakeref;
struct i915_vma *vma;
@ -137,7 +138,7 @@ struct i915_vma *intel_dpt_pin_to_ggtt(struct i915_address_space *vm,
pin_flags |= PIN_MAPPABLE;
wakeref = intel_runtime_pm_get(&i915->runtime_pm);
atomic_inc(&i915->gpu_error.pending_fb_pin);
atomic_inc(&display->restore.pending_fb_pin);
for_i915_gem_ww(&ww, err, true) {
err = i915_gem_object_lock(dpt->obj, &ww);
@ -167,7 +168,7 @@ struct i915_vma *intel_dpt_pin_to_ggtt(struct i915_address_space *vm,
dpt->obj->mm.dirty = true;
atomic_dec(&i915->gpu_error.pending_fb_pin);
atomic_dec(&display->restore.pending_fb_pin);
intel_runtime_pm_put(&i915->runtime_pm, wakeref);
return err ? ERR_PTR(err) : vma;
@ -183,7 +184,7 @@ void intel_dpt_unpin_from_ggtt(struct i915_address_space *vm)
/**
* intel_dpt_resume - restore the memory mapping for all DPT FBs during system resume
* @i915: device instance
* @display: display device instance
*
* Restore the memory mapping during system resume for all framebuffers which
* are mapped to HW via a GGTT->DPT page table. The content of these page
@ -193,26 +194,26 @@ void intel_dpt_unpin_from_ggtt(struct i915_address_space *vm)
* This function must be called after the mappings in GGTT have been restored calling
* i915_ggtt_resume().
*/
void intel_dpt_resume(struct drm_i915_private *i915)
void intel_dpt_resume(struct intel_display *display)
{
struct drm_framebuffer *drm_fb;
if (!HAS_DISPLAY(i915))
if (!HAS_DISPLAY(display))
return;
mutex_lock(&i915->drm.mode_config.fb_lock);
drm_for_each_fb(drm_fb, &i915->drm) {
mutex_lock(&display->drm->mode_config.fb_lock);
drm_for_each_fb(drm_fb, display->drm) {
struct intel_framebuffer *fb = to_intel_framebuffer(drm_fb);
if (fb->dpt_vm)
i915_ggtt_resume_vm(fb->dpt_vm, true);
}
mutex_unlock(&i915->drm.mode_config.fb_lock);
mutex_unlock(&display->drm->mode_config.fb_lock);
}
/**
* intel_dpt_suspend - suspend the memory mapping for all DPT FBs during system suspend
* @i915: device instance
* @display: display device instance
*
* Suspend the memory mapping during system suspend for all framebuffers which
* are mapped to HW via a GGTT->DPT page table.
@ -220,23 +221,23 @@ void intel_dpt_resume(struct drm_i915_private *i915)
* This function must be called before the mappings in GGTT are suspended calling
* i915_ggtt_suspend().
*/
void intel_dpt_suspend(struct drm_i915_private *i915)
void intel_dpt_suspend(struct intel_display *display)
{
struct drm_framebuffer *drm_fb;
if (!HAS_DISPLAY(i915))
if (!HAS_DISPLAY(display))
return;
mutex_lock(&i915->drm.mode_config.fb_lock);
mutex_lock(&display->drm->mode_config.fb_lock);
drm_for_each_fb(drm_fb, &i915->drm) {
drm_for_each_fb(drm_fb, display->drm) {
struct intel_framebuffer *fb = to_intel_framebuffer(drm_fb);
if (fb->dpt_vm)
i915_ggtt_suspend_vm(fb->dpt_vm, true);
}
mutex_unlock(&i915->drm.mode_config.fb_lock);
mutex_unlock(&display->drm->mode_config.fb_lock);
}
struct i915_address_space *

View File

@ -8,18 +8,17 @@
#include <linux/types.h>
struct drm_i915_private;
struct i915_address_space;
struct i915_vma;
struct intel_display;
struct intel_framebuffer;
void intel_dpt_destroy(struct i915_address_space *vm);
struct i915_vma *intel_dpt_pin_to_ggtt(struct i915_address_space *vm,
unsigned int alignment);
void intel_dpt_unpin_from_ggtt(struct i915_address_space *vm);
void intel_dpt_suspend(struct drm_i915_private *i915);
void intel_dpt_resume(struct drm_i915_private *i915);
void intel_dpt_suspend(struct intel_display *display);
void intel_dpt_resume(struct intel_display *display);
struct i915_address_space *
intel_dpt_create(struct intel_framebuffer *fb);
u64 intel_dpt_offset(struct i915_vma *dpt_vma);

View File

@ -65,31 +65,29 @@ const char *intel_drrs_type_str(enum drrs_type drrs_type)
return str[drrs_type];
}
bool intel_cpu_transcoder_has_drrs(struct drm_i915_private *i915,
bool intel_cpu_transcoder_has_drrs(struct intel_display *display,
enum transcoder cpu_transcoder)
{
struct intel_display *display = &i915->display;
if (HAS_DOUBLE_BUFFERED_M_N(display))
return true;
return intel_cpu_transcoder_has_m2_n2(i915, cpu_transcoder);
return intel_cpu_transcoder_has_m2_n2(display, cpu_transcoder);
}
static void
intel_drrs_set_refresh_rate_pipeconf(struct intel_crtc *crtc,
enum drrs_refresh_rate refresh_rate)
{
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
struct intel_display *display = to_intel_display(crtc);
enum transcoder cpu_transcoder = crtc->drrs.cpu_transcoder;
u32 bit;
if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
if (display->platform.valleyview || display->platform.cherryview)
bit = TRANSCONF_REFRESH_RATE_ALT_VLV;
else
bit = TRANSCONF_REFRESH_RATE_ALT_ILK;
intel_de_rmw(dev_priv, TRANSCONF(dev_priv, cpu_transcoder),
intel_de_rmw(display, TRANSCONF(display, cpu_transcoder),
bit, refresh_rate == DRRS_REFRESH_RATE_LOW ? bit : 0);
}
@ -110,12 +108,12 @@ bool intel_drrs_is_active(struct intel_crtc *crtc)
static void intel_drrs_set_state(struct intel_crtc *crtc,
enum drrs_refresh_rate refresh_rate)
{
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
struct intel_display *display = to_intel_display(crtc);
if (refresh_rate == crtc->drrs.refresh_rate)
return;
if (intel_cpu_transcoder_has_m2_n2(dev_priv, crtc->drrs.cpu_transcoder))
if (intel_cpu_transcoder_has_m2_n2(display, crtc->drrs.cpu_transcoder))
intel_drrs_set_refresh_rate_pipeconf(crtc, refresh_rate);
else
intel_drrs_set_refresh_rate_m_n(crtc, refresh_rate);
@ -132,13 +130,13 @@ static void intel_drrs_schedule_work(struct intel_crtc *crtc)
static unsigned int intel_drrs_frontbuffer_bits(const struct intel_crtc_state *crtc_state)
{
struct intel_display *display = to_intel_display(crtc_state);
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
unsigned int frontbuffer_bits;
frontbuffer_bits = INTEL_FRONTBUFFER_ALL_MASK(crtc->pipe);
for_each_intel_crtc_in_pipe_mask(&i915->drm, crtc,
for_each_intel_crtc_in_pipe_mask(display->drm, crtc,
crtc_state->joiner_pipes)
frontbuffer_bits |= INTEL_FRONTBUFFER_ALL_MASK(crtc->pipe);
@ -222,13 +220,13 @@ static void intel_drrs_downclock_work(struct work_struct *work)
mutex_unlock(&crtc->drrs.mutex);
}
static void intel_drrs_frontbuffer_update(struct drm_i915_private *dev_priv,
static void intel_drrs_frontbuffer_update(struct intel_display *display,
unsigned int all_frontbuffer_bits,
bool invalidate)
{
struct intel_crtc *crtc;
for_each_intel_crtc(&dev_priv->drm, crtc) {
for_each_intel_crtc(display->drm, crtc) {
unsigned int frontbuffer_bits;
mutex_lock(&crtc->drrs.mutex);
@ -262,7 +260,7 @@ static void intel_drrs_frontbuffer_update(struct drm_i915_private *dev_priv,
/**
* intel_drrs_invalidate - Disable Idleness DRRS
* @dev_priv: i915 device
* @display: display device
* @frontbuffer_bits: frontbuffer plane tracking bits
*
* This function gets called everytime rendering on the given planes start.
@ -270,15 +268,15 @@ static void intel_drrs_frontbuffer_update(struct drm_i915_private *dev_priv,
*
* Dirty frontbuffers relevant to DRRS are tracked in busy_frontbuffer_bits.
*/
void intel_drrs_invalidate(struct drm_i915_private *dev_priv,
void intel_drrs_invalidate(struct intel_display *display,
unsigned int frontbuffer_bits)
{
intel_drrs_frontbuffer_update(dev_priv, frontbuffer_bits, true);
intel_drrs_frontbuffer_update(display, frontbuffer_bits, true);
}
/**
* intel_drrs_flush - Restart Idleness DRRS
* @dev_priv: i915 device
* @display: display device
* @frontbuffer_bits: frontbuffer plane tracking bits
*
* This function gets called every time rendering on the given planes has
@ -288,10 +286,10 @@ void intel_drrs_invalidate(struct drm_i915_private *dev_priv,
*
* Dirty frontbuffers relevant to DRRS are tracked in busy_frontbuffer_bits.
*/
void intel_drrs_flush(struct drm_i915_private *dev_priv,
void intel_drrs_flush(struct intel_display *display,
unsigned int frontbuffer_bits)
{
intel_drrs_frontbuffer_update(dev_priv, frontbuffer_bits, false);
intel_drrs_frontbuffer_update(display, frontbuffer_bits, false);
}
/**
@ -312,7 +310,7 @@ void intel_drrs_crtc_init(struct intel_crtc *crtc)
static int intel_drrs_debugfs_status_show(struct seq_file *m, void *unused)
{
struct intel_crtc *crtc = m->private;
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
struct intel_display *display = to_intel_display(crtc);
const struct intel_crtc_state *crtc_state;
int ret;
@ -325,7 +323,7 @@ static int intel_drrs_debugfs_status_show(struct seq_file *m, void *unused)
mutex_lock(&crtc->drrs.mutex);
seq_printf(m, "DRRS capable: %s\n",
str_yes_no(intel_cpu_transcoder_has_drrs(i915,
str_yes_no(intel_cpu_transcoder_has_drrs(display,
crtc_state->cpu_transcoder)));
seq_printf(m, "DRRS enabled: %s\n",
@ -353,7 +351,7 @@ DEFINE_SHOW_ATTRIBUTE(intel_drrs_debugfs_status);
static int intel_drrs_debugfs_ctl_set(void *data, u64 val)
{
struct intel_crtc *crtc = data;
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
struct intel_display *display = to_intel_display(crtc);
struct intel_crtc_state *crtc_state;
struct drm_crtc_commit *commit;
int ret;
@ -375,8 +373,7 @@ static int intel_drrs_debugfs_ctl_set(void *data, u64 val)
goto out;
}
drm_dbg(&i915->drm,
"Manually %sactivating DRRS\n", val ? "" : "de");
drm_dbg_kms(display->drm, "Manually %sactivating DRRS\n", val ? "" : "de");
if (val)
intel_drrs_activate(crtc_state);

View File

@ -10,21 +10,21 @@
enum drrs_type;
enum transcoder;
struct drm_i915_private;
struct intel_atomic_state;
struct intel_connector;
struct intel_crtc;
struct intel_crtc_state;
struct intel_connector;
struct intel_display;
bool intel_cpu_transcoder_has_drrs(struct drm_i915_private *i915,
bool intel_cpu_transcoder_has_drrs(struct intel_display *display,
enum transcoder cpu_transcoder);
const char *intel_drrs_type_str(enum drrs_type drrs_type);
bool intel_drrs_is_active(struct intel_crtc *crtc);
void intel_drrs_activate(const struct intel_crtc_state *crtc_state);
void intel_drrs_deactivate(const struct intel_crtc_state *crtc_state);
void intel_drrs_invalidate(struct drm_i915_private *dev_priv,
void intel_drrs_invalidate(struct intel_display *display,
unsigned int frontbuffer_bits);
void intel_drrs_flush(struct drm_i915_private *dev_priv,
void intel_drrs_flush(struct intel_display *display,
unsigned int frontbuffer_bits);
void intel_drrs_crtc_init(struct intel_crtc *crtc);
void intel_drrs_crtc_debugfs_add(struct intel_crtc *crtc);

View File

@ -25,6 +25,7 @@ intel_fb_pin_to_dpt(const struct drm_framebuffer *fb,
struct i915_address_space *vm)
{
struct drm_device *dev = fb->dev;
struct intel_display *display = to_intel_display(dev);
struct drm_i915_private *dev_priv = to_i915(dev);
struct drm_gem_object *_obj = intel_fb_bo(fb);
struct drm_i915_gem_object *obj = to_intel_bo(_obj);
@ -42,7 +43,7 @@ intel_fb_pin_to_dpt(const struct drm_framebuffer *fb,
if (WARN_ON(!i915_gem_object_is_framebuffer(obj)))
return ERR_PTR(-EINVAL);
atomic_inc(&dev_priv->gpu_error.pending_fb_pin);
atomic_inc(&display->restore.pending_fb_pin);
for_i915_gem_ww(&ww, ret, true) {
ret = i915_gem_object_lock(obj, &ww);
@ -97,7 +98,7 @@ intel_fb_pin_to_dpt(const struct drm_framebuffer *fb,
i915_vma_get(vma);
err:
atomic_dec(&dev_priv->gpu_error.pending_fb_pin);
atomic_dec(&display->restore.pending_fb_pin);
return vma;
}
@ -112,6 +113,7 @@ intel_fb_pin_to_ggtt(const struct drm_framebuffer *fb,
unsigned long *out_flags)
{
struct drm_device *dev = fb->dev;
struct intel_display *display = to_intel_display(dev);
struct drm_i915_private *dev_priv = to_i915(dev);
struct drm_gem_object *_obj = intel_fb_bo(fb);
struct drm_i915_gem_object *obj = to_intel_bo(_obj);
@ -136,7 +138,7 @@ intel_fb_pin_to_ggtt(const struct drm_framebuffer *fb,
*/
wakeref = intel_runtime_pm_get(&dev_priv->runtime_pm);
atomic_inc(&dev_priv->gpu_error.pending_fb_pin);
atomic_inc(&display->restore.pending_fb_pin);
/*
* Valleyview is definitely limited to scanning out the first
@ -212,7 +214,7 @@ intel_fb_pin_to_ggtt(const struct drm_framebuffer *fb,
if (ret)
vma = ERR_PTR(ret);
atomic_dec(&dev_priv->gpu_error.pending_fb_pin);
atomic_dec(&display->restore.pending_fb_pin);
intel_runtime_pm_put(&dev_priv->runtime_pm, wakeref);
return vma;
}

View File

@ -88,6 +88,7 @@ struct intel_fbc_state {
u16 override_cfb_stride;
u16 interval;
s8 fence_id;
struct drm_rect dirty_rect;
};
struct intel_fbc {
@ -215,11 +216,9 @@ static unsigned int intel_fbc_cfb_stride(const struct intel_plane_state *plane_s
*/
static unsigned int intel_fbc_max_cfb_height(struct intel_display *display)
{
struct drm_i915_private *i915 = to_i915(display->drm);
if (DISPLAY_VER(display) >= 8)
return 2560;
else if (DISPLAY_VER(display) >= 5 || IS_G4X(i915))
else if (DISPLAY_VER(display) >= 5 || display->platform.g4x)
return 2048;
else
return 1536;
@ -269,9 +268,8 @@ static bool intel_fbc_has_fences(struct intel_display *display)
static u32 i8xx_fbc_ctl(struct intel_fbc *fbc)
{
const struct intel_fbc_state *fbc_state = &fbc->state;
struct intel_display *display = fbc->display;
struct drm_i915_private *i915 = to_i915(display->drm);
const struct intel_fbc_state *fbc_state = &fbc->state;
unsigned int cfb_stride;
u32 fbc_ctl;
@ -287,7 +285,7 @@ static u32 i8xx_fbc_ctl(struct intel_fbc *fbc)
FBC_CTL_INTERVAL(fbc_state->interval) |
FBC_CTL_STRIDE(cfb_stride);
if (IS_I945GM(i915))
if (display->platform.i945gm)
fbc_ctl |= FBC_CTL_C3_IDLE; /* 945 needs special SR handling */
if (fbc_state->fence_id >= 0)
@ -333,8 +331,8 @@ static void i8xx_fbc_deactivate(struct intel_fbc *fbc)
static void i8xx_fbc_activate(struct intel_fbc *fbc)
{
const struct intel_fbc_state *fbc_state = &fbc->state;
struct intel_display *display = fbc->display;
const struct intel_fbc_state *fbc_state = &fbc->state;
int i;
/* Clear old tags */
@ -365,12 +363,12 @@ static bool i8xx_fbc_is_compressing(struct intel_fbc *fbc)
static void i8xx_fbc_nuke(struct intel_fbc *fbc)
{
struct intel_display *display = fbc->display;
struct intel_fbc_state *fbc_state = &fbc->state;
enum i9xx_plane_id i9xx_plane = fbc_state->plane->i9xx_plane;
struct drm_i915_private *dev_priv = to_i915(fbc->display->drm);
intel_de_write_fw(dev_priv, DSPADDR(dev_priv, i9xx_plane),
intel_de_read_fw(dev_priv, DSPADDR(dev_priv, i9xx_plane)));
intel_de_write_fw(display, DSPADDR(display, i9xx_plane),
intel_de_read_fw(display, DSPADDR(display, i9xx_plane)));
}
static void i8xx_fbc_program_cfb(struct intel_fbc *fbc)
@ -386,9 +384,9 @@ static void i8xx_fbc_program_cfb(struct intel_fbc *fbc)
range_overflows_end_t(u64, i915_gem_stolen_area_address(i915),
i915_gem_stolen_node_offset(&fbc->compressed_llb),
U32_MAX));
intel_de_write(i915, FBC_CFB_BASE,
intel_de_write(display, FBC_CFB_BASE,
i915_gem_stolen_node_address(i915, &fbc->compressed_fb));
intel_de_write(i915, FBC_LL_BASE,
intel_de_write(display, FBC_LL_BASE,
i915_gem_stolen_node_address(i915, &fbc->compressed_llb));
}
@ -403,12 +401,12 @@ static const struct intel_fbc_funcs i8xx_fbc_funcs = {
static void i965_fbc_nuke(struct intel_fbc *fbc)
{
struct intel_display *display = fbc->display;
struct intel_fbc_state *fbc_state = &fbc->state;
enum i9xx_plane_id i9xx_plane = fbc_state->plane->i9xx_plane;
struct drm_i915_private *dev_priv = to_i915(fbc->display->drm);
intel_de_write_fw(dev_priv, DSPSURF(dev_priv, i9xx_plane),
intel_de_read_fw(dev_priv, DSPSURF(dev_priv, i9xx_plane)));
intel_de_write_fw(display, DSPSURF(display, i9xx_plane),
intel_de_read_fw(display, DSPSURF(display, i9xx_plane)));
}
static const struct intel_fbc_funcs i965_fbc_funcs = {
@ -437,15 +435,14 @@ static u32 g4x_dpfc_ctl_limit(struct intel_fbc *fbc)
static u32 g4x_dpfc_ctl(struct intel_fbc *fbc)
{
const struct intel_fbc_state *fbc_state = &fbc->state;
struct intel_display *display = fbc->display;
struct drm_i915_private *i915 = to_i915(display->drm);
const struct intel_fbc_state *fbc_state = &fbc->state;
u32 dpfc_ctl;
dpfc_ctl = g4x_dpfc_ctl_limit(fbc) |
DPFC_CTL_PLANE_G4X(fbc_state->plane->i9xx_plane);
if (IS_G4X(i915))
if (display->platform.g4x)
dpfc_ctl |= DPFC_CTL_SR_EN;
if (fbc_state->fence_id >= 0) {
@ -460,8 +457,8 @@ static u32 g4x_dpfc_ctl(struct intel_fbc *fbc)
static void g4x_fbc_activate(struct intel_fbc *fbc)
{
const struct intel_fbc_state *fbc_state = &fbc->state;
struct intel_display *display = fbc->display;
const struct intel_fbc_state *fbc_state = &fbc->state;
intel_de_write(display, DPFC_FENCE_YOFF,
fbc_state->fence_y_offset);
@ -512,8 +509,8 @@ static const struct intel_fbc_funcs g4x_fbc_funcs = {
static void ilk_fbc_activate(struct intel_fbc *fbc)
{
struct intel_fbc_state *fbc_state = &fbc->state;
struct intel_display *display = fbc->display;
struct intel_fbc_state *fbc_state = &fbc->state;
intel_de_write(display, ILK_DPFC_FENCE_YOFF(fbc->id),
fbc_state->fence_y_offset);
@ -527,6 +524,9 @@ static void ilk_fbc_deactivate(struct intel_fbc *fbc)
struct intel_display *display = fbc->display;
u32 dpfc_ctl;
if (HAS_FBC_DIRTY_RECT(display))
intel_de_write(display, XE3_FBC_DIRTY_CTL(fbc->id), 0);
/* Disable compression */
dpfc_ctl = intel_de_read(display, ILK_DPFC_CONTROL(fbc->id));
if (dpfc_ctl & DPFC_CTL_EN) {
@ -564,8 +564,8 @@ static const struct intel_fbc_funcs ilk_fbc_funcs = {
static void snb_fbc_program_fence(struct intel_fbc *fbc)
{
const struct intel_fbc_state *fbc_state = &fbc->state;
struct intel_display *display = fbc->display;
const struct intel_fbc_state *fbc_state = &fbc->state;
u32 ctl = 0;
if (fbc_state->fence_id >= 0)
@ -601,8 +601,8 @@ static const struct intel_fbc_funcs snb_fbc_funcs = {
static void glk_fbc_program_cfb_stride(struct intel_fbc *fbc)
{
const struct intel_fbc_state *fbc_state = &fbc->state;
struct intel_display *display = fbc->display;
const struct intel_fbc_state *fbc_state = &fbc->state;
u32 val = 0;
if (fbc_state->override_cfb_stride)
@ -614,8 +614,8 @@ static void glk_fbc_program_cfb_stride(struct intel_fbc *fbc)
static void skl_fbc_program_cfb_stride(struct intel_fbc *fbc)
{
const struct intel_fbc_state *fbc_state = &fbc->state;
struct intel_display *display = fbc->display;
const struct intel_fbc_state *fbc_state = &fbc->state;
u32 val = 0;
/* Display WA #0529: skl, kbl, bxt. */
@ -630,14 +630,13 @@ static void skl_fbc_program_cfb_stride(struct intel_fbc *fbc)
static u32 ivb_dpfc_ctl(struct intel_fbc *fbc)
{
const struct intel_fbc_state *fbc_state = &fbc->state;
struct intel_display *display = fbc->display;
struct drm_i915_private *i915 = to_i915(display->drm);
const struct intel_fbc_state *fbc_state = &fbc->state;
u32 dpfc_ctl;
dpfc_ctl = g4x_dpfc_ctl_limit(fbc);
if (IS_IVYBRIDGE(i915))
if (display->platform.ivybridge)
dpfc_ctl |= DPFC_CTL_PLANE_IVB(fbc_state->plane->i9xx_plane);
if (DISPLAY_VER(display) >= 20)
@ -670,6 +669,10 @@ static void ivb_fbc_activate(struct intel_fbc *fbc)
if (DISPLAY_VER(display) >= 20)
intel_de_write(display, ILK_DPFC_CONTROL(fbc->id), dpfc_ctl);
if (HAS_FBC_DIRTY_RECT(display))
intel_de_write(display, XE3_FBC_DIRTY_CTL(fbc->id),
FBC_DIRTY_RECT_EN);
intel_de_write(display, ILK_DPFC_CONTROL(fbc->id),
DPFC_CTL_EN | dpfc_ctl);
}
@ -739,8 +742,19 @@ static void intel_fbc_nuke(struct intel_fbc *fbc)
static void intel_fbc_activate(struct intel_fbc *fbc)
{
struct intel_display *display = fbc->display;
lockdep_assert_held(&fbc->lock);
/* only the fence can change for a flip nuke */
if (fbc->active && !intel_fbc_has_fences(display))
return;
/*
* In case of FBC dirt rect, any updates to the FBC registers will
* trigger the nuke.
*/
drm_WARN_ON(display->drm, fbc->active && HAS_FBC_DIRTY_RECT(display));
intel_fbc_hw_activate(fbc);
intel_fbc_nuke(fbc);
@ -759,9 +773,7 @@ static void intel_fbc_deactivate(struct intel_fbc *fbc, const char *reason)
static u64 intel_fbc_cfb_base_max(struct intel_display *display)
{
struct drm_i915_private *i915 = to_i915(display->drm);
if (DISPLAY_VER(display) >= 5 || IS_G4X(i915))
if (DISPLAY_VER(display) >= 5 || display->platform.g4x)
return BIT_ULL(28);
else
return BIT_ULL(32);
@ -776,8 +788,8 @@ static u64 intel_fbc_stolen_end(struct intel_display *display)
* reserved range size, so it always assumes the maximum (8mb) is used.
* If we enable FBC using a CFB on that memory range we'll get FIFO
* underruns, even if that range is not reserved by the BIOS. */
if (IS_BROADWELL(i915) ||
(DISPLAY_VER(display) == 9 && !IS_BROXTON(i915)))
if (display->platform.broadwell ||
(DISPLAY_VER(display) == 9 && !display->platform.broxton))
end = i915_gem_stolen_area_size(i915) - 8 * 1024 * 1024;
else
end = U64_MAX;
@ -792,10 +804,8 @@ static int intel_fbc_min_limit(const struct intel_plane_state *plane_state)
static int intel_fbc_max_limit(struct intel_display *display)
{
struct drm_i915_private *i915 = to_i915(display->drm);
/* WaFbcOnly1to1Ratio:ctg */
if (IS_G4X(i915))
if (display->platform.g4x)
return 1;
/*
@ -843,7 +853,7 @@ static int intel_fbc_alloc_cfb(struct intel_fbc *fbc,
drm_WARN_ON(display->drm,
i915_gem_stolen_node_allocated(&fbc->compressed_llb));
if (DISPLAY_VER(display) < 5 && !IS_G4X(i915)) {
if (DISPLAY_VER(display) < 5 && !display->platform.g4x) {
ret = i915_gem_stolen_insert_node(i915, &fbc->compressed_llb,
4096, 4096);
if (ret)
@ -882,9 +892,8 @@ static void intel_fbc_program_cfb(struct intel_fbc *fbc)
static void intel_fbc_program_workarounds(struct intel_fbc *fbc)
{
struct intel_display *display = fbc->display;
struct drm_i915_private *i915 = to_i915(display->drm);
if (IS_SKYLAKE(i915) || IS_BROXTON(i915)) {
if (display->platform.skylake || display->platform.broxton) {
/*
* WaFbcHighMemBwCorruptionAvoidance:skl,bxt
* Display WA #0883: skl,bxt
@ -893,8 +902,8 @@ static void intel_fbc_program_workarounds(struct intel_fbc *fbc)
0, DPFC_DISABLE_DUMMY0);
}
if (IS_SKYLAKE(i915) || IS_KABYLAKE(i915) ||
IS_COFFEELAKE(i915) || IS_COMETLAKE(i915)) {
if (display->platform.skylake || display->platform.kabylake ||
display->platform.coffeelake || display->platform.cometlake) {
/*
* WaFbcNukeOnHostModify:skl,kbl,cfl
* Display WA #0873: skl,kbl,cfl
@ -909,7 +918,7 @@ static void intel_fbc_program_workarounds(struct intel_fbc *fbc)
0, DPFC_CHICKEN_COMP_DUMMY_PIXEL);
/* Wa_22014263786:icl,jsl,tgl,dg1,rkl,adls,adlp,mtl */
if (DISPLAY_VER(display) >= 11 && !IS_DG2(i915))
if (DISPLAY_VER(display) >= 11 && !display->platform.dg2)
intel_de_rmw(display, ILK_DPFC_CHICKEN(fbc->id),
0, DPFC_CHICKEN_FORCE_SLB_INVALIDATION);
}
@ -986,13 +995,12 @@ static bool icl_fbc_stride_is_valid(const struct intel_plane_state *plane_state)
static bool stride_is_valid(const struct intel_plane_state *plane_state)
{
struct intel_display *display = to_intel_display(plane_state->uapi.plane->dev);
struct drm_i915_private *i915 = to_i915(display->drm);
if (DISPLAY_VER(display) >= 11)
return icl_fbc_stride_is_valid(plane_state);
else if (DISPLAY_VER(display) >= 9)
return skl_fbc_stride_is_valid(plane_state);
else if (DISPLAY_VER(display) >= 5 || IS_G4X(i915))
else if (DISPLAY_VER(display) >= 5 || display->platform.g4x)
return g4x_fbc_stride_is_valid(plane_state);
else if (DISPLAY_VER(display) == 4)
return i965_fbc_stride_is_valid(plane_state);
@ -1023,7 +1031,6 @@ static bool i8xx_fbc_pixel_format_is_valid(const struct intel_plane_state *plane
static bool g4x_fbc_pixel_format_is_valid(const struct intel_plane_state *plane_state)
{
struct intel_display *display = to_intel_display(plane_state->uapi.plane->dev);
struct drm_i915_private *i915 = to_i915(display->drm);
const struct drm_framebuffer *fb = plane_state->hw.fb;
switch (fb->format->format) {
@ -1032,7 +1039,7 @@ static bool g4x_fbc_pixel_format_is_valid(const struct intel_plane_state *plane_
return true;
case DRM_FORMAT_RGB565:
/* WaFbcOnly1to1Ratio:ctg */
if (IS_G4X(i915))
if (display->platform.g4x)
return false;
return true;
default:
@ -1059,11 +1066,10 @@ static bool lnl_fbc_pixel_format_is_valid(const struct intel_plane_state *plane_
static bool pixel_format_is_valid(const struct intel_plane_state *plane_state)
{
struct intel_display *display = to_intel_display(plane_state->uapi.plane->dev);
struct drm_i915_private *i915 = to_i915(display->drm);
if (DISPLAY_VER(display) >= 20)
return lnl_fbc_pixel_format_is_valid(plane_state);
else if (DISPLAY_VER(display) >= 5 || IS_G4X(i915))
else if (DISPLAY_VER(display) >= 5 || display->platform.g4x)
return g4x_fbc_pixel_format_is_valid(plane_state);
else
return i8xx_fbc_pixel_format_is_valid(plane_state);
@ -1094,11 +1100,10 @@ static bool skl_fbc_rotation_is_valid(const struct intel_plane_state *plane_stat
static bool rotation_is_valid(const struct intel_plane_state *plane_state)
{
struct intel_display *display = to_intel_display(plane_state->uapi.plane->dev);
struct drm_i915_private *i915 = to_i915(display->drm);
if (DISPLAY_VER(display) >= 9)
return skl_fbc_rotation_is_valid(plane_state);
else if (DISPLAY_VER(display) >= 5 || IS_G4X(i915))
else if (DISPLAY_VER(display) >= 5 || display->platform.g4x)
return g4x_fbc_rotation_is_valid(plane_state);
else
return i8xx_fbc_rotation_is_valid(plane_state);
@ -1107,8 +1112,6 @@ static bool rotation_is_valid(const struct intel_plane_state *plane_state)
static void intel_fbc_max_surface_size(struct intel_display *display,
unsigned int *w, unsigned int *h)
{
struct drm_i915_private *i915 = to_i915(display->drm);
if (DISPLAY_VER(display) >= 11) {
*w = 8192;
*h = 4096;
@ -1118,7 +1121,7 @@ static void intel_fbc_max_surface_size(struct intel_display *display,
} else if (DISPLAY_VER(display) >= 7) {
*w = 4096;
*h = 4096;
} else if (DISPLAY_VER(display) >= 5 || IS_G4X(i915)) {
} else if (DISPLAY_VER(display) >= 5 || display->platform.g4x) {
*w = 4096;
*h = 2048;
} else {
@ -1151,15 +1154,13 @@ static bool intel_fbc_surface_size_ok(const struct intel_plane_state *plane_stat
static void intel_fbc_max_plane_size(struct intel_display *display,
unsigned int *w, unsigned int *h)
{
struct drm_i915_private *i915 = to_i915(display->drm);
if (DISPLAY_VER(display) >= 10) {
*w = 5120;
*h = 4096;
} else if (DISPLAY_VER(display) >= 8 || IS_HASWELL(i915)) {
} else if (DISPLAY_VER(display) >= 8 || display->platform.haswell) {
*w = 4096;
*h = 4096;
} else if (DISPLAY_VER(display) >= 5 || IS_G4X(i915)) {
} else if (DISPLAY_VER(display) >= 5 || display->platform.g4x) {
*w = 4096;
*h = 2048;
} else {
@ -1203,6 +1204,74 @@ static bool tiling_is_valid(const struct intel_plane_state *plane_state)
return i8xx_fbc_tiling_valid(plane_state);
}
static void
intel_fbc_invalidate_dirty_rect(struct intel_fbc *fbc)
{
lockdep_assert_held(&fbc->lock);
fbc->state.dirty_rect = DRM_RECT_INIT(0, 0, 0, 0);
}
static void
intel_fbc_program_dirty_rect(struct intel_dsb *dsb, struct intel_fbc *fbc,
const struct drm_rect *fbc_dirty_rect)
{
struct intel_display *display = fbc->display;
drm_WARN_ON(display->drm, fbc_dirty_rect->y2 == 0);
intel_de_write_dsb(display, dsb, XE3_FBC_DIRTY_RECT(fbc->id),
FBC_DIRTY_RECT_START_LINE(fbc_dirty_rect->y1) |
FBC_DIRTY_RECT_END_LINE(fbc_dirty_rect->y2 - 1));
}
static void
intel_fbc_dirty_rect_update(struct intel_dsb *dsb, struct intel_fbc *fbc)
{
const struct drm_rect *fbc_dirty_rect = &fbc->state.dirty_rect;
lockdep_assert_held(&fbc->lock);
if (!drm_rect_visible(fbc_dirty_rect))
return;
intel_fbc_program_dirty_rect(dsb, fbc, fbc_dirty_rect);
}
void
intel_fbc_dirty_rect_update_noarm(struct intel_dsb *dsb,
struct intel_plane *plane)
{
struct intel_display *display = to_intel_display(plane);
struct intel_fbc *fbc = plane->fbc;
if (!HAS_FBC_DIRTY_RECT(display))
return;
mutex_lock(&fbc->lock);
if (fbc->state.plane == plane)
intel_fbc_dirty_rect_update(dsb, fbc);
mutex_unlock(&fbc->lock);
}
static void
intel_fbc_hw_intialize_dirty_rect(struct intel_fbc *fbc,
const struct intel_plane_state *plane_state)
{
struct drm_rect src;
/*
* Initializing the FBC HW with the whole plane area as the dirty rect.
* This is to ensure that we have valid coords be written to the
* HW as dirty rect.
*/
drm_rect_fp_to_int(&src, &plane_state->uapi.src);
intel_fbc_program_dirty_rect(NULL, fbc, &src);
}
static void intel_fbc_update_state(struct intel_atomic_state *state,
struct intel_crtc *crtc,
struct intel_plane *plane)
@ -1276,6 +1345,62 @@ static bool intel_fbc_is_ok(const struct intel_plane_state *plane_state)
intel_fbc_is_cfb_ok(plane_state);
}
static void
__intel_fbc_prepare_dirty_rect(const struct intel_plane_state *plane_state,
const struct intel_crtc_state *crtc_state)
{
struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
struct intel_fbc *fbc = plane->fbc;
struct drm_rect *fbc_dirty_rect = &fbc->state.dirty_rect;
int width = drm_rect_width(&plane_state->uapi.src) >> 16;
const struct drm_rect *damage = &plane_state->damage;
int y_offset = plane_state->view.color_plane[0].y;
lockdep_assert_held(&fbc->lock);
if (intel_crtc_needs_modeset(crtc_state) ||
!intel_fbc_is_ok(plane_state)) {
intel_fbc_invalidate_dirty_rect(fbc);
return;
}
if (drm_rect_visible(damage))
*fbc_dirty_rect = *damage;
else
/* dirty rect must cover at least one line */
*fbc_dirty_rect = DRM_RECT_INIT(0, y_offset, width, 1);
}
void
intel_fbc_prepare_dirty_rect(struct intel_atomic_state *state,
struct intel_crtc *crtc)
{
struct intel_display *display = to_intel_display(state);
const struct intel_crtc_state *crtc_state =
intel_atomic_get_new_crtc_state(state, crtc);
struct intel_plane_state *plane_state;
struct intel_plane *plane;
int i;
if (!HAS_FBC_DIRTY_RECT(display))
return;
for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
struct intel_fbc *fbc = plane->fbc;
if (!fbc || plane->pipe != crtc->pipe)
continue;
mutex_lock(&fbc->lock);
if (fbc->state.plane == plane)
__intel_fbc_prepare_dirty_rect(plane_state,
crtc_state);
mutex_unlock(&fbc->lock);
}
}
static int intel_fbc_check_plane(struct intel_atomic_state *state,
struct intel_plane *plane)
{
@ -1317,7 +1442,7 @@ static int intel_fbc_check_plane(struct intel_atomic_state *state,
}
/* WaFbcTurnOffFbcWhenHyperVisorIsUsed:skl,bxt */
if (i915_vtd_active(i915) && (IS_SKYLAKE(i915) || IS_BROXTON(i915))) {
if (i915_vtd_active(i915) && (display->platform.skylake || display->platform.broxton)) {
plane_state->no_fbc_reason = "VT-d enabled";
return 0;
}
@ -1338,16 +1463,21 @@ static int intel_fbc_check_plane(struct intel_atomic_state *state,
* Display 12+ is not supporting FBC with PSR2.
* Recommendation is to keep this combination disabled
* Bspec: 50422 HSD: 14010260002
*
* In Xe3, PSR2 selective fetch and FBC dirty rect feature cannot
* coexist. So if PSR2 selective fetch is supported then mark that
* FBC is not supported.
* TODO: Need a logic to decide between PSR2 and FBC Dirty rect
*/
if (IS_DISPLAY_VER(display, 12, 14) && crtc_state->has_sel_update &&
!crtc_state->has_panel_replay) {
if ((IS_DISPLAY_VER(display, 12, 14) || HAS_FBC_DIRTY_RECT(display)) &&
crtc_state->has_sel_update && !crtc_state->has_panel_replay) {
plane_state->no_fbc_reason = "PSR2 enabled";
return 0;
}
/* Wa_14016291713 */
if ((IS_DISPLAY_VER(display, 12, 13) ||
IS_DISPLAY_VERx100_STEP(i915, 1400, STEP_A0, STEP_C0)) &&
IS_DISPLAY_VERx100_STEP(display, 1400, STEP_A0, STEP_C0)) &&
crtc_state->has_psr && !crtc_state->has_panel_replay) {
plane_state->no_fbc_reason = "PSR1 enabled (Wa_14016291713)";
return 0;
@ -1410,7 +1540,7 @@ static int intel_fbc_check_plane(struct intel_atomic_state *state,
}
/* WaFbcExceedCdClockThreshold:hsw,bdw */
if (IS_HASWELL(i915) || IS_BROADWELL(i915)) {
if (display->platform.haswell || display->platform.broadwell) {
const struct intel_cdclk_state *cdclk_state;
cdclk_state = intel_atomic_get_cdclk_state(state);
@ -1547,6 +1677,8 @@ static void __intel_fbc_disable(struct intel_fbc *fbc)
drm_dbg_kms(display->drm, "Disabling FBC on [PLANE:%d:%s]\n",
plane->base.base.id, plane->base.name);
intel_fbc_invalidate_dirty_rect(fbc);
__intel_fbc_cleanup_cfb(fbc);
fbc->state.plane = NULL;
@ -1614,14 +1746,14 @@ static void __intel_fbc_invalidate(struct intel_fbc *fbc,
mutex_unlock(&fbc->lock);
}
void intel_fbc_invalidate(struct drm_i915_private *i915,
void intel_fbc_invalidate(struct intel_display *display,
unsigned int frontbuffer_bits,
enum fb_op_origin origin)
{
struct intel_fbc *fbc;
enum intel_fbc_id fbc_id;
for_each_intel_fbc(&i915->display, fbc, fbc_id)
for_each_intel_fbc(display, fbc, fbc_id)
__intel_fbc_invalidate(fbc, frontbuffer_bits, origin);
}
@ -1653,14 +1785,14 @@ static void __intel_fbc_flush(struct intel_fbc *fbc,
mutex_unlock(&fbc->lock);
}
void intel_fbc_flush(struct drm_i915_private *i915,
void intel_fbc_flush(struct intel_display *display,
unsigned int frontbuffer_bits,
enum fb_op_origin origin)
{
struct intel_fbc *fbc;
enum intel_fbc_id fbc_id;
for_each_intel_fbc(&i915->display, fbc, fbc_id)
for_each_intel_fbc(display, fbc, fbc_id)
__intel_fbc_flush(fbc, frontbuffer_bits, origin);
}
@ -1732,6 +1864,9 @@ static void __intel_fbc_enable(struct intel_atomic_state *state,
intel_fbc_update_state(state, crtc, plane);
if (HAS_FBC_DIRTY_RECT(display))
intel_fbc_hw_intialize_dirty_rect(fbc, plane_state);
intel_fbc_program_workarounds(fbc);
intel_fbc_program_cfb(fbc);
}
@ -1897,15 +2032,13 @@ void intel_fbc_handle_fifo_underrun_irq(struct intel_display *display)
*/
static int intel_sanitize_fbc_option(struct intel_display *display)
{
struct drm_i915_private *i915 = to_i915(display->drm);
if (display->params.enable_fbc >= 0)
return !!display->params.enable_fbc;
if (!HAS_FBC(display))
return 0;
if (IS_BROADWELL(i915) || DISPLAY_VER(display) >= 9)
if (display->platform.broadwell || DISPLAY_VER(display) >= 9)
return 1;
return 0;
@ -1919,7 +2052,6 @@ void intel_fbc_add_plane(struct intel_fbc *fbc, struct intel_plane *plane)
static struct intel_fbc *intel_fbc_create(struct intel_display *display,
enum intel_fbc_id fbc_id)
{
struct drm_i915_private *i915 = to_i915(display->drm);
struct intel_fbc *fbc;
fbc = kzalloc(sizeof(*fbc), GFP_KERNEL);
@ -1937,7 +2069,7 @@ static struct intel_fbc *intel_fbc_create(struct intel_display *display,
fbc->funcs = &snb_fbc_funcs;
else if (DISPLAY_VER(display) == 5)
fbc->funcs = &ilk_fbc_funcs;
else if (IS_G4X(i915))
else if (display->platform.g4x)
fbc->funcs = &g4x_fbc_funcs;
else if (DISPLAY_VER(display) == 4)
fbc->funcs = &i965_fbc_funcs;

View File

@ -9,11 +9,11 @@
#include <linux/types.h>
enum fb_op_origin;
struct drm_i915_private;
struct intel_atomic_state;
struct intel_crtc;
struct intel_crtc_state;
struct intel_display;
struct intel_dsb;
struct intel_fbc;
struct intel_plane;
struct intel_plane_state;
@ -38,15 +38,19 @@ void intel_fbc_sanitize(struct intel_display *display);
void intel_fbc_update(struct intel_atomic_state *state,
struct intel_crtc *crtc);
void intel_fbc_disable(struct intel_crtc *crtc);
void intel_fbc_invalidate(struct drm_i915_private *dev_priv,
void intel_fbc_invalidate(struct intel_display *display,
unsigned int frontbuffer_bits,
enum fb_op_origin origin);
void intel_fbc_flush(struct drm_i915_private *dev_priv,
void intel_fbc_flush(struct intel_display *display,
unsigned int frontbuffer_bits, enum fb_op_origin origin);
void intel_fbc_add_plane(struct intel_fbc *fbc, struct intel_plane *plane);
void intel_fbc_handle_fifo_underrun_irq(struct intel_display *display);
void intel_fbc_reset_underrun(struct intel_display *display);
void intel_fbc_crtc_debugfs_add(struct intel_crtc *crtc);
void intel_fbc_debugfs_register(struct intel_display *display);
void intel_fbc_prepare_dirty_rect(struct intel_atomic_state *state,
struct intel_crtc *crtc);
void intel_fbc_dirty_rect_update_noarm(struct intel_dsb *dsb,
struct intel_plane *plane);
#endif /* __INTEL_FBC_H__ */

View File

@ -100,6 +100,15 @@
#define FBC_STRIDE_MASK REG_GENMASK(14, 0)
#define FBC_STRIDE(x) REG_FIELD_PREP(FBC_STRIDE_MASK, (x))
#define XE3_FBC_DIRTY_RECT(fbc_id) _MMIO_PIPE((fbc_id), 0x43230, 0x43270)
#define FBC_DIRTY_RECT_END_LINE_MASK REG_GENMASK(31, 16)
#define FBC_DIRTY_RECT_END_LINE(val) REG_FIELD_PREP(FBC_DIRTY_RECT_END_LINE_MASK, (val))
#define FBC_DIRTY_RECT_START_LINE_MASK REG_GENMASK(15, 0)
#define FBC_DIRTY_RECT_START_LINE(val) REG_FIELD_PREP(FBC_DIRTY_RECT_START_LINE_MASK, (val))
#define XE3_FBC_DIRTY_CTL(fbc_id) _MMIO_PIPE((fbc_id), 0x43234, 0x43274)
#define FBC_DIRTY_RECT_EN REG_BIT(31)
#define ILK_FBC_RT_BASE _MMIO(0x2128)
#define ILK_FBC_RT_VALID REG_BIT(0)
#define SNB_FBC_FRONT_BUFFER REG_BIT(1)

View File

@ -37,14 +37,18 @@
#include <linux/tty.h>
#include <linux/vga_switcheroo.h>
#include <drm/clients/drm_client_setup.h>
#include <drm/drm_crtc.h>
#include <drm/drm_crtc_helper.h>
#include <drm/drm_fb_helper.h>
#include <drm/drm_fourcc.h>
#include <drm/drm_gem.h>
#include <drm/drm_gem_framebuffer_helper.h>
#include <drm/drm_managed.h>
#include <drm/drm_print.h>
#include "i915_drv.h"
#include "i915_vma.h"
#include "intel_bo.h"
#include "intel_display_types.h"
#include "intel_fb.h"
@ -54,24 +58,16 @@
#include "intel_frontbuffer.h"
struct intel_fbdev {
struct drm_fb_helper helper;
struct intel_framebuffer *fb;
struct i915_vma *vma;
unsigned long vma_flags;
int preferred_bpp;
/* Whether or not fbdev hpd processing is temporarily suspended */
bool hpd_suspended: 1;
/* Set when a hotplug was received while HPD processing was suspended */
bool hpd_waiting: 1;
/* Protects hpd_suspended */
struct mutex hpd_lock;
};
static struct intel_fbdev *to_intel_fbdev(struct drm_fb_helper *fb_helper)
{
return container_of(fb_helper, struct intel_fbdev, helper);
struct drm_i915_private *i915 = to_i915(fb_helper->client.dev);
return i915->display.fbdev.fbdev;
}
static struct intel_frontbuffer *to_frontbuffer(struct intel_fbdev *ifbdev)
@ -127,8 +123,8 @@ static int intel_fbdev_pan_display(struct fb_var_screeninfo *var,
static int intel_fbdev_mmap(struct fb_info *info, struct vm_area_struct *vma)
{
struct intel_fbdev *fbdev = to_intel_fbdev(info->par);
struct drm_gem_object *obj = drm_gem_fb_get_obj(&fbdev->fb->base, 0);
struct drm_fb_helper *fb_helper = info->par;
struct drm_gem_object *obj = drm_gem_fb_get_obj(fb_helper->fb, 0);
return intel_bo_fb_mmap(obj, vma);
}
@ -136,9 +132,9 @@ static int intel_fbdev_mmap(struct fb_info *info, struct vm_area_struct *vma)
static void intel_fbdev_fb_destroy(struct fb_info *info)
{
struct drm_fb_helper *fb_helper = info->par;
struct intel_fbdev *ifbdev = container_of(fb_helper, struct intel_fbdev, helper);
struct intel_fbdev *ifbdev = to_intel_fbdev(fb_helper);
drm_fb_helper_fini(&ifbdev->helper);
drm_fb_helper_fini(fb_helper);
/*
* We rely on the object-free to release the VMA pinning for
@ -146,11 +142,11 @@ static void intel_fbdev_fb_destroy(struct fb_info *info)
* trying to rectify all the possible error paths leading here.
*/
intel_fb_unpin_vma(ifbdev->vma, ifbdev->vma_flags);
drm_framebuffer_remove(&ifbdev->fb->base);
drm_framebuffer_remove(fb_helper->fb);
drm_client_release(&fb_helper->client);
drm_fb_helper_unprepare(&ifbdev->helper);
kfree(ifbdev);
drm_fb_helper_unprepare(fb_helper);
kfree(fb_helper);
}
__diag_push();
@ -170,8 +166,48 @@ static const struct fb_ops intelfb_ops = {
__diag_pop();
static int intelfb_create(struct drm_fb_helper *helper,
struct drm_fb_helper_surface_size *sizes)
static int intelfb_dirty(struct drm_fb_helper *helper, struct drm_clip_rect *clip)
{
if (!(clip->x1 < clip->x2 && clip->y1 < clip->y2))
return 0;
if (helper->fb->funcs->dirty)
return helper->fb->funcs->dirty(helper->fb, NULL, 0, 0, clip, 1);
return 0;
}
static void intelfb_restore(struct drm_fb_helper *fb_helper)
{
struct intel_fbdev *ifbdev = to_intel_fbdev(fb_helper);
intel_fbdev_invalidate(ifbdev);
}
static void intelfb_set_suspend(struct drm_fb_helper *fb_helper, bool suspend)
{
struct fb_info *info = fb_helper->info;
/*
* When resuming from hibernation, Linux restores the object's
* content from swap if the buffer is backed by shmemfs. If the
* object is stolen however, it will be full of whatever garbage
* was left in there. Clear it to zero in this case.
*/
if (!suspend && !intel_bo_is_shmem(intel_fb_bo(fb_helper->fb)))
memset_io(info->screen_base, 0, info->screen_size);
fb_set_suspend(info, suspend);
}
static const struct drm_fb_helper_funcs intel_fb_helper_funcs = {
.fb_dirty = intelfb_dirty,
.fb_restore = intelfb_restore,
.fb_set_suspend = intelfb_set_suspend,
};
int intel_fbdev_driver_fbdev_probe(struct drm_fb_helper *helper,
struct drm_fb_helper_surface_size *sizes)
{
struct intel_fbdev *ifbdev = to_intel_fbdev(helper);
struct intel_framebuffer *fb = ifbdev->fb;
@ -185,12 +221,6 @@ static int intelfb_create(struct drm_fb_helper *helper,
struct drm_gem_object *obj;
int ret;
mutex_lock(&ifbdev->hpd_lock);
ret = ifbdev->hpd_suspended ? -EAGAIN : 0;
mutex_unlock(&ifbdev->hpd_lock);
if (ret)
return ret;
ifbdev->fb = NULL;
if (fb &&
@ -240,7 +270,8 @@ static int intelfb_create(struct drm_fb_helper *helper,
goto out_unpin;
}
ifbdev->helper.fb = &fb->base;
helper->funcs = &intel_fb_helper_funcs;
helper->fb = &fb->base;
info->fbops = &intelfb_ops;
@ -250,7 +281,7 @@ static int intelfb_create(struct drm_fb_helper *helper,
if (ret)
goto out_unpin;
drm_fb_helper_fill_info(info, &ifbdev->helper, sizes);
drm_fb_helper_fill_info(info, dev->fb_helper, sizes);
/* If the object is shmemfs backed, it will have given us zeroed pages.
* If the object is stolen however, it will be full of whatever
@ -279,22 +310,6 @@ static int intelfb_create(struct drm_fb_helper *helper,
return ret;
}
static int intelfb_dirty(struct drm_fb_helper *helper, struct drm_clip_rect *clip)
{
if (!(clip->x1 < clip->x2 && clip->y1 < clip->y2))
return 0;
if (helper->fb->funcs->dirty)
return helper->fb->funcs->dirty(helper->fb, NULL, 0, 0, clip, 1);
return 0;
}
static const struct drm_fb_helper_funcs intel_fb_helper_funcs = {
.fb_probe = intelfb_create,
.fb_dirty = intelfb_dirty,
};
/*
* Build an intel_fbdev struct using a BIOS allocated framebuffer, if possible.
* The core display code will have read out the current plane configuration,
@ -417,7 +432,6 @@ static bool intel_fbdev_init_bios(struct drm_device *dev,
goto out;
}
ifbdev->preferred_bpp = fb->base.format->cpp[0] * 8;
ifbdev->fb = fb;
drm_framebuffer_get(&ifbdev->fb->base);
@ -448,251 +462,51 @@ static bool intel_fbdev_init_bios(struct drm_device *dev,
return false;
}
static void intel_fbdev_suspend_worker(struct work_struct *work)
static unsigned int intel_fbdev_color_mode(const struct drm_format_info *info)
{
intel_fbdev_set_suspend(&container_of(work,
struct drm_i915_private,
display.fbdev.suspend_work)->drm,
FBINFO_STATE_RUNNING,
true);
}
unsigned int bpp;
/* Suspends/resumes fbdev processing of incoming HPD events. When resuming HPD
* processing, fbdev will perform a full connector reprobe if a hotplug event
* was received while HPD was suspended.
*/
static void intel_fbdev_hpd_set_suspend(struct drm_i915_private *i915, int state)
{
struct intel_fbdev *ifbdev = i915->display.fbdev.fbdev;
bool send_hpd = false;
if (!info->depth || info->num_planes != 1 || info->has_alpha || info->is_yuv)
return 0;
mutex_lock(&ifbdev->hpd_lock);
ifbdev->hpd_suspended = state == FBINFO_STATE_SUSPENDED;
send_hpd = !ifbdev->hpd_suspended && ifbdev->hpd_waiting;
ifbdev->hpd_waiting = false;
mutex_unlock(&ifbdev->hpd_lock);
bpp = drm_format_info_bpp(info, 0);
if (send_hpd) {
drm_dbg_kms(&i915->drm, "Handling delayed fbcon HPD event\n");
drm_fb_helper_hotplug_event(&ifbdev->helper);
switch (bpp) {
case 16:
return info->depth; // 15 or 16
default:
return bpp;
}
}
void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous)
{
struct drm_i915_private *dev_priv = to_i915(dev);
struct intel_fbdev *ifbdev = dev_priv->display.fbdev.fbdev;
struct fb_info *info;
if (!ifbdev)
return;
if (drm_WARN_ON(&dev_priv->drm, !HAS_DISPLAY(dev_priv)))
return;
if (!ifbdev->vma)
goto set_suspend;
info = ifbdev->helper.info;
if (synchronous) {
/* Flush any pending work to turn the console on, and then
* wait to turn it off. It must be synchronous as we are
* about to suspend or unload the driver.
*
* Note that from within the work-handler, we cannot flush
* ourselves, so only flush outstanding work upon suspend!
*/
if (state != FBINFO_STATE_RUNNING)
flush_work(&dev_priv->display.fbdev.suspend_work);
console_lock();
} else {
/*
* The console lock can be pretty contented on resume due
* to all the printk activity. Try to keep it out of the hot
* path of resume if possible.
*/
drm_WARN_ON(dev, state != FBINFO_STATE_RUNNING);
if (!console_trylock()) {
/* Don't block our own workqueue as this can
* be run in parallel with other i915.ko tasks.
*/
queue_work(dev_priv->unordered_wq,
&dev_priv->display.fbdev.suspend_work);
return;
}
}
/* On resume from hibernation: If the object is shmemfs backed, it has
* been restored from swap. If the object is stolen however, it will be
* full of whatever garbage was left in there.
*/
if (state == FBINFO_STATE_RUNNING &&
!intel_bo_is_shmem(intel_fb_bo(&ifbdev->fb->base)))
memset_io(info->screen_base, 0, info->screen_size);
drm_fb_helper_set_suspend(&ifbdev->helper, state);
console_unlock();
set_suspend:
intel_fbdev_hpd_set_suspend(dev_priv, state);
}
static int intel_fbdev_output_poll_changed(struct drm_device *dev)
{
struct intel_fbdev *ifbdev = to_i915(dev)->display.fbdev.fbdev;
bool send_hpd;
if (!ifbdev)
return -EINVAL;
mutex_lock(&ifbdev->hpd_lock);
send_hpd = !ifbdev->hpd_suspended;
ifbdev->hpd_waiting = true;
mutex_unlock(&ifbdev->hpd_lock);
if (send_hpd && (ifbdev->vma || ifbdev->helper.deferred_setup))
drm_fb_helper_hotplug_event(&ifbdev->helper);
return 0;
}
static int intel_fbdev_restore_mode(struct drm_i915_private *dev_priv)
{
struct intel_fbdev *ifbdev = dev_priv->display.fbdev.fbdev;
int ret;
if (!ifbdev)
return -EINVAL;
if (!ifbdev->vma)
return -ENOMEM;
ret = drm_fb_helper_restore_fbdev_mode_unlocked(&ifbdev->helper);
if (ret)
return ret;
intel_fbdev_invalidate(ifbdev);
return 0;
}
/*
* Fbdev client and struct drm_client_funcs
*/
static void intel_fbdev_client_unregister(struct drm_client_dev *client)
{
struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client);
struct drm_device *dev = fb_helper->dev;
struct pci_dev *pdev = to_pci_dev(dev->dev);
if (fb_helper->info) {
vga_switcheroo_client_fb_set(pdev, NULL);
drm_fb_helper_unregister_info(fb_helper);
} else {
drm_fb_helper_unprepare(fb_helper);
drm_client_release(&fb_helper->client);
kfree(fb_helper);
}
}
static int intel_fbdev_client_restore(struct drm_client_dev *client)
{
struct drm_i915_private *dev_priv = to_i915(client->dev);
int ret;
ret = intel_fbdev_restore_mode(dev_priv);
if (ret)
return ret;
vga_switcheroo_process_delayed_switch();
return 0;
}
static int intel_fbdev_client_hotplug(struct drm_client_dev *client)
{
struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client);
struct drm_device *dev = client->dev;
struct pci_dev *pdev = to_pci_dev(dev->dev);
int ret;
if (dev->fb_helper)
return intel_fbdev_output_poll_changed(dev);
ret = drm_fb_helper_init(dev, fb_helper);
if (ret)
goto err_drm_err;
ret = drm_fb_helper_initial_config(fb_helper);
if (ret)
goto err_drm_fb_helper_fini;
vga_switcheroo_client_fb_set(pdev, fb_helper->info);
return 0;
err_drm_fb_helper_fini:
drm_fb_helper_fini(fb_helper);
err_drm_err:
drm_err(dev, "Failed to setup i915 fbdev emulation (ret=%d)\n", ret);
return ret;
}
static const struct drm_client_funcs intel_fbdev_client_funcs = {
.owner = THIS_MODULE,
.unregister = intel_fbdev_client_unregister,
.restore = intel_fbdev_client_restore,
.hotplug = intel_fbdev_client_hotplug,
};
void intel_fbdev_setup(struct drm_i915_private *i915)
{
struct drm_device *dev = &i915->drm;
struct intel_fbdev *ifbdev;
int ret;
unsigned int preferred_bpp = 0;
if (!HAS_DISPLAY(i915))
return;
ifbdev = kzalloc(sizeof(*ifbdev), GFP_KERNEL);
ifbdev = drmm_kzalloc(dev, sizeof(*ifbdev), GFP_KERNEL);
if (!ifbdev)
return;
drm_fb_helper_prepare(dev, &ifbdev->helper, 32, &intel_fb_helper_funcs);
i915->display.fbdev.fbdev = ifbdev;
INIT_WORK(&i915->display.fbdev.suspend_work, intel_fbdev_suspend_worker);
mutex_init(&ifbdev->hpd_lock);
if (intel_fbdev_init_bios(dev, ifbdev))
ifbdev->helper.preferred_bpp = ifbdev->preferred_bpp;
else
ifbdev->preferred_bpp = ifbdev->helper.preferred_bpp;
preferred_bpp = intel_fbdev_color_mode(ifbdev->fb->base.format);
if (!preferred_bpp)
preferred_bpp = 32;
ret = drm_client_init(dev, &ifbdev->helper.client, "intel-fbdev",
&intel_fbdev_client_funcs);
if (ret) {
drm_err(dev, "Failed to register client: %d\n", ret);
goto err_drm_fb_helper_unprepare;
}
drm_client_register(&ifbdev->helper.client);
return;
err_drm_fb_helper_unprepare:
drm_fb_helper_unprepare(&ifbdev->helper);
mutex_destroy(&ifbdev->hpd_lock);
kfree(ifbdev);
drm_client_setup_with_color_mode(dev, preferred_bpp);
}
struct intel_framebuffer *intel_fbdev_framebuffer(struct intel_fbdev *fbdev)
{
if (!fbdev || !fbdev->helper.fb)
if (!fbdev)
return NULL;
return to_intel_framebuffer(fbdev->helper.fb);
return fbdev->fb;
}
struct i915_vma *intel_fbdev_vma_pointer(struct intel_fbdev *fbdev)

View File

@ -6,28 +6,27 @@
#ifndef __INTEL_FBDEV_H__
#define __INTEL_FBDEV_H__
#include <linux/types.h>
struct drm_device;
struct drm_fb_helper;
struct drm_fb_helper_surface_size;
struct drm_i915_private;
struct intel_fbdev;
struct intel_framebuffer;
#ifdef CONFIG_DRM_FBDEV_EMULATION
int intel_fbdev_driver_fbdev_probe(struct drm_fb_helper *helper,
struct drm_fb_helper_surface_size *sizes);
#define INTEL_FBDEV_DRIVER_OPS \
.fbdev_probe = intel_fbdev_driver_fbdev_probe
void intel_fbdev_setup(struct drm_i915_private *dev_priv);
void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous);
struct intel_framebuffer *intel_fbdev_framebuffer(struct intel_fbdev *fbdev);
struct i915_vma *intel_fbdev_vma_pointer(struct intel_fbdev *fbdev);
#else
#define INTEL_FBDEV_DRIVER_OPS \
.fbdev_probe = NULL
static inline void intel_fbdev_setup(struct drm_i915_private *dev_priv)
{
}
static inline void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous)
{
}
static inline struct intel_framebuffer *intel_fbdev_framebuffer(struct intel_fbdev *fbdev)
{
return NULL;

File diff suppressed because it is too large Load Diff

View File

@ -9,16 +9,16 @@
#include <linux/types.h>
enum pipe;
struct drm_i915_private;
struct intel_atomic_state;
struct intel_crtc;
struct intel_crtc_state;
struct intel_display;
struct intel_display;
struct intel_encoder;
struct intel_link_bw_limits;
int intel_fdi_add_affected_crtcs(struct intel_atomic_state *state);
int intel_fdi_link_freq(struct drm_i915_private *i915,
int intel_fdi_link_freq(struct intel_display *display,
const struct intel_crtc_state *pipe_config);
bool intel_fdi_compute_pipe_bpp(struct intel_crtc_state *crtc_state);
int ilk_fdi_compute_config(struct intel_crtc *intel_crtc,
@ -29,19 +29,19 @@ void intel_fdi_normal_train(struct intel_crtc *crtc);
void ilk_fdi_disable(struct intel_crtc *crtc);
void ilk_fdi_pll_disable(struct intel_crtc *intel_crtc);
void ilk_fdi_pll_enable(const struct intel_crtc_state *crtc_state);
void intel_fdi_init_hook(struct drm_i915_private *dev_priv);
void intel_fdi_init_hook(struct intel_display *display);
void hsw_fdi_link_train(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state);
void hsw_fdi_disable(struct intel_encoder *encoder);
void intel_fdi_pll_freq_update(struct drm_i915_private *i915);
void intel_fdi_pll_freq_update(struct intel_display *display);
void intel_fdi_link_train(struct intel_crtc *crtc,
const struct intel_crtc_state *crtc_state);
void assert_fdi_tx_enabled(struct drm_i915_private *i915, enum pipe pipe);
void assert_fdi_tx_disabled(struct drm_i915_private *i915, enum pipe pipe);
void assert_fdi_rx_enabled(struct drm_i915_private *i915, enum pipe pipe);
void assert_fdi_rx_disabled(struct drm_i915_private *i915, enum pipe pipe);
void assert_fdi_tx_enabled(struct intel_display *display, enum pipe pipe);
void assert_fdi_tx_disabled(struct intel_display *display, enum pipe pipe);
void assert_fdi_rx_enabled(struct intel_display *display, enum pipe pipe);
void assert_fdi_rx_disabled(struct intel_display *display, enum pipe pipe);
void assert_fdi_tx_pll_enabled(struct intel_display *display, enum pipe pipe);
void assert_fdi_rx_pll_enabled(struct intel_display *display, enum pipe pipe);
void assert_fdi_rx_pll_disabled(struct intel_display *display, enum pipe pipe);

View File

@ -59,6 +59,7 @@
#include "i915_active.h"
#include "i915_drv.h"
#include "i915_vma.h"
#include "intel_bo.h"
#include "intel_display_trace.h"
#include "intel_display_types.h"
@ -98,10 +99,10 @@ static void frontbuffer_flush(struct drm_i915_private *i915,
trace_intel_frontbuffer_flush(display, frontbuffer_bits, origin);
might_sleep();
intel_td_flush(i915);
intel_drrs_flush(i915, frontbuffer_bits);
intel_td_flush(display);
intel_drrs_flush(display, frontbuffer_bits);
intel_psr_flush(display, frontbuffer_bits, origin);
intel_fbc_flush(i915, frontbuffer_bits, origin);
intel_fbc_flush(display, frontbuffer_bits, origin);
}
/**
@ -176,7 +177,6 @@ void __intel_fb_invalidate(struct intel_frontbuffer *front,
unsigned int frontbuffer_bits)
{
struct intel_display *display = to_intel_display(front->obj->dev);
struct drm_i915_private *i915 = to_i915(display->drm);
if (origin == ORIGIN_CS) {
spin_lock(&display->fb_tracking.lock);
@ -189,8 +189,8 @@ void __intel_fb_invalidate(struct intel_frontbuffer *front,
might_sleep();
intel_psr_invalidate(display, frontbuffer_bits, origin);
intel_drrs_invalidate(i915, frontbuffer_bits);
intel_fbc_invalidate(i915, frontbuffer_bits, origin);
intel_drrs_invalidate(display, frontbuffer_bits);
intel_fbc_invalidate(display, frontbuffer_bits, origin);
}
void __intel_fb_flush(struct intel_frontbuffer *front,

View File

@ -70,13 +70,13 @@ static int intel_conn_to_vcpi(struct intel_atomic_state *state,
int vcpi = 0;
/* For HDMI this is forced to be 0x0. For DP SST also this is 0x0. */
if (!connector->port)
if (!connector->mst.port)
return 0;
mgr = connector->port->mgr;
mgr = connector->mst.port->mgr;
drm_modeset_lock(&mgr->base.lock, state->base.acquire_ctx);
mst_state = to_drm_dp_mst_topology_state(mgr->base.state);
payload = drm_atomic_get_mst_payload_state(mst_state, connector->port);
payload = drm_atomic_get_mst_payload_state(mst_state, connector->mst.port);
if (drm_WARN_ON(mgr->dev, !payload))
goto out;
@ -107,16 +107,16 @@ intel_hdcp_required_content_stream(struct intel_atomic_state *state,
struct drm_connector_list_iter conn_iter;
struct intel_digital_port *conn_dig_port;
struct intel_connector *connector;
struct hdcp_port_data *data = &dig_port->hdcp_port_data;
struct hdcp_port_data *data = &dig_port->hdcp.port_data;
bool enforce_type0 = false;
int k;
if (dig_port->hdcp_auth_status)
if (dig_port->hdcp.auth_status)
return 0;
data->k = 0;
if (!dig_port->hdcp_mst_type1_capable)
if (!dig_port->hdcp.mst_type1_capable)
enforce_type0 = true;
drm_connector_list_iter_begin(display->drm, &conn_iter);
@ -136,7 +136,7 @@ intel_hdcp_required_content_stream(struct intel_atomic_state *state,
data->k++;
/* if there is only one active stream */
if (dig_port->dp.active_mst_links <= 1)
if (dig_port->dp.mst.active_links <= 1)
break;
}
drm_connector_list_iter_end(&conn_iter);
@ -159,7 +159,7 @@ static int intel_hdcp_prepare_streams(struct intel_atomic_state *state,
struct intel_connector *connector)
{
struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
struct hdcp_port_data *data = &dig_port->hdcp_port_data;
struct hdcp_port_data *data = &dig_port->hdcp.port_data;
struct intel_hdcp *hdcp = &connector->hdcp;
if (intel_encoder_is_mst(intel_attached_encoder(connector)))
@ -1001,7 +1001,7 @@ static int _intel_hdcp_disable(struct intel_connector *connector)
* don't disable it until it disabled HDCP encryption for
* all connectors in MST topology.
*/
if (dig_port->num_hdcp_streams > 0)
if (dig_port->hdcp.num_streams > 0)
return 0;
}
@ -1094,13 +1094,13 @@ static void intel_hdcp_update_value(struct intel_connector *connector,
if (hdcp->value == value)
return;
drm_WARN_ON(display->drm, !mutex_is_locked(&dig_port->hdcp_mutex));
drm_WARN_ON(display->drm, !mutex_is_locked(&dig_port->hdcp.mutex));
if (hdcp->value == DRM_MODE_CONTENT_PROTECTION_ENABLED) {
if (!drm_WARN_ON(display->drm, dig_port->num_hdcp_streams == 0))
dig_port->num_hdcp_streams--;
if (!drm_WARN_ON(display->drm, dig_port->hdcp.num_streams == 0))
dig_port->hdcp.num_streams--;
} else if (value == DRM_MODE_CONTENT_PROTECTION_ENABLED) {
dig_port->num_hdcp_streams++;
dig_port->hdcp.num_streams++;
}
hdcp->value = value;
@ -1122,7 +1122,7 @@ static int intel_hdcp_check_link(struct intel_connector *connector)
int ret = 0;
mutex_lock(&hdcp->mutex);
mutex_lock(&dig_port->hdcp_mutex);
mutex_lock(&dig_port->hdcp.mutex);
cpu_transcoder = hdcp->cpu_transcoder;
@ -1177,7 +1177,7 @@ static int intel_hdcp_check_link(struct intel_connector *connector)
}
out:
mutex_unlock(&dig_port->hdcp_mutex);
mutex_unlock(&dig_port->hdcp.mutex);
mutex_unlock(&hdcp->mutex);
return ret;
}
@ -1219,7 +1219,7 @@ hdcp2_prepare_ake_init(struct intel_connector *connector,
{
struct intel_display *display = to_intel_display(connector);
struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
struct hdcp_port_data *data = &dig_port->hdcp_port_data;
struct hdcp_port_data *data = &dig_port->hdcp.port_data;
struct i915_hdcp_arbiter *arbiter;
int ret;
@ -1249,7 +1249,7 @@ hdcp2_verify_rx_cert_prepare_km(struct intel_connector *connector,
{
struct intel_display *display = to_intel_display(connector);
struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
struct hdcp_port_data *data = &dig_port->hdcp_port_data;
struct hdcp_port_data *data = &dig_port->hdcp.port_data;
struct i915_hdcp_arbiter *arbiter;
int ret;
@ -1277,7 +1277,7 @@ static int hdcp2_verify_hprime(struct intel_connector *connector,
{
struct intel_display *display = to_intel_display(connector);
struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
struct hdcp_port_data *data = &dig_port->hdcp_port_data;
struct hdcp_port_data *data = &dig_port->hdcp.port_data;
struct i915_hdcp_arbiter *arbiter;
int ret;
@ -1303,7 +1303,7 @@ hdcp2_store_pairing_info(struct intel_connector *connector,
{
struct intel_display *display = to_intel_display(connector);
struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
struct hdcp_port_data *data = &dig_port->hdcp_port_data;
struct hdcp_port_data *data = &dig_port->hdcp.port_data;
struct i915_hdcp_arbiter *arbiter;
int ret;
@ -1330,7 +1330,7 @@ hdcp2_prepare_lc_init(struct intel_connector *connector,
{
struct intel_display *display = to_intel_display(connector);
struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
struct hdcp_port_data *data = &dig_port->hdcp_port_data;
struct hdcp_port_data *data = &dig_port->hdcp.port_data;
struct i915_hdcp_arbiter *arbiter;
int ret;
@ -1357,7 +1357,7 @@ hdcp2_verify_lprime(struct intel_connector *connector,
{
struct intel_display *display = to_intel_display(connector);
struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
struct hdcp_port_data *data = &dig_port->hdcp_port_data;
struct hdcp_port_data *data = &dig_port->hdcp.port_data;
struct i915_hdcp_arbiter *arbiter;
int ret;
@ -1383,7 +1383,7 @@ static int hdcp2_prepare_skey(struct intel_connector *connector,
{
struct intel_display *display = to_intel_display(connector);
struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
struct hdcp_port_data *data = &dig_port->hdcp_port_data;
struct hdcp_port_data *data = &dig_port->hdcp.port_data;
struct i915_hdcp_arbiter *arbiter;
int ret;
@ -1412,7 +1412,7 @@ hdcp2_verify_rep_topology_prepare_ack(struct intel_connector *connector,
{
struct intel_display *display = to_intel_display(connector);
struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
struct hdcp_port_data *data = &dig_port->hdcp_port_data;
struct hdcp_port_data *data = &dig_port->hdcp.port_data;
struct i915_hdcp_arbiter *arbiter;
int ret;
@ -1442,7 +1442,7 @@ hdcp2_verify_mprime(struct intel_connector *connector,
{
struct intel_display *display = to_intel_display(connector);
struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
struct hdcp_port_data *data = &dig_port->hdcp_port_data;
struct hdcp_port_data *data = &dig_port->hdcp.port_data;
struct i915_hdcp_arbiter *arbiter;
int ret;
@ -1466,7 +1466,7 @@ static int hdcp2_authenticate_port(struct intel_connector *connector)
{
struct intel_display *display = to_intel_display(connector);
struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
struct hdcp_port_data *data = &dig_port->hdcp_port_data;
struct hdcp_port_data *data = &dig_port->hdcp.port_data;
struct i915_hdcp_arbiter *arbiter;
int ret;
@ -1503,7 +1503,7 @@ static int hdcp2_close_session(struct intel_connector *connector)
}
ret = arbiter->ops->close_hdcp_session(arbiter->hdcp_dev,
&dig_port->hdcp_port_data);
&dig_port->hdcp.port_data);
mutex_unlock(&display->hdcp.hdcp_mutex);
return ret;
@ -1691,7 +1691,7 @@ static
int _hdcp2_propagate_stream_management_info(struct intel_connector *connector)
{
struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
struct hdcp_port_data *data = &dig_port->hdcp_port_data;
struct hdcp_port_data *data = &dig_port->hdcp.port_data;
struct intel_hdcp *hdcp = &connector->hdcp;
union {
struct hdcp2_rep_stream_manage stream_manage;
@ -1769,11 +1769,11 @@ int hdcp2_authenticate_repeater_topology(struct intel_connector *connector)
* MST topology is not Type 1 capable if it contains a downstream
* device that is only HDCP 1.x or Legacy HDCP 2.0/2.1 compliant.
*/
dig_port->hdcp_mst_type1_capable =
dig_port->hdcp.mst_type1_capable =
!HDCP_2_2_HDCP1_DEVICE_CONNECTED(rx_info[1]) &&
!HDCP_2_2_HDCP_2_0_REP_CONNECTED(rx_info[1]);
if (!dig_port->hdcp_mst_type1_capable && hdcp->content_type) {
if (!dig_port->hdcp.mst_type1_capable && hdcp->content_type) {
drm_dbg_kms(display->drm,
"HDCP1.x or 2.0 Legacy Device Downstream\n");
return -EINVAL;
@ -1869,7 +1869,7 @@ static int hdcp2_enable_stream_encryption(struct intel_connector *connector)
{
struct intel_display *display = to_intel_display(connector);
struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
struct hdcp_port_data *data = &dig_port->hdcp_port_data;
struct hdcp_port_data *data = &dig_port->hdcp.port_data;
struct intel_hdcp *hdcp = &connector->hdcp;
enum transcoder cpu_transcoder = hdcp->cpu_transcoder;
enum port port = dig_port->base.port;
@ -1900,7 +1900,7 @@ static int hdcp2_enable_stream_encryption(struct intel_connector *connector)
if (hdcp2_deauthenticate_port(connector) < 0)
drm_dbg_kms(display->drm, "Port deauth failed.\n");
dig_port->hdcp_auth_status = false;
dig_port->hdcp.auth_status = false;
data->k = 0;
return ret;
@ -1940,7 +1940,7 @@ static int hdcp2_enable_encryption(struct intel_connector *connector)
port),
LINK_ENCRYPTION_STATUS,
HDCP_ENCRYPT_STATUS_CHANGE_TIMEOUT_MS);
dig_port->hdcp_auth_status = true;
dig_port->hdcp.auth_status = true;
return ret;
}
@ -2019,7 +2019,7 @@ static int hdcp2_authenticate_and_encrypt(struct intel_atomic_state *state,
struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
int ret = 0, i, tries = 3;
for (i = 0; i < tries && !dig_port->hdcp_auth_status; i++) {
for (i = 0; i < tries && !dig_port->hdcp.auth_status; i++) {
ret = hdcp2_authenticate_sink(connector);
if (!ret) {
ret = intel_hdcp_prepare_streams(state, connector);
@ -2052,7 +2052,7 @@ static int hdcp2_authenticate_and_encrypt(struct intel_atomic_state *state,
drm_dbg_kms(display->drm, "Port deauth failed.\n");
}
if (!ret && !dig_port->hdcp_auth_status) {
if (!ret && !dig_port->hdcp.auth_status) {
/*
* Ensuring the required 200mSec min time interval between
* Session Key Exchange and encryption.
@ -2106,7 +2106,7 @@ _intel_hdcp2_disable(struct intel_connector *connector, bool hdcp2_link_recovery
{
struct intel_display *display = to_intel_display(connector);
struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
struct hdcp_port_data *data = &dig_port->hdcp_port_data;
struct hdcp_port_data *data = &dig_port->hdcp.port_data;
struct intel_hdcp *hdcp = &connector->hdcp;
int ret;
@ -2123,7 +2123,7 @@ _intel_hdcp2_disable(struct intel_connector *connector, bool hdcp2_link_recovery
drm_dbg_kms(display->drm, "HDCP 2.2 transcoder: %s stream encryption disabled\n",
transcoder_name(hdcp->stream_transcoder));
if (dig_port->num_hdcp_streams > 0 && !hdcp2_link_recovery)
if (dig_port->hdcp.num_streams > 0 && !hdcp2_link_recovery)
return 0;
}
@ -2133,7 +2133,7 @@ _intel_hdcp2_disable(struct intel_connector *connector, bool hdcp2_link_recovery
drm_dbg_kms(display->drm, "Port deauth failed.\n");
connector->hdcp.hdcp2_encrypted = false;
dig_port->hdcp_auth_status = false;
dig_port->hdcp.auth_status = false;
data->k = 0;
return ret;
@ -2150,7 +2150,7 @@ static int intel_hdcp2_check_link(struct intel_connector *connector)
int ret = 0;
mutex_lock(&hdcp->mutex);
mutex_lock(&dig_port->hdcp_mutex);
mutex_lock(&dig_port->hdcp.mutex);
cpu_transcoder = hdcp->cpu_transcoder;
/* hdcp2_check_link is expected only when HDCP2.2 is Enabled */
@ -2221,7 +2221,7 @@ static int intel_hdcp2_check_link(struct intel_connector *connector)
intel_hdcp_update_value(connector,
DRM_MODE_CONTENT_PROTECTION_DESIRED, true);
out:
mutex_unlock(&dig_port->hdcp_mutex);
mutex_unlock(&dig_port->hdcp.mutex);
mutex_unlock(&hdcp->mutex);
return ret;
}
@ -2303,7 +2303,7 @@ static int initialize_hdcp_port_data(struct intel_connector *connector,
const struct intel_hdcp_shim *shim)
{
struct intel_display *display = to_intel_display(connector);
struct hdcp_port_data *data = &dig_port->hdcp_port_data;
struct hdcp_port_data *data = &dig_port->hdcp.port_data;
enum port port = dig_port->base.port;
if (DISPLAY_VER(display) < 12)
@ -2414,7 +2414,7 @@ int intel_hdcp_init(struct intel_connector *connector,
hdcp->hdcp2_supported);
if (ret) {
hdcp->hdcp2_supported = false;
kfree(dig_port->hdcp_port_data.streams);
kfree(dig_port->hdcp.port_data.streams);
return ret;
}
@ -2451,7 +2451,7 @@ static int _intel_hdcp_enable(struct intel_atomic_state *state,
}
mutex_lock(&hdcp->mutex);
mutex_lock(&dig_port->hdcp_mutex);
mutex_lock(&dig_port->hdcp.mutex);
drm_WARN_ON(display->drm,
hdcp->value == DRM_MODE_CONTENT_PROTECTION_ENABLED);
hdcp->content_type = (u8)conn_state->hdcp_content_type;
@ -2465,7 +2465,7 @@ static int _intel_hdcp_enable(struct intel_atomic_state *state,
}
if (DISPLAY_VER(display) >= 12)
dig_port->hdcp_port_data.hdcp_transcoder =
dig_port->hdcp.port_data.hdcp_transcoder =
intel_get_hdcp_transcoder(hdcp->cpu_transcoder);
/*
@ -2499,7 +2499,7 @@ static int _intel_hdcp_enable(struct intel_atomic_state *state,
true);
}
mutex_unlock(&dig_port->hdcp_mutex);
mutex_unlock(&dig_port->hdcp.mutex);
mutex_unlock(&hdcp->mutex);
return ret;
}
@ -2535,7 +2535,7 @@ int intel_hdcp_disable(struct intel_connector *connector)
return -ENOENT;
mutex_lock(&hdcp->mutex);
mutex_lock(&dig_port->hdcp_mutex);
mutex_lock(&dig_port->hdcp.mutex);
if (hdcp->value == DRM_MODE_CONTENT_PROTECTION_UNDESIRED)
goto out;
@ -2548,7 +2548,7 @@ int intel_hdcp_disable(struct intel_connector *connector)
ret = _intel_hdcp_disable(connector);
out:
mutex_unlock(&dig_port->hdcp_mutex);
mutex_unlock(&dig_port->hdcp.mutex);
mutex_unlock(&hdcp->mutex);
cancel_delayed_work_sync(&hdcp->check_work);
return ret;
@ -2775,7 +2775,7 @@ static void __intel_hdcp_info(struct seq_file *m, struct intel_connector *connec
void intel_hdcp_info(struct seq_file *m, struct intel_connector *connector)
{
seq_puts(m, "\tHDCP version: ");
if (connector->mst_port) {
if (connector->mst.dp) {
__intel_hdcp_info(m, connector, true);
seq_puts(m, "\tMST Hub HDCP version: ");
}

View File

@ -2360,7 +2360,7 @@ int intel_hdmi_compute_config(struct intel_encoder *encoder,
}
if (intel_hdmi_is_ycbcr420(pipe_config)) {
ret = intel_panel_fitting(pipe_config, conn_state);
ret = intel_pfit_compute_config(pipe_config, conn_state);
if (ret)
return ret;
}

View File

@ -14,7 +14,6 @@ enum port;
struct drm_connector;
struct drm_connector_state;
struct drm_encoder;
struct drm_i915_private;
struct intel_connector;
struct intel_crtc_state;
struct intel_digital_port;

View File

@ -4,6 +4,7 @@
*/
#include <drm/drm_fixed.h>
#include <drm/drm_print.h>
#include "intel_atomic.h"
#include "intel_crtc.h"

View File

@ -53,6 +53,7 @@
#include "intel_lvds_regs.h"
#include "intel_panel.h"
#include "intel_pfit.h"
#include "intel_pfit_regs.h"
#include "intel_pps_regs.h"
/* Private structure for the integrated LVDS support */
@ -468,7 +469,7 @@ static int intel_lvds_compute_config(struct intel_encoder *encoder,
if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)
return -EINVAL;
ret = intel_panel_fitting(crtc_state, conn_state);
ret = intel_pfit_compute_config(crtc_state, conn_state);
if (ret)
return ret;

View File

@ -156,12 +156,6 @@ static void intel_crtc_disable_noatomic_complete(struct intel_crtc *crtc)
{
struct intel_display *display = to_intel_display(crtc);
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
struct intel_bw_state *bw_state =
to_intel_bw_state(i915->display.bw.obj.state);
struct intel_cdclk_state *cdclk_state =
to_intel_cdclk_state(i915->display.cdclk.obj.state);
struct intel_dbuf_state *dbuf_state =
to_intel_dbuf_state(i915->display.dbuf.obj.state);
struct intel_pmdemand_state *pmdemand_state =
to_intel_pmdemand_state(i915->display.pmdemand.obj.state);
struct intel_crtc_state *crtc_state =
@ -179,14 +173,9 @@ static void intel_crtc_disable_noatomic_complete(struct intel_crtc *crtc)
intel_display_power_put_all_in_set(display, &crtc->enabled_power_domains);
cdclk_state->min_cdclk[pipe] = 0;
cdclk_state->min_voltage_level[pipe] = 0;
cdclk_state->active_pipes &= ~BIT(pipe);
dbuf_state->active_pipes &= ~BIT(pipe);
bw_state->data_rate[pipe] = 0;
bw_state->num_active_planes[pipe] = 0;
intel_cdclk_crtc_disable_noatomic(crtc);
skl_wm_crtc_disable_noatomic(crtc);
intel_bw_crtc_disable_noatomic(crtc);
intel_pmdemand_update_port_clock(display, pmdemand_state, pipe, 0);
}
@ -704,10 +693,6 @@ static void readout_plane_state(struct drm_i915_private *i915)
static void intel_modeset_readout_hw_state(struct drm_i915_private *i915)
{
struct intel_display *display = &i915->display;
struct intel_cdclk_state *cdclk_state =
to_intel_cdclk_state(i915->display.cdclk.obj.state);
struct intel_dbuf_state *dbuf_state =
to_intel_dbuf_state(i915->display.dbuf.obj.state);
struct intel_pmdemand_state *pmdemand_state =
to_intel_pmdemand_state(i915->display.pmdemand.obj.state);
enum pipe pipe;
@ -715,7 +700,6 @@ static void intel_modeset_readout_hw_state(struct drm_i915_private *i915)
struct intel_encoder *encoder;
struct intel_connector *connector;
struct drm_connector_list_iter conn_iter;
u8 active_pipes = 0;
for_each_intel_crtc(&i915->drm, crtc) {
struct intel_crtc_state *crtc_state =
@ -732,18 +716,12 @@ static void intel_modeset_readout_hw_state(struct drm_i915_private *i915)
crtc->base.enabled = crtc_state->hw.enable;
crtc->active = crtc_state->hw.active;
if (crtc_state->hw.active)
active_pipes |= BIT(crtc->pipe);
drm_dbg_kms(&i915->drm,
"[CRTC:%d:%s] hw state readout: %s\n",
crtc->base.base.id, crtc->base.name,
str_enabled_disabled(crtc_state->hw.active));
}
cdclk_state->active_pipes = active_pipes;
dbuf_state->active_pipes = active_pipes;
readout_plane_state(i915);
for_each_intel_encoder(&i915->drm, encoder) {
@ -839,12 +817,9 @@ static void intel_modeset_readout_hw_state(struct drm_i915_private *i915)
drm_connector_list_iter_end(&conn_iter);
for_each_intel_crtc(&i915->drm, crtc) {
struct intel_bw_state *bw_state =
to_intel_bw_state(i915->display.bw.obj.state);
struct intel_crtc_state *crtc_state =
to_intel_crtc_state(crtc->base.state);
struct intel_plane *plane;
int min_cdclk = 0;
if (crtc_state->hw.active) {
/*
@ -893,22 +868,17 @@ static void intel_modeset_readout_hw_state(struct drm_i915_private *i915)
crtc_state->min_cdclk[plane->id]);
}
if (crtc_state->hw.active) {
min_cdclk = intel_crtc_compute_min_cdclk(crtc_state);
if (drm_WARN_ON(&i915->drm, min_cdclk < 0))
min_cdclk = 0;
}
cdclk_state->min_cdclk[crtc->pipe] = min_cdclk;
cdclk_state->min_voltage_level[crtc->pipe] =
crtc_state->min_voltage_level;
intel_pmdemand_update_port_clock(display, pmdemand_state, pipe,
crtc_state->port_clock);
intel_bw_crtc_update(bw_state, crtc_state);
}
/* TODO move here (or even earlier?) on all platforms */
if (DISPLAY_VER(display) >= 9)
intel_wm_get_hw_state(i915);
intel_bw_update_hw_state(display);
intel_cdclk_update_hw_state(display);
intel_pmdemand_init_pmdemand_params(display, pmdemand_state);
}
@ -1016,7 +986,10 @@ void intel_modeset_setup_hw_state(struct drm_i915_private *i915,
intel_dpll_sanitize_state(display);
intel_wm_get_hw_state(i915);
/* TODO move earlier on all platforms */
if (DISPLAY_VER(display) < 9)
intel_wm_get_hw_state(i915);
intel_wm_sanitize(i915);
for_each_intel_crtc(&i915->drm, crtc) {
struct intel_crtc_state *crtc_state =

View File

@ -90,10 +90,11 @@ verify_connector_state(struct intel_atomic_state *state,
static void intel_pipe_config_sanity_check(const struct intel_crtc_state *crtc_state)
{
struct intel_display *display = to_intel_display(crtc_state);
struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
if (crtc_state->has_pch_encoder) {
int fdi_dotclock = intel_dotclock_calculate(intel_fdi_link_freq(i915, crtc_state),
int fdi_dotclock = intel_dotclock_calculate(intel_fdi_link_freq(display, crtc_state),
&crtc_state->fdi_m_n);
int dotclock = crtc_state->hw.adjusted_mode.crtc_clock;

View File

@ -42,6 +42,7 @@
#include "intel_frontbuffer.h"
#include "intel_overlay.h"
#include "intel_pci_config.h"
#include "intel_pfit_regs.h"
/* Limits for overlay size. According to intel doc, the real limits are:
* Y width: 4095, UV width (planar): 2047, Y height: 2047,
@ -799,7 +800,6 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay,
struct drm_intel_overlay_put_image *params)
{
struct intel_display *display = overlay->display;
struct drm_i915_private *dev_priv = to_i915(display->drm);
struct overlay_registers __iomem *regs = overlay->regs;
u32 swidth, swidthsw, sheight, ostride;
enum pipe pipe = overlay->crtc->pipe;
@ -814,7 +814,7 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay,
if (ret != 0)
return ret;
atomic_inc(&dev_priv->gpu_error.pending_fb_pin);
atomic_inc(&display->restore.pending_fb_pin);
vma = intel_overlay_pin_fb(new_bo);
if (IS_ERR(vma)) {
@ -902,7 +902,7 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay,
out_unpin:
i915_vma_unpin(vma);
out_pin_section:
atomic_dec(&dev_priv->gpu_error.pending_fb_pin);
atomic_dec(&display->restore.pending_fb_pin);
return ret;
}

View File

@ -10,7 +10,6 @@
struct drm_device;
struct drm_file;
struct drm_i915_private;
struct drm_printer;
struct intel_display;
struct intel_overlay;

View File

@ -32,6 +32,7 @@
#include <linux/pwm.h>
#include <drm/drm_edid.h>
#include <drm/drm_print.h>
#include "intel_backlight.h"
#include "intel_connector.h"

View File

@ -181,10 +181,10 @@ static void ibx_sanitize_pch_ports(struct drm_i915_private *dev_priv)
static void intel_pch_transcoder_set_m1_n1(struct intel_crtc *crtc,
const struct intel_link_m_n *m_n)
{
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
struct intel_display *display = to_intel_display(crtc);
enum pipe pipe = crtc->pipe;
intel_set_m_n(dev_priv, m_n,
intel_set_m_n(display, m_n,
PCH_TRANS_DATA_M1(pipe), PCH_TRANS_DATA_N1(pipe),
PCH_TRANS_LINK_M1(pipe), PCH_TRANS_LINK_N1(pipe));
}
@ -192,10 +192,10 @@ static void intel_pch_transcoder_set_m1_n1(struct intel_crtc *crtc,
static void intel_pch_transcoder_set_m2_n2(struct intel_crtc *crtc,
const struct intel_link_m_n *m_n)
{
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
struct intel_display *display = to_intel_display(crtc);
enum pipe pipe = crtc->pipe;
intel_set_m_n(dev_priv, m_n,
intel_set_m_n(display, m_n,
PCH_TRANS_DATA_M2(pipe), PCH_TRANS_DATA_N2(pipe),
PCH_TRANS_LINK_M2(pipe), PCH_TRANS_LINK_N2(pipe));
}
@ -203,10 +203,10 @@ static void intel_pch_transcoder_set_m2_n2(struct intel_crtc *crtc,
void intel_pch_transcoder_get_m1_n1(struct intel_crtc *crtc,
struct intel_link_m_n *m_n)
{
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
struct intel_display *display = to_intel_display(crtc);
enum pipe pipe = crtc->pipe;
intel_get_m_n(dev_priv, m_n,
intel_get_m_n(display, m_n,
PCH_TRANS_DATA_M1(pipe), PCH_TRANS_DATA_N1(pipe),
PCH_TRANS_LINK_M1(pipe), PCH_TRANS_LINK_N1(pipe));
}
@ -214,10 +214,10 @@ void intel_pch_transcoder_get_m1_n1(struct intel_crtc *crtc,
void intel_pch_transcoder_get_m2_n2(struct intel_crtc *crtc,
struct intel_link_m_n *m_n)
{
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
struct intel_display *display = to_intel_display(crtc);
enum pipe pipe = crtc->pipe;
intel_get_m_n(dev_priv, m_n,
intel_get_m_n(display, m_n,
PCH_TRANS_DATA_M2(pipe), PCH_TRANS_DATA_N2(pipe),
PCH_TRANS_LINK_M2(pipe), PCH_TRANS_LINK_N2(pipe));
}
@ -259,8 +259,8 @@ static void ilk_enable_pch_transcoder(const struct intel_crtc_state *crtc_state)
assert_shared_dpll_enabled(display, crtc_state->shared_dpll);
/* FDI must be feeding us bits for PCH ports */
assert_fdi_tx_enabled(dev_priv, pipe);
assert_fdi_rx_enabled(dev_priv, pipe);
assert_fdi_tx_enabled(display, pipe);
assert_fdi_rx_enabled(display, pipe);
if (HAS_PCH_CPT(dev_priv)) {
reg = TRANS_CHICKEN2(pipe);
@ -316,13 +316,14 @@ static void ilk_enable_pch_transcoder(const struct intel_crtc_state *crtc_state)
static void ilk_disable_pch_transcoder(struct intel_crtc *crtc)
{
struct intel_display *display = to_intel_display(crtc);
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
enum pipe pipe = crtc->pipe;
i915_reg_t reg;
/* FDI relies on the transcoder */
assert_fdi_tx_disabled(dev_priv, pipe);
assert_fdi_rx_disabled(dev_priv, pipe);
assert_fdi_tx_disabled(display, pipe);
assert_fdi_rx_disabled(display, pipe);
/* Ports must be off as well */
assert_pch_ports_disabled(dev_priv, pipe);
@ -479,8 +480,7 @@ void ilk_pch_post_disable(struct intel_atomic_state *state,
static void ilk_pch_clock_get(struct intel_crtc_state *crtc_state)
{
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
struct intel_display *display = to_intel_display(crtc_state);
/* read out port_clock from the DPLL */
i9xx_crtc_clock_get(crtc_state);
@ -491,7 +491,7 @@ static void ilk_pch_clock_get(struct intel_crtc_state *crtc_state)
* Calculate one based on the FDI configuration.
*/
crtc_state->hw.adjusted_mode.crtc_clock =
intel_dotclock_calculate(intel_fdi_link_freq(dev_priv, crtc_state),
intel_dotclock_calculate(intel_fdi_link_freq(display, crtc_state),
&crtc_state->fdi_m_n);
}
@ -549,14 +549,15 @@ void ilk_pch_get_config(struct intel_crtc_state *crtc_state)
static void lpt_enable_pch_transcoder(const struct intel_crtc_state *crtc_state)
{
struct intel_display *display = to_intel_display(crtc_state);
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
u32 val, pipeconf_val;
/* FDI must be feeding us bits for PCH ports */
assert_fdi_tx_enabled(dev_priv, (enum pipe) cpu_transcoder);
assert_fdi_rx_enabled(dev_priv, PIPE_A);
assert_fdi_tx_enabled(display, (enum pipe)cpu_transcoder);
assert_fdi_rx_enabled(display, PIPE_A);
val = intel_de_read(dev_priv, TRANS_CHICKEN2(PIPE_A));
/* Workaround: set timing override bit. */

View File

@ -3,13 +3,17 @@
* Copyright © 2024 Intel Corporation
*/
#include <drm/drm_print.h>
#include "i915_reg.h"
#include "i915_utils.h"
#include "intel_de.h"
#include "intel_display_core.h"
#include "intel_display_driver.h"
#include "intel_display_types.h"
#include "intel_lvds_regs.h"
#include "intel_pfit.h"
#include "intel_pfit_regs.h"
static int intel_pch_pfit_check_dst_window(const struct intel_crtc_state *crtc_state)
{
@ -542,8 +546,8 @@ static int gmch_panel_fitting(struct intel_crtc_state *crtc_state,
return intel_gmch_pfit_check_timings(crtc_state);
}
int intel_panel_fitting(struct intel_crtc_state *crtc_state,
const struct drm_connector_state *conn_state)
int intel_pfit_compute_config(struct intel_crtc_state *crtc_state,
const struct drm_connector_state *conn_state)
{
struct intel_display *display = to_intel_display(crtc_state);
@ -552,3 +556,165 @@ int intel_panel_fitting(struct intel_crtc_state *crtc_state,
else
return pch_panel_fitting(crtc_state, conn_state);
}
void ilk_pfit_enable(const struct intel_crtc_state *crtc_state)
{
struct intel_display *display = to_intel_display(crtc_state);
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
const struct drm_rect *dst = &crtc_state->pch_pfit.dst;
enum pipe pipe = crtc->pipe;
int width = drm_rect_width(dst);
int height = drm_rect_height(dst);
int x = dst->x1;
int y = dst->y1;
if (!crtc_state->pch_pfit.enabled)
return;
/*
* Force use of hard-coded filter coefficients as some pre-programmed
* values are broken, e.g. x201.
*/
if (display->platform.ivybridge || display->platform.haswell)
intel_de_write_fw(display, PF_CTL(pipe), PF_ENABLE |
PF_FILTER_MED_3x3 | PF_PIPE_SEL_IVB(pipe));
else
intel_de_write_fw(display, PF_CTL(pipe), PF_ENABLE |
PF_FILTER_MED_3x3);
intel_de_write_fw(display, PF_WIN_POS(pipe),
PF_WIN_XPOS(x) | PF_WIN_YPOS(y));
intel_de_write_fw(display, PF_WIN_SZ(pipe),
PF_WIN_XSIZE(width) | PF_WIN_YSIZE(height));
}
void ilk_pfit_disable(const struct intel_crtc_state *old_crtc_state)
{
struct intel_display *display = to_intel_display(old_crtc_state);
struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
enum pipe pipe = crtc->pipe;
/*
* To avoid upsetting the power well on haswell only disable the pfit if
* it's in use. The hw state code will make sure we get this right.
*/
if (!old_crtc_state->pch_pfit.enabled)
return;
intel_de_write_fw(display, PF_CTL(pipe), 0);
intel_de_write_fw(display, PF_WIN_POS(pipe), 0);
intel_de_write_fw(display, PF_WIN_SZ(pipe), 0);
}
void ilk_pfit_get_config(struct intel_crtc_state *crtc_state)
{
struct intel_display *display = to_intel_display(crtc_state);
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
u32 ctl, pos, size;
enum pipe pipe;
ctl = intel_de_read(display, PF_CTL(crtc->pipe));
if ((ctl & PF_ENABLE) == 0)
return;
if (display->platform.ivybridge || display->platform.haswell)
pipe = REG_FIELD_GET(PF_PIPE_SEL_MASK_IVB, ctl);
else
pipe = crtc->pipe;
crtc_state->pch_pfit.enabled = true;
pos = intel_de_read(display, PF_WIN_POS(crtc->pipe));
size = intel_de_read(display, PF_WIN_SZ(crtc->pipe));
drm_rect_init(&crtc_state->pch_pfit.dst,
REG_FIELD_GET(PF_WIN_XPOS_MASK, pos),
REG_FIELD_GET(PF_WIN_YPOS_MASK, pos),
REG_FIELD_GET(PF_WIN_XSIZE_MASK, size),
REG_FIELD_GET(PF_WIN_YSIZE_MASK, size));
/*
* We currently do not free assignments of panel fitters on
* ivb/hsw (since we don't use the higher upscaling modes which
* differentiates them) so just WARN about this case for now.
*/
drm_WARN_ON(display->drm, pipe != crtc->pipe);
}
void i9xx_pfit_enable(const struct intel_crtc_state *crtc_state)
{
struct intel_display *display = to_intel_display(crtc_state);
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
if (!crtc_state->gmch_pfit.control)
return;
/*
* The panel fitter should only be adjusted whilst the pipe is disabled,
* according to register description and PRM.
*/
drm_WARN_ON(display->drm,
intel_de_read(display, PFIT_CONTROL(display)) & PFIT_ENABLE);
assert_transcoder_disabled(display, crtc_state->cpu_transcoder);
intel_de_write(display, PFIT_PGM_RATIOS(display),
crtc_state->gmch_pfit.pgm_ratios);
intel_de_write(display, PFIT_CONTROL(display),
crtc_state->gmch_pfit.control);
/*
* Border color in case we don't scale up to the full screen. Black by
* default, change to something else for debugging.
*/
intel_de_write(display, BCLRPAT(display, crtc->pipe), 0);
}
void i9xx_pfit_disable(const struct intel_crtc_state *old_crtc_state)
{
struct intel_display *display = to_intel_display(old_crtc_state);
if (!old_crtc_state->gmch_pfit.control)
return;
assert_transcoder_disabled(display, old_crtc_state->cpu_transcoder);
drm_dbg_kms(display->drm, "disabling pfit, current: 0x%08x\n",
intel_de_read(display, PFIT_CONTROL(display)));
intel_de_write(display, PFIT_CONTROL(display), 0);
}
static bool i9xx_has_pfit(struct intel_display *display)
{
if (display->platform.i830)
return false;
return DISPLAY_VER(display) >= 4 ||
display->platform.pineview || display->platform.mobile;
}
void i9xx_pfit_get_config(struct intel_crtc_state *crtc_state)
{
struct intel_display *display = to_intel_display(crtc_state);
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
enum pipe pipe;
u32 tmp;
if (!i9xx_has_pfit(display))
return;
tmp = intel_de_read(display, PFIT_CONTROL(display));
if (!(tmp & PFIT_ENABLE))
return;
/* Check whether the pfit is attached to our pipe. */
if (DISPLAY_VER(display) >= 4)
pipe = REG_FIELD_GET(PFIT_PIPE_MASK, tmp);
else
pipe = PIPE_B;
if (pipe != crtc->pipe)
return;
crtc_state->gmch_pfit.control = tmp;
crtc_state->gmch_pfit.pgm_ratios =
intel_de_read(display, PFIT_PGM_RATIOS(display));
}

View File

@ -9,7 +9,13 @@
struct drm_connector_state;
struct intel_crtc_state;
int intel_panel_fitting(struct intel_crtc_state *crtc_state,
const struct drm_connector_state *conn_state);
int intel_pfit_compute_config(struct intel_crtc_state *crtc_state,
const struct drm_connector_state *conn_state);
void ilk_pfit_enable(const struct intel_crtc_state *crtc_state);
void ilk_pfit_disable(const struct intel_crtc_state *old_crtc_state);
void ilk_pfit_get_config(struct intel_crtc_state *crtc_state);
void i9xx_pfit_enable(const struct intel_crtc_state *crtc_state);
void i9xx_pfit_disable(const struct intel_crtc_state *old_crtc_state);
void i9xx_pfit_get_config(struct intel_crtc_state *crtc_state);
#endif /* __INTEL_PFIT_H__ */

View File

@ -0,0 +1,79 @@
/* SPDX-License-Identifier: MIT */
/* Copyright © 2025 Intel Corporation */
#ifndef __INTEL_PFIT_REGS_H__
#define __INTEL_PFIT_REGS_H__
#include "intel_display_reg_defs.h"
/* Panel fitting */
#define PFIT_CONTROL(dev_priv) _MMIO(DISPLAY_MMIO_BASE(dev_priv) + 0x61230)
#define PFIT_ENABLE REG_BIT(31)
#define PFIT_PIPE_MASK REG_GENMASK(30, 29) /* 965+ */
#define PFIT_PIPE(pipe) REG_FIELD_PREP(PFIT_PIPE_MASK, (pipe))
#define PFIT_SCALING_MASK REG_GENMASK(28, 26) /* 965+ */
#define PFIT_SCALING_AUTO REG_FIELD_PREP(PFIT_SCALING_MASK, 0)
#define PFIT_SCALING_PROGRAMMED REG_FIELD_PREP(PFIT_SCALING_MASK, 1)
#define PFIT_SCALING_PILLAR REG_FIELD_PREP(PFIT_SCALING_MASK, 2)
#define PFIT_SCALING_LETTER REG_FIELD_PREP(PFIT_SCALING_MASK, 3)
#define PFIT_FILTER_MASK REG_GENMASK(25, 24) /* 965+ */
#define PFIT_FILTER_FUZZY REG_FIELD_PREP(PFIT_FILTER_MASK, 0)
#define PFIT_FILTER_CRISP REG_FIELD_PREP(PFIT_FILTER_MASK, 1)
#define PFIT_FILTER_MEDIAN REG_FIELD_PREP(PFIT_FILTER_MASK, 2)
#define PFIT_VERT_INTERP_MASK REG_GENMASK(11, 10) /* pre-965 */
#define PFIT_VERT_INTERP_BILINEAR REG_FIELD_PREP(PFIT_VERT_INTERP_MASK, 1)
#define PFIT_VERT_AUTO_SCALE REG_BIT(9) /* pre-965 */
#define PFIT_HORIZ_INTERP_MASK REG_GENMASK(7, 6) /* pre-965 */
#define PFIT_HORIZ_INTERP_BILINEAR REG_FIELD_PREP(PFIT_HORIZ_INTERP_MASK, 1)
#define PFIT_HORIZ_AUTO_SCALE REG_BIT(5) /* pre-965 */
#define PFIT_PANEL_8TO6_DITHER_ENABLE REG_BIT(3) /* pre-965 */
#define PFIT_PGM_RATIOS(dev_priv) _MMIO(DISPLAY_MMIO_BASE(dev_priv) + 0x61234)
#define PFIT_VERT_SCALE_MASK REG_GENMASK(31, 20) /* pre-965 */
#define PFIT_VERT_SCALE(x) REG_FIELD_PREP(PFIT_VERT_SCALE_MASK, (x))
#define PFIT_HORIZ_SCALE_MASK REG_GENMASK(15, 4) /* pre-965 */
#define PFIT_HORIZ_SCALE(x) REG_FIELD_PREP(PFIT_HORIZ_SCALE_MASK, (x))
#define PFIT_VERT_SCALE_MASK_965 REG_GENMASK(28, 16) /* 965+ */
#define PFIT_HORIZ_SCALE_MASK_965 REG_GENMASK(12, 0) /* 965+ */
#define PFIT_AUTO_RATIOS(dev_priv) _MMIO(DISPLAY_MMIO_BASE(dev_priv) + 0x61238)
/* CPU panel fitter */
/* IVB+ has 3 fitters, 0 is 7x5 capable, the other two only 3x3 */
#define _PFA_CTL_1 0x68080
#define _PFB_CTL_1 0x68880
#define PF_CTL(pipe) _MMIO_PIPE(pipe, _PFA_CTL_1, _PFB_CTL_1)
#define PF_ENABLE REG_BIT(31)
#define PF_PIPE_SEL_MASK_IVB REG_GENMASK(30, 29) /* ivb/hsw */
#define PF_PIPE_SEL_IVB(pipe) REG_FIELD_PREP(PF_PIPE_SEL_MASK_IVB, (pipe))
#define PF_FILTER_MASK REG_GENMASK(24, 23)
#define PF_FILTER_PROGRAMMED REG_FIELD_PREP(PF_FILTER_MASK, 0)
#define PF_FILTER_MED_3x3 REG_FIELD_PREP(PF_FILTER_MASK, 1)
#define PF_FILTER_EDGE_ENHANCE REG_FIELD_PREP(PF_FILTER_EDGE_MASK, 2)
#define PF_FILTER_EDGE_SOFTEN REG_FIELD_PREP(PF_FILTER_EDGE_MASK, 3)
#define _PFA_WIN_SZ 0x68074
#define _PFB_WIN_SZ 0x68874
#define PF_WIN_SZ(pipe) _MMIO_PIPE(pipe, _PFA_WIN_SZ, _PFB_WIN_SZ)
#define PF_WIN_XSIZE_MASK REG_GENMASK(31, 16)
#define PF_WIN_XSIZE(w) REG_FIELD_PREP(PF_WIN_XSIZE_MASK, (w))
#define PF_WIN_YSIZE_MASK REG_GENMASK(15, 0)
#define PF_WIN_YSIZE(h) REG_FIELD_PREP(PF_WIN_YSIZE_MASK, (h))
#define _PFA_WIN_POS 0x68070
#define _PFB_WIN_POS 0x68870
#define PF_WIN_POS(pipe) _MMIO_PIPE(pipe, _PFA_WIN_POS, _PFB_WIN_POS)
#define PF_WIN_XPOS_MASK REG_GENMASK(31, 16)
#define PF_WIN_XPOS(x) REG_FIELD_PREP(PF_WIN_XPOS_MASK, (x))
#define PF_WIN_YPOS_MASK REG_GENMASK(15, 0)
#define PF_WIN_YPOS(y) REG_FIELD_PREP(PF_WIN_YPOS_MASK, (y))
#define _PFA_VSCALE 0x68084
#define _PFB_VSCALE 0x68884
#define PF_VSCALE(pipe) _MMIO_PIPE(pipe, _PFA_VSCALE, _PFB_VSCALE)
#define _PFA_HSCALE 0x68090
#define _PFB_HSCALE 0x68890
#define PF_HSCALE(pipe) _MMIO_PIPE(pipe, _PFA_HSCALE, _PFB_HSCALE)
#endif /* __INTEL_PFIT_REGS_H__ */

View File

@ -9,7 +9,6 @@
#include <linux/types.h>
struct drm_crtc;
struct drm_i915_private;
struct intel_crtc;
#ifdef CONFIG_DEBUG_FS

View File

@ -5,6 +5,8 @@
#include <linux/dmi.h>
#include <drm/drm_print.h>
#include "intel_display_core.h"
#include "intel_display_types.h"
#include "intel_quirks.h"

View File

@ -5,8 +5,8 @@
#include <linux/math.h>
#include "i915_drv.h"
#include "i915_reg.h"
#include "i915_utils.h"
#include "intel_ddi.h"
#include "intel_ddi_buf_trans.h"
#include "intel_de.h"
@ -27,12 +27,12 @@
* since it is not handled by the shared DPLL framework as on other platforms.
*/
void intel_snps_phy_wait_for_calibration(struct drm_i915_private *i915)
void intel_snps_phy_wait_for_calibration(struct intel_display *display)
{
enum phy phy;
for_each_phy_masked(phy, ~0) {
if (!intel_phy_is_snps(i915, phy))
if (!intel_phy_is_snps(display, phy))
continue;
/*
@ -40,16 +40,16 @@ void intel_snps_phy_wait_for_calibration(struct drm_i915_private *i915)
* which phy was affected and skip setup of the corresponding
* output later.
*/
if (intel_de_wait_for_clear(i915, DG2_PHY_MISC(phy),
if (intel_de_wait_for_clear(display, DG2_PHY_MISC(phy),
DG2_PHY_DP_TX_ACK_MASK, 25))
i915->display.snps.phy_failed_calibration |= BIT(phy);
display->snps.phy_failed_calibration |= BIT(phy);
}
}
void intel_snps_phy_update_psr_power_state(struct intel_encoder *encoder,
bool enable)
{
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
struct intel_display *display = to_intel_display(encoder);
enum phy phy = intel_encoder_to_phy(encoder);
u32 val;
@ -58,20 +58,20 @@ void intel_snps_phy_update_psr_power_state(struct intel_encoder *encoder,
val = REG_FIELD_PREP(SNPS_PHY_TX_REQ_LN_DIS_PWR_STATE_PSR,
enable ? 2 : 3);
intel_de_rmw(i915, SNPS_PHY_TX_REQ(phy),
intel_de_rmw(display, SNPS_PHY_TX_REQ(phy),
SNPS_PHY_TX_REQ_LN_DIS_PWR_STATE_PSR, val);
}
void intel_snps_phy_set_signal_levels(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state)
{
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
struct intel_display *display = to_intel_display(encoder);
const struct intel_ddi_buf_trans *trans;
enum phy phy = intel_encoder_to_phy(encoder);
int n_entries, ln;
trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries);
if (drm_WARN_ON_ONCE(&dev_priv->drm, !trans))
if (drm_WARN_ON_ONCE(display->drm, !trans))
return;
for (ln = 0; ln < 4; ln++) {
@ -82,7 +82,7 @@ void intel_snps_phy_set_signal_levels(struct intel_encoder *encoder,
val |= REG_FIELD_PREP(SNPS_PHY_TX_EQ_PRE, trans->entries[level].snps.pre_cursor);
val |= REG_FIELD_PREP(SNPS_PHY_TX_EQ_POST, trans->entries[level].snps.post_cursor);
intel_de_write(dev_priv, SNPS_PHY_TX_EQ(ln, phy), val);
intel_de_write(display, SNPS_PHY_TX_EQ(ln, phy), val);
}
}
@ -1817,7 +1817,7 @@ int intel_mpllb_calc_state(struct intel_crtc_state *crtc_state,
void intel_mpllb_enable(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state)
{
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
struct intel_display *display = to_intel_display(encoder);
const struct intel_mpllb_state *pll_state = &crtc_state->dpll_hw_state.mpllb;
enum phy phy = intel_encoder_to_phy(encoder);
i915_reg_t enable_reg = (phy <= PHY_D ?
@ -1827,13 +1827,13 @@ void intel_mpllb_enable(struct intel_encoder *encoder,
* 3. Software programs the following PLL registers for the desired
* frequency.
*/
intel_de_write(dev_priv, SNPS_PHY_MPLLB_CP(phy), pll_state->mpllb_cp);
intel_de_write(dev_priv, SNPS_PHY_MPLLB_DIV(phy), pll_state->mpllb_div);
intel_de_write(dev_priv, SNPS_PHY_MPLLB_DIV2(phy), pll_state->mpllb_div2);
intel_de_write(dev_priv, SNPS_PHY_MPLLB_SSCEN(phy), pll_state->mpllb_sscen);
intel_de_write(dev_priv, SNPS_PHY_MPLLB_SSCSTEP(phy), pll_state->mpllb_sscstep);
intel_de_write(dev_priv, SNPS_PHY_MPLLB_FRACN1(phy), pll_state->mpllb_fracn1);
intel_de_write(dev_priv, SNPS_PHY_MPLLB_FRACN2(phy), pll_state->mpllb_fracn2);
intel_de_write(display, SNPS_PHY_MPLLB_CP(phy), pll_state->mpllb_cp);
intel_de_write(display, SNPS_PHY_MPLLB_DIV(phy), pll_state->mpllb_div);
intel_de_write(display, SNPS_PHY_MPLLB_DIV2(phy), pll_state->mpllb_div2);
intel_de_write(display, SNPS_PHY_MPLLB_SSCEN(phy), pll_state->mpllb_sscen);
intel_de_write(display, SNPS_PHY_MPLLB_SSCSTEP(phy), pll_state->mpllb_sscstep);
intel_de_write(display, SNPS_PHY_MPLLB_FRACN1(phy), pll_state->mpllb_fracn1);
intel_de_write(display, SNPS_PHY_MPLLB_FRACN2(phy), pll_state->mpllb_fracn2);
/*
* 4. If the frequency will result in a change to the voltage
@ -1844,7 +1844,7 @@ void intel_mpllb_enable(struct intel_encoder *encoder,
*/
/* 5. Software sets DPLL_ENABLE [PLL Enable] to "1". */
intel_de_rmw(dev_priv, enable_reg, 0, PLL_ENABLE);
intel_de_rmw(display, enable_reg, 0, PLL_ENABLE);
/*
* 9. Software sets SNPS_PHY_MPLLB_DIV dp_mpllb_force_en to "1". This
@ -1853,7 +1853,7 @@ void intel_mpllb_enable(struct intel_encoder *encoder,
* PLL because that will start the PLL before it has sampled the
* divider values.
*/
intel_de_write(dev_priv, SNPS_PHY_MPLLB_DIV(phy),
intel_de_write(display, SNPS_PHY_MPLLB_DIV(phy),
pll_state->mpllb_div | SNPS_PHY_MPLLB_FORCE_EN);
/*
@ -1861,8 +1861,8 @@ void intel_mpllb_enable(struct intel_encoder *encoder,
* is locked at new settings. This register bit is sampling PHY
* dp_mpllb_state interface signal.
*/
if (intel_de_wait_for_set(dev_priv, enable_reg, PLL_LOCK, 5))
drm_dbg_kms(&dev_priv->drm, "Port %c PLL not locked\n", phy_name(phy));
if (intel_de_wait_for_set(display, enable_reg, PLL_LOCK, 5))
drm_dbg_kms(display->drm, "Port %c PLL not locked\n", phy_name(phy));
/*
* 11. If the frequency will result in a change to the voltage
@ -1875,7 +1875,7 @@ void intel_mpllb_enable(struct intel_encoder *encoder,
void intel_mpllb_disable(struct intel_encoder *encoder)
{
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
struct intel_display *display = to_intel_display(encoder);
enum phy phy = intel_encoder_to_phy(encoder);
i915_reg_t enable_reg = (phy <= PHY_D ?
DG2_PLL_ENABLE(phy) : MG_PLL_ENABLE(0));
@ -1889,20 +1889,20 @@ void intel_mpllb_disable(struct intel_encoder *encoder)
*/
/* 2. Software programs DPLL_ENABLE [PLL Enable] to "0" */
intel_de_rmw(i915, enable_reg, PLL_ENABLE, 0);
intel_de_rmw(display, enable_reg, PLL_ENABLE, 0);
/*
* 4. Software programs SNPS_PHY_MPLLB_DIV dp_mpllb_force_en to "0".
* This will allow the PLL to stop running.
*/
intel_de_rmw(i915, SNPS_PHY_MPLLB_DIV(phy), SNPS_PHY_MPLLB_FORCE_EN, 0);
intel_de_rmw(display, SNPS_PHY_MPLLB_DIV(phy), SNPS_PHY_MPLLB_FORCE_EN, 0);
/*
* 5. Software polls DPLL_ENABLE [PLL Lock] for PHY acknowledgment
* (dp_txX_ack) that the new transmitter setting request is completed.
*/
if (intel_de_wait_for_clear(i915, enable_reg, PLL_LOCK, 5))
drm_err(&i915->drm, "Port %c PLL not locked\n", phy_name(phy));
if (intel_de_wait_for_clear(display, enable_reg, PLL_LOCK, 5))
drm_err(display->drm, "Port %c PLL not locked\n", phy_name(phy));
/*
* 6. If the frequency will result in a change to the voltage
@ -1947,16 +1947,16 @@ int intel_mpllb_calc_port_clock(struct intel_encoder *encoder,
void intel_mpllb_readout_hw_state(struct intel_encoder *encoder,
struct intel_mpllb_state *pll_state)
{
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
struct intel_display *display = to_intel_display(encoder);
enum phy phy = intel_encoder_to_phy(encoder);
pll_state->mpllb_cp = intel_de_read(dev_priv, SNPS_PHY_MPLLB_CP(phy));
pll_state->mpllb_div = intel_de_read(dev_priv, SNPS_PHY_MPLLB_DIV(phy));
pll_state->mpllb_div2 = intel_de_read(dev_priv, SNPS_PHY_MPLLB_DIV2(phy));
pll_state->mpllb_sscen = intel_de_read(dev_priv, SNPS_PHY_MPLLB_SSCEN(phy));
pll_state->mpllb_sscstep = intel_de_read(dev_priv, SNPS_PHY_MPLLB_SSCSTEP(phy));
pll_state->mpllb_fracn1 = intel_de_read(dev_priv, SNPS_PHY_MPLLB_FRACN1(phy));
pll_state->mpllb_fracn2 = intel_de_read(dev_priv, SNPS_PHY_MPLLB_FRACN2(phy));
pll_state->mpllb_cp = intel_de_read(display, SNPS_PHY_MPLLB_CP(phy));
pll_state->mpllb_div = intel_de_read(display, SNPS_PHY_MPLLB_DIV(phy));
pll_state->mpllb_div2 = intel_de_read(display, SNPS_PHY_MPLLB_DIV2(phy));
pll_state->mpllb_sscen = intel_de_read(display, SNPS_PHY_MPLLB_SSCEN(phy));
pll_state->mpllb_sscstep = intel_de_read(display, SNPS_PHY_MPLLB_SSCSTEP(phy));
pll_state->mpllb_fracn1 = intel_de_read(display, SNPS_PHY_MPLLB_FRACN1(phy));
pll_state->mpllb_fracn2 = intel_de_read(display, SNPS_PHY_MPLLB_FRACN2(phy));
/*
* REF_CONTROL is under firmware control and never programmed by the
@ -1964,7 +1964,7 @@ void intel_mpllb_readout_hw_state(struct intel_encoder *encoder,
* only tells us the expected value for one field in this register,
* so we'll only read out those specific bits here.
*/
pll_state->ref_control = intel_de_read(dev_priv, SNPS_PHY_REF_CONTROL(phy)) &
pll_state->ref_control = intel_de_read(display, SNPS_PHY_REF_CONTROL(phy)) &
SNPS_PHY_REF_CONTROL_REF_RANGE;
/*
@ -1980,14 +1980,13 @@ void intel_mpllb_state_verify(struct intel_atomic_state *state,
struct intel_crtc *crtc)
{
struct intel_display *display = to_intel_display(state);
struct drm_i915_private *i915 = to_i915(state->base.dev);
const struct intel_crtc_state *new_crtc_state =
intel_atomic_get_new_crtc_state(state, crtc);
struct intel_mpllb_state mpllb_hw_state = {};
const struct intel_mpllb_state *mpllb_sw_state = &new_crtc_state->dpll_hw_state.mpllb;
struct intel_encoder *encoder;
if (!IS_DG2(i915))
if (!display->platform.dg2)
return;
if (!new_crtc_state->hw.active)

View File

@ -8,15 +8,15 @@
#include <linux/types.h>
struct drm_i915_private;
enum phy;
struct intel_atomic_state;
struct intel_crtc;
struct intel_crtc_state;
struct intel_display;
struct intel_encoder;
struct intel_mpllb_state;
enum phy;
void intel_snps_phy_wait_for_calibration(struct drm_i915_private *dev_priv);
void intel_snps_phy_wait_for_calibration(struct intel_display *display);
void intel_snps_phy_update_psr_power_state(struct intel_encoder *encoder,
bool enable);

View File

@ -14,12 +14,12 @@
* the display flip, since display engine is never coherent with CPU/GPU caches.
*/
struct drm_i915_private;
struct intel_display;
#ifdef I915
static inline void intel_td_flush(struct drm_i915_private *i915) {}
static inline void intel_td_flush(struct intel_display *display) {}
#else
void intel_td_flush(struct drm_i915_private *i915);
void intel_td_flush(struct intel_display *display);
#endif
#endif

View File

@ -10,7 +10,7 @@
#include <drm/display/drm_dsc_helper.h>
#include <drm/drm_fixed.h>
#include "i915_drv.h"
#include "i915_utils.h"
#include "intel_crtc.h"
#include "intel_de.h"
#include "intel_display_types.h"
@ -22,14 +22,13 @@
bool intel_dsc_source_support(const struct intel_crtc_state *crtc_state)
{
const struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
struct intel_display *display = to_intel_display(crtc_state);
enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
if (!HAS_DSC(i915))
if (!HAS_DSC(display))
return false;
if (DISPLAY_VER(i915) == 11 && cpu_transcoder == TRANSCODER_A)
if (DISPLAY_VER(display) == 11 && cpu_transcoder == TRANSCODER_A)
return false;
return true;
@ -37,9 +36,9 @@ bool intel_dsc_source_support(const struct intel_crtc_state *crtc_state)
static bool is_pipe_dsc(struct intel_crtc *crtc, enum transcoder cpu_transcoder)
{
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
struct intel_display *display = to_intel_display(crtc);
if (DISPLAY_VER(i915) >= 12)
if (DISPLAY_VER(display) >= 12)
return true;
if (cpu_transcoder == TRANSCODER_EDP ||
@ -48,7 +47,7 @@ static bool is_pipe_dsc(struct intel_crtc *crtc, enum transcoder cpu_transcoder)
return false;
/* There's no pipe A DSC engine on ICL */
drm_WARN_ON(&i915->drm, crtc->pipe == PIPE_A);
drm_WARN_ON(display->drm, crtc->pipe == PIPE_A);
return true;
}
@ -262,8 +261,7 @@ static int intel_dsc_slice_dimensions_valid(struct intel_crtc_state *pipe_config
int intel_dsc_compute_params(struct intel_crtc_state *pipe_config)
{
struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
struct intel_display *display = to_intel_display(pipe_config);
struct drm_dsc_config *vdsc_cfg = &pipe_config->dsc.config;
u16 compressed_bpp = fxp_q4_to_int(pipe_config->dsc.compressed_bpp_x16);
int err;
@ -276,7 +274,7 @@ int intel_dsc_compute_params(struct intel_crtc_state *pipe_config)
err = intel_dsc_slice_dimensions_valid(pipe_config, vdsc_cfg);
if (err) {
drm_dbg_kms(&dev_priv->drm, "Slice dimension requirements not met\n");
drm_dbg_kms(display->drm, "Slice dimension requirements not met\n");
return err;
}
@ -287,7 +285,7 @@ int intel_dsc_compute_params(struct intel_crtc_state *pipe_config)
vdsc_cfg->convert_rgb = pipe_config->output_format != INTEL_OUTPUT_FORMAT_YCBCR420 &&
pipe_config->output_format != INTEL_OUTPUT_FORMAT_YCBCR444;
if (DISPLAY_VER(dev_priv) >= 14 &&
if (DISPLAY_VER(display) >= 14 &&
pipe_config->output_format == INTEL_OUTPUT_FORMAT_YCBCR420)
vdsc_cfg->native_420 = true;
/* We do not support YcBCr422 as of now */
@ -308,7 +306,7 @@ int intel_dsc_compute_params(struct intel_crtc_state *pipe_config)
vdsc_cfg->bits_per_component = pipe_config->pipe_bpp / 3;
if (vdsc_cfg->bits_per_component < 8) {
drm_dbg_kms(&dev_priv->drm, "DSC bpc requirements not met bpc: %d\n",
drm_dbg_kms(display->drm, "DSC bpc requirements not met bpc: %d\n",
vdsc_cfg->bits_per_component);
return -EINVAL;
}
@ -320,7 +318,7 @@ int intel_dsc_compute_params(struct intel_crtc_state *pipe_config)
* upto uncompressed bpp-1, hence add calculations for all the rc
* parameters
*/
if (DISPLAY_VER(dev_priv) >= 13) {
if (DISPLAY_VER(display) >= 13) {
calculate_rc_params(vdsc_cfg);
} else {
if ((compressed_bpp == 8 ||
@ -356,7 +354,7 @@ int intel_dsc_compute_params(struct intel_crtc_state *pipe_config)
enum intel_display_power_domain
intel_dsc_power_domain(struct intel_crtc *crtc, enum transcoder cpu_transcoder)
{
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
struct intel_display *display = to_intel_display(crtc);
enum pipe pipe = crtc->pipe;
/*
@ -370,7 +368,8 @@ intel_dsc_power_domain(struct intel_crtc *crtc, enum transcoder cpu_transcoder)
* the pipe in use. Hence another reference on the pipe power domain
* will suffice. (Except no VDSC/joining on ICL pipe A.)
*/
if (DISPLAY_VER(i915) == 12 && !IS_ROCKETLAKE(i915) && pipe == PIPE_A)
if (DISPLAY_VER(display) == 12 && !display->platform.rocketlake &&
pipe == PIPE_A)
return POWER_DOMAIN_TRANSCODER_VDSC_PW2;
else if (is_pipe_dsc(crtc, cpu_transcoder))
return POWER_DOMAIN_PIPE(pipe);
@ -416,26 +415,25 @@ static void intel_dsc_get_pps_reg(const struct intel_crtc_state *crtc_state, int
static void intel_dsc_pps_write(const struct intel_crtc_state *crtc_state,
int pps, u32 pps_val)
{
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
struct intel_display *display = to_intel_display(crtc_state);
i915_reg_t dsc_reg[3];
int i, vdsc_per_pipe, dsc_reg_num;
vdsc_per_pipe = intel_dsc_get_vdsc_per_pipe(crtc_state);
dsc_reg_num = min_t(int, ARRAY_SIZE(dsc_reg), vdsc_per_pipe);
drm_WARN_ON_ONCE(&i915->drm, dsc_reg_num < vdsc_per_pipe);
drm_WARN_ON_ONCE(display->drm, dsc_reg_num < vdsc_per_pipe);
intel_dsc_get_pps_reg(crtc_state, pps, dsc_reg, dsc_reg_num);
for (i = 0; i < dsc_reg_num; i++)
intel_de_write(i915, dsc_reg[i], pps_val);
intel_de_write(display, dsc_reg[i], pps_val);
}
static void intel_dsc_pps_configure(const struct intel_crtc_state *crtc_state)
{
struct intel_display *display = to_intel_display(crtc_state);
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
const struct drm_dsc_config *vdsc_cfg = &crtc_state->dsc.config;
enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
enum pipe pipe = crtc->pipe;
@ -529,7 +527,7 @@ static void intel_dsc_pps_configure(const struct intel_crtc_state *crtc_state)
vdsc_cfg->slice_height);
intel_dsc_pps_write(crtc_state, 16, pps_val);
if (DISPLAY_VER(dev_priv) >= 14) {
if (DISPLAY_VER(display) >= 14) {
/* PPS 17 */
pps_val = DSC_PPS17_SL_BPG_OFFSET(vdsc_cfg->second_line_bpg_offset);
intel_dsc_pps_write(crtc_state, 17, pps_val);
@ -547,44 +545,44 @@ static void intel_dsc_pps_configure(const struct intel_crtc_state *crtc_state)
(u32)(vdsc_cfg->rc_buf_thresh[i] <<
BITS_PER_BYTE * (i % 4));
if (!is_pipe_dsc(crtc, cpu_transcoder)) {
intel_de_write(dev_priv, DSCA_RC_BUF_THRESH_0,
intel_de_write(display, DSCA_RC_BUF_THRESH_0,
rc_buf_thresh_dword[0]);
intel_de_write(dev_priv, DSCA_RC_BUF_THRESH_0_UDW,
intel_de_write(display, DSCA_RC_BUF_THRESH_0_UDW,
rc_buf_thresh_dword[1]);
intel_de_write(dev_priv, DSCA_RC_BUF_THRESH_1,
intel_de_write(display, DSCA_RC_BUF_THRESH_1,
rc_buf_thresh_dword[2]);
intel_de_write(dev_priv, DSCA_RC_BUF_THRESH_1_UDW,
intel_de_write(display, DSCA_RC_BUF_THRESH_1_UDW,
rc_buf_thresh_dword[3]);
if (vdsc_instances_per_pipe > 1) {
intel_de_write(dev_priv, DSCC_RC_BUF_THRESH_0,
intel_de_write(display, DSCC_RC_BUF_THRESH_0,
rc_buf_thresh_dword[0]);
intel_de_write(dev_priv, DSCC_RC_BUF_THRESH_0_UDW,
intel_de_write(display, DSCC_RC_BUF_THRESH_0_UDW,
rc_buf_thresh_dword[1]);
intel_de_write(dev_priv, DSCC_RC_BUF_THRESH_1,
intel_de_write(display, DSCC_RC_BUF_THRESH_1,
rc_buf_thresh_dword[2]);
intel_de_write(dev_priv, DSCC_RC_BUF_THRESH_1_UDW,
intel_de_write(display, DSCC_RC_BUF_THRESH_1_UDW,
rc_buf_thresh_dword[3]);
}
} else {
intel_de_write(dev_priv, ICL_DSC0_RC_BUF_THRESH_0(pipe),
intel_de_write(display, ICL_DSC0_RC_BUF_THRESH_0(pipe),
rc_buf_thresh_dword[0]);
intel_de_write(dev_priv, ICL_DSC0_RC_BUF_THRESH_0_UDW(pipe),
intel_de_write(display, ICL_DSC0_RC_BUF_THRESH_0_UDW(pipe),
rc_buf_thresh_dword[1]);
intel_de_write(dev_priv, ICL_DSC0_RC_BUF_THRESH_1(pipe),
intel_de_write(display, ICL_DSC0_RC_BUF_THRESH_1(pipe),
rc_buf_thresh_dword[2]);
intel_de_write(dev_priv, ICL_DSC0_RC_BUF_THRESH_1_UDW(pipe),
intel_de_write(display, ICL_DSC0_RC_BUF_THRESH_1_UDW(pipe),
rc_buf_thresh_dword[3]);
if (vdsc_instances_per_pipe > 1) {
intel_de_write(dev_priv,
intel_de_write(display,
ICL_DSC1_RC_BUF_THRESH_0(pipe),
rc_buf_thresh_dword[0]);
intel_de_write(dev_priv,
intel_de_write(display,
ICL_DSC1_RC_BUF_THRESH_0_UDW(pipe),
rc_buf_thresh_dword[1]);
intel_de_write(dev_priv,
intel_de_write(display,
ICL_DSC1_RC_BUF_THRESH_1(pipe),
rc_buf_thresh_dword[2]);
intel_de_write(dev_priv,
intel_de_write(display,
ICL_DSC1_RC_BUF_THRESH_1_UDW(pipe),
rc_buf_thresh_dword[3]);
}
@ -601,88 +599,88 @@ static void intel_dsc_pps_configure(const struct intel_crtc_state *crtc_state)
(vdsc_cfg->rc_range_params[i].range_min_qp <<
RC_MIN_QP_SHIFT)) << 16 * (i % 2));
if (!is_pipe_dsc(crtc, cpu_transcoder)) {
intel_de_write(dev_priv, DSCA_RC_RANGE_PARAMETERS_0,
intel_de_write(display, DSCA_RC_RANGE_PARAMETERS_0,
rc_range_params_dword[0]);
intel_de_write(dev_priv, DSCA_RC_RANGE_PARAMETERS_0_UDW,
intel_de_write(display, DSCA_RC_RANGE_PARAMETERS_0_UDW,
rc_range_params_dword[1]);
intel_de_write(dev_priv, DSCA_RC_RANGE_PARAMETERS_1,
intel_de_write(display, DSCA_RC_RANGE_PARAMETERS_1,
rc_range_params_dword[2]);
intel_de_write(dev_priv, DSCA_RC_RANGE_PARAMETERS_1_UDW,
intel_de_write(display, DSCA_RC_RANGE_PARAMETERS_1_UDW,
rc_range_params_dword[3]);
intel_de_write(dev_priv, DSCA_RC_RANGE_PARAMETERS_2,
intel_de_write(display, DSCA_RC_RANGE_PARAMETERS_2,
rc_range_params_dword[4]);
intel_de_write(dev_priv, DSCA_RC_RANGE_PARAMETERS_2_UDW,
intel_de_write(display, DSCA_RC_RANGE_PARAMETERS_2_UDW,
rc_range_params_dword[5]);
intel_de_write(dev_priv, DSCA_RC_RANGE_PARAMETERS_3,
intel_de_write(display, DSCA_RC_RANGE_PARAMETERS_3,
rc_range_params_dword[6]);
intel_de_write(dev_priv, DSCA_RC_RANGE_PARAMETERS_3_UDW,
intel_de_write(display, DSCA_RC_RANGE_PARAMETERS_3_UDW,
rc_range_params_dword[7]);
if (vdsc_instances_per_pipe > 1) {
intel_de_write(dev_priv, DSCC_RC_RANGE_PARAMETERS_0,
intel_de_write(display, DSCC_RC_RANGE_PARAMETERS_0,
rc_range_params_dword[0]);
intel_de_write(dev_priv,
intel_de_write(display,
DSCC_RC_RANGE_PARAMETERS_0_UDW,
rc_range_params_dword[1]);
intel_de_write(dev_priv, DSCC_RC_RANGE_PARAMETERS_1,
intel_de_write(display, DSCC_RC_RANGE_PARAMETERS_1,
rc_range_params_dword[2]);
intel_de_write(dev_priv,
intel_de_write(display,
DSCC_RC_RANGE_PARAMETERS_1_UDW,
rc_range_params_dword[3]);
intel_de_write(dev_priv, DSCC_RC_RANGE_PARAMETERS_2,
intel_de_write(display, DSCC_RC_RANGE_PARAMETERS_2,
rc_range_params_dword[4]);
intel_de_write(dev_priv,
intel_de_write(display,
DSCC_RC_RANGE_PARAMETERS_2_UDW,
rc_range_params_dword[5]);
intel_de_write(dev_priv, DSCC_RC_RANGE_PARAMETERS_3,
intel_de_write(display, DSCC_RC_RANGE_PARAMETERS_3,
rc_range_params_dword[6]);
intel_de_write(dev_priv,
intel_de_write(display,
DSCC_RC_RANGE_PARAMETERS_3_UDW,
rc_range_params_dword[7]);
}
} else {
intel_de_write(dev_priv, ICL_DSC0_RC_RANGE_PARAMETERS_0(pipe),
intel_de_write(display, ICL_DSC0_RC_RANGE_PARAMETERS_0(pipe),
rc_range_params_dword[0]);
intel_de_write(dev_priv,
intel_de_write(display,
ICL_DSC0_RC_RANGE_PARAMETERS_0_UDW(pipe),
rc_range_params_dword[1]);
intel_de_write(dev_priv, ICL_DSC0_RC_RANGE_PARAMETERS_1(pipe),
intel_de_write(display, ICL_DSC0_RC_RANGE_PARAMETERS_1(pipe),
rc_range_params_dword[2]);
intel_de_write(dev_priv,
intel_de_write(display,
ICL_DSC0_RC_RANGE_PARAMETERS_1_UDW(pipe),
rc_range_params_dword[3]);
intel_de_write(dev_priv, ICL_DSC0_RC_RANGE_PARAMETERS_2(pipe),
intel_de_write(display, ICL_DSC0_RC_RANGE_PARAMETERS_2(pipe),
rc_range_params_dword[4]);
intel_de_write(dev_priv,
intel_de_write(display,
ICL_DSC0_RC_RANGE_PARAMETERS_2_UDW(pipe),
rc_range_params_dword[5]);
intel_de_write(dev_priv, ICL_DSC0_RC_RANGE_PARAMETERS_3(pipe),
intel_de_write(display, ICL_DSC0_RC_RANGE_PARAMETERS_3(pipe),
rc_range_params_dword[6]);
intel_de_write(dev_priv,
intel_de_write(display,
ICL_DSC0_RC_RANGE_PARAMETERS_3_UDW(pipe),
rc_range_params_dword[7]);
if (vdsc_instances_per_pipe > 1) {
intel_de_write(dev_priv,
intel_de_write(display,
ICL_DSC1_RC_RANGE_PARAMETERS_0(pipe),
rc_range_params_dword[0]);
intel_de_write(dev_priv,
intel_de_write(display,
ICL_DSC1_RC_RANGE_PARAMETERS_0_UDW(pipe),
rc_range_params_dword[1]);
intel_de_write(dev_priv,
intel_de_write(display,
ICL_DSC1_RC_RANGE_PARAMETERS_1(pipe),
rc_range_params_dword[2]);
intel_de_write(dev_priv,
intel_de_write(display,
ICL_DSC1_RC_RANGE_PARAMETERS_1_UDW(pipe),
rc_range_params_dword[3]);
intel_de_write(dev_priv,
intel_de_write(display,
ICL_DSC1_RC_RANGE_PARAMETERS_2(pipe),
rc_range_params_dword[4]);
intel_de_write(dev_priv,
intel_de_write(display,
ICL_DSC1_RC_RANGE_PARAMETERS_2_UDW(pipe),
rc_range_params_dword[5]);
intel_de_write(dev_priv,
intel_de_write(display,
ICL_DSC1_RC_RANGE_PARAMETERS_3(pipe),
rc_range_params_dword[6]);
intel_de_write(dev_priv,
intel_de_write(display,
ICL_DSC1_RC_RANGE_PARAMETERS_3_UDW(pipe),
rc_range_params_dword[7]);
}
@ -746,8 +744,8 @@ static i915_reg_t dss_ctl2_reg(struct intel_crtc *crtc, enum transcoder cpu_tran
void intel_uncompressed_joiner_enable(const struct intel_crtc_state *crtc_state)
{
struct intel_display *display = to_intel_display(crtc_state);
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
u32 dss_ctl1_val = 0;
if (crtc_state->joiner_pipes && !crtc_state->dsc.compression_enable) {
@ -756,14 +754,15 @@ void intel_uncompressed_joiner_enable(const struct intel_crtc_state *crtc_state)
else
dss_ctl1_val |= UNCOMPRESSED_JOINER_PRIMARY;
intel_de_write(dev_priv, dss_ctl1_reg(crtc, crtc_state->cpu_transcoder), dss_ctl1_val);
intel_de_write(display, dss_ctl1_reg(crtc, crtc_state->cpu_transcoder),
dss_ctl1_val);
}
}
void intel_dsc_enable(const struct intel_crtc_state *crtc_state)
{
struct intel_display *display = to_intel_display(crtc_state);
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
u32 dss_ctl1_val = 0;
u32 dss_ctl2_val = 0;
int vdsc_instances_per_pipe = intel_dsc_get_vdsc_per_pipe(crtc_state);
@ -796,28 +795,27 @@ void intel_dsc_enable(const struct intel_crtc_state *crtc_state)
if (intel_crtc_is_bigjoiner_primary(crtc_state))
dss_ctl1_val |= PRIMARY_BIG_JOINER_ENABLE;
}
intel_de_write(dev_priv, dss_ctl1_reg(crtc, crtc_state->cpu_transcoder), dss_ctl1_val);
intel_de_write(dev_priv, dss_ctl2_reg(crtc, crtc_state->cpu_transcoder), dss_ctl2_val);
intel_de_write(display, dss_ctl1_reg(crtc, crtc_state->cpu_transcoder), dss_ctl1_val);
intel_de_write(display, dss_ctl2_reg(crtc, crtc_state->cpu_transcoder), dss_ctl2_val);
}
void intel_dsc_disable(const struct intel_crtc_state *old_crtc_state)
{
struct intel_display *display = to_intel_display(old_crtc_state);
struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
/* Disable only if either of them is enabled */
if (old_crtc_state->dsc.compression_enable ||
old_crtc_state->joiner_pipes) {
intel_de_write(dev_priv, dss_ctl1_reg(crtc, old_crtc_state->cpu_transcoder), 0);
intel_de_write(dev_priv, dss_ctl2_reg(crtc, old_crtc_state->cpu_transcoder), 0);
intel_de_write(display, dss_ctl1_reg(crtc, old_crtc_state->cpu_transcoder), 0);
intel_de_write(display, dss_ctl2_reg(crtc, old_crtc_state->cpu_transcoder), 0);
}
}
static u32 intel_dsc_pps_read(struct intel_crtc_state *crtc_state, int pps,
bool *all_equal)
{
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
struct intel_display *display = to_intel_display(crtc_state);
i915_reg_t dsc_reg[3];
int i, vdsc_per_pipe, dsc_reg_num;
u32 val;
@ -825,16 +823,16 @@ static u32 intel_dsc_pps_read(struct intel_crtc_state *crtc_state, int pps,
vdsc_per_pipe = intel_dsc_get_vdsc_per_pipe(crtc_state);
dsc_reg_num = min_t(int, ARRAY_SIZE(dsc_reg), vdsc_per_pipe);
drm_WARN_ON_ONCE(&i915->drm, dsc_reg_num < vdsc_per_pipe);
drm_WARN_ON_ONCE(display->drm, dsc_reg_num < vdsc_per_pipe);
intel_dsc_get_pps_reg(crtc_state, pps, dsc_reg, dsc_reg_num);
*all_equal = true;
val = intel_de_read(i915, dsc_reg[0]);
val = intel_de_read(display, dsc_reg[0]);
for (i = 1; i < dsc_reg_num; i++) {
if (intel_de_read(i915, dsc_reg[i]) != val) {
if (intel_de_read(display, dsc_reg[i]) != val) {
*all_equal = false;
break;
}
@ -845,22 +843,20 @@ static u32 intel_dsc_pps_read(struct intel_crtc_state *crtc_state, int pps,
static u32 intel_dsc_pps_read_and_verify(struct intel_crtc_state *crtc_state, int pps)
{
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
struct intel_display *display = to_intel_display(crtc_state);
u32 val;
bool all_equal;
val = intel_dsc_pps_read(crtc_state, pps, &all_equal);
drm_WARN_ON(&i915->drm, !all_equal);
drm_WARN_ON(display->drm, !all_equal);
return val;
}
static void intel_dsc_get_pps_config(struct intel_crtc_state *crtc_state)
{
struct intel_display *display = to_intel_display(crtc_state);
struct drm_dsc_config *vdsc_cfg = &crtc_state->dsc.config;
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
int num_vdsc_instances = intel_dsc_get_num_vdsc_instances(crtc_state);
u32 pps_temp;
@ -946,7 +942,7 @@ static void intel_dsc_get_pps_config(struct intel_crtc_state *crtc_state)
vdsc_cfg->slice_chunk_size = REG_FIELD_GET(DSC_PPS16_SLICE_CHUNK_SIZE_MASK, pps_temp);
if (DISPLAY_VER(i915) >= 14) {
if (DISPLAY_VER(display) >= 14) {
/* PPS 17 */
pps_temp = intel_dsc_pps_read_and_verify(crtc_state, 17);
@ -964,7 +960,6 @@ void intel_dsc_get_config(struct intel_crtc_state *crtc_state)
{
struct intel_display *display = to_intel_display(crtc_state);
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
enum intel_display_power_domain power_domain;
intel_wakeref_t wakeref;
@ -979,8 +974,8 @@ void intel_dsc_get_config(struct intel_crtc_state *crtc_state)
if (!wakeref)
return;
dss_ctl1 = intel_de_read(dev_priv, dss_ctl1_reg(crtc, cpu_transcoder));
dss_ctl2 = intel_de_read(dev_priv, dss_ctl2_reg(crtc, cpu_transcoder));
dss_ctl1 = intel_de_read(display, dss_ctl1_reg(crtc, cpu_transcoder));
dss_ctl2 = intel_de_read(display, dss_ctl2_reg(crtc, cpu_transcoder));
crtc_state->dsc.compression_enable = dss_ctl2 & VDSC0_ENABLE;
if (!crtc_state->dsc.compression_enable)
@ -1020,8 +1015,7 @@ void intel_vdsc_state_dump(struct drm_printer *p, int indent,
int intel_vdsc_min_cdclk(const struct intel_crtc_state *crtc_state)
{
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
struct intel_display *display = to_intel_display(crtc);
struct intel_display *display = to_intel_display(crtc_state);
int num_vdsc_instances = intel_dsc_get_num_vdsc_instances(crtc_state);
int min_cdclk;

View File

@ -108,6 +108,12 @@ void intel_wm_get_hw_state(struct drm_i915_private *i915)
return i915->display.funcs.wm->get_hw_state(i915);
}
void intel_wm_sanitize(struct drm_i915_private *i915)
{
if (i915->display.funcs.wm->sanitize)
return i915->display.funcs.wm->sanitize(i915);
}
bool intel_wm_plane_visible(const struct intel_crtc_state *crtc_state,
const struct intel_plane_state *plane_state)
{

View File

@ -25,6 +25,7 @@ void intel_optimize_watermarks(struct intel_atomic_state *state,
struct intel_crtc *crtc);
int intel_compute_global_watermarks(struct intel_atomic_state *state);
void intel_wm_get_hw_state(struct drm_i915_private *i915);
void intel_wm_sanitize(struct drm_i915_private *i915);
bool intel_wm_plane_visible(const struct intel_crtc_state *crtc_state,
const struct intel_plane_state *plane_state);
void intel_print_wm_latency(struct drm_i915_private *i915,

View File

@ -666,12 +666,14 @@ static u16 glk_nearest_filter_coef(int t)
*/
static void glk_program_nearest_filter_coefs(struct intel_display *display,
struct intel_dsb *dsb,
enum pipe pipe, int id, int set)
{
int i;
intel_de_write_fw(display, GLK_PS_COEF_INDEX_SET(pipe, id, set),
PS_COEF_INDEX_AUTO_INC);
intel_de_write_dsb(display, dsb,
GLK_PS_COEF_INDEX_SET(pipe, id, set),
PS_COEF_INDEX_AUTO_INC);
for (i = 0; i < 17 * 7; i += 2) {
u32 tmp;
@ -683,11 +685,12 @@ static void glk_program_nearest_filter_coefs(struct intel_display *display,
t = glk_coef_tap(i + 1);
tmp |= glk_nearest_filter_coef(t) << 16;
intel_de_write_fw(display, GLK_PS_COEF_DATA_SET(pipe, id, set),
tmp);
intel_de_write_dsb(display, dsb,
GLK_PS_COEF_DATA_SET(pipe, id, set), tmp);
}
intel_de_write_fw(display, GLK_PS_COEF_INDEX_SET(pipe, id, set), 0);
intel_de_write_dsb(display, dsb,
GLK_PS_COEF_INDEX_SET(pipe, id, set), 0);
}
static u32 skl_scaler_get_filter_select(enum drm_scaling_filter filter, int set)
@ -703,14 +706,15 @@ static u32 skl_scaler_get_filter_select(enum drm_scaling_filter filter, int set)
return PS_FILTER_MEDIUM;
}
static void skl_scaler_setup_filter(struct intel_display *display, enum pipe pipe,
static void skl_scaler_setup_filter(struct intel_display *display,
struct intel_dsb *dsb, enum pipe pipe,
int id, int set, enum drm_scaling_filter filter)
{
switch (filter) {
case DRM_SCALING_FILTER_DEFAULT:
break;
case DRM_SCALING_FILTER_NEAREST_NEIGHBOR:
glk_program_nearest_filter_coefs(display, pipe, id, set);
glk_program_nearest_filter_coefs(display, dsb, pipe, id, set);
break;
default:
MISSING_CASE(filter);
@ -759,7 +763,7 @@ void skl_pfit_enable(const struct intel_crtc_state *crtc_state)
trace_intel_pipe_scaler_update_arm(crtc, id, x, y, width, height);
skl_scaler_setup_filter(display, pipe, id, 0,
skl_scaler_setup_filter(display, NULL, pipe, id, 0,
crtc_state->hw.scaling_filter);
intel_de_write_fw(display, SKL_PS_CTRL(pipe, id), ps_ctrl);
@ -775,7 +779,8 @@ void skl_pfit_enable(const struct intel_crtc_state *crtc_state)
}
void
skl_program_plane_scaler(struct intel_plane *plane,
skl_program_plane_scaler(struct intel_dsb *dsb,
struct intel_plane *plane,
const struct intel_crtc_state *crtc_state,
const struct intel_plane_state *plane_state)
{
@ -825,35 +830,38 @@ skl_program_plane_scaler(struct intel_plane *plane,
trace_intel_plane_scaler_update_arm(plane, scaler_id,
crtc_x, crtc_y, crtc_w, crtc_h);
skl_scaler_setup_filter(display, pipe, scaler_id, 0,
skl_scaler_setup_filter(display, dsb, pipe, scaler_id, 0,
plane_state->hw.scaling_filter);
intel_de_write_fw(display, SKL_PS_CTRL(pipe, scaler_id), ps_ctrl);
intel_de_write_fw(display, SKL_PS_VPHASE(pipe, scaler_id),
PS_Y_PHASE(y_vphase) | PS_UV_RGB_PHASE(uv_rgb_vphase));
intel_de_write_fw(display, SKL_PS_HPHASE(pipe, scaler_id),
PS_Y_PHASE(y_hphase) | PS_UV_RGB_PHASE(uv_rgb_hphase));
intel_de_write_fw(display, SKL_PS_WIN_POS(pipe, scaler_id),
PS_WIN_XPOS(crtc_x) | PS_WIN_YPOS(crtc_y));
intel_de_write_fw(display, SKL_PS_WIN_SZ(pipe, scaler_id),
PS_WIN_XSIZE(crtc_w) | PS_WIN_YSIZE(crtc_h));
intel_de_write_dsb(display, dsb, SKL_PS_CTRL(pipe, scaler_id),
ps_ctrl);
intel_de_write_dsb(display, dsb, SKL_PS_VPHASE(pipe, scaler_id),
PS_Y_PHASE(y_vphase) | PS_UV_RGB_PHASE(uv_rgb_vphase));
intel_de_write_dsb(display, dsb, SKL_PS_HPHASE(pipe, scaler_id),
PS_Y_PHASE(y_hphase) | PS_UV_RGB_PHASE(uv_rgb_hphase));
intel_de_write_dsb(display, dsb, SKL_PS_WIN_POS(pipe, scaler_id),
PS_WIN_XPOS(crtc_x) | PS_WIN_YPOS(crtc_y));
intel_de_write_dsb(display, dsb, SKL_PS_WIN_SZ(pipe, scaler_id),
PS_WIN_XSIZE(crtc_w) | PS_WIN_YSIZE(crtc_h));
}
static void skl_detach_scaler(struct intel_crtc *crtc, int id)
static void skl_detach_scaler(struct intel_dsb *dsb,
struct intel_crtc *crtc, int id)
{
struct intel_display *display = to_intel_display(crtc);
trace_intel_scaler_disable_arm(crtc, id);
intel_de_write_fw(display, SKL_PS_CTRL(crtc->pipe, id), 0);
intel_de_write_fw(display, SKL_PS_WIN_POS(crtc->pipe, id), 0);
intel_de_write_fw(display, SKL_PS_WIN_SZ(crtc->pipe, id), 0);
intel_de_write_dsb(display, dsb, SKL_PS_CTRL(crtc->pipe, id), 0);
intel_de_write_dsb(display, dsb, SKL_PS_WIN_POS(crtc->pipe, id), 0);
intel_de_write_dsb(display, dsb, SKL_PS_WIN_SZ(crtc->pipe, id), 0);
}
/*
* This function detaches (aka. unbinds) unused scalers in hardware
*/
void skl_detach_scalers(const struct intel_crtc_state *crtc_state)
void skl_detach_scalers(struct intel_dsb *dsb,
const struct intel_crtc_state *crtc_state)
{
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
const struct intel_crtc_scaler_state *scaler_state =
@ -863,7 +871,7 @@ void skl_detach_scalers(const struct intel_crtc_state *crtc_state)
/* loop through and disable scalers that aren't in use */
for (i = 0; i < crtc->num_scalers; i++) {
if (!scaler_state->scalers[i].in_use)
skl_detach_scaler(crtc, i);
skl_detach_scaler(dsb, crtc, i);
}
}
@ -873,7 +881,7 @@ void skl_scaler_disable(const struct intel_crtc_state *old_crtc_state)
int i;
for (i = 0; i < crtc->num_scalers; i++)
skl_detach_scaler(crtc, i);
skl_detach_scaler(NULL, crtc, i);
}
void skl_scaler_get_config(struct intel_crtc_state *crtc_state)

View File

@ -8,6 +8,7 @@
struct intel_atomic_state;
struct intel_crtc;
struct intel_crtc_state;
struct intel_dsb;
struct intel_plane;
struct intel_plane_state;
@ -21,10 +22,12 @@ int intel_atomic_setup_scalers(struct intel_atomic_state *state,
void skl_pfit_enable(const struct intel_crtc_state *crtc_state);
void skl_program_plane_scaler(struct intel_plane *plane,
void skl_program_plane_scaler(struct intel_dsb *dsb,
struct intel_plane *plane,
const struct intel_crtc_state *crtc_state,
const struct intel_plane_state *plane_state);
void skl_detach_scalers(const struct intel_crtc_state *crtc_state);
void skl_detach_scalers(struct intel_dsb *dsb,
const struct intel_crtc_state *crtc_state);
void skl_scaler_disable(const struct intel_crtc_state *old_crtc_state);
void skl_scaler_get_config(struct intel_crtc_state *crtc_state);

View File

@ -1466,7 +1466,7 @@ skl_plane_update_arm(struct intel_dsb *dsb,
* TODO: split into noarm+arm pair
*/
if (plane_state->scaler_id >= 0)
skl_program_plane_scaler(plane, crtc_state, plane_state);
skl_program_plane_scaler(dsb, plane, crtc_state, plane_state);
/*
* The control register self-arms if the plane was previously
@ -1646,7 +1646,7 @@ icl_plane_update_arm(struct intel_dsb *dsb,
* TODO: split into noarm+arm pair
*/
if (plane_state->scaler_id >= 0)
skl_program_plane_scaler(plane, crtc_state, plane_state);
skl_program_plane_scaler(dsb, plane, crtc_state, plane_state);
icl_plane_update_sel_fetch_arm(dsb, plane, crtc_state, plane_state);
@ -2258,18 +2258,55 @@ static bool skl_fb_scalable(const struct drm_framebuffer *fb)
static void check_protection(struct intel_plane_state *plane_state)
{
struct intel_display *display = to_intel_display(plane_state);
struct drm_i915_private *i915 = to_i915(display->drm);
const struct drm_framebuffer *fb = plane_state->hw.fb;
struct drm_gem_object *obj = intel_fb_bo(fb);
if (DISPLAY_VER(display) < 11)
return;
plane_state->decrypt = intel_pxp_key_check(i915->pxp, obj, false) == 0;
plane_state->decrypt = intel_pxp_key_check(obj, false) == 0;
plane_state->force_black = intel_bo_is_protected(obj) &&
!plane_state->decrypt;
}
static void
make_damage_viewport_relative(struct intel_plane_state *plane_state)
{
const struct drm_framebuffer *fb = plane_state->hw.fb;
const struct drm_rect *src = &plane_state->uapi.src;
unsigned int rotation = plane_state->hw.rotation;
struct drm_rect *damage = &plane_state->damage;
if (!drm_rect_visible(damage))
return;
if (!fb || !plane_state->uapi.visible) {
plane_state->damage = DRM_RECT_INIT(0, 0, 0, 0);
return;
}
if (drm_rotation_90_or_270(rotation)) {
drm_rect_rotate(damage, fb->width, fb->height,
DRM_MODE_ROTATE_270);
drm_rect_translate(damage, -(src->y1 >> 16), -(src->x1 >> 16));
} else {
drm_rect_translate(damage, -(src->x1 >> 16), -(src->y1 >> 16));
}
}
static void clip_damage(struct intel_plane_state *plane_state)
{
struct drm_rect *damage = &plane_state->damage;
struct drm_rect src;
if (!drm_rect_visible(damage))
return;
drm_rect_fp_to_int(&src, &plane_state->uapi.src);
drm_rect_translate(damage, src.x1, src.y1);
drm_rect_intersect(damage, &src);
}
static int skl_plane_check(struct intel_crtc_state *crtc_state,
struct intel_plane_state *plane_state)
{
@ -2295,6 +2332,8 @@ static int skl_plane_check(struct intel_crtc_state *crtc_state,
if (ret)
return ret;
make_damage_viewport_relative(plane_state);
ret = skl_check_plane_surface(plane_state);
if (ret)
return ret;
@ -2310,6 +2349,8 @@ static int skl_plane_check(struct intel_crtc_state *crtc_state,
if (ret)
return ret;
clip_damage(plane_state);
ret = skl_plane_check_nv12_rotation(plane_state);
if (ret)
return ret;
@ -2317,8 +2358,10 @@ static int skl_plane_check(struct intel_crtc_state *crtc_state,
check_protection(plane_state);
/* HW only has 8 bits pixel precision, disable plane if invisible */
if (!(plane_state->hw.alpha >> 8))
if (!(plane_state->hw.alpha >> 8)) {
plane_state->uapi.visible = false;
plane_state->damage = DRM_RECT_INIT(0, 0, 0, 0);
}
plane_state->ctl = skl_plane_ctl(crtc_state, plane_state);

View File

@ -3157,6 +3157,7 @@ static void skl_wm_get_hw_state(struct drm_i915_private *i915)
dbuf_state->joined_mbus = intel_de_read(display, MBUS_CTL) & MBUS_JOIN;
dbuf_state->mdclk_cdclk_ratio = intel_mdclk_cdclk_ratio(display, &display->cdclk.hw);
dbuf_state->active_pipes = 0;
for_each_intel_crtc(display->drm, crtc) {
struct intel_crtc_state *crtc_state =
@ -3168,8 +3169,10 @@ static void skl_wm_get_hw_state(struct drm_i915_private *i915)
memset(&crtc_state->wm.skl.optimal, 0,
sizeof(crtc_state->wm.skl.optimal));
if (crtc_state->hw.active)
if (crtc_state->hw.active) {
skl_pipe_wm_get_hw_state(crtc, &crtc_state->wm.skl.optimal);
dbuf_state->active_pipes |= BIT(pipe);
}
crtc_state->wm.skl.raw = crtc_state->wm.skl.optimal;
memset(&dbuf_state->ddb[pipe], 0, sizeof(dbuf_state->ddb[pipe]));
@ -3837,14 +3840,56 @@ static void skl_dbuf_sanitize(struct drm_i915_private *i915)
}
}
static void skl_wm_get_hw_state_and_sanitize(struct drm_i915_private *i915)
static void skl_wm_sanitize(struct drm_i915_private *i915)
{
skl_wm_get_hw_state(i915);
skl_mbus_sanitize(i915);
skl_dbuf_sanitize(i915);
}
void skl_wm_crtc_disable_noatomic(struct intel_crtc *crtc)
{
struct intel_display *display = to_intel_display(crtc);
struct intel_crtc_state *crtc_state =
to_intel_crtc_state(crtc->base.state);
struct intel_dbuf_state *dbuf_state =
to_intel_dbuf_state(display->dbuf.obj.state);
enum pipe pipe = crtc->pipe;
if (DISPLAY_VER(display) < 9)
return;
dbuf_state->active_pipes &= ~BIT(pipe);
dbuf_state->weight[pipe] = 0;
dbuf_state->slices[pipe] = 0;
memset(&dbuf_state->ddb[pipe], 0, sizeof(dbuf_state->ddb[pipe]));
memset(&crtc_state->wm.skl.ddb, 0, sizeof(crtc_state->wm.skl.ddb));
}
void skl_wm_plane_disable_noatomic(struct intel_crtc *crtc,
struct intel_plane *plane)
{
struct intel_display *display = to_intel_display(crtc);
struct intel_crtc_state *crtc_state =
to_intel_crtc_state(crtc->base.state);
if (DISPLAY_VER(display) < 9)
return;
skl_ddb_entry_init(&crtc_state->wm.skl.plane_ddb[plane->id], 0, 0);
skl_ddb_entry_init(&crtc_state->wm.skl.plane_ddb[plane->id], 0, 0);
crtc_state->wm.skl.plane_min_ddb[plane->id] = 0;
crtc_state->wm.skl.plane_interim_ddb[plane->id] = 0;
memset(&crtc_state->wm.skl.raw.planes[plane->id], 0,
sizeof(crtc_state->wm.skl.raw.planes[plane->id]));
memset(&crtc_state->wm.skl.optimal.planes[plane->id], 0,
sizeof(crtc_state->wm.skl.optimal.planes[plane->id]));
}
void intel_wm_state_verify(struct intel_atomic_state *state,
struct intel_crtc *crtc)
{
@ -3972,7 +4017,8 @@ void intel_wm_state_verify(struct intel_atomic_state *state,
static const struct intel_wm_funcs skl_wm_funcs = {
.compute_global_watermarks = skl_compute_wm,
.get_hw_state = skl_wm_get_hw_state_and_sanitize,
.get_hw_state = skl_wm_get_hw_state,
.sanitize = skl_wm_sanitize,
};
void skl_wm_init(struct drm_i915_private *i915)

View File

@ -41,6 +41,10 @@ bool skl_ddb_allocation_overlaps(const struct skl_ddb_entry *ddb,
void intel_wm_state_verify(struct intel_atomic_state *state,
struct intel_crtc *crtc);
void skl_wm_crtc_disable_noatomic(struct intel_crtc *crtc);
void skl_wm_plane_disable_noatomic(struct intel_crtc *crtc,
struct intel_plane *plane);
void skl_watermark_ipc_init(struct drm_i915_private *i915);
void skl_watermark_ipc_update(struct drm_i915_private *i915);
bool skl_watermark_ipc_enabled(struct drm_i915_private *i915);

View File

@ -283,7 +283,7 @@ static int intel_dsi_compute_config(struct intel_encoder *encoder,
if (ret)
return ret;
ret = intel_panel_fitting(pipe_config, conn_state);
ret = intel_pfit_compute_config(pipe_config, conn_state);
if (ret)
return ret;

View File

@ -23,7 +23,6 @@ u32 vlv_dsi_get_pclk(struct intel_encoder *encoder,
struct intel_crtc_state *config);
void vlv_dsi_reset_clocks(struct intel_encoder *encoder, enum port port);
bool bxt_dsi_pll_is_enabled(struct drm_i915_private *dev_priv);
int bxt_dsi_pll_compute(struct intel_encoder *encoder,
struct intel_crtc_state *config);
void bxt_dsi_pll_enable(struct intel_encoder *encoder,
@ -34,9 +33,14 @@ u32 bxt_dsi_get_pclk(struct intel_encoder *encoder,
void bxt_dsi_reset_clocks(struct intel_encoder *encoder, enum port port);
#ifdef I915
bool bxt_dsi_pll_is_enabled(struct drm_i915_private *dev_priv);
void assert_dsi_pll_enabled(struct intel_display *display);
void assert_dsi_pll_disabled(struct intel_display *display);
#else
static inline bool bxt_dsi_pll_is_enabled(struct drm_i915_private *dev_priv)
{
return false;
}
static inline void assert_dsi_pll_enabled(struct intel_display *display)
{
}

View File

@ -915,7 +915,7 @@ static struct i915_vma *eb_lookup_vma(struct i915_execbuffer *eb, u32 handle)
*/
if (i915_gem_context_uses_protected_content(eb->gem_context) &&
i915_gem_object_is_protected(obj)) {
err = intel_pxp_key_check(eb->i915->pxp, intel_bo_to_drm_bo(obj), true);
err = intel_pxp_key_check(intel_bo_to_drm_bo(obj), true);
if (err) {
i915_gem_object_put(obj);
return ERR_PTR(err);

View File

@ -677,7 +677,7 @@ void intel_engines_release(struct intel_gt *gt)
* in case we aborted before completely initialising the engines.
*/
GEM_BUG_ON(intel_gt_pm_is_awake(gt));
if (!INTEL_INFO(gt->i915)->gpu_reset_clobbers_display)
if (!intel_gt_gpu_reset_clobbers_display(gt))
intel_gt_reset_all_engines(gt);
/* Decouple the backend; but keep the layout for late GPU resets */

View File

@ -328,6 +328,7 @@ static bool fence_is_active(const struct i915_fence_reg *fence)
static struct i915_fence_reg *fence_find(struct i915_ggtt *ggtt)
{
struct intel_display *display = &ggtt->vm.i915->display;
struct i915_fence_reg *active = NULL;
struct i915_fence_reg *fence, *fn;
@ -353,7 +354,7 @@ static struct i915_fence_reg *fence_find(struct i915_ggtt *ggtt)
}
/* Wait for completion of pending flips which consume fences */
if (intel_has_pending_fb_unpin(ggtt->vm.i915))
if (intel_has_pending_fb_unpin(display))
return ERR_PTR(-EAGAIN);
return ERR_PTR(-ENOBUFS);

View File

@ -158,7 +158,7 @@ void intel_gt_pm_init(struct intel_gt *gt)
static bool reset_engines(struct intel_gt *gt)
{
if (INTEL_INFO(gt->i915)->gpu_reset_clobbers_display)
if (intel_gt_gpu_reset_clobbers_display(gt))
return false;
return intel_gt_reset_all_engines(gt) == 0;

View File

@ -986,7 +986,7 @@ static void __intel_gt_set_wedged(struct intel_gt *gt)
awake = reset_prepare(gt);
/* Even if the GPU reset fails, it should still stop the engines */
if (!INTEL_INFO(gt->i915)->gpu_reset_clobbers_display)
if (!intel_gt_gpu_reset_clobbers_display(gt))
intel_gt_reset_all_engines(gt);
for_each_engine(engine, gt, id)
@ -1106,7 +1106,7 @@ static bool __intel_gt_unset_wedged(struct intel_gt *gt)
/* We must reset pending GPU events before restoring our submission */
ok = !HAS_EXECLISTS(gt->i915); /* XXX better agnosticism desired */
if (!INTEL_INFO(gt->i915)->gpu_reset_clobbers_display)
if (!intel_gt_gpu_reset_clobbers_display(gt))
ok = intel_gt_reset_all_engines(gt) == 0;
if (!ok) {
/*
@ -1178,6 +1178,13 @@ static int resume(struct intel_gt *gt)
return 0;
}
bool intel_gt_gpu_reset_clobbers_display(struct intel_gt *gt)
{
struct drm_i915_private *i915 = gt->i915;
return INTEL_INFO(i915)->gpu_reset_clobbers_display;
}
/**
* intel_gt_reset - reset chip after a hang
* @gt: #intel_gt to reset
@ -1234,7 +1241,7 @@ void intel_gt_reset(struct intel_gt *gt,
goto error;
}
if (INTEL_INFO(gt->i915)->gpu_reset_clobbers_display)
if (intel_gt_gpu_reset_clobbers_display(gt))
intel_irq_suspend(gt->i915);
if (do_reset(gt, stalled_mask)) {
@ -1242,7 +1249,7 @@ void intel_gt_reset(struct intel_gt *gt,
goto taint;
}
if (INTEL_INFO(gt->i915)->gpu_reset_clobbers_display)
if (intel_gt_gpu_reset_clobbers_display(gt))
intel_irq_resume(gt->i915);
intel_overlay_reset(display);
@ -1396,6 +1403,11 @@ int intel_engine_reset(struct intel_engine_cs *engine, const char *msg)
return err;
}
static void display_reset_modeset_stuck(void *gt)
{
intel_gt_set_wedged(gt);
}
static void intel_gt_reset_global(struct intel_gt *gt,
u32 engine_mask,
const char *reason)
@ -1413,11 +1425,26 @@ static void intel_gt_reset_global(struct intel_gt *gt,
/* Use a watchdog to ensure that our reset completes */
intel_wedge_on_timeout(&w, gt, 60 * HZ) {
intel_display_reset_prepare(gt->i915);
struct drm_i915_private *i915 = gt->i915;
struct intel_display *display = &i915->display;
bool need_display_reset;
bool reset_display;
need_display_reset = intel_gt_gpu_reset_clobbers_display(gt) &&
intel_has_gpu_reset(gt);
reset_display = intel_display_reset_test(display) ||
need_display_reset;
if (reset_display)
reset_display = intel_display_reset_prepare(display,
display_reset_modeset_stuck,
gt);
intel_gt_reset(gt, engine_mask, reason);
intel_display_reset_finish(gt->i915);
if (reset_display)
intel_display_reset_finish(display, !need_display_reset);
}
if (!test_bit(I915_WEDGED, &gt->reset.flags))
@ -1485,7 +1512,7 @@ void intel_gt_handle_error(struct intel_gt *gt,
intel_has_reset_engine(gt) && !intel_gt_is_wedged(gt)) {
local_bh_disable();
for_each_engine_masked(engine, gt, engine_mask, tmp) {
BUILD_BUG_ON(I915_RESET_MODESET >= I915_RESET_ENGINE);
BUILD_BUG_ON(I915_RESET_BACKOFF >= I915_RESET_ENGINE);
if (test_and_set_bit(I915_RESET_ENGINE + engine->id,
&gt->reset.flags))
continue;

View File

@ -28,6 +28,8 @@ void intel_gt_handle_error(struct intel_gt *gt,
const char *fmt, ...);
#define I915_ERROR_CAPTURE BIT(0)
bool intel_gt_gpu_reset_clobbers_display(struct intel_gt *gt);
void intel_gt_reset(struct intel_gt *gt,
intel_engine_mask_t stalled_mask,
const char *reason);

View File

@ -41,8 +41,7 @@ struct intel_reset {
*/
unsigned long flags;
#define I915_RESET_BACKOFF 0
#define I915_RESET_MODESET 1
#define I915_RESET_ENGINE 2
#define I915_RESET_ENGINE 1
#define I915_WEDGED_ON_INIT (BITS_PER_LONG - 3)
#define I915_WEDGED_ON_FINI (BITS_PER_LONG - 2)
#define I915_WEDGED (BITS_PER_LONG - 1)

View File

@ -411,9 +411,6 @@ static int i915_runtime_pm_status(struct seq_file *m, void *unused)
if (!HAS_RUNTIME_PM(dev_priv))
seq_puts(m, "Runtime power management not supported\n");
seq_printf(m, "Runtime power status: %s\n",
str_enabled_disabled(!dev_priv->display.power.domains.init_wakeref));
seq_printf(m, "GPU idle: %s\n", str_yes_no(!to_gt(dev_priv)->awake));
seq_printf(m, "IRQs disabled: %s\n",
str_yes_no(!intel_irqs_enabled(dev_priv)));

View File

@ -41,6 +41,8 @@
#include <linux/vt.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_client.h>
#include <drm/drm_client_event.h>
#include <drm/drm_ioctl.h>
#include <drm/drm_managed.h>
#include <drm/drm_probe_helper.h>
@ -200,7 +202,7 @@ static void intel_detect_preproduction_hw(struct drm_i915_private *dev_priv)
static void sanitize_gpu(struct drm_i915_private *i915)
{
if (!INTEL_INFO(i915)->gpu_reset_clobbers_display) {
if (!intel_gt_gpu_reset_clobbers_display(to_gt(i915))) {
struct intel_gt *gt;
unsigned int i;
@ -968,7 +970,7 @@ void i915_driver_shutdown(struct drm_i915_private *i915)
intel_runtime_pm_disable(&i915->runtime_pm);
intel_power_domains_disable(display);
intel_fbdev_set_suspend(&i915->drm, FBINFO_STATE_SUSPENDED, true);
drm_client_dev_suspend(&i915->drm, false);
if (HAS_DISPLAY(i915)) {
drm_kms_helper_poll_disable(&i915->drm);
intel_display_driver_disable_user_access(display);
@ -1051,7 +1053,7 @@ static int i915_drm_suspend(struct drm_device *dev)
/* We do a lot of poking in a lot of registers, make sure they work
* properly. */
intel_power_domains_disable(display);
intel_fbdev_set_suspend(dev, FBINFO_STATE_SUSPENDED, true);
drm_client_dev_suspend(dev, false);
if (HAS_DISPLAY(dev_priv)) {
drm_kms_helper_poll_disable(dev);
intel_display_driver_disable_user_access(display);
@ -1070,7 +1072,7 @@ static int i915_drm_suspend(struct drm_device *dev)
intel_encoder_suspend_all(&dev_priv->display);
/* Must be called before GGTT is suspended. */
intel_dpt_suspend(dev_priv);
intel_dpt_suspend(display);
i915_ggtt_suspend(to_gt(dev_priv)->ggtt);
i9xx_display_sr_save(display);
@ -1187,7 +1189,7 @@ static int i915_drm_resume(struct drm_device *dev)
setup_private_pat(gt);
/* Must be called after GGTT is resumed. */
intel_dpt_resume(dev_priv);
intel_dpt_resume(display);
intel_dmc_resume(display);
@ -1237,7 +1239,7 @@ static int i915_drm_resume(struct drm_device *dev)
intel_opregion_resume(display);
intel_fbdev_set_suspend(dev, FBINFO_STATE_RUNNING, false);
drm_client_dev_resume(dev, false);
intel_power_domains_enable(display);
@ -1807,6 +1809,8 @@ static const struct drm_driver i915_drm_driver = {
.dumb_create = i915_gem_dumb_create,
.dumb_map_offset = i915_gem_dumb_mmap_offset,
INTEL_FBDEV_DRIVER_OPS,
.ioctls = i915_ioctls,
.num_ioctls = ARRAY_SIZE(i915_ioctls),
.fops = &i915_driver_fops,

Some files were not shown because too many files have changed in this diff Show More