- Removing unused declarations (Arnd, Gustavo)
- ICL+ DSI modeset sequence fixes (Ville) - Improvements on HDCP (Suraj) - Fixes and clean up on MTL Display (Mika Kahola, Lee, RK, Nirmoy, Chaitanya) - Restore HSW/BDW PSR1 (Ville) - Other PSR Fixes (Jouni) - Fixes around DC states and other Display Power (Imre) - Init DDI ports in VBT order (Ville) - General documentation fixes (Jani) - General refactor for better organization (Jani) - Bigjoiner fix (Stanislav) - VDSC Fixes and improvements (Stanialav, Suraj) - Hotplug fixes and improvements (Simon, Suraj) - Start using plane scale factor for relative data rate (Stanislav) - Use shmem for dpt objects (RK) - Simplify expression &to_i915(dev)->drm (Uwe) - Do not access i915_gem_object members from frontbuffer tracking (Jouni) - Fix uncore race around i915->params.mmio_debug (Jani) -----BEGIN PGP SIGNATURE----- iQEzBAABCAAdFiEEbSBwaO7dZQkcLOKj+mJfZA7rE8oFAmTL9/EACgkQ+mJfZA7r E8oqdQgAtD6j4Lih3rVRSLW5Y64MXnGdIHdNtVzLIOJWKLex3e7lFRvZp8IE6MY/ UifZBQ45UEJAo3kcX36TReKG/URzc6jpu3YA2ihwt6uTJW2bZWmtNgfGgnILssOi hnOTRaxUwVM6wvi62AUKi6AxtDdHrRzcP+RyqGFvjBP76CuOpYSuJq8AK/PBXKFH z760SqAWILOXqPG+oUYV9vdAmzY71gWDyi3MJqTYYg4YORK+itKMTbeWtFnEJF59 YqAD+/neZ7Y9FafSajUu9l9E9A9srqVAc2zFlcof2rA2MgJyHRBAl2fP4GY6+TDI ahjmQY/BNP711SnEGArPkRZdcUSMXA== =44FM -----END PGP SIGNATURE----- Merge tag 'drm-intel-next-2023-08-03' of git://anongit.freedesktop.org/drm/drm-intel into drm-next - Removing unused declarations (Arnd, Gustavo) - ICL+ DSI modeset sequence fixes (Ville) - Improvements on HDCP (Suraj) - Fixes and clean up on MTL Display (Mika Kahola, Lee, RK, Nirmoy, Chaitanya) - Restore HSW/BDW PSR1 (Ville) - Other PSR Fixes (Jouni) - Fixes around DC states and other Display Power (Imre) - Init DDI ports in VBT order (Ville) - General documentation fixes (Jani) - General refactor for better organization (Jani) - Bigjoiner fix (Stanislav) - VDSC Fixes and improvements (Stanialav, Suraj) - Hotplug fixes and improvements (Simon, Suraj) - Start using plane scale factor for relative data rate (Stanislav) - Use shmem for dpt objects (RK) - Simplify expression &to_i915(dev)->drm (Uwe) - Do not access i915_gem_object members from frontbuffer tracking (Jouni) - Fix uncore race around i915->params.mmio_debug (Jani) Signed-off-by: Dave Airlie <airlied@redhat.com> From: Rodrigo Vivi <rodrigo.vivi@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/ZMv4RCzGyCmG/BDe@intel.com
This commit is contained in:
commit
7c9aa0f746
@ -135,9 +135,13 @@ Add I915_CONTEXT_ENGINES_EXT_PARALLEL_SUBMIT and
|
||||
drm_i915_context_engines_parallel_submit to the uAPI to implement this
|
||||
extension.
|
||||
|
||||
.. c:namespace-push:: rfc
|
||||
|
||||
.. kernel-doc:: include/uapi/drm/i915_drm.h
|
||||
:functions: i915_context_engines_parallel_submit
|
||||
|
||||
.. c:namespace-pop::
|
||||
|
||||
Extend execbuf2 IOCTL to support submitting N BBs in a single IOCTL
|
||||
-------------------------------------------------------------------
|
||||
Contexts that have been configured with the 'set_parallel' extension can only
|
||||
|
@ -23,6 +23,11 @@ subdir-ccflags-y += $(call cc-option, -Wunused-but-set-variable)
|
||||
subdir-ccflags-y += $(call cc-disable-warning, frame-address)
|
||||
subdir-ccflags-$(CONFIG_DRM_I915_WERROR) += -Werror
|
||||
|
||||
# Fine grained warnings disable
|
||||
CFLAGS_i915_pci.o = $(call cc-disable-warning, override-init)
|
||||
CFLAGS_display/intel_display_device.o = $(call cc-disable-warning, override-init)
|
||||
CFLAGS_display/intel_fbdev.o = $(call cc-disable-warning, override-init)
|
||||
|
||||
subdir-ccflags-y += -I$(srctree)/$(src)
|
||||
|
||||
# Please keep these build lists sorted!
|
||||
|
@ -1259,6 +1259,9 @@ bool g4x_dp_init(struct drm_i915_private *dev_priv,
|
||||
struct drm_encoder *encoder;
|
||||
struct intel_connector *intel_connector;
|
||||
|
||||
if (!assert_port_valid(dev_priv, port))
|
||||
return false;
|
||||
|
||||
devdata = intel_bios_encoder_data_lookup(dev_priv, port);
|
||||
|
||||
/* FIXME bail? */
|
||||
@ -1270,6 +1273,8 @@ bool g4x_dp_init(struct drm_i915_private *dev_priv,
|
||||
if (!dig_port)
|
||||
return false;
|
||||
|
||||
dig_port->aux_ch = AUX_CH_NONE;
|
||||
|
||||
intel_connector = intel_connector_alloc();
|
||||
if (!intel_connector)
|
||||
goto err_connector_alloc;
|
||||
@ -1373,6 +1378,9 @@ bool g4x_dp_init(struct drm_i915_private *dev_priv,
|
||||
intel_infoframe_init(dig_port);
|
||||
|
||||
dig_port->aux_ch = intel_dp_aux_ch(intel_encoder);
|
||||
if (dig_port->aux_ch == AUX_CH_NONE)
|
||||
goto err_init_connector;
|
||||
|
||||
if (!intel_dp_init_connector(dig_port, intel_connector))
|
||||
goto err_init_connector;
|
||||
|
||||
|
@ -659,6 +659,20 @@ int g4x_hdmi_connector_atomic_check(struct drm_connector *connector,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool is_hdmi_port_valid(struct drm_i915_private *i915, enum port port)
|
||||
{
|
||||
if (IS_G4X(i915) || IS_VALLEYVIEW(i915))
|
||||
return port == PORT_B || port == PORT_C;
|
||||
else
|
||||
return port == PORT_B || port == PORT_C || port == PORT_D;
|
||||
}
|
||||
|
||||
static bool assert_hdmi_port_valid(struct drm_i915_private *i915, enum port port)
|
||||
{
|
||||
return !drm_WARN(&i915->drm, !is_hdmi_port_valid(i915, port),
|
||||
"Platform does not support HDMI %c\n", port_name(port));
|
||||
}
|
||||
|
||||
void g4x_hdmi_init(struct drm_i915_private *dev_priv,
|
||||
i915_reg_t hdmi_reg, enum port port)
|
||||
{
|
||||
@ -667,6 +681,12 @@ void g4x_hdmi_init(struct drm_i915_private *dev_priv,
|
||||
struct intel_encoder *intel_encoder;
|
||||
struct intel_connector *intel_connector;
|
||||
|
||||
if (!assert_port_valid(dev_priv, port))
|
||||
return;
|
||||
|
||||
if (!assert_hdmi_port_valid(dev_priv, port))
|
||||
return;
|
||||
|
||||
devdata = intel_bios_encoder_data_lookup(dev_priv, port);
|
||||
|
||||
/* FIXME bail? */
|
||||
@ -678,6 +698,8 @@ void g4x_hdmi_init(struct drm_i915_private *dev_priv,
|
||||
if (!dig_port)
|
||||
return;
|
||||
|
||||
dig_port->aux_ch = AUX_CH_NONE;
|
||||
|
||||
intel_connector = intel_connector_alloc();
|
||||
if (!intel_connector) {
|
||||
kfree(dig_port);
|
||||
@ -753,6 +775,5 @@ void g4x_hdmi_init(struct drm_i915_private *dev_priv,
|
||||
|
||||
intel_infoframe_init(dig_port);
|
||||
|
||||
dig_port->aux_ch = intel_dp_aux_ch(intel_encoder);
|
||||
intel_hdmi_init_connector(dig_port, intel_connector);
|
||||
}
|
||||
|
@ -528,31 +528,16 @@ gen11_dsi_setup_dphy_timings(struct intel_encoder *encoder,
|
||||
enum port port;
|
||||
enum phy phy;
|
||||
|
||||
/* Program T-INIT master registers */
|
||||
for_each_dsi_port(port, intel_dsi->ports)
|
||||
intel_de_rmw(dev_priv, ICL_DSI_T_INIT_MASTER(port),
|
||||
DSI_T_INIT_MASTER_MASK, intel_dsi->init_count);
|
||||
|
||||
/* Program DPHY clock lanes timings */
|
||||
for_each_dsi_port(port, intel_dsi->ports) {
|
||||
for_each_dsi_port(port, intel_dsi->ports)
|
||||
intel_de_write(dev_priv, DPHY_CLK_TIMING_PARAM(port),
|
||||
intel_dsi->dphy_reg);
|
||||
|
||||
/* shadow register inside display core */
|
||||
intel_de_write(dev_priv, DSI_CLK_TIMING_PARAM(port),
|
||||
intel_dsi->dphy_reg);
|
||||
}
|
||||
|
||||
/* Program DPHY data lanes timings */
|
||||
for_each_dsi_port(port, intel_dsi->ports) {
|
||||
for_each_dsi_port(port, intel_dsi->ports)
|
||||
intel_de_write(dev_priv, DPHY_DATA_TIMING_PARAM(port),
|
||||
intel_dsi->dphy_data_lane_reg);
|
||||
|
||||
/* shadow register inside display core */
|
||||
intel_de_write(dev_priv, DSI_DATA_TIMING_PARAM(port),
|
||||
intel_dsi->dphy_data_lane_reg);
|
||||
}
|
||||
|
||||
/*
|
||||
* If DSI link operating at or below an 800 MHz,
|
||||
* TA_SURE should be override and programmed to
|
||||
@ -561,16 +546,10 @@ gen11_dsi_setup_dphy_timings(struct intel_encoder *encoder,
|
||||
*/
|
||||
if (DISPLAY_VER(dev_priv) == 11) {
|
||||
if (afe_clk(encoder, crtc_state) <= 800000) {
|
||||
for_each_dsi_port(port, intel_dsi->ports) {
|
||||
for_each_dsi_port(port, intel_dsi->ports)
|
||||
intel_de_rmw(dev_priv, DPHY_TA_TIMING_PARAM(port),
|
||||
TA_SURE_MASK,
|
||||
TA_SURE_OVERRIDE | TA_SURE(0));
|
||||
|
||||
/* shadow register inside display core */
|
||||
intel_de_rmw(dev_priv, DSI_TA_TIMING_PARAM(port),
|
||||
TA_SURE_MASK,
|
||||
TA_SURE_OVERRIDE | TA_SURE(0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -581,6 +560,41 @@ gen11_dsi_setup_dphy_timings(struct intel_encoder *encoder,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gen11_dsi_setup_timings(struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
|
||||
struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
|
||||
enum port port;
|
||||
|
||||
/* Program T-INIT master registers */
|
||||
for_each_dsi_port(port, intel_dsi->ports)
|
||||
intel_de_rmw(dev_priv, ICL_DSI_T_INIT_MASTER(port),
|
||||
DSI_T_INIT_MASTER_MASK, intel_dsi->init_count);
|
||||
|
||||
/* shadow register inside display core */
|
||||
for_each_dsi_port(port, intel_dsi->ports)
|
||||
intel_de_write(dev_priv, DSI_CLK_TIMING_PARAM(port),
|
||||
intel_dsi->dphy_reg);
|
||||
|
||||
/* shadow register inside display core */
|
||||
for_each_dsi_port(port, intel_dsi->ports)
|
||||
intel_de_write(dev_priv, DSI_DATA_TIMING_PARAM(port),
|
||||
intel_dsi->dphy_data_lane_reg);
|
||||
|
||||
/* shadow register inside display core */
|
||||
if (DISPLAY_VER(dev_priv) == 11) {
|
||||
if (afe_clk(encoder, crtc_state) <= 800000) {
|
||||
for_each_dsi_port(port, intel_dsi->ports) {
|
||||
intel_de_rmw(dev_priv, DSI_TA_TIMING_PARAM(port),
|
||||
TA_SURE_MASK,
|
||||
TA_SURE_OVERRIDE | TA_SURE(0));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void gen11_dsi_gate_clocks(struct intel_encoder *encoder)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
|
||||
@ -1090,11 +1104,15 @@ gen11_dsi_enable_port_and_phy(struct intel_encoder *encoder,
|
||||
/* step 4c: configure voltage swing and skew */
|
||||
gen11_dsi_voltage_swing_program_seq(encoder);
|
||||
|
||||
/* setup D-PHY timings */
|
||||
gen11_dsi_setup_dphy_timings(encoder, crtc_state);
|
||||
|
||||
/* enable DDI buffer */
|
||||
gen11_dsi_enable_ddi_buffer(encoder);
|
||||
|
||||
/* setup D-PHY timings */
|
||||
gen11_dsi_setup_dphy_timings(encoder, crtc_state);
|
||||
gen11_dsi_gate_clocks(encoder);
|
||||
|
||||
gen11_dsi_setup_timings(encoder, crtc_state);
|
||||
|
||||
/* Since transcoder is configured to take events from GPIO */
|
||||
gen11_dsi_config_util_pin(encoder, true);
|
||||
@ -1104,9 +1122,6 @@ gen11_dsi_enable_port_and_phy(struct intel_encoder *encoder,
|
||||
|
||||
/* Step (4h, 4i, 4j, 4k): Configure transcoder */
|
||||
gen11_dsi_configure_transcoder(encoder, crtc_state);
|
||||
|
||||
/* Step 4l: Gate DDI clocks */
|
||||
gen11_dsi_gate_clocks(encoder);
|
||||
}
|
||||
|
||||
static void gen11_dsi_powerup_panel(struct intel_encoder *encoder)
|
||||
@ -1138,12 +1153,7 @@ static void gen11_dsi_powerup_panel(struct intel_encoder *encoder)
|
||||
"error setting max return pkt size%d\n", tmp);
|
||||
}
|
||||
|
||||
/* panel power on related mipi dsi vbt sequences */
|
||||
intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_POWER_ON);
|
||||
msleep(intel_dsi->panel_on_delay);
|
||||
intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_DEASSERT_RESET);
|
||||
intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_INIT_OTP);
|
||||
intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_DISPLAY_ON);
|
||||
|
||||
/* ensure all panel commands dispatched before enabling transcoder */
|
||||
wait_for_cmds_dispatched_to_panel(encoder);
|
||||
@ -1154,6 +1164,14 @@ static void gen11_dsi_pre_pll_enable(struct intel_atomic_state *state,
|
||||
const struct intel_crtc_state *crtc_state,
|
||||
const struct drm_connector_state *conn_state)
|
||||
{
|
||||
struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
|
||||
|
||||
intel_dsi_wait_panel_power_cycle(intel_dsi);
|
||||
|
||||
intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_POWER_ON);
|
||||
msleep(intel_dsi->panel_on_delay);
|
||||
intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_DEASSERT_RESET);
|
||||
|
||||
/* step2: enable IO power */
|
||||
gen11_dsi_enable_io_power(encoder);
|
||||
|
||||
@ -1225,9 +1243,7 @@ static void gen11_dsi_enable(struct intel_atomic_state *state,
|
||||
const struct drm_connector_state *conn_state)
|
||||
{
|
||||
struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
|
||||
struct intel_crtc *crtc = to_intel_crtc(conn_state->crtc);
|
||||
|
||||
drm_WARN_ON(state->base.dev, crtc_state->has_pch_encoder);
|
||||
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
||||
|
||||
/* Wa_1409054076:icl,jsl,ehl */
|
||||
icl_apply_kvmr_pipe_a_wa(encoder, crtc->pipe, true);
|
||||
@ -1238,6 +1254,8 @@ static void gen11_dsi_enable(struct intel_atomic_state *state,
|
||||
/* step6d: enable dsi transcoder */
|
||||
gen11_dsi_enable_transcoder(encoder);
|
||||
|
||||
intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_DISPLAY_ON);
|
||||
|
||||
/* step7: enable backlight */
|
||||
intel_backlight_enable(crtc_state, conn_state);
|
||||
intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_BACKLIGHT_ON);
|
||||
@ -1271,8 +1289,6 @@ static void gen11_dsi_powerdown_panel(struct intel_encoder *encoder)
|
||||
struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
|
||||
|
||||
intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_DISPLAY_OFF);
|
||||
intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_ASSERT_RESET);
|
||||
intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_POWER_OFF);
|
||||
|
||||
/* ensure cmds dispatched to panel */
|
||||
wait_for_cmds_dispatched_to_panel(encoder);
|
||||
@ -1373,11 +1389,21 @@ static void gen11_dsi_disable(struct intel_atomic_state *state,
|
||||
const struct drm_connector_state *old_conn_state)
|
||||
{
|
||||
struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
|
||||
struct intel_crtc *crtc = to_intel_crtc(old_conn_state->crtc);
|
||||
|
||||
/* step1: turn off backlight */
|
||||
intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_BACKLIGHT_OFF);
|
||||
intel_backlight_disable(old_conn_state);
|
||||
}
|
||||
|
||||
static void gen11_dsi_post_disable(struct intel_atomic_state *state,
|
||||
struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *old_crtc_state,
|
||||
const struct drm_connector_state *old_conn_state)
|
||||
{
|
||||
struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
|
||||
struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
|
||||
|
||||
intel_crtc_vblank_off(old_crtc_state);
|
||||
|
||||
/* step2d,e: disable transcoder and wait */
|
||||
gen11_dsi_disable_transcoder(encoder);
|
||||
@ -1391,6 +1417,9 @@ static void gen11_dsi_disable(struct intel_atomic_state *state,
|
||||
/* step2h,i,j: deconfig trancoder */
|
||||
gen11_dsi_deconfigure_trancoder(encoder);
|
||||
|
||||
intel_dsc_disable(old_crtc_state);
|
||||
skl_scaler_disable(old_crtc_state);
|
||||
|
||||
/* step3: disable port */
|
||||
gen11_dsi_disable_port(encoder);
|
||||
|
||||
@ -1398,18 +1427,13 @@ static void gen11_dsi_disable(struct intel_atomic_state *state,
|
||||
|
||||
/* step4: disable IO power */
|
||||
gen11_dsi_disable_io_power(encoder);
|
||||
}
|
||||
|
||||
static void gen11_dsi_post_disable(struct intel_atomic_state *state,
|
||||
struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *old_crtc_state,
|
||||
const struct drm_connector_state *old_conn_state)
|
||||
{
|
||||
intel_crtc_vblank_off(old_crtc_state);
|
||||
intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_ASSERT_RESET);
|
||||
|
||||
intel_dsc_disable(old_crtc_state);
|
||||
msleep(intel_dsi->panel_off_delay);
|
||||
intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_POWER_OFF);
|
||||
|
||||
skl_scaler_disable(old_crtc_state);
|
||||
intel_dsi->panel_power_off_time = ktime_get_boottime();
|
||||
}
|
||||
|
||||
static enum drm_mode_status gen11_dsi_mode_valid(struct drm_connector *connector,
|
||||
@ -1909,7 +1933,8 @@ static void icl_dsi_add_properties(struct intel_connector *connector)
|
||||
fixed_mode->vdisplay);
|
||||
}
|
||||
|
||||
void icl_dsi_init(struct drm_i915_private *dev_priv)
|
||||
void icl_dsi_init(struct drm_i915_private *dev_priv,
|
||||
const struct intel_bios_encoder_data *devdata)
|
||||
{
|
||||
struct intel_dsi *intel_dsi;
|
||||
struct intel_encoder *encoder;
|
||||
@ -1917,7 +1942,8 @@ void icl_dsi_init(struct drm_i915_private *dev_priv)
|
||||
struct drm_connector *connector;
|
||||
enum port port;
|
||||
|
||||
if (!intel_bios_is_dsi_present(dev_priv, &port))
|
||||
port = intel_bios_encoder_port(devdata);
|
||||
if (port == PORT_NONE)
|
||||
return;
|
||||
|
||||
intel_dsi = kzalloc(sizeof(*intel_dsi), GFP_KERNEL);
|
||||
@ -1934,6 +1960,8 @@ void icl_dsi_init(struct drm_i915_private *dev_priv)
|
||||
intel_dsi->attached_connector = intel_connector;
|
||||
connector = &intel_connector->base;
|
||||
|
||||
encoder->devdata = devdata;
|
||||
|
||||
/* register DSI encoder with DRM subsystem */
|
||||
drm_encoder_init(&dev_priv->drm, &encoder->base, &gen11_dsi_encoder_funcs,
|
||||
DRM_MODE_ENCODER_DSI, "DSI %c", port_name(port));
|
||||
@ -1957,6 +1985,7 @@ void icl_dsi_init(struct drm_i915_private *dev_priv)
|
||||
encoder->get_power_domains = gen11_dsi_get_power_domains;
|
||||
encoder->disable_clock = gen11_dsi_gate_clocks;
|
||||
encoder->is_clock_enabled = gen11_dsi_is_clock_enabled;
|
||||
encoder->shutdown = intel_dsi_shutdown;
|
||||
|
||||
/* register DSI connector with DRM subsystem */
|
||||
drm_connector_init(&dev_priv->drm, connector, &gen11_dsi_connector_funcs,
|
||||
@ -1968,7 +1997,8 @@ void icl_dsi_init(struct drm_i915_private *dev_priv)
|
||||
/* attach connector to encoder */
|
||||
intel_connector_attach_encoder(intel_connector, encoder);
|
||||
|
||||
encoder->devdata = intel_bios_encoder_data_lookup(dev_priv, port);
|
||||
intel_dsi->panel_power_off_time = ktime_get_boottime();
|
||||
|
||||
intel_bios_init_panel_late(dev_priv, &intel_connector->panel, encoder->devdata, NULL);
|
||||
|
||||
mutex_lock(&dev_priv->drm.mode_config.mutex);
|
||||
|
@ -7,9 +7,11 @@
|
||||
#define __ICL_DSI_H__
|
||||
|
||||
struct drm_i915_private;
|
||||
struct intel_bios_encoder_data;
|
||||
struct intel_crtc_state;
|
||||
|
||||
void icl_dsi_init(struct drm_i915_private *i915);
|
||||
void icl_dsi_init(struct drm_i915_private *dev_priv,
|
||||
const struct intel_bios_encoder_data *devdata);
|
||||
void icl_dsi_frame_update(struct intel_crtc_state *crtc_state);
|
||||
|
||||
#endif /* __ICL_DSI_H__ */
|
||||
|
@ -212,6 +212,7 @@ intel_plane_relative_data_rate(const struct intel_crtc_state *crtc_state,
|
||||
struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
|
||||
const struct drm_framebuffer *fb = plane_state->hw.fb;
|
||||
int width, height;
|
||||
unsigned int rel_data_rate;
|
||||
|
||||
if (plane->id == PLANE_CURSOR)
|
||||
return 0;
|
||||
@ -241,7 +242,11 @@ intel_plane_relative_data_rate(const struct intel_crtc_state *crtc_state,
|
||||
height /= 2;
|
||||
}
|
||||
|
||||
return width * height * fb->format->cpp[color_plane];
|
||||
rel_data_rate = width * height * fb->format->cpp[color_plane];
|
||||
|
||||
return intel_adjusted_rate(&plane_state->uapi.src,
|
||||
&plane_state->uapi.dst,
|
||||
rel_data_rate);
|
||||
}
|
||||
|
||||
int intel_plane_calc_min_cdclk(struct intel_atomic_state *state,
|
||||
|
@ -2230,122 +2230,6 @@ static u8 map_ddc_pin(struct drm_i915_private *i915, u8 vbt_pin)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static enum port get_port_by_ddc_pin(struct drm_i915_private *i915, u8 ddc_pin)
|
||||
{
|
||||
enum port port;
|
||||
|
||||
if (!ddc_pin)
|
||||
return PORT_NONE;
|
||||
|
||||
for_each_port(port) {
|
||||
const struct intel_bios_encoder_data *devdata =
|
||||
i915->display.vbt.ports[port];
|
||||
|
||||
if (devdata && ddc_pin == devdata->child.ddc_pin)
|
||||
return port;
|
||||
}
|
||||
|
||||
return PORT_NONE;
|
||||
}
|
||||
|
||||
static void sanitize_ddc_pin(struct intel_bios_encoder_data *devdata,
|
||||
enum port port)
|
||||
{
|
||||
struct drm_i915_private *i915 = devdata->i915;
|
||||
struct child_device_config *child;
|
||||
u8 mapped_ddc_pin;
|
||||
enum port p;
|
||||
|
||||
if (!devdata->child.ddc_pin)
|
||||
return;
|
||||
|
||||
mapped_ddc_pin = map_ddc_pin(i915, devdata->child.ddc_pin);
|
||||
if (!intel_gmbus_is_valid_pin(i915, mapped_ddc_pin)) {
|
||||
drm_dbg_kms(&i915->drm,
|
||||
"Port %c has invalid DDC pin %d, "
|
||||
"sticking to defaults\n",
|
||||
port_name(port), mapped_ddc_pin);
|
||||
devdata->child.ddc_pin = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
p = get_port_by_ddc_pin(i915, devdata->child.ddc_pin);
|
||||
if (p == PORT_NONE)
|
||||
return;
|
||||
|
||||
drm_dbg_kms(&i915->drm,
|
||||
"port %c trying to use the same DDC pin (0x%x) as port %c, "
|
||||
"disabling port %c DVI/HDMI support\n",
|
||||
port_name(port), mapped_ddc_pin,
|
||||
port_name(p), port_name(p));
|
||||
|
||||
/*
|
||||
* If we have multiple ports supposedly sharing the pin, then dvi/hdmi
|
||||
* couldn't exist on the shared port. Otherwise they share the same ddc
|
||||
* pin and system couldn't communicate with them separately.
|
||||
*
|
||||
* Give inverse child device order the priority, last one wins. Yes,
|
||||
* there are real machines (eg. Asrock B250M-HDV) where VBT has both
|
||||
* port A and port E with the same AUX ch and we must pick port E :(
|
||||
*/
|
||||
child = &i915->display.vbt.ports[p]->child;
|
||||
|
||||
child->device_type &= ~DEVICE_TYPE_TMDS_DVI_SIGNALING;
|
||||
child->device_type |= DEVICE_TYPE_NOT_HDMI_OUTPUT;
|
||||
|
||||
child->ddc_pin = 0;
|
||||
}
|
||||
|
||||
static enum port get_port_by_aux_ch(struct drm_i915_private *i915, u8 aux_ch)
|
||||
{
|
||||
enum port port;
|
||||
|
||||
if (!aux_ch)
|
||||
return PORT_NONE;
|
||||
|
||||
for_each_port(port) {
|
||||
const struct intel_bios_encoder_data *devdata =
|
||||
i915->display.vbt.ports[port];
|
||||
|
||||
if (devdata && aux_ch == devdata->child.aux_channel)
|
||||
return port;
|
||||
}
|
||||
|
||||
return PORT_NONE;
|
||||
}
|
||||
|
||||
static void sanitize_aux_ch(struct intel_bios_encoder_data *devdata,
|
||||
enum port port)
|
||||
{
|
||||
struct drm_i915_private *i915 = devdata->i915;
|
||||
struct child_device_config *child;
|
||||
enum port p;
|
||||
|
||||
p = get_port_by_aux_ch(i915, devdata->child.aux_channel);
|
||||
if (p == PORT_NONE)
|
||||
return;
|
||||
|
||||
drm_dbg_kms(&i915->drm,
|
||||
"port %c trying to use the same AUX CH (0x%x) as port %c, "
|
||||
"disabling port %c DP support\n",
|
||||
port_name(port), devdata->child.aux_channel,
|
||||
port_name(p), port_name(p));
|
||||
|
||||
/*
|
||||
* If we have multiple ports supposedly sharing the aux channel, then DP
|
||||
* couldn't exist on the shared port. Otherwise they share the same aux
|
||||
* channel and system couldn't communicate with them separately.
|
||||
*
|
||||
* Give inverse child device order the priority, last one wins. Yes,
|
||||
* there are real machines (eg. Asrock B250M-HDV) where VBT has both
|
||||
* port A and port E with the same AUX ch and we must pick port E :(
|
||||
*/
|
||||
child = &i915->display.vbt.ports[p]->child;
|
||||
|
||||
child->device_type &= ~DEVICE_TYPE_DISPLAYPORT_OUTPUT;
|
||||
child->aux_channel = 0;
|
||||
}
|
||||
|
||||
static u8 dvo_port_type(u8 dvo_port)
|
||||
{
|
||||
switch (dvo_port) {
|
||||
@ -2490,6 +2374,19 @@ dsi_dvo_port_to_port(struct drm_i915_private *i915, u8 dvo_port)
|
||||
}
|
||||
}
|
||||
|
||||
enum port intel_bios_encoder_port(const struct intel_bios_encoder_data *devdata)
|
||||
{
|
||||
struct drm_i915_private *i915 = devdata->i915;
|
||||
const struct child_device_config *child = &devdata->child;
|
||||
enum port port;
|
||||
|
||||
port = dvo_port_to_port(i915, child->dvo_port);
|
||||
if (port == PORT_NONE && DISPLAY_VER(i915) >= 11)
|
||||
port = dsi_dvo_port_to_port(i915, child->dvo_port);
|
||||
|
||||
return port;
|
||||
}
|
||||
|
||||
static int parse_bdb_230_dp_max_link_rate(const int vbt_max_link_rate)
|
||||
{
|
||||
switch (vbt_max_link_rate) {
|
||||
@ -2600,7 +2497,7 @@ intel_bios_encoder_supports_edp(const struct intel_bios_encoder_data *devdata)
|
||||
devdata->child.device_type & DEVICE_TYPE_INTERNAL_CONNECTOR;
|
||||
}
|
||||
|
||||
static bool
|
||||
bool
|
||||
intel_bios_encoder_supports_dsi(const struct intel_bios_encoder_data *devdata)
|
||||
{
|
||||
return devdata->child.device_type & DEVICE_TYPE_MIPI_OUTPUT;
|
||||
@ -2615,7 +2512,8 @@ intel_bios_encoder_is_lspcon(const struct intel_bios_encoder_data *devdata)
|
||||
/* This is an index in the HDMI/DVI DDI buffer translation table, or -1 */
|
||||
int intel_bios_hdmi_level_shift(const struct intel_bios_encoder_data *devdata)
|
||||
{
|
||||
if (!devdata || devdata->i915->display.vbt.version < 158)
|
||||
if (!devdata || devdata->i915->display.vbt.version < 158 ||
|
||||
DISPLAY_VER(devdata->i915) >= 14)
|
||||
return -1;
|
||||
|
||||
return devdata->child.hdmi_level_shifter_value;
|
||||
@ -2658,13 +2556,17 @@ static bool is_port_valid(struct drm_i915_private *i915, enum port port)
|
||||
return true;
|
||||
}
|
||||
|
||||
static void print_ddi_port(const struct intel_bios_encoder_data *devdata,
|
||||
enum port port)
|
||||
static void print_ddi_port(const struct intel_bios_encoder_data *devdata)
|
||||
{
|
||||
struct drm_i915_private *i915 = devdata->i915;
|
||||
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;
|
||||
|
||||
port = intel_bios_encoder_port(devdata);
|
||||
if (port == PORT_NONE)
|
||||
return;
|
||||
|
||||
is_dvi = intel_bios_encoder_supports_dvi(devdata);
|
||||
is_dp = intel_bios_encoder_supports_dp(devdata);
|
||||
@ -2728,12 +2630,9 @@ static void print_ddi_port(const struct intel_bios_encoder_data *devdata,
|
||||
static void parse_ddi_port(struct intel_bios_encoder_data *devdata)
|
||||
{
|
||||
struct drm_i915_private *i915 = devdata->i915;
|
||||
const struct child_device_config *child = &devdata->child;
|
||||
enum port port;
|
||||
|
||||
port = dvo_port_to_port(i915, child->dvo_port);
|
||||
if (port == PORT_NONE && DISPLAY_VER(i915) >= 11)
|
||||
port = dsi_dvo_port_to_port(i915, child->dvo_port);
|
||||
port = intel_bios_encoder_port(devdata);
|
||||
if (port == PORT_NONE)
|
||||
return;
|
||||
|
||||
@ -2744,22 +2643,7 @@ static void parse_ddi_port(struct intel_bios_encoder_data *devdata)
|
||||
return;
|
||||
}
|
||||
|
||||
if (i915->display.vbt.ports[port]) {
|
||||
drm_dbg_kms(&i915->drm,
|
||||
"More than one child device for port %c in VBT, using the first.\n",
|
||||
port_name(port));
|
||||
return;
|
||||
}
|
||||
|
||||
sanitize_device_type(devdata, port);
|
||||
|
||||
if (intel_bios_encoder_supports_dvi(devdata))
|
||||
sanitize_ddc_pin(devdata, port);
|
||||
|
||||
if (intel_bios_encoder_supports_dp(devdata))
|
||||
sanitize_aux_ch(devdata, port);
|
||||
|
||||
i915->display.vbt.ports[port] = devdata;
|
||||
}
|
||||
|
||||
static bool has_ddi_port_info(struct drm_i915_private *i915)
|
||||
@ -2770,7 +2654,6 @@ static bool has_ddi_port_info(struct drm_i915_private *i915)
|
||||
static void parse_ddi_ports(struct drm_i915_private *i915)
|
||||
{
|
||||
struct intel_bios_encoder_data *devdata;
|
||||
enum port port;
|
||||
|
||||
if (!has_ddi_port_info(i915))
|
||||
return;
|
||||
@ -2778,10 +2661,8 @@ static void parse_ddi_ports(struct drm_i915_private *i915)
|
||||
list_for_each_entry(devdata, &i915->display.vbt.display_devices, node)
|
||||
parse_ddi_port(devdata);
|
||||
|
||||
for_each_port(port) {
|
||||
if (i915->display.vbt.ports[port])
|
||||
print_ddi_port(i915->display.vbt.ports[port], port);
|
||||
}
|
||||
list_for_each_entry(devdata, &i915->display.vbt.display_devices, node)
|
||||
print_ddi_port(devdata);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -3706,5 +3587,22 @@ bool intel_bios_encoder_hpd_invert(const struct intel_bios_encoder_data *devdata
|
||||
const struct intel_bios_encoder_data *
|
||||
intel_bios_encoder_data_lookup(struct drm_i915_private *i915, enum port port)
|
||||
{
|
||||
return i915->display.vbt.ports[port];
|
||||
struct intel_bios_encoder_data *devdata;
|
||||
|
||||
list_for_each_entry(devdata, &i915->display.vbt.display_devices, node) {
|
||||
if (intel_bios_encoder_port(devdata) == port)
|
||||
return devdata;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void intel_bios_for_each_encoder(struct drm_i915_private *i915,
|
||||
void (*func)(struct drm_i915_private *i915,
|
||||
const struct intel_bios_encoder_data *devdata))
|
||||
{
|
||||
struct intel_bios_encoder_data *devdata;
|
||||
|
||||
list_for_each_entry(devdata, &i915->display.vbt.display_devices, node)
|
||||
func(i915, devdata);
|
||||
}
|
||||
|
@ -263,10 +263,12 @@ bool intel_bios_encoder_supports_dp(const struct intel_bios_encoder_data *devdat
|
||||
bool intel_bios_encoder_supports_edp(const struct intel_bios_encoder_data *devdata);
|
||||
bool intel_bios_encoder_supports_typec_usb(const struct intel_bios_encoder_data *devdata);
|
||||
bool intel_bios_encoder_supports_tbt(const struct intel_bios_encoder_data *devdata);
|
||||
bool intel_bios_encoder_supports_dsi(const struct intel_bios_encoder_data *devdata);
|
||||
bool intel_bios_encoder_supports_dp_dual_mode(const struct intel_bios_encoder_data *devdata);
|
||||
bool intel_bios_encoder_is_lspcon(const struct intel_bios_encoder_data *devdata);
|
||||
bool intel_bios_encoder_lane_reversal(const struct intel_bios_encoder_data *devdata);
|
||||
bool intel_bios_encoder_hpd_invert(const struct intel_bios_encoder_data *devdata);
|
||||
enum port intel_bios_encoder_port(const struct intel_bios_encoder_data *devdata);
|
||||
enum aux_ch intel_bios_dp_aux_ch(const struct intel_bios_encoder_data *devdata);
|
||||
int intel_bios_dp_boost_level(const struct intel_bios_encoder_data *devdata);
|
||||
int intel_bios_dp_max_lane_count(const struct intel_bios_encoder_data *devdata);
|
||||
@ -276,4 +278,8 @@ int intel_bios_hdmi_ddc_pin(const struct intel_bios_encoder_data *devdata);
|
||||
int intel_bios_hdmi_level_shift(const struct intel_bios_encoder_data *devdata);
|
||||
int intel_bios_hdmi_max_tmds_clock(const struct intel_bios_encoder_data *devdata);
|
||||
|
||||
void intel_bios_for_each_encoder(struct drm_i915_private *i915,
|
||||
void (*func)(struct drm_i915_private *i915,
|
||||
const struct intel_bios_encoder_data *devdata));
|
||||
|
||||
#endif /* _INTEL_BIOS_H_ */
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include "intel_pci_config.h"
|
||||
#include "intel_pcode.h"
|
||||
#include "intel_psr.h"
|
||||
#include "intel_vdsc.h"
|
||||
#include "vlv_sideband.h"
|
||||
|
||||
/**
|
||||
@ -2607,9 +2608,16 @@ int intel_crtc_compute_min_cdclk(const struct intel_crtc_state *crtc_state)
|
||||
* When we decide to use only one VDSC engine, since
|
||||
* each VDSC operates with 1 ppc throughput, pixel clock
|
||||
* cannot be higher than the VDSC clock (cdclk)
|
||||
* If there 2 VDSC engines, then pixel clock can't be higher than
|
||||
* VDSC clock(cdclk) * 2 and so on.
|
||||
*/
|
||||
if (crtc_state->dsc.compression_enable && !crtc_state->dsc.dsc_split)
|
||||
min_cdclk = max(min_cdclk, (int)crtc_state->pixel_rate);
|
||||
if (crtc_state->dsc.compression_enable) {
|
||||
int num_vdsc_instances = intel_dsc_get_num_vdsc_instances(crtc_state);
|
||||
|
||||
min_cdclk = max_t(int, min_cdclk,
|
||||
DIV_ROUND_UP(crtc_state->pixel_rate,
|
||||
num_vdsc_instances));
|
||||
}
|
||||
|
||||
/*
|
||||
* HACK. Currently for TGL/DG2 platforms we calculate
|
||||
|
@ -1453,6 +1453,16 @@ static int glk_degamma_lut_size(struct drm_i915_private *i915)
|
||||
return 35;
|
||||
}
|
||||
|
||||
/*
|
||||
* change_lut_val_precision: helper function to upscale or downscale lut values.
|
||||
* Parameters 'to' and 'from' needs to be less than 32. This should be sufficient
|
||||
* as currently there are no lut values exceeding 32 bit.
|
||||
*/
|
||||
static u32 change_lut_val_precision(u32 lut_val, int to, int from)
|
||||
{
|
||||
return mul_u32_u32(lut_val, (1 << to)) / (1 << from);
|
||||
}
|
||||
|
||||
static void glk_load_degamma_lut(const struct intel_crtc_state *crtc_state,
|
||||
const struct drm_property_blob *blob)
|
||||
{
|
||||
@ -1487,8 +1497,15 @@ static void glk_load_degamma_lut(const struct intel_crtc_state *crtc_state,
|
||||
* ToDo: Extend to max 7.0. Enable 32 bit input value
|
||||
* as compared to just 16 to achieve this.
|
||||
*/
|
||||
u32 lut_val;
|
||||
|
||||
if (DISPLAY_VER(i915) >= 14)
|
||||
lut_val = change_lut_val_precision(lut[i].green, 24, 16);
|
||||
else
|
||||
lut_val = lut[i].green;
|
||||
|
||||
ilk_lut_write(crtc_state, PRE_CSC_GAMC_DATA(pipe),
|
||||
lut[i].green);
|
||||
lut_val);
|
||||
}
|
||||
|
||||
/* Clamp values > 1.0. */
|
||||
@ -3439,6 +3456,14 @@ static struct drm_property_blob *glk_read_degamma_lut(struct intel_crtc *crtc)
|
||||
for (i = 0; i < lut_size; i++) {
|
||||
u32 val = intel_de_read_fw(dev_priv, PRE_CSC_GAMC_DATA(pipe));
|
||||
|
||||
/*
|
||||
* For MTL and beyond, convert back the 24 bit lut values
|
||||
* read from HW to 16 bit values to maintain parity with
|
||||
* userspace values
|
||||
*/
|
||||
if (DISPLAY_VER(dev_priv) >= 14)
|
||||
val = change_lut_val_precision(val, 16, 24);
|
||||
|
||||
lut[i].red = val;
|
||||
lut[i].green = val;
|
||||
lut[i].blue = val;
|
||||
|
@ -1064,6 +1064,8 @@ void intel_crt_init(struct drm_i915_private *dev_priv)
|
||||
}
|
||||
|
||||
if (HAS_DDI(dev_priv)) {
|
||||
assert_port_valid(dev_priv, PORT_E);
|
||||
|
||||
crt->base.port = PORT_E;
|
||||
crt->base.get_config = hsw_crt_get_config;
|
||||
crt->base.get_hw_state = intel_ddi_get_hw_state;
|
||||
|
@ -116,6 +116,7 @@ static int intel_cx0_wait_for_ack(struct drm_i915_private *i915, enum port port,
|
||||
XELPDP_MSGBUS_TIMEOUT_SLOW, val)) {
|
||||
drm_dbg_kms(&i915->drm, "PHY %c Timeout waiting for message ACK. Status: 0x%x\n",
|
||||
phy_name(phy), *val);
|
||||
intel_cx0_bus_reset(i915, port, lane);
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
@ -158,10 +159,8 @@ static int __intel_cx0_read_once(struct drm_i915_private *i915, enum port port,
|
||||
XELPDP_PORT_M2P_ADDRESS(addr));
|
||||
|
||||
ack = intel_cx0_wait_for_ack(i915, port, XELPDP_PORT_P2M_COMMAND_READ_ACK, lane, &val);
|
||||
if (ack < 0) {
|
||||
intel_cx0_bus_reset(i915, port, lane);
|
||||
if (ack < 0)
|
||||
return ack;
|
||||
}
|
||||
|
||||
intel_clear_response_ready_flag(i915, port, lane);
|
||||
|
||||
@ -202,6 +201,7 @@ static int __intel_cx0_write_once(struct drm_i915_private *i915, enum port port,
|
||||
int lane, u16 addr, u8 data, bool committed)
|
||||
{
|
||||
enum phy phy = intel_port_to_phy(i915, port);
|
||||
int ack;
|
||||
u32 val;
|
||||
|
||||
if (intel_de_wait_for_clear(i915, XELPDP_PORT_M2P_MSGBUS_CTL(port, lane),
|
||||
@ -230,10 +230,9 @@ static int __intel_cx0_write_once(struct drm_i915_private *i915, enum port port,
|
||||
}
|
||||
|
||||
if (committed) {
|
||||
if (intel_cx0_wait_for_ack(i915, port, XELPDP_PORT_P2M_COMMAND_WRITE_ACK, lane, &val) < 0) {
|
||||
intel_cx0_bus_reset(i915, port, lane);
|
||||
return -EINVAL;
|
||||
}
|
||||
ack = intel_cx0_wait_for_ack(i915, port, XELPDP_PORT_P2M_COMMAND_WRITE_ACK, lane, &val);
|
||||
if (ack < 0)
|
||||
return ack;
|
||||
} else if ((intel_de_read(i915, XELPDP_PORT_P2M_MSGBUS_STATUS(port, lane)) &
|
||||
XELPDP_PORT_P2M_ERROR_SET)) {
|
||||
drm_dbg_kms(&i915->drm,
|
||||
|
@ -43,8 +43,5 @@ int intel_c20pll_calc_port_clock(struct intel_encoder *encoder,
|
||||
void intel_cx0_phy_set_signal_levels(struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *crtc_state);
|
||||
int intel_cx0_phy_check_hdmi_link_rate(struct intel_hdmi *hdmi, int clock);
|
||||
void intel_cx0_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *crtc_state,
|
||||
u32 level);
|
||||
int intel_mtl_tbt_calc_port_clock(struct intel_encoder *encoder);
|
||||
#endif /* __INTEL_CX0_PHY_H__ */
|
||||
|
@ -32,6 +32,7 @@
|
||||
|
||||
#include "i915_drv.h"
|
||||
#include "i915_reg.h"
|
||||
#include "icl_dsi.h"
|
||||
#include "intel_audio.h"
|
||||
#include "intel_audio_regs.h"
|
||||
#include "intel_backlight.h"
|
||||
@ -4653,13 +4654,95 @@ static void intel_ddi_tc_encoder_shutdown_complete(struct intel_encoder *encoder
|
||||
#define port_tc_name(port) ((port) - PORT_TC1 + '1')
|
||||
#define tc_port_name(tc_port) ((tc_port) - TC_PORT_1 + '1')
|
||||
|
||||
void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port)
|
||||
static bool port_strap_detected(struct drm_i915_private *i915, enum port port)
|
||||
{
|
||||
/* straps not used on skl+ */
|
||||
if (DISPLAY_VER(i915) >= 9)
|
||||
return true;
|
||||
|
||||
switch (port) {
|
||||
case PORT_A:
|
||||
return intel_de_read(i915, DDI_BUF_CTL(PORT_A)) & DDI_INIT_DISPLAY_DETECTED;
|
||||
case PORT_B:
|
||||
return intel_de_read(i915, SFUSE_STRAP) & SFUSE_STRAP_DDIB_DETECTED;
|
||||
case PORT_C:
|
||||
return intel_de_read(i915, SFUSE_STRAP) & SFUSE_STRAP_DDIC_DETECTED;
|
||||
case PORT_D:
|
||||
return intel_de_read(i915, SFUSE_STRAP) & SFUSE_STRAP_DDID_DETECTED;
|
||||
case PORT_E:
|
||||
return true; /* no strap for DDI-E */
|
||||
default:
|
||||
MISSING_CASE(port);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool need_aux_ch(struct intel_encoder *encoder, bool init_dp)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
|
||||
enum phy phy = intel_port_to_phy(i915, encoder->port);
|
||||
|
||||
return init_dp || intel_phy_is_tc(i915, phy);
|
||||
}
|
||||
|
||||
static bool assert_has_icl_dsi(struct drm_i915_private *i915)
|
||||
{
|
||||
return !drm_WARN(&i915->drm, !IS_ALDERLAKE_P(i915) &&
|
||||
!IS_TIGERLAKE(i915) && DISPLAY_VER(i915) != 11,
|
||||
"Platform does not support DSI\n");
|
||||
}
|
||||
|
||||
static bool port_in_use(struct drm_i915_private *i915, enum port port)
|
||||
{
|
||||
struct intel_encoder *encoder;
|
||||
|
||||
for_each_intel_encoder(&i915->drm, encoder) {
|
||||
/* FIXME what about second port for dual link DSI? */
|
||||
if (encoder->port == port)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void intel_ddi_init(struct drm_i915_private *dev_priv,
|
||||
const struct intel_bios_encoder_data *devdata)
|
||||
{
|
||||
struct intel_digital_port *dig_port;
|
||||
struct intel_encoder *encoder;
|
||||
const struct intel_bios_encoder_data *devdata;
|
||||
bool init_hdmi, init_dp;
|
||||
enum phy phy = intel_port_to_phy(dev_priv, port);
|
||||
enum port port;
|
||||
enum phy phy;
|
||||
|
||||
port = intel_bios_encoder_port(devdata);
|
||||
if (port == PORT_NONE)
|
||||
return;
|
||||
|
||||
if (!port_strap_detected(dev_priv, port)) {
|
||||
drm_dbg_kms(&dev_priv->drm,
|
||||
"Port %c strap not detected\n", port_name(port));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!assert_port_valid(dev_priv, port))
|
||||
return;
|
||||
|
||||
if (port_in_use(dev_priv, port)) {
|
||||
drm_dbg_kms(&dev_priv->drm,
|
||||
"Port %c already claimed\n", port_name(port));
|
||||
return;
|
||||
}
|
||||
|
||||
if (intel_bios_encoder_supports_dsi(devdata)) {
|
||||
/* BXT/GLK handled elsewhere, for now at least */
|
||||
if (!assert_has_icl_dsi(dev_priv))
|
||||
return;
|
||||
|
||||
icl_dsi_init(dev_priv, devdata);
|
||||
return;
|
||||
}
|
||||
|
||||
phy = intel_port_to_phy(dev_priv, port);
|
||||
|
||||
/*
|
||||
* On platforms with HTI (aka HDPORT), if it's enabled at boot it may
|
||||
@ -4673,14 +4756,6 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port)
|
||||
return;
|
||||
}
|
||||
|
||||
devdata = intel_bios_encoder_data_lookup(dev_priv, port);
|
||||
if (!devdata) {
|
||||
drm_dbg_kms(&dev_priv->drm,
|
||||
"VBT says port %c is not present\n",
|
||||
port_name(port));
|
||||
return;
|
||||
}
|
||||
|
||||
init_hdmi = intel_bios_encoder_supports_dvi(devdata) ||
|
||||
intel_bios_encoder_supports_hdmi(devdata);
|
||||
init_dp = intel_bios_encoder_supports_dp(devdata);
|
||||
@ -4715,6 +4790,8 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port)
|
||||
if (!dig_port)
|
||||
return;
|
||||
|
||||
dig_port->aux_ch = AUX_CH_NONE;
|
||||
|
||||
encoder = &dig_port->base;
|
||||
encoder->devdata = devdata;
|
||||
|
||||
@ -4895,7 +4972,12 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port)
|
||||
|
||||
dig_port->dp.output_reg = INVALID_MMIO_REG;
|
||||
dig_port->max_lanes = intel_ddi_max_lanes(dig_port);
|
||||
dig_port->aux_ch = intel_dp_aux_ch(encoder);
|
||||
|
||||
if (need_aux_ch(encoder, init_dp)) {
|
||||
dig_port->aux_ch = intel_dp_aux_ch(encoder);
|
||||
if (dig_port->aux_ch == AUX_CH_NONE)
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (intel_phy_is_tc(dev_priv, phy)) {
|
||||
bool is_legacy =
|
||||
|
@ -11,6 +11,7 @@
|
||||
struct drm_connector_state;
|
||||
struct drm_i915_private;
|
||||
struct intel_atomic_state;
|
||||
struct intel_bios_encoder_data;
|
||||
struct intel_connector;
|
||||
struct intel_crtc;
|
||||
struct intel_crtc_state;
|
||||
@ -50,7 +51,8 @@ void hsw_prepare_dp_ddi_buffers(struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *crtc_state);
|
||||
void intel_wait_ddi_buf_idle(struct drm_i915_private *dev_priv,
|
||||
enum port port);
|
||||
void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port);
|
||||
void intel_ddi_init(struct drm_i915_private *dev_priv,
|
||||
const struct intel_bios_encoder_data *devdata);
|
||||
bool intel_ddi_get_hw_state(struct intel_encoder *encoder, enum pipe *pipe);
|
||||
void intel_ddi_enable_transcoder_func(struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *crtc_state);
|
||||
|
@ -1049,12 +1049,26 @@ static const union intel_ddi_buf_trans_entry _mtl_c10_trans_dp14[] = {
|
||||
{ .snps = { 62, 0, 0 } }, /* preset 9 */
|
||||
};
|
||||
|
||||
static const struct intel_ddi_buf_trans mtl_cx0_trans = {
|
||||
static const struct intel_ddi_buf_trans mtl_c10_trans_dp14 = {
|
||||
.entries = _mtl_c10_trans_dp14,
|
||||
.num_entries = ARRAY_SIZE(_mtl_c10_trans_dp14),
|
||||
.hdmi_default_entry = ARRAY_SIZE(_mtl_c10_trans_dp14) - 1,
|
||||
};
|
||||
|
||||
/* DP1.4 */
|
||||
static const union intel_ddi_buf_trans_entry _mtl_c20_trans_dp14[] = {
|
||||
{ .snps = { 20, 0, 0 } }, /* preset 0 */
|
||||
{ .snps = { 24, 0, 4 } }, /* preset 1 */
|
||||
{ .snps = { 30, 0, 9 } }, /* preset 2 */
|
||||
{ .snps = { 34, 0, 14 } }, /* preset 3 */
|
||||
{ .snps = { 29, 0, 0 } }, /* preset 4 */
|
||||
{ .snps = { 34, 0, 5 } }, /* preset 5 */
|
||||
{ .snps = { 38, 0, 10 } }, /* preset 6 */
|
||||
{ .snps = { 36, 0, 0 } }, /* preset 7 */
|
||||
{ .snps = { 40, 0, 6 } }, /* preset 8 */
|
||||
{ .snps = { 48, 0, 0 } }, /* preset 9 */
|
||||
};
|
||||
|
||||
/* DP2.0 */
|
||||
static const union intel_ddi_buf_trans_entry _mtl_c20_trans_uhbr[] = {
|
||||
{ .snps = { 48, 0, 0 } }, /* preset 0 */
|
||||
@ -1072,7 +1086,7 @@ static const union intel_ddi_buf_trans_entry _mtl_c20_trans_uhbr[] = {
|
||||
{ .snps = { 37, 4, 7 } }, /* preset 12 */
|
||||
{ .snps = { 33, 4, 11 } }, /* preset 13 */
|
||||
{ .snps = { 40, 8, 0 } }, /* preset 14 */
|
||||
{ .snps = { 28, 2, 2 } }, /* preset 15 */
|
||||
{ .snps = { 30, 2, 2 } }, /* preset 15 */
|
||||
};
|
||||
|
||||
/* HDMI2.0 */
|
||||
@ -1090,6 +1104,12 @@ static const struct intel_ddi_buf_trans mtl_c20_trans_hdmi = {
|
||||
.hdmi_default_entry = 0,
|
||||
};
|
||||
|
||||
static const struct intel_ddi_buf_trans mtl_c20_trans_dp14 = {
|
||||
.entries = _mtl_c20_trans_dp14,
|
||||
.num_entries = ARRAY_SIZE(_mtl_c20_trans_dp14),
|
||||
.hdmi_default_entry = ARRAY_SIZE(_mtl_c20_trans_dp14) - 1,
|
||||
};
|
||||
|
||||
static const struct intel_ddi_buf_trans mtl_c20_trans_uhbr = {
|
||||
.entries = _mtl_c20_trans_uhbr,
|
||||
.num_entries = ARRAY_SIZE(_mtl_c20_trans_uhbr),
|
||||
@ -1678,8 +1698,10 @@ mtl_get_cx0_buf_trans(struct intel_encoder *encoder,
|
||||
return intel_get_buf_trans(&mtl_c20_trans_uhbr, n_entries);
|
||||
else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI) && !(intel_is_c10phy(i915, phy)))
|
||||
return intel_get_buf_trans(&mtl_c20_trans_hdmi, n_entries);
|
||||
else if (!intel_is_c10phy(i915, phy))
|
||||
return intel_get_buf_trans(&mtl_c20_trans_dp14, n_entries);
|
||||
else
|
||||
return intel_get_buf_trans(&mtl_cx0_trans, n_entries);
|
||||
return intel_get_buf_trans(&mtl_c10_trans_dp14, n_entries);
|
||||
}
|
||||
|
||||
void intel_ddi_buf_trans_init(struct intel_encoder *encoder)
|
||||
|
@ -53,7 +53,6 @@
|
||||
#include "i915_utils.h"
|
||||
#include "i9xx_plane.h"
|
||||
#include "i9xx_wm.h"
|
||||
#include "icl_dsi.h"
|
||||
#include "intel_atomic.h"
|
||||
#include "intel_atomic_plane.h"
|
||||
#include "intel_audio.h"
|
||||
@ -3153,6 +3152,10 @@ static void bdw_set_pipe_misc(const struct intel_crtc_state *crtc_state)
|
||||
if (DISPLAY_VER(dev_priv) >= 12)
|
||||
val |= PIPE_MISC_PIXEL_ROUNDING_TRUNC;
|
||||
|
||||
/* allow PSR with sprite enabled */
|
||||
if (IS_BROADWELL(dev_priv))
|
||||
val |= PIPE_MISC_PSR_MASK_SPRITE_ENABLE;
|
||||
|
||||
intel_de_write(dev_priv, PIPE_MISC(crtc->pipe), val);
|
||||
}
|
||||
|
||||
@ -7143,7 +7146,11 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
|
||||
*/
|
||||
intel_uncore_arm_unclaimed_mmio_detection(&dev_priv->uncore);
|
||||
}
|
||||
intel_display_power_put(dev_priv, POWER_DOMAIN_DC_OFF, wakeref);
|
||||
/*
|
||||
* Delay re-enabling DC states by 17 ms to avoid the off->on->off
|
||||
* toggling overhead at and above 60 FPS.
|
||||
*/
|
||||
intel_display_power_put_async_delay(dev_priv, POWER_DOMAIN_DC_OFF, wakeref, 17);
|
||||
intel_runtime_pm_put(&dev_priv->runtime_pm, state->wakeref);
|
||||
|
||||
/*
|
||||
@ -7387,6 +7394,12 @@ static bool intel_ddi_crt_present(struct drm_i915_private *dev_priv)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool assert_port_valid(struct drm_i915_private *i915, enum port port)
|
||||
{
|
||||
return !drm_WARN(&i915->drm, !(DISPLAY_RUNTIME_INFO(i915)->port_mask & BIT(port)),
|
||||
"Platform does not support port %c\n", port_name(port));
|
||||
}
|
||||
|
||||
void intel_setup_outputs(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
struct intel_encoder *encoder;
|
||||
@ -7397,93 +7410,14 @@ void intel_setup_outputs(struct drm_i915_private *dev_priv)
|
||||
if (!HAS_DISPLAY(dev_priv))
|
||||
return;
|
||||
|
||||
if (IS_METEORLAKE(dev_priv)) {
|
||||
intel_ddi_init(dev_priv, PORT_A);
|
||||
intel_ddi_init(dev_priv, PORT_B);
|
||||
intel_ddi_init(dev_priv, PORT_TC1);
|
||||
intel_ddi_init(dev_priv, PORT_TC2);
|
||||
intel_ddi_init(dev_priv, PORT_TC3);
|
||||
intel_ddi_init(dev_priv, PORT_TC4);
|
||||
} else if (IS_DG2(dev_priv)) {
|
||||
intel_ddi_init(dev_priv, PORT_A);
|
||||
intel_ddi_init(dev_priv, PORT_B);
|
||||
intel_ddi_init(dev_priv, PORT_C);
|
||||
intel_ddi_init(dev_priv, PORT_D_XELPD);
|
||||
intel_ddi_init(dev_priv, PORT_TC1);
|
||||
} else if (IS_ALDERLAKE_P(dev_priv)) {
|
||||
intel_ddi_init(dev_priv, PORT_A);
|
||||
intel_ddi_init(dev_priv, PORT_B);
|
||||
intel_ddi_init(dev_priv, PORT_TC1);
|
||||
intel_ddi_init(dev_priv, PORT_TC2);
|
||||
intel_ddi_init(dev_priv, PORT_TC3);
|
||||
intel_ddi_init(dev_priv, PORT_TC4);
|
||||
icl_dsi_init(dev_priv);
|
||||
} else if (IS_ALDERLAKE_S(dev_priv)) {
|
||||
intel_ddi_init(dev_priv, PORT_A);
|
||||
intel_ddi_init(dev_priv, PORT_TC1);
|
||||
intel_ddi_init(dev_priv, PORT_TC2);
|
||||
intel_ddi_init(dev_priv, PORT_TC3);
|
||||
intel_ddi_init(dev_priv, PORT_TC4);
|
||||
} else if (IS_DG1(dev_priv) || IS_ROCKETLAKE(dev_priv)) {
|
||||
intel_ddi_init(dev_priv, PORT_A);
|
||||
intel_ddi_init(dev_priv, PORT_B);
|
||||
intel_ddi_init(dev_priv, PORT_TC1);
|
||||
intel_ddi_init(dev_priv, PORT_TC2);
|
||||
} else if (DISPLAY_VER(dev_priv) >= 12) {
|
||||
intel_ddi_init(dev_priv, PORT_A);
|
||||
intel_ddi_init(dev_priv, PORT_B);
|
||||
intel_ddi_init(dev_priv, PORT_TC1);
|
||||
intel_ddi_init(dev_priv, PORT_TC2);
|
||||
intel_ddi_init(dev_priv, PORT_TC3);
|
||||
intel_ddi_init(dev_priv, PORT_TC4);
|
||||
intel_ddi_init(dev_priv, PORT_TC5);
|
||||
intel_ddi_init(dev_priv, PORT_TC6);
|
||||
icl_dsi_init(dev_priv);
|
||||
} else if (IS_JSL_EHL(dev_priv)) {
|
||||
intel_ddi_init(dev_priv, PORT_A);
|
||||
intel_ddi_init(dev_priv, PORT_B);
|
||||
intel_ddi_init(dev_priv, PORT_C);
|
||||
intel_ddi_init(dev_priv, PORT_D);
|
||||
icl_dsi_init(dev_priv);
|
||||
} else if (DISPLAY_VER(dev_priv) == 11) {
|
||||
intel_ddi_init(dev_priv, PORT_A);
|
||||
intel_ddi_init(dev_priv, PORT_B);
|
||||
intel_ddi_init(dev_priv, PORT_C);
|
||||
intel_ddi_init(dev_priv, PORT_D);
|
||||
intel_ddi_init(dev_priv, PORT_E);
|
||||
intel_ddi_init(dev_priv, PORT_F);
|
||||
icl_dsi_init(dev_priv);
|
||||
} else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) {
|
||||
intel_ddi_init(dev_priv, PORT_A);
|
||||
intel_ddi_init(dev_priv, PORT_B);
|
||||
intel_ddi_init(dev_priv, PORT_C);
|
||||
vlv_dsi_init(dev_priv);
|
||||
} else if (DISPLAY_VER(dev_priv) >= 9) {
|
||||
intel_ddi_init(dev_priv, PORT_A);
|
||||
intel_ddi_init(dev_priv, PORT_B);
|
||||
intel_ddi_init(dev_priv, PORT_C);
|
||||
intel_ddi_init(dev_priv, PORT_D);
|
||||
intel_ddi_init(dev_priv, PORT_E);
|
||||
} else if (HAS_DDI(dev_priv)) {
|
||||
u32 found;
|
||||
|
||||
if (HAS_DDI(dev_priv)) {
|
||||
if (intel_ddi_crt_present(dev_priv))
|
||||
intel_crt_init(dev_priv);
|
||||
|
||||
/* Haswell uses DDI functions to detect digital outputs. */
|
||||
found = intel_de_read(dev_priv, DDI_BUF_CTL(PORT_A)) & DDI_INIT_DISPLAY_DETECTED;
|
||||
if (found)
|
||||
intel_ddi_init(dev_priv, PORT_A);
|
||||
intel_bios_for_each_encoder(dev_priv, intel_ddi_init);
|
||||
|
||||
found = intel_de_read(dev_priv, SFUSE_STRAP);
|
||||
if (found & SFUSE_STRAP_DDIB_DETECTED)
|
||||
intel_ddi_init(dev_priv, PORT_B);
|
||||
if (found & SFUSE_STRAP_DDIC_DETECTED)
|
||||
intel_ddi_init(dev_priv, PORT_C);
|
||||
if (found & SFUSE_STRAP_DDID_DETECTED)
|
||||
intel_ddi_init(dev_priv, PORT_D);
|
||||
if (found & SFUSE_STRAP_DDIF_DETECTED)
|
||||
intel_ddi_init(dev_priv, PORT_F);
|
||||
if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv))
|
||||
vlv_dsi_init(dev_priv);
|
||||
} else if (HAS_PCH_SPLIT(dev_priv)) {
|
||||
int found;
|
||||
|
||||
|
@ -113,7 +113,7 @@ enum i9xx_plane_id {
|
||||
|
||||
#define for_each_dbuf_slice(__dev_priv, __slice) \
|
||||
for ((__slice) = DBUF_S1; (__slice) < I915_MAX_DBUF_SLICES; (__slice)++) \
|
||||
for_each_if(INTEL_INFO(__dev_priv)->display->dbuf.slice_mask & BIT(__slice))
|
||||
for_each_if(DISPLAY_INFO(__dev_priv)->dbuf.slice_mask & BIT(__slice))
|
||||
|
||||
#define for_each_dbuf_slice_in_mask(__dev_priv, __slice, __mask) \
|
||||
for_each_dbuf_slice((__dev_priv), (__slice)) \
|
||||
@ -539,6 +539,8 @@ void assert_transcoder(struct drm_i915_private *dev_priv,
|
||||
#define assert_transcoder_enabled(d, t) assert_transcoder(d, t, true)
|
||||
#define assert_transcoder_disabled(d, t) assert_transcoder(d, t, false)
|
||||
|
||||
bool assert_port_valid(struct drm_i915_private *i915, enum port port);
|
||||
|
||||
/*
|
||||
* Use I915_STATE_WARN(x) (rather than WARN() and WARN_ON()) for hw state sanity
|
||||
* checks to check for unexpected conditions which may not necessarily be a user
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include <drm/drm_modeset_lock.h>
|
||||
|
||||
#include "intel_cdclk.h"
|
||||
#include "intel_display_device.h"
|
||||
#include "intel_display_limits.h"
|
||||
#include "intel_display_power.h"
|
||||
#include "intel_dpll_mgr.h"
|
||||
@ -33,7 +34,6 @@ struct i915_audio_component;
|
||||
struct i915_hdcp_arbiter;
|
||||
struct intel_atomic_state;
|
||||
struct intel_audio_funcs;
|
||||
struct intel_bios_encoder_data;
|
||||
struct intel_cdclk_funcs;
|
||||
struct intel_cdclk_vals;
|
||||
struct intel_color_funcs;
|
||||
@ -218,7 +218,6 @@ struct intel_vbt_data {
|
||||
struct list_head display_devices;
|
||||
struct list_head bdb_blocks;
|
||||
|
||||
struct intel_bios_encoder_data *ports[I915_MAX_PORTS]; /* Non-NULL if port present. */
|
||||
struct sdvo_device_mapping {
|
||||
u8 initialized;
|
||||
u8 dvo_port;
|
||||
@ -429,6 +428,14 @@ struct intel_display {
|
||||
u32 state;
|
||||
} hti;
|
||||
|
||||
struct {
|
||||
/* Access with DISPLAY_INFO() */
|
||||
const struct intel_display_device_info *__device_info;
|
||||
|
||||
/* Access with DISPLAY_RUNTIME_INFO() */
|
||||
struct intel_display_runtime_info __runtime_info;
|
||||
} info;
|
||||
|
||||
struct {
|
||||
bool false_color;
|
||||
} ips;
|
||||
|
@ -819,8 +819,7 @@ static ssize_t i915_displayport_test_active_write(struct file *file,
|
||||
if (IS_ERR(input_buffer))
|
||||
return PTR_ERR(input_buffer);
|
||||
|
||||
drm_dbg(&to_i915(dev)->drm,
|
||||
"Copied %d bytes from user\n", (unsigned int)len);
|
||||
drm_dbg(dev, "Copied %d bytes from user\n", (unsigned int)len);
|
||||
|
||||
drm_connector_list_iter_begin(dev, &conn_iter);
|
||||
drm_for_each_connector_iter(connector, &conn_iter) {
|
||||
@ -839,8 +838,7 @@ static ssize_t i915_displayport_test_active_write(struct file *file,
|
||||
status = kstrtoint(input_buffer, 10, &val);
|
||||
if (status < 0)
|
||||
break;
|
||||
drm_dbg(&to_i915(dev)->drm,
|
||||
"Got %d for test active\n", val);
|
||||
drm_dbg(dev, "Got %d for test active\n", val);
|
||||
/* To prevent erroneous activation of the compliance
|
||||
* testing code, only accept an actual value of 1 here
|
||||
*/
|
||||
|
@ -16,9 +16,6 @@
|
||||
#include "intel_display_reg_defs.h"
|
||||
#include "intel_fbc.h"
|
||||
|
||||
__diag_push();
|
||||
__diag_ignore_all("-Woverride-init", "Allow overriding inherited members");
|
||||
|
||||
static const struct intel_display_device_info no_display = {};
|
||||
|
||||
#define PIPE_A_OFFSET 0x70000
|
||||
@ -187,10 +184,6 @@ static const struct intel_display_device_info no_display = {};
|
||||
.__runtime_defaults.cpu_transcoder_mask = \
|
||||
BIT(TRANSCODER_A) | BIT(TRANSCODER_B)
|
||||
|
||||
static const struct intel_display_device_info i830_display = {
|
||||
I830_DISPLAY,
|
||||
};
|
||||
|
||||
#define I845_DISPLAY \
|
||||
.has_overlay = 1, \
|
||||
.overlay_needs_physical = 1, \
|
||||
@ -203,19 +196,29 @@ static const struct intel_display_device_info i830_display = {
|
||||
.__runtime_defaults.pipe_mask = BIT(PIPE_A), \
|
||||
.__runtime_defaults.cpu_transcoder_mask = BIT(TRANSCODER_A)
|
||||
|
||||
static const struct intel_display_device_info i830_display = {
|
||||
I830_DISPLAY,
|
||||
|
||||
.__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) | BIT(PORT_C), /* DVO A/B/C */
|
||||
};
|
||||
|
||||
static const struct intel_display_device_info i845_display = {
|
||||
I845_DISPLAY,
|
||||
|
||||
.__runtime_defaults.port_mask = BIT(PORT_B) | BIT(PORT_C), /* DVO B/C */
|
||||
};
|
||||
|
||||
static const struct intel_display_device_info i85x_display = {
|
||||
I830_DISPLAY,
|
||||
|
||||
.__runtime_defaults.port_mask = BIT(PORT_B) | BIT(PORT_C), /* DVO B/C */
|
||||
.__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
|
||||
};
|
||||
|
||||
static const struct intel_display_device_info i865g_display = {
|
||||
I845_DISPLAY,
|
||||
|
||||
.__runtime_defaults.port_mask = BIT(PORT_B) | BIT(PORT_C), /* DVO B/C */
|
||||
.__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
|
||||
};
|
||||
|
||||
@ -228,7 +231,8 @@ static const struct intel_display_device_info i865g_display = {
|
||||
.__runtime_defaults.ip.ver = 3, \
|
||||
.__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B), \
|
||||
.__runtime_defaults.cpu_transcoder_mask = \
|
||||
BIT(TRANSCODER_A) | BIT(TRANSCODER_B)
|
||||
BIT(TRANSCODER_A) | BIT(TRANSCODER_B), \
|
||||
.__runtime_defaults.port_mask = BIT(PORT_B) | BIT(PORT_C) /* SDVO B/C */
|
||||
|
||||
static const struct intel_display_device_info i915g_display = {
|
||||
GEN3_DISPLAY,
|
||||
@ -293,6 +297,8 @@ static const struct intel_display_device_info pnv_display = {
|
||||
static const struct intel_display_device_info i965g_display = {
|
||||
GEN4_DISPLAY,
|
||||
.has_overlay = 1,
|
||||
|
||||
.__runtime_defaults.port_mask = BIT(PORT_B) | BIT(PORT_C), /* SDVO B/C */
|
||||
};
|
||||
|
||||
static const struct intel_display_device_info i965gm_display = {
|
||||
@ -300,17 +306,21 @@ static const struct intel_display_device_info i965gm_display = {
|
||||
.has_overlay = 1,
|
||||
.supports_tv = 1,
|
||||
|
||||
.__runtime_defaults.port_mask = BIT(PORT_B) | BIT(PORT_C), /* SDVO B/C */
|
||||
.__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
|
||||
};
|
||||
|
||||
static const struct intel_display_device_info g45_display = {
|
||||
GEN4_DISPLAY,
|
||||
|
||||
.__runtime_defaults.port_mask = BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D), /* SDVO/HDMI/DP B/C, DP D */
|
||||
};
|
||||
|
||||
static const struct intel_display_device_info gm45_display = {
|
||||
GEN4_DISPLAY,
|
||||
.supports_tv = 1,
|
||||
|
||||
.__runtime_defaults.port_mask = BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D), /* SDVO/HDMI/DP B/C, DP D */
|
||||
.__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
|
||||
};
|
||||
|
||||
@ -323,7 +333,8 @@ static const struct intel_display_device_info gm45_display = {
|
||||
.__runtime_defaults.ip.ver = 5, \
|
||||
.__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B), \
|
||||
.__runtime_defaults.cpu_transcoder_mask = \
|
||||
BIT(TRANSCODER_A) | BIT(TRANSCODER_B)
|
||||
BIT(TRANSCODER_A) | BIT(TRANSCODER_B), \
|
||||
.__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D) /* DP A, SDVO/HDMI/DP B, HDMI/DP C/D */
|
||||
|
||||
static const struct intel_display_device_info ilk_d_display = {
|
||||
ILK_DISPLAY,
|
||||
@ -345,6 +356,7 @@ static const struct intel_display_device_info snb_display = {
|
||||
.__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B),
|
||||
.__runtime_defaults.cpu_transcoder_mask =
|
||||
BIT(TRANSCODER_A) | BIT(TRANSCODER_B),
|
||||
.__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D), /* DP A, SDVO/HDMI/DP B, HDMI/DP C/D */
|
||||
.__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
|
||||
};
|
||||
|
||||
@ -358,6 +370,7 @@ static const struct intel_display_device_info ivb_display = {
|
||||
.__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C),
|
||||
.__runtime_defaults.cpu_transcoder_mask =
|
||||
BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | BIT(TRANSCODER_C),
|
||||
.__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D), /* DP A, SDVO/HDMI/DP B, HDMI/DP C/D */
|
||||
.__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
|
||||
};
|
||||
|
||||
@ -373,6 +386,7 @@ static const struct intel_display_device_info vlv_display = {
|
||||
.__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B),
|
||||
.__runtime_defaults.cpu_transcoder_mask =
|
||||
BIT(TRANSCODER_A) | BIT(TRANSCODER_B),
|
||||
.__runtime_defaults.port_mask = BIT(PORT_B) | BIT(PORT_C), /* HDMI/DP B/C */
|
||||
};
|
||||
|
||||
static const struct intel_display_device_info hsw_display = {
|
||||
@ -380,6 +394,8 @@ static const struct intel_display_device_info hsw_display = {
|
||||
.has_dp_mst = 1,
|
||||
.has_fpga_dbg = 1,
|
||||
.has_hotplug = 1,
|
||||
.has_psr = 1,
|
||||
.has_psr_hw_tracking = 1,
|
||||
HSW_PIPE_OFFSETS,
|
||||
IVB_CURSOR_OFFSETS,
|
||||
IVB_COLORS,
|
||||
@ -389,6 +405,7 @@ static const struct intel_display_device_info hsw_display = {
|
||||
.__runtime_defaults.cpu_transcoder_mask =
|
||||
BIT(TRANSCODER_A) | BIT(TRANSCODER_B) |
|
||||
BIT(TRANSCODER_C) | BIT(TRANSCODER_EDP),
|
||||
.__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D) | BIT(PORT_E),
|
||||
.__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
|
||||
};
|
||||
|
||||
@ -397,6 +414,8 @@ static const struct intel_display_device_info bdw_display = {
|
||||
.has_dp_mst = 1,
|
||||
.has_fpga_dbg = 1,
|
||||
.has_hotplug = 1,
|
||||
.has_psr = 1,
|
||||
.has_psr_hw_tracking = 1,
|
||||
HSW_PIPE_OFFSETS,
|
||||
IVB_CURSOR_OFFSETS,
|
||||
IVB_COLORS,
|
||||
@ -406,6 +425,7 @@ static const struct intel_display_device_info bdw_display = {
|
||||
.__runtime_defaults.cpu_transcoder_mask =
|
||||
BIT(TRANSCODER_A) | BIT(TRANSCODER_B) |
|
||||
BIT(TRANSCODER_C) | BIT(TRANSCODER_EDP),
|
||||
.__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D) | BIT(PORT_E),
|
||||
.__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
|
||||
};
|
||||
|
||||
@ -421,6 +441,7 @@ static const struct intel_display_device_info chv_display = {
|
||||
.__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C),
|
||||
.__runtime_defaults.cpu_transcoder_mask =
|
||||
BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | BIT(TRANSCODER_C),
|
||||
.__runtime_defaults.port_mask = BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D), /* HDMI/DP B/C/D */
|
||||
};
|
||||
|
||||
static const struct intel_display_device_info skl_display = {
|
||||
@ -444,6 +465,7 @@ static const struct intel_display_device_info skl_display = {
|
||||
.__runtime_defaults.cpu_transcoder_mask =
|
||||
BIT(TRANSCODER_A) | BIT(TRANSCODER_B) |
|
||||
BIT(TRANSCODER_C) | BIT(TRANSCODER_EDP),
|
||||
.__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D) | BIT(PORT_E),
|
||||
.__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
|
||||
};
|
||||
|
||||
@ -467,7 +489,8 @@ static const struct intel_display_device_info skl_display = {
|
||||
.__runtime_defaults.cpu_transcoder_mask = \
|
||||
BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | \
|
||||
BIT(TRANSCODER_C) | BIT(TRANSCODER_EDP) | \
|
||||
BIT(TRANSCODER_DSI_A) | BIT(TRANSCODER_DSI_C)
|
||||
BIT(TRANSCODER_DSI_A) | BIT(TRANSCODER_DSI_C), \
|
||||
.__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) | BIT(PORT_C)
|
||||
|
||||
static const struct intel_display_device_info bxt_display = {
|
||||
GEN9_LP_DISPLAY,
|
||||
@ -484,46 +507,57 @@ static const struct intel_display_device_info glk_display = {
|
||||
.__runtime_defaults.ip.ver = 10,
|
||||
};
|
||||
|
||||
static const struct intel_display_device_info gen11_display = {
|
||||
.abox_mask = BIT(0),
|
||||
.dbuf.size = 2048,
|
||||
.dbuf.slice_mask = BIT(DBUF_S1) | BIT(DBUF_S2),
|
||||
.has_ddi = 1,
|
||||
.has_dp_mst = 1,
|
||||
.has_fpga_dbg = 1,
|
||||
.has_hotplug = 1,
|
||||
.has_ipc = 1,
|
||||
.has_psr = 1,
|
||||
.has_psr_hw_tracking = 1,
|
||||
.pipe_offsets = {
|
||||
[TRANSCODER_A] = PIPE_A_OFFSET,
|
||||
[TRANSCODER_B] = PIPE_B_OFFSET,
|
||||
[TRANSCODER_C] = PIPE_C_OFFSET,
|
||||
[TRANSCODER_EDP] = PIPE_EDP_OFFSET,
|
||||
[TRANSCODER_DSI_0] = PIPE_DSI0_OFFSET,
|
||||
[TRANSCODER_DSI_1] = PIPE_DSI1_OFFSET,
|
||||
},
|
||||
.trans_offsets = {
|
||||
[TRANSCODER_A] = TRANSCODER_A_OFFSET,
|
||||
[TRANSCODER_B] = TRANSCODER_B_OFFSET,
|
||||
[TRANSCODER_C] = TRANSCODER_C_OFFSET,
|
||||
[TRANSCODER_EDP] = TRANSCODER_EDP_OFFSET,
|
||||
[TRANSCODER_DSI_0] = TRANSCODER_DSI0_OFFSET,
|
||||
[TRANSCODER_DSI_1] = TRANSCODER_DSI1_OFFSET,
|
||||
},
|
||||
IVB_CURSOR_OFFSETS,
|
||||
ICL_COLORS,
|
||||
#define ICL_DISPLAY \
|
||||
.abox_mask = BIT(0), \
|
||||
.dbuf.size = 2048, \
|
||||
.dbuf.slice_mask = BIT(DBUF_S1) | BIT(DBUF_S2), \
|
||||
.has_ddi = 1, \
|
||||
.has_dp_mst = 1, \
|
||||
.has_fpga_dbg = 1, \
|
||||
.has_hotplug = 1, \
|
||||
.has_ipc = 1, \
|
||||
.has_psr = 1, \
|
||||
.has_psr_hw_tracking = 1, \
|
||||
.pipe_offsets = { \
|
||||
[TRANSCODER_A] = PIPE_A_OFFSET, \
|
||||
[TRANSCODER_B] = PIPE_B_OFFSET, \
|
||||
[TRANSCODER_C] = PIPE_C_OFFSET, \
|
||||
[TRANSCODER_EDP] = PIPE_EDP_OFFSET, \
|
||||
[TRANSCODER_DSI_0] = PIPE_DSI0_OFFSET, \
|
||||
[TRANSCODER_DSI_1] = PIPE_DSI1_OFFSET, \
|
||||
}, \
|
||||
.trans_offsets = { \
|
||||
[TRANSCODER_A] = TRANSCODER_A_OFFSET, \
|
||||
[TRANSCODER_B] = TRANSCODER_B_OFFSET, \
|
||||
[TRANSCODER_C] = TRANSCODER_C_OFFSET, \
|
||||
[TRANSCODER_EDP] = TRANSCODER_EDP_OFFSET, \
|
||||
[TRANSCODER_DSI_0] = TRANSCODER_DSI0_OFFSET, \
|
||||
[TRANSCODER_DSI_1] = TRANSCODER_DSI1_OFFSET, \
|
||||
}, \
|
||||
IVB_CURSOR_OFFSETS, \
|
||||
ICL_COLORS, \
|
||||
\
|
||||
.__runtime_defaults.ip.ver = 11, \
|
||||
.__runtime_defaults.has_dmc = 1, \
|
||||
.__runtime_defaults.has_dsc = 1, \
|
||||
.__runtime_defaults.has_hdcp = 1, \
|
||||
.__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C), \
|
||||
.__runtime_defaults.cpu_transcoder_mask = \
|
||||
BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | \
|
||||
BIT(TRANSCODER_C) | BIT(TRANSCODER_EDP) | \
|
||||
BIT(TRANSCODER_DSI_0) | BIT(TRANSCODER_DSI_1), \
|
||||
.__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A)
|
||||
|
||||
.__runtime_defaults.ip.ver = 11,
|
||||
.__runtime_defaults.has_dmc = 1,
|
||||
.__runtime_defaults.has_dsc = 1,
|
||||
.__runtime_defaults.has_hdcp = 1,
|
||||
.__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C),
|
||||
.__runtime_defaults.cpu_transcoder_mask =
|
||||
BIT(TRANSCODER_A) | BIT(TRANSCODER_B) |
|
||||
BIT(TRANSCODER_C) | BIT(TRANSCODER_EDP) |
|
||||
BIT(TRANSCODER_DSI_0) | BIT(TRANSCODER_DSI_1),
|
||||
.__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
|
||||
static const struct intel_display_device_info icl_display = {
|
||||
ICL_DISPLAY,
|
||||
|
||||
.__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D) | BIT(PORT_E),
|
||||
};
|
||||
|
||||
static const struct intel_display_device_info jsl_ehl_display = {
|
||||
ICL_DISPLAY,
|
||||
|
||||
.__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D),
|
||||
};
|
||||
|
||||
#define XE_D_DISPLAY \
|
||||
@ -571,6 +605,20 @@ static const struct intel_display_device_info gen11_display = {
|
||||
|
||||
static const struct intel_display_device_info tgl_display = {
|
||||
XE_D_DISPLAY,
|
||||
|
||||
/*
|
||||
* FIXME DDI C/combo PHY C missing due to combo PHY
|
||||
* code making a mess on SKUs where the PHY is missing.
|
||||
*/
|
||||
.__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) |
|
||||
BIT(PORT_TC1) | BIT(PORT_TC2) | BIT(PORT_TC3) | BIT(PORT_TC4) | BIT(PORT_TC5) | BIT(PORT_TC6),
|
||||
};
|
||||
|
||||
static const struct intel_display_device_info dg1_display = {
|
||||
XE_D_DISPLAY,
|
||||
|
||||
.__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) |
|
||||
BIT(PORT_TC1) | BIT(PORT_TC2),
|
||||
};
|
||||
|
||||
static const struct intel_display_device_info rkl_display = {
|
||||
@ -582,12 +630,17 @@ static const struct intel_display_device_info rkl_display = {
|
||||
.__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C),
|
||||
.__runtime_defaults.cpu_transcoder_mask =
|
||||
BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | BIT(TRANSCODER_C),
|
||||
.__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) |
|
||||
BIT(PORT_TC1) | BIT(PORT_TC2),
|
||||
};
|
||||
|
||||
static const struct intel_display_device_info adl_s_display = {
|
||||
XE_D_DISPLAY,
|
||||
.has_hti = 1,
|
||||
.has_psr_hw_tracking = 0,
|
||||
|
||||
.__runtime_defaults.port_mask = BIT(PORT_A) |
|
||||
BIT(PORT_TC1) | BIT(PORT_TC2) | BIT(PORT_TC3) | BIT(PORT_TC4),
|
||||
};
|
||||
|
||||
#define XE_LPD_FEATURES \
|
||||
@ -642,6 +695,8 @@ static const struct intel_display_device_info xe_lpd_display = {
|
||||
BIT(TRANSCODER_A) | BIT(TRANSCODER_B) |
|
||||
BIT(TRANSCODER_C) | BIT(TRANSCODER_D) |
|
||||
BIT(TRANSCODER_DSI_0) | BIT(TRANSCODER_DSI_1),
|
||||
.__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) |
|
||||
BIT(PORT_TC1) | BIT(PORT_TC2) | BIT(PORT_TC3) | BIT(PORT_TC4),
|
||||
};
|
||||
|
||||
static const struct intel_display_device_info xe_hpd_display = {
|
||||
@ -651,6 +706,8 @@ static const struct intel_display_device_info xe_hpd_display = {
|
||||
.__runtime_defaults.cpu_transcoder_mask =
|
||||
BIT(TRANSCODER_A) | BIT(TRANSCODER_B) |
|
||||
BIT(TRANSCODER_C) | BIT(TRANSCODER_D),
|
||||
.__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D_XELPD) |
|
||||
BIT(PORT_TC1),
|
||||
};
|
||||
|
||||
static const struct intel_display_device_info xe_lpdp_display = {
|
||||
@ -663,10 +720,10 @@ static const struct intel_display_device_info xe_lpdp_display = {
|
||||
.__runtime_defaults.cpu_transcoder_mask =
|
||||
BIT(TRANSCODER_A) | BIT(TRANSCODER_B) |
|
||||
BIT(TRANSCODER_C) | BIT(TRANSCODER_D),
|
||||
.__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) |
|
||||
BIT(PORT_TC1) | BIT(PORT_TC2) | BIT(PORT_TC3) | BIT(PORT_TC4),
|
||||
};
|
||||
|
||||
__diag_pop();
|
||||
|
||||
#undef INTEL_VGA_DEVICE
|
||||
#undef INTEL_QUANTA_VGA_DEVICE
|
||||
#define INTEL_VGA_DEVICE(id, info) { id, info }
|
||||
@ -707,11 +764,11 @@ static const struct {
|
||||
INTEL_GLK_IDS(&glk_display),
|
||||
INTEL_KBL_IDS(&skl_display),
|
||||
INTEL_CFL_IDS(&skl_display),
|
||||
INTEL_ICL_11_IDS(&gen11_display),
|
||||
INTEL_EHL_IDS(&gen11_display),
|
||||
INTEL_JSL_IDS(&gen11_display),
|
||||
INTEL_ICL_11_IDS(&icl_display),
|
||||
INTEL_EHL_IDS(&jsl_ehl_display),
|
||||
INTEL_JSL_IDS(&jsl_ehl_display),
|
||||
INTEL_TGL_12_IDS(&tgl_display),
|
||||
INTEL_DG1_IDS(&tgl_display),
|
||||
INTEL_DG1_IDS(&dg1_display),
|
||||
INTEL_RKL_IDS(&rkl_display),
|
||||
INTEL_ADLS_IDS(&adl_s_display),
|
||||
INTEL_RPLS_IDS(&adl_s_display),
|
||||
@ -796,6 +853,10 @@ void intel_display_device_info_runtime_init(struct drm_i915_private *i915)
|
||||
struct intel_display_runtime_info *display_runtime = DISPLAY_RUNTIME_INFO(i915);
|
||||
enum pipe pipe;
|
||||
|
||||
BUILD_BUG_ON(BITS_PER_TYPE(display_runtime->pipe_mask) < I915_MAX_PIPES);
|
||||
BUILD_BUG_ON(BITS_PER_TYPE(display_runtime->cpu_transcoder_mask) < I915_MAX_TRANSCODERS);
|
||||
BUILD_BUG_ON(BITS_PER_TYPE(display_runtime->port_mask) < I915_MAX_PORTS);
|
||||
|
||||
/* Wa_14011765242: adl-s A0,A1 */
|
||||
if (IS_ADLS_DISPLAY_STEP(i915, STEP_A0, STEP_A2))
|
||||
for_each_pipe(i915, pipe)
|
||||
@ -915,3 +976,24 @@ void intel_display_device_info_runtime_init(struct drm_i915_private *i915)
|
||||
display_fused_off:
|
||||
memset(display_runtime, 0, sizeof(*display_runtime));
|
||||
}
|
||||
|
||||
void intel_display_device_info_print(const struct intel_display_device_info *info,
|
||||
const struct intel_display_runtime_info *runtime,
|
||||
struct drm_printer *p)
|
||||
{
|
||||
if (runtime->ip.rel)
|
||||
drm_printf(p, "display version: %u.%02u\n",
|
||||
runtime->ip.ver,
|
||||
runtime->ip.rel);
|
||||
else
|
||||
drm_printf(p, "display version: %u\n",
|
||||
runtime->ip.ver);
|
||||
|
||||
#define PRINT_FLAG(name) drm_printf(p, "%s: %s\n", #name, str_yes_no(info->name))
|
||||
DEV_INFO_DISPLAY_FOR_EACH_FLAG(PRINT_FLAG);
|
||||
#undef PRINT_FLAG
|
||||
|
||||
drm_printf(p, "has_hdcp: %s\n", str_yes_no(runtime->has_hdcp));
|
||||
drm_printf(p, "has_dmc: %s\n", str_yes_no(runtime->has_dmc));
|
||||
drm_printf(p, "has_dsc: %s\n", str_yes_no(runtime->has_dsc));
|
||||
}
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "intel_display_limits.h"
|
||||
|
||||
struct drm_i915_private;
|
||||
struct drm_printer;
|
||||
|
||||
#define DEV_INFO_DISPLAY_FOR_EACH_FLAG(func) \
|
||||
/* Keep in alphabetical order */ \
|
||||
@ -79,6 +80,7 @@ struct intel_display_runtime_info {
|
||||
|
||||
u8 pipe_mask;
|
||||
u8 cpu_transcoder_mask;
|
||||
u16 port_mask;
|
||||
|
||||
u8 num_sprites[I915_MAX_PIPES];
|
||||
u8 num_scalers[I915_MAX_PIPES];
|
||||
@ -126,4 +128,8 @@ intel_display_device_probe(struct drm_i915_private *i915, bool has_gmdid,
|
||||
u16 *ver, u16 *rel, u16 *step);
|
||||
void intel_display_device_info_runtime_init(struct drm_i915_private *i915);
|
||||
|
||||
void intel_display_device_info_print(const struct intel_display_device_info *info,
|
||||
const struct intel_display_runtime_info *runtime,
|
||||
struct drm_printer *p);
|
||||
|
||||
#endif
|
||||
|
@ -749,6 +749,20 @@ void ivb_display_irq_handler(struct drm_i915_private *dev_priv, u32 de_iir)
|
||||
if (de_iir & DE_ERR_INT_IVB)
|
||||
ivb_err_int_handler(dev_priv);
|
||||
|
||||
if (de_iir & DE_EDP_PSR_INT_HSW) {
|
||||
struct intel_encoder *encoder;
|
||||
|
||||
for_each_intel_encoder_with_psr(&dev_priv->drm, encoder) {
|
||||
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
|
||||
u32 psr_iir;
|
||||
|
||||
psr_iir = intel_uncore_rmw(&dev_priv->uncore,
|
||||
EDP_PSR_IIR, 0, 0);
|
||||
intel_psr_irq_handler(intel_dp, psr_iir);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (de_iir & DE_AUX_CHANNEL_A_IVB)
|
||||
intel_dp_aux_irq_handler(dev_priv);
|
||||
|
||||
@ -1135,7 +1149,7 @@ void gen8_de_irq_handler(struct drm_i915_private *dev_priv, u32 master_ctl)
|
||||
|
||||
u32 gen11_gu_misc_irq_ack(struct drm_i915_private *i915, const u32 master_ctl)
|
||||
{
|
||||
void __iomem * const regs = i915->uncore.regs;
|
||||
void __iomem * const regs = intel_uncore_regs(&i915->uncore);
|
||||
u32 iir;
|
||||
|
||||
if (!(master_ctl & GEN11_GU_MISC_IRQ))
|
||||
@ -1156,7 +1170,7 @@ void gen11_gu_misc_irq_handler(struct drm_i915_private *i915, const u32 iir)
|
||||
|
||||
void gen11_display_irq_handler(struct drm_i915_private *i915)
|
||||
{
|
||||
void __iomem * const regs = i915->uncore.regs;
|
||||
void __iomem * const regs = intel_uncore_regs(&i915->uncore);
|
||||
const u32 disp_ctl = raw_reg_read(regs, GEN11_DISPLAY_INT_CTL);
|
||||
|
||||
disable_rpm_wakeref_asserts(&i915->runtime_pm);
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "i915_reg.h"
|
||||
#include "intel_backlight_regs.h"
|
||||
#include "intel_cdclk.h"
|
||||
#include "intel_clock_gating.h"
|
||||
#include "intel_combo_phy.h"
|
||||
#include "intel_de.h"
|
||||
#include "intel_display_power.h"
|
||||
@ -457,6 +458,17 @@ async_put_domains_clear_domain(struct i915_power_domains *power_domains,
|
||||
clear_bit(domain, power_domains->async_put_domains[1].bits);
|
||||
}
|
||||
|
||||
static void
|
||||
cancel_async_put_work(struct i915_power_domains *power_domains, bool sync)
|
||||
{
|
||||
if (sync)
|
||||
cancel_delayed_work_sync(&power_domains->async_put_work);
|
||||
else
|
||||
cancel_delayed_work(&power_domains->async_put_work);
|
||||
|
||||
power_domains->async_put_next_delay = 0;
|
||||
}
|
||||
|
||||
static bool
|
||||
intel_display_power_grab_async_put_ref(struct drm_i915_private *dev_priv,
|
||||
enum intel_display_power_domain domain)
|
||||
@ -477,7 +489,7 @@ intel_display_power_grab_async_put_ref(struct drm_i915_private *dev_priv,
|
||||
if (!bitmap_empty(async_put_mask.bits, POWER_DOMAIN_NUM))
|
||||
goto out_verify;
|
||||
|
||||
cancel_delayed_work(&power_domains->async_put_work);
|
||||
cancel_async_put_work(power_domains, false);
|
||||
intel_runtime_pm_put_raw(&dev_priv->runtime_pm,
|
||||
fetch_and_zero(&power_domains->async_put_wakeref));
|
||||
out_verify:
|
||||
@ -608,7 +620,8 @@ static void __intel_display_power_put(struct drm_i915_private *dev_priv,
|
||||
|
||||
static void
|
||||
queue_async_put_domains_work(struct i915_power_domains *power_domains,
|
||||
intel_wakeref_t wakeref)
|
||||
intel_wakeref_t wakeref,
|
||||
int delay_ms)
|
||||
{
|
||||
struct drm_i915_private *i915 = container_of(power_domains,
|
||||
struct drm_i915_private,
|
||||
@ -617,7 +630,7 @@ queue_async_put_domains_work(struct i915_power_domains *power_domains,
|
||||
power_domains->async_put_wakeref = wakeref;
|
||||
drm_WARN_ON(&i915->drm, !queue_delayed_work(system_unbound_wq,
|
||||
&power_domains->async_put_work,
|
||||
msecs_to_jiffies(100)));
|
||||
msecs_to_jiffies(delay_ms)));
|
||||
}
|
||||
|
||||
static void
|
||||
@ -680,13 +693,15 @@ intel_display_power_put_async_work(struct work_struct *work)
|
||||
bitmap_zero(power_domains->async_put_domains[1].bits,
|
||||
POWER_DOMAIN_NUM);
|
||||
queue_async_put_domains_work(power_domains,
|
||||
fetch_and_zero(&new_work_wakeref));
|
||||
fetch_and_zero(&new_work_wakeref),
|
||||
power_domains->async_put_next_delay);
|
||||
power_domains->async_put_next_delay = 0;
|
||||
} else {
|
||||
/*
|
||||
* Cancel the work that got queued after this one got dequeued,
|
||||
* since here we released the corresponding async-put reference.
|
||||
*/
|
||||
cancel_delayed_work(&power_domains->async_put_work);
|
||||
cancel_async_put_work(power_domains, false);
|
||||
}
|
||||
|
||||
out_verify:
|
||||
@ -705,19 +720,25 @@ out_verify:
|
||||
* @i915: i915 device instance
|
||||
* @domain: power domain to reference
|
||||
* @wakeref: wakeref acquired for the reference that is being released
|
||||
* @delay_ms: delay of powering down the power domain
|
||||
*
|
||||
* This function drops the power domain reference obtained by
|
||||
* intel_display_power_get*() and schedules a work to power down the
|
||||
* corresponding hardware block if this is the last reference.
|
||||
* The power down is delayed by @delay_ms if this is >= 0, or by a default
|
||||
* 100 ms otherwise.
|
||||
*/
|
||||
void __intel_display_power_put_async(struct drm_i915_private *i915,
|
||||
enum intel_display_power_domain domain,
|
||||
intel_wakeref_t wakeref)
|
||||
intel_wakeref_t wakeref,
|
||||
int delay_ms)
|
||||
{
|
||||
struct i915_power_domains *power_domains = &i915->display.power.domains;
|
||||
struct intel_runtime_pm *rpm = &i915->runtime_pm;
|
||||
intel_wakeref_t work_wakeref = intel_runtime_pm_get_raw(rpm);
|
||||
|
||||
delay_ms = delay_ms >= 0 ? delay_ms : 100;
|
||||
|
||||
mutex_lock(&power_domains->lock);
|
||||
|
||||
if (power_domains->domain_use_count[domain] > 1) {
|
||||
@ -731,10 +752,13 @@ void __intel_display_power_put_async(struct drm_i915_private *i915,
|
||||
/* Let a pending work requeue itself or queue a new one. */
|
||||
if (power_domains->async_put_wakeref) {
|
||||
set_bit(domain, power_domains->async_put_domains[1].bits);
|
||||
power_domains->async_put_next_delay = max(power_domains->async_put_next_delay,
|
||||
delay_ms);
|
||||
} else {
|
||||
set_bit(domain, power_domains->async_put_domains[0].bits);
|
||||
queue_async_put_domains_work(power_domains,
|
||||
fetch_and_zero(&work_wakeref));
|
||||
fetch_and_zero(&work_wakeref),
|
||||
delay_ms);
|
||||
}
|
||||
|
||||
out_verify:
|
||||
@ -774,7 +798,7 @@ void intel_display_power_flush_work(struct drm_i915_private *i915)
|
||||
|
||||
async_put_domains_mask(power_domains, &async_put_mask);
|
||||
release_async_put_domains(power_domains, &async_put_mask);
|
||||
cancel_delayed_work(&power_domains->async_put_work);
|
||||
cancel_async_put_work(power_domains, false);
|
||||
|
||||
out_verify:
|
||||
verify_async_put_domains_state(power_domains);
|
||||
@ -798,7 +822,7 @@ intel_display_power_flush_work_sync(struct drm_i915_private *i915)
|
||||
struct i915_power_domains *power_domains = &i915->display.power.domains;
|
||||
|
||||
intel_display_power_flush_work(i915);
|
||||
cancel_delayed_work_sync(&power_domains->async_put_work);
|
||||
cancel_async_put_work(power_domains, true);
|
||||
|
||||
verify_async_put_domains_state(power_domains);
|
||||
|
||||
@ -1385,9 +1409,8 @@ static void hsw_disable_pc8(struct drm_i915_private *dev_priv)
|
||||
hsw_restore_lcpll(dev_priv);
|
||||
intel_init_pch_refclk(dev_priv);
|
||||
|
||||
if (HAS_PCH_LPT_LP(dev_priv))
|
||||
intel_de_rmw(dev_priv, SOUTH_DSPCLK_GATE_D,
|
||||
0, PCH_LP_PARTITION_LEVEL_DISABLE);
|
||||
/* Many display registers don't survive PC8+ */
|
||||
intel_clock_gating_init(dev_priv);
|
||||
}
|
||||
|
||||
static void intel_pch_reset_handshake(struct drm_i915_private *dev_priv,
|
||||
|
@ -12,9 +12,6 @@
|
||||
#include "intel_wakeref.h"
|
||||
|
||||
enum aux_ch;
|
||||
enum dpio_channel;
|
||||
enum dpio_phy;
|
||||
enum i915_drm_suspend_mode;
|
||||
enum port;
|
||||
struct drm_i915_private;
|
||||
struct i915_power_well;
|
||||
@ -154,6 +151,7 @@ struct i915_power_domains {
|
||||
struct delayed_work async_put_work;
|
||||
intel_wakeref_t async_put_wakeref;
|
||||
struct intel_power_domain_mask async_put_domains[2];
|
||||
int async_put_next_delay;
|
||||
|
||||
struct i915_power_well *power_wells;
|
||||
};
|
||||
@ -200,7 +198,8 @@ intel_display_power_get_if_enabled(struct drm_i915_private *dev_priv,
|
||||
enum intel_display_power_domain domain);
|
||||
void __intel_display_power_put_async(struct drm_i915_private *i915,
|
||||
enum intel_display_power_domain domain,
|
||||
intel_wakeref_t wakeref);
|
||||
intel_wakeref_t wakeref,
|
||||
int delay_ms);
|
||||
void intel_display_power_flush_work(struct drm_i915_private *i915);
|
||||
#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM)
|
||||
void intel_display_power_put(struct drm_i915_private *dev_priv,
|
||||
@ -211,7 +210,16 @@ intel_display_power_put_async(struct drm_i915_private *i915,
|
||||
enum intel_display_power_domain domain,
|
||||
intel_wakeref_t wakeref)
|
||||
{
|
||||
__intel_display_power_put_async(i915, domain, wakeref);
|
||||
__intel_display_power_put_async(i915, domain, wakeref, -1);
|
||||
}
|
||||
|
||||
static inline void
|
||||
intel_display_power_put_async_delay(struct drm_i915_private *i915,
|
||||
enum intel_display_power_domain domain,
|
||||
intel_wakeref_t wakeref,
|
||||
int delay_ms)
|
||||
{
|
||||
__intel_display_power_put_async(i915, domain, wakeref, delay_ms);
|
||||
}
|
||||
#else
|
||||
void intel_display_power_put_unchecked(struct drm_i915_private *dev_priv,
|
||||
@ -230,7 +238,16 @@ intel_display_power_put_async(struct drm_i915_private *i915,
|
||||
enum intel_display_power_domain domain,
|
||||
intel_wakeref_t wakeref)
|
||||
{
|
||||
__intel_display_power_put_async(i915, domain, -1);
|
||||
__intel_display_power_put_async(i915, domain, -1, -1);
|
||||
}
|
||||
|
||||
static inline void
|
||||
intel_display_power_put_async_delay(struct drm_i915_private *i915,
|
||||
enum intel_display_power_domain domain,
|
||||
intel_wakeref_t wakeref,
|
||||
int delay_ms)
|
||||
{
|
||||
__intel_display_power_put_async(i915, domain, -1, delay_ms);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -11,7 +11,6 @@
|
||||
#include "intel_dpio_phy.h"
|
||||
|
||||
struct drm_i915_private;
|
||||
struct i915_power_well;
|
||||
struct i915_power_well_ops;
|
||||
struct intel_encoder;
|
||||
|
||||
|
@ -713,9 +713,18 @@ u32 intel_dp_dsc_nearest_valid_bpp(struct drm_i915_private *i915, u32 bpp, u32 p
|
||||
|
||||
/*
|
||||
* According to BSpec, 27 is the max DSC output bpp,
|
||||
* 8 is the min DSC output bpp
|
||||
* 8 is the min DSC output bpp.
|
||||
* While we can still clamp higher bpp values to 27, saving bandwidth,
|
||||
* if it is required to oompress up to bpp < 8, means we can't do
|
||||
* that and probably means we can't fit the required mode, even with
|
||||
* DSC enabled.
|
||||
*/
|
||||
bits_per_pixel = clamp_t(u32, bits_per_pixel, 8, 27);
|
||||
if (bits_per_pixel < 8) {
|
||||
drm_dbg_kms(&i915->drm, "Unsupported BPP %u, min 8\n",
|
||||
bits_per_pixel);
|
||||
return 0;
|
||||
}
|
||||
bits_per_pixel = min_t(u32, bits_per_pixel, 27);
|
||||
} else {
|
||||
/* Find the nearest match in the array of known BPPs from VESA */
|
||||
for (i = 0; i < ARRAY_SIZE(valid_dsc_bpp) - 1; i++) {
|
||||
|
@ -14,7 +14,7 @@
|
||||
#include "intel_pps.h"
|
||||
#include "intel_tc.h"
|
||||
|
||||
static u32 intel_dp_aux_pack(const u8 *src, int src_bytes)
|
||||
u32 intel_dp_aux_pack(const u8 *src, int src_bytes)
|
||||
{
|
||||
int i;
|
||||
u32 v = 0;
|
||||
@ -792,25 +792,60 @@ static enum aux_ch default_aux_ch(struct intel_encoder *encoder)
|
||||
return (enum aux_ch)encoder->port;
|
||||
}
|
||||
|
||||
static struct intel_encoder *
|
||||
get_encoder_by_aux_ch(struct intel_encoder *encoder,
|
||||
enum aux_ch aux_ch)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
|
||||
struct intel_encoder *other;
|
||||
|
||||
for_each_intel_encoder(&i915->drm, other) {
|
||||
if (other == encoder)
|
||||
continue;
|
||||
|
||||
if (!intel_encoder_is_dig_port(other))
|
||||
continue;
|
||||
|
||||
if (enc_to_dig_port(other)->aux_ch == aux_ch)
|
||||
return other;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
enum aux_ch intel_dp_aux_ch(struct intel_encoder *encoder)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
|
||||
struct intel_encoder *other;
|
||||
const char *source;
|
||||
enum aux_ch aux_ch;
|
||||
|
||||
aux_ch = intel_bios_dp_aux_ch(encoder->devdata);
|
||||
if (aux_ch != AUX_CH_NONE) {
|
||||
drm_dbg_kms(&i915->drm, "[ENCODER:%d:%s] using AUX %c (VBT)\n",
|
||||
encoder->base.base.id, encoder->base.name,
|
||||
aux_ch_name(aux_ch));
|
||||
return aux_ch;
|
||||
source = "VBT";
|
||||
|
||||
if (aux_ch == AUX_CH_NONE) {
|
||||
aux_ch = default_aux_ch(encoder);
|
||||
source = "platform default";
|
||||
}
|
||||
|
||||
aux_ch = default_aux_ch(encoder);
|
||||
if (aux_ch == AUX_CH_NONE)
|
||||
return AUX_CH_NONE;
|
||||
|
||||
/* FIXME validate aux_ch against platform caps */
|
||||
|
||||
other = get_encoder_by_aux_ch(encoder, aux_ch);
|
||||
if (other) {
|
||||
drm_dbg_kms(&i915->drm,
|
||||
"[ENCODER:%d:%s] AUX CH %c already claimed by [ENCODER:%d:%s]\n",
|
||||
encoder->base.base.id, encoder->base.name, aux_ch_name(aux_ch),
|
||||
other->base.base.id, other->base.name);
|
||||
return AUX_CH_NONE;
|
||||
}
|
||||
|
||||
drm_dbg_kms(&i915->drm,
|
||||
"[ENCODER:%d:%s] using AUX %c (platform default)\n",
|
||||
"[ENCODER:%d:%s] Using AUX CH %c (%s)\n",
|
||||
encoder->base.base.id, encoder->base.name,
|
||||
aux_ch_name(aux_ch));
|
||||
aux_ch_name(aux_ch), source);
|
||||
|
||||
return aux_ch;
|
||||
}
|
||||
|
@ -6,6 +6,8 @@
|
||||
#ifndef __INTEL_DP_AUX_H__
|
||||
#define __INTEL_DP_AUX_H__
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
enum aux_ch;
|
||||
struct drm_i915_private;
|
||||
struct intel_dp;
|
||||
@ -17,5 +19,6 @@ void intel_dp_aux_init(struct intel_dp *intel_dp);
|
||||
enum aux_ch intel_dp_aux_ch(struct intel_encoder *encoder);
|
||||
|
||||
void intel_dp_aux_irq_handler(struct drm_i915_private *i915);
|
||||
u32 intel_dp_aux_pack(const u8 *src, int src_bytes);
|
||||
|
||||
#endif /* __INTEL_DP_AUX_H__ */
|
||||
|
@ -166,6 +166,8 @@ struct i915_vma *intel_dpt_pin(struct i915_address_space *vm)
|
||||
i915_vma_get(vma);
|
||||
}
|
||||
|
||||
dpt->obj->mm.dirty = true;
|
||||
|
||||
atomic_dec(&i915->gpu_error.pending_fb_pin);
|
||||
intel_runtime_pm_put(&i915->runtime_pm, wakeref);
|
||||
|
||||
@ -261,7 +263,7 @@ intel_dpt_create(struct intel_framebuffer *fb)
|
||||
dpt_obj = i915_gem_object_create_stolen(i915, size);
|
||||
if (IS_ERR(dpt_obj) && !HAS_LMEM(i915)) {
|
||||
drm_dbg_kms(&i915->drm, "Allocating dpt from smem\n");
|
||||
dpt_obj = i915_gem_object_create_internal(i915, size);
|
||||
dpt_obj = i915_gem_object_create_shmem(i915, size);
|
||||
}
|
||||
if (IS_ERR(dpt_obj))
|
||||
return ERR_CAST(dpt_obj);
|
||||
|
@ -9,6 +9,26 @@
|
||||
#include "intel_dsi.h"
|
||||
#include "intel_panel.h"
|
||||
|
||||
void intel_dsi_wait_panel_power_cycle(struct intel_dsi *intel_dsi)
|
||||
{
|
||||
ktime_t panel_power_on_time;
|
||||
s64 panel_power_off_duration;
|
||||
|
||||
panel_power_on_time = ktime_get_boottime();
|
||||
panel_power_off_duration = ktime_ms_delta(panel_power_on_time,
|
||||
intel_dsi->panel_power_off_time);
|
||||
|
||||
if (panel_power_off_duration < (s64)intel_dsi->panel_pwr_cycle_delay)
|
||||
msleep(intel_dsi->panel_pwr_cycle_delay - panel_power_off_duration);
|
||||
}
|
||||
|
||||
void intel_dsi_shutdown(struct intel_encoder *encoder)
|
||||
{
|
||||
struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
|
||||
|
||||
intel_dsi_wait_panel_power_cycle(intel_dsi);
|
||||
}
|
||||
|
||||
int intel_dsi_bitrate(const struct intel_dsi *intel_dsi)
|
||||
{
|
||||
int bpp = mipi_dsi_pixel_format_to_bpp(intel_dsi->pixel_format);
|
||||
|
@ -173,5 +173,7 @@ enum drm_mode_status intel_dsi_mode_valid(struct drm_connector *connector,
|
||||
struct intel_dsi_host *intel_dsi_host_init(struct intel_dsi *intel_dsi,
|
||||
const struct mipi_dsi_host_ops *funcs,
|
||||
enum port port);
|
||||
void intel_dsi_wait_panel_power_cycle(struct intel_dsi *intel_dsi);
|
||||
void intel_dsi_shutdown(struct intel_encoder *encoder);
|
||||
|
||||
#endif /* _INTEL_DSI_H */
|
||||
|
@ -235,7 +235,7 @@ static const u8 *mipi_exec_delay(struct intel_dsi *intel_dsi, const u8 *data)
|
||||
struct drm_i915_private *i915 = to_i915(intel_dsi->base.base.dev);
|
||||
u32 delay = *((const u32 *) data);
|
||||
|
||||
drm_dbg_kms(&i915->drm, "\n");
|
||||
drm_dbg_kms(&i915->drm, "%d usecs\n", delay);
|
||||
|
||||
usleep_range(delay, delay + 10);
|
||||
data += 4;
|
||||
|
@ -509,6 +509,8 @@ void intel_dvo_init(struct drm_i915_private *i915)
|
||||
return;
|
||||
}
|
||||
|
||||
assert_port_valid(i915, intel_dvo->dev.port);
|
||||
|
||||
encoder->type = INTEL_OUTPUT_DVO;
|
||||
encoder->power_domain = POWER_DOMAIN_PORT_OTHER;
|
||||
encoder->port = intel_dvo->dev.port;
|
||||
|
@ -135,9 +135,6 @@ static int intel_fbdev_mmap(struct fb_info *info, struct vm_area_struct *vma)
|
||||
return i915_gem_fb_mmap(obj, vma);
|
||||
}
|
||||
|
||||
__diag_push();
|
||||
__diag_ignore_all("-Woverride-init", "Allow overriding the default ops");
|
||||
|
||||
static const struct fb_ops intelfb_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
__FB_DEFAULT_DEFERRED_OPS_RDWR(intel_fbdev),
|
||||
@ -149,8 +146,6 @@ static const struct fb_ops intelfb_ops = {
|
||||
.fb_mmap = intel_fbdev_mmap,
|
||||
};
|
||||
|
||||
__diag_pop();
|
||||
|
||||
static int intelfb_alloc(struct drm_fb_helper *helper,
|
||||
struct drm_fb_helper_surface_size *sizes)
|
||||
{
|
||||
@ -187,8 +182,10 @@ static int intelfb_alloc(struct drm_fb_helper *helper,
|
||||
* If the FB is too big, just don't use it since fbdev is not very
|
||||
* important and we should probably use that space with FBC or other
|
||||
* features.
|
||||
*
|
||||
* Also skip stolen on MTL as Wa_22018444074 mitigation.
|
||||
*/
|
||||
if (size * 2 < dev_priv->dsm.usable_size)
|
||||
if (!(IS_METEORLAKE(dev_priv)) && size * 2 < dev_priv->dsm.usable_size)
|
||||
obj = i915_gem_object_create_stolen(dev_priv, size);
|
||||
if (IS_ERR(obj))
|
||||
obj = i915_gem_object_create_shmem(dev_priv, size);
|
||||
|
@ -167,7 +167,7 @@ void __intel_fb_invalidate(struct intel_frontbuffer *front,
|
||||
enum fb_op_origin origin,
|
||||
unsigned int frontbuffer_bits)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(front->obj->base.dev);
|
||||
struct drm_i915_private *i915 = intel_bo_to_i915(front->obj);
|
||||
|
||||
if (origin == ORIGIN_CS) {
|
||||
spin_lock(&i915->display.fb_tracking.lock);
|
||||
@ -188,7 +188,7 @@ void __intel_fb_flush(struct intel_frontbuffer *front,
|
||||
enum fb_op_origin origin,
|
||||
unsigned int frontbuffer_bits)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(front->obj->base.dev);
|
||||
struct drm_i915_private *i915 = intel_bo_to_i915(front->obj);
|
||||
|
||||
if (origin == ORIGIN_CS) {
|
||||
spin_lock(&i915->display.fb_tracking.lock);
|
||||
@ -221,24 +221,18 @@ static void frontbuffer_retire(struct i915_active *ref)
|
||||
}
|
||||
|
||||
static void frontbuffer_release(struct kref *ref)
|
||||
__releases(&to_i915(front->obj->base.dev)->display.fb_tracking.lock)
|
||||
__releases(&intel_bo_to_i915(front->obj)->display.fb_tracking.lock)
|
||||
{
|
||||
struct intel_frontbuffer *front =
|
||||
container_of(ref, typeof(*front), ref);
|
||||
struct drm_i915_gem_object *obj = front->obj;
|
||||
struct i915_vma *vma;
|
||||
|
||||
drm_WARN_ON(obj->base.dev, atomic_read(&front->bits));
|
||||
drm_WARN_ON(&intel_bo_to_i915(obj)->drm, atomic_read(&front->bits));
|
||||
|
||||
spin_lock(&obj->vma.lock);
|
||||
for_each_ggtt_vma(vma, obj) {
|
||||
i915_vma_clear_scanout(vma);
|
||||
vma->display_alignment = I915_GTT_MIN_ALIGNMENT;
|
||||
}
|
||||
spin_unlock(&obj->vma.lock);
|
||||
i915_ggtt_clear_scanout(obj);
|
||||
|
||||
RCU_INIT_POINTER(obj->frontbuffer, NULL);
|
||||
spin_unlock(&to_i915(obj->base.dev)->display.fb_tracking.lock);
|
||||
i915_gem_object_set_frontbuffer(obj, NULL);
|
||||
spin_unlock(&intel_bo_to_i915(obj)->display.fb_tracking.lock);
|
||||
|
||||
i915_active_fini(&front->write);
|
||||
|
||||
@ -249,10 +243,10 @@ static void frontbuffer_release(struct kref *ref)
|
||||
struct intel_frontbuffer *
|
||||
intel_frontbuffer_get(struct drm_i915_gem_object *obj)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(obj->base.dev);
|
||||
struct intel_frontbuffer *front;
|
||||
struct drm_i915_private *i915 = intel_bo_to_i915(obj);
|
||||
struct intel_frontbuffer *front, *cur;
|
||||
|
||||
front = __intel_frontbuffer_get(obj);
|
||||
front = i915_gem_object_get_frontbuffer(obj);
|
||||
if (front)
|
||||
return front;
|
||||
|
||||
@ -269,24 +263,18 @@ intel_frontbuffer_get(struct drm_i915_gem_object *obj)
|
||||
I915_ACTIVE_RETIRE_SLEEPS);
|
||||
|
||||
spin_lock(&i915->display.fb_tracking.lock);
|
||||
if (rcu_access_pointer(obj->frontbuffer)) {
|
||||
kfree(front);
|
||||
front = rcu_dereference_protected(obj->frontbuffer, true);
|
||||
kref_get(&front->ref);
|
||||
} else {
|
||||
i915_gem_object_get(obj);
|
||||
rcu_assign_pointer(obj->frontbuffer, front);
|
||||
}
|
||||
cur = i915_gem_object_set_frontbuffer(obj, front);
|
||||
spin_unlock(&i915->display.fb_tracking.lock);
|
||||
|
||||
return front;
|
||||
if (cur != front)
|
||||
kfree(front);
|
||||
return cur;
|
||||
}
|
||||
|
||||
void intel_frontbuffer_put(struct intel_frontbuffer *front)
|
||||
{
|
||||
kref_put_lock(&front->ref,
|
||||
frontbuffer_release,
|
||||
&to_i915(front->obj->base.dev)->display.fb_tracking.lock);
|
||||
&intel_bo_to_i915(front->obj)->display.fb_tracking.lock);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -315,13 +303,13 @@ void intel_frontbuffer_track(struct intel_frontbuffer *old,
|
||||
BUILD_BUG_ON(I915_MAX_PLANES > INTEL_FRONTBUFFER_BITS_PER_PIPE);
|
||||
|
||||
if (old) {
|
||||
drm_WARN_ON(old->obj->base.dev,
|
||||
drm_WARN_ON(&intel_bo_to_i915(old->obj)->drm,
|
||||
!(atomic_read(&old->bits) & frontbuffer_bits));
|
||||
atomic_andnot(frontbuffer_bits, &old->bits);
|
||||
}
|
||||
|
||||
if (new) {
|
||||
drm_WARN_ON(new->obj->base.dev,
|
||||
drm_WARN_ON(&intel_bo_to_i915(new->obj)->drm,
|
||||
atomic_read(&new->bits) & frontbuffer_bits);
|
||||
atomic_or(frontbuffer_bits, &new->bits);
|
||||
}
|
||||
|
@ -28,7 +28,6 @@
|
||||
#include <linux/bits.h>
|
||||
#include <linux/kref.h>
|
||||
|
||||
#include "gem/i915_gem_object_types.h"
|
||||
#include "i915_active_types.h"
|
||||
|
||||
struct drm_i915_private;
|
||||
@ -75,33 +74,6 @@ void intel_frontbuffer_flip(struct drm_i915_private *i915,
|
||||
|
||||
void intel_frontbuffer_put(struct intel_frontbuffer *front);
|
||||
|
||||
static inline struct intel_frontbuffer *
|
||||
__intel_frontbuffer_get(const struct drm_i915_gem_object *obj)
|
||||
{
|
||||
struct intel_frontbuffer *front;
|
||||
|
||||
if (likely(!rcu_access_pointer(obj->frontbuffer)))
|
||||
return NULL;
|
||||
|
||||
rcu_read_lock();
|
||||
do {
|
||||
front = rcu_dereference(obj->frontbuffer);
|
||||
if (!front)
|
||||
break;
|
||||
|
||||
if (unlikely(!kref_get_unless_zero(&front->ref)))
|
||||
continue;
|
||||
|
||||
if (likely(front == rcu_access_pointer(obj->frontbuffer)))
|
||||
break;
|
||||
|
||||
intel_frontbuffer_put(front);
|
||||
} while (1);
|
||||
rcu_read_unlock();
|
||||
|
||||
return front;
|
||||
}
|
||||
|
||||
struct intel_frontbuffer *
|
||||
intel_frontbuffer_get(struct drm_i915_gem_object *obj);
|
||||
|
||||
|
@ -177,8 +177,11 @@ bool intel_hdcp2_capable(struct intel_connector *connector)
|
||||
struct intel_gt *gt = i915->media_gt;
|
||||
struct intel_gsc_uc *gsc = gt ? >->uc.gsc : NULL;
|
||||
|
||||
if (!gsc || !intel_uc_fw_is_running(&gsc->fw))
|
||||
if (!gsc || !intel_uc_fw_is_running(&gsc->fw)) {
|
||||
drm_dbg_kms(&i915->drm,
|
||||
"GSC components required for HDCP2.2 are not ready\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* MEI/GSC interface is solid depending on which is used */
|
||||
|
@ -621,24 +621,26 @@ static int intel_hdcp_gsc_initialize_message(struct drm_i915_private *i915,
|
||||
struct intel_gt *gt = i915->media_gt;
|
||||
struct drm_i915_gem_object *obj = NULL;
|
||||
struct i915_vma *vma = NULL;
|
||||
void *cmd;
|
||||
void *cmd_in, *cmd_out;
|
||||
int err;
|
||||
|
||||
/* allocate object of one page for HDCP command memory and store it */
|
||||
obj = i915_gem_object_create_shmem(i915, PAGE_SIZE);
|
||||
/* allocate object of two page for HDCP command memory and store it */
|
||||
obj = i915_gem_object_create_shmem(i915, 2 * PAGE_SIZE);
|
||||
|
||||
if (IS_ERR(obj)) {
|
||||
drm_err(&i915->drm, "Failed to allocate HDCP streaming command!\n");
|
||||
return PTR_ERR(obj);
|
||||
}
|
||||
|
||||
cmd = i915_gem_object_pin_map_unlocked(obj, i915_coherent_map_type(i915, obj, true));
|
||||
if (IS_ERR(cmd)) {
|
||||
cmd_in = i915_gem_object_pin_map_unlocked(obj, i915_coherent_map_type(i915, obj, true));
|
||||
if (IS_ERR(cmd_in)) {
|
||||
drm_err(&i915->drm, "Failed to map gsc message page!\n");
|
||||
err = PTR_ERR(cmd);
|
||||
err = PTR_ERR(cmd_in);
|
||||
goto out_unpin;
|
||||
}
|
||||
|
||||
cmd_out = cmd_in + PAGE_SIZE;
|
||||
|
||||
vma = i915_vma_instance(obj, >->ggtt->vm, NULL);
|
||||
if (IS_ERR(vma)) {
|
||||
err = PTR_ERR(vma);
|
||||
@ -649,9 +651,10 @@ static int intel_hdcp_gsc_initialize_message(struct drm_i915_private *i915,
|
||||
if (err)
|
||||
goto out_unmap;
|
||||
|
||||
memset(cmd, 0, obj->base.size);
|
||||
memset(cmd_in, 0, obj->base.size);
|
||||
|
||||
hdcp_message->hdcp_cmd = cmd;
|
||||
hdcp_message->hdcp_cmd_in = cmd_in;
|
||||
hdcp_message->hdcp_cmd_out = cmd_out;
|
||||
hdcp_message->vma = vma;
|
||||
|
||||
return 0;
|
||||
@ -691,6 +694,8 @@ static void intel_hdcp_gsc_free_message(struct drm_i915_private *i915)
|
||||
struct intel_hdcp_gsc_message *hdcp_message =
|
||||
i915->display.hdcp.hdcp_message;
|
||||
|
||||
hdcp_message->hdcp_cmd_in = NULL;
|
||||
hdcp_message->hdcp_cmd_out = NULL;
|
||||
i915_vma_unpin_and_release(&hdcp_message->vma, I915_VMA_RELEASE_MAP);
|
||||
kfree(hdcp_message);
|
||||
}
|
||||
@ -721,38 +726,42 @@ void intel_hdcp_gsc_fini(struct drm_i915_private *i915)
|
||||
}
|
||||
|
||||
static int intel_gsc_send_sync(struct drm_i915_private *i915,
|
||||
struct intel_gsc_mtl_header *header, u64 addr,
|
||||
struct intel_gsc_mtl_header *header_in,
|
||||
struct intel_gsc_mtl_header *header_out,
|
||||
u64 addr_in, u64 addr_out,
|
||||
size_t msg_out_len)
|
||||
{
|
||||
struct intel_gt *gt = i915->media_gt;
|
||||
int ret;
|
||||
|
||||
header->flags = 0;
|
||||
ret = intel_gsc_uc_heci_cmd_submit_packet(>->uc.gsc, addr,
|
||||
header->message_size,
|
||||
addr,
|
||||
msg_out_len + sizeof(*header));
|
||||
ret = intel_gsc_uc_heci_cmd_submit_packet(>->uc.gsc, addr_in,
|
||||
header_in->message_size,
|
||||
addr_out,
|
||||
msg_out_len + sizeof(*header_out));
|
||||
if (ret) {
|
||||
drm_err(&i915->drm, "failed to send gsc HDCP msg (%d)\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Checking validity marker for memory sanity
|
||||
* Checking validity marker and header status to see if some error has
|
||||
* blocked us from sending message to gsc cs
|
||||
*/
|
||||
if (header->validity_marker != GSC_HECI_VALIDITY_MARKER) {
|
||||
if (header_out->validity_marker != GSC_HECI_VALIDITY_MARKER) {
|
||||
drm_err(&i915->drm, "invalid validity marker\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (header->status != 0) {
|
||||
if (header_out->status != 0) {
|
||||
drm_err(&i915->drm, "header status indicates error %d\n",
|
||||
header->status);
|
||||
header_out->status);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (header->flags & GSC_OUTFLAG_MSG_PENDING)
|
||||
if (header_out->flags & GSC_OUTFLAG_MSG_PENDING) {
|
||||
header_in->gsc_message_handle = header_out->gsc_message_handle;
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -769,11 +778,11 @@ ssize_t intel_hdcp_gsc_msg_send(struct drm_i915_private *i915, u8 *msg_in,
|
||||
size_t msg_out_len)
|
||||
{
|
||||
struct intel_gt *gt = i915->media_gt;
|
||||
struct intel_gsc_mtl_header *header;
|
||||
const size_t max_msg_size = PAGE_SIZE - sizeof(*header);
|
||||
struct intel_gsc_mtl_header *header_in, *header_out;
|
||||
const size_t max_msg_size = PAGE_SIZE - sizeof(*header_in);
|
||||
struct intel_hdcp_gsc_message *hdcp_message;
|
||||
u64 addr, host_session_id;
|
||||
u32 reply_size, msg_size;
|
||||
u64 addr_in, addr_out, host_session_id;
|
||||
u32 reply_size, msg_size_in, msg_size_out;
|
||||
int ret, tries = 0;
|
||||
|
||||
if (!intel_uc_uses_gsc_uc(>->uc))
|
||||
@ -782,16 +791,20 @@ ssize_t intel_hdcp_gsc_msg_send(struct drm_i915_private *i915, u8 *msg_in,
|
||||
if (msg_in_len > max_msg_size || msg_out_len > max_msg_size)
|
||||
return -ENOSPC;
|
||||
|
||||
msg_size_in = msg_in_len + sizeof(*header_in);
|
||||
msg_size_out = msg_out_len + sizeof(*header_out);
|
||||
hdcp_message = i915->display.hdcp.hdcp_message;
|
||||
header = hdcp_message->hdcp_cmd;
|
||||
addr = i915_ggtt_offset(hdcp_message->vma);
|
||||
header_in = hdcp_message->hdcp_cmd_in;
|
||||
header_out = hdcp_message->hdcp_cmd_out;
|
||||
addr_in = i915_ggtt_offset(hdcp_message->vma);
|
||||
addr_out = addr_in + PAGE_SIZE;
|
||||
|
||||
msg_size = msg_in_len + sizeof(*header);
|
||||
memset(header, 0, msg_size);
|
||||
memset(header_in, 0, msg_size_in);
|
||||
memset(header_out, 0, msg_size_out);
|
||||
get_random_bytes(&host_session_id, sizeof(u64));
|
||||
intel_gsc_uc_heci_cmd_emit_mtl_header(header, HECI_MEADDRESS_HDCP,
|
||||
msg_size, host_session_id);
|
||||
memcpy(hdcp_message->hdcp_cmd + sizeof(*header), msg_in, msg_in_len);
|
||||
intel_gsc_uc_heci_cmd_emit_mtl_header(header_in, HECI_MEADDRESS_HDCP,
|
||||
msg_size_in, host_session_id);
|
||||
memcpy(hdcp_message->hdcp_cmd_in + sizeof(*header_in), msg_in, msg_in_len);
|
||||
|
||||
/*
|
||||
* Keep sending request in case the pending bit is set no need to add
|
||||
@ -800,7 +813,8 @@ ssize_t intel_hdcp_gsc_msg_send(struct drm_i915_private *i915, u8 *msg_in,
|
||||
* 20 times each message 50 ms apart
|
||||
*/
|
||||
do {
|
||||
ret = intel_gsc_send_sync(i915, header, addr, msg_out_len);
|
||||
ret = intel_gsc_send_sync(i915, header_in, header_out, addr_in,
|
||||
addr_out, msg_out_len);
|
||||
|
||||
/* Only try again if gsc says so */
|
||||
if (ret != -EAGAIN)
|
||||
@ -814,7 +828,7 @@ ssize_t intel_hdcp_gsc_msg_send(struct drm_i915_private *i915, u8 *msg_in,
|
||||
goto err;
|
||||
|
||||
/* we use the same mem for the reply, so header is in the same loc */
|
||||
reply_size = header->message_size - sizeof(*header);
|
||||
reply_size = header_out->message_size - sizeof(*header_out);
|
||||
if (reply_size > msg_out_len) {
|
||||
drm_warn(&i915->drm, "caller with insufficient HDCP reply size %u (%d)\n",
|
||||
reply_size, (u32)msg_out_len);
|
||||
@ -824,7 +838,7 @@ ssize_t intel_hdcp_gsc_msg_send(struct drm_i915_private *i915, u8 *msg_in,
|
||||
reply_size, (u32)msg_out_len);
|
||||
}
|
||||
|
||||
memcpy(msg_out, hdcp_message->hdcp_cmd + sizeof(*header), msg_out_len);
|
||||
memcpy(msg_out, hdcp_message->hdcp_cmd_out + sizeof(*header_out), msg_out_len);
|
||||
|
||||
err:
|
||||
return ret;
|
||||
|
@ -13,7 +13,8 @@ struct drm_i915_private;
|
||||
|
||||
struct intel_hdcp_gsc_message {
|
||||
struct i915_vma *vma;
|
||||
void *hdcp_cmd;
|
||||
void *hdcp_cmd_in;
|
||||
void *hdcp_cmd_out;
|
||||
};
|
||||
|
||||
bool intel_hdcp_gsc_cs_required(struct drm_i915_private *i915);
|
||||
|
@ -2880,21 +2880,12 @@ static u8 g4x_port_to_ddc_pin(struct drm_i915_private *dev_priv,
|
||||
return ddc_pin;
|
||||
}
|
||||
|
||||
static u8 intel_hdmi_ddc_pin(struct intel_encoder *encoder)
|
||||
static u8 intel_hdmi_default_ddc_pin(struct intel_encoder *encoder)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
|
||||
enum port port = encoder->port;
|
||||
u8 ddc_pin;
|
||||
|
||||
ddc_pin = intel_bios_hdmi_ddc_pin(encoder->devdata);
|
||||
if (ddc_pin) {
|
||||
drm_dbg_kms(&dev_priv->drm,
|
||||
"[ENCODER:%d:%s] Using DDC pin 0x%x (VBT)\n",
|
||||
encoder->base.base.id, encoder->base.name,
|
||||
ddc_pin);
|
||||
return ddc_pin;
|
||||
}
|
||||
|
||||
if (IS_ALDERLAKE_S(dev_priv))
|
||||
ddc_pin = adls_port_to_ddc_pin(dev_priv, port);
|
||||
else if (INTEL_PCH_TYPE(dev_priv) >= PCH_DG1)
|
||||
@ -2916,10 +2907,62 @@ static u8 intel_hdmi_ddc_pin(struct intel_encoder *encoder)
|
||||
else
|
||||
ddc_pin = g4x_port_to_ddc_pin(dev_priv, port);
|
||||
|
||||
drm_dbg_kms(&dev_priv->drm,
|
||||
"[ENCODER:%d:%s] Using DDC pin 0x%x (platform default)\n",
|
||||
return ddc_pin;
|
||||
}
|
||||
|
||||
static struct intel_encoder *
|
||||
get_encoder_by_ddc_pin(struct intel_encoder *encoder, u8 ddc_pin)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
|
||||
struct intel_encoder *other;
|
||||
|
||||
for_each_intel_encoder(&i915->drm, other) {
|
||||
if (other == encoder)
|
||||
continue;
|
||||
|
||||
if (!intel_encoder_is_dig_port(other))
|
||||
continue;
|
||||
|
||||
if (enc_to_dig_port(other)->hdmi.ddc_bus == ddc_pin)
|
||||
return other;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static u8 intel_hdmi_ddc_pin(struct intel_encoder *encoder)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
|
||||
struct intel_encoder *other;
|
||||
const char *source;
|
||||
u8 ddc_pin;
|
||||
|
||||
ddc_pin = intel_bios_hdmi_ddc_pin(encoder->devdata);
|
||||
source = "VBT";
|
||||
|
||||
if (!ddc_pin) {
|
||||
ddc_pin = intel_hdmi_default_ddc_pin(encoder);
|
||||
source = "platform default";
|
||||
}
|
||||
|
||||
if (!intel_gmbus_is_valid_pin(i915, ddc_pin)) {
|
||||
drm_dbg_kms(&i915->drm, "[ENCODER:%d:%s] Invalid DDC pin %d\n",
|
||||
encoder->base.base.id, encoder->base.name, ddc_pin);
|
||||
return 0;
|
||||
}
|
||||
|
||||
other = get_encoder_by_ddc_pin(encoder, ddc_pin);
|
||||
if (other) {
|
||||
drm_dbg_kms(&i915->drm, "[ENCODER:%d:%s] DDC pin %d already claimed by [ENCODER:%d:%s]\n",
|
||||
encoder->base.base.id, encoder->base.name, ddc_pin,
|
||||
other->base.base.id, other->base.name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
drm_dbg_kms(&i915->drm,
|
||||
"[ENCODER:%d:%s] Using DDC pin 0x%x (%s)\n",
|
||||
encoder->base.base.id, encoder->base.name,
|
||||
ddc_pin);
|
||||
ddc_pin, source);
|
||||
|
||||
return ddc_pin;
|
||||
}
|
||||
@ -2990,6 +3033,9 @@ void intel_hdmi_init_connector(struct intel_digital_port *dig_port,
|
||||
return;
|
||||
|
||||
intel_hdmi->ddc_bus = intel_hdmi_ddc_pin(intel_encoder);
|
||||
if (!intel_hdmi->ddc_bus)
|
||||
return;
|
||||
|
||||
ddc = intel_gmbus_get_adapter(dev_priv, intel_hdmi->ddc_bus);
|
||||
|
||||
drm_connector_init_with_ddc(dev, connector,
|
||||
|
@ -376,6 +376,8 @@ static void i915_hotplug_work_func(struct work_struct *work)
|
||||
u32 changed = 0, retry = 0;
|
||||
u32 hpd_event_bits;
|
||||
u32 hpd_retry_bits;
|
||||
struct drm_connector *first_changed_connector = NULL;
|
||||
int changed_connectors = 0;
|
||||
|
||||
mutex_lock(&dev_priv->drm.mode_config.mutex);
|
||||
drm_dbg_kms(&dev_priv->drm, "running encoder hotplug functions\n");
|
||||
@ -428,6 +430,11 @@ static void i915_hotplug_work_func(struct work_struct *work)
|
||||
break;
|
||||
case INTEL_HOTPLUG_CHANGED:
|
||||
changed |= hpd_bit;
|
||||
changed_connectors++;
|
||||
if (!first_changed_connector) {
|
||||
drm_connector_get(&connector->base);
|
||||
first_changed_connector = &connector->base;
|
||||
}
|
||||
break;
|
||||
case INTEL_HOTPLUG_RETRY:
|
||||
retry |= hpd_bit;
|
||||
@ -438,9 +445,14 @@ static void i915_hotplug_work_func(struct work_struct *work)
|
||||
drm_connector_list_iter_end(&conn_iter);
|
||||
mutex_unlock(&dev_priv->drm.mode_config.mutex);
|
||||
|
||||
if (changed)
|
||||
if (changed_connectors == 1)
|
||||
drm_kms_helper_connector_hotplug_event(first_changed_connector);
|
||||
else if (changed_connectors > 0)
|
||||
drm_kms_helper_hotplug_event(&dev_priv->drm);
|
||||
|
||||
if (first_changed_connector)
|
||||
drm_connector_put(first_changed_connector);
|
||||
|
||||
/* Remove shared HPD pins that have changed */
|
||||
retry &= ~changed;
|
||||
if (retry) {
|
||||
|
@ -842,6 +842,8 @@ static void icp_hpd_irq_setup(struct drm_i915_private *dev_priv)
|
||||
|
||||
if (INTEL_PCH_TYPE(dev_priv) <= PCH_TGP)
|
||||
intel_uncore_write(&dev_priv->uncore, SHPD_FILTER_CNT, SHPD_FILTER_CNT_500_ADJ);
|
||||
else
|
||||
intel_uncore_write(&dev_priv->uncore, SHPD_FILTER_CNT, SHPD_FILTER_CNT_250);
|
||||
|
||||
ibx_display_interrupt_update(dev_priv, hotplug_irqs, enabled_irqs);
|
||||
|
||||
@ -1049,7 +1051,7 @@ static void mtp_hpd_irq_setup(struct drm_i915_private *i915)
|
||||
enabled_irqs = intel_hpd_enabled_irqs(i915, i915->display.hotplug.pch_hpd);
|
||||
hotplug_irqs = intel_hpd_hotplug_irqs(i915, i915->display.hotplug.pch_hpd);
|
||||
|
||||
intel_de_write(i915, SHPD_FILTER_CNT, SHPD_FILTER_CNT_500_ADJ);
|
||||
intel_de_write(i915, SHPD_FILTER_CNT, SHPD_FILTER_CNT_250);
|
||||
|
||||
mtp_hpd_invert(i915);
|
||||
ibx_display_interrupt_update(i915, hotplug_irqs, enabled_irqs);
|
||||
|
@ -1348,11 +1348,12 @@ out_unlock:
|
||||
static int get_registers(struct intel_overlay *overlay, bool use_phys)
|
||||
{
|
||||
struct drm_i915_private *i915 = overlay->i915;
|
||||
struct drm_i915_gem_object *obj;
|
||||
struct drm_i915_gem_object *obj = ERR_PTR(-ENODEV);
|
||||
struct i915_vma *vma;
|
||||
int err;
|
||||
|
||||
obj = i915_gem_object_create_stolen(i915, PAGE_SIZE);
|
||||
if (!IS_METEORLAKE(i915)) /* Wa_22018444074 */
|
||||
obj = i915_gem_object_create_stolen(i915, PAGE_SIZE);
|
||||
if (IS_ERR(obj))
|
||||
obj = i915_gem_object_create_internal(i915, PAGE_SIZE);
|
||||
if (IS_ERR(obj))
|
||||
|
@ -234,23 +234,91 @@ static u32 psr_irq_mask_get(struct intel_dp *intel_dp)
|
||||
EDP_PSR_MASK(intel_dp->psr.transcoder);
|
||||
}
|
||||
|
||||
static i915_reg_t psr_ctl_reg(struct drm_i915_private *dev_priv,
|
||||
enum transcoder cpu_transcoder)
|
||||
{
|
||||
if (DISPLAY_VER(dev_priv) >= 8)
|
||||
return EDP_PSR_CTL(cpu_transcoder);
|
||||
else
|
||||
return HSW_SRD_CTL;
|
||||
}
|
||||
|
||||
static i915_reg_t psr_debug_reg(struct drm_i915_private *dev_priv,
|
||||
enum transcoder cpu_transcoder)
|
||||
{
|
||||
if (DISPLAY_VER(dev_priv) >= 8)
|
||||
return EDP_PSR_DEBUG(cpu_transcoder);
|
||||
else
|
||||
return HSW_SRD_DEBUG;
|
||||
}
|
||||
|
||||
static i915_reg_t psr_perf_cnt_reg(struct drm_i915_private *dev_priv,
|
||||
enum transcoder cpu_transcoder)
|
||||
{
|
||||
if (DISPLAY_VER(dev_priv) >= 8)
|
||||
return EDP_PSR_PERF_CNT(cpu_transcoder);
|
||||
else
|
||||
return HSW_SRD_PERF_CNT;
|
||||
}
|
||||
|
||||
static i915_reg_t psr_status_reg(struct drm_i915_private *dev_priv,
|
||||
enum transcoder cpu_transcoder)
|
||||
{
|
||||
if (DISPLAY_VER(dev_priv) >= 8)
|
||||
return EDP_PSR_STATUS(cpu_transcoder);
|
||||
else
|
||||
return HSW_SRD_STATUS;
|
||||
}
|
||||
|
||||
static i915_reg_t psr_imr_reg(struct drm_i915_private *dev_priv,
|
||||
enum transcoder cpu_transcoder)
|
||||
{
|
||||
if (DISPLAY_VER(dev_priv) >= 12)
|
||||
return TRANS_PSR_IMR(cpu_transcoder);
|
||||
else
|
||||
return EDP_PSR_IMR;
|
||||
}
|
||||
|
||||
static i915_reg_t psr_iir_reg(struct drm_i915_private *dev_priv,
|
||||
enum transcoder cpu_transcoder)
|
||||
{
|
||||
if (DISPLAY_VER(dev_priv) >= 12)
|
||||
return TRANS_PSR_IIR(cpu_transcoder);
|
||||
else
|
||||
return EDP_PSR_IIR;
|
||||
}
|
||||
|
||||
static i915_reg_t psr_aux_ctl_reg(struct drm_i915_private *dev_priv,
|
||||
enum transcoder cpu_transcoder)
|
||||
{
|
||||
if (DISPLAY_VER(dev_priv) >= 8)
|
||||
return EDP_PSR_AUX_CTL(cpu_transcoder);
|
||||
else
|
||||
return HSW_SRD_AUX_CTL;
|
||||
}
|
||||
|
||||
static i915_reg_t psr_aux_data_reg(struct drm_i915_private *dev_priv,
|
||||
enum transcoder cpu_transcoder, int i)
|
||||
{
|
||||
if (DISPLAY_VER(dev_priv) >= 8)
|
||||
return EDP_PSR_AUX_DATA(cpu_transcoder, i);
|
||||
else
|
||||
return HSW_SRD_AUX_DATA(i);
|
||||
}
|
||||
|
||||
static void psr_irq_control(struct intel_dp *intel_dp)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
|
||||
i915_reg_t imr_reg;
|
||||
enum transcoder cpu_transcoder = intel_dp->psr.transcoder;
|
||||
u32 mask;
|
||||
|
||||
if (DISPLAY_VER(dev_priv) >= 12)
|
||||
imr_reg = TRANS_PSR_IMR(intel_dp->psr.transcoder);
|
||||
else
|
||||
imr_reg = EDP_PSR_IMR;
|
||||
|
||||
mask = psr_irq_psr_error_bit_get(intel_dp);
|
||||
if (intel_dp->psr.debug & I915_PSR_DEBUG_IRQ)
|
||||
mask |= psr_irq_post_exit_bit_get(intel_dp) |
|
||||
psr_irq_pre_entry_bit_get(intel_dp);
|
||||
|
||||
intel_de_rmw(dev_priv, imr_reg, psr_irq_mask_get(intel_dp), ~mask);
|
||||
intel_de_rmw(dev_priv, psr_imr_reg(dev_priv, cpu_transcoder),
|
||||
psr_irq_mask_get(intel_dp), ~mask);
|
||||
}
|
||||
|
||||
static void psr_event_print(struct drm_i915_private *i915,
|
||||
@ -296,12 +364,6 @@ void intel_psr_irq_handler(struct intel_dp *intel_dp, u32 psr_iir)
|
||||
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
|
||||
enum transcoder cpu_transcoder = intel_dp->psr.transcoder;
|
||||
ktime_t time_ns = ktime_get();
|
||||
i915_reg_t imr_reg;
|
||||
|
||||
if (DISPLAY_VER(dev_priv) >= 12)
|
||||
imr_reg = TRANS_PSR_IMR(cpu_transcoder);
|
||||
else
|
||||
imr_reg = EDP_PSR_IMR;
|
||||
|
||||
if (psr_iir & psr_irq_pre_entry_bit_get(intel_dp)) {
|
||||
intel_dp->psr.last_entry_attempt = time_ns;
|
||||
@ -339,7 +401,8 @@ void intel_psr_irq_handler(struct intel_dp *intel_dp, u32 psr_iir)
|
||||
* again so we don't care about unmask the interruption
|
||||
* or unset irq_aux_error.
|
||||
*/
|
||||
intel_de_rmw(dev_priv, imr_reg, 0, psr_irq_psr_error_bit_get(intel_dp));
|
||||
intel_de_rmw(dev_priv, psr_imr_reg(dev_priv, cpu_transcoder),
|
||||
0, psr_irq_psr_error_bit_get(intel_dp));
|
||||
|
||||
queue_work(dev_priv->unordered_wq, &intel_dp->psr.work);
|
||||
}
|
||||
@ -467,6 +530,43 @@ void intel_psr_init_dpcd(struct intel_dp *intel_dp)
|
||||
}
|
||||
}
|
||||
|
||||
static void hsw_psr_setup_aux(struct intel_dp *intel_dp)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
|
||||
enum transcoder cpu_transcoder = intel_dp->psr.transcoder;
|
||||
u32 aux_clock_divider, aux_ctl;
|
||||
/* write DP_SET_POWER=D0 */
|
||||
static const u8 aux_msg[] = {
|
||||
[0] = (DP_AUX_NATIVE_WRITE << 4) | ((DP_SET_POWER >> 16) & 0xf),
|
||||
[1] = (DP_SET_POWER >> 8) & 0xff,
|
||||
[2] = DP_SET_POWER & 0xff,
|
||||
[3] = 1 - 1,
|
||||
[4] = DP_SET_POWER_D0,
|
||||
};
|
||||
int i;
|
||||
|
||||
BUILD_BUG_ON(sizeof(aux_msg) > 20);
|
||||
for (i = 0; i < sizeof(aux_msg); i += 4)
|
||||
intel_de_write(dev_priv,
|
||||
psr_aux_data_reg(dev_priv, cpu_transcoder, i >> 2),
|
||||
intel_dp_aux_pack(&aux_msg[i], sizeof(aux_msg) - i));
|
||||
|
||||
aux_clock_divider = intel_dp->get_aux_clock_divider(intel_dp, 0);
|
||||
|
||||
/* Start with bits set for DDI_AUX_CTL register */
|
||||
aux_ctl = intel_dp->get_aux_send_ctl(intel_dp, sizeof(aux_msg),
|
||||
aux_clock_divider);
|
||||
|
||||
/* Select only valid bits for SRD_AUX_CTL */
|
||||
aux_ctl &= EDP_PSR_AUX_CTL_TIME_OUT_MASK |
|
||||
EDP_PSR_AUX_CTL_MESSAGE_SIZE_MASK |
|
||||
EDP_PSR_AUX_CTL_PRECHARGE_2US_MASK |
|
||||
EDP_PSR_AUX_CTL_BIT_CLOCK_2X_MASK;
|
||||
|
||||
intel_de_write(dev_priv, psr_aux_ctl_reg(dev_priv, cpu_transcoder),
|
||||
aux_ctl);
|
||||
}
|
||||
|
||||
static void intel_psr_enable_sink(struct intel_dp *intel_dp)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
|
||||
@ -528,6 +628,15 @@ static u32 intel_psr1_get_tp_time(struct intel_dp *intel_dp)
|
||||
else
|
||||
val |= EDP_PSR_TP2_TP3_TIME_2500us;
|
||||
|
||||
/*
|
||||
* WA 0479: hsw,bdw
|
||||
* "Do not skip both TP1 and TP2/TP3"
|
||||
*/
|
||||
if (DISPLAY_VER(dev_priv) < 9 &&
|
||||
connector->panel.vbt.psr.tp1_wakeup_time_us == 0 &&
|
||||
connector->panel.vbt.psr.tp2_tp3_wakeup_time_us == 0)
|
||||
val |= EDP_PSR_TP2_TP3_TIME_100us;
|
||||
|
||||
check_tp3_sel:
|
||||
if (intel_dp_source_supports_tps3(dev_priv) &&
|
||||
drm_dp_tps3_supported(intel_dp->dpcd))
|
||||
@ -577,7 +686,7 @@ static void hsw_activate_psr1(struct intel_dp *intel_dp)
|
||||
if (DISPLAY_VER(dev_priv) >= 8)
|
||||
val |= EDP_PSR_CRC_ENABLE;
|
||||
|
||||
intel_de_rmw(dev_priv, EDP_PSR_CTL(cpu_transcoder),
|
||||
intel_de_rmw(dev_priv, psr_ctl_reg(dev_priv, cpu_transcoder),
|
||||
~EDP_PSR_RESTORE_PSR_ACTIVE_CTX_MASK, val);
|
||||
}
|
||||
|
||||
@ -685,7 +794,7 @@ static void hsw_activate_psr2(struct intel_dp *intel_dp)
|
||||
* PSR2 HW is incorrectly using EDP_PSR_TP1_TP3_SEL and BSpec is
|
||||
* recommending keep this bit unset while PSR2 is enabled.
|
||||
*/
|
||||
intel_de_write(dev_priv, EDP_PSR_CTL(cpu_transcoder), 0);
|
||||
intel_de_write(dev_priv, psr_ctl_reg(dev_priv, cpu_transcoder), 0);
|
||||
|
||||
intel_de_write(dev_priv, EDP_PSR2_CTL(cpu_transcoder), val);
|
||||
}
|
||||
@ -697,8 +806,10 @@ transcoder_has_psr2(struct drm_i915_private *dev_priv, enum transcoder cpu_trans
|
||||
return cpu_transcoder == TRANSCODER_A || cpu_transcoder == TRANSCODER_B;
|
||||
else if (DISPLAY_VER(dev_priv) >= 12)
|
||||
return cpu_transcoder == TRANSCODER_A;
|
||||
else
|
||||
else if (DISPLAY_VER(dev_priv) >= 9)
|
||||
return cpu_transcoder == TRANSCODER_EDP;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
static u32 intel_get_frame_time_us(const struct intel_crtc_state *cstate)
|
||||
@ -1201,13 +1312,15 @@ static void intel_psr_activate(struct intel_dp *intel_dp)
|
||||
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
|
||||
enum transcoder cpu_transcoder = intel_dp->psr.transcoder;
|
||||
|
||||
if (transcoder_has_psr2(dev_priv, cpu_transcoder))
|
||||
drm_WARN_ON(&dev_priv->drm,
|
||||
intel_de_read(dev_priv, EDP_PSR2_CTL(cpu_transcoder)) & EDP_PSR2_ENABLE);
|
||||
drm_WARN_ON(&dev_priv->drm,
|
||||
transcoder_has_psr2(dev_priv, cpu_transcoder) &&
|
||||
intel_de_read(dev_priv, EDP_PSR2_CTL(cpu_transcoder)) & EDP_PSR2_ENABLE);
|
||||
|
||||
drm_WARN_ON(&dev_priv->drm,
|
||||
intel_de_read(dev_priv, EDP_PSR_CTL(cpu_transcoder)) & EDP_PSR_ENABLE);
|
||||
intel_de_read(dev_priv, psr_ctl_reg(dev_priv, cpu_transcoder)) & EDP_PSR_ENABLE);
|
||||
|
||||
drm_WARN_ON(&dev_priv->drm, intel_dp->psr.active);
|
||||
|
||||
lockdep_assert_held(&intel_dp->psr.lock);
|
||||
|
||||
/* psr1 and psr2 are mutually exclusive.*/
|
||||
@ -1271,6 +1384,13 @@ static void intel_psr_enable_source(struct intel_dp *intel_dp,
|
||||
enum transcoder cpu_transcoder = intel_dp->psr.transcoder;
|
||||
u32 mask;
|
||||
|
||||
/*
|
||||
* Only HSW and BDW have PSR AUX registers that need to be setup.
|
||||
* SKL+ use hardcoded values PSR AUX transactions
|
||||
*/
|
||||
if (DISPLAY_VER(dev_priv) < 9)
|
||||
hsw_psr_setup_aux(intel_dp);
|
||||
|
||||
/*
|
||||
* Per Spec: Avoid continuous PSR exit by masking MEMUP and HPD also
|
||||
* mask LPSP to avoid dependency on other drivers that might block
|
||||
@ -1282,11 +1402,18 @@ static void intel_psr_enable_source(struct intel_dp *intel_dp,
|
||||
EDP_PSR_DEBUG_MASK_LPSP |
|
||||
EDP_PSR_DEBUG_MASK_MAX_SLEEP;
|
||||
|
||||
if (DISPLAY_VER(dev_priv) < 11)
|
||||
/*
|
||||
* No separate pipe reg write mask on hsw/bdw, so have to unmask all
|
||||
* registers in order to keep the CURSURFLIVE tricks working :(
|
||||
*/
|
||||
if (IS_DISPLAY_VER(dev_priv, 9, 10))
|
||||
mask |= EDP_PSR_DEBUG_MASK_DISP_REG_WRITE;
|
||||
|
||||
intel_de_write(dev_priv, EDP_PSR_DEBUG(cpu_transcoder),
|
||||
mask);
|
||||
/* allow PSR with sprite enabled */
|
||||
if (IS_HASWELL(dev_priv))
|
||||
mask |= EDP_PSR_DEBUG_MASK_SPRITE_ENABLE;
|
||||
|
||||
intel_de_write(dev_priv, psr_debug_reg(dev_priv, cpu_transcoder), mask);
|
||||
|
||||
psr_irq_control(intel_dp);
|
||||
|
||||
@ -1352,10 +1479,7 @@ static bool psr_interrupt_error_check(struct intel_dp *intel_dp)
|
||||
* first time that PSR HW tries to activate so lets keep PSR disabled
|
||||
* to avoid any rendering problems.
|
||||
*/
|
||||
if (DISPLAY_VER(dev_priv) >= 12)
|
||||
val = intel_de_read(dev_priv, TRANS_PSR_IIR(cpu_transcoder));
|
||||
else
|
||||
val = intel_de_read(dev_priv, EDP_PSR_IIR);
|
||||
val = intel_de_read(dev_priv, psr_iir_reg(dev_priv, cpu_transcoder));
|
||||
val &= psr_irq_psr_error_bit_get(intel_dp);
|
||||
if (val) {
|
||||
intel_dp->psr.sink_not_reliable = true;
|
||||
@ -1418,7 +1542,7 @@ static void intel_psr_exit(struct intel_dp *intel_dp)
|
||||
drm_WARN_ON(&dev_priv->drm, val & EDP_PSR2_ENABLE);
|
||||
}
|
||||
|
||||
val = intel_de_read(dev_priv, EDP_PSR_CTL(cpu_transcoder));
|
||||
val = intel_de_read(dev_priv, psr_ctl_reg(dev_priv, cpu_transcoder));
|
||||
drm_WARN_ON(&dev_priv->drm, val & EDP_PSR_ENABLE);
|
||||
|
||||
return;
|
||||
@ -1432,7 +1556,7 @@ static void intel_psr_exit(struct intel_dp *intel_dp)
|
||||
|
||||
drm_WARN_ON(&dev_priv->drm, !(val & EDP_PSR2_ENABLE));
|
||||
} else {
|
||||
val = intel_de_rmw(dev_priv, EDP_PSR_CTL(cpu_transcoder),
|
||||
val = intel_de_rmw(dev_priv, psr_ctl_reg(dev_priv, cpu_transcoder),
|
||||
EDP_PSR_ENABLE, 0);
|
||||
|
||||
drm_WARN_ON(&dev_priv->drm, !(val & EDP_PSR_ENABLE));
|
||||
@ -1451,7 +1575,7 @@ static void intel_psr_wait_exit_locked(struct intel_dp *intel_dp)
|
||||
psr_status = EDP_PSR2_STATUS(cpu_transcoder);
|
||||
psr_status_mask = EDP_PSR2_STATUS_STATE_MASK;
|
||||
} else {
|
||||
psr_status = EDP_PSR_STATUS(cpu_transcoder);
|
||||
psr_status = psr_status_reg(dev_priv, cpu_transcoder);
|
||||
psr_status_mask = EDP_PSR_STATUS_STATE_MASK;
|
||||
}
|
||||
|
||||
@ -2151,7 +2275,7 @@ static int _psr1_ready_for_pipe_update_locked(struct intel_dp *intel_dp)
|
||||
* defensive enough to cover everything.
|
||||
*/
|
||||
return intel_de_wait_for_clear(dev_priv,
|
||||
EDP_PSR_STATUS(cpu_transcoder),
|
||||
psr_status_reg(dev_priv, cpu_transcoder),
|
||||
EDP_PSR_STATUS_STATE_MASK, 50);
|
||||
}
|
||||
|
||||
@ -2205,7 +2329,7 @@ static bool __psr_wait_for_idle_locked(struct intel_dp *intel_dp)
|
||||
reg = EDP_PSR2_STATUS(cpu_transcoder);
|
||||
mask = EDP_PSR2_STATUS_STATE_MASK;
|
||||
} else {
|
||||
reg = EDP_PSR_STATUS(cpu_transcoder);
|
||||
reg = psr_status_reg(dev_priv, cpu_transcoder);
|
||||
mask = EDP_PSR_STATUS_STATE_MASK;
|
||||
}
|
||||
|
||||
@ -2825,7 +2949,7 @@ psr_source_status(struct intel_dp *intel_dp, struct seq_file *m)
|
||||
"SRDOFFACK",
|
||||
"SRDENT_ON",
|
||||
};
|
||||
val = intel_de_read(dev_priv, EDP_PSR_STATUS(cpu_transcoder));
|
||||
val = intel_de_read(dev_priv, psr_status_reg(dev_priv, cpu_transcoder));
|
||||
status_val = REG_FIELD_GET(EDP_PSR_STATUS_STATE_MASK, val);
|
||||
if (status_val < ARRAY_SIZE(live_status))
|
||||
status = live_status[status_val];
|
||||
@ -2872,7 +2996,7 @@ static int intel_psr_status(struct seq_file *m, struct intel_dp *intel_dp)
|
||||
val = intel_de_read(dev_priv, EDP_PSR2_CTL(cpu_transcoder));
|
||||
enabled = val & EDP_PSR2_ENABLE;
|
||||
} else {
|
||||
val = intel_de_read(dev_priv, EDP_PSR_CTL(cpu_transcoder));
|
||||
val = intel_de_read(dev_priv, psr_ctl_reg(dev_priv, cpu_transcoder));
|
||||
enabled = val & EDP_PSR_ENABLE;
|
||||
}
|
||||
seq_printf(m, "Source PSR ctl: %s [0x%08x]\n",
|
||||
@ -2884,7 +3008,7 @@ static int intel_psr_status(struct seq_file *m, struct intel_dp *intel_dp)
|
||||
/*
|
||||
* SKL+ Perf counter is reset to 0 everytime DC state is entered
|
||||
*/
|
||||
val = intel_de_read(dev_priv, EDP_PSR_PERF_CNT(cpu_transcoder));
|
||||
val = intel_de_read(dev_priv, psr_perf_cnt_reg(dev_priv, cpu_transcoder));
|
||||
seq_printf(m, "Performance counter: %u\n",
|
||||
REG_FIELD_GET(EDP_PSR_PERF_CNT_MASK, val));
|
||||
|
||||
|
@ -7,6 +7,7 @@
|
||||
#define __INTEL_PSR_REGS_H__
|
||||
|
||||
#include "intel_display_reg_defs.h"
|
||||
#include "intel_dp_aux_regs.h"
|
||||
|
||||
#define TRANS_EXITLINE(trans) _MMIO_TRANS2((trans), _TRANS_EXITLINE_A)
|
||||
#define EXITLINE_ENABLE REG_BIT(31)
|
||||
@ -19,6 +20,7 @@
|
||||
* HSW PSR registers are relative to DDIA(_DDI_BUF_CTL_A + 0x800) with just one
|
||||
* instance of it
|
||||
*/
|
||||
#define HSW_SRD_CTL _MMIO(0x64800)
|
||||
#define _SRD_CTL_A 0x60800
|
||||
#define _SRD_CTL_EDP 0x6f800
|
||||
#define EDP_PSR_CTL(tran) _MMIO_TRANS2(tran, _SRD_CTL_A)
|
||||
@ -79,10 +81,22 @@
|
||||
#define EDP_PSR_PRE_ENTRY(trans) (TGL_PSR_PRE_ENTRY << \
|
||||
_EDP_PSR_TRANS_SHIFT(trans))
|
||||
|
||||
#define HSW_SRD_AUX_CTL _MMIO(0x64810)
|
||||
#define _SRD_AUX_CTL_A 0x60810
|
||||
#define _SRD_AUX_CTL_EDP 0x6f810
|
||||
#define EDP_PSR_AUX_CTL(tran) _MMIO_TRANS2(tran, _SRD_AUX_CTL_A)
|
||||
#define EDP_PSR_AUX_CTL_TIME_OUT_MASK DP_AUX_CH_CTL_TIME_OUT_MASK
|
||||
#define EDP_PSR_AUX_CTL_MESSAGE_SIZE_MASK DP_AUX_CH_CTL_MESSAGE_SIZE_MASK
|
||||
#define EDP_PSR_AUX_CTL_PRECHARGE_2US_MASK DP_AUX_CH_CTL_PRECHARGE_2US_MASK
|
||||
#define EDP_PSR_AUX_CTL_ERROR_INTERRUPT REG_BIT(11)
|
||||
#define EDP_PSR_AUX_CTL_BIT_CLOCK_2X_MASK DP_AUX_CH_CTL_BIT_CLOCK_2X_MASK
|
||||
|
||||
#define HSW_SRD_AUX_DATA(i) _MMIO(0x64814 + (i) * 4) /* 5 registers */
|
||||
#define _SRD_AUX_DATA_A 0x60814
|
||||
#define _SRD_AUX_DATA_EDP 0x6f814
|
||||
#define EDP_PSR_AUX_DATA(tran, i) _MMIO_TRANS2(tran, _SRD_AUX_DATA_A + (i) * 4) /* 5 registers */
|
||||
|
||||
#define HSW_SRD_STATUS _MMIO(0x64840)
|
||||
#define _SRD_STATUS_A 0x60840
|
||||
#define _SRD_STATUS_EDP 0x6f840
|
||||
#define EDP_PSR_STATUS(tran) _MMIO_TRANS2(tran, _SRD_STATUS_A)
|
||||
@ -107,12 +121,14 @@
|
||||
#define EDP_PSR_STATUS_SENDING_TP1 REG_BIT(4)
|
||||
#define EDP_PSR_STATUS_IDLE_MASK REG_GENMASK(3, 0)
|
||||
|
||||
#define HSW_SRD_PERF_CNT _MMIO(0x64844)
|
||||
#define _SRD_PERF_CNT_A 0x60844
|
||||
#define _SRD_PERF_CNT_EDP 0x6f844
|
||||
#define EDP_PSR_PERF_CNT(tran) _MMIO_TRANS2(tran, _SRD_PERF_CNT_A)
|
||||
#define EDP_PSR_PERF_CNT_MASK REG_GENMASK(23, 0)
|
||||
|
||||
/* PSR_MASK on SKL+ */
|
||||
#define HSW_SRD_DEBUG _MMIO(0x64860)
|
||||
#define _SRD_DEBUG_A 0x60860
|
||||
#define _SRD_DEBUG_EDP 0x6f860
|
||||
#define EDP_PSR_DEBUG(tran) _MMIO_TRANS2(tran, _SRD_DEBUG_A)
|
||||
|
@ -17,13 +17,17 @@
|
||||
/* from BPP 6 to 36 in steps of 0.5 */
|
||||
#define RC_RANGE_QP444_12BPC_MAX_NUM_BPP 61
|
||||
|
||||
/* from BPP 6 to 24 in steps of 0.5 */
|
||||
/* For YCbCr420 the bits_per_pixel sent in PPS params
|
||||
* is double the target bpp. The below values represent
|
||||
* the target bpp.
|
||||
*/
|
||||
/* from BPP 4 to 12 in steps of 0.5 */
|
||||
#define RC_RANGE_QP420_8BPC_MAX_NUM_BPP 17
|
||||
|
||||
/* from BPP 6 to 30 in steps of 0.5 */
|
||||
/* from BPP 4 to 15 in steps of 0.5 */
|
||||
#define RC_RANGE_QP420_10BPC_MAX_NUM_BPP 23
|
||||
|
||||
/* from BPP 6 to 36 in steps of 0.5 */
|
||||
/* from BPP 4 to 18 in steps of 0.5 */
|
||||
#define RC_RANGE_QP420_12BPC_MAX_NUM_BPP 29
|
||||
|
||||
/*
|
||||
|
@ -3313,13 +3313,19 @@ intel_sdvo_init_ddc_proxy(struct intel_sdvo *sdvo,
|
||||
return i2c_add_adapter(&sdvo->ddc) == 0;
|
||||
}
|
||||
|
||||
static void assert_sdvo_port_valid(const struct drm_i915_private *dev_priv,
|
||||
enum port port)
|
||||
static bool is_sdvo_port_valid(struct drm_i915_private *dev_priv, enum port port)
|
||||
{
|
||||
if (HAS_PCH_SPLIT(dev_priv))
|
||||
drm_WARN_ON(&dev_priv->drm, port != PORT_B);
|
||||
return port == PORT_B;
|
||||
else
|
||||
drm_WARN_ON(&dev_priv->drm, port != PORT_B && port != PORT_C);
|
||||
return port == PORT_B || port == PORT_C;
|
||||
}
|
||||
|
||||
static bool assert_sdvo_port_valid(struct drm_i915_private *dev_priv,
|
||||
enum port port)
|
||||
{
|
||||
return !drm_WARN(&dev_priv->drm, !is_sdvo_port_valid(dev_priv, port),
|
||||
"Platform does not support SDVO %c\n", port_name(port));
|
||||
}
|
||||
|
||||
bool intel_sdvo_init(struct drm_i915_private *dev_priv,
|
||||
@ -3329,7 +3335,11 @@ bool intel_sdvo_init(struct drm_i915_private *dev_priv,
|
||||
struct intel_sdvo *intel_sdvo;
|
||||
int i;
|
||||
|
||||
assert_sdvo_port_valid(dev_priv, port);
|
||||
if (!assert_port_valid(dev_priv, port))
|
||||
return false;
|
||||
|
||||
if (!assert_sdvo_port_valid(dev_priv, port))
|
||||
return false;
|
||||
|
||||
intel_sdvo = kzalloc(sizeof(*intel_sdvo), GFP_KERNEL);
|
||||
if (!intel_sdvo)
|
||||
|
@ -52,23 +52,33 @@ static bool is_pipe_dsc(struct intel_crtc *crtc, enum transcoder cpu_transcoder)
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
intel_vdsc_set_min_max_qp(struct drm_dsc_config *vdsc_cfg, int buf,
|
||||
int bpp)
|
||||
{
|
||||
int bpc = vdsc_cfg->bits_per_component;
|
||||
|
||||
/* Read range_minqp and range_max_qp from qp tables */
|
||||
vdsc_cfg->rc_range_params[buf].range_min_qp =
|
||||
intel_lookup_range_min_qp(bpc, buf, bpp, vdsc_cfg->native_420);
|
||||
vdsc_cfg->rc_range_params[buf].range_max_qp =
|
||||
intel_lookup_range_max_qp(bpc, buf, bpp, vdsc_cfg->native_420);
|
||||
}
|
||||
|
||||
/*
|
||||
* We are using the method provided in DSC 1.2a C-Model in codec_main.c
|
||||
* Above method use a common formula to derive values for any combination of DSC
|
||||
* variables. The formula approach may yield slight differences in the derived PPS
|
||||
* parameters from the original parameter sets. These differences are not consequential
|
||||
* to the coding performance because all parameter sets have been shown to produce
|
||||
* visually lossless quality (provides the same PPS values as
|
||||
* DSCParameterValuesVESA V1-2 spreadsheet).
|
||||
*/
|
||||
static void
|
||||
calculate_rc_params(struct drm_dsc_config *vdsc_cfg)
|
||||
{
|
||||
int bpc = vdsc_cfg->bits_per_component;
|
||||
int bpp = vdsc_cfg->bits_per_pixel >> 4;
|
||||
static const s8 ofs_und6[] = {
|
||||
0, -2, -2, -4, -6, -6, -8, -8, -8, -10, -10, -12, -12, -12, -12
|
||||
};
|
||||
static const s8 ofs_und8[] = {
|
||||
2, 0, 0, -2, -4, -6, -8, -8, -8, -10, -10, -10, -12, -12, -12
|
||||
};
|
||||
static const s8 ofs_und12[] = {
|
||||
2, 0, 0, -2, -4, -6, -8, -8, -8, -10, -10, -10, -12, -12, -12
|
||||
};
|
||||
static const s8 ofs_und15[] = {
|
||||
10, 8, 6, 4, 2, 0, -2, -4, -6, -8, -10, -10, -12, -12, -12
|
||||
};
|
||||
int qp_bpc_modifier = (bpc - 8) * 2;
|
||||
u32 res, buf_i, bpp_i;
|
||||
|
||||
@ -78,6 +88,28 @@ calculate_rc_params(struct drm_dsc_config *vdsc_cfg)
|
||||
else
|
||||
vdsc_cfg->first_line_bpg_offset = 2 * (vdsc_cfg->slice_height - 1);
|
||||
|
||||
/*
|
||||
* According to DSC 1.2 spec in Section 4.1 if native_420 is set:
|
||||
* -second_line_bpg_offset is 12 in general and equal to 2*(slice_height-1) if slice
|
||||
* height < 8.
|
||||
* -second_line_offset_adj is 512 as shown by emperical values to yield best chroma
|
||||
* preservation in second line.
|
||||
* -nsl_bpg_offset is calculated as second_line_offset/slice_height -1 then rounded
|
||||
* up to 16 fractional bits, we left shift second line offset by 11 to preserve 11
|
||||
* fractional bits.
|
||||
*/
|
||||
if (vdsc_cfg->native_420) {
|
||||
if (vdsc_cfg->slice_height >= 8)
|
||||
vdsc_cfg->second_line_bpg_offset = 12;
|
||||
else
|
||||
vdsc_cfg->second_line_bpg_offset =
|
||||
2 * (vdsc_cfg->slice_height - 1);
|
||||
|
||||
vdsc_cfg->second_line_offset_adj = 512;
|
||||
vdsc_cfg->nsl_bpg_offset = DIV_ROUND_UP(vdsc_cfg->second_line_bpg_offset << 11,
|
||||
vdsc_cfg->slice_height - 1);
|
||||
}
|
||||
|
||||
/* Our hw supports only 444 modes as of today */
|
||||
if (bpp >= 12)
|
||||
vdsc_cfg->initial_offset = 2048;
|
||||
@ -97,33 +129,88 @@ calculate_rc_params(struct drm_dsc_config *vdsc_cfg)
|
||||
vdsc_cfg->rc_quant_incr_limit0 = 11 + qp_bpc_modifier;
|
||||
vdsc_cfg->rc_quant_incr_limit1 = 11 + qp_bpc_modifier;
|
||||
|
||||
bpp_i = (2 * (bpp - 6));
|
||||
for (buf_i = 0; buf_i < DSC_NUM_BUF_RANGES; buf_i++) {
|
||||
u8 range_bpg_offset;
|
||||
if (vdsc_cfg->native_420) {
|
||||
static const s8 ofs_und4[] = {
|
||||
2, 0, 0, -2, -4, -6, -8, -8, -8, -10, -10, -12, -12, -12, -12
|
||||
};
|
||||
static const s8 ofs_und5[] = {
|
||||
2, 0, 0, -2, -4, -6, -8, -8, -8, -10, -10, -10, -12, -12, -12
|
||||
};
|
||||
static const s8 ofs_und6[] = {
|
||||
2, 0, 0, -2, -4, -6, -8, -8, -8, -10, -10, -10, -12, -12, -12
|
||||
};
|
||||
static const s8 ofs_und8[] = {
|
||||
10, 8, 6, 4, 2, 0, -2, -4, -6, -8, -10, -10, -12, -12, -12
|
||||
};
|
||||
|
||||
/* Read range_minqp and range_max_qp from qp tables */
|
||||
vdsc_cfg->rc_range_params[buf_i].range_min_qp =
|
||||
intel_lookup_range_min_qp(bpc, buf_i, bpp_i, vdsc_cfg->native_420);
|
||||
vdsc_cfg->rc_range_params[buf_i].range_max_qp =
|
||||
intel_lookup_range_max_qp(bpc, buf_i, bpp_i, vdsc_cfg->native_420);
|
||||
bpp_i = bpp - 8;
|
||||
for (buf_i = 0; buf_i < DSC_NUM_BUF_RANGES; buf_i++) {
|
||||
u8 range_bpg_offset;
|
||||
|
||||
/* Calculate range_bpg_offset */
|
||||
if (bpp <= 6) {
|
||||
range_bpg_offset = ofs_und6[buf_i];
|
||||
} else if (bpp <= 8) {
|
||||
res = DIV_ROUND_UP(((bpp - 6) * (ofs_und8[buf_i] - ofs_und6[buf_i])), 2);
|
||||
range_bpg_offset = ofs_und6[buf_i] + res;
|
||||
} else if (bpp <= 12) {
|
||||
range_bpg_offset = ofs_und8[buf_i];
|
||||
} else if (bpp <= 15) {
|
||||
res = DIV_ROUND_UP(((bpp - 12) * (ofs_und15[buf_i] - ofs_und12[buf_i])), 3);
|
||||
range_bpg_offset = ofs_und12[buf_i] + res;
|
||||
} else {
|
||||
range_bpg_offset = ofs_und15[buf_i];
|
||||
intel_vdsc_set_min_max_qp(vdsc_cfg, buf_i, bpp_i);
|
||||
|
||||
/* Calculate range_bpg_offset */
|
||||
if (bpp <= 8) {
|
||||
range_bpg_offset = ofs_und4[buf_i];
|
||||
} else if (bpp <= 10) {
|
||||
res = DIV_ROUND_UP(((bpp - 8) *
|
||||
(ofs_und5[buf_i] - ofs_und4[buf_i])), 2);
|
||||
range_bpg_offset = ofs_und4[buf_i] + res;
|
||||
} else if (bpp <= 12) {
|
||||
res = DIV_ROUND_UP(((bpp - 10) *
|
||||
(ofs_und6[buf_i] - ofs_und5[buf_i])), 2);
|
||||
range_bpg_offset = ofs_und5[buf_i] + res;
|
||||
} else if (bpp <= 16) {
|
||||
res = DIV_ROUND_UP(((bpp - 12) *
|
||||
(ofs_und8[buf_i] - ofs_und6[buf_i])), 4);
|
||||
range_bpg_offset = ofs_und6[buf_i] + res;
|
||||
} else {
|
||||
range_bpg_offset = ofs_und8[buf_i];
|
||||
}
|
||||
|
||||
vdsc_cfg->rc_range_params[buf_i].range_bpg_offset =
|
||||
range_bpg_offset & DSC_RANGE_BPG_OFFSET_MASK;
|
||||
}
|
||||
} else {
|
||||
static const s8 ofs_und6[] = {
|
||||
0, -2, -2, -4, -6, -6, -8, -8, -8, -10, -10, -12, -12, -12, -12
|
||||
};
|
||||
static const s8 ofs_und8[] = {
|
||||
2, 0, 0, -2, -4, -6, -8, -8, -8, -10, -10, -10, -12, -12, -12
|
||||
};
|
||||
static const s8 ofs_und12[] = {
|
||||
2, 0, 0, -2, -4, -6, -8, -8, -8, -10, -10, -10, -12, -12, -12
|
||||
};
|
||||
static const s8 ofs_und15[] = {
|
||||
10, 8, 6, 4, 2, 0, -2, -4, -6, -8, -10, -10, -12, -12, -12
|
||||
};
|
||||
|
||||
vdsc_cfg->rc_range_params[buf_i].range_bpg_offset =
|
||||
range_bpg_offset & DSC_RANGE_BPG_OFFSET_MASK;
|
||||
bpp_i = (2 * (bpp - 6));
|
||||
for (buf_i = 0; buf_i < DSC_NUM_BUF_RANGES; buf_i++) {
|
||||
u8 range_bpg_offset;
|
||||
|
||||
intel_vdsc_set_min_max_qp(vdsc_cfg, buf_i, bpp_i);
|
||||
|
||||
/* Calculate range_bpg_offset */
|
||||
if (bpp <= 6) {
|
||||
range_bpg_offset = ofs_und6[buf_i];
|
||||
} else if (bpp <= 8) {
|
||||
res = DIV_ROUND_UP(((bpp - 6) *
|
||||
(ofs_und8[buf_i] - ofs_und6[buf_i])), 2);
|
||||
range_bpg_offset = ofs_und6[buf_i] + res;
|
||||
} else if (bpp <= 12) {
|
||||
range_bpg_offset = ofs_und8[buf_i];
|
||||
} else if (bpp <= 15) {
|
||||
res = DIV_ROUND_UP(((bpp - 12) *
|
||||
(ofs_und15[buf_i] - ofs_und12[buf_i])), 3);
|
||||
range_bpg_offset = ofs_und12[buf_i] + res;
|
||||
} else {
|
||||
range_bpg_offset = ofs_und15[buf_i];
|
||||
}
|
||||
|
||||
vdsc_cfg->rc_range_params[buf_i].range_bpg_offset =
|
||||
range_bpg_offset & DSC_RANGE_BPG_OFFSET_MASK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -190,30 +277,12 @@ int intel_dsc_compute_params(struct intel_crtc_state *pipe_config)
|
||||
vdsc_cfg->bits_per_pixel = compressed_bpp << 4;
|
||||
|
||||
/*
|
||||
* According to DSC 1.2 specs in Section 4.1 if native_420 is set:
|
||||
* -We need to double the current bpp.
|
||||
* -second_line_bpg_offset is 12 in general and equal to 2*(slice_height-1) if slice
|
||||
* height < 8.
|
||||
* -second_line_offset_adj is 512 as shown by emperical values to yeild best chroma
|
||||
* preservation in second line.
|
||||
* -nsl_bpg_offset is calculated as second_line_offset/slice_height -1 then rounded
|
||||
* up to 16 fractional bits, we left shift second line offset by 11 to preserve 11
|
||||
* fractional bits.
|
||||
* According to DSC 1.2 specs in Section 4.1 if native_420 is set
|
||||
* we need to double the current bpp.
|
||||
*/
|
||||
if (vdsc_cfg->native_420) {
|
||||
if (vdsc_cfg->native_420)
|
||||
vdsc_cfg->bits_per_pixel <<= 1;
|
||||
|
||||
if (vdsc_cfg->slice_height >= 8)
|
||||
vdsc_cfg->second_line_bpg_offset = 12;
|
||||
else
|
||||
vdsc_cfg->second_line_bpg_offset =
|
||||
2 * (vdsc_cfg->slice_height - 1);
|
||||
|
||||
vdsc_cfg->second_line_offset_adj = 512;
|
||||
vdsc_cfg->nsl_bpg_offset = DIV_ROUND_UP(vdsc_cfg->second_line_bpg_offset << 11,
|
||||
vdsc_cfg->slice_height - 1);
|
||||
}
|
||||
|
||||
vdsc_cfg->bits_per_component = pipe_config->pipe_bpp / 3;
|
||||
|
||||
drm_dsc_set_rc_buf_thresh(vdsc_cfg);
|
||||
@ -237,18 +306,6 @@ int intel_dsc_compute_params(struct intel_crtc_state *pipe_config)
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* FIXME: verify that the hardware actually needs these
|
||||
* modifications rather than them being simple typos.
|
||||
*/
|
||||
if (compressed_bpp == 6 &&
|
||||
vdsc_cfg->bits_per_component == 8)
|
||||
vdsc_cfg->rc_quant_incr_limit1 = 23;
|
||||
|
||||
if (compressed_bpp == 8 &&
|
||||
vdsc_cfg->bits_per_component == 14)
|
||||
vdsc_cfg->rc_range_params[0].range_bpg_offset = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -293,6 +350,16 @@ intel_dsc_power_domain(struct intel_crtc *crtc, enum transcoder cpu_transcoder)
|
||||
return POWER_DOMAIN_TRANSCODER_VDSC_PW2;
|
||||
}
|
||||
|
||||
int intel_dsc_get_num_vdsc_instances(const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
int num_vdsc_instances = (crtc_state->dsc.dsc_split) ? 2 : 1;
|
||||
|
||||
if (crtc_state->bigjoiner_pipes)
|
||||
num_vdsc_instances *= 2;
|
||||
|
||||
return num_vdsc_instances;
|
||||
}
|
||||
|
||||
static void intel_dsc_pps_configure(const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
||||
@ -303,11 +370,8 @@ static void intel_dsc_pps_configure(const struct intel_crtc_state *crtc_state)
|
||||
u32 pps_val = 0;
|
||||
u32 rc_buf_thresh_dword[4];
|
||||
u32 rc_range_params_dword[8];
|
||||
u8 num_vdsc_instances = (crtc_state->dsc.dsc_split) ? 2 : 1;
|
||||
int i = 0;
|
||||
|
||||
if (crtc_state->bigjoiner_pipes)
|
||||
num_vdsc_instances *= 2;
|
||||
int num_vdsc_instances = intel_dsc_get_num_vdsc_instances(crtc_state);
|
||||
|
||||
/* Populate PICTURE_PARAMETER_SET_0 registers */
|
||||
pps_val = DSC_VER_MAJ | vdsc_cfg->dsc_version_minor <<
|
||||
|
@ -22,6 +22,7 @@ void intel_dsc_get_config(struct intel_crtc_state *crtc_state);
|
||||
enum intel_display_power_domain
|
||||
intel_dsc_power_domain(struct intel_crtc *crtc, enum transcoder cpu_transcoder);
|
||||
struct intel_crtc *intel_dsc_get_bigjoiner_secondary(const struct intel_crtc *primary_crtc);
|
||||
int intel_dsc_get_num_vdsc_instances(const struct intel_crtc_state *crtc_state);
|
||||
void intel_dsc_dsi_pps_write(struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *crtc_state);
|
||||
void intel_dsc_dp_pps_write(struct intel_encoder *encoder,
|
||||
|
@ -671,20 +671,6 @@ static void intel_dsi_port_disable(struct intel_encoder *encoder)
|
||||
intel_de_posting_read(dev_priv, port_ctrl);
|
||||
}
|
||||
}
|
||||
|
||||
static void intel_dsi_wait_panel_power_cycle(struct intel_dsi *intel_dsi)
|
||||
{
|
||||
ktime_t panel_power_on_time;
|
||||
s64 panel_power_off_duration;
|
||||
|
||||
panel_power_on_time = ktime_get_boottime();
|
||||
panel_power_off_duration = ktime_ms_delta(panel_power_on_time,
|
||||
intel_dsi->panel_power_off_time);
|
||||
|
||||
if (panel_power_off_duration < (s64)intel_dsi->panel_pwr_cycle_delay)
|
||||
msleep(intel_dsi->panel_pwr_cycle_delay - panel_power_off_duration);
|
||||
}
|
||||
|
||||
static void intel_dsi_prepare(struct intel_encoder *intel_encoder,
|
||||
const struct intel_crtc_state *pipe_config);
|
||||
static void intel_dsi_unprepare(struct intel_encoder *encoder);
|
||||
@ -831,8 +817,6 @@ static void bxt_dsi_enable(struct intel_atomic_state *state,
|
||||
const struct intel_crtc_state *crtc_state,
|
||||
const struct drm_connector_state *conn_state)
|
||||
{
|
||||
drm_WARN_ON(state->base.dev, crtc_state->has_pch_encoder);
|
||||
|
||||
intel_crtc_vblank_on(crtc_state);
|
||||
}
|
||||
|
||||
@ -943,13 +927,6 @@ static void intel_dsi_post_disable(struct intel_atomic_state *state,
|
||||
intel_dsi->panel_power_off_time = ktime_get_boottime();
|
||||
}
|
||||
|
||||
static void intel_dsi_shutdown(struct intel_encoder *encoder)
|
||||
{
|
||||
struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
|
||||
|
||||
intel_dsi_wait_panel_power_cycle(intel_dsi);
|
||||
}
|
||||
|
||||
static bool intel_dsi_get_hw_state(struct intel_encoder *encoder,
|
||||
enum pipe *pipe)
|
||||
{
|
||||
|
@ -469,7 +469,7 @@ void __i915_gem_object_flush_frontbuffer(struct drm_i915_gem_object *obj,
|
||||
{
|
||||
struct intel_frontbuffer *front;
|
||||
|
||||
front = __intel_frontbuffer_get(obj);
|
||||
front = i915_gem_object_get_frontbuffer(obj);
|
||||
if (front) {
|
||||
intel_frontbuffer_flush(front, origin);
|
||||
intel_frontbuffer_put(front);
|
||||
@ -481,7 +481,7 @@ void __i915_gem_object_invalidate_frontbuffer(struct drm_i915_gem_object *obj,
|
||||
{
|
||||
struct intel_frontbuffer *front;
|
||||
|
||||
front = __intel_frontbuffer_get(obj);
|
||||
front = i915_gem_object_get_frontbuffer(obj);
|
||||
if (front) {
|
||||
intel_frontbuffer_invalidate(front, origin);
|
||||
intel_frontbuffer_put(front);
|
||||
|
@ -891,4 +891,71 @@ static inline int i915_gem_object_userptr_validate(struct drm_i915_gem_object *o
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* i915_gem_object_get_frontbuffer - Get the object's frontbuffer
|
||||
* @obj: The object whose frontbuffer to get.
|
||||
*
|
||||
* Get pointer to object's frontbuffer if such exists. Please note that RCU
|
||||
* mechanism is used to handle e.g. ongoing removal of frontbuffer pointer.
|
||||
*
|
||||
* Return: pointer to object's frontbuffer is such exists or NULL
|
||||
*/
|
||||
static inline struct intel_frontbuffer *
|
||||
i915_gem_object_get_frontbuffer(const struct drm_i915_gem_object *obj)
|
||||
{
|
||||
struct intel_frontbuffer *front;
|
||||
|
||||
if (likely(!rcu_access_pointer(obj->frontbuffer)))
|
||||
return NULL;
|
||||
|
||||
rcu_read_lock();
|
||||
do {
|
||||
front = rcu_dereference(obj->frontbuffer);
|
||||
if (!front)
|
||||
break;
|
||||
|
||||
if (unlikely(!kref_get_unless_zero(&front->ref)))
|
||||
continue;
|
||||
|
||||
if (likely(front == rcu_access_pointer(obj->frontbuffer)))
|
||||
break;
|
||||
|
||||
intel_frontbuffer_put(front);
|
||||
} while (1);
|
||||
rcu_read_unlock();
|
||||
|
||||
return front;
|
||||
}
|
||||
|
||||
/**
|
||||
* i915_gem_object_set_frontbuffer - Set the object's frontbuffer
|
||||
* @obj: The object whose frontbuffer to set.
|
||||
* @front: The frontbuffer to set
|
||||
*
|
||||
* Set object's frontbuffer pointer. If frontbuffer is already set for the
|
||||
* object keep it and return it's pointer to the caller. Please note that RCU
|
||||
* mechanism is used to handle e.g. ongoing removal of frontbuffer pointer. This
|
||||
* function is protected by i915->display.fb_tracking.lock
|
||||
*
|
||||
* Return: pointer to frontbuffer which was set.
|
||||
*/
|
||||
static inline struct intel_frontbuffer *
|
||||
i915_gem_object_set_frontbuffer(struct drm_i915_gem_object *obj,
|
||||
struct intel_frontbuffer *front)
|
||||
{
|
||||
struct intel_frontbuffer *cur = front;
|
||||
|
||||
if (!front) {
|
||||
RCU_INIT_POINTER(obj->frontbuffer, NULL);
|
||||
} else if (rcu_access_pointer(obj->frontbuffer)) {
|
||||
cur = rcu_dereference_protected(obj->frontbuffer, true);
|
||||
kref_get(&cur->ref);
|
||||
} else {
|
||||
drm_gem_object_get(intel_bo_to_drm_bo(obj));
|
||||
rcu_assign_pointer(obj->frontbuffer, front);
|
||||
}
|
||||
|
||||
return cur;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -718,6 +718,9 @@ struct drm_i915_gem_object {
|
||||
};
|
||||
};
|
||||
|
||||
#define intel_bo_to_drm_bo(bo) (&(bo)->base)
|
||||
#define intel_bo_to_i915(bo) to_i915(intel_bo_to_drm_bo(bo)->dev)
|
||||
|
||||
static inline struct drm_i915_gem_object *
|
||||
to_intel_bo(struct drm_gem_object *gem)
|
||||
{
|
||||
|
@ -3556,16 +3556,16 @@ int intel_execlists_submission_setup(struct intel_engine_cs *engine)
|
||||
lrc_init_wa_ctx(engine);
|
||||
|
||||
if (HAS_LOGICAL_RING_ELSQ(i915)) {
|
||||
execlists->submit_reg = uncore->regs +
|
||||
execlists->submit_reg = intel_uncore_regs(uncore) +
|
||||
i915_mmio_reg_offset(RING_EXECLIST_SQ_CONTENTS(base));
|
||||
execlists->ctrl_reg = uncore->regs +
|
||||
execlists->ctrl_reg = intel_uncore_regs(uncore) +
|
||||
i915_mmio_reg_offset(RING_EXECLIST_CONTROL(base));
|
||||
|
||||
engine->fw_domain = intel_uncore_forcewake_for_reg(engine->uncore,
|
||||
RING_EXECLIST_CONTROL(engine->mmio_base),
|
||||
FW_REG_WRITE);
|
||||
} else {
|
||||
execlists->submit_reg = uncore->regs +
|
||||
execlists->submit_reg = intel_uncore_regs(uncore) +
|
||||
i915_mmio_reg_offset(RING_ELSP(base));
|
||||
}
|
||||
|
||||
|
@ -818,7 +818,7 @@ i915_gem_object_save_bit_17_swizzle(struct drm_i915_gem_object *obj,
|
||||
if (obj->bit_17 == NULL) {
|
||||
obj->bit_17 = bitmap_zalloc(page_count, GFP_KERNEL);
|
||||
if (obj->bit_17 == NULL) {
|
||||
drm_err(&to_i915(obj->base.dev)->drm,
|
||||
drm_err(obj->base.dev,
|
||||
"Failed to allocate memory for bit 17 record\n");
|
||||
return;
|
||||
}
|
||||
|
@ -904,7 +904,7 @@ int intel_gt_probe_all(struct drm_i915_private *i915)
|
||||
*/
|
||||
gt->i915 = i915;
|
||||
gt->name = "Primary GT";
|
||||
gt->info.engine_mask = RUNTIME_INFO(i915)->platform_engine_mask;
|
||||
gt->info.engine_mask = INTEL_INFO(i915)->platform_engine_mask;
|
||||
|
||||
gt_dbg(gt, "Setting up %s\n", gt->name);
|
||||
ret = intel_gt_tile_setup(gt, phys_addr);
|
||||
|
@ -31,7 +31,7 @@ static u32
|
||||
gen11_gt_engine_identity(struct intel_gt *gt,
|
||||
const unsigned int bank, const unsigned int bit)
|
||||
{
|
||||
void __iomem * const regs = gt->uncore->regs;
|
||||
void __iomem * const regs = intel_uncore_regs(gt->uncore);
|
||||
u32 timeout_ts;
|
||||
u32 ident;
|
||||
|
||||
@ -148,7 +148,7 @@ gen11_gt_identity_handler(struct intel_gt *gt, const u32 identity)
|
||||
static void
|
||||
gen11_gt_bank_handler(struct intel_gt *gt, const unsigned int bank)
|
||||
{
|
||||
void __iomem * const regs = gt->uncore->regs;
|
||||
void __iomem * const regs = intel_uncore_regs(gt->uncore);
|
||||
unsigned long intr_dw;
|
||||
unsigned int bit;
|
||||
|
||||
@ -183,7 +183,7 @@ void gen11_gt_irq_handler(struct intel_gt *gt, const u32 master_ctl)
|
||||
bool gen11_gt_reset_one_iir(struct intel_gt *gt,
|
||||
const unsigned int bank, const unsigned int bit)
|
||||
{
|
||||
void __iomem * const regs = gt->uncore->regs;
|
||||
void __iomem * const regs = intel_uncore_regs(gt->uncore);
|
||||
u32 dw;
|
||||
|
||||
lockdep_assert_held(gt->irq_lock);
|
||||
@ -404,7 +404,7 @@ void gen6_gt_irq_handler(struct intel_gt *gt, u32 gt_iir)
|
||||
|
||||
void gen8_gt_irq_handler(struct intel_gt *gt, u32 master_ctl)
|
||||
{
|
||||
void __iomem * const regs = gt->uncore->regs;
|
||||
void __iomem * const regs = intel_uncore_regs(gt->uncore);
|
||||
u32 iir;
|
||||
|
||||
if (master_ctl & (GEN8_GT_RCS_IRQ | GEN8_GT_BCS_IRQ)) {
|
||||
|
@ -29,7 +29,7 @@ int intel_sa_mediagt_setup(struct intel_gt *gt, phys_addr_t phys_addr,
|
||||
* Standalone media shares the general MMIO space with the primary
|
||||
* GT. We'll re-use the primary GT's mapping.
|
||||
*/
|
||||
uncore->regs = i915->uncore.regs;
|
||||
uncore->regs = intel_uncore_regs(&i915->uncore);
|
||||
if (drm_WARN_ON(&i915->drm, uncore->regs == NULL))
|
||||
return -EIO;
|
||||
|
||||
|
@ -98,7 +98,7 @@ static bool gsc_engine_supported(struct intel_gt *gt)
|
||||
GEM_BUG_ON(!gt_is_root(gt) && !gt->info.engine_mask);
|
||||
|
||||
if (gt_is_root(gt))
|
||||
mask = RUNTIME_INFO(gt->i915)->platform_engine_mask;
|
||||
mask = INTEL_INFO(gt->i915)->platform_engine_mask;
|
||||
else
|
||||
mask = gt->info.engine_mask;
|
||||
|
||||
|
@ -26,6 +26,7 @@
|
||||
* The kernel driver is only responsible for loading the HuC firmware and
|
||||
* triggering its security authentication. This is done differently depending
|
||||
* on the platform:
|
||||
*
|
||||
* - older platforms (from Gen9 to most Gen12s): the load is performed via DMA
|
||||
* and the authentication via GuC
|
||||
* - DG2: load and authentication are both performed via GSC.
|
||||
@ -33,6 +34,7 @@
|
||||
* not-DG2 older platforms), while the authentication is done in 2-steps,
|
||||
* a first auth for clear-media workloads via GuC and a second one for all
|
||||
* workloads via GSC.
|
||||
*
|
||||
* On platforms where the GuC does the authentication, to correctly do so the
|
||||
* HuC binary must be loaded before the GuC one.
|
||||
* Loading the HuC is optional; however, not using the HuC might negatively
|
||||
@ -265,7 +267,7 @@ static bool vcs_supported(struct intel_gt *gt)
|
||||
GEM_BUG_ON(!gt_is_root(gt) && !gt->info.engine_mask);
|
||||
|
||||
if (gt_is_root(gt))
|
||||
mask = RUNTIME_INFO(gt->i915)->platform_engine_mask;
|
||||
mask = INTEL_INFO(gt->i915)->platform_engine_mask;
|
||||
else
|
||||
mask = gt->info.engine_mask;
|
||||
|
||||
|
@ -67,6 +67,7 @@ static int i915_capabilities(struct seq_file *m, void *data)
|
||||
seq_printf(m, "pch: %d\n", INTEL_PCH_TYPE(i915));
|
||||
|
||||
intel_device_info_print(INTEL_INFO(i915), RUNTIME_INFO(i915), &p);
|
||||
intel_display_device_info_print(DISPLAY_INFO(i915), DISPLAY_RUNTIME_INFO(i915), &p);
|
||||
i915_print_iommu_status(i915, &p);
|
||||
intel_gt_info_print(&to_gt(i915)->info, &p);
|
||||
intel_driver_caps_print(&i915->caps, &p);
|
||||
|
@ -711,6 +711,8 @@ static void i915_welcome_messages(struct drm_i915_private *dev_priv)
|
||||
|
||||
intel_device_info_print(INTEL_INFO(dev_priv),
|
||||
RUNTIME_INFO(dev_priv), &p);
|
||||
intel_display_device_info_print(DISPLAY_INFO(dev_priv),
|
||||
DISPLAY_RUNTIME_INFO(dev_priv), &p);
|
||||
i915_print_iommu_status(dev_priv, &p);
|
||||
for_each_gt(gt, dev_priv, i)
|
||||
intel_gt_info_print(>->info, &p);
|
||||
|
@ -203,9 +203,8 @@ struct drm_i915_private {
|
||||
/* i915 device parameters */
|
||||
struct i915_params params;
|
||||
|
||||
const struct intel_device_info __info; /* Use INTEL_INFO() to access. */
|
||||
const struct intel_device_info *__info; /* Use INTEL_INFO() to access. */
|
||||
struct intel_runtime_info __runtime; /* Use RUNTIME_INFO() to access. */
|
||||
struct intel_display_runtime_info __display_runtime; /* Access with DISPLAY_RUNTIME_INFO() */
|
||||
struct intel_driver_caps caps;
|
||||
|
||||
struct i915_dsm dsm;
|
||||
@ -416,10 +415,10 @@ static inline struct intel_gt *to_gt(struct drm_i915_private *i915)
|
||||
(engine__) && (engine__)->uabi_class == (class__); \
|
||||
(engine__) = rb_to_uabi_engine(rb_next(&(engine__)->uabi_node)))
|
||||
|
||||
#define INTEL_INFO(i915) (&(i915)->__info)
|
||||
#define DISPLAY_INFO(i915) (INTEL_INFO(i915)->display)
|
||||
#define INTEL_INFO(i915) ((i915)->__info)
|
||||
#define RUNTIME_INFO(i915) (&(i915)->__runtime)
|
||||
#define DISPLAY_RUNTIME_INFO(i915) (&(i915)->__display_runtime)
|
||||
#define DISPLAY_INFO(i915) ((i915)->display.info.__device_info)
|
||||
#define DISPLAY_RUNTIME_INFO(i915) (&(i915)->display.info.__runtime_info)
|
||||
#define DRIVER_CAPS(i915) (&(i915)->caps)
|
||||
|
||||
#define INTEL_DEVID(i915) (RUNTIME_INFO(i915)->device_id)
|
||||
@ -839,7 +838,7 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915,
|
||||
*/
|
||||
#define HAS_64K_PAGES(i915) (INTEL_INFO(i915)->has_64k_pages)
|
||||
|
||||
#define HAS_REGION(i915, i) (RUNTIME_INFO(i915)->memory_regions & (i))
|
||||
#define HAS_REGION(i915, i) (INTEL_INFO(i915)->memory_regions & (i))
|
||||
#define HAS_LMEM(i915) HAS_REGION(i915, REGION_LMEM)
|
||||
|
||||
#define HAS_EXTRA_GT_LIST(i915) (INTEL_INFO(i915)->extra_gt_list)
|
||||
|
@ -649,6 +649,8 @@ static void err_print_capabilities(struct drm_i915_error_state_buf *m,
|
||||
struct drm_printer p = i915_error_printer(m);
|
||||
|
||||
intel_device_info_print(&error->device_info, &error->runtime_info, &p);
|
||||
intel_display_device_info_print(&error->display_device_info,
|
||||
&error->display_runtime_info, &p);
|
||||
intel_driver_caps_print(&error->driver_caps, &p);
|
||||
}
|
||||
|
||||
@ -1983,6 +1985,10 @@ static void capture_gen(struct i915_gpu_coredump *error)
|
||||
memcpy(&error->runtime_info,
|
||||
RUNTIME_INFO(i915),
|
||||
sizeof(error->runtime_info));
|
||||
memcpy(&error->display_device_info, DISPLAY_INFO(i915),
|
||||
sizeof(error->display_device_info));
|
||||
memcpy(&error->display_runtime_info, DISPLAY_RUNTIME_INFO(i915),
|
||||
sizeof(error->display_runtime_info));
|
||||
error->driver_caps = i915->caps;
|
||||
}
|
||||
|
||||
|
@ -14,6 +14,7 @@
|
||||
|
||||
#include <drm/drm_mm.h>
|
||||
|
||||
#include "display/intel_display_device.h"
|
||||
#include "gt/intel_engine.h"
|
||||
#include "gt/intel_gt_types.h"
|
||||
#include "gt/uc/intel_uc_fw.h"
|
||||
@ -209,6 +210,8 @@ struct i915_gpu_coredump {
|
||||
|
||||
struct intel_device_info device_info;
|
||||
struct intel_runtime_info runtime_info;
|
||||
struct intel_display_device_info display_device_info;
|
||||
struct intel_display_runtime_info display_runtime_info;
|
||||
struct intel_driver_caps driver_caps;
|
||||
struct i915_params params;
|
||||
|
||||
|
@ -423,7 +423,7 @@ static irqreturn_t cherryview_irq_handler(int irq, void *arg)
|
||||
static irqreturn_t ilk_irq_handler(int irq, void *arg)
|
||||
{
|
||||
struct drm_i915_private *i915 = arg;
|
||||
void __iomem * const regs = i915->uncore.regs;
|
||||
void __iomem * const regs = intel_uncore_regs(&i915->uncore);
|
||||
u32 de_iir, gt_iir, de_ier, sde_ier = 0;
|
||||
irqreturn_t ret = IRQ_NONE;
|
||||
|
||||
@ -511,7 +511,7 @@ static inline void gen8_master_intr_enable(void __iomem * const regs)
|
||||
static irqreturn_t gen8_irq_handler(int irq, void *arg)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = arg;
|
||||
void __iomem * const regs = dev_priv->uncore.regs;
|
||||
void __iomem * const regs = intel_uncore_regs(&dev_priv->uncore);
|
||||
u32 master_ctl;
|
||||
|
||||
if (!intel_irqs_enabled(dev_priv))
|
||||
@ -561,7 +561,7 @@ static inline void gen11_master_intr_enable(void __iomem * const regs)
|
||||
static irqreturn_t gen11_irq_handler(int irq, void *arg)
|
||||
{
|
||||
struct drm_i915_private *i915 = arg;
|
||||
void __iomem * const regs = i915->uncore.regs;
|
||||
void __iomem * const regs = intel_uncore_regs(&i915->uncore);
|
||||
struct intel_gt *gt = to_gt(i915);
|
||||
u32 master_ctl;
|
||||
u32 gu_misc_iir;
|
||||
@ -619,7 +619,7 @@ static irqreturn_t dg1_irq_handler(int irq, void *arg)
|
||||
{
|
||||
struct drm_i915_private * const i915 = arg;
|
||||
struct intel_gt *gt = to_gt(i915);
|
||||
void __iomem * const regs = gt->uncore->regs;
|
||||
void __iomem * const regs = intel_uncore_regs(gt->uncore);
|
||||
u32 master_tile_ctl, master_ctl;
|
||||
u32 gu_misc_iir;
|
||||
|
||||
@ -711,7 +711,7 @@ static void gen8_irq_reset(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
struct intel_uncore *uncore = &dev_priv->uncore;
|
||||
|
||||
gen8_master_intr_disable(uncore->regs);
|
||||
gen8_master_intr_disable(intel_uncore_regs(uncore));
|
||||
|
||||
gen8_gt_irq_reset(to_gt(dev_priv));
|
||||
gen8_display_irq_reset(dev_priv);
|
||||
@ -727,7 +727,7 @@ static void gen11_irq_reset(struct drm_i915_private *dev_priv)
|
||||
struct intel_gt *gt = to_gt(dev_priv);
|
||||
struct intel_uncore *uncore = gt->uncore;
|
||||
|
||||
gen11_master_intr_disable(dev_priv->uncore.regs);
|
||||
gen11_master_intr_disable(intel_uncore_regs(&dev_priv->uncore));
|
||||
|
||||
gen11_gt_irq_reset(gt);
|
||||
gen11_display_irq_reset(dev_priv);
|
||||
@ -742,7 +742,7 @@ static void dg1_irq_reset(struct drm_i915_private *dev_priv)
|
||||
struct intel_gt *gt;
|
||||
unsigned int i;
|
||||
|
||||
dg1_master_intr_disable(dev_priv->uncore.regs);
|
||||
dg1_master_intr_disable(intel_uncore_regs(&dev_priv->uncore));
|
||||
|
||||
for_each_gt(gt, dev_priv, i)
|
||||
gen11_gt_irq_reset(gt);
|
||||
@ -836,7 +836,7 @@ static void gen8_irq_postinstall(struct drm_i915_private *dev_priv)
|
||||
gen8_gt_irq_postinstall(to_gt(dev_priv));
|
||||
gen8_de_irq_postinstall(dev_priv);
|
||||
|
||||
gen8_master_intr_enable(dev_priv->uncore.regs);
|
||||
gen8_master_intr_enable(intel_uncore_regs(&dev_priv->uncore));
|
||||
}
|
||||
|
||||
static void gen11_irq_postinstall(struct drm_i915_private *dev_priv)
|
||||
@ -853,7 +853,7 @@ static void gen11_irq_postinstall(struct drm_i915_private *dev_priv)
|
||||
|
||||
GEN3_IRQ_INIT(uncore, GEN11_GU_MISC_, ~gu_misc_masked, gu_misc_masked);
|
||||
|
||||
gen11_master_intr_enable(uncore->regs);
|
||||
gen11_master_intr_enable(intel_uncore_regs(uncore));
|
||||
intel_uncore_posting_read(&dev_priv->uncore, GEN11_GFX_MSTR_IRQ);
|
||||
}
|
||||
|
||||
@ -880,7 +880,7 @@ static void dg1_irq_postinstall(struct drm_i915_private *dev_priv)
|
||||
GEN11_DISPLAY_IRQ_ENABLE);
|
||||
}
|
||||
|
||||
dg1_master_intr_enable(uncore->regs);
|
||||
dg1_master_intr_enable(intel_uncore_regs(uncore));
|
||||
intel_uncore_posting_read(uncore, DG1_MSTR_TILE_INTR);
|
||||
}
|
||||
|
||||
|
@ -38,9 +38,6 @@
|
||||
#include "i915_reg.h"
|
||||
#include "intel_pci_config.h"
|
||||
|
||||
__diag_push();
|
||||
__diag_ignore_all("-Woverride-init", "Allow overriding inherited members");
|
||||
|
||||
#define PLATFORM(x) .platform = (x)
|
||||
#define GEN(x) \
|
||||
.__runtime.graphics.ip.ver = (x), \
|
||||
@ -84,7 +81,7 @@ __diag_ignore_all("-Woverride-init", "Allow overriding inherited members");
|
||||
.__runtime.page_sizes = I915_GTT_PAGE_SIZE_4K
|
||||
|
||||
#define GEN_DEFAULT_REGIONS \
|
||||
.__runtime.memory_regions = REGION_SMEM | REGION_STOLEN_SMEM
|
||||
.memory_regions = REGION_SMEM | REGION_STOLEN_SMEM
|
||||
|
||||
#define I830_FEATURES \
|
||||
GEN(2), \
|
||||
@ -93,7 +90,7 @@ __diag_ignore_all("-Woverride-init", "Allow overriding inherited members");
|
||||
.has_3d_pipeline = 1, \
|
||||
.hws_needs_physical = 1, \
|
||||
.unfenced_needs_alignment = 1, \
|
||||
.__runtime.platform_engine_mask = BIT(RCS0), \
|
||||
.platform_engine_mask = BIT(RCS0), \
|
||||
.has_snoop = true, \
|
||||
.has_coherent_ggtt = false, \
|
||||
.dma_mask_size = 32, \
|
||||
@ -108,7 +105,7 @@ __diag_ignore_all("-Woverride-init", "Allow overriding inherited members");
|
||||
.gpu_reset_clobbers_display = true, \
|
||||
.hws_needs_physical = 1, \
|
||||
.unfenced_needs_alignment = 1, \
|
||||
.__runtime.platform_engine_mask = BIT(RCS0), \
|
||||
.platform_engine_mask = BIT(RCS0), \
|
||||
.has_snoop = true, \
|
||||
.has_coherent_ggtt = false, \
|
||||
.dma_mask_size = 32, \
|
||||
@ -140,7 +137,7 @@ static const struct intel_device_info i865g_info = {
|
||||
#define GEN3_FEATURES \
|
||||
GEN(3), \
|
||||
.gpu_reset_clobbers_display = true, \
|
||||
.__runtime.platform_engine_mask = BIT(RCS0), \
|
||||
.platform_engine_mask = BIT(RCS0), \
|
||||
.has_3d_pipeline = 1, \
|
||||
.has_snoop = true, \
|
||||
.has_coherent_ggtt = true, \
|
||||
@ -203,7 +200,7 @@ static const struct intel_device_info pnv_m_info = {
|
||||
#define GEN4_FEATURES \
|
||||
GEN(4), \
|
||||
.gpu_reset_clobbers_display = true, \
|
||||
.__runtime.platform_engine_mask = BIT(RCS0), \
|
||||
.platform_engine_mask = BIT(RCS0), \
|
||||
.has_3d_pipeline = 1, \
|
||||
.has_snoop = true, \
|
||||
.has_coherent_ggtt = true, \
|
||||
@ -231,7 +228,7 @@ static const struct intel_device_info i965gm_info = {
|
||||
static const struct intel_device_info g45_info = {
|
||||
GEN4_FEATURES,
|
||||
PLATFORM(INTEL_G45),
|
||||
.__runtime.platform_engine_mask = BIT(RCS0) | BIT(VCS0),
|
||||
.platform_engine_mask = BIT(RCS0) | BIT(VCS0),
|
||||
.gpu_reset_clobbers_display = false,
|
||||
};
|
||||
|
||||
@ -239,13 +236,13 @@ static const struct intel_device_info gm45_info = {
|
||||
GEN4_FEATURES,
|
||||
PLATFORM(INTEL_GM45),
|
||||
.is_mobile = 1,
|
||||
.__runtime.platform_engine_mask = BIT(RCS0) | BIT(VCS0),
|
||||
.platform_engine_mask = BIT(RCS0) | BIT(VCS0),
|
||||
.gpu_reset_clobbers_display = false,
|
||||
};
|
||||
|
||||
#define GEN5_FEATURES \
|
||||
GEN(5), \
|
||||
.__runtime.platform_engine_mask = BIT(RCS0) | BIT(VCS0), \
|
||||
.platform_engine_mask = BIT(RCS0) | BIT(VCS0), \
|
||||
.has_3d_pipeline = 1, \
|
||||
.has_snoop = true, \
|
||||
.has_coherent_ggtt = true, \
|
||||
@ -271,7 +268,7 @@ static const struct intel_device_info ilk_m_info = {
|
||||
|
||||
#define GEN6_FEATURES \
|
||||
GEN(6), \
|
||||
.__runtime.platform_engine_mask = BIT(RCS0) | BIT(VCS0) | BIT(BCS0), \
|
||||
.platform_engine_mask = BIT(RCS0) | BIT(VCS0) | BIT(BCS0), \
|
||||
.has_3d_pipeline = 1, \
|
||||
.has_coherent_ggtt = true, \
|
||||
.has_llc = 1, \
|
||||
@ -319,7 +316,7 @@ static const struct intel_device_info snb_m_gt2_info = {
|
||||
|
||||
#define GEN7_FEATURES \
|
||||
GEN(7), \
|
||||
.__runtime.platform_engine_mask = BIT(RCS0) | BIT(VCS0) | BIT(BCS0), \
|
||||
.platform_engine_mask = BIT(RCS0) | BIT(VCS0) | BIT(BCS0), \
|
||||
.has_3d_pipeline = 1, \
|
||||
.has_coherent_ggtt = true, \
|
||||
.has_llc = 1, \
|
||||
@ -387,7 +384,7 @@ static const struct intel_device_info vlv_info = {
|
||||
.__runtime.ppgtt_size = 31,
|
||||
.has_snoop = true,
|
||||
.has_coherent_ggtt = false,
|
||||
.__runtime.platform_engine_mask = BIT(RCS0) | BIT(VCS0) | BIT(BCS0),
|
||||
.platform_engine_mask = BIT(RCS0) | BIT(VCS0) | BIT(BCS0),
|
||||
GEN_DEFAULT_PAGE_SIZES,
|
||||
GEN_DEFAULT_REGIONS,
|
||||
LEGACY_CACHELEVEL,
|
||||
@ -395,7 +392,7 @@ static const struct intel_device_info vlv_info = {
|
||||
|
||||
#define G75_FEATURES \
|
||||
GEN7_FEATURES, \
|
||||
.__runtime.platform_engine_mask = BIT(RCS0) | BIT(VCS0) | BIT(BCS0) | BIT(VECS0), \
|
||||
.platform_engine_mask = BIT(RCS0) | BIT(VCS0) | BIT(BCS0) | BIT(VECS0), \
|
||||
.has_rc6p = 0 /* RC6p removed-by HSW */, \
|
||||
.has_runtime_pm = 1
|
||||
|
||||
@ -453,7 +450,7 @@ static const struct intel_device_info bdw_rsvd_info = {
|
||||
static const struct intel_device_info bdw_gt3_info = {
|
||||
BDW_PLATFORM,
|
||||
.gt = 3,
|
||||
.__runtime.platform_engine_mask =
|
||||
.platform_engine_mask =
|
||||
BIT(RCS0) | BIT(VCS0) | BIT(BCS0) | BIT(VECS0) | BIT(VCS1),
|
||||
};
|
||||
|
||||
@ -461,7 +458,7 @@ static const struct intel_device_info chv_info = {
|
||||
PLATFORM(INTEL_CHERRYVIEW),
|
||||
GEN(8),
|
||||
.is_lp = 1,
|
||||
.__runtime.platform_engine_mask = BIT(RCS0) | BIT(VCS0) | BIT(BCS0) | BIT(VECS0),
|
||||
.platform_engine_mask = BIT(RCS0) | BIT(VCS0) | BIT(BCS0) | BIT(VECS0),
|
||||
.has_64bit_reloc = 1,
|
||||
.has_runtime_pm = 1,
|
||||
.has_rc6 = 1,
|
||||
@ -505,7 +502,7 @@ static const struct intel_device_info skl_gt2_info = {
|
||||
|
||||
#define SKL_GT3_PLUS_PLATFORM \
|
||||
SKL_PLATFORM, \
|
||||
.__runtime.platform_engine_mask = \
|
||||
.platform_engine_mask = \
|
||||
BIT(RCS0) | BIT(VCS0) | BIT(BCS0) | BIT(VECS0) | BIT(VCS1)
|
||||
|
||||
|
||||
@ -522,7 +519,7 @@ static const struct intel_device_info skl_gt4_info = {
|
||||
#define GEN9_LP_FEATURES \
|
||||
GEN(9), \
|
||||
.is_lp = 1, \
|
||||
.__runtime.platform_engine_mask = BIT(RCS0) | BIT(VCS0) | BIT(BCS0) | BIT(VECS0), \
|
||||
.platform_engine_mask = BIT(RCS0) | BIT(VCS0) | BIT(BCS0) | BIT(VECS0), \
|
||||
.has_3d_pipeline = 1, \
|
||||
.has_64bit_reloc = 1, \
|
||||
.has_runtime_pm = 1, \
|
||||
@ -568,7 +565,7 @@ static const struct intel_device_info kbl_gt2_info = {
|
||||
static const struct intel_device_info kbl_gt3_info = {
|
||||
KBL_PLATFORM,
|
||||
.gt = 3,
|
||||
.__runtime.platform_engine_mask =
|
||||
.platform_engine_mask =
|
||||
BIT(RCS0) | BIT(VCS0) | BIT(BCS0) | BIT(VECS0) | BIT(VCS1),
|
||||
};
|
||||
|
||||
@ -589,7 +586,7 @@ static const struct intel_device_info cfl_gt2_info = {
|
||||
static const struct intel_device_info cfl_gt3_info = {
|
||||
CFL_PLATFORM,
|
||||
.gt = 3,
|
||||
.__runtime.platform_engine_mask =
|
||||
.platform_engine_mask =
|
||||
BIT(RCS0) | BIT(VCS0) | BIT(BCS0) | BIT(VECS0) | BIT(VCS1),
|
||||
};
|
||||
|
||||
@ -622,21 +619,21 @@ static const struct intel_device_info cml_gt2_info = {
|
||||
static const struct intel_device_info icl_info = {
|
||||
GEN11_FEATURES,
|
||||
PLATFORM(INTEL_ICELAKE),
|
||||
.__runtime.platform_engine_mask =
|
||||
.platform_engine_mask =
|
||||
BIT(RCS0) | BIT(BCS0) | BIT(VECS0) | BIT(VCS0) | BIT(VCS2),
|
||||
};
|
||||
|
||||
static const struct intel_device_info ehl_info = {
|
||||
GEN11_FEATURES,
|
||||
PLATFORM(INTEL_ELKHARTLAKE),
|
||||
.__runtime.platform_engine_mask = BIT(RCS0) | BIT(BCS0) | BIT(VCS0) | BIT(VECS0),
|
||||
.platform_engine_mask = BIT(RCS0) | BIT(BCS0) | BIT(VCS0) | BIT(VECS0),
|
||||
.__runtime.ppgtt_size = 36,
|
||||
};
|
||||
|
||||
static const struct intel_device_info jsl_info = {
|
||||
GEN11_FEATURES,
|
||||
PLATFORM(INTEL_JASPERLAKE),
|
||||
.__runtime.platform_engine_mask = BIT(RCS0) | BIT(BCS0) | BIT(VCS0) | BIT(VECS0),
|
||||
.platform_engine_mask = BIT(RCS0) | BIT(BCS0) | BIT(VCS0) | BIT(VECS0),
|
||||
.__runtime.ppgtt_size = 36,
|
||||
};
|
||||
|
||||
@ -651,19 +648,19 @@ static const struct intel_device_info jsl_info = {
|
||||
static const struct intel_device_info tgl_info = {
|
||||
GEN12_FEATURES,
|
||||
PLATFORM(INTEL_TIGERLAKE),
|
||||
.__runtime.platform_engine_mask =
|
||||
.platform_engine_mask =
|
||||
BIT(RCS0) | BIT(BCS0) | BIT(VECS0) | BIT(VCS0) | BIT(VCS2),
|
||||
};
|
||||
|
||||
static const struct intel_device_info rkl_info = {
|
||||
GEN12_FEATURES,
|
||||
PLATFORM(INTEL_ROCKETLAKE),
|
||||
.__runtime.platform_engine_mask =
|
||||
.platform_engine_mask =
|
||||
BIT(RCS0) | BIT(BCS0) | BIT(VECS0) | BIT(VCS0),
|
||||
};
|
||||
|
||||
#define DGFX_FEATURES \
|
||||
.__runtime.memory_regions = REGION_SMEM | REGION_LMEM | REGION_STOLEN_LMEM, \
|
||||
.memory_regions = REGION_SMEM | REGION_LMEM | REGION_STOLEN_LMEM, \
|
||||
.has_llc = 0, \
|
||||
.has_pxp = 0, \
|
||||
.has_snoop = 1, \
|
||||
@ -676,7 +673,7 @@ static const struct intel_device_info dg1_info = {
|
||||
.__runtime.graphics.ip.rel = 10,
|
||||
PLATFORM(INTEL_DG1),
|
||||
.require_force_probe = 1,
|
||||
.__runtime.platform_engine_mask =
|
||||
.platform_engine_mask =
|
||||
BIT(RCS0) | BIT(BCS0) | BIT(VECS0) |
|
||||
BIT(VCS0) | BIT(VCS2),
|
||||
/* Wa_16011227922 */
|
||||
@ -686,7 +683,7 @@ static const struct intel_device_info dg1_info = {
|
||||
static const struct intel_device_info adl_s_info = {
|
||||
GEN12_FEATURES,
|
||||
PLATFORM(INTEL_ALDERLAKE_S),
|
||||
.__runtime.platform_engine_mask =
|
||||
.platform_engine_mask =
|
||||
BIT(RCS0) | BIT(BCS0) | BIT(VECS0) | BIT(VCS0) | BIT(VCS2),
|
||||
.dma_mask_size = 39,
|
||||
};
|
||||
@ -694,7 +691,7 @@ static const struct intel_device_info adl_s_info = {
|
||||
static const struct intel_device_info adl_p_info = {
|
||||
GEN12_FEATURES,
|
||||
PLATFORM(INTEL_ALDERLAKE_P),
|
||||
.__runtime.platform_engine_mask =
|
||||
.platform_engine_mask =
|
||||
BIT(RCS0) | BIT(BCS0) | BIT(VECS0) | BIT(VCS0) | BIT(VCS2),
|
||||
.__runtime.ppgtt_size = 48,
|
||||
.dma_mask_size = 39,
|
||||
@ -746,7 +743,7 @@ static const struct intel_device_info xehpsdv_info = {
|
||||
PLATFORM(INTEL_XEHPSDV),
|
||||
.has_64k_pages = 1,
|
||||
.has_media_ratio_mode = 1,
|
||||
.__runtime.platform_engine_mask =
|
||||
.platform_engine_mask =
|
||||
BIT(RCS0) | BIT(BCS0) |
|
||||
BIT(VECS0) | BIT(VECS1) | BIT(VECS2) | BIT(VECS3) |
|
||||
BIT(VCS0) | BIT(VCS1) | BIT(VCS2) | BIT(VCS3) |
|
||||
@ -766,7 +763,7 @@ static const struct intel_device_info xehpsdv_info = {
|
||||
.has_guc_deprivilege = 1, \
|
||||
.has_heci_pxp = 1, \
|
||||
.has_media_ratio_mode = 1, \
|
||||
.__runtime.platform_engine_mask = \
|
||||
.platform_engine_mask = \
|
||||
BIT(RCS0) | BIT(BCS0) | \
|
||||
BIT(VECS0) | BIT(VECS1) | \
|
||||
BIT(VCS0) | BIT(VCS2) | \
|
||||
@ -801,7 +798,7 @@ static const struct intel_device_info pvc_info = {
|
||||
PLATFORM(INTEL_PONTEVECCHIO),
|
||||
.has_flat_ccs = 0,
|
||||
.max_pat_index = 7,
|
||||
.__runtime.platform_engine_mask =
|
||||
.platform_engine_mask =
|
||||
BIT(BCS0) |
|
||||
BIT(VCS0) |
|
||||
BIT(CCS0) | BIT(CCS1) | BIT(CCS2) | BIT(CCS3),
|
||||
@ -838,16 +835,14 @@ static const struct intel_device_info mtl_info = {
|
||||
.has_snoop = 1,
|
||||
.max_pat_index = 4,
|
||||
.has_pxp = 1,
|
||||
.__runtime.memory_regions = REGION_SMEM | REGION_STOLEN_LMEM,
|
||||
.__runtime.platform_engine_mask = BIT(RCS0) | BIT(BCS0) | BIT(CCS0),
|
||||
.memory_regions = REGION_SMEM | REGION_STOLEN_LMEM,
|
||||
.platform_engine_mask = BIT(RCS0) | BIT(BCS0) | BIT(CCS0),
|
||||
.require_force_probe = 1,
|
||||
MTL_CACHELEVEL,
|
||||
};
|
||||
|
||||
#undef PLATFORM
|
||||
|
||||
__diag_pop();
|
||||
|
||||
/*
|
||||
* Make sure any device matches here are from most specific to most
|
||||
* general. For example, since the Quanta match is based on the subsystem
|
||||
|
@ -4917,6 +4917,7 @@
|
||||
|
||||
#define SHPD_FILTER_CNT _MMIO(0xc4038)
|
||||
#define SHPD_FILTER_CNT_500_ADJ 0x001D9
|
||||
#define SHPD_FILTER_CNT_250 0x000F8
|
||||
|
||||
#define _PCH_DPLL_A 0xc6014
|
||||
#define _PCH_DPLL_B 0xc6018
|
||||
|
@ -74,14 +74,14 @@ static void vma_print_allocator(struct i915_vma *vma, const char *reason)
|
||||
char buf[512];
|
||||
|
||||
if (!vma->node.stack) {
|
||||
drm_dbg(&to_i915(vma->obj->base.dev)->drm,
|
||||
drm_dbg(vma->obj->base.dev,
|
||||
"vma.node [%08llx + %08llx] %s: unknown owner\n",
|
||||
vma->node.start, vma->node.size, reason);
|
||||
return;
|
||||
}
|
||||
|
||||
stack_depot_snprint(vma->node.stack, buf, sizeof(buf), 0);
|
||||
drm_dbg(&to_i915(vma->obj->base.dev)->drm,
|
||||
drm_dbg(vma->obj->base.dev,
|
||||
"vma.node [%08llx + %08llx] %s: inserted at %s\n",
|
||||
vma->node.start, vma->node.size, reason, buf);
|
||||
}
|
||||
@ -805,7 +805,7 @@ i915_vma_insert(struct i915_vma *vma, struct i915_gem_ww_ctx *ww,
|
||||
* attempt to find space.
|
||||
*/
|
||||
if (size > end - 2 * guard) {
|
||||
drm_dbg(&to_i915(vma->obj->base.dev)->drm,
|
||||
drm_dbg(vma->obj->base.dev,
|
||||
"Attempting to bind an object larger than the aperture: request=%llu > %s aperture=%llu\n",
|
||||
size, flags & PIN_MAPPABLE ? "mappable" : "total", end);
|
||||
return -ENOSPC;
|
||||
@ -1629,6 +1629,26 @@ int i915_ggtt_pin(struct i915_vma *vma, struct i915_gem_ww_ctx *ww,
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* i915_ggtt_clear_scanout - Clear scanout flag for all objects ggtt vmas
|
||||
* @obj: i915 GEM object
|
||||
* This function clears scanout flags for objects ggtt vmas. These flags are set
|
||||
* when object is pinned for display use and this function to clear them all is
|
||||
* targeted to be called by frontbuffer tracking code when the frontbuffer is
|
||||
* about to be released.
|
||||
*/
|
||||
void i915_ggtt_clear_scanout(struct drm_i915_gem_object *obj)
|
||||
{
|
||||
struct i915_vma *vma;
|
||||
|
||||
spin_lock(&obj->vma.lock);
|
||||
for_each_ggtt_vma(vma, obj) {
|
||||
i915_vma_clear_scanout(vma);
|
||||
vma->display_alignment = I915_GTT_MIN_ALIGNMENT;
|
||||
}
|
||||
spin_unlock(&obj->vma.lock);
|
||||
}
|
||||
|
||||
static void __vma_close(struct i915_vma *vma, struct intel_gt *gt)
|
||||
{
|
||||
/*
|
||||
@ -1908,7 +1928,7 @@ int _i915_vma_move_to_active(struct i915_vma *vma,
|
||||
if (flags & EXEC_OBJECT_WRITE) {
|
||||
struct intel_frontbuffer *front;
|
||||
|
||||
front = __intel_frontbuffer_get(obj);
|
||||
front = i915_gem_object_get_frontbuffer(obj);
|
||||
if (unlikely(front)) {
|
||||
if (intel_frontbuffer_invalidate(front, ORIGIN_CS))
|
||||
i915_active_add_request(&front->write, rq);
|
||||
|
@ -435,6 +435,8 @@ static inline void i915_vma_clear_scanout(struct i915_vma *vma)
|
||||
clear_bit(I915_VMA_SCANOUT_BIT, __i915_vma_flags(vma));
|
||||
}
|
||||
|
||||
void i915_ggtt_clear_scanout(struct drm_i915_gem_object *obj);
|
||||
|
||||
#define for_each_until(cond) if (cond) break; else
|
||||
|
||||
/**
|
||||
|
@ -559,9 +559,20 @@ static void bdw_init_clock_gating(struct drm_i915_private *i915)
|
||||
|
||||
static void hsw_init_clock_gating(struct drm_i915_private *i915)
|
||||
{
|
||||
enum pipe pipe;
|
||||
|
||||
/* WaFbcAsynchFlipDisableFbcQueue:hsw,bdw */
|
||||
intel_uncore_rmw(&i915->uncore, CHICKEN_PIPESL_1(PIPE_A), 0, HSW_FBCQ_DIS);
|
||||
|
||||
/* WaPsrDPAMaskVBlankInSRD:hsw */
|
||||
intel_uncore_rmw(&i915->uncore, CHICKEN_PAR1_1, 0, HSW_MASK_VBL_TO_PIPE_IN_SRD);
|
||||
|
||||
for_each_pipe(i915, pipe) {
|
||||
/* WaPsrDPRSUnmaskVBlankInSRD:hsw */
|
||||
intel_uncore_rmw(&i915->uncore, CHICKEN_PIPESL_1(pipe),
|
||||
0, HSW_UNMASK_VBL_TO_REGS_IN_SRD);
|
||||
}
|
||||
|
||||
/* This is required by WaCatErrorRejectionIssue:hsw */
|
||||
intel_uncore_rmw(&i915->uncore, GEN7_SQ_CHICKEN_MBCUNIT_CONFIG,
|
||||
0, GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB);
|
||||
|
@ -93,9 +93,6 @@ void intel_device_info_print(const struct intel_device_info *info,
|
||||
const struct intel_runtime_info *runtime,
|
||||
struct drm_printer *p)
|
||||
{
|
||||
const struct intel_display_runtime_info *display_runtime =
|
||||
&info->display->__runtime_defaults;
|
||||
|
||||
if (runtime->graphics.ip.rel)
|
||||
drm_printf(p, "graphics version: %u.%02u\n",
|
||||
runtime->graphics.ip.ver,
|
||||
@ -112,21 +109,13 @@ void intel_device_info_print(const struct intel_device_info *info,
|
||||
drm_printf(p, "media version: %u\n",
|
||||
runtime->media.ip.ver);
|
||||
|
||||
if (display_runtime->ip.rel)
|
||||
drm_printf(p, "display version: %u.%02u\n",
|
||||
display_runtime->ip.ver,
|
||||
display_runtime->ip.rel);
|
||||
else
|
||||
drm_printf(p, "display version: %u\n",
|
||||
display_runtime->ip.ver);
|
||||
|
||||
drm_printf(p, "graphics stepping: %s\n", intel_step_name(runtime->step.graphics_step));
|
||||
drm_printf(p, "media stepping: %s\n", intel_step_name(runtime->step.media_step));
|
||||
drm_printf(p, "display stepping: %s\n", intel_step_name(runtime->step.display_step));
|
||||
drm_printf(p, "base die stepping: %s\n", intel_step_name(runtime->step.basedie_step));
|
||||
|
||||
drm_printf(p, "gt: %d\n", info->gt);
|
||||
drm_printf(p, "memory-regions: 0x%x\n", runtime->memory_regions);
|
||||
drm_printf(p, "memory-regions: 0x%x\n", info->memory_regions);
|
||||
drm_printf(p, "page-sizes: 0x%x\n", runtime->page_sizes);
|
||||
drm_printf(p, "platform: %s\n", intel_platform_name(info->platform));
|
||||
drm_printf(p, "ppgtt-size: %d\n", runtime->ppgtt_size);
|
||||
@ -138,15 +127,6 @@ void intel_device_info_print(const struct intel_device_info *info,
|
||||
#undef PRINT_FLAG
|
||||
|
||||
drm_printf(p, "has_pooled_eu: %s\n", str_yes_no(runtime->has_pooled_eu));
|
||||
|
||||
#define PRINT_FLAG(name) drm_printf(p, "%s: %s\n", #name, str_yes_no(info->display->name))
|
||||
DEV_INFO_DISPLAY_FOR_EACH_FLAG(PRINT_FLAG);
|
||||
#undef PRINT_FLAG
|
||||
|
||||
drm_printf(p, "has_hdcp: %s\n", str_yes_no(display_runtime->has_hdcp));
|
||||
drm_printf(p, "has_dmc: %s\n", str_yes_no(display_runtime->has_dmc));
|
||||
drm_printf(p, "has_dsc: %s\n", str_yes_no(display_runtime->has_dsc));
|
||||
|
||||
drm_printf(p, "rawclk rate: %u kHz\n", runtime->rawclk_freq);
|
||||
}
|
||||
|
||||
@ -260,15 +240,19 @@ static void intel_device_info_subplatform_init(struct drm_i915_private *i915)
|
||||
if (find_devid(devid, subplatform_ult_ids,
|
||||
ARRAY_SIZE(subplatform_ult_ids))) {
|
||||
mask = BIT(INTEL_SUBPLATFORM_ULT);
|
||||
if (IS_HASWELL(i915) || IS_BROADWELL(i915))
|
||||
DISPLAY_RUNTIME_INFO(i915)->port_mask &= ~BIT(PORT_D);
|
||||
} else if (find_devid(devid, subplatform_ulx_ids,
|
||||
ARRAY_SIZE(subplatform_ulx_ids))) {
|
||||
mask = BIT(INTEL_SUBPLATFORM_ULX);
|
||||
if (IS_HASWELL(i915) || IS_BROADWELL(i915)) {
|
||||
/* ULX machines are also considered ULT. */
|
||||
mask |= BIT(INTEL_SUBPLATFORM_ULT);
|
||||
DISPLAY_RUNTIME_INFO(i915)->port_mask &= ~BIT(PORT_D);
|
||||
}
|
||||
} else if (find_devid(devid, subplatform_portf_ids,
|
||||
ARRAY_SIZE(subplatform_portf_ids))) {
|
||||
DISPLAY_RUNTIME_INFO(i915)->port_mask |= BIT(PORT_F);
|
||||
mask = BIT(INTEL_SUBPLATFORM_PORTF);
|
||||
} else if (find_devid(devid, subplatform_uy_ids,
|
||||
ARRAY_SIZE(subplatform_uy_ids))) {
|
||||
@ -380,13 +364,6 @@ void intel_device_info_runtime_init_early(struct drm_i915_private *i915)
|
||||
intel_device_info_subplatform_init(i915);
|
||||
}
|
||||
|
||||
/* FIXME: Remove this, and make device info a const pointer to rodata. */
|
||||
static struct intel_device_info *
|
||||
mkwrite_device_info(struct drm_i915_private *i915)
|
||||
{
|
||||
return (struct intel_device_info *)INTEL_INFO(i915);
|
||||
}
|
||||
|
||||
static const struct intel_display_device_info no_display = {};
|
||||
|
||||
/**
|
||||
@ -407,7 +384,6 @@ static const struct intel_display_device_info no_display = {};
|
||||
*/
|
||||
void intel_device_info_runtime_init(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
struct intel_device_info *info = mkwrite_device_info(dev_priv);
|
||||
struct intel_runtime_info *runtime = RUNTIME_INFO(dev_priv);
|
||||
|
||||
if (HAS_DISPLAY(dev_priv))
|
||||
@ -417,7 +393,7 @@ void intel_device_info_runtime_init(struct drm_i915_private *dev_priv)
|
||||
if (!HAS_DISPLAY(dev_priv)) {
|
||||
dev_priv->drm.driver_features &= ~(DRIVER_MODESET |
|
||||
DRIVER_ATOMIC);
|
||||
info->display = &no_display;
|
||||
dev_priv->display.info.__device_info = &no_display;
|
||||
}
|
||||
|
||||
/* Disable nuclear pageflip by default on pre-g4x */
|
||||
@ -447,26 +423,24 @@ void intel_device_info_driver_create(struct drm_i915_private *i915,
|
||||
u16 device_id,
|
||||
const struct intel_device_info *match_info)
|
||||
{
|
||||
struct intel_device_info *info;
|
||||
struct intel_runtime_info *runtime;
|
||||
u16 ver, rel, step;
|
||||
|
||||
/* Setup the write-once "constant" device info */
|
||||
info = mkwrite_device_info(i915);
|
||||
memcpy(info, match_info, sizeof(*info));
|
||||
/* Setup INTEL_INFO() */
|
||||
i915->__info = match_info;
|
||||
|
||||
/* Initialize initial runtime info from static const data and pdev. */
|
||||
runtime = RUNTIME_INFO(i915);
|
||||
memcpy(runtime, &INTEL_INFO(i915)->__runtime, sizeof(*runtime));
|
||||
|
||||
/* Probe display support */
|
||||
info->display = intel_display_device_probe(i915, info->has_gmd_id,
|
||||
&ver, &rel, &step);
|
||||
i915->display.info.__device_info = intel_display_device_probe(i915, HAS_GMD_ID(i915),
|
||||
&ver, &rel, &step);
|
||||
memcpy(DISPLAY_RUNTIME_INFO(i915),
|
||||
&DISPLAY_INFO(i915)->__runtime_defaults,
|
||||
sizeof(*DISPLAY_RUNTIME_INFO(i915)));
|
||||
|
||||
if (info->has_gmd_id) {
|
||||
if (HAS_GMD_ID(i915)) {
|
||||
DISPLAY_RUNTIME_INFO(i915)->ip.ver = ver;
|
||||
DISPLAY_RUNTIME_INFO(i915)->ip.rel = rel;
|
||||
DISPLAY_RUNTIME_INFO(i915)->ip.step = step;
|
||||
|
@ -29,8 +29,6 @@
|
||||
|
||||
#include "intel_step.h"
|
||||
|
||||
#include "display/intel_display_device.h"
|
||||
|
||||
#include "gt/intel_engine_types.h"
|
||||
#include "gt/intel_context_types.h"
|
||||
#include "gt/intel_sseu.h"
|
||||
@ -212,8 +210,6 @@ struct intel_runtime_info {
|
||||
|
||||
u16 device_id;
|
||||
|
||||
intel_engine_mask_t platform_engine_mask; /* Engines supported by the HW */
|
||||
|
||||
u32 rawclk_freq;
|
||||
|
||||
struct intel_step_info step;
|
||||
@ -223,8 +219,6 @@ struct intel_runtime_info {
|
||||
enum intel_ppgtt_type ppgtt_type;
|
||||
unsigned int ppgtt_size; /* log2, e.g. 31/32/48 bits */
|
||||
|
||||
u32 memory_regions; /* regions supported by the HW */
|
||||
|
||||
bool has_pooled_eu;
|
||||
};
|
||||
|
||||
@ -237,12 +231,13 @@ struct intel_device_info {
|
||||
|
||||
u8 gt; /* GT number, 0 if undefined */
|
||||
|
||||
intel_engine_mask_t platform_engine_mask; /* Engines supported by the HW */
|
||||
u32 memory_regions; /* regions supported by the HW */
|
||||
|
||||
#define DEFINE_FLAG(name) u8 name:1
|
||||
DEV_INFO_FOR_EACH_FLAG(DEFINE_FLAG);
|
||||
#undef DEFINE_FLAG
|
||||
|
||||
const struct intel_display_device_info *display;
|
||||
|
||||
/*
|
||||
* Initial runtime info. Do not access outside of i915_driver_create().
|
||||
*/
|
||||
|
@ -1925,25 +1925,31 @@ __unclaimed_previous_reg_debug(struct intel_uncore *uncore,
|
||||
i915_mmio_reg_offset(reg));
|
||||
}
|
||||
|
||||
static inline void
|
||||
unclaimed_reg_debug(struct intel_uncore *uncore,
|
||||
const i915_reg_t reg,
|
||||
const bool read,
|
||||
const bool before)
|
||||
static inline bool __must_check
|
||||
unclaimed_reg_debug_header(struct intel_uncore *uncore,
|
||||
const i915_reg_t reg, const bool read)
|
||||
{
|
||||
if (likely(!uncore->i915->params.mmio_debug) || !uncore->debug)
|
||||
return;
|
||||
return false;
|
||||
|
||||
/* interrupts are disabled and re-enabled around uncore->lock usage */
|
||||
lockdep_assert_held(&uncore->lock);
|
||||
|
||||
if (before) {
|
||||
spin_lock(&uncore->debug->lock);
|
||||
__unclaimed_previous_reg_debug(uncore, reg, read);
|
||||
} else {
|
||||
__unclaimed_reg_debug(uncore, reg, read);
|
||||
spin_unlock(&uncore->debug->lock);
|
||||
}
|
||||
spin_lock(&uncore->debug->lock);
|
||||
__unclaimed_previous_reg_debug(uncore, reg, read);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline void
|
||||
unclaimed_reg_debug_footer(struct intel_uncore *uncore,
|
||||
const i915_reg_t reg, const bool read)
|
||||
{
|
||||
/* interrupts are disabled and re-enabled around uncore->lock usage */
|
||||
lockdep_assert_held(&uncore->lock);
|
||||
|
||||
__unclaimed_reg_debug(uncore, reg, read);
|
||||
spin_unlock(&uncore->debug->lock);
|
||||
}
|
||||
|
||||
#define __vgpu_read(x) \
|
||||
@ -2001,13 +2007,15 @@ __gen2_read(64)
|
||||
#define GEN6_READ_HEADER(x) \
|
||||
u32 offset = i915_mmio_reg_offset(reg); \
|
||||
unsigned long irqflags; \
|
||||
bool unclaimed_reg_debug; \
|
||||
u##x val = 0; \
|
||||
assert_rpm_wakelock_held(uncore->rpm); \
|
||||
spin_lock_irqsave(&uncore->lock, irqflags); \
|
||||
unclaimed_reg_debug(uncore, reg, true, true)
|
||||
unclaimed_reg_debug = unclaimed_reg_debug_header(uncore, reg, true)
|
||||
|
||||
#define GEN6_READ_FOOTER \
|
||||
unclaimed_reg_debug(uncore, reg, true, false); \
|
||||
if (unclaimed_reg_debug) \
|
||||
unclaimed_reg_debug_footer(uncore, reg, true); \
|
||||
spin_unlock_irqrestore(&uncore->lock, irqflags); \
|
||||
trace_i915_reg_rw(false, reg, val, sizeof(val), trace); \
|
||||
return val
|
||||
@ -2105,13 +2113,15 @@ __gen2_write(32)
|
||||
#define GEN6_WRITE_HEADER \
|
||||
u32 offset = i915_mmio_reg_offset(reg); \
|
||||
unsigned long irqflags; \
|
||||
bool unclaimed_reg_debug; \
|
||||
trace_i915_reg_rw(true, reg, val, sizeof(val), trace); \
|
||||
assert_rpm_wakelock_held(uncore->rpm); \
|
||||
spin_lock_irqsave(&uncore->lock, irqflags); \
|
||||
unclaimed_reg_debug(uncore, reg, false, true)
|
||||
unclaimed_reg_debug = unclaimed_reg_debug_header(uncore, reg, false)
|
||||
|
||||
#define GEN6_WRITE_FOOTER \
|
||||
unclaimed_reg_debug(uncore, reg, false, false); \
|
||||
if (unclaimed_reg_debug) \
|
||||
unclaimed_reg_debug_footer(uncore, reg, false); \
|
||||
spin_unlock_irqrestore(&uncore->lock, irqflags)
|
||||
|
||||
#define __gen6_write(x) \
|
||||
|
@ -496,6 +496,11 @@ static inline int intel_uncore_write_and_verify(struct intel_uncore *uncore,
|
||||
return (reg_val & mask) != expected_val ? -EINVAL : 0;
|
||||
}
|
||||
|
||||
static inline void __iomem *intel_uncore_regs(struct intel_uncore *uncore)
|
||||
{
|
||||
return uncore->regs;
|
||||
}
|
||||
|
||||
/*
|
||||
* The raw_reg_{read,write} macros are intended as a micro-optimization for
|
||||
* interrupt handlers so that the pointer indirection on uncore->regs can
|
||||
|
@ -210,7 +210,7 @@ static int live_forcewake_ops(void *arg)
|
||||
|
||||
for_each_engine(engine, gt, id) {
|
||||
i915_reg_t mmio = _MMIO(engine->mmio_base + r->offset);
|
||||
u32 __iomem *reg = uncore->regs + engine->mmio_base + r->offset;
|
||||
u32 __iomem *reg = intel_uncore_regs(uncore) + engine->mmio_base + r->offset;
|
||||
enum forcewake_domains fw_domains;
|
||||
u32 val;
|
||||
|
||||
|
@ -123,8 +123,8 @@ static const struct intel_device_info mock_info = {
|
||||
.__runtime.page_sizes = (I915_GTT_PAGE_SIZE_4K |
|
||||
I915_GTT_PAGE_SIZE_64K |
|
||||
I915_GTT_PAGE_SIZE_2M),
|
||||
.__runtime.memory_regions = REGION_SMEM,
|
||||
.__runtime.platform_engine_mask = BIT(0),
|
||||
.memory_regions = REGION_SMEM,
|
||||
.platform_engine_mask = BIT(0),
|
||||
|
||||
/* simply use legacy cache level for mock device */
|
||||
.max_pat_index = 3,
|
||||
|
@ -704,7 +704,7 @@ void intel_dram_edram_detect(struct drm_i915_private *i915)
|
||||
if (!(IS_HASWELL(i915) || IS_BROADWELL(i915) || GRAPHICS_VER(i915) >= 9))
|
||||
return;
|
||||
|
||||
edram_cap = __raw_uncore_read32(&i915->uncore, HSW_EDRAM_CAP);
|
||||
edram_cap = intel_uncore_read_fw(&i915->uncore, HSW_EDRAM_CAP);
|
||||
|
||||
/* NB: We can't write IDICR yet because we don't have gt funcs set up */
|
||||
|
||||
|
@ -47,11 +47,9 @@ intel_alloc_mchbar_resource(struct drm_i915_private *i915)
|
||||
mchbar_addr = ((u64)temp_hi << 32) | temp_lo;
|
||||
|
||||
/* If ACPI doesn't have it, assume we need to allocate it ourselves */
|
||||
#ifdef CONFIG_PNP
|
||||
if (mchbar_addr &&
|
||||
if (IS_ENABLED(CONFIG_PNP) && mchbar_addr &&
|
||||
pnp_range_reserved(mchbar_addr, mchbar_addr + MCHBAR_SIZE))
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
/* Get some space for it */
|
||||
i915->gmch.mch_res.name = "i915 MCHBAR";
|
||||
|
Loading…
x
Reference in New Issue
Block a user