- 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:
Dave Airlie 2023-08-07 13:18:12 +10:00
commit 7c9aa0f746
81 changed files with 1401 additions and 804 deletions

View file

@ -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

View file

@ -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!

View file

@ -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;

View file

@ -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);
}

View file

@ -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);

View file

@ -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__ */

View file

@ -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,

View file

@ -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);
}

View file

@ -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_ */

View file

@ -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

View file

@ -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;

View file

@ -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;

View file

@ -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,

View file

@ -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__ */

View file

@ -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 =

View file

@ -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);

View file

@ -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)

View file

@ -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;

View file

@ -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

View file

@ -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;

View file

@ -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
*/

View file

@ -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));
}

View file

@ -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

View file

@ -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);

View file

@ -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 @@ intel_display_power_put_async_work(struct work_struct *work)
* @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,

View file

@ -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

View file

@ -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;

View file

@ -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++) {

View file

@ -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;
}

View file

@ -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__ */

View file

@ -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);

View file

@ -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);

View file

@ -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 */

View file

@ -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;

View file

@ -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;

View file

@ -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);

View file

@ -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);
}

View file

@ -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);

View file

@ -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 ? &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 */

View file

@ -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, &gt->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(&gt->uc.gsc, addr,
header->message_size,
addr,
msg_out_len + sizeof(*header));
ret = intel_gsc_uc_heci_cmd_submit_packet(&gt->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(&gt->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;

View file

@ -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);

View file

@ -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,

View file

@ -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) {

View file

@ -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);

View file

@ -1348,11 +1348,12 @@ int intel_overlay_attrs_ioctl(struct drm_device *dev, void *data,
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))

View file

@ -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));

View file

@ -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)

View file

@ -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
/*

View file

@ -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)

View file

@ -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 <<

View file

@ -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,

View file

@ -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)
{

View file

@ -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);

View file

@ -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

View file

@ -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)
{

View file

@ -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));
}

View file

@ -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;
}

View file

@ -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);

View file

@ -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)) {

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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);

View file

@ -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(&gt->info, &p);

View file

@ -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)

View file

@ -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;
}

View file

@ -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;

View file

@ -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);
}

View file

@ -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

View file

@ -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

View file

@ -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);

View file

@ -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
/**

View file

@ -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);

View file

@ -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;

View file

@ -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().
*/

View file

@ -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) \

View file

@ -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

View file

@ -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;

View file

@ -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,

View file

@ -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 */

View file

@ -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";