mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
- Vswing / Pre-emphasis Override (Michal)
- Enable AS SDP Skip Frames (Uma) - Handle negative configuration index on DP link caps for robustness (Luca) - Perform full wedge on display reset (Ville) - PSR related revert and fix (Nemesa) - Preparation for enabling SDR plane color pipeline (Chaitanya, Pranay) - An eDP quirk for HP Pavilion Plus (Ankit) - DP MST fixes (Imre) - General display fixes and small improvements (Jani, Lalit, Vinod, Sebastian) - Introduce PME (Power Management Event) support on display hotplug (Vinod) - Force eDP sink awake on dpcd init (Arun) - Stop using the configurable fence timeout and other cleanups (Jani) - Add support for Common SDP Transmission Line (Ankit, Arun) - Map AUX power domains to DC_off (Suraj) - Handle VSC SDP revision 7 in unpack (Juasheem) - Disable VRR DC balance by default (Mitul) - Switch to modern drm_dp_dpcd* accessors (Jani) - Lg DPCD access errors (Suraj) - Fixes to make i915 work well with PREEMPT_RT (Maarten, Sebastian) - Update the CMN_SDP_TL in fastset path (Ankit) - Use a shared gtt_view_types.h header (Jani) -----BEGIN PGP SIGNATURE----- iQEzBAABCgAdFiEEbSBwaO7dZQkcLOKj+mJfZA7rE8oFAmrAA8IACgkQ+mJfZA7r E8rItggAt2YC091NcyHoA31t9cSzr93+TGn8SRJEU1gB96YVWh0xUDsVDQux2yYS aNsIMS0+B9lfexM7vwlWiAQGV6HPpWp2B4GJ5AEc+BvLZpp2n1bXiKnBgO5VRvF3 TTKpeKnhFUkuJfAYq1Glv+yfHpiXxzocvsowzvoTc+nI7ZN/McoShzH/B245b/Ko CuTQGvAanYziLdCbkvhr4sO39DWoKAyYtgfTywDRjgYcTS+2W/cx+EJV+8D0yZCJ W6MpuuSI/UY2R2w9l7QfNMNz42M8yHbgvsNdkg7JGsvZT8nkiBjMYFiBomIHe670 rjVU2qSwOU0wEFdJEl4u5ia3weDpwA== =PrrV -----END PGP SIGNATURE----- Merge tag 'drm-intel-next-2026-10-02' of https://gitlab.freedesktop.org/drm/i915/kernel into drm-next [airlied: add xe fixup] - Vswing / Pre-emphasis Override (Michal) - Enable AS SDP Skip Frames (Uma) - Handle negative configuration index on DP link caps for robustness (Luca) - Perform full wedge on display reset (Ville) - PSR related revert and fix (Nemesa) - Preparation for enabling SDR plane color pipeline (Chaitanya, Pranay) - An eDP quirk for HP Pavilion Plus (Ankit) - DP MST fixes (Imre) - General display fixes and small improvements (Jani, Lalit, Vinod, Sebastian) - Introduce PME (Power Management Event) support on display hotplug (Vinod) - Force eDP sink awake on dpcd init (Arun) - Stop using the configurable fence timeout and other cleanups (Jani) - Add support for Common SDP Transmission Line (Ankit, Arun) - Map AUX power domains to DC_off (Suraj) - Handle VSC SDP revision 7 in unpack (Juasheem) - Disable VRR DC balance by default (Mitul) - Switch to modern drm_dp_dpcd* accessors (Jani) - Lg DPCD access errors (Suraj) - Fixes to make i915 work well with PREEMPT_RT (Maarten, Sebastian) - Update the CMN_SDP_TL in fastset path (Ankit) - Use a shared gtt_view_types.h header (Jani) Signed-off-by: Dave Airlie <airlied@redhat.com> From: Rodrigo Vivi <rodrigo.vivi@intel.com> Link: https://patch.msgid.link/asAD6RRGxlbIPdhz@intel.com
This commit is contained in:
commit
f2bf20011b
|
|
@ -349,6 +349,7 @@ i915-y += \
|
|||
display/intel_cx0_phy.o \
|
||||
display/intel_ddi.o \
|
||||
display/intel_ddi_buf_trans.o \
|
||||
display/intel_dip.o \
|
||||
display/intel_display_device.o \
|
||||
display/intel_display_trace.o \
|
||||
display/intel_dkl_phy.o \
|
||||
|
|
|
|||
|
|
@ -375,6 +375,142 @@ static u32 get_pr_alpm_as_sdp_transmission_time(const struct intel_crtc_state *c
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Periodic Adaptive-Sync SDP skip frames.
|
||||
*
|
||||
* While Panel Replay is active the transcoder timing generator runs at the
|
||||
* panel's maximum refresh rate. To drive the panel down to its minimum
|
||||
* refresh rate the Adaptive-Sync SDP only needs to reach the panel once per
|
||||
* minimum-rate frame, so transmitting it on every (maximum-rate) frame is
|
||||
* unnecessary and shows up as repeated SDPs on the link. Program the HW skip
|
||||
* counter so that a single AS SDP is followed by
|
||||
* (max_vrefresh / min_vrefresh - 1) idle frames, i.e. one AS SDP per slowest
|
||||
* panel frame.
|
||||
*
|
||||
* The maximum and minimum refresh rates come from the panel's adaptive-sync
|
||||
* monitor range, so this is independent of the current content/flip rate.
|
||||
*/
|
||||
static u32 intel_pr_as_sdp_skip_frames(struct intel_dp *intel_dp)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(intel_dp);
|
||||
const struct drm_display_info *info =
|
||||
&intel_dp->attached_connector->base.display_info;
|
||||
int max_vrefresh = info->monitor_range.max_vfreq;
|
||||
int min_vrefresh = info->monitor_range.min_vfreq;
|
||||
|
||||
/* Off by default; gated by the enable_periodic_assdp debugfs knob. */
|
||||
if (!display->params.enable_periodic_assdp)
|
||||
return 0;
|
||||
|
||||
if (min_vrefresh <= 0 || max_vrefresh <= min_vrefresh)
|
||||
return 0;
|
||||
|
||||
return min_t(u32, max_vrefresh / min_vrefresh - 1,
|
||||
REG_FIELD_MAX(PR_ALPM_CTL_AS_SDP_SKIP_FRAMES_MASK));
|
||||
}
|
||||
|
||||
/*
|
||||
* Whether periodic AS SDP transmission (AS SDP skip frames) will be programmed
|
||||
* for this Panel Replay config. The skip counter needs the AS SDP to keep
|
||||
* flowing during PR active, which is incompatible with DC3co, so this is used
|
||||
* to keep DC3co disabled while skip frames is enabled.
|
||||
*/
|
||||
bool intel_alpm_pr_as_sdp_skip_frames_enabled(struct intel_dp *intel_dp,
|
||||
const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(intel_dp);
|
||||
|
||||
/*
|
||||
* The AS SDP skip frames field only exists on Xe3p_LPD+. Periodic AS SDP
|
||||
* drives the panel down to its minimum refresh rate on its own, so it is
|
||||
* only used when VRR is not actively driving the refresh rate.
|
||||
*/
|
||||
if (DISPLAY_VER(display) < 35 || !intel_dp->as_sdp_supported ||
|
||||
!crtc_state->has_panel_replay || crtc_state->vrr.enable)
|
||||
return false;
|
||||
|
||||
return intel_pr_as_sdp_skip_frames(intel_dp) > 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Program the AS SDP portion of PR_ALPM_CTL: the transmission position, the
|
||||
* skip-frame counter and the coupled AS SDP transmission / DC3CO idle-protocol
|
||||
* bits. This is a full recompute of those fields (the base value is built from
|
||||
* scratch, not read back), so it can be called both at PR enable time and when
|
||||
* VRR is toggled seamlessly - which changes whether periodic AS SDP is used.
|
||||
*
|
||||
* Caller must hold intel_dp->alpm.lock.
|
||||
*/
|
||||
static void intel_alpm_configure_pr_as_sdp(struct intel_dp *intel_dp,
|
||||
const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(intel_dp);
|
||||
enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
|
||||
u32 pr_alpm_ctl = get_pr_alpm_as_sdp_transmission_time(crtc_state);
|
||||
u32 skip_frames = 0;
|
||||
|
||||
if (intel_alpm_pr_as_sdp_skip_frames_enabled(intel_dp, crtc_state))
|
||||
skip_frames = intel_pr_as_sdp_skip_frames(intel_dp);
|
||||
|
||||
if (crtc_state->link_off_after_as_sdp_when_pr_active)
|
||||
pr_alpm_ctl |= PR_ALPM_CTL_ALLOW_LINK_OFF_BETWEEN_AS_SDP_AND_SU;
|
||||
|
||||
/*
|
||||
* Skip frames needs the AS SDP to keep flowing during PR active, so it
|
||||
* is mutually exclusive with disabling AS SDP transmission in active and
|
||||
* with the DC3CO idle protocol.
|
||||
*/
|
||||
if (skip_frames) {
|
||||
pr_alpm_ctl |= PR_ALPM_CTL_AS_SDP_SKIP_FRAMES(skip_frames);
|
||||
pr_alpm_ctl &= ~PR_ALPM_CTL_AS_SDP_TRANSMISSION_IN_ACTIVE_DISABLE;
|
||||
pr_alpm_ctl &= ~PR_ALPM_CTL_USE_DC3CO_IDLE_PROTOCOL;
|
||||
} else {
|
||||
pr_alpm_ctl &= ~PR_ALPM_CTL_AS_SDP_SKIP_FRAMES_MASK;
|
||||
|
||||
if (crtc_state->disable_as_sdp_when_pr_active)
|
||||
pr_alpm_ctl |= PR_ALPM_CTL_AS_SDP_TRANSMISSION_IN_ACTIVE_DISABLE;
|
||||
|
||||
if (intel_display_power_dc3co_allowed(display))
|
||||
pr_alpm_ctl |= PR_ALPM_CTL_USE_DC3CO_IDLE_PROTOCOL;
|
||||
}
|
||||
|
||||
intel_de_write(display, PR_ALPM_CTL(display, cpu_transcoder), pr_alpm_ctl);
|
||||
}
|
||||
|
||||
/*
|
||||
* VRR can be enabled or disabled seamlessly, i.e. without a modeset and without
|
||||
* cycling Panel Replay, so the AS SDP skip-frame programming done at PR enable
|
||||
* time would otherwise go stale across a VRR toggle. Reprogram it here so the
|
||||
* skip counter (and the coupled bits) matches the new VRR state.
|
||||
*/
|
||||
void intel_alpm_pr_as_sdp_update(const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(crtc_state);
|
||||
struct intel_encoder *encoder;
|
||||
|
||||
/* AS SDP skip frames field only exists on Xe3p_LPD+ */
|
||||
if (DISPLAY_VER(display) < 35)
|
||||
return;
|
||||
|
||||
for_each_intel_encoder_mask(display->drm, encoder,
|
||||
crtc_state->uapi.encoder_mask) {
|
||||
struct intel_dp *intel_dp;
|
||||
|
||||
if (!intel_encoder_is_dp(encoder))
|
||||
continue;
|
||||
|
||||
intel_dp = enc_to_intel_dp(encoder);
|
||||
|
||||
if (!intel_dp->as_sdp_supported ||
|
||||
!intel_alpm_is_alpm_aux_less(intel_dp, crtc_state))
|
||||
continue;
|
||||
|
||||
mutex_lock(&intel_dp->alpm.lock);
|
||||
intel_alpm_configure_pr_as_sdp(intel_dp, crtc_state);
|
||||
mutex_unlock(&intel_dp->alpm.lock);
|
||||
}
|
||||
}
|
||||
|
||||
static void lnl_alpm_configure(struct intel_dp *intel_dp,
|
||||
const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
|
|
@ -397,22 +533,8 @@ static void lnl_alpm_configure(struct intel_dp *intel_dp,
|
|||
ALPM_CTL_AUX_LESS_SLEEP_HOLD_TIME_50_SYMBOLS |
|
||||
ALPM_CTL_AUX_LESS_WAKE_TIME(crtc_state->alpm_state.aux_less_wake_lines);
|
||||
|
||||
if (intel_dp->as_sdp_supported) {
|
||||
u32 pr_alpm_ctl = get_pr_alpm_as_sdp_transmission_time(crtc_state);
|
||||
|
||||
if (crtc_state->link_off_after_as_sdp_when_pr_active)
|
||||
pr_alpm_ctl |= PR_ALPM_CTL_ALLOW_LINK_OFF_BETWEEN_AS_SDP_AND_SU;
|
||||
if (crtc_state->disable_as_sdp_when_pr_active)
|
||||
pr_alpm_ctl |= PR_ALPM_CTL_AS_SDP_TRANSMISSION_IN_ACTIVE_DISABLE;
|
||||
|
||||
if (intel_display_power_dc3co_allowed(display))
|
||||
pr_alpm_ctl |= PR_ALPM_CTL_USE_DC3CO_IDLE_PROTOCOL;
|
||||
else
|
||||
pr_alpm_ctl &= ~PR_ALPM_CTL_USE_DC3CO_IDLE_PROTOCOL;
|
||||
|
||||
intel_de_write(display, PR_ALPM_CTL(display, cpu_transcoder),
|
||||
pr_alpm_ctl);
|
||||
}
|
||||
if (intel_dp->as_sdp_supported)
|
||||
intel_alpm_configure_pr_as_sdp(intel_dp, crtc_state);
|
||||
|
||||
} else {
|
||||
alpm_ctl = ALPM_CTL_EXTENDED_FAST_WAKE_ENABLE |
|
||||
|
|
@ -506,7 +628,7 @@ void intel_alpm_enable_sink(struct intel_dp *intel_dp,
|
|||
intel_alpm_aux_less_wake_supported(intel_dp)))
|
||||
val |= DP_ALPM_MODE_AUX_LESS;
|
||||
|
||||
drm_dp_dpcd_writeb(&intel_dp->aux, DP_RECEIVER_ALPM_CONFIG, val);
|
||||
drm_dp_dpcd_write_byte(&intel_dp->aux, DP_RECEIVER_ALPM_CONFIG, val);
|
||||
}
|
||||
|
||||
void intel_alpm_lobf_enable(const struct intel_crtc_state *new_crtc_state)
|
||||
|
|
@ -629,12 +751,12 @@ bool intel_alpm_get_error(struct intel_dp *intel_dp)
|
|||
{
|
||||
struct intel_display *display = to_intel_display(intel_dp);
|
||||
struct drm_dp_aux *aux = &intel_dp->aux;
|
||||
int ret;
|
||||
u8 val;
|
||||
int r;
|
||||
|
||||
r = drm_dp_dpcd_readb(aux, DP_RECEIVER_ALPM_STATUS, &val);
|
||||
if (r != 1) {
|
||||
drm_err(display->drm, "Error reading ALPM status\n");
|
||||
ret = drm_dp_dpcd_read_byte(aux, DP_RECEIVER_ALPM_STATUS, &val);
|
||||
if (ret < 0) {
|
||||
drm_err(display->drm, "Error reading ALPM status (%pe)\n", ERR_PTR(ret));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -642,7 +764,7 @@ bool intel_alpm_get_error(struct intel_dp *intel_dp)
|
|||
drm_dbg_kms(display->drm, "ALPM lock timeout error\n");
|
||||
|
||||
/* Clearing error */
|
||||
drm_dp_dpcd_writeb(aux, DP_RECEIVER_ALPM_STATUS, val);
|
||||
drm_dp_dpcd_write_byte(aux, DP_RECEIVER_ALPM_STATUS, val);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -34,6 +34,9 @@ bool intel_alpm_aux_wake_supported(struct intel_dp *intel_dp);
|
|||
bool intel_alpm_aux_less_wake_supported(struct intel_dp *intel_dp);
|
||||
bool intel_alpm_is_alpm_aux_less(struct intel_dp *intel_dp,
|
||||
const struct intel_crtc_state *crtc_state);
|
||||
bool intel_alpm_pr_as_sdp_skip_frames_enabled(struct intel_dp *intel_dp,
|
||||
const struct intel_crtc_state *crtc_state);
|
||||
void intel_alpm_pr_as_sdp_update(const struct intel_crtc_state *crtc_state);
|
||||
void intel_alpm_disable(struct intel_dp *intel_dp);
|
||||
bool intel_alpm_get_error(struct intel_dp *intel_dp);
|
||||
void intel_alpm_lobf_compute_config_late(struct intel_dp *intel_dp,
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
#include <drm/drm_fixed.h>
|
||||
#include <drm/drm_print.h>
|
||||
|
||||
#include "intel_ddi_buf_trans.h"
|
||||
#include "intel_display.h"
|
||||
#include "intel_display_core.h"
|
||||
#include "intel_display_rpm.h"
|
||||
|
|
@ -72,6 +73,8 @@
|
|||
struct intel_bios_encoder_data {
|
||||
struct intel_display *display;
|
||||
|
||||
struct intel_ddi_buf_trans *vspeo;
|
||||
union intel_ddi_buf_trans_entry *entries;
|
||||
struct child_device_config child;
|
||||
struct dsc_compression_parameters_entry *dsc;
|
||||
struct list_head node;
|
||||
|
|
@ -200,6 +203,8 @@ static const struct {
|
|||
.min_size = sizeof(struct bdb_mipi_sequence) },
|
||||
{ .section_id = BDB_COMPRESSION_PARAMETERS,
|
||||
.min_size = sizeof(struct bdb_compression_parameters), },
|
||||
{ .section_id = BDB_VSWING_PREEMPH,
|
||||
.min_size = sizeof(struct bdb_vswing_preemph), },
|
||||
{ .section_id = BDB_GENERIC_DTD,
|
||||
.min_size = sizeof(struct bdb_generic_dtd), },
|
||||
};
|
||||
|
|
@ -2203,6 +2208,31 @@ parse_compression_parameters(struct intel_display *display)
|
|||
}
|
||||
}
|
||||
|
||||
static int vswing_preemph_num_rows(struct intel_display *display)
|
||||
{
|
||||
return DISPLAY_VER(display) >= 14 ? 16 : 10;
|
||||
}
|
||||
|
||||
static void
|
||||
parse_vswing_preemph_override(struct intel_display *display)
|
||||
{
|
||||
const struct bdb_vswing_preemph *block;
|
||||
|
||||
if (display->vbt.version < 218)
|
||||
return;
|
||||
|
||||
block = bdb_find_section(display, BDB_VSWING_PREEMPH);
|
||||
|
||||
/* pre-ICL GOPs don't have VBT #57 */
|
||||
if (!block)
|
||||
return;
|
||||
|
||||
display->vbt.vspeo.tables = block->tables;
|
||||
display->vbt.vspeo.num_tables = block->num_tables;
|
||||
display->vbt.vspeo.num_columns = block->num_columns;
|
||||
display->vbt.vspeo.num_rows = vswing_preemph_num_rows(display);
|
||||
}
|
||||
|
||||
static u8 translate_iboost(struct intel_display *display, u8 val)
|
||||
{
|
||||
static const u8 mapping[] = { 1, 3, 7 }; /* See VBT spec */
|
||||
|
|
@ -2621,6 +2651,30 @@ static void sanitize_device_type(struct intel_bios_encoder_data *devdata,
|
|||
devdata->child.device_type |= DEVICE_TYPE_NOT_HDMI_OUTPUT;
|
||||
}
|
||||
|
||||
static void allocate_vswing_preemph_override(struct intel_bios_encoder_data *devdata)
|
||||
{
|
||||
int num_rows = devdata->display->vbt.vspeo.num_rows;
|
||||
union intel_ddi_buf_trans_entry *entries;
|
||||
struct intel_ddi_buf_trans *vspeo;
|
||||
|
||||
if (!intel_bios_encoder_requests_vspeo(devdata))
|
||||
return;
|
||||
|
||||
vspeo = kzalloc_obj(*vspeo);
|
||||
if (!vspeo)
|
||||
return;
|
||||
|
||||
entries = kzalloc_objs(*entries, num_rows);
|
||||
if (!entries) {
|
||||
kfree(vspeo);
|
||||
return;
|
||||
}
|
||||
|
||||
devdata->entries = entries;
|
||||
devdata->vspeo = vspeo;
|
||||
devdata->vspeo->num_entries = num_rows;
|
||||
}
|
||||
|
||||
static void sanitize_hdmi_level_shift(struct intel_bios_encoder_data *devdata,
|
||||
enum port port)
|
||||
{
|
||||
|
|
@ -2737,7 +2791,6 @@ static bool is_port_valid(struct intel_display *display, enum port port)
|
|||
static void print_ddi_port(const struct intel_bios_encoder_data *devdata)
|
||||
{
|
||||
struct intel_display *display = devdata->display;
|
||||
const struct child_device_config *child = &devdata->child;
|
||||
bool is_dvi, is_hdmi, is_dp, is_edp, is_dsi, is_crt, supports_typec_usb, supports_tbt;
|
||||
int dp_boost_level, dp_max_link_rate, hdmi_boost_level, hdmi_level_shift, max_tmds_clock;
|
||||
enum port port;
|
||||
|
|
@ -2774,6 +2827,11 @@ static void print_ddi_port(const struct intel_bios_encoder_data *devdata)
|
|||
"Port %c supports dynamic DDI allocation in TCSS\n",
|
||||
port_name(port));
|
||||
|
||||
if (intel_bios_encoder_requests_vspeo(devdata))
|
||||
drm_dbg_kms(display->drm,
|
||||
"Port %c requests vswing/pre-emphasis override\n",
|
||||
port_name(port));
|
||||
|
||||
hdmi_level_shift = intel_bios_hdmi_level_shift(devdata);
|
||||
if (hdmi_level_shift >= 0) {
|
||||
drm_dbg_kms(display->drm,
|
||||
|
|
@ -2805,14 +2863,6 @@ static void print_ddi_port(const struct intel_bios_encoder_data *devdata)
|
|||
drm_dbg_kms(display->drm,
|
||||
"Port %c VBT DP max link rate: %d\n",
|
||||
port_name(port), dp_max_link_rate);
|
||||
|
||||
/*
|
||||
* FIXME need to implement support for VBT
|
||||
* vswing/preemph tables should this ever trigger.
|
||||
*/
|
||||
drm_WARN(display->drm, child->use_vbt_vswing,
|
||||
"Port %c asks to use VBT vswing/preemph tables\n",
|
||||
port_name(port));
|
||||
}
|
||||
|
||||
static void parse_ddi_port(struct intel_bios_encoder_data *devdata)
|
||||
|
|
@ -2834,6 +2884,7 @@ static void parse_ddi_port(struct intel_bios_encoder_data *devdata)
|
|||
sanitize_dedicated_external(devdata, port);
|
||||
sanitize_device_type(devdata, port);
|
||||
sanitize_hdmi_level_shift(devdata, port);
|
||||
allocate_vswing_preemph_override(devdata);
|
||||
}
|
||||
|
||||
static bool has_ddi_port_info(struct intel_display *display)
|
||||
|
|
@ -3291,6 +3342,7 @@ void intel_bios_init(struct intel_display *display)
|
|||
parse_general_features(display);
|
||||
parse_general_definitions(display);
|
||||
parse_driver_features(display);
|
||||
parse_vswing_preemph_override(display);
|
||||
|
||||
/* Depends on child device list */
|
||||
parse_compression_parameters(display);
|
||||
|
|
@ -3370,6 +3422,9 @@ void intel_bios_driver_remove(struct intel_display *display)
|
|||
list_for_each_entry_safe(devdata, nd, &display->vbt.display_devices,
|
||||
node) {
|
||||
list_del(&devdata->node);
|
||||
|
||||
kfree(devdata->entries);
|
||||
kfree(devdata->vspeo);
|
||||
kfree(devdata->dsc);
|
||||
kfree(devdata);
|
||||
}
|
||||
|
|
@ -3801,6 +3856,11 @@ int intel_bios_hdmi_ddc_pin(const struct intel_bios_encoder_data *devdata)
|
|||
return map_ddc_pin(devdata->display, devdata->child.ddc_pin);
|
||||
}
|
||||
|
||||
bool intel_bios_encoder_requests_vspeo(const struct intel_bios_encoder_data *devdata)
|
||||
{
|
||||
return devdata->display->vbt.version >= 218 && devdata->child.use_vbt_vswing;
|
||||
}
|
||||
|
||||
bool intel_bios_encoder_supports_typec_usb(const struct intel_bios_encoder_data *devdata)
|
||||
{
|
||||
return devdata->display->vbt.version >= 195 && devdata->child.dp_usb_type_c;
|
||||
|
|
@ -3811,6 +3871,190 @@ bool intel_bios_encoder_supports_tbt(const struct intel_bios_encoder_data *devda
|
|||
return devdata->display->vbt.version >= 209 && devdata->child.tbt;
|
||||
}
|
||||
|
||||
static bool
|
||||
validate_vspeo(const struct intel_bios_encoder_data *devdata, bool has_dp)
|
||||
{
|
||||
struct intel_ddi_buf_trans *vspeo;
|
||||
|
||||
vspeo = devdata->vspeo;
|
||||
if (!vspeo)
|
||||
return false;
|
||||
|
||||
if (!has_dp)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const struct intel_ddi_buf_trans *
|
||||
intel_bios_get_c20_vspeo(const struct intel_bios_encoder_data *devdata,
|
||||
bool has_dp, bool is_uhbr)
|
||||
{
|
||||
struct intel_display *display = devdata->display;
|
||||
union intel_ddi_buf_trans_entry *entries = devdata->entries;
|
||||
struct intel_ddi_buf_trans *vspeo = devdata->vspeo;
|
||||
const u32 *tables = display->vbt.vspeo.tables;
|
||||
int num_columns = display->vbt.vspeo.num_columns;
|
||||
int num_rows = display->vbt.vspeo.num_rows;
|
||||
int idx = is_uhbr ? 5 : 4;
|
||||
size_t offset = 0;
|
||||
int level;
|
||||
|
||||
if (!validate_vspeo(devdata, has_dp))
|
||||
return NULL;
|
||||
|
||||
offset += idx * num_rows * num_columns;
|
||||
|
||||
for (level = 0; level < num_rows; level++) {
|
||||
u32 vswing = tables[offset];
|
||||
u32 pre_cursor = tables[offset + 1];
|
||||
u32 post_cursor = tables[offset + 2];
|
||||
|
||||
entries[level].snps.vswing = vswing;
|
||||
entries[level].snps.pre_cursor = pre_cursor;
|
||||
entries[level].snps.post_cursor = post_cursor;
|
||||
|
||||
offset += num_columns;
|
||||
}
|
||||
|
||||
vspeo->entries = entries;
|
||||
|
||||
return vspeo;
|
||||
}
|
||||
|
||||
const struct intel_ddi_buf_trans *
|
||||
intel_bios_get_c10_vspeo(const struct intel_bios_encoder_data *devdata,
|
||||
bool has_dp, int port_clock, bool has_edp)
|
||||
{
|
||||
struct intel_display *display = devdata->display;
|
||||
union intel_ddi_buf_trans_entry *entries = devdata->entries;
|
||||
struct intel_ddi_buf_trans *vspeo = devdata->vspeo;
|
||||
const u32 *tables = display->vbt.vspeo.tables;
|
||||
int num_columns = display->vbt.vspeo.num_columns;
|
||||
int num_rows = display->vbt.vspeo.num_rows;
|
||||
size_t offset = 0;
|
||||
int level, idx;
|
||||
|
||||
if (!validate_vspeo(devdata, has_dp))
|
||||
return NULL;
|
||||
|
||||
if (has_edp)
|
||||
idx = port_clock > 540000 ? 3 : 2;
|
||||
else
|
||||
idx = port_clock > 270000 ? 1 : 0;
|
||||
|
||||
offset += idx * num_rows * num_columns;
|
||||
|
||||
for (level = 0; level < num_rows; level++) {
|
||||
u32 vswing = tables[offset];
|
||||
u32 pre_cursor = tables[offset + 1];
|
||||
u32 post_cursor = tables[offset + 2];
|
||||
|
||||
entries[level].snps.vswing = vswing;
|
||||
entries[level].snps.pre_cursor = pre_cursor;
|
||||
entries[level].snps.post_cursor = post_cursor;
|
||||
|
||||
offset += num_columns;
|
||||
}
|
||||
|
||||
vspeo->entries = entries;
|
||||
|
||||
return vspeo;
|
||||
}
|
||||
|
||||
const struct intel_ddi_buf_trans *
|
||||
intel_bios_get_ehl_combo_vspeo(const struct intel_bios_encoder_data *devdata,
|
||||
bool has_dp, int port_clock, bool low_vswing_edp)
|
||||
{
|
||||
struct intel_display *display = devdata->display;
|
||||
union intel_ddi_buf_trans_entry *entries = devdata->entries;
|
||||
struct intel_ddi_buf_trans *vspeo = devdata->vspeo;
|
||||
const u32 *tables = display->vbt.vspeo.tables;
|
||||
int num_columns = display->vbt.vspeo.num_columns;
|
||||
int num_rows = display->vbt.vspeo.num_rows;
|
||||
size_t offset = 0;
|
||||
int level, idx;
|
||||
|
||||
if (!validate_vspeo(devdata, has_dp))
|
||||
return NULL;
|
||||
|
||||
if (low_vswing_edp)
|
||||
idx = port_clock > 540000 ? 2 : 1;
|
||||
else
|
||||
idx = port_clock > 270000 ? 1 : 0;
|
||||
|
||||
offset += idx * num_rows * num_columns;
|
||||
|
||||
for (level = 0; level < num_rows; level++) {
|
||||
u32 dw2_swing_sel = tables[offset];
|
||||
u32 dw7_n_scalar = tables[offset + 1];
|
||||
u32 dw4_cursor_coeff = tables[offset + 2];
|
||||
u32 dw4_post_cursor_2 = tables[offset + 3];
|
||||
u32 dw4_post_cursor_1 = tables[offset + 4];
|
||||
|
||||
entries[level].icl.dw2_swing_sel = dw2_swing_sel;
|
||||
entries[level].icl.dw7_n_scalar = dw7_n_scalar;
|
||||
entries[level].icl.dw4_cursor_coeff = dw4_cursor_coeff;
|
||||
entries[level].icl.dw4_post_cursor_2 = dw4_post_cursor_2;
|
||||
entries[level].icl.dw4_post_cursor_1 = dw4_post_cursor_1;
|
||||
|
||||
offset += num_columns;
|
||||
}
|
||||
|
||||
vspeo->entries = entries;
|
||||
|
||||
return vspeo;
|
||||
}
|
||||
|
||||
const struct intel_ddi_buf_trans *
|
||||
intel_bios_get_jsl_combo_vspeo(const struct intel_bios_encoder_data *devdata,
|
||||
bool has_dp, int port_clock, bool low_vswing_edp)
|
||||
{
|
||||
struct intel_display *display = devdata->display;
|
||||
union intel_ddi_buf_trans_entry *entries = devdata->entries;
|
||||
struct intel_ddi_buf_trans *vspeo = devdata->vspeo;
|
||||
const u32 *tables = display->vbt.vspeo.tables;
|
||||
int num_columns = display->vbt.vspeo.num_columns;
|
||||
int num_rows = display->vbt.vspeo.num_rows;
|
||||
size_t offset = 0;
|
||||
int idx = 0;
|
||||
int level;
|
||||
|
||||
if (!validate_vspeo(devdata, has_dp))
|
||||
return NULL;
|
||||
|
||||
if (low_vswing_edp) {
|
||||
if (port_clock > 540000)
|
||||
idx = 0;
|
||||
else if (port_clock > 270000)
|
||||
idx = 2;
|
||||
else
|
||||
idx = 1;
|
||||
}
|
||||
|
||||
offset += idx * num_rows * num_columns;
|
||||
|
||||
for (level = 0; level < num_rows; level++) {
|
||||
u32 dw2_swing_sel = tables[offset];
|
||||
u32 dw7_n_scalar = tables[offset + 1];
|
||||
u32 dw4_cursor_coeff = tables[offset + 2];
|
||||
u32 dw4_post_cursor_2 = tables[offset + 3];
|
||||
u32 dw4_post_cursor_1 = tables[offset + 4];
|
||||
|
||||
entries[level].icl.dw2_swing_sel = dw2_swing_sel;
|
||||
entries[level].icl.dw7_n_scalar = dw7_n_scalar;
|
||||
entries[level].icl.dw4_cursor_coeff = dw4_cursor_coeff;
|
||||
entries[level].icl.dw4_post_cursor_2 = dw4_post_cursor_2;
|
||||
entries[level].icl.dw4_post_cursor_1 = dw4_post_cursor_1;
|
||||
|
||||
offset += num_columns;
|
||||
}
|
||||
|
||||
vspeo->entries = entries;
|
||||
|
||||
return vspeo;
|
||||
}
|
||||
|
||||
bool intel_bios_encoder_is_dedicated_external(const struct intel_bios_encoder_data *devdata)
|
||||
{
|
||||
return devdata->display->vbt.version >= 264 &&
|
||||
|
|
|
|||
|
|
@ -73,6 +73,20 @@ bool intel_bios_get_dsc_params(struct intel_encoder *encoder,
|
|||
const struct intel_bios_encoder_data *
|
||||
intel_bios_encoder_data_lookup(struct intel_display *display, enum port port);
|
||||
|
||||
const struct intel_ddi_buf_trans *
|
||||
intel_bios_get_c20_vspeo(const struct intel_bios_encoder_data *devdata,
|
||||
bool has_dp, bool is_uhbr);
|
||||
const struct intel_ddi_buf_trans *
|
||||
intel_bios_get_c10_vspeo(const struct intel_bios_encoder_data *devdata,
|
||||
bool has_dp, int port_clock, bool has_edp);
|
||||
const struct intel_ddi_buf_trans *
|
||||
intel_bios_get_ehl_combo_vspeo(const struct intel_bios_encoder_data *devdata,
|
||||
bool has_dp, int port_clock, bool low_vswing_edp);
|
||||
const struct intel_ddi_buf_trans *
|
||||
intel_bios_get_jsl_combo_vspeo(const struct intel_bios_encoder_data *devdata,
|
||||
bool has_dp, int port_clock, bool low_vswing_edp);
|
||||
|
||||
bool intel_bios_encoder_requests_vspeo(const struct intel_bios_encoder_data *devdata);
|
||||
bool intel_bios_encoder_supports_dvi(const struct intel_bios_encoder_data *devdata);
|
||||
bool intel_bios_encoder_supports_hdmi(const struct intel_bios_encoder_data *devdata);
|
||||
bool intel_bios_encoder_supports_dp(const struct intel_bios_encoder_data *devdata);
|
||||
|
|
|
|||
|
|
@ -3998,25 +3998,17 @@ xelpd_program_plane_pre_csc_lut(struct intel_dsb *dsb,
|
|||
}
|
||||
|
||||
static void
|
||||
xelpd_program_plane_post_csc_lut(struct intel_dsb *dsb,
|
||||
const struct intel_plane_state *plane_state)
|
||||
xelpd_load_hdr_post_csc_lut(struct intel_display *display,
|
||||
struct intel_dsb *dsb,
|
||||
enum pipe pipe,
|
||||
enum plane_id plane,
|
||||
const struct drm_color_lut32 *post_csc_lut)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(plane_state);
|
||||
const struct drm_plane_state *state = &plane_state->uapi;
|
||||
enum pipe pipe = to_intel_plane(state->plane)->pipe;
|
||||
enum plane_id plane = to_intel_plane(state->plane)->id;
|
||||
const struct drm_color_lut32 *post_csc_lut = plane_state->hw.gamma_lut->data;
|
||||
int i, lut_size = 32;
|
||||
u32 lut_val;
|
||||
|
||||
if (!icl_is_hdr_plane(display, plane))
|
||||
return;
|
||||
|
||||
intel_de_write_dsb(display, dsb, PLANE_POST_CSC_GAMC_INDEX_ENH(pipe, plane, 0),
|
||||
PLANE_PAL_PREC_AUTO_INCREMENT);
|
||||
/* TODO: Add macro */
|
||||
intel_de_write_dsb(display, dsb, PLANE_POST_CSC_GAMC_SEG0_INDEX_ENH(pipe, plane, 0),
|
||||
PLANE_PAL_PREC_AUTO_INCREMENT);
|
||||
|
||||
for (i = 0; i < lut_size + 3; i++) {
|
||||
if (post_csc_lut) {
|
||||
|
|
@ -4036,8 +4028,62 @@ xelpd_program_plane_post_csc_lut(struct intel_dsb *dsb,
|
|||
}
|
||||
|
||||
intel_de_write_dsb(display, dsb, PLANE_POST_CSC_GAMC_INDEX_ENH(pipe, plane, 0), 0);
|
||||
intel_de_write_dsb(display, dsb,
|
||||
PLANE_POST_CSC_GAMC_SEG0_INDEX_ENH(pipe, plane, 0), 0);
|
||||
}
|
||||
|
||||
static void
|
||||
xelpd_load_sdr_post_csc_lut(struct intel_display *display,
|
||||
struct intel_dsb *dsb,
|
||||
enum pipe pipe,
|
||||
enum plane_id plane,
|
||||
const struct drm_color_lut32 *post_csc_lut)
|
||||
{
|
||||
int i, lut_size = 32;
|
||||
u32 lut_val;
|
||||
|
||||
/*
|
||||
* First 3 planes are HDR, so reduce by 3 to get to the right
|
||||
* SDR plane offset
|
||||
*/
|
||||
plane = plane - 3;
|
||||
|
||||
intel_de_write_dsb(display, dsb, PLANE_POST_CSC_GAMC_INDEX(pipe, plane, 0),
|
||||
PLANE_PAL_PREC_AUTO_INCREMENT);
|
||||
|
||||
for (i = 0; i < lut_size + 3; i++) {
|
||||
if (post_csc_lut) {
|
||||
if (i < lut_size)
|
||||
lut_val = drm_color_lut32_extract(post_csc_lut[i].green, 16);
|
||||
/* else duplicate last lut_val */
|
||||
} else {
|
||||
if (i < lut_size)
|
||||
lut_val = (i * ((1 << 16) - 1)) / (lut_size - 1);
|
||||
else
|
||||
lut_val = 1 << 16;
|
||||
}
|
||||
|
||||
intel_de_write_dsb(display, dsb,
|
||||
PLANE_POST_CSC_GAMC_DATA(pipe, plane, 0),
|
||||
lut_val);
|
||||
}
|
||||
|
||||
intel_de_write_dsb(display, dsb, PLANE_POST_CSC_GAMC_INDEX(pipe, plane, 0), 0);
|
||||
}
|
||||
|
||||
static void
|
||||
xelpd_program_plane_post_csc_lut(struct intel_dsb *dsb,
|
||||
const struct intel_plane_state *plane_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(plane_state);
|
||||
const struct drm_plane_state *state = &plane_state->uapi;
|
||||
enum pipe pipe = to_intel_plane(state->plane)->pipe;
|
||||
enum plane_id plane = to_intel_plane(state->plane)->id;
|
||||
const struct drm_color_lut32 *post_csc_lut = plane_state->hw.gamma_lut ?
|
||||
plane_state->hw.gamma_lut->data : NULL;
|
||||
|
||||
if (icl_is_hdr_plane(display, plane))
|
||||
xelpd_load_hdr_post_csc_lut(display, dsb, pipe, plane, post_csc_lut);
|
||||
else
|
||||
xelpd_load_sdr_post_csc_lut(display, dsb, pipe, plane, post_csc_lut);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
#include "skl_universal_plane.h"
|
||||
|
||||
#define MAX_COLOR_PIPELINES 1
|
||||
#define MAX_COLOROP 4
|
||||
#define MAX_COLOROP 5
|
||||
#define PLANE_DEGAMMA_SIZE 128
|
||||
#define PLANE_GAMMA_SIZE 32
|
||||
|
||||
|
|
@ -31,6 +31,7 @@ static const struct drm_colorop_funcs intel_colorop_funcs = {
|
|||
* the pipeline totally unusable.
|
||||
*/
|
||||
static const enum intel_color_block xe3plpd_primary_plane_pipeline[] = {
|
||||
INTEL_PLANE_CB_CSC_FF,
|
||||
INTEL_PLANE_CB_PRE_CSC_LUT,
|
||||
INTEL_PLANE_CB_CSC,
|
||||
INTEL_PLANE_CB_3DLUT,
|
||||
|
|
@ -38,11 +39,25 @@ static const enum intel_color_block xe3plpd_primary_plane_pipeline[] = {
|
|||
};
|
||||
|
||||
static const enum intel_color_block hdr_plane_pipeline[] = {
|
||||
INTEL_PLANE_CB_CSC_FF,
|
||||
INTEL_PLANE_CB_PRE_CSC_LUT,
|
||||
INTEL_PLANE_CB_CSC,
|
||||
INTEL_PLANE_CB_POST_CSC_LUT,
|
||||
};
|
||||
|
||||
static const enum intel_color_block sdr_plane_yuv_pipeline[] = {
|
||||
INTEL_PLANE_CB_CSC_FF,
|
||||
INTEL_PLANE_CB_POST_CSC_LUT,
|
||||
};
|
||||
|
||||
static const u64 intel_plane_supported_csc_ff =
|
||||
BIT(DRM_COLOROP_FM_YCBCR601_FULL_RGB) |
|
||||
BIT(DRM_COLOROP_FM_YCBCR601_LIMITED_RGB) |
|
||||
BIT(DRM_COLOROP_FM_YCBCR709_FULL_RGB) |
|
||||
BIT(DRM_COLOROP_FM_YCBCR709_LIMITED_RGB) |
|
||||
BIT(DRM_COLOROP_FM_YCBCR2020_NC_FULL_RGB) |
|
||||
BIT(DRM_COLOROP_FM_YCBCR2020_NC_LIMITED_RGB);
|
||||
|
||||
static bool plane_has_3dlut(struct intel_display *display, enum pipe pipe,
|
||||
struct drm_plane *plane)
|
||||
{
|
||||
|
|
@ -92,6 +107,12 @@ struct intel_colorop *intel_color_pipeline_plane_add_colorop(struct drm_plane *p
|
|||
DRM_COLOROP_LUT1D_INTERPOLATION_LINEAR,
|
||||
DRM_COLOROP_FLAG_ALLOW_BYPASS);
|
||||
break;
|
||||
case INTEL_PLANE_CB_CSC_FF:
|
||||
ret = drm_plane_colorop_fixed_matrix_init(dev, &colorop->base, plane,
|
||||
&intel_colorop_funcs,
|
||||
intel_plane_supported_csc_ff,
|
||||
DRM_COLOROP_FLAG_ALLOW_BYPASS);
|
||||
break;
|
||||
default:
|
||||
drm_err(plane->dev, "Invalid colorop id [%d]", id);
|
||||
ret = -EINVAL;
|
||||
|
|
@ -126,9 +147,12 @@ int _intel_color_pipeline_plane_init(struct drm_plane *plane, struct drm_prop_en
|
|||
if (plane_has_3dlut(display, pipe, plane)) {
|
||||
pipeline = xe3plpd_primary_plane_pipeline;
|
||||
pipeline_len = ARRAY_SIZE(xe3plpd_primary_plane_pipeline);
|
||||
} else {
|
||||
} else if (icl_is_hdr_plane(display, to_intel_plane(plane)->id)) {
|
||||
pipeline = hdr_plane_pipeline;
|
||||
pipeline_len = ARRAY_SIZE(hdr_plane_pipeline);
|
||||
} else {
|
||||
pipeline = sdr_plane_yuv_pipeline;
|
||||
pipeline_len = ARRAY_SIZE(sdr_plane_yuv_pipeline);
|
||||
}
|
||||
|
||||
for (i = 0; i < pipeline_len; i++) {
|
||||
|
|
@ -155,17 +179,11 @@ int _intel_color_pipeline_plane_init(struct drm_plane *plane, struct drm_prop_en
|
|||
|
||||
int intel_color_pipeline_plane_init(struct drm_plane *plane, enum pipe pipe)
|
||||
{
|
||||
struct drm_device *dev = plane->dev;
|
||||
struct intel_display *display = to_intel_display(dev);
|
||||
struct drm_prop_enum_list pipelines[MAX_COLOR_PIPELINES] = {};
|
||||
int len = 0;
|
||||
int ret = 0;
|
||||
int i;
|
||||
|
||||
/* Currently expose pipeline only for HDR planes */
|
||||
if (!icl_is_hdr_plane(display, to_intel_plane(plane)->id))
|
||||
return 0;
|
||||
|
||||
/* Add pipeline consisting of transfer functions */
|
||||
ret = _intel_color_pipeline_plane_init(plane, &pipelines[len], pipe);
|
||||
if (ret)
|
||||
|
|
|
|||
|
|
@ -251,6 +251,15 @@ void intel_crtc_state_dump(const struct intel_crtc_state *pipe_config,
|
|||
str_enabled_disabled(pipe_config->has_panel_replay),
|
||||
str_enabled_disabled(pipe_config->enable_psr2_sel_fetch));
|
||||
drm_printf(&p, "minimum hblank: %d\n", pipe_config->min_hblank);
|
||||
|
||||
drm_printf(&p, "DIP Transmission Lines: EMP/AS SDP: %u\n",
|
||||
pipe_config->dip.emp_as_sdp_tl);
|
||||
drm_printf(&p, "DIP Transmission Lines: Common Base SDP: %u, GMP SDP: %u, PPS SDP: %u, VSC SDP: %u, VSC_EXT SDP: %u\n",
|
||||
pipe_config->dip.cmn_sdp_tl,
|
||||
pipe_config->dip.gmp_sdp_tl,
|
||||
pipe_config->dip.pps_sdp_tl,
|
||||
pipe_config->dip.vsc_sdp_tl,
|
||||
pipe_config->dip.vsc_ext_sdp_tl);
|
||||
}
|
||||
|
||||
drm_printf(&p, "audio: %i, infoframes: %i, infoframes enabled: 0x%x\n",
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#include <linux/log2.h>
|
||||
#include <linux/math64.h>
|
||||
#include <linux/string_choices.h>
|
||||
|
||||
#include <drm/drm_print.h>
|
||||
|
||||
|
|
@ -189,7 +190,7 @@ int intel_cx0_wait_for_ack(struct intel_encoder *encoder,
|
|||
drm_dbg_kms(display->drm,
|
||||
"PHY %c Error occurred during %s command. Status: 0x%x\n",
|
||||
phy_name(phy),
|
||||
command == XELPDP_PORT_P2M_COMMAND_READ_ACK ? "read" : "write", *val);
|
||||
str_read_write(command == XELPDP_PORT_P2M_COMMAND_READ_ACK), *val);
|
||||
intel_cx0_bus_reset(encoder, lane);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
@ -198,7 +199,7 @@ int intel_cx0_wait_for_ack(struct intel_encoder *encoder,
|
|||
drm_dbg_kms(display->drm,
|
||||
"PHY %c Not a %s response. MSGBUS Status: 0x%x.\n",
|
||||
phy_name(phy),
|
||||
command == XELPDP_PORT_P2M_COMMAND_READ_ACK ? "read" : "write", *val);
|
||||
str_read_write(command == XELPDP_PORT_P2M_COMMAND_READ_ACK), *val);
|
||||
intel_cx0_bus_reset(encoder, lane);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@
|
|||
#include "intel_ddi.h"
|
||||
#include "intel_ddi_buf_trans.h"
|
||||
#include "intel_de.h"
|
||||
#include "intel_dip.h"
|
||||
#include "intel_display_power.h"
|
||||
#include "intel_display_regs.h"
|
||||
#include "intel_display_types.h"
|
||||
|
|
@ -2331,15 +2332,17 @@ static void intel_dp_sink_set_msa_timing_par_ignore_state(struct intel_dp *intel
|
|||
bool enable)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(intel_dp);
|
||||
int ret;
|
||||
|
||||
if (!crtc_state->vrr.enable)
|
||||
return;
|
||||
|
||||
if (drm_dp_dpcd_writeb(&intel_dp->aux, DP_DOWNSPREAD_CTRL,
|
||||
enable ? DP_MSA_TIMING_PAR_IGNORE_EN : 0) <= 0)
|
||||
ret = drm_dp_dpcd_write_byte(&intel_dp->aux, DP_DOWNSPREAD_CTRL,
|
||||
enable ? DP_MSA_TIMING_PAR_IGNORE_EN : 0);
|
||||
if (ret < 0)
|
||||
drm_dbg_kms(display->drm,
|
||||
"Failed to %s MSA_TIMING_PAR_IGNORE in the sink\n",
|
||||
str_enable_disable(enable));
|
||||
"Failed to %s MSA_TIMING_PAR_IGNORE in the sink (%pe)\n",
|
||||
str_enable_disable(enable), ERR_PTR(ret));
|
||||
}
|
||||
|
||||
static void intel_dp_sink_set_fec_ready(struct intel_dp *intel_dp,
|
||||
|
|
@ -2347,19 +2350,25 @@ static void intel_dp_sink_set_fec_ready(struct intel_dp *intel_dp,
|
|||
bool enable)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(intel_dp);
|
||||
int ret;
|
||||
|
||||
if (!crtc_state->fec_enable)
|
||||
return;
|
||||
|
||||
if (drm_dp_dpcd_writeb(&intel_dp->aux, DP_FEC_CONFIGURATION,
|
||||
enable ? DP_FEC_READY : 0) <= 0)
|
||||
drm_dbg_kms(display->drm, "Failed to set FEC_READY to %s in the sink\n",
|
||||
str_enabled_disabled(enable));
|
||||
ret = drm_dp_dpcd_write_byte(&intel_dp->aux, DP_FEC_CONFIGURATION,
|
||||
enable ? DP_FEC_READY : 0);
|
||||
if (ret < 0)
|
||||
drm_dbg_kms(display->drm, "Failed to set FEC_READY to %s in the sink (%pe)\n",
|
||||
str_enabled_disabled(enable), ERR_PTR(ret));
|
||||
|
||||
if (enable &&
|
||||
drm_dp_dpcd_writeb(&intel_dp->aux, DP_FEC_STATUS,
|
||||
DP_FEC_DECODE_EN_DETECTED | DP_FEC_DECODE_DIS_DETECTED) <= 0)
|
||||
drm_dbg_kms(display->drm, "Failed to clear FEC detected flags\n");
|
||||
if (enable) {
|
||||
ret = drm_dp_dpcd_write_byte(&intel_dp->aux, DP_FEC_STATUS,
|
||||
DP_FEC_DECODE_EN_DETECTED |
|
||||
DP_FEC_DECODE_DIS_DETECTED);
|
||||
if (ret < 0)
|
||||
drm_dbg_kms(display->drm, "Failed to clear FEC detected flags (%pe)\n",
|
||||
ERR_PTR(ret));
|
||||
}
|
||||
}
|
||||
|
||||
static int wait_for_fec_detected(struct drm_dp_aux *aux, bool enabled)
|
||||
|
|
@ -2736,6 +2745,8 @@ static void mtl_ddi_pre_enable_dp(struct intel_atomic_state *state,
|
|||
/* 6.o Configure and enable FEC if needed */
|
||||
intel_ddi_enable_fec(encoder, crtc_state);
|
||||
|
||||
intel_dip_cmn_sdp_transmission_line_enable(crtc_state);
|
||||
|
||||
/* 7.a 128b/132b SST. */
|
||||
if (!is_mst && intel_dp_is_uhbr(crtc_state)) {
|
||||
/* VCPID 1, start slot 0 for 128b/132b, tu slots */
|
||||
|
|
@ -3123,6 +3134,7 @@ static void intel_ddi_buf_disable(struct intel_encoder *encoder,
|
|||
DP_TP_CTL_ENABLE, 0);
|
||||
}
|
||||
|
||||
intel_dip_cmn_sdp_transmission_line_disable(crtc_state);
|
||||
intel_ddi_disable_fec(encoder, crtc_state);
|
||||
|
||||
if (DISPLAY_VER(display) < 14)
|
||||
|
|
@ -4235,6 +4247,7 @@ static void intel_ddi_get_config(struct intel_encoder *encoder,
|
|||
intel_read_dp_sdp(encoder, pipe_config, HDMI_PACKET_TYPE_GAMUT_METADATA);
|
||||
intel_read_dp_sdp(encoder, pipe_config, DP_SDP_VSC);
|
||||
intel_read_dp_sdp(encoder, pipe_config, DP_SDP_ADAPTIVE_SYNC);
|
||||
intel_dip_sdp_transmission_line_get_config(pipe_config);
|
||||
|
||||
intel_audio_codec_get_config(encoder, pipe_config);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1784,6 +1784,70 @@ xe3plpd_get_lt_buf_trans(struct intel_encoder *encoder,
|
|||
return intel_get_buf_trans(&xe3plpd_lt_trans_dp14, n_entries);
|
||||
}
|
||||
|
||||
static const struct intel_ddi_buf_trans *
|
||||
jsl_get_combo_buf_trans_override(struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *crtc_state,
|
||||
int *n_entries)
|
||||
{
|
||||
const struct intel_bios_encoder_data *devdata = encoder->devdata;
|
||||
bool has_edp, has_dp;
|
||||
int port_clock;
|
||||
|
||||
has_edp = intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP);
|
||||
has_dp = intel_crtc_has_dp_encoder(crtc_state);
|
||||
port_clock = crtc_state->port_clock;
|
||||
|
||||
return intel_bios_get_jsl_combo_vspeo(devdata, has_dp, port_clock,
|
||||
has_edp && use_edp_low_vswing(encoder));
|
||||
}
|
||||
|
||||
static const struct intel_ddi_buf_trans *
|
||||
ehl_get_combo_buf_trans_override(struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *crtc_state,
|
||||
int *n_entries)
|
||||
{
|
||||
const struct intel_bios_encoder_data *devdata = encoder->devdata;
|
||||
bool has_edp, has_dp;
|
||||
int port_clock;
|
||||
|
||||
has_edp = intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP);
|
||||
has_dp = intel_crtc_has_dp_encoder(crtc_state);
|
||||
port_clock = crtc_state->port_clock;
|
||||
|
||||
return intel_bios_get_ehl_combo_vspeo(devdata, has_dp, port_clock,
|
||||
has_edp && use_edp_low_vswing(encoder));
|
||||
}
|
||||
|
||||
static const struct intel_ddi_buf_trans *
|
||||
mtl_get_c10_buf_trans_override(struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *crtc_state,
|
||||
int *n_entries)
|
||||
{
|
||||
const struct intel_bios_encoder_data *devdata = encoder->devdata;
|
||||
bool has_edp, has_dp;
|
||||
int port_clock;
|
||||
|
||||
has_edp = intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP);
|
||||
has_dp = intel_crtc_has_dp_encoder(crtc_state);
|
||||
port_clock = crtc_state->port_clock;
|
||||
|
||||
return intel_bios_get_c10_vspeo(devdata, has_dp, port_clock, has_edp);
|
||||
}
|
||||
|
||||
static const struct intel_ddi_buf_trans *
|
||||
mtl_get_c20_buf_trans_override(struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *crtc_state,
|
||||
int *n_entries)
|
||||
{
|
||||
const struct intel_bios_encoder_data *devdata = encoder->devdata;
|
||||
bool has_dp, is_uhbr;
|
||||
|
||||
has_dp = intel_crtc_has_dp_encoder(crtc_state);
|
||||
is_uhbr = intel_dp_is_uhbr(crtc_state);
|
||||
|
||||
return intel_bios_get_c20_vspeo(devdata, has_dp, is_uhbr);
|
||||
}
|
||||
|
||||
void intel_ddi_buf_trans_init(struct intel_encoder *encoder)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
|
|
@ -1791,10 +1855,13 @@ void intel_ddi_buf_trans_init(struct intel_encoder *encoder)
|
|||
if (HAS_LT_PHY(display)) {
|
||||
encoder->get_buf_trans = xe3plpd_get_lt_buf_trans;
|
||||
} else if (DISPLAY_VER(display) >= 14) {
|
||||
if (intel_encoder_is_c10phy(encoder))
|
||||
if (intel_encoder_is_c10phy(encoder)) {
|
||||
encoder->get_buf_trans = mtl_get_c10_buf_trans;
|
||||
else
|
||||
encoder->get_buf_trans_override = mtl_get_c10_buf_trans_override;
|
||||
} else {
|
||||
encoder->get_buf_trans = mtl_get_c20_buf_trans;
|
||||
encoder->get_buf_trans_override = mtl_get_c20_buf_trans_override;
|
||||
}
|
||||
} else if (display->platform.dg2) {
|
||||
encoder->get_buf_trans = dg2_get_snps_buf_trans;
|
||||
} else if (display->platform.alderlake_p) {
|
||||
|
|
@ -1814,14 +1881,17 @@ void intel_ddi_buf_trans_init(struct intel_encoder *encoder)
|
|||
else
|
||||
encoder->get_buf_trans = tgl_get_dkl_buf_trans;
|
||||
} else if (DISPLAY_VER(display) == 11) {
|
||||
if (display->platform.jasperlake)
|
||||
if (display->platform.jasperlake) {
|
||||
encoder->get_buf_trans = jsl_get_combo_buf_trans;
|
||||
else if (display->platform.elkhartlake)
|
||||
encoder->get_buf_trans_override = jsl_get_combo_buf_trans_override;
|
||||
} else if (display->platform.elkhartlake) {
|
||||
encoder->get_buf_trans = ehl_get_combo_buf_trans;
|
||||
else if (intel_encoder_is_combo(encoder))
|
||||
encoder->get_buf_trans_override = ehl_get_combo_buf_trans_override;
|
||||
} else if (intel_encoder_is_combo(encoder)) {
|
||||
encoder->get_buf_trans = icl_get_combo_buf_trans;
|
||||
else
|
||||
} else {
|
||||
encoder->get_buf_trans = icl_get_mg_buf_trans;
|
||||
}
|
||||
} else if (display->platform.geminilake || display->platform.broxton) {
|
||||
encoder->get_buf_trans = bxt_get_buf_trans;
|
||||
} else if (display->platform.cometlake_ulx ||
|
||||
|
|
@ -1857,5 +1927,13 @@ const struct intel_ddi_buf_trans *intel_ddi_buf_trans_get(struct intel_encoder *
|
|||
const struct intel_crtc_state *crtc_state,
|
||||
int *n_entries)
|
||||
{
|
||||
if (encoder->get_buf_trans_override) {
|
||||
const struct intel_ddi_buf_trans *override;
|
||||
|
||||
override = encoder->get_buf_trans_override(encoder, crtc_state, n_entries);
|
||||
if (override)
|
||||
return intel_get_buf_trans(override, n_entries);
|
||||
}
|
||||
|
||||
return encoder->get_buf_trans(encoder, crtc_state, n_entries);
|
||||
}
|
||||
|
|
|
|||
215
drivers/gpu/drm/i915/display/intel_dip.c
Normal file
215
drivers/gpu/drm/i915/display/intel_dip.c
Normal file
|
|
@ -0,0 +1,215 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
/*
|
||||
* Copyright © 2026 Intel Corporation
|
||||
*
|
||||
*/
|
||||
|
||||
#include <drm/drm_print.h>
|
||||
|
||||
#include "intel_de.h"
|
||||
#include "intel_dip.h"
|
||||
#include "intel_dip_regs.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_hdmi.h"
|
||||
|
||||
static int intel_dip_get_as_sdp_transmission_line(const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(crtc_state);
|
||||
|
||||
if (!HAS_EMP_AS_SDP_TL(display))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* EMP_AS_SDP_TL defines the T1 position as the default AS SDP
|
||||
* Transmission Line, which corresponds to the start of the
|
||||
* VSYNC pulse.
|
||||
*
|
||||
* Use the T1 position for now.
|
||||
*/
|
||||
return crtc_state->vrr.vsync_start;
|
||||
}
|
||||
|
||||
u16 intel_dip_read_emp_as_sdp_tl(const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(crtc_state);
|
||||
enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
|
||||
u32 val;
|
||||
|
||||
if (!HAS_EMP_AS_SDP_TL(display))
|
||||
return 0;
|
||||
|
||||
val = intel_de_read(display, EMP_AS_SDP_TL(display, cpu_transcoder));
|
||||
return REG_FIELD_GET(EMP_AS_SDP_DB_TL_MASK, val);
|
||||
}
|
||||
|
||||
void intel_dip_write_emp_as_sdp_tl(const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(crtc_state);
|
||||
enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
|
||||
|
||||
if (!HAS_EMP_AS_SDP_TL(display))
|
||||
return;
|
||||
|
||||
intel_de_write(display,
|
||||
EMP_AS_SDP_TL(display, cpu_transcoder),
|
||||
EMP_AS_SDP_DB_TL(crtc_state->dip.emp_as_sdp_tl));
|
||||
}
|
||||
|
||||
static int intel_dip_sdp_stagger_to_tl(struct intel_crtc_state *crtc_state,
|
||||
int stagger)
|
||||
{
|
||||
return crtc_state->dip.cmn_sdp_tl + stagger;
|
||||
}
|
||||
|
||||
static
|
||||
void intel_dip_cmn_sdp_tl_compute_config_late(struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(crtc_state);
|
||||
bool as_sdp;
|
||||
|
||||
if (!HAS_COMMON_SDP_TL(display))
|
||||
return;
|
||||
|
||||
as_sdp = crtc_state->infoframes.enable &
|
||||
intel_hdmi_infoframe_enable(DP_SDP_ADAPTIVE_SYNC);
|
||||
/*
|
||||
* When AS SDP is enabled :
|
||||
* - The common SDP Transmission Line matches the EMP SDP Transmission Line.
|
||||
*
|
||||
* When AS SDP is disabled:
|
||||
* - Bspec mentions the positions as lines of delayed vblank.
|
||||
* - Guardband = 1st line of delayed vblank
|
||||
* - Common SDP Transmission line is set to 2nd line of delayed vblank.
|
||||
*/
|
||||
|
||||
if (as_sdp)
|
||||
crtc_state->dip.cmn_sdp_tl = crtc_state->dip.emp_as_sdp_tl;
|
||||
else
|
||||
crtc_state->dip.cmn_sdp_tl = crtc_state->vrr.guardband - 1;
|
||||
|
||||
if (drm_WARN_ON(display->drm,
|
||||
crtc_state->dip.cmn_sdp_tl >=
|
||||
crtc_state->vrr.guardband + crtc_state->set_context_latency))
|
||||
return;
|
||||
|
||||
/*
|
||||
* Currently we are programming the default stagger values, but these
|
||||
* can be optimized if required, based on number of SDPs enabled.
|
||||
*
|
||||
* Default values of the Transmission lines for SDPs other than AS SDP:
|
||||
* VSC : CMN SDP Transmission line
|
||||
* GMP : CMN SDP Transmission line
|
||||
* PPS : CMN SDP Transmission line + 1
|
||||
* VSC_EXT: CMN SDP Transmission line + 2
|
||||
*/
|
||||
crtc_state->dip.vsc_sdp_tl = crtc_state->dip.cmn_sdp_tl;
|
||||
crtc_state->dip.gmp_sdp_tl =
|
||||
intel_dip_sdp_stagger_to_tl(crtc_state, GMP_STAGGER_DEFAULT);
|
||||
crtc_state->dip.pps_sdp_tl =
|
||||
intel_dip_sdp_stagger_to_tl(crtc_state, PPS_STAGGER_DEFAULT);
|
||||
crtc_state->dip.vsc_ext_sdp_tl =
|
||||
intel_dip_sdp_stagger_to_tl(crtc_state, VSC_EXT_STAGGER_DEFAULT);
|
||||
}
|
||||
|
||||
void intel_dip_sdp_tl_compute_config_late(struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
crtc_state->dip.emp_as_sdp_tl = intel_dip_get_as_sdp_transmission_line(crtc_state);
|
||||
|
||||
intel_dip_cmn_sdp_tl_compute_config_late(crtc_state);
|
||||
}
|
||||
|
||||
static
|
||||
void intel_dip_cmn_sdp_transmission_line_get_config(struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(crtc_state);
|
||||
enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
|
||||
u16 vsc_ext_stagger, pps_stagger, gmp_stagger;
|
||||
u32 val;
|
||||
|
||||
if (!HAS_COMMON_SDP_TL(display))
|
||||
return;
|
||||
|
||||
val = intel_de_read(display, CMN_SDP_TL(display, cpu_transcoder));
|
||||
|
||||
if (!(val & TRANSMISSION_LINE_ENABLE))
|
||||
return;
|
||||
|
||||
crtc_state->dip.cmn_sdp_tl = REG_FIELD_GET(BASE_TRANSMISSION_LINE_MASK, val);
|
||||
|
||||
/* SDP VSC uses same transmission line as CMN base transmission line */
|
||||
crtc_state->dip.vsc_sdp_tl = crtc_state->dip.cmn_sdp_tl;
|
||||
|
||||
val = intel_de_read(display, CMN_SDP_TL_STGR_CTL(display, cpu_transcoder));
|
||||
|
||||
vsc_ext_stagger = REG_FIELD_GET(VSC_EXT_STAGGER_MASK, val);
|
||||
pps_stagger = REG_FIELD_GET(PPS_STAGGER_MASK, val);
|
||||
gmp_stagger = REG_FIELD_GET(GMP_STAGGER_MASK, val);
|
||||
|
||||
crtc_state->dip.vsc_ext_sdp_tl =
|
||||
intel_dip_sdp_stagger_to_tl(crtc_state, vsc_ext_stagger);
|
||||
crtc_state->dip.pps_sdp_tl =
|
||||
intel_dip_sdp_stagger_to_tl(crtc_state, pps_stagger);
|
||||
crtc_state->dip.gmp_sdp_tl =
|
||||
intel_dip_sdp_stagger_to_tl(crtc_state, gmp_stagger);
|
||||
}
|
||||
|
||||
void intel_dip_sdp_transmission_line_get_config(struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
crtc_state->dip.emp_as_sdp_tl = intel_dip_read_emp_as_sdp_tl(crtc_state);
|
||||
|
||||
intel_dip_cmn_sdp_transmission_line_get_config(crtc_state);
|
||||
}
|
||||
|
||||
static int intel_dip_sdp_tl_to_stagger(const struct intel_crtc_state *crtc_state,
|
||||
u16 sdp_transmission_line)
|
||||
{
|
||||
return sdp_transmission_line - crtc_state->dip.cmn_sdp_tl;
|
||||
}
|
||||
|
||||
void intel_dip_cmn_sdp_transmission_line_enable(const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(crtc_state);
|
||||
enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
|
||||
int gmp_stagger;
|
||||
int pps_stagger;
|
||||
int vsc_ext_stagger;
|
||||
|
||||
if (!HAS_COMMON_SDP_TL(display))
|
||||
return;
|
||||
|
||||
gmp_stagger = intel_dip_sdp_tl_to_stagger(crtc_state,
|
||||
crtc_state->dip.gmp_sdp_tl);
|
||||
|
||||
pps_stagger = intel_dip_sdp_tl_to_stagger(crtc_state,
|
||||
crtc_state->dip.pps_sdp_tl);
|
||||
|
||||
vsc_ext_stagger = intel_dip_sdp_tl_to_stagger(crtc_state,
|
||||
crtc_state->dip.vsc_ext_sdp_tl);
|
||||
|
||||
if (drm_WARN_ON(display->drm, gmp_stagger < 0))
|
||||
return;
|
||||
if (drm_WARN_ON(display->drm, pps_stagger < 0))
|
||||
return;
|
||||
if (drm_WARN_ON(display->drm, vsc_ext_stagger < 0))
|
||||
return;
|
||||
|
||||
intel_de_write(display, CMN_SDP_TL_STGR_CTL(display, cpu_transcoder),
|
||||
GMP_STAGGER(gmp_stagger) |
|
||||
PPS_STAGGER(pps_stagger) |
|
||||
VSC_EXT_STAGGER(vsc_ext_stagger));
|
||||
|
||||
intel_de_write(display, CMN_SDP_TL(display, cpu_transcoder),
|
||||
TRANSMISSION_LINE_ENABLE |
|
||||
BASE_TRANSMISSION_LINE(crtc_state->dip.cmn_sdp_tl));
|
||||
}
|
||||
|
||||
void intel_dip_cmn_sdp_transmission_line_disable(const struct intel_crtc_state *old_crtc_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(old_crtc_state);
|
||||
enum transcoder cpu_transcoder = old_crtc_state->cpu_transcoder;
|
||||
|
||||
if (!HAS_COMMON_SDP_TL(display))
|
||||
return;
|
||||
|
||||
intel_de_write(display, CMN_SDP_TL(display, cpu_transcoder), 0);
|
||||
}
|
||||
53
drivers/gpu/drm/i915/display/intel_dip.h
Normal file
53
drivers/gpu/drm/i915/display/intel_dip.h
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
/* SPDX-License-Identifier: MIT */
|
||||
/*
|
||||
* Copyright © 2026 Intel Corporation
|
||||
*/
|
||||
|
||||
#ifndef __INTEL_DIP_H__
|
||||
#define __INTEL_DIP_H__
|
||||
|
||||
#include "intel_display_device.h"
|
||||
|
||||
/*
|
||||
* Video DIP (Data Island Packet) helpers.
|
||||
*
|
||||
* This file contains helpers for programming video DIP related hardware.
|
||||
*
|
||||
* TODO: Currently, this is only used for programming EMP_AS_SDP_TL i.e. to
|
||||
* program Transmission Line for HDMI 2.1 Extended Metadata Packet (EMP) and
|
||||
* DP Adaptive Sync (AS) Secondary Data Packet (SDP). However, all low level
|
||||
* DIP buffer read/write and related helpers should be extracted here later.
|
||||
*/
|
||||
|
||||
struct intel_crtc_state;
|
||||
|
||||
/*
|
||||
* EMP AS SDP TL: Extended Metadata Packet (EMP) Adaptive Sync (AS)
|
||||
* Secondary Data Packet (SDP) Transmission Line (TL).
|
||||
*
|
||||
* Starting with BMG (display ver 14.01) and LNL+ (display ver 20+),
|
||||
* the AS SDP transmission line is programmable via the EMP AS SDP TL
|
||||
* register.
|
||||
*/
|
||||
#define HAS_EMP_AS_SDP_TL(__display) (DISPLAY_VERx100(__display) == 1401 || \
|
||||
DISPLAY_VER(__display) >= 20)
|
||||
|
||||
/*
|
||||
* CMN SDP TL: Common Secondary Data Packet Transmission Line.
|
||||
*
|
||||
* Xe3p_lpd introduces new register CMN_SDP_TL to program a common SDP
|
||||
* Transmission line that will be used by the Hardware to position the
|
||||
* SDPs. Along with this, another new register CMN_SDP_TL_STGR_CTL is
|
||||
* also added to stagger the different SDPs.
|
||||
*/
|
||||
#define HAS_COMMON_SDP_TL(__display) (DISPLAY_VER(__display) >= 35)
|
||||
|
||||
u16 intel_dip_read_emp_as_sdp_tl(const struct intel_crtc_state *crtc_state);
|
||||
void intel_dip_write_emp_as_sdp_tl(const struct intel_crtc_state *crtc_state);
|
||||
|
||||
void intel_dip_sdp_tl_compute_config_late(struct intel_crtc_state *crtc_state);
|
||||
void intel_dip_sdp_transmission_line_get_config(struct intel_crtc_state *crtc_state);
|
||||
void intel_dip_cmn_sdp_transmission_line_enable(const struct intel_crtc_state *crtc_state);
|
||||
void intel_dip_cmn_sdp_transmission_line_disable(const struct intel_crtc_state *old_crtc_state);
|
||||
|
||||
#endif /* __INTEL_DIP_H__ */
|
||||
38
drivers/gpu/drm/i915/display/intel_dip_regs.h
Normal file
38
drivers/gpu/drm/i915/display/intel_dip_regs.h
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
/* SPDX-License-Identifier: MIT */
|
||||
/*
|
||||
* Copyright © 2026 Intel Corporation
|
||||
*/
|
||||
|
||||
#ifndef __INTEL_DIP_REGS_H__
|
||||
#define __INTEL_DIP_REGS_H__
|
||||
|
||||
#include "intel_display_reg_defs.h"
|
||||
|
||||
/* EMP (Extended Metadata Packet) AS (Adaptive Sync) SDP Transmission Line */
|
||||
#define _EMP_AS_SDP_TL_A 0x60204
|
||||
#define EMP_AS_SDP_TL(display, trans) _MMIO_TRANS2((display), (trans), _EMP_AS_SDP_TL_A)
|
||||
#define EMP_AS_SDP_DB_TL_MASK REG_GENMASK(12, 0)
|
||||
#define EMP_AS_SDP_DB_TL(db_transmit_line) REG_FIELD_PREP(EMP_AS_SDP_DB_TL_MASK, \
|
||||
(db_transmit_line))
|
||||
|
||||
/* COMMON SDP TRANSMISSION LINE */
|
||||
#define _CMN_SDP_TL_A 0x6020c
|
||||
#define CMN_SDP_TL(display, trans) _MMIO_TRANS2(display, (trans), _CMN_SDP_TL_A)
|
||||
#define TRANSMISSION_LINE_ENABLE REG_BIT(31)
|
||||
#define BASE_TRANSMISSION_LINE_MASK REG_GENMASK(12, 0)
|
||||
#define BASE_TRANSMISSION_LINE(x) REG_FIELD_PREP(BASE_TRANSMISSION_LINE_MASK, x)
|
||||
|
||||
#define _CMN_SDP_TL_STGR_CTL_A 0x60214
|
||||
#define CMN_SDP_TL_STGR_CTL(display, trans) _MMIO_TRANS2(display, (trans), \
|
||||
_CMN_SDP_TL_STGR_CTL_A)
|
||||
#define VSC_EXT_STAGGER_MASK REG_GENMASK(11, 8)
|
||||
#define VSC_EXT_STAGGER(x) REG_FIELD_PREP(VSC_EXT_STAGGER_MASK, x)
|
||||
#define VSC_EXT_STAGGER_DEFAULT 0x2
|
||||
#define PPS_STAGGER_MASK REG_GENMASK(7, 4)
|
||||
#define PPS_STAGGER(x) REG_FIELD_PREP(PPS_STAGGER_MASK, x)
|
||||
#define PPS_STAGGER_DEFAULT 0x1
|
||||
#define GMP_STAGGER_MASK REG_GENMASK(3, 0)
|
||||
#define GMP_STAGGER(x) REG_FIELD_PREP(GMP_STAGGER_MASK, x)
|
||||
#define GMP_STAGGER_DEFAULT 0x0
|
||||
|
||||
#endif /* __INTEL_DIP_REGS_H__ */
|
||||
|
|
@ -50,7 +50,6 @@
|
|||
#include "g4x_dp.h"
|
||||
#include "g4x_hdmi.h"
|
||||
#include "hsw_ips.h"
|
||||
#include "i915_config.h"
|
||||
#include "i9xx_plane.h"
|
||||
#include "i9xx_plane_regs.h"
|
||||
#include "i9xx_wm.h"
|
||||
|
|
@ -70,6 +69,7 @@
|
|||
#include "intel_cx0_phy.h"
|
||||
#include "intel_ddi.h"
|
||||
#include "intel_de.h"
|
||||
#include "intel_dip.h"
|
||||
#include "intel_display_driver.h"
|
||||
#include "intel_display_power.h"
|
||||
#include "intel_display_regs.h"
|
||||
|
|
@ -1000,6 +1000,15 @@ static bool cmrr_params_changed(const struct intel_crtc_state *old_crtc_state,
|
|||
old_crtc_state->vrr.cmrr.cmrr_n != new_crtc_state->vrr.cmrr.cmrr_n;
|
||||
}
|
||||
|
||||
static bool cmn_sdp_changed(const struct intel_crtc_state *old_crtc_state,
|
||||
const struct intel_crtc_state *new_crtc_state)
|
||||
{
|
||||
return old_crtc_state->dip.cmn_sdp_tl != new_crtc_state->dip.cmn_sdp_tl ||
|
||||
old_crtc_state->dip.gmp_sdp_tl != new_crtc_state->dip.gmp_sdp_tl ||
|
||||
old_crtc_state->dip.pps_sdp_tl != new_crtc_state->dip.pps_sdp_tl ||
|
||||
old_crtc_state->dip.vsc_ext_sdp_tl != new_crtc_state->dip.vsc_ext_sdp_tl;
|
||||
}
|
||||
|
||||
static bool intel_crtc_vrr_enabling(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc)
|
||||
{
|
||||
|
|
@ -1232,6 +1241,14 @@ static void intel_pre_plane_update(struct intel_atomic_state *state,
|
|||
intel_vrr_disable(old_crtc_state);
|
||||
intel_vrr_dcb_reset(old_crtc_state, crtc);
|
||||
intel_crtc_update_active_timings(old_crtc_state, false);
|
||||
|
||||
/*
|
||||
* VRR is being disabled seamlessly (no modeset, Panel Replay
|
||||
* stays enabled), so re-apply the AS SDP skip-frame programming
|
||||
* for the new (VRR off) state.
|
||||
*/
|
||||
if (!intel_crtc_needs_modeset(new_crtc_state))
|
||||
intel_alpm_pr_as_sdp_update(new_crtc_state);
|
||||
}
|
||||
|
||||
if (audio_disabling(old_crtc_state, new_crtc_state))
|
||||
|
|
@ -5594,6 +5611,12 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
|
|||
PIPE_CONF_CHECK_I(vrr.dc_balance.max_increase);
|
||||
PIPE_CONF_CHECK_I(vrr.dc_balance.max_decrease);
|
||||
PIPE_CONF_CHECK_I(vrr.dc_balance.vblank_target);
|
||||
PIPE_CONF_CHECK_I(dip.emp_as_sdp_tl);
|
||||
PIPE_CONF_CHECK_I(dip.gmp_sdp_tl);
|
||||
PIPE_CONF_CHECK_I(dip.pps_sdp_tl);
|
||||
PIPE_CONF_CHECK_I(dip.vsc_sdp_tl);
|
||||
PIPE_CONF_CHECK_I(dip.vsc_ext_sdp_tl);
|
||||
PIPE_CONF_CHECK_I(dip.cmn_sdp_tl);
|
||||
}
|
||||
|
||||
if (!fastset || intel_vrr_always_use_vrr_tg(display)) {
|
||||
|
|
@ -6911,6 +6934,9 @@ static void intel_pre_update_crtc(struct intel_atomic_state *state,
|
|||
if (vrr_params_changed(old_crtc_state, new_crtc_state) ||
|
||||
cmrr_params_changed(old_crtc_state, new_crtc_state))
|
||||
intel_vrr_set_transcoder_timings(new_crtc_state);
|
||||
|
||||
if (cmn_sdp_changed(old_crtc_state, new_crtc_state))
|
||||
intel_dip_cmn_sdp_transmission_line_enable(new_crtc_state);
|
||||
}
|
||||
|
||||
intel_fbc_update(state, crtc);
|
||||
|
|
@ -6971,6 +6997,16 @@ static void intel_update_crtc(struct intel_atomic_state *state,
|
|||
intel_crtc_update_active_timings(new_crtc_state,
|
||||
new_crtc_state->vrr.enable);
|
||||
|
||||
/*
|
||||
* VRR is being enabled seamlessly (no modeset, Panel Replay stays
|
||||
* enabled), so re-apply the AS SDP skip-frame programming for the new
|
||||
* (VRR on) state. Done here, outside the vblank-evasion critical section
|
||||
* (which runs with interrupts disabled), because it takes alpm.lock.
|
||||
*/
|
||||
if (intel_crtc_vrr_enabling(state, crtc) &&
|
||||
!intel_crtc_needs_modeset(new_crtc_state))
|
||||
intel_alpm_pr_as_sdp_update(new_crtc_state);
|
||||
|
||||
if (new_crtc_state->vrr.dc_balance.enable)
|
||||
intel_vrr_dcb_increment_flip_count(new_crtc_state, crtc);
|
||||
|
||||
|
|
@ -7271,23 +7307,27 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
|
|||
drm_WARN_ON(display->drm, update_pipes);
|
||||
}
|
||||
|
||||
static void intel_atomic_commit_fence_wait(struct intel_atomic_state *intel_state)
|
||||
static void intel_atomic_commit_fence_wait(struct intel_atomic_state *state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(state);
|
||||
struct drm_plane *plane;
|
||||
struct drm_plane_state *new_plane_state;
|
||||
long ret;
|
||||
int i;
|
||||
|
||||
for_each_new_plane_in_state(&intel_state->base, plane, new_plane_state, i) {
|
||||
if (new_plane_state->fence) {
|
||||
ret = dma_fence_wait_timeout(new_plane_state->fence, false,
|
||||
i915_fence_timeout());
|
||||
if (ret <= 0)
|
||||
break;
|
||||
for_each_new_plane_in_state(&state->base, plane, new_plane_state, i) {
|
||||
if (!new_plane_state->fence)
|
||||
continue;
|
||||
|
||||
dma_fence_put(new_plane_state->fence);
|
||||
new_plane_state->fence = NULL;
|
||||
ret = dma_fence_wait(new_plane_state->fence, false);
|
||||
if (ret < 0) {
|
||||
drm_dbg_kms(display->drm, "[PLANE:%d:%s] fence wait failed (%pe)\n",
|
||||
plane->base.id, plane->name, ERR_PTR(ret));
|
||||
break;
|
||||
}
|
||||
|
||||
dma_fence_put(new_plane_state->fence);
|
||||
new_plane_state->fence = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -244,6 +244,13 @@ struct intel_vbt_data {
|
|||
struct list_head display_devices;
|
||||
struct list_head bdb_blocks;
|
||||
|
||||
struct {
|
||||
const u32 *tables;
|
||||
int num_tables;
|
||||
int num_columns;
|
||||
int num_rows;
|
||||
} vspeo;
|
||||
|
||||
struct sdvo_device_mapping {
|
||||
u8 initialized;
|
||||
u8 dvo_port;
|
||||
|
|
|
|||
|
|
@ -2217,8 +2217,10 @@ static void gen11_display_irq_reset(struct intel_display *display)
|
|||
enum pipe pipe;
|
||||
u32 trans_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B) |
|
||||
BIT(TRANSCODER_C) | BIT(TRANSCODER_D);
|
||||
bool reset_hpd = !intel_display_rpm_pme_enabled(display);
|
||||
|
||||
intel_de_write(display, GEN11_DISPLAY_INT_CTL, 0);
|
||||
if (reset_hpd)
|
||||
intel_de_write(display, GEN11_DISPLAY_INT_CTL, 0);
|
||||
|
||||
if (DISPLAY_VER(display) >= 12) {
|
||||
enum transcoder trans;
|
||||
|
|
@ -2250,13 +2252,15 @@ static void gen11_display_irq_reset(struct intel_display *display)
|
|||
irq_reset(display, GEN8_DE_PORT_IRQ_REGS);
|
||||
irq_reset(display, GEN8_DE_MISC_IRQ_REGS);
|
||||
|
||||
if (DISPLAY_VER(display) >= 14)
|
||||
irq_reset(display, PICAINTERRUPT_IRQ_REGS);
|
||||
else
|
||||
irq_reset(display, GEN11_DE_HPD_IRQ_REGS);
|
||||
if (reset_hpd) {
|
||||
if (DISPLAY_VER(display) >= 14)
|
||||
irq_reset(display, PICAINTERRUPT_IRQ_REGS);
|
||||
else
|
||||
irq_reset(display, GEN11_DE_HPD_IRQ_REGS);
|
||||
|
||||
if (INTEL_PCH_TYPE(display) >= PCH_ICP)
|
||||
irq_reset(display, SDE_IRQ_REGS);
|
||||
if (INTEL_PCH_TYPE(display) >= PCH_ICP)
|
||||
irq_reset(display, SDE_IRQ_REGS);
|
||||
}
|
||||
}
|
||||
|
||||
void gen8_irq_power_well_post_enable(struct intel_display *display,
|
||||
|
|
|
|||
|
|
@ -169,6 +169,7 @@ enum aux_ch {
|
|||
enum intel_color_block {
|
||||
INTEL_PLANE_CB_PRE_CSC_LUT,
|
||||
INTEL_PLANE_CB_CSC,
|
||||
INTEL_PLANE_CB_CSC_FF,
|
||||
INTEL_PLANE_CB_POST_CSC_LUT,
|
||||
INTEL_PLANE_CB_3DLUT,
|
||||
|
||||
|
|
|
|||
|
|
@ -51,6 +51,11 @@ struct drm_printer;
|
|||
param(bool, psr_safest_params, false, 0400) \
|
||||
param(bool, enable_psr2_sel_fetch, true, 0400) \
|
||||
param(int, enable_dmc_wl, -1, 0400) \
|
||||
/*
|
||||
* Debugfs-only knob (per-device): no matching module_param is registered
|
||||
* in intel_display_params.c on purpose. Runtime-toggle via debugfs.
|
||||
*/ \
|
||||
param(bool, enable_periodic_assdp, false, 0600) \
|
||||
|
||||
#define MEMBER(T, member, ...) T member;
|
||||
struct intel_display_params {
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
#include <drm/intel/intel_pcode_regs.h>
|
||||
#include <drm/intel/step.h>
|
||||
|
||||
#include "intel_alpm.h"
|
||||
#include "intel_backlight_regs.h"
|
||||
#include "intel_cdclk.h"
|
||||
#include "intel_clock_gating.h"
|
||||
|
|
@ -488,6 +489,14 @@ void intel_display_power_dc3co_compute(struct intel_atomic_state *state)
|
|||
if (crtc_state->has_sel_update)
|
||||
trigger |= DC3CO_TRIGGER_PSR2;
|
||||
|
||||
/*
|
||||
* Periodic AS SDP (skip frames) needs the AS SDP to keep flowing during
|
||||
* PR active, which is incompatible with DC3co. Keep DC3co disabled while
|
||||
* skip frames is enabled.
|
||||
*/
|
||||
if (intel_alpm_pr_as_sdp_skip_frames_enabled(intel_dp, crtc_state))
|
||||
trigger = DC3CO_TRIGGER_NONE;
|
||||
|
||||
done:
|
||||
intel_display_power_dc3co_update(display, trigger);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1759,6 +1759,44 @@ static const struct i915_power_well_desc_list wcl_power_wells[] = {
|
|||
I915_PW_DESCRIPTORS(wcl_power_wells_aux),
|
||||
};
|
||||
|
||||
I915_DECL_PW_DOMAINS(xe3plpd_pwdoms_dc_off,
|
||||
POWER_DOMAIN_DC_OFF,
|
||||
XE3LPD_PW_2_POWER_DOMAINS,
|
||||
XE3LPD_PW_C_POWER_DOMAINS,
|
||||
XE3LPD_PW_D_POWER_DOMAINS,
|
||||
POWER_DOMAIN_AUDIO_MMIO,
|
||||
POWER_DOMAIN_AUDIO_PLAYBACK,
|
||||
POWER_DOMAIN_AUX_A,
|
||||
POWER_DOMAIN_AUX_B,
|
||||
POWER_DOMAIN_AUX_USBC1,
|
||||
POWER_DOMAIN_AUX_USBC2,
|
||||
POWER_DOMAIN_AUX_USBC3,
|
||||
POWER_DOMAIN_AUX_USBC4,
|
||||
POWER_DOMAIN_AUX_TBT1,
|
||||
POWER_DOMAIN_AUX_TBT2,
|
||||
POWER_DOMAIN_AUX_TBT3,
|
||||
POWER_DOMAIN_AUX_TBT4,
|
||||
POWER_DOMAIN_INIT);
|
||||
|
||||
static const struct i915_power_well_desc xe3plpd_power_wells_dcoff[] = {
|
||||
{
|
||||
.instances = &I915_PW_INSTANCES(
|
||||
I915_PW("DC_off", &xe3plpd_pwdoms_dc_off,
|
||||
.id = SKL_DISP_DC_OFF),
|
||||
),
|
||||
.ops = &gen9_dc_off_power_well_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct i915_power_well_desc_list xe3plpd_power_wells[] = {
|
||||
I915_PW_DESCRIPTORS(i9xx_power_wells_always_on),
|
||||
I915_PW_DESCRIPTORS(icl_power_wells_pw_1),
|
||||
I915_PW_DESCRIPTORS(xe3plpd_power_wells_dcoff),
|
||||
I915_PW_DESCRIPTORS(xe3lpd_power_wells_main),
|
||||
I915_PW_DESCRIPTORS(xe2lpd_power_wells_pica),
|
||||
I915_PW_DESCRIPTORS(xelpdp_power_wells_aux),
|
||||
};
|
||||
|
||||
static void init_power_well_domains(const struct i915_power_well_instance *inst,
|
||||
struct i915_power_well *power_well)
|
||||
{
|
||||
|
|
@ -1865,7 +1903,9 @@ int intel_display_power_map_init(struct i915_power_domains *power_domains)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (DISPLAY_VERx100(display) == 3002)
|
||||
if (DISPLAY_VER(display) >= 35)
|
||||
return set_power_wells(power_domains, xe3plpd_power_wells);
|
||||
else if (DISPLAY_VERx100(display) == 3002)
|
||||
return set_power_wells(power_domains, wcl_power_wells);
|
||||
else if (DISPLAY_VER(display) >= 30)
|
||||
return set_power_wells(power_domains, xe3lpd_power_wells);
|
||||
|
|
|
|||
|
|
@ -46,6 +46,13 @@ bool intel_display_rpm_suspended(struct intel_display *display)
|
|||
return display->parent->rpm->suspended(display->drm);
|
||||
}
|
||||
|
||||
bool intel_display_rpm_pme_enabled(struct intel_display *display)
|
||||
{
|
||||
const struct intel_display_rpm_interface *rpm = display->parent->rpm;
|
||||
|
||||
return rpm->pme_enabled && rpm->pme_enabled(display->drm);
|
||||
}
|
||||
|
||||
void assert_display_rpm_held(struct intel_display *display)
|
||||
{
|
||||
display->parent->rpm->assert_held(display->drm);
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ void intel_display_rpm_put(struct intel_display *display, struct ref_tracker *wa
|
|||
|
||||
/* Only for special cases. */
|
||||
bool intel_display_rpm_suspended(struct intel_display *display);
|
||||
bool intel_display_rpm_pme_enabled(struct intel_display *display);
|
||||
|
||||
void assert_display_rpm_held(struct intel_display *display);
|
||||
void intel_display_rpm_assert_block(struct intel_display *display);
|
||||
|
|
|
|||
|
|
@ -41,10 +41,10 @@
|
|||
#include <drm/drm_panel.h>
|
||||
#include <drm/drm_rect.h>
|
||||
#include <drm/drm_vblank_work.h>
|
||||
#include <drm/intel/gtt_view_types.h>
|
||||
#include <drm/intel/i915_hdcp_interface.h>
|
||||
#include <uapi/drm/i915_drm.h>
|
||||
|
||||
#include "i915_gtt_view_types.h"
|
||||
#include "intel_bios.h"
|
||||
#include "intel_display.h"
|
||||
#include "intel_display_conversion.h"
|
||||
|
|
@ -111,7 +111,7 @@ struct intel_fb_view {
|
|||
* In the normal view the FB object's backing store sg list is used
|
||||
* directly and hence the remap information here is not used.
|
||||
*/
|
||||
struct i915_gtt_view gtt;
|
||||
struct intel_gtt_view gtt;
|
||||
|
||||
/*
|
||||
* The GTT view (gtt.type) specific information for each FB color
|
||||
|
|
@ -289,6 +289,9 @@ struct intel_encoder {
|
|||
*/
|
||||
enum icl_port_dpll_id (*port_pll_type)(struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *crtc_state);
|
||||
const struct intel_ddi_buf_trans *(*get_buf_trans_override)(struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *crtc_state,
|
||||
int *n_entries);
|
||||
const struct intel_ddi_buf_trans *(*get_buf_trans)(struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *crtc_state,
|
||||
int *n_entries);
|
||||
|
|
@ -683,6 +686,7 @@ struct intel_plane_state {
|
|||
enum drm_color_range color_range;
|
||||
enum drm_scaling_filter scaling_filter;
|
||||
struct drm_property_blob *ctm, *degamma_lut, *gamma_lut, *lut_3d;
|
||||
bool csc_ff_enable;
|
||||
} hw;
|
||||
|
||||
struct i915_vma *ggtt_vma;
|
||||
|
|
@ -1003,6 +1007,20 @@ struct intel_casf {
|
|||
bool enable;
|
||||
};
|
||||
|
||||
struct intel_dip {
|
||||
/*
|
||||
* DIP Transmission line, relative to the Vtotal.
|
||||
* The programmed transmit line is (Vtotal - value)
|
||||
*/
|
||||
u16 emp_as_sdp_tl;
|
||||
u16 gmp_sdp_tl;
|
||||
u16 pps_sdp_tl;
|
||||
u16 vsc_sdp_tl;
|
||||
u16 vsc_ext_sdp_tl;
|
||||
/* Common SDP Base transmission line (Xe3p_lpd+) */
|
||||
u16 cmn_sdp_tl;
|
||||
};
|
||||
|
||||
struct intel_crtc_state {
|
||||
/*
|
||||
* uapi (drm) state. This is the software state shown to userspace.
|
||||
|
|
@ -1311,6 +1329,8 @@ struct intel_crtc_state {
|
|||
struct drm_dp_as_sdp as_sdp;
|
||||
} infoframes;
|
||||
|
||||
struct intel_dip dip;
|
||||
|
||||
u8 eld[MAX_ELD_BYTES];
|
||||
|
||||
/* HDMI scrambling status */
|
||||
|
|
|
|||
|
|
@ -61,6 +61,8 @@
|
|||
#include "intel_cx0_phy.h"
|
||||
#include "intel_ddi.h"
|
||||
#include "intel_de.h"
|
||||
#include "intel_dip.h"
|
||||
#include "intel_dip_regs.h"
|
||||
#include "intel_display_driver.h"
|
||||
#include "intel_display_jiffies.h"
|
||||
#include "intel_display_utils.h"
|
||||
|
|
@ -3734,19 +3736,19 @@ static bool downstream_hpd_needs_d0(struct intel_dp *intel_dp)
|
|||
static int
|
||||
write_dsc_decompression_flag(struct drm_dp_aux *aux, u8 flag, bool set)
|
||||
{
|
||||
int err;
|
||||
int ret;
|
||||
u8 val;
|
||||
|
||||
err = drm_dp_dpcd_readb(aux, DP_DSC_ENABLE, &val);
|
||||
if (err < 0)
|
||||
return err;
|
||||
ret = drm_dp_dpcd_read_byte(aux, DP_DSC_ENABLE, &val);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (set)
|
||||
val |= flag;
|
||||
else
|
||||
val &= ~flag;
|
||||
|
||||
return drm_dp_dpcd_writeb(aux, DP_DSC_ENABLE, val);
|
||||
return drm_dp_dpcd_write_byte(aux, DP_DSC_ENABLE, val);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -3910,6 +3912,7 @@ intel_dp_init_source_oui(struct intel_dp *intel_dp)
|
|||
struct intel_display *display = to_intel_display(intel_dp);
|
||||
u8 oui[] = { 0x00, 0xaa, 0x01 };
|
||||
u8 buf[3] = {};
|
||||
int ret;
|
||||
|
||||
if (READ_ONCE(intel_dp->oui_valid))
|
||||
return;
|
||||
|
|
@ -3920,8 +3923,9 @@ intel_dp_init_source_oui(struct intel_dp *intel_dp)
|
|||
* During driver init, we want to be careful and avoid changing the source OUI if it's
|
||||
* already set to what we want, so as to avoid clearing any state by accident
|
||||
*/
|
||||
if (drm_dp_dpcd_read(&intel_dp->aux, DP_SOURCE_OUI, buf, sizeof(buf)) < 0)
|
||||
drm_dbg_kms(display->drm, "Failed to read source OUI\n");
|
||||
ret = drm_dp_dpcd_read_data(&intel_dp->aux, DP_SOURCE_OUI, buf, sizeof(buf));
|
||||
if (ret < 0)
|
||||
drm_dbg_kms(display->drm, "Failed to read source OUI (%pe)\n", ERR_PTR(ret));
|
||||
|
||||
if (memcmp(oui, buf, sizeof(oui)) == 0) {
|
||||
/* Assume the OUI was written now. */
|
||||
|
|
@ -3929,8 +3933,9 @@ intel_dp_init_source_oui(struct intel_dp *intel_dp)
|
|||
return;
|
||||
}
|
||||
|
||||
if (drm_dp_dpcd_write(&intel_dp->aux, DP_SOURCE_OUI, oui, sizeof(oui)) < 0) {
|
||||
drm_dbg_kms(display->drm, "Failed to write source OUI\n");
|
||||
ret = drm_dp_dpcd_write_data(&intel_dp->aux, DP_SOURCE_OUI, oui, sizeof(oui));
|
||||
if (ret < 0) {
|
||||
drm_dbg_kms(display->drm, "Failed to write source OUI (%pe)\n", ERR_PTR(ret));
|
||||
WRITE_ONCE(intel_dp->oui_valid, false);
|
||||
}
|
||||
|
||||
|
|
@ -3971,7 +3976,7 @@ void intel_dp_set_power(struct intel_dp *intel_dp, u8 mode)
|
|||
if (downstream_hpd_needs_d0(intel_dp))
|
||||
return;
|
||||
|
||||
ret = drm_dp_dpcd_writeb(&intel_dp->aux, DP_SET_POWER, mode);
|
||||
ret = drm_dp_dpcd_write_byte(&intel_dp->aux, DP_SET_POWER, mode);
|
||||
} else {
|
||||
struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
|
||||
|
||||
|
|
@ -3985,21 +3990,21 @@ void intel_dp_set_power(struct intel_dp *intel_dp, u8 mode)
|
|||
* time to wake up.
|
||||
*/
|
||||
for (i = 0; i < 3; i++) {
|
||||
ret = drm_dp_dpcd_writeb(&intel_dp->aux, DP_SET_POWER, mode);
|
||||
if (ret == 1)
|
||||
ret = drm_dp_dpcd_write_byte(&intel_dp->aux, DP_SET_POWER, mode);
|
||||
if (!ret)
|
||||
break;
|
||||
msleep(1);
|
||||
}
|
||||
|
||||
if (ret == 1 && intel_lspcon_active(dig_port))
|
||||
if (!ret && intel_lspcon_active(dig_port))
|
||||
intel_lspcon_wait_pcon_mode(dig_port);
|
||||
}
|
||||
|
||||
if (ret != 1)
|
||||
if (ret < 0)
|
||||
drm_dbg_kms(display->drm,
|
||||
"[ENCODER:%d:%s] Set power to %s failed\n",
|
||||
"[ENCODER:%d:%s] Set power to %s failed (%pe)\n",
|
||||
encoder->base.base.id, encoder->base.name,
|
||||
mode == DP_SET_POWER_D0 ? "D0" : "D3");
|
||||
mode == DP_SET_POWER_D0 ? "D0" : "D3", ERR_PTR(ret));
|
||||
}
|
||||
|
||||
static bool
|
||||
|
|
@ -4086,6 +4091,7 @@ bool intel_dp_initial_fastset_check(struct intel_encoder *encoder,
|
|||
static void intel_dp_get_pcon_dsc_cap(struct intel_dp *intel_dp)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(intel_dp);
|
||||
int ret;
|
||||
|
||||
/* Clear the cached register set to avoid using stale values */
|
||||
|
||||
|
|
@ -4094,11 +4100,12 @@ static void intel_dp_get_pcon_dsc_cap(struct intel_dp *intel_dp)
|
|||
if (!drm_dp_is_branch(intel_dp->dpcd))
|
||||
return;
|
||||
|
||||
if (drm_dp_dpcd_read(&intel_dp->aux, DP_PCON_DSC_ENCODER,
|
||||
intel_dp->pcon_dsc_dpcd,
|
||||
sizeof(intel_dp->pcon_dsc_dpcd)) < 0)
|
||||
drm_err(display->drm, "Failed to read DPCD register 0x%x\n",
|
||||
DP_PCON_DSC_ENCODER);
|
||||
ret = drm_dp_dpcd_read_data(&intel_dp->aux, DP_PCON_DSC_ENCODER,
|
||||
intel_dp->pcon_dsc_dpcd,
|
||||
sizeof(intel_dp->pcon_dsc_dpcd));
|
||||
if (ret < 0)
|
||||
drm_err(display->drm, "Failed to read DPCD register 0x%x (%pe)\n",
|
||||
DP_PCON_DSC_ENCODER, ERR_PTR(ret));
|
||||
|
||||
drm_dbg_kms(display->drm, "PCON ENCODER DSC DPCD: %*ph\n",
|
||||
(int)sizeof(intel_dp->pcon_dsc_dpcd), intel_dp->pcon_dsc_dpcd);
|
||||
|
|
@ -4255,13 +4262,13 @@ int intel_dp_pcon_set_tmds_mode(struct intel_dp *intel_dp)
|
|||
/* Set PCON source control mode */
|
||||
buf |= DP_PCON_ENABLE_SOURCE_CTL_MODE;
|
||||
|
||||
ret = drm_dp_dpcd_writeb(&intel_dp->aux, DP_PCON_HDMI_LINK_CONFIG_1, buf);
|
||||
ret = drm_dp_dpcd_write_byte(&intel_dp->aux, DP_PCON_HDMI_LINK_CONFIG_1, buf);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Set HDMI LINK ENABLE */
|
||||
buf |= DP_PCON_ENABLE_HDMI_LINK;
|
||||
ret = drm_dp_dpcd_writeb(&intel_dp->aux, DP_PCON_HDMI_LINK_CONFIG_1, buf);
|
||||
ret = drm_dp_dpcd_write_byte(&intel_dp->aux, DP_PCON_HDMI_LINK_CONFIG_1, buf);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
|
@ -4407,6 +4414,7 @@ void intel_dp_configure_protocol_converter(struct intel_dp *intel_dp,
|
|||
bool ycbcr444_to_420 = false;
|
||||
bool rgb_to_ycbcr = false;
|
||||
u8 tmp;
|
||||
int ret;
|
||||
|
||||
if (intel_dp->dpcd[DP_DPCD_REV] < 0x13)
|
||||
return;
|
||||
|
|
@ -4416,11 +4424,13 @@ void intel_dp_configure_protocol_converter(struct intel_dp *intel_dp,
|
|||
|
||||
tmp = intel_dp_has_hdmi_sink(intel_dp) ? DP_HDMI_DVI_OUTPUT_CONFIG : 0;
|
||||
|
||||
if (drm_dp_dpcd_writeb(&intel_dp->aux,
|
||||
DP_PROTOCOL_CONVERTER_CONTROL_0, tmp) != 1)
|
||||
ret = drm_dp_dpcd_write_byte(&intel_dp->aux,
|
||||
DP_PROTOCOL_CONVERTER_CONTROL_0, tmp);
|
||||
if (ret < 0)
|
||||
drm_dbg_kms(display->drm,
|
||||
"Failed to %s protocol converter HDMI mode\n",
|
||||
str_enable_disable(intel_dp_has_hdmi_sink(intel_dp)));
|
||||
"Failed to %s protocol converter HDMI mode (%pe)\n",
|
||||
str_enable_disable(intel_dp_has_hdmi_sink(intel_dp)),
|
||||
ERR_PTR(ret));
|
||||
|
||||
if (crtc_state->sink_format == INTEL_OUTPUT_FORMAT_YCBCR420) {
|
||||
switch (crtc_state->output_format) {
|
||||
|
|
@ -4452,26 +4462,29 @@ void intel_dp_configure_protocol_converter(struct intel_dp *intel_dp,
|
|||
|
||||
tmp = ycbcr444_to_420 ? DP_CONVERSION_TO_YCBCR420_ENABLE : 0;
|
||||
|
||||
if (drm_dp_dpcd_writeb(&intel_dp->aux,
|
||||
DP_PROTOCOL_CONVERTER_CONTROL_1, tmp) != 1)
|
||||
ret = drm_dp_dpcd_write_byte(&intel_dp->aux,
|
||||
DP_PROTOCOL_CONVERTER_CONTROL_1, tmp);
|
||||
if (ret < 0)
|
||||
drm_dbg_kms(display->drm,
|
||||
"Failed to %s protocol converter YCbCr 4:2:0 conversion mode\n",
|
||||
str_enable_disable(intel_dp->dfp.ycbcr_444_to_420));
|
||||
"Failed to %s protocol converter YCbCr 4:2:0 conversion mode (%pe)\n",
|
||||
str_enable_disable(intel_dp->dfp.ycbcr_444_to_420),
|
||||
ERR_PTR(ret));
|
||||
|
||||
tmp = rgb_to_ycbcr ? DP_CONVERSION_BT709_RGB_YCBCR_ENABLE : 0;
|
||||
|
||||
if (drm_dp_pcon_convert_rgb_to_ycbcr(&intel_dp->aux, tmp) < 0)
|
||||
ret = drm_dp_pcon_convert_rgb_to_ycbcr(&intel_dp->aux, tmp);
|
||||
if (ret < 0)
|
||||
drm_dbg_kms(display->drm,
|
||||
"Failed to %s protocol converter RGB->YCbCr conversion mode\n",
|
||||
str_enable_disable(tmp));
|
||||
"Failed to %s protocol converter RGB->YCbCr conversion mode (%pe)\n",
|
||||
str_enable_disable(tmp), ERR_PTR(ret));
|
||||
}
|
||||
|
||||
static u8 intel_dp_read_dprx_feature_enum(struct intel_dp *intel_dp)
|
||||
{
|
||||
u8 dprx = 0;
|
||||
|
||||
drm_dp_dpcd_read_data(&intel_dp->aux, DP_DPRX_FEATURE_ENUMERATION_LIST,
|
||||
&dprx, sizeof(dprx));
|
||||
drm_dp_dpcd_read_byte(&intel_dp->aux, DP_DPRX_FEATURE_ENUMERATION_LIST, &dprx);
|
||||
|
||||
return dprx;
|
||||
}
|
||||
|
||||
|
|
@ -4490,9 +4503,8 @@ static int intel_dp_read_dsc_dpcd(struct drm_dp_aux *aux,
|
|||
{
|
||||
int ret;
|
||||
|
||||
ret = drm_dp_dpcd_read_data(aux, DP_DSC_SUPPORT, dsc_dpcd,
|
||||
DP_DSC_RECEIVER_CAP_SIZE);
|
||||
if (ret) {
|
||||
ret = drm_dp_dpcd_read_data(aux, DP_DSC_SUPPORT, dsc_dpcd, DP_DSC_RECEIVER_CAP_SIZE);
|
||||
if (ret < 0) {
|
||||
drm_dbg_kms(aux->drm_dev,
|
||||
"Could not read DSC DPCD register 0x%x Error: %pe\n",
|
||||
DP_DSC_SUPPORT, ERR_PTR(ret));
|
||||
|
|
@ -4508,7 +4520,7 @@ static int intel_dp_read_dsc_dpcd(struct drm_dp_aux *aux,
|
|||
static void init_dsc_overall_throughput_limits(struct intel_connector *connector, bool is_branch)
|
||||
{
|
||||
u8 branch_caps[DP_DSC_BRANCH_CAP_SIZE];
|
||||
int line_width;
|
||||
int line_width, ret;
|
||||
|
||||
connector->dp.dsc_branch_caps.overall_throughput.rgb_yuv444 = INT_MAX;
|
||||
connector->dp.dsc_branch_caps.overall_throughput.yuv422_420 = INT_MAX;
|
||||
|
|
@ -4517,9 +4529,10 @@ static void init_dsc_overall_throughput_limits(struct intel_connector *connector
|
|||
if (!is_branch)
|
||||
return;
|
||||
|
||||
if (drm_dp_dpcd_read_data(connector->dp.dsc_decompression_aux,
|
||||
DP_DSC_BRANCH_OVERALL_THROUGHPUT_0, branch_caps,
|
||||
sizeof(branch_caps)) != 0)
|
||||
ret = drm_dp_dpcd_read_data(connector->dp.dsc_decompression_aux,
|
||||
DP_DSC_BRANCH_OVERALL_THROUGHPUT_0, branch_caps,
|
||||
sizeof(branch_caps));
|
||||
if (ret < 0)
|
||||
return;
|
||||
|
||||
connector->dp.dsc_branch_caps.overall_throughput.rgb_yuv444 =
|
||||
|
|
@ -4537,6 +4550,7 @@ void intel_dp_get_dsc_sink_cap(u8 dpcd_rev,
|
|||
struct intel_connector *connector)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(connector);
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Clear the cached register set to avoid using stale values
|
||||
|
|
@ -4553,13 +4567,16 @@ void intel_dp_get_dsc_sink_cap(u8 dpcd_rev,
|
|||
if (dpcd_rev < DP_DPCD_REV_14)
|
||||
return;
|
||||
|
||||
if (intel_dp_read_dsc_dpcd(connector->dp.dsc_decompression_aux,
|
||||
connector->dp.dsc_dpcd) < 0)
|
||||
ret = intel_dp_read_dsc_dpcd(connector->dp.dsc_decompression_aux,
|
||||
connector->dp.dsc_dpcd);
|
||||
if (ret < 0)
|
||||
return;
|
||||
|
||||
if (drm_dp_dpcd_readb(connector->dp.dsc_decompression_aux, DP_FEC_CAPABILITY,
|
||||
&connector->dp.fec_capability) < 0) {
|
||||
drm_dbg_kms(display->drm, "Could not read FEC DPCD register\n");
|
||||
ret = drm_dp_dpcd_read_byte(connector->dp.dsc_decompression_aux, DP_FEC_CAPABILITY,
|
||||
&connector->dp.fec_capability);
|
||||
if (ret < 0) {
|
||||
drm_dbg_kms(display->drm, "Could not read FEC DPCD register (%pe)\n",
|
||||
ERR_PTR(ret));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -4668,13 +4685,15 @@ static void intel_edp_mso_init(struct intel_dp *intel_dp)
|
|||
struct intel_display *display = to_intel_display(intel_dp);
|
||||
struct intel_connector *connector = intel_dp->attached_connector;
|
||||
struct drm_display_info *info = &connector->base.display_info;
|
||||
int ret;
|
||||
u8 mso;
|
||||
|
||||
if (intel_dp->edp_dpcd[0] < DP_EDP_14)
|
||||
return;
|
||||
|
||||
if (drm_dp_dpcd_readb(&intel_dp->aux, DP_EDP_MSO_LINK_CAPABILITIES, &mso) != 1) {
|
||||
drm_err(display->drm, "Failed to read MSO cap\n");
|
||||
ret = drm_dp_dpcd_read_byte(&intel_dp->aux, DP_EDP_MSO_LINK_CAPABILITIES, &mso);
|
||||
if (ret < 0) {
|
||||
drm_err(display->drm, "Failed to read MSO cap (%pe)\n", ERR_PTR(ret));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -4779,6 +4798,38 @@ intel_edp_set_sink_rates(struct intel_dp *intel_dp)
|
|||
intel_edp_set_data_override_rates(intel_dp);
|
||||
}
|
||||
|
||||
static void intel_edp_wake_sink(struct intel_dp *intel_dp)
|
||||
{
|
||||
u8 value = 0;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Read the current sink power state. drm_dp_dpcd_read_byte() already
|
||||
* retries the AUX transaction internally, so a single read suffices.
|
||||
* First commercial eDP panels are Ver1.0 or 1.1, on which DPCD
|
||||
* DP_SET_POWER is supported.
|
||||
*/
|
||||
ret = drm_dp_dpcd_read_byte(&intel_dp->aux, DP_SET_POWER, &value);
|
||||
|
||||
/*
|
||||
* If the AUX read failed the sink may be asleep and not responding,
|
||||
* or it read back D3; in either case wake it up to D0.
|
||||
* In case of AUX read failure which is usually a POR case, the
|
||||
* remaining bits of register 0x600 is set to '0' on POR. So a bare
|
||||
* write should be fine.
|
||||
*/
|
||||
if (ret < 0 || value == DP_SET_POWER_D3) {
|
||||
value &= ~DP_SET_POWER_MASK;
|
||||
value |= DP_SET_POWER_D0;
|
||||
drm_dp_dpcd_write_byte(&intel_dp->aux, DP_SET_POWER,
|
||||
value);
|
||||
/* After setting to D0 need a min of 1ms to wake (Spec DP2.1 sec 2.3.1.2) */
|
||||
fsleep(1000);
|
||||
drm_dp_dpcd_write_byte(&intel_dp->aux, DP_SET_POWER,
|
||||
value);
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
intel_edp_init_dpcd(struct intel_dp *intel_dp, struct intel_connector *connector)
|
||||
{
|
||||
|
|
@ -4789,6 +4840,12 @@ intel_edp_init_dpcd(struct intel_dp *intel_dp, struct intel_connector *connector
|
|||
/* this function is meant to be called only once */
|
||||
drm_WARN_ON(display->drm, intel_dp->dpcd[DP_DPCD_REV] != 0);
|
||||
|
||||
/*
|
||||
* Spec DP2.1 Section 3.5.2.16 page 966.
|
||||
* Also if sink is asleep, this will wake the sink.
|
||||
*/
|
||||
intel_edp_wake_sink(intel_dp);
|
||||
|
||||
if (drm_dp_read_dpcd_caps(&intel_dp->aux, intel_dp->dpcd) != 0)
|
||||
return false;
|
||||
|
||||
|
|
@ -4813,9 +4870,9 @@ intel_edp_init_dpcd(struct intel_dp *intel_dp, struct intel_connector *connector
|
|||
* method). The display control registers should read zero if they're
|
||||
* not supported anyway.
|
||||
*/
|
||||
if (drm_dp_dpcd_read(&intel_dp->aux, DP_EDP_DPCD_REV,
|
||||
intel_dp->edp_dpcd, sizeof(intel_dp->edp_dpcd)) ==
|
||||
sizeof(intel_dp->edp_dpcd)) {
|
||||
ret = drm_dp_dpcd_read_data(&intel_dp->aux, DP_EDP_DPCD_REV,
|
||||
intel_dp->edp_dpcd, sizeof(intel_dp->edp_dpcd));
|
||||
if (!ret) {
|
||||
drm_dbg_kms(display->drm, "eDP DPCD: %*ph\n",
|
||||
(int)sizeof(intel_dp->edp_dpcd),
|
||||
intel_dp->edp_dpcd);
|
||||
|
|
@ -5044,6 +5101,7 @@ static bool
|
|||
intel_dp_get_sink_irq_esi(struct intel_dp *intel_dp, u8 *esi)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(intel_dp);
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Display WA for HSD #13013007775: mtl/arl/lnl
|
||||
|
|
@ -5052,24 +5110,30 @@ intel_dp_get_sink_irq_esi(struct intel_dp *intel_dp, u8 *esi)
|
|||
* inadvertently.
|
||||
*/
|
||||
if (IS_DISPLAY_VER(display, 14, 20) && !display->platform.battlemage) {
|
||||
if (drm_dp_dpcd_read(&intel_dp->aux, DP_SINK_COUNT_ESI, esi, 3) != 3)
|
||||
ret = drm_dp_dpcd_read_data(&intel_dp->aux, DP_SINK_COUNT_ESI, esi, 3);
|
||||
if (ret < 0)
|
||||
return false;
|
||||
|
||||
/* DP_SINK_COUNT_ESI + 3 == DP_LINK_SERVICE_IRQ_VECTOR_ESI0 */
|
||||
return drm_dp_dpcd_readb(&intel_dp->aux, DP_LINK_SERVICE_IRQ_VECTOR_ESI0,
|
||||
&esi[3]) == 1;
|
||||
ret = drm_dp_dpcd_read_byte(&intel_dp->aux, DP_LINK_SERVICE_IRQ_VECTOR_ESI0,
|
||||
&esi[3]);
|
||||
return ret == 0;
|
||||
}
|
||||
|
||||
return drm_dp_dpcd_read(&intel_dp->aux, DP_SINK_COUNT_ESI, esi, 4) == 4;
|
||||
ret = drm_dp_dpcd_read_data(&intel_dp->aux, DP_SINK_COUNT_ESI, esi, 4);
|
||||
|
||||
return ret == 0;
|
||||
}
|
||||
|
||||
static bool intel_dp_ack_sink_irq_esi(struct intel_dp *intel_dp, u8 esi[4])
|
||||
{
|
||||
int retry;
|
||||
int ret;
|
||||
|
||||
for (retry = 0; retry < 3; retry++) {
|
||||
if (drm_dp_dpcd_write(&intel_dp->aux, DP_SINK_COUNT_ESI + 1,
|
||||
&esi[1], 3) == 3)
|
||||
ret = drm_dp_dpcd_write_data(&intel_dp->aux, DP_SINK_COUNT_ESI + 1,
|
||||
&esi[1], 3);
|
||||
if (!ret)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -5079,20 +5143,24 @@ static bool intel_dp_ack_sink_irq_esi(struct intel_dp *intel_dp, u8 esi[4])
|
|||
/* Return %true if reading the ESI vector succeeded, %false otherwise. */
|
||||
static bool intel_dp_get_sink_irq_esi_sst(struct intel_dp *intel_dp, u8 esi[4])
|
||||
{
|
||||
int ret;
|
||||
|
||||
memset(esi, 0, 4);
|
||||
|
||||
/*
|
||||
* TODO: For DP_DPCD_REV >= 0x12 read
|
||||
* DP_SINK_COUNT_ESI and DP_DEVICE_SERVICE_IRQ_VECTOR_ESI0.
|
||||
*/
|
||||
if (drm_dp_dpcd_read_data(&intel_dp->aux, DP_SINK_COUNT, esi, 2) != 0)
|
||||
ret = drm_dp_dpcd_read_data(&intel_dp->aux, DP_SINK_COUNT, esi, 2);
|
||||
if (ret < 0)
|
||||
return false;
|
||||
|
||||
if (intel_dp->dpcd[DP_DPCD_REV] < DP_DPCD_REV_12)
|
||||
return true;
|
||||
|
||||
/* TODO: Read DP_DEVICE_SERVICE_IRQ_VECTOR_ESI1 as well */
|
||||
if (drm_dp_dpcd_read_byte(&intel_dp->aux, DP_LINK_SERVICE_IRQ_VECTOR_ESI0, &esi[3]) != 0)
|
||||
ret = drm_dp_dpcd_read_byte(&intel_dp->aux, DP_LINK_SERVICE_IRQ_VECTOR_ESI0, &esi[3]);
|
||||
if (ret < 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
|
@ -5101,18 +5169,22 @@ static bool intel_dp_get_sink_irq_esi_sst(struct intel_dp *intel_dp, u8 esi[4])
|
|||
/* Return %true if acking the ESI vector IRQ events succeeded, %false otherwise. */
|
||||
static bool intel_dp_ack_sink_irq_esi_sst(struct intel_dp *intel_dp, u8 esi[4])
|
||||
{
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* TODO: For DP_DPCD_REV >= 0x12 write
|
||||
* DP_DEVICE_SERVICE_IRQ_VECTOR_ESI0
|
||||
*/
|
||||
if (drm_dp_dpcd_write_byte(&intel_dp->aux, DP_DEVICE_SERVICE_IRQ_VECTOR, esi[1]) != 0)
|
||||
ret = drm_dp_dpcd_write_byte(&intel_dp->aux, DP_DEVICE_SERVICE_IRQ_VECTOR, esi[1]);
|
||||
if (ret < 0)
|
||||
return false;
|
||||
|
||||
if (intel_dp->dpcd[DP_DPCD_REV] < DP_DPCD_REV_12)
|
||||
return true;
|
||||
|
||||
/* TODO: Read DP_DEVICE_SERVICE_IRQ_VECTOR_ESI1 as well */
|
||||
if (drm_dp_dpcd_write_byte(&intel_dp->aux, DP_LINK_SERVICE_IRQ_VECTOR_ESI0, esi[3]) != 0)
|
||||
ret = drm_dp_dpcd_write_byte(&intel_dp->aux, DP_LINK_SERVICE_IRQ_VECTOR_ESI0, esi[3]);
|
||||
if (ret < 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
|
@ -5435,11 +5507,15 @@ static int intel_dp_vsc_sdp_unpack(struct drm_dp_vsc_sdp *vsc,
|
|||
* VSC SDP supporting 3D stereo + Panel Replay.
|
||||
*/
|
||||
return 0;
|
||||
} else if (sdp->sdp_header.HB2 == 0x5 && sdp->sdp_header.HB3 == 0x13) {
|
||||
} else if ((sdp->sdp_header.HB2 == 0x5 || sdp->sdp_header.HB2 == 0x7) &&
|
||||
sdp->sdp_header.HB3 == 0x13) {
|
||||
/*
|
||||
* - HB2 = 0x5, HB3 = 0x13
|
||||
* VSC SDP supporting 3D stereo + PSR2 + Pixel Encoding/Colorimetry
|
||||
* Format.
|
||||
* - HB2 = 0x7, HB3 = 0x13
|
||||
* VSC SDP supporting 3D stereo + Panel Replay + Pixel Encoding/Colorimetry
|
||||
* Format.
|
||||
*/
|
||||
vsc->pixelformat = (sdp->db[16] >> 4) & 0xf;
|
||||
vsc->colorimetry = sdp->db[16] & 0xf;
|
||||
|
|
@ -5706,14 +5782,17 @@ intel_dp_handle_hdmi_link_status_change(struct intel_dp *intel_dp)
|
|||
{
|
||||
bool is_active;
|
||||
u8 buf = 0;
|
||||
int ret;
|
||||
|
||||
is_active = drm_dp_pcon_hdmi_link_active(&intel_dp->aux);
|
||||
if (intel_dp->frl.is_trained && !is_active) {
|
||||
if (drm_dp_dpcd_readb(&intel_dp->aux, DP_PCON_HDMI_LINK_CONFIG_1, &buf) < 0)
|
||||
ret = drm_dp_dpcd_read_byte(&intel_dp->aux, DP_PCON_HDMI_LINK_CONFIG_1, &buf);
|
||||
if (ret < 0)
|
||||
return;
|
||||
|
||||
buf &= ~DP_PCON_ENABLE_HDMI_LINK;
|
||||
if (drm_dp_dpcd_writeb(&intel_dp->aux, DP_PCON_HDMI_LINK_CONFIG_1, buf) < 0)
|
||||
ret = drm_dp_dpcd_write_byte(&intel_dp->aux, DP_PCON_HDMI_LINK_CONFIG_1, buf);
|
||||
if (ret < 0)
|
||||
return;
|
||||
|
||||
drm_dp_pcon_hdmi_frl_link_error_count(&intel_dp->aux, &intel_dp->attached_connector->base);
|
||||
|
|
@ -6218,6 +6297,7 @@ static bool
|
|||
intel_dp_sink_supports_as_sdp_v2(struct intel_dp *intel_dp)
|
||||
{
|
||||
u8 rx_features;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* The DP spec does not explicitly provide the AS SDP v2 capability.
|
||||
|
|
@ -6240,9 +6320,10 @@ intel_dp_sink_supports_as_sdp_v2(struct intel_dp *intel_dp)
|
|||
* support from Display ID.
|
||||
*/
|
||||
|
||||
if (drm_dp_dpcd_read_byte(&intel_dp->aux,
|
||||
DP_DPRX_FEATURE_ENUMERATION_LIST_CONT_1,
|
||||
&rx_features) == 1) {
|
||||
ret = drm_dp_dpcd_read_byte(&intel_dp->aux,
|
||||
DP_DPRX_FEATURE_ENUMERATION_LIST_CONT_1,
|
||||
&rx_features);
|
||||
if (!ret) {
|
||||
if (rx_features & DP_AS_SDP_FAVT_PAYLOAD_FIELDS_PARSING_SUPPORTED)
|
||||
return true;
|
||||
}
|
||||
|
|
@ -7324,6 +7405,8 @@ int intel_dp_sdp_compute_config_late(struct intel_crtc_state *crtc_state)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
intel_dip_sdp_tl_compute_config_late(crtc_state);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -7345,9 +7428,58 @@ int intel_dp_compute_config_late(struct intel_encoder *encoder,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
int intel_dp_get_lines_for_cmn_sdp_tl(u32 type)
|
||||
{
|
||||
u32 stagger_val;
|
||||
|
||||
/*
|
||||
* Since we are using default stagger values similar to the case
|
||||
* where CMN SDP TL is not set, the different SDP transmission
|
||||
* lines are:
|
||||
* base : 2nd line of delayed vblank:
|
||||
* GMP : 2 + GMP_STAGGER
|
||||
* VSC_EXT: 2 + VSC_EXT_STAGGER
|
||||
* VSC : 2
|
||||
* PPS : 2 + PPS_STAGGER
|
||||
*
|
||||
* SDP Setup = 1 + MAX(GMP, VSC_EXT, VSC, PPS setup lines)
|
||||
*
|
||||
* For EMP_AS_SDP_TL guardband should be more than vrr.vsync_start.
|
||||
*/
|
||||
|
||||
switch (type) {
|
||||
case DP_SDP_VSC_EXT_VESA:
|
||||
case DP_SDP_VSC_EXT_CEA:
|
||||
stagger_val = VSC_EXT_STAGGER_DEFAULT;
|
||||
break;
|
||||
case HDMI_PACKET_TYPE_GAMUT_METADATA:
|
||||
stagger_val = GMP_STAGGER_DEFAULT;
|
||||
break;
|
||||
case DP_SDP_PPS:
|
||||
stagger_val = PPS_STAGGER_DEFAULT;
|
||||
break;
|
||||
case DP_SDP_VSC:
|
||||
stagger_val = 0;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1 + 2 + stagger_val;
|
||||
}
|
||||
|
||||
static
|
||||
int intel_dp_get_lines_for_sdp(const struct intel_crtc_state *crtc_state, u32 type)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(crtc_state);
|
||||
|
||||
if (type == DP_SDP_ADAPTIVE_SYNC)
|
||||
return crtc_state->vrr.vsync_start + 1;
|
||||
|
||||
if (HAS_COMMON_SDP_TL(display))
|
||||
return intel_dp_get_lines_for_cmn_sdp_tl(type);
|
||||
|
||||
switch (type) {
|
||||
case DP_SDP_VSC_EXT_VESA:
|
||||
case DP_SDP_VSC_EXT_CEA:
|
||||
|
|
@ -7356,8 +7488,8 @@ int intel_dp_get_lines_for_sdp(const struct intel_crtc_state *crtc_state, u32 ty
|
|||
return 8;
|
||||
case DP_SDP_PPS:
|
||||
return 7;
|
||||
case DP_SDP_ADAPTIVE_SYNC:
|
||||
return crtc_state->vrr.vsync_start + 1;
|
||||
case DP_SDP_VSC:
|
||||
return 3;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -7387,6 +7519,11 @@ int intel_dp_sdp_min_guardband(const struct intel_crtc_state *crtc_state,
|
|||
sdp_guardband = max(sdp_guardband,
|
||||
intel_dp_get_lines_for_sdp(crtc_state, DP_SDP_ADAPTIVE_SYNC));
|
||||
|
||||
if (crtc_state->infoframes.enable &
|
||||
intel_hdmi_infoframe_enable(DP_SDP_VSC))
|
||||
sdp_guardband = max(sdp_guardband,
|
||||
intel_dp_get_lines_for_sdp(crtc_state, DP_SDP_VSC));
|
||||
|
||||
return sdp_guardband;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -120,8 +120,8 @@ intel_dp_aux_supports_hdr_backlight(struct intel_connector *connector)
|
|||
|
||||
intel_dp_wait_source_oui(intel_dp);
|
||||
|
||||
ret = drm_dp_dpcd_read(aux, INTEL_EDP_HDR_TCON_CAP0, tcon_cap, sizeof(tcon_cap));
|
||||
if (ret != sizeof(tcon_cap))
|
||||
ret = drm_dp_dpcd_read_data(aux, INTEL_EDP_HDR_TCON_CAP0, tcon_cap, sizeof(tcon_cap));
|
||||
if (ret < 0)
|
||||
return false;
|
||||
|
||||
drm_dbg_kms(display->drm,
|
||||
|
|
@ -178,11 +178,13 @@ intel_dp_aux_hdr_get_backlight(struct intel_connector *connector, enum pipe pipe
|
|||
struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder);
|
||||
u8 tmp;
|
||||
u8 buf[2] = {};
|
||||
int ret;
|
||||
|
||||
if (drm_dp_dpcd_readb(&intel_dp->aux, INTEL_EDP_HDR_GETSET_CTRL_PARAMS, &tmp) != 1) {
|
||||
ret = drm_dp_dpcd_read_byte(&intel_dp->aux, INTEL_EDP_HDR_GETSET_CTRL_PARAMS, &tmp);
|
||||
if (ret < 0) {
|
||||
drm_err(display->drm,
|
||||
"[CONNECTOR:%d:%s] Failed to read current backlight mode from DPCD\n",
|
||||
connector->base.base.id, connector->base.name);
|
||||
"[CONNECTOR:%d:%s] Failed to read current backlight mode from DPCD (%pe)\n",
|
||||
connector->base.base.id, connector->base.name, ERR_PTR(ret));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -197,11 +199,12 @@ intel_dp_aux_hdr_get_backlight(struct intel_connector *connector, enum pipe pipe
|
|||
return panel->backlight.max;
|
||||
}
|
||||
|
||||
if (drm_dp_dpcd_read(&intel_dp->aux, INTEL_EDP_BRIGHTNESS_NITS_LSB, buf,
|
||||
sizeof(buf)) != sizeof(buf)) {
|
||||
ret = drm_dp_dpcd_read_data(&intel_dp->aux, INTEL_EDP_BRIGHTNESS_NITS_LSB, buf,
|
||||
sizeof(buf));
|
||||
if (ret < 0) {
|
||||
drm_err(display->drm,
|
||||
"[CONNECTOR:%d:%s] Failed to read brightness from DPCD\n",
|
||||
connector->base.base.id, connector->base.name);
|
||||
"[CONNECTOR:%d:%s] Failed to read brightness from DPCD (%pe)\n",
|
||||
connector->base.base.id, connector->base.name, ERR_PTR(ret));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -215,14 +218,16 @@ intel_dp_aux_hdr_set_aux_backlight(const struct drm_connector_state *conn_state,
|
|||
struct drm_device *dev = connector->base.dev;
|
||||
struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder);
|
||||
u8 buf[4] = {};
|
||||
int ret;
|
||||
|
||||
buf[0] = level & 0xFF;
|
||||
buf[1] = (level & 0xFF00) >> 8;
|
||||
|
||||
if (drm_dp_dpcd_write(&intel_dp->aux, INTEL_EDP_BRIGHTNESS_NITS_LSB, buf,
|
||||
sizeof(buf)) != sizeof(buf))
|
||||
drm_err(dev, "[CONNECTOR:%d:%s] Failed to write brightness level to DPCD\n",
|
||||
connector->base.base.id, connector->base.name);
|
||||
ret = drm_dp_dpcd_write_data(&intel_dp->aux, INTEL_EDP_BRIGHTNESS_NITS_LSB, buf,
|
||||
sizeof(buf));
|
||||
if (ret < 0)
|
||||
drm_err(dev, "[CONNECTOR:%d:%s] Failed to write brightness level to DPCD (%pe)\n",
|
||||
connector->base.base.id, connector->base.name, ERR_PTR(ret));
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -258,13 +263,12 @@ intel_dp_aux_write_content_luminance(struct intel_connector *connector,
|
|||
buf[2] = hdr_metadata->hdmi_metadata_type1.max_fall & 0xFF;
|
||||
buf[3] = (hdr_metadata->hdmi_metadata_type1.max_fall & 0xFF00) >> 8;
|
||||
|
||||
ret = drm_dp_dpcd_write(&intel_dp->aux,
|
||||
INTEL_EDP_HDR_CONTENT_LUMINANCE,
|
||||
buf, sizeof(buf));
|
||||
ret = drm_dp_dpcd_write_data(&intel_dp->aux,
|
||||
INTEL_EDP_HDR_CONTENT_LUMINANCE,
|
||||
buf, sizeof(buf));
|
||||
if (ret < 0)
|
||||
drm_dbg_kms(display->drm,
|
||||
"Content Luminance DPCD reg write failed, err:-%d\n",
|
||||
ret);
|
||||
"Content Luminance DPCD reg write failed (%pe)\n", ERR_PTR(ret));
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -313,11 +317,11 @@ intel_dp_aux_hdr_enable_backlight(const struct intel_crtc_state *crtc_state,
|
|||
|
||||
intel_dp_wait_source_oui(intel_dp);
|
||||
|
||||
ret = drm_dp_dpcd_readb(&intel_dp->aux, INTEL_EDP_HDR_GETSET_CTRL_PARAMS, &old_ctrl);
|
||||
if (ret != 1) {
|
||||
ret = drm_dp_dpcd_read_byte(&intel_dp->aux, INTEL_EDP_HDR_GETSET_CTRL_PARAMS, &old_ctrl);
|
||||
if (ret < 0) {
|
||||
drm_err(display->drm,
|
||||
"[CONNECTOR:%d:%s] Failed to read current backlight control mode: %d\n",
|
||||
connector->base.base.id, connector->base.name, ret);
|
||||
"[CONNECTOR:%d:%s] Failed to read current backlight control mode (%pe)\n",
|
||||
connector->base.base.id, connector->base.name, ERR_PTR(ret));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -337,11 +341,14 @@ intel_dp_aux_hdr_enable_backlight(const struct intel_crtc_state *crtc_state,
|
|||
|
||||
intel_dp_aux_fill_hdr_tcon_params(conn_state, &ctrl);
|
||||
|
||||
if (ctrl != old_ctrl &&
|
||||
drm_dp_dpcd_writeb(&intel_dp->aux, INTEL_EDP_HDR_GETSET_CTRL_PARAMS, ctrl) != 1)
|
||||
drm_err(display->drm,
|
||||
"[CONNECTOR:%d:%s] Failed to configure DPCD brightness controls\n",
|
||||
connector->base.base.id, connector->base.name);
|
||||
if (ctrl != old_ctrl) {
|
||||
ret = drm_dp_dpcd_write_byte(&intel_dp->aux,
|
||||
INTEL_EDP_HDR_GETSET_CTRL_PARAMS, ctrl);
|
||||
if (ret < 0)
|
||||
drm_err(display->drm,
|
||||
"[CONNECTOR:%d:%s] Failed to configure DPCD brightness controls (%pe)\n",
|
||||
connector->base.base.id, connector->base.name, ERR_PTR(ret));
|
||||
}
|
||||
|
||||
if (intel_dp_in_hdr_mode(conn_state)) {
|
||||
hdr_metadata = conn_state->hdr_output_metadata->data;
|
||||
|
|
@ -392,13 +399,12 @@ intel_dp_aux_write_panel_luminance_override(struct intel_connector *connector)
|
|||
buf[2] = panel->backlight.max & 0xFF;
|
||||
buf[3] = (panel->backlight.max & 0xFF00) >> 8;
|
||||
|
||||
ret = drm_dp_dpcd_write(&intel_dp->aux,
|
||||
INTEL_EDP_HDR_PANEL_LUMINANCE_OVERRIDE,
|
||||
buf, sizeof(buf));
|
||||
ret = drm_dp_dpcd_write_data(&intel_dp->aux,
|
||||
INTEL_EDP_HDR_PANEL_LUMINANCE_OVERRIDE,
|
||||
buf, sizeof(buf));
|
||||
if (ret < 0)
|
||||
drm_dbg_kms(display->drm,
|
||||
"Panel Luminance DPCD reg write failed, err:-%d\n",
|
||||
ret);
|
||||
"Panel Luminance DPCD reg write failed (%pe)\n", ERR_PTR(ret));
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
@ -456,12 +462,12 @@ static u32 intel_dp_aux_vesa_get_backlight(struct intel_connector *connector, en
|
|||
int ret;
|
||||
|
||||
if (panel->backlight.edp.vesa.luminance_control_support) {
|
||||
ret = drm_dp_dpcd_read(&intel_dp->aux, DP_EDP_PANEL_TARGET_LUMINANCE_VALUE, buf,
|
||||
sizeof(buf));
|
||||
ret = drm_dp_dpcd_read_data(&intel_dp->aux, DP_EDP_PANEL_TARGET_LUMINANCE_VALUE, buf,
|
||||
sizeof(buf));
|
||||
if (ret < 0) {
|
||||
drm_err(intel_dp->aux.drm_dev,
|
||||
"[CONNECTOR:%d:%s] Failed to read Luminance from DPCD\n",
|
||||
connector->base.base.id, connector->base.name);
|
||||
"[CONNECTOR:%d:%s] Failed to read Luminance from DPCD (%pe)\n",
|
||||
connector->base.base.id, connector->base.name, ERR_PTR(ret));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -60,16 +60,15 @@ int intel_dp_hdcp_write_an_aksv(struct intel_digital_port *dig_port,
|
|||
{
|
||||
struct intel_display *display = to_intel_display(dig_port);
|
||||
u8 aksv[DRM_HDCP_KSV_LEN] = {};
|
||||
ssize_t dpcd_ret;
|
||||
int ret;
|
||||
|
||||
/* Output An first, that's easy */
|
||||
dpcd_ret = drm_dp_dpcd_write(&dig_port->dp.aux, DP_AUX_HDCP_AN,
|
||||
ret = drm_dp_dpcd_write_data(&dig_port->dp.aux, DP_AUX_HDCP_AN,
|
||||
an, DRM_HDCP_AN_LEN);
|
||||
if (dpcd_ret != DRM_HDCP_AN_LEN) {
|
||||
if (ret < 0) {
|
||||
drm_dbg_kms(display->drm,
|
||||
"Failed to write An over DP/AUX (%zd)\n",
|
||||
dpcd_ret);
|
||||
return dpcd_ret >= 0 ? -EIO : dpcd_ret;
|
||||
"Failed to write An over DP/AUX (%pe)\n", ERR_PTR(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -79,14 +78,14 @@ int intel_dp_hdcp_write_an_aksv(struct intel_digital_port *dig_port,
|
|||
* the destination address which will tickle the hardware to output the
|
||||
* Aksv on our behalf after the header is sent.
|
||||
*/
|
||||
dpcd_ret = drm_dp_dpcd_write(&dig_port->dp.aux, DP_AUX_HDCP_AKSV,
|
||||
ret = drm_dp_dpcd_write_data(&dig_port->dp.aux, DP_AUX_HDCP_AKSV,
|
||||
aksv, DRM_HDCP_KSV_LEN);
|
||||
if (dpcd_ret != DRM_HDCP_KSV_LEN) {
|
||||
if (ret < 0) {
|
||||
drm_dbg_kms(display->drm,
|
||||
"Failed to write Aksv over DP/AUX (%zd)\n",
|
||||
dpcd_ret);
|
||||
return dpcd_ret >= 0 ? -EIO : dpcd_ret;
|
||||
"Failed to write Aksv over DP/AUX (%pe)\n", ERR_PTR(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -94,15 +93,16 @@ static int intel_dp_hdcp_read_bksv(struct intel_digital_port *dig_port,
|
|||
u8 *bksv)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(dig_port);
|
||||
ssize_t ret;
|
||||
int ret;
|
||||
|
||||
ret = drm_dp_dpcd_read(&dig_port->dp.aux, DP_AUX_HDCP_BKSV, bksv,
|
||||
DRM_HDCP_KSV_LEN);
|
||||
if (ret != DRM_HDCP_KSV_LEN) {
|
||||
ret = drm_dp_dpcd_read_data(&dig_port->dp.aux, DP_AUX_HDCP_BKSV, bksv,
|
||||
DRM_HDCP_KSV_LEN);
|
||||
if (ret < 0) {
|
||||
drm_dbg_kms(display->drm,
|
||||
"Read Bksv from DP/AUX failed (%zd)\n", ret);
|
||||
return ret >= 0 ? -EIO : ret;
|
||||
"Read Bksv from DP/AUX failed (%pe)\n", ERR_PTR(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -110,20 +110,21 @@ static int intel_dp_hdcp_read_bstatus(struct intel_digital_port *dig_port,
|
|||
u8 *bstatus)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(dig_port);
|
||||
ssize_t ret;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* For some reason the HDMI and DP HDCP specs call this register
|
||||
* definition by different names. In the HDMI spec, it's called BSTATUS,
|
||||
* but in DP it's called BINFO.
|
||||
*/
|
||||
ret = drm_dp_dpcd_read(&dig_port->dp.aux, DP_AUX_HDCP_BINFO,
|
||||
bstatus, DRM_HDCP_BSTATUS_LEN);
|
||||
if (ret != DRM_HDCP_BSTATUS_LEN) {
|
||||
ret = drm_dp_dpcd_read_data(&dig_port->dp.aux, DP_AUX_HDCP_BINFO,
|
||||
bstatus, DRM_HDCP_BSTATUS_LEN);
|
||||
if (ret < 0) {
|
||||
drm_dbg_kms(display->drm,
|
||||
"Read bstatus from DP/AUX failed (%zd)\n", ret);
|
||||
return ret >= 0 ? -EIO : ret;
|
||||
"Read bstatus from DP/AUX failed (%pe)\n", ERR_PTR(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -132,14 +133,13 @@ int intel_dp_hdcp_read_bcaps(struct drm_dp_aux *aux,
|
|||
struct intel_display *display,
|
||||
u8 *bcaps)
|
||||
{
|
||||
ssize_t ret;
|
||||
int ret;
|
||||
|
||||
ret = drm_dp_dpcd_read(aux, DP_AUX_HDCP_BCAPS,
|
||||
bcaps, 1);
|
||||
if (ret != 1) {
|
||||
ret = drm_dp_dpcd_read_byte(aux, DP_AUX_HDCP_BCAPS, bcaps);
|
||||
if (ret < 0) {
|
||||
drm_dbg_kms(display->drm,
|
||||
"Read bcaps from DP/AUX failed (%zd)\n", ret);
|
||||
return ret >= 0 ? -EIO : ret;
|
||||
"Read bcaps from DP/AUX failed (%pe)\n", ERR_PTR(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
@ -166,16 +166,16 @@ int intel_dp_hdcp_read_ri_prime(struct intel_digital_port *dig_port,
|
|||
u8 *ri_prime)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(dig_port);
|
||||
ssize_t ret;
|
||||
int ret;
|
||||
|
||||
ret = drm_dp_dpcd_read(&dig_port->dp.aux, DP_AUX_HDCP_RI_PRIME,
|
||||
ri_prime, DRM_HDCP_RI_LEN);
|
||||
if (ret != DRM_HDCP_RI_LEN) {
|
||||
ret = drm_dp_dpcd_read_data(&dig_port->dp.aux, DP_AUX_HDCP_RI_PRIME,
|
||||
ri_prime, DRM_HDCP_RI_LEN);
|
||||
if (ret < 0) {
|
||||
drm_dbg_kms(display->drm,
|
||||
"Read Ri' from DP/AUX failed (%zd)\n",
|
||||
ret);
|
||||
return ret >= 0 ? -EIO : ret;
|
||||
"Read Ri' from DP/AUX failed (%pe)\n", ERR_PTR(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -184,17 +184,18 @@ int intel_dp_hdcp_read_ksv_ready(struct intel_digital_port *dig_port,
|
|||
bool *ksv_ready)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(dig_port);
|
||||
ssize_t ret;
|
||||
u8 bstatus;
|
||||
int ret;
|
||||
|
||||
ret = drm_dp_dpcd_read(&dig_port->dp.aux, DP_AUX_HDCP_BSTATUS,
|
||||
&bstatus, 1);
|
||||
if (ret != 1) {
|
||||
ret = drm_dp_dpcd_read_byte(&dig_port->dp.aux, DP_AUX_HDCP_BSTATUS,
|
||||
&bstatus);
|
||||
if (ret < 0) {
|
||||
drm_dbg_kms(display->drm,
|
||||
"Read bstatus from DP/AUX failed (%zd)\n", ret);
|
||||
return ret >= 0 ? -EIO : ret;
|
||||
"Read bstatus from DP/AUX failed (%pe)\n", ERR_PTR(ret));
|
||||
return ret;
|
||||
}
|
||||
*ksv_ready = bstatus & DP_BSTATUS_READY;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -203,23 +204,24 @@ int intel_dp_hdcp_read_ksv_fifo(struct intel_digital_port *dig_port,
|
|||
int num_downstream, u8 *ksv_fifo)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(dig_port);
|
||||
ssize_t ret;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
/* KSV list is read via 15 byte window (3 entries @ 5 bytes each) */
|
||||
for (i = 0; i < num_downstream; i += 3) {
|
||||
size_t len = min(num_downstream - i, 3) * DRM_HDCP_KSV_LEN;
|
||||
ret = drm_dp_dpcd_read(&dig_port->dp.aux,
|
||||
DP_AUX_HDCP_KSV_FIFO,
|
||||
ksv_fifo + i * DRM_HDCP_KSV_LEN,
|
||||
len);
|
||||
if (ret != len) {
|
||||
ret = drm_dp_dpcd_read_data(&dig_port->dp.aux,
|
||||
DP_AUX_HDCP_KSV_FIFO,
|
||||
ksv_fifo + i * DRM_HDCP_KSV_LEN,
|
||||
len);
|
||||
if (ret < 0) {
|
||||
drm_dbg_kms(display->drm,
|
||||
"Read ksv[%d] from DP/AUX failed (%zd)\n",
|
||||
i, ret);
|
||||
return ret >= 0 ? -EIO : ret;
|
||||
"Read ksv[%d] from DP/AUX failed (%pe)\n",
|
||||
i, ERR_PTR(ret));
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -228,19 +230,19 @@ int intel_dp_hdcp_read_v_prime_part(struct intel_digital_port *dig_port,
|
|||
int i, u32 *part)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(dig_port);
|
||||
ssize_t ret;
|
||||
int ret;
|
||||
|
||||
if (i >= DRM_HDCP_V_PRIME_NUM_PARTS)
|
||||
return -EINVAL;
|
||||
|
||||
ret = drm_dp_dpcd_read(&dig_port->dp.aux,
|
||||
DP_AUX_HDCP_V_PRIME(i), part,
|
||||
DRM_HDCP_V_PRIME_PART_LEN);
|
||||
if (ret != DRM_HDCP_V_PRIME_PART_LEN) {
|
||||
ret = drm_dp_dpcd_read_data(&dig_port->dp.aux, DP_AUX_HDCP_V_PRIME(i), part,
|
||||
DRM_HDCP_V_PRIME_PART_LEN);
|
||||
if (ret < 0) {
|
||||
drm_dbg_kms(display->drm,
|
||||
"Read v'[%d] from DP/AUX failed (%zd)\n", i, ret);
|
||||
return ret >= 0 ? -EIO : ret;
|
||||
"Read v'[%d] from DP/AUX failed (%pe)\n", i, ERR_PTR(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -258,14 +260,13 @@ bool intel_dp_hdcp_check_link(struct intel_digital_port *dig_port,
|
|||
struct intel_connector *connector)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(dig_port);
|
||||
ssize_t ret;
|
||||
u8 bstatus;
|
||||
int ret;
|
||||
|
||||
ret = drm_dp_dpcd_read(&dig_port->dp.aux, DP_AUX_HDCP_BSTATUS,
|
||||
&bstatus, 1);
|
||||
if (ret != 1) {
|
||||
ret = drm_dp_dpcd_read_byte(&dig_port->dp.aux, DP_AUX_HDCP_BSTATUS, &bstatus);
|
||||
if (ret < 0) {
|
||||
drm_dbg_kms(display->drm,
|
||||
"Read bstatus from DP/AUX failed (%zd)\n", ret);
|
||||
"Read bstatus from DP/AUX failed (%pe)\n", ERR_PTR(ret));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -346,15 +347,14 @@ intel_dp_hdcp2_read_rx_status(struct intel_connector *connector,
|
|||
struct intel_display *display = to_intel_display(connector);
|
||||
struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
|
||||
struct drm_dp_aux *aux = &dig_port->dp.aux;
|
||||
ssize_t ret;
|
||||
int ret;
|
||||
|
||||
ret = drm_dp_dpcd_read(aux,
|
||||
DP_HDCP_2_2_REG_RXSTATUS_OFFSET, rx_status,
|
||||
HDCP_2_2_DP_RXSTATUS_LEN);
|
||||
if (ret != HDCP_2_2_DP_RXSTATUS_LEN) {
|
||||
ret = drm_dp_dpcd_read_data(aux, DP_HDCP_2_2_REG_RXSTATUS_OFFSET, rx_status,
|
||||
HDCP_2_2_DP_RXSTATUS_LEN);
|
||||
if (ret < 0) {
|
||||
drm_dbg_kms(display->drm,
|
||||
"Read bstatus from DP/AUX failed (%zd)\n", ret);
|
||||
return ret >= 0 ? -EIO : ret;
|
||||
"Read bstatus from DP/AUX failed (%pe)\n", ERR_PTR(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
@ -474,8 +474,8 @@ int intel_dp_hdcp2_write_msg(struct intel_connector *connector,
|
|||
len = bytes_to_write > DP_AUX_MAX_PAYLOAD_BYTES ?
|
||||
DP_AUX_MAX_PAYLOAD_BYTES : bytes_to_write;
|
||||
|
||||
ret = drm_dp_dpcd_write(aux,
|
||||
offset, (void *)byte, len);
|
||||
/* Note: This may return < len for partial writes. */
|
||||
ret = drm_dp_dpcd_write(aux, offset, byte, len);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
|
@ -487,20 +487,20 @@ int intel_dp_hdcp2_write_msg(struct intel_connector *connector,
|
|||
return size;
|
||||
}
|
||||
|
||||
/* return number of bytes read on success */
|
||||
static
|
||||
ssize_t get_receiver_id_list_rx_info(struct intel_connector *connector,
|
||||
u32 *dev_cnt, u8 *byte)
|
||||
{
|
||||
struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
|
||||
struct drm_dp_aux *aux = &dig_port->dp.aux;
|
||||
ssize_t ret;
|
||||
u8 *rx_info = byte;
|
||||
int ret;
|
||||
|
||||
ret = drm_dp_dpcd_read(aux,
|
||||
DP_HDCP_2_2_REG_RXINFO_OFFSET,
|
||||
(void *)rx_info, HDCP_2_2_RXINFO_LEN);
|
||||
if (ret != HDCP_2_2_RXINFO_LEN)
|
||||
return ret >= 0 ? -EIO : ret;
|
||||
ret = drm_dp_dpcd_read_data(aux, DP_HDCP_2_2_REG_RXINFO_OFFSET,
|
||||
rx_info, HDCP_2_2_RXINFO_LEN);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
*dev_cnt = (HDCP_2_2_DEV_COUNT_HI(rx_info[0]) << 4 |
|
||||
HDCP_2_2_DEV_COUNT_LO(rx_info[1]));
|
||||
|
|
@ -508,7 +508,7 @@ ssize_t get_receiver_id_list_rx_info(struct intel_connector *connector,
|
|||
if (*dev_cnt > HDCP_2_2_MAX_DEVICE_COUNT)
|
||||
*dev_cnt = HDCP_2_2_MAX_DEVICE_COUNT;
|
||||
|
||||
return ret;
|
||||
return HDCP_2_2_RXINFO_LEN;
|
||||
}
|
||||
|
||||
static
|
||||
|
|
@ -566,11 +566,11 @@ int intel_dp_hdcp2_read_msg(struct intel_connector *connector,
|
|||
hdcp2_msg_data->msg_read_timeout);
|
||||
}
|
||||
|
||||
ret = drm_dp_dpcd_read(aux, offset,
|
||||
(void *)byte, len);
|
||||
/* Note: This may return < len for partial reads. */
|
||||
ret = drm_dp_dpcd_read(aux, offset, byte, len);
|
||||
if (ret < 0) {
|
||||
drm_dbg_kms(display->drm, "msg_id %d, ret %zd\n",
|
||||
msg_id, ret);
|
||||
drm_dbg_kms(display->drm, "msg_id %d, ret %pe\n",
|
||||
msg_id, ERR_PTR(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -660,11 +660,11 @@ int _intel_dp_hdcp2_get_capability(struct drm_dp_aux *aux,
|
|||
* declare a monitor not capable of HDCP 2.2.
|
||||
*/
|
||||
for (i = 0; i < 3; i++) {
|
||||
ret = drm_dp_dpcd_read(aux,
|
||||
DP_HDCP_2_2_REG_RX_CAPS_OFFSET,
|
||||
rx_caps, HDCP_2_2_RXCAPS_LEN);
|
||||
if (ret != HDCP_2_2_RXCAPS_LEN)
|
||||
return ret >= 0 ? -EIO : ret;
|
||||
ret = drm_dp_dpcd_read_data(aux,
|
||||
DP_HDCP_2_2_REG_RX_CAPS_OFFSET,
|
||||
rx_caps, HDCP_2_2_RXCAPS_LEN);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (rx_caps[0] == HDCP_2_2_RX_CAPS_VERSION_VAL &&
|
||||
HDCP_2_2_DP_HDCP_CAPABLE(rx_caps[2])) {
|
||||
|
|
|
|||
|
|
@ -929,7 +929,7 @@ intel_dp_set_link_train(struct intel_dp *intel_dp,
|
|||
{
|
||||
int reg = intel_dp_training_pattern_set_reg(intel_dp, dp_phy);
|
||||
u8 buf[sizeof(intel_dp->train_set) + 1];
|
||||
int len;
|
||||
int ret, len;
|
||||
|
||||
intel_dp_program_link_training_pattern(intel_dp, crtc_state,
|
||||
dp_phy, dp_train_pat);
|
||||
|
|
@ -939,7 +939,9 @@ intel_dp_set_link_train(struct intel_dp *intel_dp,
|
|||
memcpy(buf + 1, intel_dp->train_set, crtc_state->lane_count);
|
||||
len = crtc_state->lane_count + 1;
|
||||
|
||||
return drm_dp_dpcd_write(&intel_dp->aux, reg, buf, len) == len;
|
||||
ret = drm_dp_dpcd_write_data(&intel_dp->aux, reg, buf, len);
|
||||
|
||||
return !ret;
|
||||
}
|
||||
|
||||
static char dp_training_pattern_name(u8 train_pat)
|
||||
|
|
@ -1046,10 +1048,10 @@ intel_dp_update_link_train(struct intel_dp *intel_dp,
|
|||
|
||||
intel_dp_set_signal_levels(intel_dp, crtc_state, dp_phy);
|
||||
|
||||
ret = drm_dp_dpcd_write(&intel_dp->aux, reg,
|
||||
intel_dp->train_set, crtc_state->lane_count);
|
||||
ret = drm_dp_dpcd_write_data(&intel_dp->aux, reg,
|
||||
intel_dp->train_set, crtc_state->lane_count);
|
||||
|
||||
return ret == crtc_state->lane_count;
|
||||
return !ret;
|
||||
}
|
||||
|
||||
/* 128b/132b */
|
||||
|
|
@ -1115,7 +1117,7 @@ void intel_dp_link_training_set_mode(struct intel_dp *intel_dp, int link_rate,
|
|||
link_config[0] |= pr_with_as_sdp_enable ? DP_FIXED_VTOTAL_AS_SDP_EN_IN_PR_ACTIVE : 0;
|
||||
link_config[1] = drm_dp_is_uhbr_rate(link_rate) ?
|
||||
DP_SET_ANSI_128B132B : DP_SET_ANSI_8B10B;
|
||||
drm_dp_dpcd_write(&intel_dp->aux, DP_DOWNSPREAD_CTRL, link_config, 2);
|
||||
drm_dp_dpcd_write_data(&intel_dp->aux, DP_DOWNSPREAD_CTRL, link_config, 2);
|
||||
}
|
||||
|
||||
static bool
|
||||
|
|
@ -1163,8 +1165,8 @@ void intel_dp_link_training_set_bw(struct intel_dp *intel_dp,
|
|||
/* DP and eDP v1.3 and earlier link bw set method. */
|
||||
u8 link_config[] = { link_bw, lane_count };
|
||||
|
||||
drm_dp_dpcd_write(&intel_dp->aux, DP_LINK_BW_SET, link_config,
|
||||
ARRAY_SIZE(link_config));
|
||||
drm_dp_dpcd_write_data(&intel_dp->aux, DP_LINK_BW_SET, link_config,
|
||||
sizeof(link_config));
|
||||
} else {
|
||||
/*
|
||||
* eDP v1.4 and later link rate set method.
|
||||
|
|
@ -1175,8 +1177,8 @@ void intel_dp_link_training_set_bw(struct intel_dp *intel_dp,
|
|||
* eDP v1.5 sinks allow choosing either, and the last choice
|
||||
* shall be active.
|
||||
*/
|
||||
drm_dp_dpcd_writeb(&intel_dp->aux, DP_LANE_COUNT_SET, lane_count);
|
||||
drm_dp_dpcd_writeb(&intel_dp->aux, DP_LINK_RATE_SET, rate_select);
|
||||
drm_dp_dpcd_write_byte(&intel_dp->aux, DP_LANE_COUNT_SET, lane_count);
|
||||
drm_dp_dpcd_write_byte(&intel_dp->aux, DP_LINK_RATE_SET, rate_select);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1286,8 +1288,8 @@ intel_dp_prepare_link_train(struct intel_dp *intel_dp,
|
|||
|
||||
lt_dbg(intel_dp, DP_PHY_DPRX, "Reloading eDP link rates\n");
|
||||
|
||||
drm_dp_dpcd_read(&intel_dp->aux, DP_SUPPORTED_LINK_RATES,
|
||||
sink_rates, sizeof(sink_rates));
|
||||
drm_dp_dpcd_read_data(&intel_dp->aux, DP_SUPPORTED_LINK_RATES,
|
||||
sink_rates, sizeof(sink_rates));
|
||||
}
|
||||
|
||||
if (link_bw)
|
||||
|
|
@ -1612,7 +1614,7 @@ static void intel_dp_stop_post_lt_adj_req(struct intel_dp *intel_dp,
|
|||
if (crtc_state->enhanced_framing)
|
||||
lane_count |= DP_LANE_COUNT_ENHANCED_FRAME_EN;
|
||||
|
||||
drm_dp_dpcd_writeb(&intel_dp->aux, DP_LANE_COUNT_SET, lane_count);
|
||||
drm_dp_dpcd_write_byte(&intel_dp->aux, DP_LANE_COUNT_SET, lane_count);
|
||||
}
|
||||
|
||||
static bool intel_dp_disable_dpcd_training_pattern(struct intel_dp *intel_dp,
|
||||
|
|
@ -1621,7 +1623,7 @@ static bool intel_dp_disable_dpcd_training_pattern(struct intel_dp *intel_dp,
|
|||
int reg = intel_dp_training_pattern_set_reg(intel_dp, dp_phy);
|
||||
u8 val = DP_TRAINING_PATTERN_DISABLE;
|
||||
|
||||
return drm_dp_dpcd_write(&intel_dp->aux, reg, &val, 1) == 1;
|
||||
return drm_dp_dpcd_write_byte(&intel_dp->aux, reg, val) == 0;
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
@ -1631,10 +1633,11 @@ intel_dp_128b132b_intra_hop(struct intel_dp *intel_dp,
|
|||
u8 sink_status;
|
||||
int ret;
|
||||
|
||||
ret = drm_dp_dpcd_readb(&intel_dp->aux, DP_SINK_STATUS, &sink_status);
|
||||
if (ret != 1) {
|
||||
lt_dbg(intel_dp, DP_PHY_DPRX, "Failed to read sink status\n");
|
||||
return ret < 0 ? ret : -EIO;
|
||||
ret = drm_dp_dpcd_read_byte(&intel_dp->aux, DP_SINK_STATUS, &sink_status);
|
||||
if (ret < 0) {
|
||||
lt_dbg(intel_dp, DP_PHY_DPRX, "Failed to read sink status (%pe)\n",
|
||||
ERR_PTR(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
return sink_status & DP_INTRA_HOP_AUX_REPLY_INDICATION ? 1 : 0;
|
||||
|
|
@ -2173,10 +2176,13 @@ intel_dp_128b132b_lane_cds(struct intel_dp *intel_dp,
|
|||
{
|
||||
u8 link_status[DP_LINK_STATUS_SIZE];
|
||||
unsigned long deadline;
|
||||
int ret;
|
||||
|
||||
if (drm_dp_dpcd_writeb(&intel_dp->aux, DP_TRAINING_PATTERN_SET,
|
||||
DP_TRAINING_PATTERN_2_CDS) != 1) {
|
||||
lt_err(intel_dp, DP_PHY_DPRX, "Failed to start 128b/132b TPS2 CDS\n");
|
||||
ret = drm_dp_dpcd_write_byte(&intel_dp->aux, DP_TRAINING_PATTERN_SET,
|
||||
DP_TRAINING_PATTERN_2_CDS);
|
||||
if (ret < 0) {
|
||||
lt_err(intel_dp, DP_PHY_DPRX, "Failed to start 128b/132b TPS2 CDS (%pe)\n",
|
||||
ERR_PTR(ret));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -2363,9 +2369,9 @@ void intel_dp_128b132b_sdp_crc16(struct intel_dp *intel_dp,
|
|||
return;
|
||||
|
||||
/* DP v2.0 SCR on SDP CRC16 for 128b/132b Link Layer */
|
||||
drm_dp_dpcd_writeb(&intel_dp->aux,
|
||||
DP_SDP_ERROR_DETECTION_CONFIGURATION,
|
||||
DP_SDP_CRC16_128B132B_EN);
|
||||
drm_dp_dpcd_write_byte(&intel_dp->aux,
|
||||
DP_SDP_ERROR_DETECTION_CONFIGURATION,
|
||||
DP_SDP_CRC16_128B132B_EN);
|
||||
|
||||
lt_dbg(intel_dp, DP_PHY_DPRX, "DP2.0 SDP CRC16 for 128b/132b enabled\n");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2252,7 +2252,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_read_byte(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)) {
|
||||
|
|
|
|||
|
|
@ -147,26 +147,25 @@ bool intel_dp_test_compute_config(struct intel_connector *connector,
|
|||
static u8 intel_dp_autotest_link_training(struct intel_dp *intel_dp)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(intel_dp);
|
||||
int status = 0;
|
||||
int ret;
|
||||
int test_link_rate;
|
||||
u8 test_lane_count, test_link_bw;
|
||||
/* (DP CTS 1.2)
|
||||
* 4.3.1.11
|
||||
*/
|
||||
/* Read the TEST_LANE_COUNT and TEST_LINK_RTAE fields (DP CTS 3.1.4) */
|
||||
status = drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_LANE_COUNT,
|
||||
&test_lane_count);
|
||||
|
||||
if (status <= 0) {
|
||||
drm_dbg_kms(display->drm, "Lane count read failed\n");
|
||||
ret = drm_dp_dpcd_read_byte(&intel_dp->aux, DP_TEST_LANE_COUNT,
|
||||
&test_lane_count);
|
||||
if (ret < 0) {
|
||||
drm_dbg_kms(display->drm, "Lane count read failed (%pe)\n", ERR_PTR(ret));
|
||||
return DP_TEST_NAK;
|
||||
}
|
||||
test_lane_count &= DP_MAX_LANE_COUNT_MASK;
|
||||
|
||||
status = drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_LINK_RATE,
|
||||
&test_link_bw);
|
||||
if (status <= 0) {
|
||||
drm_dbg_kms(display->drm, "Link Rate read failed\n");
|
||||
ret = drm_dp_dpcd_read_byte(&intel_dp->aux, DP_TEST_LINK_RATE,
|
||||
&test_link_bw);
|
||||
if (ret < 0) {
|
||||
drm_dbg_kms(display->drm, "Link Rate read failed (%pe)\n", ERR_PTR(ret));
|
||||
return DP_TEST_NAK;
|
||||
}
|
||||
test_link_rate = drm_dp_bw_code_to_link_rate(test_link_bw);
|
||||
|
|
@ -188,36 +187,34 @@ static u8 intel_dp_autotest_video_pattern(struct intel_dp *intel_dp)
|
|||
u8 test_pattern;
|
||||
u8 test_misc;
|
||||
__be16 h_width, v_height;
|
||||
int status = 0;
|
||||
int ret;
|
||||
|
||||
/* Read the TEST_PATTERN (DP CTS 3.1.5) */
|
||||
status = drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_PATTERN,
|
||||
&test_pattern);
|
||||
if (status <= 0) {
|
||||
drm_dbg_kms(display->drm, "Test pattern read failed\n");
|
||||
ret = drm_dp_dpcd_read_byte(&intel_dp->aux, DP_TEST_PATTERN,
|
||||
&test_pattern);
|
||||
if (ret < 0) {
|
||||
drm_dbg_kms(display->drm, "Test pattern read failed (%pe)\n", ERR_PTR(ret));
|
||||
return DP_TEST_NAK;
|
||||
}
|
||||
if (test_pattern != DP_COLOR_RAMP)
|
||||
return DP_TEST_NAK;
|
||||
|
||||
status = drm_dp_dpcd_read(&intel_dp->aux, DP_TEST_H_WIDTH_HI,
|
||||
&h_width, 2);
|
||||
if (status <= 0) {
|
||||
drm_dbg_kms(display->drm, "H Width read failed\n");
|
||||
ret = drm_dp_dpcd_read_data(&intel_dp->aux, DP_TEST_H_WIDTH_HI, &h_width, 2);
|
||||
if (ret < 0) {
|
||||
drm_dbg_kms(display->drm, "H Width read failed (%pe)\n", ERR_PTR(ret));
|
||||
return DP_TEST_NAK;
|
||||
}
|
||||
|
||||
status = drm_dp_dpcd_read(&intel_dp->aux, DP_TEST_V_HEIGHT_HI,
|
||||
&v_height, 2);
|
||||
if (status <= 0) {
|
||||
drm_dbg_kms(display->drm, "V Height read failed\n");
|
||||
ret = drm_dp_dpcd_read_data(&intel_dp->aux, DP_TEST_V_HEIGHT_HI,
|
||||
&v_height, 2);
|
||||
if (ret < 0) {
|
||||
drm_dbg_kms(display->drm, "V Height read failed (%pe)\n", ERR_PTR(ret));
|
||||
return DP_TEST_NAK;
|
||||
}
|
||||
|
||||
status = drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_MISC0,
|
||||
&test_misc);
|
||||
if (status <= 0) {
|
||||
drm_dbg_kms(display->drm, "TEST MISC read failed\n");
|
||||
ret = drm_dp_dpcd_read_byte(&intel_dp->aux, DP_TEST_MISC0, &test_misc);
|
||||
if (ret < 0) {
|
||||
drm_dbg_kms(display->drm, "TEST MISC read failed (%pe)\n", ERR_PTR(ret));
|
||||
return DP_TEST_NAK;
|
||||
}
|
||||
if ((test_misc & DP_TEST_COLOR_FORMAT_MASK) != DP_COLOR_FORMAT_RGB)
|
||||
|
|
@ -250,6 +247,7 @@ static u8 intel_dp_autotest_edid(struct intel_dp *intel_dp)
|
|||
u8 test_result = DP_TEST_ACK;
|
||||
struct intel_connector *intel_connector = intel_dp->attached_connector;
|
||||
struct drm_connector *connector = &intel_connector->base;
|
||||
int ret;
|
||||
|
||||
if (!intel_connector->detect_edid || connector->edid_corrupt ||
|
||||
intel_dp->aux.i2c_defer_count > 6) {
|
||||
|
|
@ -274,10 +272,11 @@ static u8 intel_dp_autotest_edid(struct intel_dp *intel_dp)
|
|||
/* We have to write the checksum of the last block read */
|
||||
block += block->extensions;
|
||||
|
||||
if (drm_dp_dpcd_writeb(&intel_dp->aux, DP_TEST_EDID_CHECKSUM,
|
||||
block->checksum) <= 0)
|
||||
ret = drm_dp_dpcd_write_byte(&intel_dp->aux, DP_TEST_EDID_CHECKSUM,
|
||||
block->checksum);
|
||||
if (ret < 0)
|
||||
drm_dbg_kms(display->drm,
|
||||
"Failed to write EDID checksum\n");
|
||||
"Failed to write EDID checksum (%pe)\n", ERR_PTR(ret));
|
||||
|
||||
test_result = DP_TEST_ACK | DP_TEST_EDID_CHECKSUM_WRITE;
|
||||
intel_dp->compliance.test_data.edid = INTEL_DP_RESOLUTION_PREFERRED;
|
||||
|
|
@ -397,8 +396,8 @@ static void intel_dp_process_phy_request(struct intel_dp *intel_dp,
|
|||
|
||||
intel_dp_phy_pattern_update(intel_dp, crtc_state);
|
||||
|
||||
drm_dp_dpcd_write(&intel_dp->aux, DP_TRAINING_LANE0_SET,
|
||||
intel_dp->train_set, crtc_state->lane_count);
|
||||
drm_dp_dpcd_write_data(&intel_dp->aux, DP_TRAINING_LANE0_SET,
|
||||
intel_dp->train_set, crtc_state->lane_count);
|
||||
|
||||
drm_dp_set_phy_test_pattern(&intel_dp->aux, data,
|
||||
intel_dp->dpcd[DP_DPCD_REV]);
|
||||
|
|
@ -427,12 +426,12 @@ void intel_dp_test_request(struct intel_dp *intel_dp)
|
|||
struct intel_display *display = to_intel_display(intel_dp);
|
||||
u8 response = DP_TEST_NAK;
|
||||
u8 request = 0;
|
||||
int status;
|
||||
int ret;
|
||||
|
||||
status = drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_REQUEST, &request);
|
||||
if (status <= 0) {
|
||||
ret = drm_dp_dpcd_read_byte(&intel_dp->aux, DP_TEST_REQUEST, &request);
|
||||
if (ret < 0) {
|
||||
drm_dbg_kms(display->drm,
|
||||
"Could not read test request from sink\n");
|
||||
"Could not read test request from sink (%pe)\n", ERR_PTR(ret));
|
||||
goto update_status;
|
||||
}
|
||||
|
||||
|
|
@ -463,10 +462,10 @@ void intel_dp_test_request(struct intel_dp *intel_dp)
|
|||
intel_dp->compliance.test_type = request;
|
||||
|
||||
update_status:
|
||||
status = drm_dp_dpcd_writeb(&intel_dp->aux, DP_TEST_RESPONSE, response);
|
||||
if (status <= 0)
|
||||
ret = drm_dp_dpcd_write_byte(&intel_dp->aux, DP_TEST_RESPONSE, response);
|
||||
if (ret < 0)
|
||||
drm_dbg_kms(display->drm,
|
||||
"Could not write test response to sink\n");
|
||||
"Could not write test response to sink (%pe)\n", ERR_PTR(ret));
|
||||
}
|
||||
|
||||
/* phy test */
|
||||
|
|
|
|||
|
|
@ -596,7 +596,7 @@ u64 *intel_fb_plane_get_modifiers(struct intel_display *display,
|
|||
count++;
|
||||
}
|
||||
|
||||
list = kmalloc_array(count, sizeof(*list), GFP_KERNEL);
|
||||
list = kmalloc_objs(*list, count);
|
||||
if (drm_WARN_ON(display->drm, !list))
|
||||
return NULL;
|
||||
|
||||
|
|
@ -1289,7 +1289,7 @@ bool intel_plane_uses_fence(const struct intel_plane_state *plane_state)
|
|||
|
||||
return intel_plane_needs_fence(display) ||
|
||||
(plane->fbc && !plane_state->no_fbc_reason &&
|
||||
i915_gtt_view_is_normal(&plane_state->view.gtt));
|
||||
intel_gtt_view_is_normal(&plane_state->view.gtt));
|
||||
}
|
||||
|
||||
static int intel_fb_pitch(const struct intel_framebuffer *fb, int color_plane, unsigned int rotation)
|
||||
|
|
@ -1511,7 +1511,7 @@ static u32 calc_plane_remap_info(const struct intel_framebuffer *fb, int color_p
|
|||
plane_view_height_tiles(fb, color_plane, dims, y));
|
||||
}
|
||||
|
||||
if (i915_gtt_view_is_rotated(&view->gtt)) {
|
||||
if (intel_gtt_view_is_rotated(&view->gtt)) {
|
||||
drm_WARN_ON(display->drm, remap_info->linear);
|
||||
check_array_bounds(display, view->gtt.rotated.plane, color_plane);
|
||||
|
||||
|
|
@ -1536,7 +1536,7 @@ static u32 calc_plane_remap_info(const struct intel_framebuffer *fb, int color_p
|
|||
/* rotate the tile dimensions to match the GTT view */
|
||||
swap(tile_width, tile_height);
|
||||
} else {
|
||||
drm_WARN_ON(display->drm, !i915_gtt_view_is_remapped(&view->gtt));
|
||||
drm_WARN_ON(display->drm, !intel_gtt_view_is_remapped(&view->gtt));
|
||||
|
||||
check_array_bounds(display, view->gtt.remapped.plane, color_plane);
|
||||
|
||||
|
|
@ -1632,13 +1632,13 @@ calc_plane_normal_size(const struct intel_framebuffer *fb, int color_plane,
|
|||
|
||||
static void intel_fb_view_init(struct intel_display *display,
|
||||
struct intel_fb_view *view,
|
||||
enum i915_gtt_view_type view_type,
|
||||
enum intel_gtt_view_type view_type,
|
||||
const struct intel_framebuffer *fb)
|
||||
{
|
||||
memset(view, 0, sizeof(*view));
|
||||
view->gtt.type = view_type;
|
||||
|
||||
if (i915_gtt_view_is_remapped(&view->gtt) &&
|
||||
if (intel_gtt_view_is_remapped(&view->gtt) &&
|
||||
intel_fb_needs_pot_stride_remap(fb))
|
||||
view->gtt.remapped.plane_alignment = SZ_2M / PAGE_SIZE;
|
||||
}
|
||||
|
|
@ -1706,7 +1706,7 @@ int intel_fill_fb_info(struct intel_display *display, struct intel_framebuffer *
|
|||
unsigned int tile_size = intel_tile_size(display);
|
||||
|
||||
intel_fb_view_init(display, &fb->normal_view,
|
||||
I915_GTT_VIEW_NORMAL, fb);
|
||||
INTEL_GTT_VIEW_NORMAL, fb);
|
||||
|
||||
drm_WARN_ON(display->drm,
|
||||
intel_fb_supports_90_270_rotation(fb) &&
|
||||
|
|
@ -1714,10 +1714,10 @@ int intel_fill_fb_info(struct intel_display *display, struct intel_framebuffer *
|
|||
|
||||
if (intel_fb_supports_90_270_rotation(fb))
|
||||
intel_fb_view_init(display, &fb->rotated_view,
|
||||
I915_GTT_VIEW_ROTATED, fb);
|
||||
INTEL_GTT_VIEW_ROTATED, fb);
|
||||
if (intel_fb_needs_pot_stride_remap(fb))
|
||||
intel_fb_view_init(display, &fb->remapped_view,
|
||||
I915_GTT_VIEW_REMAPPED, fb);
|
||||
INTEL_GTT_VIEW_REMAPPED, fb);
|
||||
|
||||
for (i = 0; i < num_planes; i++) {
|
||||
struct fb_plane_view_dims view_dims;
|
||||
|
|
@ -1845,7 +1845,7 @@ static void intel_plane_remap_gtt(struct intel_plane_state *plane_state)
|
|||
|
||||
intel_fb_view_init(display, &plane_state->view,
|
||||
drm_rotation_90_or_270(rotation) ?
|
||||
I915_GTT_VIEW_ROTATED : I915_GTT_VIEW_REMAPPED,
|
||||
INTEL_GTT_VIEW_ROTATED : INTEL_GTT_VIEW_REMAPPED,
|
||||
intel_fb);
|
||||
|
||||
src_x = plane_state->uapi.src.x1 >> 16;
|
||||
|
|
|
|||
|
|
@ -1196,23 +1196,13 @@ xe3p_lpd_fbc_fp16_format_is_valid(const struct intel_plane_state *plane_state)
|
|||
|
||||
static bool xe3p_lpd_fbc_pixel_format_is_valid(const struct intel_plane_state *plane_state)
|
||||
{
|
||||
const struct drm_framebuffer *fb = plane_state->hw.fb;
|
||||
|
||||
if (lnl_fbc_pixel_format_is_valid(plane_state))
|
||||
return true;
|
||||
|
||||
if (xe3p_lpd_fbc_fp16_format_is_valid(plane_state))
|
||||
return true;
|
||||
|
||||
switch (fb->format->format) {
|
||||
case DRM_FORMAT_XRGB16161616:
|
||||
case DRM_FORMAT_XBGR16161616:
|
||||
case DRM_FORMAT_ARGB16161616:
|
||||
case DRM_FORMAT_ABGR16161616:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool intel_fbc_need_pixel_normalizer(const struct intel_plane_state *plane_state)
|
||||
|
|
|
|||
|
|
@ -867,6 +867,11 @@ void intel_hpd_poll_enable(struct intel_display *display)
|
|||
if (!HAS_DISPLAY(display) || !intel_display_device_enabled(display))
|
||||
return;
|
||||
|
||||
if (intel_display_rpm_pme_enabled(display)) {
|
||||
drm_dbg_kms(display->drm, "PME wake capable device, skipping HPD polling.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
WRITE_ONCE(display->hotplug.poll_enabled, true);
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -137,11 +137,10 @@ bool intel_lspcon_detect_hdr_capability(struct intel_digital_port *dig_port)
|
|||
u8 hdr_caps;
|
||||
int ret;
|
||||
|
||||
ret = drm_dp_dpcd_read(&intel_dp->aux, get_hdr_status_reg(lspcon),
|
||||
&hdr_caps, 1);
|
||||
|
||||
ret = drm_dp_dpcd_read_byte(&intel_dp->aux, get_hdr_status_reg(lspcon), &hdr_caps);
|
||||
if (ret < 0) {
|
||||
drm_dbg_kms(display->drm, "HDR capability detection failed\n");
|
||||
drm_dbg_kms(display->drm, "HDR capability detection failed (%pe)\n",
|
||||
ERR_PTR(ret));
|
||||
lspcon->hdr_supported = false;
|
||||
} else if (hdr_caps & 0x1) {
|
||||
drm_dbg_kms(display->drm, "LSPCON capable of HDR\n");
|
||||
|
|
@ -244,11 +243,12 @@ static bool lspcon_wake_native_aux_ch(struct intel_lspcon *lspcon)
|
|||
{
|
||||
struct intel_dp *intel_dp = lspcon_to_intel_dp(lspcon);
|
||||
struct intel_display *display = to_intel_display(intel_dp);
|
||||
int ret;
|
||||
u8 rev;
|
||||
|
||||
if (drm_dp_dpcd_readb(&lspcon_to_intel_dp(lspcon)->aux, DP_DPCD_REV,
|
||||
&rev) != 1) {
|
||||
drm_dbg_kms(display->drm, "Native AUX CH down\n");
|
||||
ret = drm_dp_dpcd_read_byte(&lspcon_to_intel_dp(lspcon)->aux, DP_DPCD_REV, &rev);
|
||||
if (ret < 0) {
|
||||
drm_dbg_kms(display->drm, "Native AUX CH down (%pe)\n", ERR_PTR(ret));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -331,17 +331,17 @@ static bool lspcon_parade_fw_ready(struct drm_dp_aux *aux)
|
|||
{
|
||||
u8 avi_if_ctrl;
|
||||
u8 retry;
|
||||
ssize_t ret;
|
||||
int ret;
|
||||
|
||||
/* Check if LSPCON FW is ready for data */
|
||||
for (retry = 0; retry < 5; retry++) {
|
||||
if (retry)
|
||||
usleep_range(200, 300);
|
||||
|
||||
ret = drm_dp_dpcd_read(aux, LSPCON_PARADE_AVI_IF_CTRL,
|
||||
&avi_if_ctrl, 1);
|
||||
ret = drm_dp_dpcd_read_byte(aux, LSPCON_PARADE_AVI_IF_CTRL, &avi_if_ctrl);
|
||||
if (ret < 0) {
|
||||
drm_err(aux->drm_dev, "Failed to read AVI IF control\n");
|
||||
drm_err(aux->drm_dev, "Failed to read AVI IF control (%pe)\n",
|
||||
ERR_PTR(ret));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -371,10 +371,10 @@ static bool _lspcon_parade_write_infoframe_blocks(struct drm_dp_aux *aux,
|
|||
|
||||
reg = LSPCON_PARADE_AVI_IF_WRITE_OFFSET;
|
||||
data = avi_buf + block_count * 8;
|
||||
ret = drm_dp_dpcd_write(aux, reg, data, 8);
|
||||
ret = drm_dp_dpcd_write_data(aux, reg, data, 8);
|
||||
if (ret < 0) {
|
||||
drm_err(aux->drm_dev, "Failed to write AVI IF block %d\n",
|
||||
block_count);
|
||||
drm_err(aux->drm_dev, "Failed to write AVI IF block %d (%pe)\n",
|
||||
block_count, ERR_PTR(ret));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -386,10 +386,10 @@ static bool _lspcon_parade_write_infoframe_blocks(struct drm_dp_aux *aux,
|
|||
*/
|
||||
reg = LSPCON_PARADE_AVI_IF_CTRL;
|
||||
avi_if_ctrl = LSPCON_PARADE_AVI_IF_KICKOFF | block_count;
|
||||
ret = drm_dp_dpcd_write(aux, reg, &avi_if_ctrl, 1);
|
||||
ret = drm_dp_dpcd_write_byte(aux, reg, avi_if_ctrl);
|
||||
if (ret < 0) {
|
||||
drm_err(aux->drm_dev, "Failed to update (0x%x), block %d\n",
|
||||
reg, block_count);
|
||||
drm_err(aux->drm_dev, "Failed to update (0x%x), block %d (%pe)\n",
|
||||
reg, block_count, ERR_PTR(ret));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -435,35 +435,38 @@ static bool _lspcon_write_avi_infoframe_parade(struct drm_dp_aux *aux,
|
|||
static bool _lspcon_write_avi_infoframe_mca(struct drm_dp_aux *aux,
|
||||
const u8 *buffer, ssize_t len)
|
||||
{
|
||||
int ret;
|
||||
u32 val = 0;
|
||||
int ret, written = 0;
|
||||
u32 retry;
|
||||
u16 reg;
|
||||
const u8 *data = buffer;
|
||||
u8 val;
|
||||
|
||||
reg = LSPCON_MCA_AVI_IF_WRITE_OFFSET;
|
||||
while (val < len) {
|
||||
while (written < len) {
|
||||
/* DPCD write for AVI IF can fail on a slow FW day, so retry */
|
||||
for (retry = 0; retry < 5; retry++) {
|
||||
ret = drm_dp_dpcd_write(aux, reg, (void *)data, 1);
|
||||
if (ret == 1) {
|
||||
ret = drm_dp_dpcd_write_byte(aux, reg, *data);
|
||||
if (!ret) {
|
||||
break;
|
||||
} else if (retry < 4) {
|
||||
mdelay(50);
|
||||
continue;
|
||||
} else {
|
||||
drm_err(aux->drm_dev, "DPCD write failed at:0x%x\n", reg);
|
||||
drm_err(aux->drm_dev, "DPCD write failed at:0x%x (%pe)\n",
|
||||
reg, ERR_PTR(ret));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
val++; reg++; data++;
|
||||
written++;
|
||||
reg++;
|
||||
data++;
|
||||
}
|
||||
|
||||
val = 0;
|
||||
reg = LSPCON_MCA_AVI_IF_CTRL;
|
||||
ret = drm_dp_dpcd_read(aux, reg, &val, 1);
|
||||
ret = drm_dp_dpcd_read_byte(aux, reg, &val);
|
||||
if (ret < 0) {
|
||||
drm_err(aux->drm_dev, "DPCD read failed, address 0x%x\n", reg);
|
||||
drm_err(aux->drm_dev, "DPCD read failed, address 0x%x (%pe)\n",
|
||||
reg, ERR_PTR(ret));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -471,16 +474,17 @@ static bool _lspcon_write_avi_infoframe_mca(struct drm_dp_aux *aux,
|
|||
val &= ~LSPCON_MCA_AVI_IF_HANDLED;
|
||||
val |= LSPCON_MCA_AVI_IF_KICKOFF;
|
||||
|
||||
ret = drm_dp_dpcd_write(aux, reg, &val, 1);
|
||||
ret = drm_dp_dpcd_write_byte(aux, reg, val);
|
||||
if (ret < 0) {
|
||||
drm_err(aux->drm_dev, "DPCD read failed, address 0x%x\n", reg);
|
||||
drm_err(aux->drm_dev, "DPCD write failed at:0x%x (%pe)\n",
|
||||
reg, ERR_PTR(ret));
|
||||
return false;
|
||||
}
|
||||
|
||||
val = 0;
|
||||
ret = drm_dp_dpcd_read(aux, reg, &val, 1);
|
||||
ret = drm_dp_dpcd_read_byte(aux, reg, &val);
|
||||
if (ret < 0) {
|
||||
drm_err(aux->drm_dev, "DPCD read failed, address 0x%x\n", reg);
|
||||
drm_err(aux->drm_dev, "DPCD read failed, address 0x%x (%pe)\n",
|
||||
reg, ERR_PTR(ret));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -612,12 +616,13 @@ void lspcon_set_infoframes(struct intel_encoder *encoder,
|
|||
static bool _lspcon_read_avi_infoframe_enabled_mca(struct drm_dp_aux *aux)
|
||||
{
|
||||
int ret;
|
||||
u32 val = 0;
|
||||
u16 reg = LSPCON_MCA_AVI_IF_CTRL;
|
||||
u8 val;
|
||||
|
||||
ret = drm_dp_dpcd_read(aux, reg, &val, 1);
|
||||
ret = drm_dp_dpcd_read_byte(aux, reg, &val);
|
||||
if (ret < 0) {
|
||||
drm_err(aux->drm_dev, "DPCD read failed, address 0x%x\n", reg);
|
||||
drm_err(aux->drm_dev, "DPCD read failed, address 0x%x (%pe)\n",
|
||||
reg, ERR_PTR(ret));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -627,12 +632,13 @@ static bool _lspcon_read_avi_infoframe_enabled_mca(struct drm_dp_aux *aux)
|
|||
static bool _lspcon_read_avi_infoframe_enabled_parade(struct drm_dp_aux *aux)
|
||||
{
|
||||
int ret;
|
||||
u32 val = 0;
|
||||
u16 reg = LSPCON_PARADE_AVI_IF_CTRL;
|
||||
u8 val;
|
||||
|
||||
ret = drm_dp_dpcd_read(aux, reg, &val, 1);
|
||||
ret = drm_dp_dpcd_read_byte(aux, reg, &val);
|
||||
if (ret < 0) {
|
||||
drm_err(aux->drm_dev, "DPCD read failed, address 0x%x\n", reg);
|
||||
drm_err(aux->drm_dev, "DPCD read failed, address 0x%x (%pe)\n",
|
||||
reg, ERR_PTR(ret));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -94,9 +94,9 @@ void intel_parent_fb_pin_dpt_unpin(struct intel_display *display,
|
|||
struct i915_vma *intel_parent_fb_pin_reuse_vma(struct intel_display *display,
|
||||
struct i915_vma *old_ggtt_vma,
|
||||
struct drm_gem_object *old_obj,
|
||||
const struct i915_gtt_view *old_view,
|
||||
const struct intel_gtt_view *old_view,
|
||||
struct drm_gem_object *new_obj,
|
||||
const struct i915_gtt_view *new_view,
|
||||
const struct intel_gtt_view *new_view,
|
||||
u32 *out_offset)
|
||||
{
|
||||
if (!display->parent->fb_pin->reuse_vma)
|
||||
|
|
|
|||
|
|
@ -11,12 +11,12 @@ struct dma_fence;
|
|||
struct drm_file;
|
||||
struct drm_gem_object;
|
||||
struct drm_scanout_buffer;
|
||||
struct i915_gtt_view;
|
||||
struct i915_vma;
|
||||
struct intel_display;
|
||||
struct intel_dpt;
|
||||
struct intel_fb_pin_params;
|
||||
struct intel_frontbuffer;
|
||||
struct intel_gtt_view;
|
||||
struct intel_hdcp_gsc_context;
|
||||
struct intel_panic;
|
||||
struct intel_stolen_node;
|
||||
|
|
@ -53,9 +53,9 @@ void intel_parent_fb_pin_dpt_unpin(struct intel_display *display,
|
|||
struct i915_vma *intel_parent_fb_pin_reuse_vma(struct intel_display *display,
|
||||
struct i915_vma *old_ggtt_vma,
|
||||
struct drm_gem_object *old_obj,
|
||||
const struct i915_gtt_view *old_view,
|
||||
const struct intel_gtt_view *old_view,
|
||||
struct drm_gem_object *new_obj,
|
||||
const struct i915_gtt_view *new_view,
|
||||
const struct intel_gtt_view *new_view,
|
||||
u32 *out_offset);
|
||||
void intel_parent_fb_pin_get_map(struct intel_display *display,
|
||||
struct i915_vma *vma, struct iosys_map *map);
|
||||
|
|
|
|||
|
|
@ -462,6 +462,42 @@ intel_plane_colorop_replace_blob(struct intel_plane_state *plane_state,
|
|||
return false;
|
||||
}
|
||||
|
||||
static u32
|
||||
fixedmatrix_colorop_to_encoding(enum drm_colorop_fixed_matrix_type fm_type)
|
||||
{
|
||||
switch (fm_type) {
|
||||
case DRM_COLOROP_FM_YCBCR709_FULL_RGB:
|
||||
case DRM_COLOROP_FM_YCBCR709_LIMITED_RGB:
|
||||
return DRM_COLOR_YCBCR_BT709;
|
||||
|
||||
case DRM_COLOROP_FM_YCBCR2020_NC_FULL_RGB:
|
||||
case DRM_COLOROP_FM_YCBCR2020_NC_LIMITED_RGB:
|
||||
return DRM_COLOR_YCBCR_BT2020;
|
||||
|
||||
case DRM_COLOROP_FM_YCBCR601_FULL_RGB:
|
||||
case DRM_COLOROP_FM_YCBCR601_LIMITED_RGB:
|
||||
default:
|
||||
return DRM_COLOR_YCBCR_BT601;
|
||||
}
|
||||
}
|
||||
|
||||
static u32
|
||||
fixedmatrix_colorop_to_range(enum drm_colorop_fixed_matrix_type fm_type)
|
||||
{
|
||||
switch (fm_type) {
|
||||
case DRM_COLOROP_FM_YCBCR601_FULL_RGB:
|
||||
case DRM_COLOROP_FM_YCBCR709_FULL_RGB:
|
||||
case DRM_COLOROP_FM_YCBCR2020_NC_FULL_RGB:
|
||||
return DRM_COLOR_YCBCR_FULL_RANGE;
|
||||
|
||||
case DRM_COLOROP_FM_YCBCR601_LIMITED_RGB:
|
||||
case DRM_COLOROP_FM_YCBCR709_LIMITED_RGB:
|
||||
case DRM_COLOROP_FM_YCBCR2020_NC_LIMITED_RGB:
|
||||
default:
|
||||
return DRM_COLOR_YCBCR_LIMITED_RANGE;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
intel_plane_color_copy_uapi_to_hw_state(struct intel_atomic_state *state,
|
||||
struct intel_plane_state *plane_state,
|
||||
|
|
@ -474,6 +510,7 @@ intel_plane_color_copy_uapi_to_hw_state(struct intel_atomic_state *state,
|
|||
struct drm_property_blob *blob;
|
||||
struct intel_crtc_state *new_crtc_state = state ?
|
||||
intel_atomic_get_new_crtc_state(state, crtc) : NULL;
|
||||
enum drm_colorop_fixed_matrix_type fm_type;
|
||||
bool changed = false;
|
||||
int i = 0;
|
||||
|
||||
|
|
@ -485,11 +522,23 @@ intel_plane_color_copy_uapi_to_hw_state(struct intel_atomic_state *state,
|
|||
while (iter_colorop) {
|
||||
for_each_new_colorop_in_state(&state->base, colorop, new_colorop_state, i) {
|
||||
if (new_colorop_state->colorop == iter_colorop) {
|
||||
blob = new_colorop_state->bypass ? NULL : new_colorop_state->data;
|
||||
intel_colorop = to_intel_colorop(colorop);
|
||||
changed |= intel_plane_colorop_replace_blob(plane_state,
|
||||
if (intel_colorop->id == INTEL_PLANE_CB_CSC_FF) {
|
||||
fm_type = new_colorop_state->fixed_matrix_type;
|
||||
|
||||
plane_state->hw.csc_ff_enable =
|
||||
!new_colorop_state->bypass;
|
||||
plane_state->hw.color_encoding =
|
||||
fixedmatrix_colorop_to_encoding(fm_type);
|
||||
plane_state->hw.color_range =
|
||||
fixedmatrix_colorop_to_range(fm_type);
|
||||
} else {
|
||||
blob = new_colorop_state->bypass ?
|
||||
NULL : new_colorop_state->data;
|
||||
changed |= intel_plane_colorop_replace_blob(plane_state,
|
||||
intel_colorop,
|
||||
blob);
|
||||
}
|
||||
}
|
||||
}
|
||||
iter_colorop = iter_colorop->next;
|
||||
|
|
|
|||
|
|
@ -471,13 +471,15 @@ static u8 intel_dp_get_sink_sync_latency(struct intel_dp *intel_dp)
|
|||
{
|
||||
struct intel_display *display = to_intel_display(intel_dp);
|
||||
u8 val = 8; /* assume the worst if we can't read the value */
|
||||
int ret;
|
||||
|
||||
if (drm_dp_dpcd_readb(&intel_dp->aux,
|
||||
DP_SYNCHRONIZATION_LATENCY_IN_SINK, &val) == 1)
|
||||
ret = drm_dp_dpcd_read_byte(&intel_dp->aux, DP_SYNCHRONIZATION_LATENCY_IN_SINK, &val);
|
||||
if (!ret)
|
||||
val &= DP_MAX_RESYNC_FRAME_COUNT_MASK;
|
||||
else
|
||||
drm_dbg_kms(display->drm,
|
||||
"Unable to get sink synchronization latency, assuming 8 frames\n");
|
||||
"Unable to get sink synchronization latency, assuming 8 frames (%pe)\n",
|
||||
ERR_PTR(ret));
|
||||
return val;
|
||||
}
|
||||
|
||||
|
|
@ -485,7 +487,7 @@ static void _psr_compute_su_granularity(struct intel_dp *intel_dp,
|
|||
struct intel_connector *connector)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(intel_dp);
|
||||
ssize_t r;
|
||||
int ret;
|
||||
__le16 w;
|
||||
u8 y;
|
||||
|
||||
|
|
@ -500,21 +502,23 @@ static void _psr_compute_su_granularity(struct intel_dp *intel_dp,
|
|||
goto exit;
|
||||
}
|
||||
|
||||
r = drm_dp_dpcd_read(&intel_dp->aux, DP_PSR2_SU_X_GRANULARITY, &w, sizeof(w));
|
||||
if (r != sizeof(w))
|
||||
ret = drm_dp_dpcd_read_data(&intel_dp->aux, DP_PSR2_SU_X_GRANULARITY, &w, sizeof(w));
|
||||
if (ret < 0)
|
||||
drm_dbg_kms(display->drm,
|
||||
"Unable to read selective update x granularity\n");
|
||||
"Unable to read selective update x granularity (%pe)\n",
|
||||
ERR_PTR(ret));
|
||||
/*
|
||||
* Spec says that if the value read is 0 the default granularity should
|
||||
* be used instead.
|
||||
*/
|
||||
if (r != sizeof(w) || w == 0)
|
||||
if (ret < 0 || w == 0)
|
||||
w = cpu_to_le16(4);
|
||||
|
||||
r = drm_dp_dpcd_read(&intel_dp->aux, DP_PSR2_SU_Y_GRANULARITY, &y, 1);
|
||||
if (r != 1) {
|
||||
ret = drm_dp_dpcd_read_byte(&intel_dp->aux, DP_PSR2_SU_Y_GRANULARITY, &y);
|
||||
if (ret < 0) {
|
||||
drm_dbg_kms(display->drm,
|
||||
"Unable to read selective update y granularity\n");
|
||||
"Unable to read selective update y granularity (%pe)\n",
|
||||
ERR_PTR(ret));
|
||||
y = 4;
|
||||
}
|
||||
if (y == 0)
|
||||
|
|
@ -796,11 +800,11 @@ static void _panel_replay_enable_sink(struct intel_dp *intel_dp,
|
|||
panel_replay_config[1] |=
|
||||
DP_PANEL_REPLAY_SU_REGION_SCANLINE_CAPTURE;
|
||||
|
||||
drm_dp_dpcd_write(&intel_dp->aux, PANEL_REPLAY_CONFIG,
|
||||
panel_replay_config, sizeof(panel_replay_config));
|
||||
drm_dp_dpcd_write_data(&intel_dp->aux, PANEL_REPLAY_CONFIG,
|
||||
panel_replay_config, sizeof(panel_replay_config));
|
||||
|
||||
panel_replay_config_3 = intel_dp_as_sdp_transmission_time();
|
||||
drm_dp_dpcd_writeb(&intel_dp->aux, PANEL_REPLAY_CONFIG3, panel_replay_config_3);
|
||||
drm_dp_dpcd_write_byte(&intel_dp->aux, PANEL_REPLAY_CONFIG3, panel_replay_config_3);
|
||||
}
|
||||
|
||||
static void _psr_enable_sink(struct intel_dp *intel_dp,
|
||||
|
|
@ -827,10 +831,10 @@ static void _psr_enable_sink(struct intel_dp *intel_dp,
|
|||
|
||||
if (intel_dp->psr.entry_setup_frames > 0)
|
||||
val |= DP_PSR_FRAME_CAPTURE;
|
||||
drm_dp_dpcd_writeb(&intel_dp->aux, DP_PSR_EN_CFG, val);
|
||||
drm_dp_dpcd_write_byte(&intel_dp->aux, DP_PSR_EN_CFG, val);
|
||||
|
||||
val |= DP_PSR_ENABLE;
|
||||
drm_dp_dpcd_writeb(&intel_dp->aux, DP_PSR_EN_CFG, val);
|
||||
drm_dp_dpcd_write_byte(&intel_dp->aux, DP_PSR_EN_CFG, val);
|
||||
}
|
||||
|
||||
static void intel_psr_enable_sink(struct intel_dp *intel_dp,
|
||||
|
|
@ -843,7 +847,7 @@ static void intel_psr_enable_sink(struct intel_dp *intel_dp,
|
|||
_psr_enable_sink(intel_dp, crtc_state);
|
||||
|
||||
if (intel_dp_is_edp(intel_dp))
|
||||
drm_dp_dpcd_writeb(&intel_dp->aux, DP_SET_POWER, DP_SET_POWER_D0);
|
||||
drm_dp_dpcd_write_byte(&intel_dp->aux, DP_SET_POWER, DP_SET_POWER_D0);
|
||||
}
|
||||
|
||||
void intel_psr_panel_replay_enable_sink(struct intel_dp *intel_dp)
|
||||
|
|
@ -854,8 +858,8 @@ void intel_psr_panel_replay_enable_sink(struct intel_dp *intel_dp)
|
|||
* ensure this bit is cleared/set accordingly.
|
||||
*/
|
||||
if (CAN_PANEL_REPLAY(intel_dp) && panel_replay_global_enabled(intel_dp))
|
||||
drm_dp_dpcd_writeb(&intel_dp->aux, PANEL_REPLAY_CONFIG,
|
||||
DP_PANEL_REPLAY_ENABLE);
|
||||
drm_dp_dpcd_write_byte(&intel_dp->aux, PANEL_REPLAY_CONFIG,
|
||||
DP_PANEL_REPLAY_ENABLE);
|
||||
}
|
||||
|
||||
static u32 intel_psr1_get_tp_time(struct intel_dp *intel_dp)
|
||||
|
|
@ -2373,11 +2377,11 @@ static void intel_psr_disable_locked(struct intel_dp *intel_dp)
|
|||
|
||||
/* Disable PSR on Sink */
|
||||
if (!intel_dp->psr.panel_replay_enabled) {
|
||||
drm_dp_dpcd_writeb(&intel_dp->aux, DP_PSR_EN_CFG, 0);
|
||||
drm_dp_dpcd_write_byte(&intel_dp->aux, DP_PSR_EN_CFG, 0);
|
||||
|
||||
if (intel_dp->psr.sel_update_enabled)
|
||||
drm_dp_dpcd_writeb(&intel_dp->aux,
|
||||
DP_RECEIVER_ALPM_CONFIG, 0);
|
||||
drm_dp_dpcd_write_byte(&intel_dp->aux,
|
||||
DP_RECEIVER_ALPM_CONFIG, 0);
|
||||
}
|
||||
|
||||
/* Wa_16025596647 */
|
||||
|
|
@ -3517,7 +3521,7 @@ static void intel_psr_handle_irq(struct intel_dp *intel_dp)
|
|||
intel_psr_disable_locked(intel_dp);
|
||||
psr->sink_not_reliable = true;
|
||||
/* let's make sure that sink is awaken */
|
||||
drm_dp_dpcd_writeb(&intel_dp->aux, DP_SET_POWER, DP_SET_POWER_D0);
|
||||
drm_dp_dpcd_write_byte(&intel_dp->aux, DP_SET_POWER, DP_SET_POWER_D0);
|
||||
}
|
||||
|
||||
static void intel_psr_work(struct work_struct *work)
|
||||
|
|
@ -3796,15 +3800,15 @@ static int psr_get_status_and_error_status(struct intel_dp *intel_dp,
|
|||
offset = intel_dp->psr.panel_replay_enabled ?
|
||||
DP_SINK_DEVICE_PR_AND_FRAME_LOCK_STATUS : DP_PSR_STATUS;
|
||||
|
||||
ret = drm_dp_dpcd_readb(aux, offset, status);
|
||||
if (ret != 1)
|
||||
ret = drm_dp_dpcd_read_byte(aux, offset, status);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
offset = intel_dp->psr.panel_replay_enabled ?
|
||||
DP_PANEL_REPLAY_ERROR_STATUS : DP_PSR_ERROR_STATUS;
|
||||
|
||||
ret = drm_dp_dpcd_readb(aux, offset, error_status);
|
||||
if (ret != 1)
|
||||
ret = drm_dp_dpcd_read_byte(aux, offset, error_status);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
*status = *status & DP_PSR_SINK_STATE_MASK;
|
||||
|
|
@ -3829,12 +3833,12 @@ static void psr_capability_changed_check(struct intel_dp *intel_dp)
|
|||
{
|
||||
struct intel_display *display = to_intel_display(intel_dp);
|
||||
struct intel_psr *psr = &intel_dp->psr;
|
||||
int ret;
|
||||
u8 val;
|
||||
int r;
|
||||
|
||||
r = drm_dp_dpcd_readb(&intel_dp->aux, DP_PSR_ESI, &val);
|
||||
if (r != 1) {
|
||||
drm_err(display->drm, "Error reading DP_PSR_ESI\n");
|
||||
ret = drm_dp_dpcd_read_byte(&intel_dp->aux, DP_PSR_ESI, &val);
|
||||
if (ret < 0) {
|
||||
drm_err(display->drm, "Error reading DP_PSR_ESI (%pe)\n", ERR_PTR(ret));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -3845,7 +3849,7 @@ static void psr_capability_changed_check(struct intel_dp *intel_dp)
|
|||
"Sink PSR capability changed, disabling PSR\n");
|
||||
|
||||
/* Clearing it */
|
||||
drm_dp_dpcd_writeb(&intel_dp->aux, DP_PSR_ESI, val);
|
||||
drm_dp_dpcd_write_byte(&intel_dp->aux, DP_PSR_ESI, val);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3913,10 +3917,10 @@ void intel_psr_short_pulse(struct intel_dp *intel_dp)
|
|||
"PSR_ERROR_STATUS unhandled errors %x\n",
|
||||
error_status & ~errors);
|
||||
/* clear status register */
|
||||
drm_dp_dpcd_writeb(&intel_dp->aux,
|
||||
panel_replay_enabled ?
|
||||
DP_PANEL_REPLAY_ERROR_STATUS : DP_PSR_ERROR_STATUS,
|
||||
error_status);
|
||||
drm_dp_dpcd_write_byte(&intel_dp->aux,
|
||||
panel_replay_enabled ?
|
||||
DP_PANEL_REPLAY_ERROR_STATUS : DP_PSR_ERROR_STATUS,
|
||||
error_status);
|
||||
|
||||
if (!psr->panel_replay_enabled) {
|
||||
psr_alpm_check(intel_dp);
|
||||
|
|
|
|||
|
|
@ -276,6 +276,8 @@
|
|||
#define PR_ALPM_CTL_ADAPTIVE_SYNC_SDP_POSITION_T1_OR_T2 REG_FIELD_PREP(PR_ALPM_CTL_ADAPTIVE_SYNC_SDP_POSITION_MASK, 0)
|
||||
#define PR_ALPM_CTL_ADAPTIVE_SYNC_SDP_POSITION_T1 REG_FIELD_PREP(PR_ALPM_CTL_ADAPTIVE_SYNC_SDP_POSITION_MASK, 1)
|
||||
#define PR_ALPM_CTL_ADAPTIVE_SYNC_SDP_POSITION_T2 REG_FIELD_PREP(PR_ALPM_CTL_ADAPTIVE_SYNC_SDP_POSITION_MASK, 2)
|
||||
#define PR_ALPM_CTL_AS_SDP_SKIP_FRAMES_MASK REG_GENMASK(27, 16)
|
||||
#define PR_ALPM_CTL_AS_SDP_SKIP_FRAMES(frames) REG_FIELD_PREP(PR_ALPM_CTL_AS_SDP_SKIP_FRAMES_MASK, (frames))
|
||||
|
||||
#define _ALPM_CTL_A 0x60950
|
||||
#define ALPM_CTL(dev_priv, tran) _MMIO_TRANS2(dev_priv, tran, _ALPM_CTL_A)
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@
|
|||
#include "intel_cmtg.h"
|
||||
#include "intel_crtc.h"
|
||||
#include "intel_de.h"
|
||||
#include "intel_dip.h"
|
||||
#include "intel_dip_regs.h"
|
||||
#include "intel_display_limits.h"
|
||||
#include "intel_display_regs.h"
|
||||
#include "intel_display_types.h"
|
||||
|
|
@ -712,17 +714,7 @@ void intel_vrr_set_transcoder_timings(const struct intel_crtc_state *crtc_state)
|
|||
VRR_VSYNC_END(crtc_state->vrr.vsync_end) |
|
||||
VRR_VSYNC_START(crtc_state->vrr.vsync_start));
|
||||
|
||||
/*
|
||||
* For BMG and LNL+ onwards the EMP_AS_SDP_TL is used for programming
|
||||
* double buffering point and transmission line for VRR packets for
|
||||
* HDMI2.1/DP/eDP/DP->HDMI2.1 PCON.
|
||||
* Since currently we support VRR only for DP/eDP, so this is programmed
|
||||
* to for Adaptive Sync SDP to Vsync start.
|
||||
*/
|
||||
if (DISPLAY_VERx100(display) == 1401 || DISPLAY_VER(display) >= 20)
|
||||
intel_de_write(display,
|
||||
EMP_AS_SDP_TL(display, cpu_transcoder),
|
||||
EMP_AS_SDP_DB_TL(crtc_state->vrr.vsync_start));
|
||||
intel_dip_write_emp_as_sdp_tl(crtc_state);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -174,12 +174,6 @@
|
|||
#define VRR_VSYNC_START_MASK REG_GENMASK(12, 0)
|
||||
#define VRR_VSYNC_START(vsync_start) REG_FIELD_PREP(VRR_VSYNC_START_MASK, (vsync_start))
|
||||
|
||||
/* Common register for HDMI EMP and DP AS SDP */
|
||||
#define _EMP_AS_SDP_TL_A 0x60204
|
||||
#define EMP_AS_SDP_TL(display, trans) _MMIO_TRANS2((display), (trans), _EMP_AS_SDP_TL_A)
|
||||
#define EMP_AS_SDP_DB_TL_MASK REG_GENMASK(12, 0)
|
||||
#define EMP_AS_SDP_DB_TL(db_transmit_line) REG_FIELD_PREP(EMP_AS_SDP_DB_TL_MASK, (db_transmit_line))
|
||||
|
||||
#define _TRANS_CMRR_M_LO_A 0x604F0
|
||||
#define TRANS_CMRR_M_LO(display, trans) _MMIO_TRANS2((display), (trans), _TRANS_CMRR_M_LO_A)
|
||||
|
||||
|
|
|
|||
|
|
@ -1242,36 +1242,46 @@ static u32 glk_plane_color_ctl_crtc(const struct intel_crtc_state *crtc_state)
|
|||
return plane_color_ctl;
|
||||
}
|
||||
|
||||
static u32 glk_plane_color_ctl(const struct intel_plane_state *plane_state)
|
||||
static u32 glk_plane_color_ctl_input_csc(const struct intel_plane_state *plane_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(plane_state);
|
||||
const struct drm_framebuffer *fb = plane_state->hw.fb;
|
||||
struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
|
||||
bool color_pipeline = !!plane_state->uapi.color_pipeline;
|
||||
bool needs_csc = color_pipeline ? plane_state->hw.csc_ff_enable : fb->format->is_yuv;
|
||||
u32 ctl = 0;
|
||||
|
||||
if (!needs_csc)
|
||||
return 0;
|
||||
|
||||
if (!icl_is_hdr_plane(display, plane->id)) {
|
||||
switch (plane_state->hw.color_encoding) {
|
||||
case DRM_COLOR_YCBCR_BT709:
|
||||
ctl |= PLANE_COLOR_CSC_MODE_YUV709_TO_RGB709;
|
||||
break;
|
||||
case DRM_COLOR_YCBCR_BT2020:
|
||||
ctl |= PLANE_COLOR_CSC_MODE_YUV2020_TO_RGB2020;
|
||||
break;
|
||||
default:
|
||||
ctl |= PLANE_COLOR_CSC_MODE_YUV601_TO_RGB601;
|
||||
}
|
||||
} else {
|
||||
ctl |= PLANE_COLOR_INPUT_CSC_ENABLE;
|
||||
}
|
||||
|
||||
if (plane_state->hw.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
|
||||
ctl |= PLANE_COLOR_YUV_RANGE_CORRECTION_DISABLE;
|
||||
|
||||
return ctl;
|
||||
}
|
||||
|
||||
static u32 glk_plane_color_ctl(const struct intel_plane_state *plane_state)
|
||||
{
|
||||
u32 plane_color_ctl = 0;
|
||||
|
||||
plane_color_ctl |= PLANE_COLOR_PLANE_GAMMA_DISABLE;
|
||||
plane_color_ctl |= glk_plane_color_ctl_alpha(plane_state);
|
||||
|
||||
if (fb->format->is_yuv && !icl_is_hdr_plane(display, plane->id)) {
|
||||
switch (plane_state->hw.color_encoding) {
|
||||
case DRM_COLOR_YCBCR_BT709:
|
||||
plane_color_ctl |= PLANE_COLOR_CSC_MODE_YUV709_TO_RGB709;
|
||||
break;
|
||||
case DRM_COLOR_YCBCR_BT2020:
|
||||
plane_color_ctl |=
|
||||
PLANE_COLOR_CSC_MODE_YUV2020_TO_RGB2020;
|
||||
break;
|
||||
default:
|
||||
plane_color_ctl |=
|
||||
PLANE_COLOR_CSC_MODE_YUV601_TO_RGB601;
|
||||
}
|
||||
if (plane_state->hw.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
|
||||
plane_color_ctl |= PLANE_COLOR_YUV_RANGE_CORRECTION_DISABLE;
|
||||
} else if (fb->format->is_yuv) {
|
||||
plane_color_ctl |= PLANE_COLOR_INPUT_CSC_ENABLE;
|
||||
if (plane_state->hw.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
|
||||
plane_color_ctl |= PLANE_COLOR_YUV_RANGE_CORRECTION_DISABLE;
|
||||
}
|
||||
plane_color_ctl |= glk_plane_color_ctl_input_csc(plane_state);
|
||||
|
||||
if (plane_state->force_black)
|
||||
plane_color_ctl |= PLANE_COLOR_PLANE_CSC_ENABLE;
|
||||
|
|
@ -1613,7 +1623,8 @@ icl_plane_update_noarm(struct intel_dsb *dsb,
|
|||
intel_de_write_dsb(display, dsb, PLANE_COLOR_CTL(pipe, plane_id),
|
||||
plane_color_ctl);
|
||||
|
||||
if (fb->format->is_yuv && icl_is_hdr_plane(display, plane_id))
|
||||
if (icl_is_hdr_plane(display, plane_id) &&
|
||||
(fb->format->is_yuv || plane_state->hw.csc_ff_enable))
|
||||
icl_program_input_csc(dsb, plane, plane_state);
|
||||
|
||||
skl_write_plane_wm(dsb, plane, crtc_state);
|
||||
|
|
|
|||
|
|
@ -421,7 +421,7 @@ struct i915_vma *
|
|||
i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj,
|
||||
struct i915_gem_ww_ctx *ww,
|
||||
u32 alignment, unsigned int guard,
|
||||
const struct i915_gtt_view *view,
|
||||
const struct intel_gtt_view *view,
|
||||
unsigned int flags)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(obj->base.dev);
|
||||
|
|
@ -462,7 +462,7 @@ i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj,
|
|||
*/
|
||||
vma = ERR_PTR(-ENOSPC);
|
||||
if ((flags & PIN_MAPPABLE) == 0 &&
|
||||
(!view || view->type == I915_GTT_VIEW_NORMAL))
|
||||
(!view || intel_gtt_view_is_normal(view)))
|
||||
vma = i915_gem_object_ggtt_pin_ww(obj, ww, view, 0, alignment,
|
||||
flags | PIN_MAPPABLE |
|
||||
PIN_NONBLOCK);
|
||||
|
|
|
|||
|
|
@ -196,17 +196,17 @@ int i915_gem_mmap_gtt_version(void)
|
|||
return 5;
|
||||
}
|
||||
|
||||
static inline struct i915_gtt_view
|
||||
static inline struct intel_gtt_view
|
||||
compute_partial_view(const struct drm_i915_gem_object *obj,
|
||||
pgoff_t page_offset,
|
||||
unsigned int chunk)
|
||||
{
|
||||
struct i915_gtt_view view;
|
||||
struct intel_gtt_view view;
|
||||
|
||||
if (i915_gem_object_is_tiled(obj))
|
||||
chunk = roundup(chunk, tile_row_pages(obj) ?: 1);
|
||||
|
||||
view.type = I915_GTT_VIEW_PARTIAL;
|
||||
view.type = INTEL_GTT_VIEW_PARTIAL;
|
||||
view.partial.offset = rounddown(page_offset, chunk);
|
||||
view.partial.size =
|
||||
min_t(unsigned int, chunk,
|
||||
|
|
@ -214,7 +214,7 @@ compute_partial_view(const struct drm_i915_gem_object *obj,
|
|||
|
||||
/* If the partial covers the entire object, just create a normal VMA. */
|
||||
if (chunk >= obj->base.size >> PAGE_SHIFT)
|
||||
view.type = I915_GTT_VIEW_NORMAL;
|
||||
view.type = INTEL_GTT_VIEW_NORMAL;
|
||||
|
||||
return view;
|
||||
}
|
||||
|
|
@ -391,12 +391,12 @@ static vm_fault_t vm_fault_gtt(struct vm_fault *vmf)
|
|||
PIN_NOEVICT);
|
||||
if (IS_ERR(vma) && vma != ERR_PTR(-EDEADLK)) {
|
||||
/* Use a partial view if it is bigger than available space */
|
||||
struct i915_gtt_view view =
|
||||
struct intel_gtt_view view =
|
||||
compute_partial_view(obj, page_offset, MIN_CHUNK_PAGES);
|
||||
unsigned int flags;
|
||||
|
||||
flags = PIN_MAPPABLE | PIN_NOSEARCH;
|
||||
if (view.type == I915_GTT_VIEW_NORMAL)
|
||||
if (intel_gtt_view_is_normal(&view))
|
||||
flags |= PIN_NONBLOCK; /* avoid warnings for pinned */
|
||||
|
||||
/*
|
||||
|
|
@ -407,7 +407,7 @@ static vm_fault_t vm_fault_gtt(struct vm_fault *vmf)
|
|||
vma = i915_gem_object_ggtt_pin_ww(obj, &ww, &view, 0, 0, flags);
|
||||
if (IS_ERR(vma) && vma != ERR_PTR(-EDEADLK)) {
|
||||
flags = PIN_MAPPABLE;
|
||||
view.type = I915_GTT_VIEW_PARTIAL;
|
||||
view.type = INTEL_GTT_VIEW_PARTIAL;
|
||||
vma = i915_gem_object_ggtt_pin_ww(obj, &ww, &view, 0, 0, flags);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -776,7 +776,7 @@ struct i915_vma * __must_check
|
|||
i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj,
|
||||
struct i915_gem_ww_ctx *ww,
|
||||
u32 alignment, unsigned int guard,
|
||||
const struct i915_gtt_view *view,
|
||||
const struct intel_gtt_view *view,
|
||||
unsigned int flags);
|
||||
|
||||
void i915_gem_object_make_unshrinkable(struct drm_i915_gem_object *obj);
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ static int check_partial_mapping(struct drm_i915_gem_object *obj,
|
|||
{
|
||||
const unsigned long npages = obj->base.size / PAGE_SIZE;
|
||||
struct drm_i915_private *i915 = to_i915(obj->base.dev);
|
||||
struct i915_gtt_view view;
|
||||
struct intel_gtt_view view;
|
||||
struct i915_vma *vma;
|
||||
unsigned long offset;
|
||||
unsigned long page;
|
||||
|
|
@ -214,7 +214,7 @@ static int check_partial_mappings(struct drm_i915_gem_object *obj,
|
|||
}
|
||||
|
||||
for_each_prime_number_from(page, 1, npages) {
|
||||
struct i915_gtt_view view =
|
||||
struct intel_gtt_view view =
|
||||
compute_partial_view(obj, page, MIN_CHUNK_PAGES);
|
||||
unsigned long offset;
|
||||
u32 __iomem *io;
|
||||
|
|
|
|||
|
|
@ -1607,7 +1607,7 @@ u64 intel_engine_get_last_batch_head(const struct intel_engine_cs *engine)
|
|||
|
||||
static unsigned long stop_timeout(const struct intel_engine_cs *engine)
|
||||
{
|
||||
if (in_atomic() || irqs_disabled()) /* inside atomic preempt-reset? */
|
||||
if (in_atomic() || irqs_disabled() || rcu_preempt_depth()) /* inside atomic preempt-reset? */
|
||||
return 0;
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -1300,7 +1300,7 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
|
|||
* and context switches) submission.
|
||||
*/
|
||||
|
||||
spin_lock(&sched_engine->lock);
|
||||
spin_lock_irq(&sched_engine->lock);
|
||||
|
||||
/*
|
||||
* If the queue is higher priority than the last
|
||||
|
|
@ -1400,7 +1400,7 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
|
|||
* Even if ELSP[1] is occupied and not worthy
|
||||
* of timeslices, our queue might be.
|
||||
*/
|
||||
spin_unlock(&sched_engine->lock);
|
||||
spin_unlock_irq(&sched_engine->lock);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -1426,7 +1426,7 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
|
|||
|
||||
if (last && !can_merge_rq(last, rq)) {
|
||||
spin_unlock(&ve->base.sched_engine->lock);
|
||||
spin_unlock(&engine->sched_engine->lock);
|
||||
spin_unlock_irq(&engine->sched_engine->lock);
|
||||
return; /* leave this for another sibling */
|
||||
}
|
||||
|
||||
|
|
@ -1588,7 +1588,7 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
|
|||
*/
|
||||
sched_engine->queue_priority_hint = queue_prio(sched_engine);
|
||||
i915_sched_engine_reset_on_empty(sched_engine);
|
||||
spin_unlock(&sched_engine->lock);
|
||||
spin_unlock_irq(&sched_engine->lock);
|
||||
|
||||
/*
|
||||
* We can skip poking the HW if we ended up with exactly the same set
|
||||
|
|
@ -1614,13 +1614,6 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
|
|||
}
|
||||
}
|
||||
|
||||
static void execlists_dequeue_irq(struct intel_engine_cs *engine)
|
||||
{
|
||||
local_irq_disable(); /* Suspend interrupts across request submission */
|
||||
execlists_dequeue(engine);
|
||||
local_irq_enable(); /* flush irq_work (e.g. breadcrumb enabling) */
|
||||
}
|
||||
|
||||
static void clear_ports(struct i915_request **ports, int count)
|
||||
{
|
||||
memset_p((void **)ports, NULL, count);
|
||||
|
|
@ -2475,7 +2468,7 @@ static void execlists_submission_tasklet(struct tasklet_struct *t)
|
|||
}
|
||||
|
||||
if (!engine->execlists.pending[0]) {
|
||||
execlists_dequeue_irq(engine);
|
||||
execlists_dequeue(engine);
|
||||
start_timeslice(engine);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1433,13 +1433,7 @@ static void intel_gt_reset_global(struct intel_gt *gt,
|
|||
need_display_reset;
|
||||
|
||||
if (reset_display) {
|
||||
if (atomic_read(&i915->pending_fb_pin)) {
|
||||
drm_dbg_kms(&i915->drm,
|
||||
"Modeset potentially stuck, unbreaking through wedging\n");
|
||||
|
||||
intel_gt_set_wedged(gt);
|
||||
}
|
||||
|
||||
intel_gt_set_wedged(gt);
|
||||
intel_display_reset_prepare(display);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -277,11 +277,11 @@ static int live_engine_busy_stats(void *arg)
|
|||
st_engine_heartbeat_disable(engine);
|
||||
|
||||
ENGINE_TRACE(engine, "measuring idle time\n");
|
||||
preempt_disable();
|
||||
migrate_disable();
|
||||
de = intel_engine_get_busy_time(engine, &t[0]);
|
||||
udelay(100);
|
||||
de = ktime_sub(intel_engine_get_busy_time(engine, &t[1]), de);
|
||||
preempt_enable();
|
||||
migrate_enable();
|
||||
dt = ktime_sub(t[1], t[0]);
|
||||
if (de < 0 || de > 10) {
|
||||
pr_err("%s: reported %lldns [%d%%] busyness while sleeping [for %lldns]\n",
|
||||
|
|
@ -316,11 +316,11 @@ static int live_engine_busy_stats(void *arg)
|
|||
}
|
||||
|
||||
ENGINE_TRACE(engine, "measuring busy time\n");
|
||||
preempt_disable();
|
||||
migrate_disable();
|
||||
de = intel_engine_get_busy_time(engine, &t[0]);
|
||||
mdelay(100);
|
||||
de = ktime_sub(intel_engine_get_busy_time(engine, &t[1]), de);
|
||||
preempt_enable();
|
||||
migrate_enable();
|
||||
dt = ktime_sub(t[1], t[0]);
|
||||
if (100 * de < 95 * dt || 95 * de > 100 * dt) {
|
||||
pr_err("%s: reported %lldns [%d%%] busyness while spinning [for %lldns]\n",
|
||||
|
|
|
|||
|
|
@ -362,7 +362,7 @@ static inline int intel_guc_send_busy_loop(struct intel_guc *guc,
|
|||
{
|
||||
int err;
|
||||
unsigned int sleep_period_ms = 1;
|
||||
bool not_atomic = !in_atomic() && !irqs_disabled();
|
||||
bool not_atomic = !in_atomic() && !irqs_disabled() && !rcu_preempt_depth();
|
||||
|
||||
/*
|
||||
* FIXME: Have caller pass in if we are in an atomic context to avoid
|
||||
|
|
|
|||
|
|
@ -34,6 +34,8 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include <linux/string_choices.h>
|
||||
|
||||
#include <drm/drm_print.h>
|
||||
|
||||
#include "gt/intel_ggtt_fencing.h"
|
||||
|
|
@ -76,7 +78,7 @@ static int alloc_gm(struct intel_vgpu *vgpu, bool high_gm)
|
|||
mutex_unlock(>->ggtt->vm.mutex);
|
||||
if (ret)
|
||||
gvt_err("fail to alloc %s gm space from host\n",
|
||||
high_gm ? "high" : "low");
|
||||
str_high_low(high_gm));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -179,7 +179,7 @@ i915_debugfs_describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
|
|||
struct i915_vma *vma;
|
||||
int pin_count = 0;
|
||||
|
||||
seq_printf(m, "%pK: %c%c%c %8zdKiB %02x %02x %s%s%s",
|
||||
seq_printf(m, "%p: %c%c%c %8zdKiB %02x %02x %s%s%s",
|
||||
&obj->base,
|
||||
get_tiling_flag(obj),
|
||||
get_global_flag(obj),
|
||||
|
|
@ -209,18 +209,13 @@ i915_debugfs_describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
|
|||
stringify_page_sizes(vma->resource->page_sizes_gtt,
|
||||
NULL, 0));
|
||||
if (i915_vma_is_ggtt(vma) || i915_vma_is_dpt(vma)) {
|
||||
switch (vma->gtt_view.type) {
|
||||
case I915_GTT_VIEW_NORMAL:
|
||||
if (intel_gtt_view_is_normal(&vma->gtt_view)) {
|
||||
seq_puts(m, ", normal");
|
||||
break;
|
||||
|
||||
case I915_GTT_VIEW_PARTIAL:
|
||||
} else if (intel_gtt_view_is_partial(&vma->gtt_view)) {
|
||||
seq_printf(m, ", partial [%08llx+%x]",
|
||||
vma->gtt_view.partial.offset << PAGE_SHIFT,
|
||||
vma->gtt_view.partial.size << PAGE_SHIFT);
|
||||
break;
|
||||
|
||||
case I915_GTT_VIEW_ROTATED:
|
||||
} else if (intel_gtt_view_is_rotated(&vma->gtt_view)) {
|
||||
seq_printf(m, ", rotated [(%ux%u, src_stride=%u, dst_stride=%u, offset=%u), (%ux%u, src_stride=%u, dst_stride=%u, offset=%u)]",
|
||||
vma->gtt_view.rotated.plane[0].width,
|
||||
vma->gtt_view.rotated.plane[0].height,
|
||||
|
|
@ -232,9 +227,7 @@ i915_debugfs_describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
|
|||
vma->gtt_view.rotated.plane[1].src_stride,
|
||||
vma->gtt_view.rotated.plane[1].dst_stride,
|
||||
vma->gtt_view.rotated.plane[1].offset);
|
||||
break;
|
||||
|
||||
case I915_GTT_VIEW_REMAPPED:
|
||||
} else if (intel_gtt_view_is_remapped(&vma->gtt_view)) {
|
||||
seq_printf(m, ", remapped [(%ux%u, src_stride=%u, dst_stride=%u, offset=%u), (%ux%u, src_stride=%u, dst_stride=%u, offset=%u)]",
|
||||
vma->gtt_view.remapped.plane[0].width,
|
||||
vma->gtt_view.remapped.plane[0].height,
|
||||
|
|
@ -246,11 +239,8 @@ i915_debugfs_describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
|
|||
vma->gtt_view.remapped.plane[1].src_stride,
|
||||
vma->gtt_view.remapped.plane[1].dst_stride,
|
||||
vma->gtt_view.remapped.plane[1].offset);
|
||||
break;
|
||||
|
||||
default:
|
||||
} else {
|
||||
MISSING_CASE(vma->gtt_view.type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (vma->fence)
|
||||
|
|
|
|||
|
|
@ -139,7 +139,6 @@ struct i915_vma *i915_dpt_pin_to_ggtt(struct intel_dpt *dpt, unsigned int alignm
|
|||
pin_flags |= PIN_MAPPABLE;
|
||||
|
||||
wakeref = intel_runtime_pm_get(&i915->runtime_pm);
|
||||
atomic_inc(&i915->pending_fb_pin);
|
||||
|
||||
for_i915_gem_ww(&ww, err, true) {
|
||||
err = i915_gem_object_lock(dpt->obj, &ww);
|
||||
|
|
@ -169,7 +168,6 @@ struct i915_vma *i915_dpt_pin_to_ggtt(struct intel_dpt *dpt, unsigned int alignm
|
|||
|
||||
dpt->obj->mm.dirty = true;
|
||||
|
||||
atomic_dec(&i915->pending_fb_pin);
|
||||
intel_runtime_pm_put(&i915->runtime_pm, wakeref);
|
||||
|
||||
return err ? ERR_PTR(err) : vma;
|
||||
|
|
|
|||
|
|
@ -315,8 +315,6 @@ struct drm_i915_private {
|
|||
/* The TTM device structure. */
|
||||
struct ttm_device bdev;
|
||||
|
||||
atomic_t pending_fb_pin;
|
||||
|
||||
I915_SELFTEST_DECLARE(struct i915_selftest_stash selftest;)
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -35,8 +35,6 @@ intel_fb_pin_to_dpt(struct drm_gem_object *_obj, struct intel_dpt *dpt,
|
|||
if (WARN_ON(!i915_gem_object_is_framebuffer(obj)))
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
atomic_inc(&i915->pending_fb_pin);
|
||||
|
||||
for_i915_gem_ww(&ww, ret, true) {
|
||||
ret = i915_gem_object_lock(obj, &ww);
|
||||
if (ret)
|
||||
|
|
@ -98,7 +96,6 @@ intel_fb_pin_to_dpt(struct drm_gem_object *_obj, struct intel_dpt *dpt,
|
|||
*/
|
||||
drm_WARN_ON(&i915->drm, i915_dpt_offset(vma));
|
||||
err:
|
||||
atomic_dec(&i915->pending_fb_pin);
|
||||
|
||||
return vma;
|
||||
}
|
||||
|
|
@ -132,8 +129,6 @@ intel_fb_pin_to_ggtt(struct drm_gem_object *_obj,
|
|||
*/
|
||||
wakeref = intel_runtime_pm_get(&i915->runtime_pm);
|
||||
|
||||
atomic_inc(&i915->pending_fb_pin);
|
||||
|
||||
pinctl = 0;
|
||||
/* PIN_MAPPABLE limits the address to GMADR size */
|
||||
if (pin_params->needs_low_address)
|
||||
|
|
@ -206,7 +201,6 @@ intel_fb_pin_to_ggtt(struct drm_gem_object *_obj,
|
|||
if (ret)
|
||||
vma = ERR_PTR(ret);
|
||||
|
||||
atomic_dec(&i915->pending_fb_pin);
|
||||
intel_runtime_pm_put(&i915->runtime_pm, wakeref);
|
||||
return vma;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -902,7 +902,7 @@ static void discard_ggtt_vma(struct i915_vma *vma)
|
|||
struct i915_vma *
|
||||
i915_gem_object_ggtt_pin_ww(struct drm_i915_gem_object *obj,
|
||||
struct i915_gem_ww_ctx *ww,
|
||||
const struct i915_gtt_view *view,
|
||||
const struct intel_gtt_view *view,
|
||||
u64 size, u64 alignment, u64 flags)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(obj->base.dev);
|
||||
|
|
@ -913,7 +913,7 @@ i915_gem_object_ggtt_pin_ww(struct drm_i915_gem_object *obj,
|
|||
GEM_WARN_ON(!ww);
|
||||
|
||||
if (flags & PIN_MAPPABLE &&
|
||||
(!view || view->type == I915_GTT_VIEW_NORMAL)) {
|
||||
(!view || intel_gtt_view_is_normal(view))) {
|
||||
/*
|
||||
* If the required space is larger than the available
|
||||
* aperture, we will not able to find a slot for the
|
||||
|
|
@ -1004,7 +1004,7 @@ i915_gem_object_ggtt_pin_ww(struct drm_i915_gem_object *obj,
|
|||
|
||||
struct i915_vma * __must_check
|
||||
i915_gem_object_ggtt_pin(struct drm_i915_gem_object *obj,
|
||||
const struct i915_gtt_view *view,
|
||||
const struct intel_gtt_view *view,
|
||||
u64 size, u64 alignment, u64 flags)
|
||||
{
|
||||
struct i915_gem_ww_ctx ww;
|
||||
|
|
|
|||
|
|
@ -36,8 +36,8 @@ struct drm_file;
|
|||
struct drm_i915_gem_object;
|
||||
struct drm_i915_private;
|
||||
struct i915_gem_ww_ctx;
|
||||
struct i915_gtt_view;
|
||||
struct i915_vma;
|
||||
struct intel_gtt_view;
|
||||
|
||||
#define I915_GEM_GPU_DOMAINS \
|
||||
(I915_GEM_DOMAIN_RENDER | \
|
||||
|
|
@ -55,12 +55,12 @@ void i915_gem_drain_workqueue(struct drm_i915_private *i915);
|
|||
struct i915_vma * __must_check
|
||||
i915_gem_object_ggtt_pin_ww(struct drm_i915_gem_object *obj,
|
||||
struct i915_gem_ww_ctx *ww,
|
||||
const struct i915_gtt_view *view,
|
||||
const struct intel_gtt_view *view,
|
||||
u64 size, u64 alignment, u64 flags);
|
||||
|
||||
struct i915_vma * __must_check
|
||||
i915_gem_object_ggtt_pin(struct drm_i915_gem_object *obj,
|
||||
const struct i915_gtt_view *view,
|
||||
const struct intel_gtt_view *view,
|
||||
u64 size, u64 alignment, u64 flags);
|
||||
|
||||
int i915_gem_object_unbind(struct drm_i915_gem_object *obj,
|
||||
|
|
|
|||
|
|
@ -1,74 +0,0 @@
|
|||
/* SPDX-License-Identifier: MIT */
|
||||
/* Copyright © 2025 Intel Corporation */
|
||||
|
||||
#ifndef __I915_GTT_VIEW_TYPES_H__
|
||||
#define __I915_GTT_VIEW_TYPES_H__
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
struct intel_remapped_plane_info {
|
||||
/* in gtt pages */
|
||||
u32 offset:31;
|
||||
u32 linear:1;
|
||||
union {
|
||||
/* in gtt pages for !linear */
|
||||
struct {
|
||||
u16 width;
|
||||
u16 height;
|
||||
u16 src_stride;
|
||||
u16 dst_stride;
|
||||
};
|
||||
|
||||
/* in gtt pages for linear */
|
||||
u32 size;
|
||||
};
|
||||
} __packed;
|
||||
|
||||
struct intel_rotation_info {
|
||||
struct intel_remapped_plane_info plane[2];
|
||||
} __packed;
|
||||
|
||||
struct intel_partial_info {
|
||||
u64 offset;
|
||||
unsigned int size;
|
||||
} __packed;
|
||||
|
||||
struct intel_remapped_info {
|
||||
struct intel_remapped_plane_info plane[4];
|
||||
/* in gtt pages */
|
||||
u32 plane_alignment;
|
||||
} __packed;
|
||||
|
||||
enum i915_gtt_view_type {
|
||||
I915_GTT_VIEW_NORMAL = 0,
|
||||
I915_GTT_VIEW_ROTATED = sizeof(struct intel_rotation_info),
|
||||
I915_GTT_VIEW_PARTIAL = sizeof(struct intel_partial_info),
|
||||
I915_GTT_VIEW_REMAPPED = sizeof(struct intel_remapped_info),
|
||||
};
|
||||
|
||||
struct i915_gtt_view {
|
||||
enum i915_gtt_view_type type;
|
||||
union {
|
||||
/* Members need to contain no holes/padding */
|
||||
struct intel_partial_info partial;
|
||||
struct intel_rotation_info rotated;
|
||||
struct intel_remapped_info remapped;
|
||||
};
|
||||
};
|
||||
|
||||
static inline bool i915_gtt_view_is_normal(const struct i915_gtt_view *view)
|
||||
{
|
||||
return view->type == I915_GTT_VIEW_NORMAL;
|
||||
}
|
||||
|
||||
static inline bool i915_gtt_view_is_remapped(const struct i915_gtt_view *view)
|
||||
{
|
||||
return view->type == I915_GTT_VIEW_REMAPPED;
|
||||
}
|
||||
|
||||
static inline bool i915_gtt_view_is_rotated(const struct i915_gtt_view *view)
|
||||
{
|
||||
return view->type == I915_GTT_VIEW_ROTATED;
|
||||
}
|
||||
|
||||
#endif /* __I915_GTT_VIEW_TYPES_H__ */
|
||||
|
|
@ -354,14 +354,11 @@ static struct i915_vma *i915_overlay_pin_fb(struct drm_device *drm,
|
|||
struct drm_gem_object *obj,
|
||||
u32 *offset)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(drm);
|
||||
struct drm_i915_gem_object *new_bo = to_intel_bo(obj);
|
||||
struct i915_gem_ww_ctx ww;
|
||||
struct i915_vma *vma;
|
||||
int ret;
|
||||
|
||||
atomic_inc(&i915->pending_fb_pin);
|
||||
|
||||
i915_gem_ww_ctx_init(&ww, true);
|
||||
retry:
|
||||
ret = i915_gem_object_lock(new_bo, &ww);
|
||||
|
|
@ -377,8 +374,6 @@ static struct i915_vma *i915_overlay_pin_fb(struct drm_device *drm,
|
|||
}
|
||||
i915_gem_ww_ctx_fini(&ww);
|
||||
|
||||
atomic_dec(&i915->pending_fb_pin);
|
||||
|
||||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
|
||||
|
|
|
|||
|
|
@ -610,7 +610,6 @@ bool __i915_request_submit(struct i915_request *request)
|
|||
|
||||
RQ_TRACE(request, "\n");
|
||||
|
||||
GEM_BUG_ON(!irqs_disabled());
|
||||
lockdep_assert_held(&engine->sched_engine->lock);
|
||||
|
||||
/*
|
||||
|
|
@ -719,7 +718,6 @@ void __i915_request_unsubmit(struct i915_request *request)
|
|||
*/
|
||||
RQ_TRACE(request, "\n");
|
||||
|
||||
GEM_BUG_ON(!irqs_disabled());
|
||||
lockdep_assert_held(&engine->sched_engine->lock);
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -147,7 +147,7 @@ static void __i915_vma_retire(struct i915_active *ref)
|
|||
static struct i915_vma *
|
||||
vma_create(struct drm_i915_gem_object *obj,
|
||||
struct i915_address_space *vm,
|
||||
const struct i915_gtt_view *view)
|
||||
const struct intel_gtt_view *view)
|
||||
{
|
||||
struct i915_vma *pos = ERR_PTR(-E2BIG);
|
||||
struct i915_vma *vma;
|
||||
|
|
@ -179,9 +179,9 @@ vma_create(struct drm_i915_gem_object *obj,
|
|||
INIT_LIST_HEAD(&vma->obj_link);
|
||||
RB_CLEAR_NODE(&vma->obj_node);
|
||||
|
||||
if (view && view->type != I915_GTT_VIEW_NORMAL) {
|
||||
if (view && !intel_gtt_view_is_normal(view)) {
|
||||
vma->gtt_view = *view;
|
||||
if (view->type == I915_GTT_VIEW_PARTIAL) {
|
||||
if (intel_gtt_view_is_partial(view)) {
|
||||
GEM_BUG_ON(range_overflows_t(u64,
|
||||
view->partial.offset,
|
||||
view->partial.size,
|
||||
|
|
@ -189,10 +189,10 @@ vma_create(struct drm_i915_gem_object *obj,
|
|||
vma->size = view->partial.size;
|
||||
vma->size <<= PAGE_SHIFT;
|
||||
GEM_BUG_ON(vma->size > obj->base.size);
|
||||
} else if (view->type == I915_GTT_VIEW_ROTATED) {
|
||||
} else if (intel_gtt_view_is_rotated(view)) {
|
||||
vma->size = intel_rotation_info_size(&view->rotated);
|
||||
vma->size <<= PAGE_SHIFT;
|
||||
} else if (view->type == I915_GTT_VIEW_REMAPPED) {
|
||||
} else if (intel_gtt_view_is_remapped(view)) {
|
||||
vma->size = intel_remapped_info_size(&view->remapped);
|
||||
vma->size <<= PAGE_SHIFT;
|
||||
}
|
||||
|
|
@ -286,7 +286,7 @@ vma_create(struct drm_i915_gem_object *obj,
|
|||
static struct i915_vma *
|
||||
i915_vma_lookup(struct drm_i915_gem_object *obj,
|
||||
struct i915_address_space *vm,
|
||||
const struct i915_gtt_view *view)
|
||||
const struct intel_gtt_view *view)
|
||||
{
|
||||
struct rb_node *rb;
|
||||
|
||||
|
|
@ -324,7 +324,7 @@ i915_vma_lookup(struct drm_i915_gem_object *obj,
|
|||
struct i915_vma *
|
||||
i915_vma_instance(struct drm_i915_gem_object *obj,
|
||||
struct i915_address_space *vm,
|
||||
const struct i915_gtt_view *view)
|
||||
const struct intel_gtt_view *view)
|
||||
{
|
||||
struct i915_vma *vma;
|
||||
|
||||
|
|
@ -1267,7 +1267,7 @@ intel_remap_pages(struct intel_remapped_info *rem_info,
|
|||
}
|
||||
|
||||
static noinline struct sg_table *
|
||||
intel_partial_pages(const struct i915_gtt_view *view,
|
||||
intel_partial_pages(const struct intel_gtt_view *view,
|
||||
struct drm_i915_gem_object *obj)
|
||||
{
|
||||
struct sg_table *st;
|
||||
|
|
@ -1311,27 +1311,15 @@ __i915_vma_get_pages(struct i915_vma *vma)
|
|||
*/
|
||||
GEM_BUG_ON(!i915_gem_object_has_pinned_pages(vma->obj));
|
||||
|
||||
switch (vma->gtt_view.type) {
|
||||
default:
|
||||
GEM_BUG_ON(vma->gtt_view.type);
|
||||
fallthrough;
|
||||
case I915_GTT_VIEW_NORMAL:
|
||||
pages = vma->obj->mm.pages;
|
||||
break;
|
||||
|
||||
case I915_GTT_VIEW_ROTATED:
|
||||
pages =
|
||||
intel_rotate_pages(&vma->gtt_view.rotated, vma->obj);
|
||||
break;
|
||||
|
||||
case I915_GTT_VIEW_REMAPPED:
|
||||
pages =
|
||||
intel_remap_pages(&vma->gtt_view.remapped, vma->obj);
|
||||
break;
|
||||
|
||||
case I915_GTT_VIEW_PARTIAL:
|
||||
if (intel_gtt_view_is_rotated(&vma->gtt_view)) {
|
||||
pages = intel_rotate_pages(&vma->gtt_view.rotated, vma->obj);
|
||||
} else if (intel_gtt_view_is_remapped(&vma->gtt_view)) {
|
||||
pages = intel_remap_pages(&vma->gtt_view.remapped, vma->obj);
|
||||
} else if (intel_gtt_view_is_partial(&vma->gtt_view)) {
|
||||
pages = intel_partial_pages(&vma->gtt_view, vma->obj);
|
||||
break;
|
||||
} else {
|
||||
GEM_BUG_ON(!intel_gtt_view_is_normal(&vma->gtt_view));
|
||||
pages = vma->obj->mm.pages;
|
||||
}
|
||||
|
||||
if (IS_ERR(pages)) {
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@
|
|||
struct i915_vma *
|
||||
i915_vma_instance(struct drm_i915_gem_object *obj,
|
||||
struct i915_address_space *vm,
|
||||
const struct i915_gtt_view *view);
|
||||
const struct intel_gtt_view *view);
|
||||
|
||||
void i915_vma_unpin_and_release(struct i915_vma **p_vma, unsigned int flags);
|
||||
#define I915_VMA_RELEASE_MAP BIT(0)
|
||||
|
|
@ -207,7 +207,7 @@ static inline void i915_vma_put(struct i915_vma *vma)
|
|||
static inline long
|
||||
i915_vma_compare(struct i915_vma *vma,
|
||||
struct i915_address_space *vm,
|
||||
const struct i915_gtt_view *view)
|
||||
const struct intel_gtt_view *view)
|
||||
{
|
||||
ptrdiff_t cmp;
|
||||
|
||||
|
|
@ -217,7 +217,7 @@ i915_vma_compare(struct i915_vma *vma,
|
|||
if (cmp)
|
||||
return cmp;
|
||||
|
||||
BUILD_BUG_ON(I915_GTT_VIEW_NORMAL != 0);
|
||||
BUILD_BUG_ON(INTEL_GTT_VIEW_NORMAL != 0);
|
||||
cmp = vma->gtt_view.type;
|
||||
if (!view)
|
||||
return cmp;
|
||||
|
|
@ -238,9 +238,9 @@ i915_vma_compare(struct i915_vma *vma,
|
|||
* we assert above that all branches have the same address, and that
|
||||
* each branch has a unique type/size.
|
||||
*/
|
||||
BUILD_BUG_ON(I915_GTT_VIEW_NORMAL >= I915_GTT_VIEW_PARTIAL);
|
||||
BUILD_BUG_ON(I915_GTT_VIEW_PARTIAL >= I915_GTT_VIEW_ROTATED);
|
||||
BUILD_BUG_ON(I915_GTT_VIEW_ROTATED >= I915_GTT_VIEW_REMAPPED);
|
||||
BUILD_BUG_ON(INTEL_GTT_VIEW_NORMAL >= INTEL_GTT_VIEW_PARTIAL);
|
||||
BUILD_BUG_ON(INTEL_GTT_VIEW_PARTIAL >= INTEL_GTT_VIEW_ROTATED);
|
||||
BUILD_BUG_ON(INTEL_GTT_VIEW_ROTATED >= INTEL_GTT_VIEW_REMAPPED);
|
||||
BUILD_BUG_ON(offsetof(typeof(*view), rotated) !=
|
||||
offsetof(typeof(*view), partial));
|
||||
BUILD_BUG_ON(offsetof(typeof(*view), rotated) !=
|
||||
|
|
|
|||
|
|
@ -29,11 +29,10 @@
|
|||
#include <linux/rbtree.h>
|
||||
|
||||
#include <drm/drm_mm.h>
|
||||
#include <drm/intel/gtt_view_types.h>
|
||||
|
||||
#include "gem/i915_gem_object_types.h"
|
||||
|
||||
#include "i915_gtt_view_types.h"
|
||||
|
||||
/**
|
||||
* DOC: Global GTT views
|
||||
*
|
||||
|
|
@ -67,22 +66,22 @@
|
|||
* Implementation and usage
|
||||
*
|
||||
* GGTT views are implemented using VMAs and are distinguished via enum
|
||||
* i915_gtt_view_type and struct i915_gtt_view.
|
||||
* intel_gtt_view_type and struct intel_gtt_view.
|
||||
*
|
||||
* A new flavour of core GEM functions which work with GGTT bound objects were
|
||||
* added with the _ggtt_ infix, and sometimes with _view postfix to avoid
|
||||
* renaming in large amounts of code. They take the struct i915_gtt_view
|
||||
* renaming in large amounts of code. They take the struct intel_gtt_view
|
||||
* parameter encapsulating all metadata required to implement a view.
|
||||
*
|
||||
* As a helper for callers which are only interested in the normal view,
|
||||
* globally const i915_gtt_view_normal singleton instance exists. All old core
|
||||
* globally const intel_gtt_view_normal singleton instance exists. All old core
|
||||
* GEM API functions, the ones not taking the view parameter, are operating on,
|
||||
* or with the normal GGTT view.
|
||||
*
|
||||
* Code wanting to add or use a new GGTT view needs to:
|
||||
*
|
||||
* 1. Add a new enum with a suitable name.
|
||||
* 2. Extend the metadata in the i915_gtt_view structure if required.
|
||||
* 2. Extend the metadata in the intel_gtt_view structure if required.
|
||||
* 3. Add support to i915_get_vma_pages().
|
||||
*
|
||||
* New views are required to build a scatter-gather table from within the
|
||||
|
|
@ -90,7 +89,7 @@
|
|||
* exists for the lifetime of an VMA.
|
||||
*
|
||||
* Core API is designed to have copy semantics which means that passed in
|
||||
* struct i915_gtt_view does not need to be persistent (left around after
|
||||
* struct intel_gtt_view does not need to be persistent (left around after
|
||||
* calling the core API functions).
|
||||
*
|
||||
*/
|
||||
|
|
@ -112,11 +111,11 @@ static inline void assert_i915_gem_gtt_types(void)
|
|||
/* As we encode the size of each branch inside the union into its type,
|
||||
* we have to be careful that each branch has a unique size.
|
||||
*/
|
||||
switch ((enum i915_gtt_view_type)0) {
|
||||
case I915_GTT_VIEW_NORMAL:
|
||||
case I915_GTT_VIEW_PARTIAL:
|
||||
case I915_GTT_VIEW_ROTATED:
|
||||
case I915_GTT_VIEW_REMAPPED:
|
||||
switch ((enum intel_gtt_view_type)0) {
|
||||
case INTEL_GTT_VIEW_NORMAL:
|
||||
case INTEL_GTT_VIEW_PARTIAL:
|
||||
case INTEL_GTT_VIEW_ROTATED:
|
||||
case INTEL_GTT_VIEW_REMAPPED:
|
||||
/* gcc complains if these are identical cases */
|
||||
break;
|
||||
}
|
||||
|
|
@ -231,11 +230,11 @@ struct i915_vma {
|
|||
/**
|
||||
* Support different GGTT views into the same object.
|
||||
* This means there can be multiple VMA mappings per object and per VM.
|
||||
* i915_gtt_view_type is used to distinguish between those entries.
|
||||
* The default one of zero (I915_GTT_VIEW_NORMAL) is default and also
|
||||
* intel_gtt_view_type is used to distinguish between those entries.
|
||||
* The default one of zero (INTEL_GTT_VIEW_NORMAL) is default and also
|
||||
* assumed in GEM functions which take no ggtt view parameter.
|
||||
*/
|
||||
struct i915_gtt_view gtt_view;
|
||||
struct intel_gtt_view gtt_view;
|
||||
|
||||
/** This object's place on the active/inactive lists */
|
||||
struct list_head vm_link;
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ static bool assert_vma(struct i915_vma *vma,
|
|||
ok = false;
|
||||
}
|
||||
|
||||
if (vma->gtt_view.type != I915_GTT_VIEW_NORMAL) {
|
||||
if (!intel_gtt_view_is_normal(&vma->gtt_view)) {
|
||||
pr_err("VMA created with wrong type [%d]\n",
|
||||
vma->gtt_view.type);
|
||||
ok = false;
|
||||
|
|
@ -63,7 +63,7 @@ static bool assert_vma(struct i915_vma *vma,
|
|||
static struct i915_vma *
|
||||
checked_vma_instance(struct drm_i915_gem_object *obj,
|
||||
struct i915_address_space *vm,
|
||||
const struct i915_gtt_view *view)
|
||||
const struct intel_gtt_view *view)
|
||||
{
|
||||
struct i915_vma *vma;
|
||||
bool ok = true;
|
||||
|
|
@ -533,12 +533,12 @@ assert_remapped(struct drm_i915_gem_object *obj,
|
|||
return sg;
|
||||
}
|
||||
|
||||
static unsigned int remapped_size(enum i915_gtt_view_type view_type,
|
||||
static unsigned int remapped_size(const struct intel_gtt_view *view,
|
||||
const struct intel_remapped_plane_info *a,
|
||||
const struct intel_remapped_plane_info *b)
|
||||
{
|
||||
|
||||
if (view_type == I915_GTT_VIEW_ROTATED)
|
||||
if (intel_gtt_view_is_rotated(view))
|
||||
return a->dst_stride * a->width + b->dst_stride * b->width;
|
||||
else
|
||||
return a->dst_stride * a->height + b->dst_stride * b->height;
|
||||
|
|
@ -572,9 +572,9 @@ static int igt_vma_rotate_remap(void *arg)
|
|||
|
||||
{ }
|
||||
}, *a, *b;
|
||||
enum i915_gtt_view_type types[] = {
|
||||
I915_GTT_VIEW_ROTATED,
|
||||
I915_GTT_VIEW_REMAPPED,
|
||||
enum intel_gtt_view_type types[] = {
|
||||
INTEL_GTT_VIEW_ROTATED,
|
||||
INTEL_GTT_VIEW_REMAPPED,
|
||||
0,
|
||||
}, *t;
|
||||
const unsigned int max_pages = 64;
|
||||
|
|
@ -592,7 +592,7 @@ static int igt_vma_rotate_remap(void *arg)
|
|||
for (t = types; *t; t++) {
|
||||
for (a = planes; a->width; a++) {
|
||||
for (b = planes + ARRAY_SIZE(planes); b-- != planes; ) {
|
||||
struct i915_gtt_view view = {
|
||||
struct intel_gtt_view view = {
|
||||
.type = *t,
|
||||
.remapped.plane[0] = *a,
|
||||
.remapped.plane[1] = *b,
|
||||
|
|
@ -606,11 +606,11 @@ static int igt_vma_rotate_remap(void *arg)
|
|||
max_offset = max_pages - max_offset;
|
||||
|
||||
if (!plane_info[0].dst_stride)
|
||||
plane_info[0].dst_stride = view.type == I915_GTT_VIEW_ROTATED ?
|
||||
plane_info[0].dst_stride = intel_gtt_view_is_rotated(&view) ?
|
||||
plane_info[0].height :
|
||||
plane_info[0].width;
|
||||
if (!plane_info[1].dst_stride)
|
||||
plane_info[1].dst_stride = view.type == I915_GTT_VIEW_ROTATED ?
|
||||
plane_info[1].dst_stride = intel_gtt_view_is_rotated(&view) ?
|
||||
plane_info[1].height :
|
||||
plane_info[1].width;
|
||||
|
||||
|
|
@ -632,9 +632,9 @@ static int igt_vma_rotate_remap(void *arg)
|
|||
goto out_object;
|
||||
}
|
||||
|
||||
expected_pages = remapped_size(view.type, &plane_info[0], &plane_info[1]);
|
||||
expected_pages = remapped_size(&view, &plane_info[0], &plane_info[1]);
|
||||
|
||||
if (view.type == I915_GTT_VIEW_ROTATED &&
|
||||
if (intel_gtt_view_is_rotated(&view) &&
|
||||
vma->size != expected_pages * PAGE_SIZE) {
|
||||
pr_err("VMA is wrong size, expected %lu, found %llu\n",
|
||||
PAGE_SIZE * expected_pages, vma->size);
|
||||
|
|
@ -642,7 +642,7 @@ static int igt_vma_rotate_remap(void *arg)
|
|||
goto out_object;
|
||||
}
|
||||
|
||||
if (view.type == I915_GTT_VIEW_REMAPPED &&
|
||||
if (intel_gtt_view_is_remapped(&view) &&
|
||||
vma->size > expected_pages * PAGE_SIZE) {
|
||||
pr_err("VMA is wrong size, expected %lu, found %llu\n",
|
||||
PAGE_SIZE * expected_pages, vma->size);
|
||||
|
|
@ -672,13 +672,13 @@ static int igt_vma_rotate_remap(void *arg)
|
|||
|
||||
sg = vma->pages->sgl;
|
||||
for (n = 0; n < ARRAY_SIZE(view.rotated.plane); n++) {
|
||||
if (view.type == I915_GTT_VIEW_ROTATED)
|
||||
if (intel_gtt_view_is_rotated(&view))
|
||||
sg = assert_rotated(obj, &view.rotated, n, sg);
|
||||
else
|
||||
sg = assert_remapped(obj, &view.remapped, n, sg);
|
||||
if (IS_ERR(sg)) {
|
||||
pr_err("Inconsistent %s VMA pages for plane %d: [(%d, %d, %d, %d, %d), (%d, %d, %d, %d, %d)]\n",
|
||||
view.type == I915_GTT_VIEW_ROTATED ?
|
||||
intel_gtt_view_is_rotated(&view) ?
|
||||
"rotated" : "remapped", n,
|
||||
plane_info[0].width,
|
||||
plane_info[0].height,
|
||||
|
|
@ -745,7 +745,7 @@ static bool assert_partial(struct drm_i915_gem_object *obj,
|
|||
}
|
||||
|
||||
static bool assert_pin(struct i915_vma *vma,
|
||||
struct i915_gtt_view *view,
|
||||
struct intel_gtt_view *view,
|
||||
u64 size,
|
||||
const char *name)
|
||||
{
|
||||
|
|
@ -763,7 +763,7 @@ static bool assert_pin(struct i915_vma *vma,
|
|||
ok = false;
|
||||
}
|
||||
|
||||
if (view && view->type != I915_GTT_VIEW_NORMAL) {
|
||||
if (view && !intel_gtt_view_is_normal(view)) {
|
||||
if (memcmp(&vma->gtt_view, view, sizeof(*view))) {
|
||||
pr_err("(%s) VMA mismatch upon creation!\n",
|
||||
name);
|
||||
|
|
@ -776,7 +776,7 @@ static bool assert_pin(struct i915_vma *vma,
|
|||
ok = false;
|
||||
}
|
||||
} else {
|
||||
if (vma->gtt_view.type != I915_GTT_VIEW_NORMAL) {
|
||||
if (!intel_gtt_view_is_normal(&vma->gtt_view)) {
|
||||
pr_err("Not the normal ggtt view! Found %d\n",
|
||||
vma->gtt_view.type);
|
||||
ok = false;
|
||||
|
|
@ -823,14 +823,14 @@ static int igt_vma_partial(void *arg)
|
|||
nvma = 0;
|
||||
for_each_prime_number_from(sz, 1, npages) {
|
||||
for_each_prime_number_from(offset, 0, npages - sz) {
|
||||
struct i915_gtt_view view;
|
||||
struct intel_gtt_view view;
|
||||
|
||||
view.type = I915_GTT_VIEW_PARTIAL;
|
||||
view.type = INTEL_GTT_VIEW_PARTIAL;
|
||||
view.partial.offset = offset;
|
||||
view.partial.size = sz;
|
||||
|
||||
if (sz == npages)
|
||||
view.type = I915_GTT_VIEW_NORMAL;
|
||||
view.type = INTEL_GTT_VIEW_NORMAL;
|
||||
|
||||
vma = checked_vma_instance(obj, vm, &view);
|
||||
if (IS_ERR(vma)) {
|
||||
|
|
@ -981,9 +981,9 @@ static int igt_vma_remapped_gtt(void *arg)
|
|||
|
||||
{ }
|
||||
}, *p;
|
||||
enum i915_gtt_view_type types[] = {
|
||||
I915_GTT_VIEW_ROTATED,
|
||||
I915_GTT_VIEW_REMAPPED,
|
||||
enum intel_gtt_view_type types[] = {
|
||||
INTEL_GTT_VIEW_ROTATED,
|
||||
INTEL_GTT_VIEW_REMAPPED,
|
||||
0,
|
||||
}, *t;
|
||||
struct drm_i915_gem_object *obj;
|
||||
|
|
@ -1001,7 +1001,7 @@ static int igt_vma_remapped_gtt(void *arg)
|
|||
|
||||
for (t = types; *t; t++) {
|
||||
for (p = planes; p->width; p++) {
|
||||
struct i915_gtt_view view = {
|
||||
struct intel_gtt_view view = {
|
||||
.type = *t,
|
||||
.rotated.plane[0] = *p,
|
||||
};
|
||||
|
|
@ -1017,7 +1017,7 @@ static int igt_vma_remapped_gtt(void *arg)
|
|||
goto out;
|
||||
|
||||
if (!plane_info[0].dst_stride)
|
||||
plane_info[0].dst_stride = *t == I915_GTT_VIEW_ROTATED ?
|
||||
plane_info[0].dst_stride = intel_gtt_view_is_rotated(&view) ?
|
||||
p->height : p->width;
|
||||
|
||||
vma = i915_gem_object_ggtt_pin(obj, &view, 0, 0, PIN_MAPPABLE);
|
||||
|
|
@ -1040,7 +1040,7 @@ static int igt_vma_remapped_gtt(void *arg)
|
|||
unsigned int offset;
|
||||
u32 val = y << 16 | x;
|
||||
|
||||
if (*t == I915_GTT_VIEW_ROTATED)
|
||||
if (intel_gtt_view_is_rotated(&view))
|
||||
offset = (x * plane_info[0].dst_stride + y) * PAGE_SIZE;
|
||||
else
|
||||
offset = (y * plane_info[0].dst_stride + x) * PAGE_SIZE;
|
||||
|
|
@ -1057,7 +1057,7 @@ static int igt_vma_remapped_gtt(void *arg)
|
|||
goto out;
|
||||
}
|
||||
|
||||
GEM_BUG_ON(vma->gtt_view.type != I915_GTT_VIEW_NORMAL);
|
||||
GEM_BUG_ON(!intel_gtt_view_is_normal(&vma->gtt_view));
|
||||
|
||||
map = i915_vma_pin_iomap(vma);
|
||||
i915_vma_unpin(vma);
|
||||
|
|
@ -1072,7 +1072,7 @@ static int igt_vma_remapped_gtt(void *arg)
|
|||
u32 exp = y << 16 | x;
|
||||
u32 val;
|
||||
|
||||
if (*t == I915_GTT_VIEW_ROTATED)
|
||||
if (intel_gtt_view_is_rotated(&view))
|
||||
src_idx = rotated_index(&view.rotated, 0, x, y);
|
||||
else
|
||||
src_idx = remapped_index(&view.remapped, 0, x, y);
|
||||
|
|
@ -1081,7 +1081,7 @@ static int igt_vma_remapped_gtt(void *arg)
|
|||
val = ioread32(&map[offset / sizeof(*map)]);
|
||||
if (val != exp) {
|
||||
pr_err("%s VMA write test failed, expected 0x%x, found 0x%x\n",
|
||||
*t == I915_GTT_VIEW_ROTATED ? "Rotated" : "Remapped",
|
||||
intel_gtt_view_is_rotated(&view) ? "Rotated" : "Remapped",
|
||||
exp, val);
|
||||
i915_vma_unpin_iomap(vma);
|
||||
err = -EINVAL;
|
||||
|
|
|
|||
|
|
@ -39,7 +39,14 @@ static void __hardirq_end(void)
|
|||
local_irq_enable();
|
||||
}
|
||||
|
||||
static void __maybe_unused __nop(void)
|
||||
{}
|
||||
|
||||
const struct igt_atomic_section igt_atomic_phases[] = {
|
||||
#if IS_ENABLED(CONFIG_PREEMPT_RT)
|
||||
{ "sleeping", __nop, __nop },
|
||||
{ },
|
||||
#endif
|
||||
{ "preempt", __preempt_begin, __preempt_end },
|
||||
{ "softirq", __softirq_begin, __softirq_end },
|
||||
{ "hardirq", __hardirq_begin, __hardirq_end },
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
* Copyright © 2013-2021 Intel Corporation
|
||||
*/
|
||||
|
||||
#include <linux/string_choices.h>
|
||||
|
||||
#include <drm/drm_print.h>
|
||||
#include <drm/intel/display_parent_interface.h>
|
||||
|
||||
|
|
@ -101,7 +103,7 @@ static int vlv_sideband_rw(struct drm_i915_private *i915,
|
|||
VLV_IOSF_DOORBELL_REQ, IOSF_SB_BUSY, 0,
|
||||
5)) {
|
||||
drm_dbg(&i915->drm, "IOSF sideband idle wait (%s) timed out\n",
|
||||
is_read ? "read" : "write");
|
||||
str_read_write(is_read));
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
|
|
@ -125,7 +127,7 @@ static int vlv_sideband_rw(struct drm_i915_private *i915,
|
|||
err = 0;
|
||||
} else {
|
||||
drm_dbg(&i915->drm, "IOSF sideband finish wait (%s) timed out\n",
|
||||
is_read ? "read" : "write");
|
||||
str_read_write(is_read));
|
||||
err = -ETIMEDOUT;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -260,6 +260,7 @@ xe-$(CONFIG_DRM_XE_DISPLAY) += \
|
|||
i915-display/intel_ddi.o \
|
||||
i915-display/intel_ddi_buf_trans.o \
|
||||
i915-display/intel_de.o \
|
||||
i915-display/intel_dip.o \
|
||||
i915-display/intel_display.o \
|
||||
i915-display/intel_display_conversion.o \
|
||||
i915-display/intel_display_device.o \
|
||||
|
|
|
|||
|
|
@ -1,16 +0,0 @@
|
|||
/* SPDX-License-Identifier: MIT */
|
||||
/*
|
||||
* Copyright © 2023 Intel Corporation
|
||||
*/
|
||||
|
||||
#ifndef __I915_CONFIG_H__
|
||||
#define __I915_CONFIG_H__
|
||||
|
||||
#include <linux/sched.h>
|
||||
|
||||
static inline unsigned long i915_fence_timeout(void)
|
||||
{
|
||||
return MAX_SCHEDULE_TIMEOUT;
|
||||
}
|
||||
|
||||
#endif /* __I915_CONFIG_H__ */
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
/* SPDX-License-Identifier: MIT */
|
||||
/* Copyright © 2025 Intel Corporation */
|
||||
|
||||
#include "../../i915/i915_gtt_view_types.h"
|
||||
|
||||
/* Partial view not supported in xe, fail build if used. */
|
||||
#define I915_GTT_VIEW_PARTIAL
|
||||
|
|
@ -6,31 +6,23 @@
|
|||
#include "xe_display.h"
|
||||
#include "regs/xe_irq_regs.h"
|
||||
|
||||
#include <linux/fb.h>
|
||||
#include <linux/acpi.h>
|
||||
|
||||
#include <drm/drm_client.h>
|
||||
#include <drm/drm_client_event.h>
|
||||
#include <drm/drm_drv.h>
|
||||
#include <drm/drm_managed.h>
|
||||
#include <drm/drm_probe_helper.h>
|
||||
#include <drm/intel/display_member.h>
|
||||
#include <drm/intel/display_parent_interface.h>
|
||||
#include <uapi/drm/xe_drm.h>
|
||||
|
||||
#include "intel_acpi.h"
|
||||
#include "intel_display.h"
|
||||
#include "intel_display_core.h"
|
||||
#include "intel_display_device.h"
|
||||
#include "intel_display_driver.h"
|
||||
#include "intel_display_irq.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_dmc.h"
|
||||
#include "intel_dmc_wl.h"
|
||||
#include "intel_dp.h"
|
||||
#include "intel_fbdev.h"
|
||||
#include "intel_hotplug.h"
|
||||
#include "intel_opregion.h"
|
||||
#include "skl_watermark.h"
|
||||
#include "xe_device.h"
|
||||
#include "xe_display_bo.h"
|
||||
#include "xe_display_pcode.h"
|
||||
|
|
|
|||
|
|
@ -45,6 +45,11 @@ static bool xe_display_rpm_suspended(const struct drm_device *drm)
|
|||
return pm_runtime_suspended(xe->drm.dev);
|
||||
}
|
||||
|
||||
static bool xe_display_rpm_pme_enabled(const struct drm_device *drm)
|
||||
{
|
||||
return xe_pm_pme_enabled(to_xe_device(drm));
|
||||
}
|
||||
|
||||
static void xe_display_rpm_assert_held(const struct drm_device *drm)
|
||||
{
|
||||
/* FIXME */
|
||||
|
|
@ -69,6 +74,7 @@ const struct intel_display_rpm_interface xe_display_rpm_interface = {
|
|||
.put_raw = xe_display_rpm_put,
|
||||
.put_unchecked = xe_display_rpm_put_unchecked,
|
||||
.suspended = xe_display_rpm_suspended,
|
||||
.pme_enabled = xe_display_rpm_pme_enabled,
|
||||
.assert_held = xe_display_rpm_assert_held,
|
||||
.assert_block = xe_display_rpm_assert_block,
|
||||
.assert_unblock = xe_display_rpm_assert_unblock
|
||||
|
|
|
|||
|
|
@ -4,11 +4,9 @@
|
|||
*/
|
||||
|
||||
#include <drm/intel/display_parent_interface.h>
|
||||
#include <drm/intel/gtt_view_types.h>
|
||||
#include <drm/ttm/ttm_bo.h>
|
||||
|
||||
/* FIXME move the types to parent interface? */
|
||||
#include "i915_gtt_view_types.h"
|
||||
|
||||
/* FIXME move intel_remapped_info_size() & co. to parent interface? */
|
||||
#include "intel_fb.h"
|
||||
|
||||
|
|
@ -150,13 +148,13 @@ static int __xe_pin_fb_vma_dpt(struct drm_gem_object *obj,
|
|||
struct xe_device *xe = to_xe_device(obj->dev);
|
||||
struct xe_tile *tile0 = xe_device_get_root_tile(xe);
|
||||
struct xe_ggtt *ggtt = tile0->mem.ggtt;
|
||||
const struct i915_gtt_view *view = pin_params->view;
|
||||
const struct intel_gtt_view *view = pin_params->view;
|
||||
struct xe_bo *bo = gem_to_xe_bo(obj), *dpt;
|
||||
u32 dpt_size, size = bo->ttm.base.size;
|
||||
|
||||
if (view->type == I915_GTT_VIEW_NORMAL)
|
||||
if (intel_gtt_view_is_normal(view))
|
||||
dpt_size = ALIGN(size / XE_PAGE_SIZE * 8, XE_PAGE_SIZE);
|
||||
else if (view->type == I915_GTT_VIEW_REMAPPED)
|
||||
else if (intel_gtt_view_is_remapped(view))
|
||||
dpt_size = ALIGN(intel_remapped_info_size(&view->remapped) * 8,
|
||||
XE_PAGE_SIZE);
|
||||
else
|
||||
|
|
@ -175,7 +173,7 @@ static int __xe_pin_fb_vma_dpt(struct drm_gem_object *obj,
|
|||
if (IS_ERR(dpt))
|
||||
return PTR_ERR(dpt);
|
||||
|
||||
if (view->type == I915_GTT_VIEW_NORMAL) {
|
||||
if (intel_gtt_view_is_normal(view)) {
|
||||
u64 pte = xe_ggtt_encode_pte_flags(ggtt, bo, xe_cache_pat_idx(xe, XE_CACHE_NONE));
|
||||
u32 x;
|
||||
|
||||
|
|
@ -184,7 +182,7 @@ static int __xe_pin_fb_vma_dpt(struct drm_gem_object *obj,
|
|||
|
||||
iosys_map_wr(&dpt->vmap, x * 8, u64, pte | addr);
|
||||
}
|
||||
} else if (view->type == I915_GTT_VIEW_REMAPPED) {
|
||||
} else if (intel_gtt_view_is_remapped(view)) {
|
||||
write_dpt_remapped(bo, &view->remapped, &dpt->vmap);
|
||||
} else {
|
||||
const struct intel_rotation_info *rot_info = &view->rotated;
|
||||
|
|
@ -233,7 +231,7 @@ write_ggtt_rotated(struct xe_ggtt *ggtt, u32 *ggtt_ofs,
|
|||
}
|
||||
|
||||
struct fb_rotate_args {
|
||||
const struct i915_gtt_view *view;
|
||||
const struct intel_gtt_view *view;
|
||||
struct xe_bo *bo;
|
||||
};
|
||||
|
||||
|
|
@ -258,7 +256,7 @@ static int __xe_pin_fb_vma_ggtt(struct drm_gem_object *obj,
|
|||
const struct intel_fb_pin_params *pin_params,
|
||||
struct i915_vma *vma)
|
||||
{
|
||||
const struct i915_gtt_view *view = pin_params->view;
|
||||
const struct intel_gtt_view *view = pin_params->view;
|
||||
struct xe_bo *bo = gem_to_xe_bo(obj);
|
||||
struct xe_device *xe = to_xe_device(obj->dev);
|
||||
struct xe_tile *tile0 = xe_device_get_root_tile(xe);
|
||||
|
|
@ -277,7 +275,7 @@ static int __xe_pin_fb_vma_ggtt(struct drm_gem_object *obj,
|
|||
align = max(align, SZ_64K);
|
||||
|
||||
/* Fast case, preallocated GGTT view? */
|
||||
if (bo->ggtt_node[tile0->id] && view->type == I915_GTT_VIEW_NORMAL) {
|
||||
if (bo->ggtt_node[tile0->id] && intel_gtt_view_is_normal(view)) {
|
||||
vma->node = bo->ggtt_node[tile0->id];
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -285,7 +283,7 @@ static int __xe_pin_fb_vma_ggtt(struct drm_gem_object *obj,
|
|||
/* TODO: Consider sharing framebuffer mapping?
|
||||
* embed i915_vma inside intel_framebuffer
|
||||
*/
|
||||
if (view->type == I915_GTT_VIEW_NORMAL)
|
||||
if (intel_gtt_view_is_normal(view))
|
||||
size = xe_bo_size(bo);
|
||||
else
|
||||
/* display uses tiles instead of bytes here, so convert it back.. */
|
||||
|
|
@ -294,7 +292,7 @@ static int __xe_pin_fb_vma_ggtt(struct drm_gem_object *obj,
|
|||
pte = xe_ggtt_encode_pte_flags(ggtt, bo, xe_cache_pat_idx(xe, XE_CACHE_NONE));
|
||||
vma->node = xe_ggtt_insert_node_transform(ggtt, bo, pte,
|
||||
ALIGN(size, align), align,
|
||||
view->type == I915_GTT_VIEW_NORMAL ?
|
||||
intel_gtt_view_is_normal(view) ?
|
||||
NULL : write_ggtt_rotated_node,
|
||||
&(struct fb_rotate_args){view, bo});
|
||||
if (IS_ERR(vma->node))
|
||||
|
|
@ -459,9 +457,9 @@ static void xe_fb_pin_dpt_unpin(struct intel_dpt *dpt,
|
|||
static struct i915_vma *
|
||||
xe_fb_pin_reuse_vma(struct i915_vma *old_ggtt_vma,
|
||||
struct drm_gem_object *old_obj,
|
||||
const struct i915_gtt_view *old_view,
|
||||
const struct intel_gtt_view *old_view,
|
||||
struct drm_gem_object *new_obj,
|
||||
const struct i915_gtt_view *new_view,
|
||||
const struct intel_gtt_view *new_view,
|
||||
u32 *out_offset)
|
||||
{
|
||||
if (old_ggtt_vma && old_obj == new_obj &&
|
||||
|
|
|
|||
|
|
@ -466,6 +466,19 @@ struct xe_device {
|
|||
struct mutex lock;
|
||||
} d3cold;
|
||||
|
||||
/** @pme: Encapsulate pme related stuff */
|
||||
struct {
|
||||
/** @pme.capable: Indicates if device is PME capable */
|
||||
bool capable;
|
||||
|
||||
/** @pme.enabled:
|
||||
*
|
||||
* Indicates if PME is enabled - depends on user controllable
|
||||
* sysfs interface as well
|
||||
*/
|
||||
bool enabled;
|
||||
} pme;
|
||||
|
||||
/** @pm_notifier: Our PM notifier to perform actions in response to various PM events. */
|
||||
struct notifier_block pm_notifier;
|
||||
/** @pm_block: Completion to block validating tasks on suspend / hibernate prepare */
|
||||
|
|
|
|||
|
|
@ -1384,6 +1384,8 @@ static int xe_pci_runtime_suspend(struct device *dev)
|
|||
{
|
||||
struct pci_dev *pdev = to_pci_dev(dev);
|
||||
struct xe_device *xe = pdev_to_xe_device(pdev);
|
||||
unsigned int flags;
|
||||
bool pme_enabled;
|
||||
int err, ret;
|
||||
|
||||
/*
|
||||
|
|
@ -1395,9 +1397,25 @@ static int xe_pci_runtime_suspend(struct device *dev)
|
|||
xe_assert(xe, !IS_SRIOV_VF(xe));
|
||||
xe_assert(xe, !pci_num_vf(pdev));
|
||||
|
||||
flags = memalloc_noreclaim_save();
|
||||
pme_enabled = xe->pme.capable && !xe->d3cold.allowed &&
|
||||
pci_enable_wake(pdev, PCI_D3hot, true) == 0;
|
||||
memalloc_noreclaim_restore(flags);
|
||||
|
||||
xe_pm_update_pme_enabled(xe, pme_enabled);
|
||||
|
||||
err = xe_pm_runtime_suspend(xe);
|
||||
if (err)
|
||||
if (err) {
|
||||
if (pme_enabled) {
|
||||
flags = memalloc_noreclaim_save();
|
||||
pci_enable_wake(pdev, PCI_D3hot, false);
|
||||
memalloc_noreclaim_restore(flags);
|
||||
|
||||
xe_pm_update_pme_enabled(xe, false);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
err = xe_pm_wait_all_c6(xe);
|
||||
if (err) {
|
||||
|
|
@ -1437,6 +1455,8 @@ static int xe_pci_runtime_resume(struct device *dev)
|
|||
|
||||
pci_restore_state(pdev);
|
||||
|
||||
xe_pm_update_pme_enabled(xe, false);
|
||||
|
||||
if (xe->d3cold.allowed) {
|
||||
err = pci_enable_device(pdev);
|
||||
if (err)
|
||||
|
|
|
|||
|
|
@ -78,6 +78,8 @@
|
|||
* management (RPS).
|
||||
*/
|
||||
|
||||
#define HAS_PM_PME_SUPPORT(xe) (GRAPHICS_VERx100(xe) >= 3500)
|
||||
|
||||
#ifdef CONFIG_LOCKDEP
|
||||
static struct lockdep_map xe_pm_runtime_d3cold_map = {
|
||||
.name = "xe_rpm_d3cold_map"
|
||||
|
|
@ -384,6 +386,14 @@ int xe_pm_init_early(struct xe_device *xe)
|
|||
}
|
||||
ALLOW_ERROR_INJECTION(xe_pm_init_early, ERRNO); /* See xe_pci_probe() */
|
||||
|
||||
static bool xe_pm_pci_pme_capable(struct xe_device *xe)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(xe->drm.dev);
|
||||
|
||||
return HAS_PM_PME_SUPPORT(xe) ?
|
||||
pci_pme_capable(pdev, PCI_D3hot) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* xe_pm_probe() - Initialize Xe Power Management
|
||||
* @xe: the &xe_device instance
|
||||
|
|
@ -397,6 +407,16 @@ int xe_pm_probe(struct xe_device *xe)
|
|||
xe->d3cold.capable = xe_pm_pci_d3cold_capable(xe);
|
||||
xe_dbg(xe, "d3cold: capable=%s\n", str_yes_no(xe->d3cold.capable));
|
||||
|
||||
xe->pme.capable = xe_pm_pci_pme_capable(xe);
|
||||
xe_dbg(xe, "pme: capable=%s\n", str_yes_no(xe->pme.capable));
|
||||
|
||||
if (xe->pme.capable) {
|
||||
int err = devm_device_init_wakeup(xe->drm.dev);
|
||||
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -650,6 +670,7 @@ int xe_pm_runtime_suspend(struct xe_device *xe)
|
|||
return 0;
|
||||
|
||||
out_resume:
|
||||
xe_pm_update_pme_enabled(xe, false);
|
||||
xe_display_pm_runtime_resume(xe);
|
||||
xe_pxp_pm_resume(xe->pxp);
|
||||
out:
|
||||
|
|
@ -993,6 +1014,30 @@ int xe_pm_set_vram_threshold(struct xe_device *xe, u32 threshold)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* xe_pm_pme_enabled - get the current status of PME enabled
|
||||
* @xe: xe device instance
|
||||
*
|
||||
* Returns: True if PME is enabled, false otherwise.
|
||||
*/
|
||||
bool xe_pm_pme_enabled(struct xe_device *xe)
|
||||
{
|
||||
return xe->pme.enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* xe_pm_update_pme_enabled - Update the PME enabled state
|
||||
* @xe: xe device instance
|
||||
* @status: New PME enabled status
|
||||
*
|
||||
* Called during runtime suspend / resume. Status is set to True if PME is
|
||||
* enabled during runtime_suspend. Cleared on runtime_resume.
|
||||
*/
|
||||
void xe_pm_update_pme_enabled(struct xe_device *xe, bool status)
|
||||
{
|
||||
xe->pme.enabled = status;
|
||||
}
|
||||
|
||||
/**
|
||||
* xe_pm_d3cold_allowed_toggle - Check conditions to toggle d3cold.allowed
|
||||
* @xe: xe device instance
|
||||
|
|
|
|||
|
|
@ -33,6 +33,8 @@ bool xe_pm_runtime_resume_and_get(struct xe_device *xe);
|
|||
void xe_pm_assert_unbounded_bridge(struct xe_device *xe);
|
||||
int xe_pm_set_vram_threshold(struct xe_device *xe, u32 threshold);
|
||||
void xe_pm_d3cold_allowed_toggle(struct xe_device *xe);
|
||||
bool xe_pm_pme_enabled(struct xe_device *xe);
|
||||
void xe_pm_update_pme_enabled(struct xe_device *xe, bool status);
|
||||
bool xe_rpm_reclaim_safe(const struct xe_device *xe);
|
||||
struct task_struct *xe_pm_read_callback_task(struct xe_device *xe);
|
||||
int xe_pm_block_on_suspend(struct xe_device *xe);
|
||||
|
|
|
|||
|
|
@ -16,11 +16,11 @@ struct drm_mode_fb_cmd2;
|
|||
struct drm_plane_state;
|
||||
struct drm_scanout_buffer;
|
||||
struct fb_info;
|
||||
struct i915_gtt_view;
|
||||
struct i915_vma;
|
||||
struct intel_dpt;
|
||||
struct intel_dsb_buffer;
|
||||
struct intel_frontbuffer;
|
||||
struct intel_gtt_view;
|
||||
struct intel_hdcp_gsc_context;
|
||||
struct intel_initial_plane_config;
|
||||
struct intel_panic;
|
||||
|
|
@ -31,7 +31,7 @@ struct seq_file;
|
|||
struct vm_area_struct;
|
||||
|
||||
struct intel_fb_pin_params {
|
||||
const struct i915_gtt_view *view;
|
||||
const struct intel_gtt_view *view;
|
||||
unsigned int alignment;
|
||||
unsigned int phys_alignment;
|
||||
unsigned int vtd_guard;
|
||||
|
|
@ -101,9 +101,9 @@ struct intel_display_fb_pin_interface {
|
|||
struct i915_vma *ggtt_vma);
|
||||
struct i915_vma *(*reuse_vma)(struct i915_vma *old_ggtt_vma,
|
||||
struct drm_gem_object *old_obj,
|
||||
const struct i915_gtt_view *old_view,
|
||||
const struct intel_gtt_view *old_view,
|
||||
struct drm_gem_object *new_obj,
|
||||
const struct i915_gtt_view *new_view,
|
||||
const struct intel_gtt_view *new_view,
|
||||
u32 *out_offset);
|
||||
void (*get_map)(struct i915_vma *vma, struct iosys_map *map);
|
||||
};
|
||||
|
|
@ -196,6 +196,7 @@ struct intel_display_rpm_interface {
|
|||
void (*put_unchecked)(const struct drm_device *drm);
|
||||
|
||||
bool (*suspended)(const struct drm_device *drm);
|
||||
bool (*pme_enabled)(const struct drm_device *drm); /* Optional */
|
||||
void (*assert_held)(const struct drm_device *drm);
|
||||
void (*assert_block)(const struct drm_device *drm);
|
||||
void (*assert_unblock)(const struct drm_device *drm);
|
||||
|
|
|
|||
79
include/drm/intel/gtt_view_types.h
Normal file
79
include/drm/intel/gtt_view_types.h
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
/* SPDX-License-Identifier: MIT */
|
||||
/* Copyright © 2025 Intel Corporation */
|
||||
|
||||
#ifndef __DRM_INTEL_GTT_VIEW_TYPES_H__
|
||||
#define __DRM_INTEL_GTT_VIEW_TYPES_H__
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
struct intel_remapped_plane_info {
|
||||
/* in gtt pages */
|
||||
u32 offset:31;
|
||||
u32 linear:1;
|
||||
union {
|
||||
/* in gtt pages for !linear */
|
||||
struct {
|
||||
u16 width;
|
||||
u16 height;
|
||||
u16 src_stride;
|
||||
u16 dst_stride;
|
||||
};
|
||||
|
||||
/* in gtt pages for linear */
|
||||
u32 size;
|
||||
};
|
||||
} __packed;
|
||||
|
||||
struct intel_rotation_info {
|
||||
struct intel_remapped_plane_info plane[2];
|
||||
} __packed;
|
||||
|
||||
struct intel_partial_info {
|
||||
u64 offset;
|
||||
unsigned int size;
|
||||
} __packed;
|
||||
|
||||
struct intel_remapped_info {
|
||||
struct intel_remapped_plane_info plane[4];
|
||||
/* in gtt pages */
|
||||
u32 plane_alignment;
|
||||
} __packed;
|
||||
|
||||
enum intel_gtt_view_type {
|
||||
INTEL_GTT_VIEW_NORMAL = 0,
|
||||
INTEL_GTT_VIEW_ROTATED = sizeof(struct intel_rotation_info),
|
||||
INTEL_GTT_VIEW_PARTIAL = sizeof(struct intel_partial_info),
|
||||
INTEL_GTT_VIEW_REMAPPED = sizeof(struct intel_remapped_info),
|
||||
};
|
||||
|
||||
struct intel_gtt_view {
|
||||
enum intel_gtt_view_type type;
|
||||
union {
|
||||
/* Members need to contain no holes/padding */
|
||||
struct intel_partial_info partial;
|
||||
struct intel_rotation_info rotated;
|
||||
struct intel_remapped_info remapped;
|
||||
};
|
||||
};
|
||||
|
||||
static inline bool intel_gtt_view_is_normal(const struct intel_gtt_view *view)
|
||||
{
|
||||
return view->type == INTEL_GTT_VIEW_NORMAL;
|
||||
}
|
||||
|
||||
static inline bool intel_gtt_view_is_remapped(const struct intel_gtt_view *view)
|
||||
{
|
||||
return view->type == INTEL_GTT_VIEW_REMAPPED;
|
||||
}
|
||||
|
||||
static inline bool intel_gtt_view_is_rotated(const struct intel_gtt_view *view)
|
||||
{
|
||||
return view->type == INTEL_GTT_VIEW_ROTATED;
|
||||
}
|
||||
|
||||
static inline bool intel_gtt_view_is_partial(const struct intel_gtt_view *view)
|
||||
{
|
||||
return view->type == INTEL_GTT_VIEW_PARTIAL;
|
||||
}
|
||||
|
||||
#endif /* __DRM_INTEL_GTT_VIEW_TYPES_H__ */
|
||||
Loading…
Reference in New Issue
Block a user